[SCM] obs-studio/master: New upstream version 18.0.1+dfsg1

sramacher at users.alioth.debian.org sramacher at users.alioth.debian.org
Wed Apr 19 20:07:26 UTC 2017


The following commit has been merged in the master branch:
commit f2cf6cce509c8f9e2f0d72d39d06680e31ebef3b
Author: Sebastian Ramacher <sramacher at debian.org>
Date:   Wed Apr 19 21:54:15 2017 +0200

    New upstream version 18.0.1+dfsg1

diff --git a/.gitmodules b/.gitmodules
index cb9da41..f0d468b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,13 +1,15 @@
 [submodule "plugins/win-dshow/libdshowcapture"]
 	path = plugins/win-dshow/libdshowcapture
 	url = https://github.com/jp9000/libdshowcapture.git
-
 [submodule "plugins/mac-syphon/syphon-framework"]
 	path = plugins/mac-syphon/syphon-framework
 	url = https://github.com/palana/Syphon-Framework.git
 [submodule "plugins/enc-amf"]
 	path = plugins/enc-amf
-	url = https://github.com/Xaymar/OBS-AMD-Advanced-Media-Framework.git
+	url = https://github.com/Xaymar/obs-studio_amf-encoder-plugin.git
 [submodule "plugins/obs-browser"]
 	path = plugins/obs-browser
 	url = https://github.com/kc5nra/obs-browser.git
+[submodule "plugins/obs-vst"]
+	path = plugins/obs-vst
+	url = https://github.com/DDRBoxman/obs-vst.git
diff --git a/.mailmap b/.mailmap
index 754acfd..46fd23e 100644
--- a/.mailmap
+++ b/.mailmap
@@ -3,3 +3,6 @@ Zachary Lund <admin at computerquip.com>
 Benjamin Klettbach <b.klettbach at gmail.com>
 BtbN <btbn at btbn.de>
 John Bradley <jrb at turrettech.com>
+HomeWorld <homeworld at gmail.com> hwdro <pdarvaru at yahoo.com>
+Michael Fabian Dirks <info at xaymar.com> <michael.dirks at xaymar.com>
+Martell Malone <martellmalone at gmail.com>
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..00376f9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,52 @@
+language: cpp
+
+env:
+  global:
+  # AWS S3 creds
+  # access key
+  - secure: "MfhOg+84yb4ZHB2tM8PIPFQX2Y+WLN0I0iiAgyLC4KaHPUoNOyloe9yk6OjV7Lj7SZWqTlQUsqHa8S9mOUswGIody1Ydglo4RvyGOKCd8I6b2ri/jE8qHVuD9sO+sNlIxq4YqqG/qReTsbSs2YEgLneZUCYLCk/fihl8L6eVuSc="
+  # secret
+  - secure: "JRQVU2zgC3hY6CEY+Crmh/upp93En0BzKaLcsuBT538johNlK7m5hn3m2UOw63seLvBvVaKKWUDj9N986a3DwcXxWPMyF/9ctXgNWy39WzaVWxrbVR5nQB1fdiRp5YEgkoVN+gEm3OVF7sV5AGzh5/8CvEdRCoTLIGgMGHxW9mc="
+
+matrix:
+  include:
+    - os: osx
+      env:
+       - CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake
+       - CEF_BUILD_VERSION=3.2987.1588.g1952835
+      before_install: "./CI/install-dependencies-osx.sh"
+      before_script: "./CI/before-script-osx.sh"
+      before_deploy: "./CI/before-deploy-osx.sh"
+
+    - os: linux
+      dist: trusty
+      sudo: required
+      before_install: "./CI/install-dependencies-linux.sh"
+      before_script: "./CI/before-script-linux.sh"
+
+script: cd ./build && make -j4 && cd -
+
+deploy:
+  provider: s3
+  access_key_id: $AWS_ACCESS_KEY
+  secret_access_key: $AWS_SECRET_KEY
+  skip_cleanup: true
+  local_dir: nightly
+  bucket: obs-nightly
+  region: us-west-2
+  acl: public_read
+  on:
+    repo: jp9000/obs-studio
+    condition: "$TRAVIS_OS_NAME = osx"
+    all_branches: true
+
+# The channel name "azubu.il.us.quakenet.org#obs-dev" is encrypted against jp9000/obs-studio to prevent IRC spam of forks
+notifications:
+  irc:
+    skip_join: false
+    template:
+      - "[Travis CI|%{result}] %{repository_name}/%{branch} (%{author} - %{commit_subject}) %{build_url}"
+    channels:
+      - secure: k9j7+ogVODMlveZdd5pP73AVLCFl1VbzVaVon0ECn3EQcxnLSpiZbc6l+PnIUKgee5pRKtUB4breufgmr4puq3s69YeQiOVKk5gx2yJGZ5jGacbSne0xTspzPxapiEbVUkcJ2L7gKntDG4+SUiW67dtt4G26O7zsErDF/lY/woQ=
+    on_failure: always
+    on_success: change
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..5ca5194
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,477 @@
+Contributors are sorted by their amount of commits / translated strings.
+
+Contributors:
+Jim
+Palana
+fryshorts
+BtbN
+John Bradley
+Gol-D-Ace
+Colin Edwards
+Richard Stanway
+Zachary Lund
+Michael Fabian Dirks
+Martell Malone
+Christoph Hohmann
+HomeWorld
+cg2121
+dodgepong
+derrod
+Ryan Foster
+Radzaquiel
+Socapex
+Skyler Lipthay
+SuslikV
+Arkkis
+Cephas Reis
+GoaLitiuM
+Danni
+Jess Mayo
+Kris Moore
+Carl Fürstenberg
+juvester
+Anry
+CoDEmanX
+Ján Mlynek
+Manuel Kroeber
+sorayuki
+Alexandre Vicenzi
+Benjamin Klettbach
+bl
+Bl00drav3n
+Blackhive
+Charles Ray Shisler III
+Jeremiah Senkpiel
+John R. Bradley
+Kilian von Pflugk
+Serge Paquet
+shiina424
+shousa
+Timo Gurr
+adray
+Andrei Nistor
+Andrew Surzhynskyi
+Azat Khasanshin
+Ben Torell
+bootkiller
+Brian S. Stephan
+Eric Bataille
+Joseph El-Khouri
+jpk
+Kurt Kartaltepe
+Lexsus
+Lionheart Zhang
+paibox
+Robin Hielscher
+skwerlman
+taesheren
+Take Vos
+Taylor Blau
+Warren Turkal
+yogpstop
+Aarni Koskela
+Aesen Vismea
+Akagi201
+Alexander Uhlmann
+Alexandre Biny
+Andreas Reischuck
+Anthony Catel
+Anthony Super
+Asgeir Mortensen
+Autumin
+Aydin Akan
+Bernd Buschinski
+bla
+boombatower
+Caitlin Potter
+Caleb Anderson
+CallumHoward
+Cam
+CommanderRoot
+Copy Liu
+cryptonaut
+Dan Dascalescu
+David Cooper
+David McMackins II
+dennis
+Derrick Lambert
+Emil Sayahi
+EpicCoder
+Ethan Lee
+Frank Gehann
+Giorgio Pellero
+Grigorii Chirkov
+Guillermo A. Amaral
+Gökberk Yaltıraklı
+Haden F
+Iblis Lin
+Jake Probst
+Jamy Timmermans
+Jimmy Berry
+Jkoan
+Joel Bethke
+Julian Miller
+Kazuki Oishi
+ka’imi
+Kevin
+Kevin Tardif
+Lasse Dalegaard
+lemmi
+Lioncash
+Lucian Poston
+Lukas Monka
+Luke Yelavich
+mape
+Marc Chambers
+Mark Vaughn
+Mathias Panzenböck
+Matthew McNamara
+MedicMomcilo
+michael bishop
+Michael Hoang
+Momcilo Medic
+nd
+Nicolas F
+Night
+Olle Kelderman
+pantonvich
+partouf
+Peter SZTANOJEV
+pipll
+raincomplex
+repeat
+Ricardo Constantino
+Rodrigo Ipince
+rpslack
+Ryan Sullivan
+sam8641
+Seth Murphy
+Seung-Woo Kim
+Simon
+Teemu Kauhanen
+thekrzos
+Thomas McGrew
+TotalCaesar659
+vic
+vividnightmare
+VodBox
+wayne wang
+Weikardzaena
+Will Jamieson
+William Casarin
+Younes SERRAJ
+Ziemas
+
+Translations:
+Arabic
+    Abdullah AL-Qahtani (Za7ef_SA)
+    majdcomp
+    ZILZAL
+    BWU Wheelman (Wheelman)
+    Saleh Luxmaroc (salehoukiki)
+    Gol D. Ace (goldace)
+    معتصم دعنا (rozana-media)
+    chaironeko
+    dodgepong
+    FC Barcelona HD (kurdnews)
+Basque
+    Alexander Gabilondo (alexgabi)
+    Xabier Aramendi (azpidatziak)
+    Osoitz
+    txaro
+    etxondoko
+    Gol D. Ace (goldace)
+    dodgepong
+Bulgarian
+    kalmarin
+    Seyhan Halil (yildirim17)
+    Viktor Kitov (viktorkitov)
+    Stanislav_Evtimov
+    Ivan (SKDown)
+Catalan
+    Jaime Muñoz Martín (jmmartin_5)
+    jmontane
+    Nil Campamà (Soifam)
+    Aleix Vidal i Gaya (leixet)
+    Gol D. Ace (goldace)
+Chinese Simplified
+    Bob Liu (Akagi201)
+    PabloLiu (719018105)
+    Sasasu
+    cai_miao
+    David Kuo (s50407s)
+    Boyuan Yang (073plan)
+    鲜童 (xiananjyzy)
+    copyliu
+    wwj402_github
+    Bing Feng (fengbing123)
+    dodgepong
+    WaterOtaku
+Chinese Traditional
+    TzeKei Lee (chikei)
+    dodgepong
+    Julian_Lai
+    Chien-Yu Lin (u900011)
+    David Kuo (s50407s)
+    You-Ruei Tzeng (e222et)
+    Inndy.Lin (inndy)
+    Meng Hao Li (GazCore)
+    Gol D. Ace (goldace)
+    Watson Tsai (ashaneba)
+    cai_miao
+    Jimmy Huang (f56112000)
+    chaironeko
+    tomoe-musashi
+Croatian
+    medicmomcilo
+    Gol D. Ace (goldace)
+    dodgepong
+Czech
+    Jirka 'Venty' Michel (VentyCZ)
+    Sawanyo
+    dodgepong
+    Kiznoh
+Danish
+    Jens Hyllegaard (Hyllegaard)
+    Anders G. Jørgensen (spirit55555)
+    MaltahlGaming (maltahlgaming)
+    NCAA
+    Anders Urban (minikaliffen)
+    Christian Henriksen (cnhenriksen)
+    Gol D. Ace (goldace)
+    Johan Keller Jensen (JKeller)
+Dutch
+    Eric Bataille (ThoNohT)
+    Michel Snippe (michelsnippe)
+    Nicole (NIsengo)
+    Jasper J (JassieJ)
+    Gol D. Ace (goldace)
+    JorRy
+Estonian
+    MartinEwing
+    AndresTraks
+Finnish
+    ArkkisN (j)
+    dodgepong
+    Jarska
+    Jarppi (Jarppi01)
+    Gol D. Ace (goldace)
+    chaironeko
+French
+    radzaquiel
+    Yberion
+    Nunzio Conte (nunzioconte54)
+    Stéphane Lepin (Palakis)
+    Léo (leeo97one)
+    DoK_-
+    BoboopTeam
+    DarkInFire
+    steve_fr
+    Grisou2907
+    McGuygnol
+    Gabriel Dugny (Gabigabigo)
+    Gol D. Ace (goldace)
+    dodgepong
+    chaironeko
+Galician
+    Xesús M. Mosquera Carregal (xesusmosquera)
+    Gol D. Ace (goldace)
+    chaironeko
+German
+    Gol D. Ace (goldace)
+    Michael Fabian Dirks (Xaymar)
+    dodgepong
+    Benjamin Klettbach (benklett)
+    Sven Kirschbaum (fallobst22) (fallobst22)
+    random31415
+    Palana
+    Dennis Giebert (Isegrim) (isegrimderwolf)
+    Jonathan (macburgerjunior)
+    Robin Hielscher (Jack0r)
+    BoJustus
+    Jonas Otto (jottosmail)
+    mdod
+    Prince_of_Raop
+    Tiim
+    Tim (robske_110) (robske110)
+    WurstOnAir
+Greek
+    Mepharees
+    Tasos Sahanidis (tatokis)
+    Alex Kalles (alexakis1997)
+    iosifidis
+    chaironeko
+    dodgepong
+Hebrew
+    amirsher
+    Chemi
+    epic_ziver_D
+Hungarian
+    Gige
+    Adam Liszkai (adamos42)
+    dodgepong
+    Gol D. Ace (goldace)
+Italian
+    LordShadow95
+    Marocco2
+    dodgepong
+    Edoardo Macrì (edomacri)
+    smart2128
+    Edoardo “OfficialDJMela” Macrì (agersforum)
+    ScemEnzo
+    Fisherozzo
+    Gol D. Ace (goldace)
+    Sergio Beneduce (sbeneduce)
+    SkyLion
+Japanese
+    shousa
+    Kenta (kenta0644)
+    dodgepong
+    chaironeko
+Korean
+    Wonjoo Noh (ynetwork)
+    Gol D. Ace (goldace)
+    antome
+Lithuanian
+    Justas Vilimas (tyntas)
+Malay
+    amsyar ZeRo (amsyarminer555)
+    dodgepong
+Norwegian Bokmal
+    Taesh (magnusmbratteng)
+    dodgepong
+    mgKaiztra
+    Tommy (nwgat)
+    Oddbjørn Grytdal (Fooshi)
+    Decicus
+    Gol D. Ace (goldace)
+    areedw
+    Legend27
+    chaironeko
+    Mats Andreassen (MatsA)
+Pirate English
+    Matthew Hatcher (MatthewSH)
+    jkcoaster
+    Charlie W. (wallichc)
+    iltrof
+    chaironeko
+    Gol D. Ace (goldace)
+Polish
+    grocal
+    Michał Durak (micechal)
+    Damian Korcz (damikiller)
+    opl
+    Gol D. Ace (goldace)
+    dodgepong
+    Mateusz (Silesianek)
+    Michał Lewczak (michal200507)
+Portuguese
+    André Biscaia (LazP)
+    dodgepong
+    joaoboia
+    Gol D. Ace (goldace)
+Portuguese, Brazilian
+    Ramon Mendes (rbrgameplays)
+    Fabio Madia (Shaolin)
+    Burkes
+    TFSThiagoBR98
+    CaioWzy
+    clr0dr1g
+    aalonsomb
+    André Gama (ToeOficial)
+    Gol D. Ace (goldace)
+    dodgepong
+    ThisGuy
+Romanian
+    Cristian Silaghi (stelistcristi)
+    banrek
+    Hisashi
+    Gol D. Ace (goldace)
+    chaironeko
+    dodgepong
+Russian
+    iltrof
+    Alek Nirov (dectanova)
+    VNGXR
+    dodgepong
+    Pavel (Shevalie)
+    Maxim Gribanov (MaximGribanov)
+    Andy (anry025)
+    fromgate
+    Gol D. Ace (goldace)
+    Andrei Stepanov (adem4ik)
+    Vlad (KoTmaxHo)
+    Bugo
+    Mixaill
+    Sergei Fug1t1v3 (fug)
+    Walt Gee (vovanych)
+    Sigge Stjärnholm (Kladdy)
+    Yuri Mihaqlov (yurijmi)
+Serbian (Cyrillic)
+    medicmomcilo
+    Gol D. Ace (goldace)
+Serbian (Latin)
+    medicmomcilo
+    Gol D. Ace (goldace)
+    dodgepong
+Slovak
+    Ján M (longmoped)
+    Anton Lokaj (anlo)
+    LoLLy Nka (lollynka279)
+Slovenian
+    kristjan.krusic (krusic22)
+    ArcaneWater
+    Gol D. Ace (goldace)
+    dodgepong
+Spanish
+    Roberto Lorenzo (HonzoNebro)
+    Marcos Vidal Martinez (M4RK22)
+    Jaime Martinez Rincon (mrjaime1999)
+    Jaime Muñoz Martín (jmmartin_5)
+    Maximiliano Schtroumpftech Pena-Roig (som2tokmynam)
+    Eleazar Córcoles (MtrElee3)
+    Gol D. Ace (goldace)
+    Sigge Stjärnholm (Kladdy)
+    chaironeko
+    dodgepong
+    Rodrigo Ipince (ipince)
+    Rubén Pérez (RixzZ)
+Swedish
+    Anton R (FirePhoenix)
+    Sigge Stjärnholm (Kladdy)
+    Laccy IEST (Laccy)
+    Olle Dahström (odahlstrom)
+    Gustav Ekner (ekner)
+    Gol D. Ace (goldace)
+    Henrik Mattsson-MÃ¥rn (rchk)
+    chaironeko
+    Jonas Svensson (jonassanojj99)
+Tamil
+    Kolappan Nathan (kolappannathan)
+Thai
+    sakuhanachan* (sakuhanachanloli)
+    盛凤阁 (execzero)
+    nongnoobjung (kitcharuk_4)
+    dodgepong
+Turkish
+    Ali Kömesöğütlü (Mobile46) (byzlo685)
+    omer.karagoz (mrkaragoz)
+    monolifed
+    Cemal Dursun (cmldrs)
+    Savas Tokmak (Laserist)
+    Murat Karagöz (anemon_1994)
+    gecebekcisi1
+    Gol D. Ace (goldace)
+    Hydroboost
+    mustafaa
+Ukrainian
+    SuslikV
+    Юрій (Devinit)
+    Andy (anry025)
+    Maksym Tymoshyk (maximillian_)
+Vietnamese
+    Johnny “max20091” Utah (boostyourprogram)
+    HÆ°ng Nguyá»…n (hoyostudio)
+    Hà Phi Hùng (haphihungcom)
+    dodgepong
+    NCAA
diff --git a/CI/before-deploy-osx.sh b/CI/before-deploy-osx.sh
new file mode 100755
index 0000000..f427b36
--- /dev/null
+++ b/CI/before-deploy-osx.sh
@@ -0,0 +1,56 @@
+hr() {
+  echo "───────────────────────────────────────────────────"
+  echo $1
+  echo "───────────────────────────────────────────────────"
+}
+
+# Exit if something fails
+set -e
+
+# Generate file name variables
+export GIT_HASH=$(git rev-parse --short HEAD)
+export FILE_DATE=$(date +%Y-%m-%d.%H:%M:%S)
+export FILENAME=$FILE_DATE-$GIT_HASH-$TRAVIS_BRANCH-osx.pkg
+
+cd ./build
+
+# Move the CEF plugin out before running build_app so that it doesn't get packaged twice
+hr "Moving CEF out to preserve linking"
+mv ./rundir/RelWithDebInfo/obs-plugins/CEF.app ./
+mv ./rundir/RelWithDebInfo/obs-plugins/obs-browser.so ./
+
+# Package everything into a nice .app
+hr "Packaging .app"
+STABLE=false
+if [ -n "${TRAVIS_TAG}" ]; then
+  STABLE=true
+fi
+
+sudo python ../CI/install/osx/build_app.py --public-key ../CI/install/osx/OBSPublicDSAKey.pem --sparkle-framework ../../sparkle/Sparkle.framework --base-url "https://obsproject.com/osx_update" --stable=$STABLE
+
+# Move the CEF plugin back to where it belongs
+hr "Moving CEF back"
+mv ./CEF.app ./rundir/RelWithDebInfo/obs-plugins/
+mv ./obs-browser.so ./rundir/RelWithDebInfo/obs-plugins/
+
+# Package app
+hr "Generating .pkg"
+packagesbuild ../CI/install/osx/CMakeLists.pkgproj
+
+# Signing stuff
+hr "Decrypting Cert"
+openssl aes-256-cbc -K $encrypted_dd3c7f5e9db9_key -iv $encrypted_dd3c7f5e9db9_iv -in ../CI/osxcert/Certificates.p12.enc -out Certificates.p12 -d
+hr "Creating Keychain"
+security create-keychain -p mysecretpassword build.keychain
+security default-keychain -s build.keychain
+security unlock-keychain -p mysecretpassword build.keychain
+security set-keychain-settings -t 3600 -u build.keychain
+hr "Importing certs into keychain"
+security import ./Certificates.p12 -k build.keychain -T /usr/bin/productsign -P ""
+hr "Signing Package"
+productsign --sign 'Developer ID Installer: Hugh Bailey (2MMRE5MTB8)' ./OBS.pkg ./$FILENAME
+
+# Move to the folder that travis uses to upload artifacts from
+hr "Moving package to nightly folder for distribution"
+mkdir ../nightly
+sudo mv ./$FILENAME ../nightly
diff --git a/CI/before-deploy-win.cmd b/CI/before-deploy-win.cmd
new file mode 100644
index 0000000..2be9c5f
--- /dev/null
+++ b/CI/before-deploy-win.cmd
@@ -0,0 +1,3 @@
+xcopy /e C:\projects\obs-studio\build32\rundir\RelWithDebInfo C:\projects\obs-studio\build\
+robocopy C:\projects\obs-studio\build64\rundir\RelWithDebInfo C:\projects\obs-studio\build\ /E /XC /XN /XO
+7z a build.zip C:\projects\obs-studio\build\*
\ No newline at end of file
diff --git a/CI/before-script-linux.sh b/CI/before-script-linux.sh
new file mode 100755
index 0000000..7a42daa
--- /dev/null
+++ b/CI/before-script-linux.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+set -ex
+
+mkdir build && cd build
+cmake ..
diff --git a/CI/before-script-osx.sh b/CI/before-script-osx.sh
new file mode 100755
index 0000000..922816b
--- /dev/null
+++ b/CI/before-script-osx.sh
@@ -0,0 +1,3 @@
+mkdir build
+cd build
+cmake -DENABLE_SPARKLE_UPDATER=ON -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 -DDepsPath=/tmp/obsdeps -DVLCPath=$PWD/../../vlc-master -DBUILD_BROWSER=ON -DCEF_ROOT_DIR=$PWD/../../cef_binary_${CEF_BUILD_VERSION}_macosx64 ..
diff --git a/CI/install-dependencies-linux.sh b/CI/install-dependencies-linux.sh
new file mode 100755
index 0000000..134756b
--- /dev/null
+++ b/CI/install-dependencies-linux.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+set -ex
+
+sudo add-apt-repository ppa:kirillshkrogalev/ffmpeg-next -y
+sudo apt-get -qq update
+sudo apt-get install -y \
+        build-essential \
+        checkinstall \
+        cmake \
+        libasound2-dev \
+        libavcodec-ffmpeg-dev \
+        libavdevice-ffmpeg-dev \
+        libavfilter-ffmpeg-dev \
+        libavformat-ffmpeg-dev \
+        libavutil-ffmpeg-dev \
+        libcurl4-openssl-dev \
+        libfontconfig-dev \
+        libfreetype6-dev \
+        libgl1-mesa-dev \
+        libjack-jackd2-dev \
+        libjansson-dev \
+        libpulse-dev \
+        libqt5x11extras5-dev \
+        libspeexdsp-dev \
+        libswresample-ffmpeg-dev \
+        libswscale-ffmpeg-dev \
+        libudev-dev \
+        libv4l-dev \
+        libvlc-dev \
+        libx11-dev \
+        libx264-dev \
+        libxcb-shm0-dev \
+        libxcb-xinerama0-dev \
+        libxcomposite-dev \
+        libxinerama-dev \
+        pkg-config \
+        qtbase5-dev
diff --git a/CI/install-dependencies-osx.sh b/CI/install-dependencies-osx.sh
new file mode 100755
index 0000000..69c71e9
--- /dev/null
+++ b/CI/install-dependencies-osx.sh
@@ -0,0 +1,42 @@
+# Exit if something fails
+set -e
+
+git fetch --tags
+
+# Leave obs-studio folder
+cd ../
+
+# Install Packages app so we can build a package later
+# http://s.sudre.free.fr/Software/Packages/about.html
+curl -L -O https://s3-us-west-2.amazonaws.com/obs-nightly/Packages.pkg -f --retry 5 -C -
+sudo installer -pkg ./Packages.pkg -target /
+
+brew update
+
+#Base OBS Deps
+brew install qt5 jack speexdsp
+
+# Fetch and untar prebuilt OBS deps that are compatible with older versions of OSX
+curl -L -O https://s3-us-west-2.amazonaws.com/obs-nightly/osx-deps.tar.gz -f --retry 5 -C -
+tar -xf ./osx-deps.tar.gz -C /tmp
+
+# Fetch vlc codebase
+curl -L -o vlc-master.zip https://github.com/videolan/vlc/archive/master.zip -f --retry 5 -C -
+unzip -q ./vlc-master.zip
+
+# Get sparkle
+curl -L -o ./sparkle.tar.bz2 https://github.com/sparkle-project/Sparkle/releases/download/1.16.0/Sparkle-1.16.0.tar.bz2
+mkdir ./sparkle
+tar -xf ./sparkle.tar.bz2 -C ./sparkle
+sudo cp -R ./sparkle/Sparkle.framework /Library/Frameworks/Sparkle.framework
+
+# CEF Stuff
+curl -kLO https://obs-nightly.s3-us-west-2.amazonaws.com/cef_binary_${CEF_BUILD_VERSION}_macosx64.tar.bz2 -f --retry 5 -C -
+tar -xf ./cef_binary_${CEF_BUILD_VERSION}_macosx64.tar.bz2
+cd ./cef_binary_${CEF_BUILD_VERSION}_macosx64
+mkdir build
+cd ./build
+cmake -DCMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++" -DCMAKE_EXE_LINKER_FLAGS="-std=c++11 -stdlib=libc++" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 ..
+make -j4
+mkdir libcef_dll
+cd ../../
diff --git a/CI/install/osx/CMakeLists.pkgproj b/CI/install/osx/CMakeLists.pkgproj
new file mode 100644
index 0000000..eff607a
--- /dev/null
+++ b/CI/install/osx/CMakeLists.pkgproj
@@ -0,0 +1,1026 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PACKAGES</key>
+	<array>
+		<dict>
+			<key>PACKAGE_FILES</key>
+			<dict>
+				<key>DEFAULT_INSTALL_LOCATION</key>
+				<string>/</string>
+				<key>HIERARCHY</key>
+				<dict>
+					<key>CHILDREN</key>
+					<array>
+						<dict>
+							<key>CHILDREN</key>
+							<array>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>80</integer>
+									<key>PATH</key>
+									<string>../../../build/OBS.app</string>
+									<key>PATH_TYPE</key>
+									<integer>3</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>3</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>80</integer>
+									<key>PATH</key>
+									<string>Utilities</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+							</array>
+							<key>GID</key>
+							<integer>80</integer>
+							<key>PATH</key>
+							<string>Applications</string>
+							<key>PATH_TYPE</key>
+							<integer>0</integer>
+							<key>PERMISSIONS</key>
+							<integer>509</integer>
+							<key>TYPE</key>
+							<integer>1</integer>
+							<key>UID</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>CHILDREN</key>
+							<array>
+								<dict>
+									<key>CHILDREN</key>
+									<array>
+										<dict>
+											<key>CHILDREN</key>
+											<array>
+												<dict>
+													<key>CHILDREN</key>
+													<array>
+														<dict>
+															<key>CHILDREN</key>
+															<array>
+																<dict>
+																	<key>CHILDREN</key>
+																	<array>
+																		<dict>
+																			<key>CHILDREN</key>
+																			<array/>
+																			<key>GID</key>
+																			<integer>80</integer>
+																			<key>PATH</key>
+																			<string>../../../build/plugins/obs-browser/CEF.app</string>
+																			<key>PATH_TYPE</key>
+																			<integer>3</integer>
+																			<key>PERMISSIONS</key>
+																			<integer>493</integer>
+																			<key>TYPE</key>
+																			<integer>3</integer>
+																			<key>UID</key>
+																			<integer>0</integer>
+																		</dict>
+																		<dict>
+																			<key>CHILDREN</key>
+																			<array/>
+																			<key>GID</key>
+																			<integer>80</integer>
+																			<key>PATH</key>
+																			<string>../../../build/plugins/obs-browser/obs-browser.so</string>
+																			<key>PATH_TYPE</key>
+																			<integer>3</integer>
+																			<key>PERMISSIONS</key>
+																			<integer>493</integer>
+																			<key>TYPE</key>
+																			<integer>3</integer>
+																			<key>UID</key>
+																			<integer>0</integer>
+																		</dict>
+																	</array>
+																	<key>GID</key>
+																	<integer>80</integer>
+																	<key>PATH</key>
+																	<string>bin</string>
+																	<key>PATH_TYPE</key>
+																	<integer>0</integer>
+																	<key>PERMISSIONS</key>
+																	<integer>493</integer>
+																	<key>TYPE</key>
+																	<integer>2</integer>
+																	<key>UID</key>
+																	<integer>0</integer>
+																</dict>
+															</array>
+															<key>GID</key>
+															<integer>80</integer>
+															<key>PATH</key>
+															<string>obs-browser</string>
+															<key>PATH_TYPE</key>
+															<integer>0</integer>
+															<key>PERMISSIONS</key>
+															<integer>493</integer>
+															<key>TYPE</key>
+															<integer>2</integer>
+															<key>UID</key>
+															<integer>0</integer>
+														</dict>
+													</array>
+													<key>GID</key>
+													<integer>80</integer>
+													<key>PATH</key>
+													<string>plugins</string>
+													<key>PATH_TYPE</key>
+													<integer>0</integer>
+													<key>PERMISSIONS</key>
+													<integer>493</integer>
+													<key>TYPE</key>
+													<integer>2</integer>
+													<key>UID</key>
+													<integer>0</integer>
+												</dict>
+											</array>
+											<key>GID</key>
+											<integer>80</integer>
+											<key>PATH</key>
+											<string>obs-studio</string>
+											<key>PATH_TYPE</key>
+											<integer>0</integer>
+											<key>PERMISSIONS</key>
+											<integer>493</integer>
+											<key>TYPE</key>
+											<integer>2</integer>
+											<key>UID</key>
+											<integer>0</integer>
+										</dict>
+									</array>
+									<key>GID</key>
+									<integer>80</integer>
+									<key>PATH</key>
+									<string>Application Support</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Documentation</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Filesystems</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Frameworks</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Input Methods</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Internet Plug-Ins</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>LaunchAgents</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>LaunchDaemons</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>PreferencePanes</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Preferences</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>80</integer>
+									<key>PATH</key>
+									<string>Printers</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>PrivilegedHelperTools</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>QuickLook</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>QuickTime</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Screen Savers</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Scripts</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Services</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Widgets</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+							</array>
+							<key>GID</key>
+							<integer>0</integer>
+							<key>PATH</key>
+							<string>Library</string>
+							<key>PATH_TYPE</key>
+							<integer>0</integer>
+							<key>PERMISSIONS</key>
+							<integer>493</integer>
+							<key>TYPE</key>
+							<integer>1</integer>
+							<key>UID</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>CHILDREN</key>
+							<array>
+								<dict>
+									<key>CHILDREN</key>
+									<array>
+										<dict>
+											<key>CHILDREN</key>
+											<array/>
+											<key>GID</key>
+											<integer>0</integer>
+											<key>PATH</key>
+											<string>Extensions</string>
+											<key>PATH_TYPE</key>
+											<integer>0</integer>
+											<key>PERMISSIONS</key>
+											<integer>493</integer>
+											<key>TYPE</key>
+											<integer>1</integer>
+											<key>UID</key>
+											<integer>0</integer>
+										</dict>
+									</array>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Library</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+							</array>
+							<key>GID</key>
+							<integer>0</integer>
+							<key>PATH</key>
+							<string>System</string>
+							<key>PATH_TYPE</key>
+							<integer>0</integer>
+							<key>PERMISSIONS</key>
+							<integer>493</integer>
+							<key>TYPE</key>
+							<integer>1</integer>
+							<key>UID</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>CHILDREN</key>
+							<array>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Shared</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>1023</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+							</array>
+							<key>GID</key>
+							<integer>80</integer>
+							<key>PATH</key>
+							<string>Users</string>
+							<key>PATH_TYPE</key>
+							<integer>0</integer>
+							<key>PERMISSIONS</key>
+							<integer>493</integer>
+							<key>TYPE</key>
+							<integer>1</integer>
+							<key>UID</key>
+							<integer>0</integer>
+						</dict>
+					</array>
+					<key>GID</key>
+					<integer>0</integer>
+					<key>PATH</key>
+					<string>/</string>
+					<key>PATH_TYPE</key>
+					<integer>0</integer>
+					<key>PERMISSIONS</key>
+					<integer>493</integer>
+					<key>TYPE</key>
+					<integer>1</integer>
+					<key>UID</key>
+					<integer>0</integer>
+				</dict>
+				<key>PAYLOAD_TYPE</key>
+				<integer>0</integer>
+				<key>VERSION</key>
+				<integer>2</integer>
+			</dict>
+			<key>PACKAGE_SCRIPTS</key>
+			<dict>
+				<key>POSTINSTALL_PATH</key>
+				<dict>
+					<key>PATH</key>
+					<string>post-install.sh</string>
+					<key>PATH_TYPE</key>
+					<integer>3</integer>
+				</dict>
+				<key>PREINSTALL_PATH</key>
+				<dict/>
+				<key>RESOURCES</key>
+				<array/>
+			</dict>
+			<key>PACKAGE_SETTINGS</key>
+			<dict>
+				<key>AUTHENTICATION</key>
+				<integer>1</integer>
+				<key>CONCLUSION_ACTION</key>
+				<integer>0</integer>
+				<key>IDENTIFIER</key>
+				<string>org.obsproject.pkg.obs-studio</string>
+				<key>NAME</key>
+				<string>OBS</string>
+				<key>OVERWRITE_PERMISSIONS</key>
+				<false/>
+				<key>VERSION</key>
+				<string>1.0</string>
+			</dict>
+			<key>UUID</key>
+			<string>19CCE3F2-8911-4364-B673-8B5BC3ABD4DA</string>
+		</dict>
+		<dict>
+			<key>PACKAGE_SETTINGS</key>
+			<dict>
+				<key>LOCATION</key>
+				<integer>0</integer>
+				<key>NAME</key>
+				<string>SyphonInject</string>
+			</dict>
+			<key>PATH</key>
+			<dict>
+				<key>PATH</key>
+				<string>SyphonInject.pkg</string>
+				<key>PATH_TYPE</key>
+				<integer>1</integer>
+			</dict>
+			<key>TYPE</key>
+			<integer>1</integer>
+			<key>UUID</key>
+			<string>0CC9C67E-4D14-4794-9930-019925513B1C</string>
+		</dict>
+	</array>
+	<key>PROJECT</key>
+	<dict>
+		<key>PROJECT_COMMENTS</key>
+		<dict>
+			<key>NOTES</key>
+			<data>
+			PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1M
+			IDQuMDEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQv
+			c3RyaWN0LmR0ZCI+CjxodG1sPgo8aGVhZD4KPG1ldGEgaHR0cC1l
+			cXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7
+			IGNoYXJzZXQ9VVRGLTgiPgo8bWV0YSBodHRwLWVxdWl2PSJDb250
+			ZW50LVN0eWxlLVR5cGUiIGNvbnRlbnQ9InRleHQvY3NzIj4KPHRp
+			dGxlPjwvdGl0bGU+CjxtZXRhIG5hbWU9IkdlbmVyYXRvciIgY29u
+			dGVudD0iQ29jb2EgSFRNTCBXcml0ZXIiPgo8bWV0YSBuYW1lPSJD
+			b2NvYVZlcnNpb24iIGNvbnRlbnQ9IjE1MDQuODEiPgo8c3R5bGUg
+			dHlwZT0idGV4dC9jc3MiPgo8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5
+			Pgo8L2JvZHk+CjwvaHRtbD4K
+			</data>
+		</dict>
+		<key>PROJECT_PRESENTATION</key>
+		<dict>
+			<key>BACKGROUND</key>
+			<dict>
+				<key>ALIGNMENT</key>
+				<integer>4</integer>
+				<key>BACKGROUND_PATH</key>
+				<dict>
+					<key>PATH</key>
+					<string>obs.png</string>
+					<key>PATH_TYPE</key>
+					<integer>1</integer>
+				</dict>
+				<key>CUSTOM</key>
+				<integer>1</integer>
+				<key>SCALING</key>
+				<integer>0</integer>
+			</dict>
+			<key>INSTALLATION TYPE</key>
+			<dict>
+				<key>HIERARCHIES</key>
+				<dict>
+					<key>INSTALLER</key>
+					<dict>
+						<key>LIST</key>
+						<array>
+							<dict>
+								<key>DESCRIPTION</key>
+								<array/>
+								<key>OPTIONS</key>
+								<dict>
+									<key>HIDDEN</key>
+									<false/>
+									<key>STATE</key>
+									<integer>0</integer>
+								</dict>
+								<key>PACKAGE_UUID</key>
+								<string>19CCE3F2-8911-4364-B673-8B5BC3ABD4DA</string>
+								<key>REQUIREMENTS</key>
+								<array/>
+								<key>TITLE</key>
+								<array/>
+								<key>TOOLTIP</key>
+								<array/>
+								<key>TYPE</key>
+								<integer>0</integer>
+								<key>UUID</key>
+								<string>7C540711-59F4-479C-9CFD-8C4D6594992E</string>
+							</dict>
+							<dict>
+								<key>DESCRIPTION</key>
+								<array/>
+								<key>OPTIONS</key>
+								<dict>
+									<key>HIDDEN</key>
+									<false/>
+									<key>STATE</key>
+									<integer>1</integer>
+								</dict>
+								<key>PACKAGE_UUID</key>
+								<string>0CC9C67E-4D14-4794-9930-019925513B1C</string>
+								<key>REQUIREMENTS</key>
+								<array/>
+								<key>TITLE</key>
+								<array/>
+								<key>TOOLTIP</key>
+								<array/>
+								<key>TYPE</key>
+								<integer>0</integer>
+								<key>UUID</key>
+								<string>BBDE08F6-D7EE-47CB-881F-7F208B3A604B</string>
+							</dict>
+						</array>
+						<key>REMOVED</key>
+						<dict/>
+					</dict>
+				</dict>
+				<key>INSTALLATION TYPE</key>
+				<integer>0</integer>
+				<key>MODE</key>
+				<integer>0</integer>
+			</dict>
+			<key>INSTALLATION_STEPS</key>
+			<array>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewIntroductionController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>Introduction</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewReadMeController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>ReadMe</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewLicenseController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>License</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewDestinationSelectController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>TargetSelect</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewInstallationTypeController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>PackageSelection</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewInstallationController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>Install</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewSummaryController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>Summary</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+			</array>
+			<key>INTRODUCTION</key>
+			<dict>
+				<key>LOCALIZATIONS</key>
+				<array/>
+			</dict>
+			<key>LICENSE</key>
+			<dict>
+				<key>KEYWORDS</key>
+				<dict/>
+				<key>LOCALIZATIONS</key>
+				<array/>
+				<key>MODE</key>
+				<integer>0</integer>
+			</dict>
+			<key>README</key>
+			<dict>
+				<key>LOCALIZATIONS</key>
+				<array/>
+			</dict>
+			<key>SUMMARY</key>
+			<dict>
+				<key>LOCALIZATIONS</key>
+				<array/>
+			</dict>
+			<key>TITLE</key>
+			<dict>
+				<key>LOCALIZATIONS</key>
+				<array>
+					<dict>
+						<key>LANGUAGE</key>
+						<string>English</string>
+						<key>VALUE</key>
+						<string>OBS</string>
+					</dict>
+				</array>
+			</dict>
+		</dict>
+		<key>PROJECT_REQUIREMENTS</key>
+		<dict>
+			<key>LIST</key>
+			<array/>
+			<key>POSTINSTALL_PATH</key>
+			<dict/>
+			<key>PREINSTALL_PATH</key>
+			<dict/>
+			<key>RESOURCES</key>
+			<array/>
+			<key>ROOT_VOLUME_ONLY</key>
+			<false/>
+		</dict>
+		<key>PROJECT_SETTINGS</key>
+		<dict>
+			<key>ADVANCED_OPTIONS</key>
+			<dict/>
+			<key>BUILD_FORMAT</key>
+			<integer>0</integer>
+			<key>BUILD_PATH</key>
+			<dict>
+				<key>PATH</key>
+				<string>../../../build</string>
+				<key>PATH_TYPE</key>
+				<integer>3</integer>
+			</dict>
+			<key>EXCLUDED_FILES</key>
+			<array>
+				<dict>
+					<key>PATTERNS_ARRAY</key>
+					<array>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.DS_Store</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+					</array>
+					<key>PROTECTED</key>
+					<true/>
+					<key>PROXY_NAME</key>
+					<string>Remove .DS_Store files</string>
+					<key>PROXY_TOOLTIP</key>
+					<string>Remove ".DS_Store" files created by the Finder.</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+				<dict>
+					<key>PATTERNS_ARRAY</key>
+					<array>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.pbdevelopment</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+					</array>
+					<key>PROTECTED</key>
+					<true/>
+					<key>PROXY_NAME</key>
+					<string>Remove .pbdevelopment files</string>
+					<key>PROXY_TOOLTIP</key>
+					<string>Remove ".pbdevelopment" files created by ProjectBuilder or Xcode.</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+				<dict>
+					<key>PATTERNS_ARRAY</key>
+					<array>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>CVS</string>
+							<key>TYPE</key>
+							<integer>1</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.cvsignore</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.cvspass</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.svn</string>
+							<key>TYPE</key>
+							<integer>1</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.git</string>
+							<key>TYPE</key>
+							<integer>1</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.gitignore</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+					</array>
+					<key>PROTECTED</key>
+					<true/>
+					<key>PROXY_NAME</key>
+					<string>Remove SCM metadata</string>
+					<key>PROXY_TOOLTIP</key>
+					<string>Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems.</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+				<dict>
+					<key>PATTERNS_ARRAY</key>
+					<array>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>classes.nib</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>designable.db</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>info.nib</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+					</array>
+					<key>PROTECTED</key>
+					<true/>
+					<key>PROXY_NAME</key>
+					<string>Optimize nib files</string>
+					<key>PROXY_TOOLTIP</key>
+					<string>Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles.</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+				<dict>
+					<key>PATTERNS_ARRAY</key>
+					<array>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>Resources Disabled</string>
+							<key>TYPE</key>
+							<integer>1</integer>
+						</dict>
+					</array>
+					<key>PROTECTED</key>
+					<true/>
+					<key>PROXY_NAME</key>
+					<string>Remove Resources Disabled folders</string>
+					<key>PROXY_TOOLTIP</key>
+					<string>Remove "Resources Disabled" folders.</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+				<dict>
+					<key>SEPARATOR</key>
+					<true/>
+				</dict>
+			</array>
+			<key>NAME</key>
+			<string>OBS</string>
+		</dict>
+	</dict>
+	<key>TYPE</key>
+	<integer>0</integer>
+	<key>VERSION</key>
+	<integer>2</integer>
+</dict>
+</plist>
diff --git a/CI/install/osx/OBSPublicDSAKey.pem b/CI/install/osx/OBSPublicDSAKey.pem
new file mode 100644
index 0000000..91adb40
--- /dev/null
+++ b/CI/install/osx/OBSPublicDSAKey.pem
@@ -0,0 +1,36 @@
+-----BEGIN PUBLIC KEY-----
+MIIGPDCCBC4GByqGSM44BAEwggQhAoICAQCZZZ2y7H2GJmMfP4KQihJTJOoiGNUw
+mue6sqMbH+utRykRnSKBZux6R665eRFMpNgrgFO1TLLGbdD2U31KiGtCvFJOmOl3
++QP055BuXjEG36NU7AWEFLAlbDlr/2D3oumq3Ib3iMnnr9RrVztJ2VFOvVio1eWr
+ZxboVwKPK8D6BqsWiv15vbYlJnTC4Fls6ySmdjVBxwoPlTaMu1ysi5DfbIZ93s5u
+aQt1FvXuWtPBWjyVUORcNbcWf49E5R2pV0OSBK95Hw2/wXz4vmj+w92dTePGnVaW
+Me4CoF5PIeZILwp6DCLStX4eW2WG1NChJTC8zeQ/3bMMoGyKM/MadyvrDqMywsKY
+caxkIwHrDKOEdXXGo80dIwZMMLipPA8DKhx5ojphfkeXjIhKSx+49knXT3ED5okE
+Wai7tGUXj/8D8sGh+7b+AVsdujvr4v8WQaZiKUOZ2IIHOg3VLz9T9v0zet1Yt987
+KNymFcp2CHeJ6KnDP/ZGQ6Nl0HsPxUgscsXV+R2FEc8Q1j0Ukkuxnopa0E4/huUu
+gjyRzpXD734qFMDf7LcXca6qNjBor6gVj5sRyRKCpZ+KQfMUlr8jp506ztYSyeJu
+dxJV30tQgztwkbrs02CqOt4Z3Peo6sdht7hWKSPVwmja3tq8/TfUSSoo6wKYN9/w
+Mf3dVeRF8hCzJQIVAJnzuzmzQhCKPiQnl3jh5qGII2XfAoICAQCCVATAff89ceHj
+ROHEbHTQFpVxJ/kRZPfxnU46DSw79Tih7tthV68oakPSOTP3cx/Tga0GwogarZ9N
+F2VVan5w9OQSSewXsr5UDT5bnmJF+h+JB7TMy+sXZBYobUqjlUd5VtKc8RsN86P4
+s7xbK0mA+hfe+27r18JT81/eH3xUfh7UOUGSdMN2Ch9f7RFSMZIgUAZUzu2K3ODp
+hPgtc2QJ8QVAp7GLvQgw8ZUME/ChZslyBIyJvYgUIxfxlgRWYro5pQT7/ngkgdXo
+wlghHKkldwMuY3zaFdhPnFNuEUEtc18ILsbz0+AnagCUd6n+3safskCRqLIHMOY6
+iLBSZPX9hJQhVCqSqz1VNDDww8FNa/fojJ1Lr/TI0I+0Ib2pCiY2LChXUqGY5SLZ
+2KNs5qFsyZP+I0L8YsGwqvUYyFwk7Ok224n0NtaOwqpLCrtXd/i6DaDNiaoJuwJC
+1ELCfaZivorgkC5rhBt2H7qWUAR+EtrFE/gb0k/G5EIhjYql7onGbX+G2re38vQA
+fg1pzguhig2dafP/BxMLZrn1Gg61xzmEYPuS9gclktaf675srv8GVb46VkOxXL+D
+YvTmpJPP7UUOVlmAMCo4j4y09MW3jq9TDp42VTLeZVubyjslGnavlnq1O+ZyXUye
+1FMeby65sIbSHHHwoFnRv3hLSEXI5gOCAgYAAoICAQCUkYnZkPfHfOJZI403xUYP
+CE/bLpkza074Xo6EXElsWRnpQgNTx+JFOvItgj3v0OkIqDin9UredKOwfkiftslV
+jxUVKA6I5kwnGvCpvTpQMLyLjq+VQr+J2D6eId6tV/iajhdu5r4JThU8KllT7Ywb
+NAur34ftLNCVAMRUaDNeEoHfePgderW384e+lbvpmtifmBluammGSxxRtUsdjvJZ
+BFkhaJu86CKxcU7D1lbPVOtV/jaxz6d16VdGcfBdi2LzXZzZtYpT9XGPX3NF+xii
+spAURWsoe11LTRXF+eJhgCm5iIDN3kh1HEQKYKAVpmrcM0aFzk/NpS+tFyU72vaq
+IRSSJw/aa1oELOAakG5oPldc4RcYWl32sbnVwXHO7TZvgTrBSC10o65MAC5CHP/s
+b07heDYAIt7re7szvOYq+c/9zAMAlu3pcO8MqaXYMmybdHBXHQ2b+DdJWHmIUWcX
+CbUzr09vzGkJAvqsXqbmJPr8aixrO75DhT0iDTILLWe/GWK51nf+Tg0pNxVgGyAl
+BqvRqqo7SSDu9FMkwQesFFHhuoHLyEHwVPJ+sMQTNwQcm9c6YuW8EYDRSkeKLWYk
+3fkjG+Pe9uVE8a1taDg3FjSY0UqjUT6XMw+i0Lajyus2L6wFBwrrGM6E4xa6x1CC
+MGjmuSOlPA1umQsToIcO4g==
+-----END PUBLIC KEY-----
diff --git a/CI/install/osx/SyphonInject.pkg b/CI/install/osx/SyphonInject.pkg
new file mode 100644
index 0000000..4371acc
Binary files /dev/null and b/CI/install/osx/SyphonInject.pkg differ
diff --git a/CI/install/osx/build_app.py b/CI/install/osx/build_app.py
new file mode 100644
index 0000000..907e113
--- /dev/null
+++ b/CI/install/osx/build_app.py
@@ -0,0 +1,225 @@
+#!/usr/bin/env python
+ 
+candidate_paths = "bin obs-plugins data".split()
+ 
+plist_path = "../cmake/osxbundle/Info.plist"
+icon_path = "../cmake/osxbundle/obs.icns"
+run_path = "../cmake/osxbundle/obslaunch.sh"
+ 
+#not copied
+blacklist = """/usr /System""".split()
+ 
+#copied
+whitelist = """/usr/local""".split()
+ 
+#
+#
+#
+ 
+ 
+from sys import argv
+from glob import glob
+from subprocess import check_output, call
+from collections import namedtuple
+from shutil import copy, copytree, rmtree
+from os import makedirs, rename, walk, path as ospath
+import plistlib
+
+import argparse
+
+def _str_to_bool(s):
+    """Convert string to bool (in argparse context)."""
+    if s.lower() not in ['true', 'false']:
+        raise ValueError('Need bool; got %r' % s)
+    return {'true': True, 'false': False}[s.lower()]
+
+def add_boolean_argument(parser, name, default=False):                                                                                               
+    """Add a boolean argument to an ArgumentParser instance."""
+    group = parser.add_mutually_exclusive_group()
+    group.add_argument(
+        '--' + name, nargs='?', default=default, const=True, type=_str_to_bool)
+    group.add_argument('--no' + name, dest=name, action='store_false')
+
+parser = argparse.ArgumentParser(description='obs-studio package util')
+parser.add_argument('-d', '--base-dir', dest='dir', default='rundir/RelWithDebInfo')
+parser.add_argument('-n', '--build-number', dest='build_number', default='0')
+parser.add_argument('-k', '--public-key', dest='public_key', default='OBSPublicDSAKey.pem')
+parser.add_argument('-f', '--sparkle-framework', dest='sparkle', default=None)
+parser.add_argument('-b', '--base-url', dest='base_url', default='https://builds.catchexception.org/obs-studio')
+parser.add_argument('-u', '--user', dest='user', default='jp9000')
+parser.add_argument('-c', '--channel', dest='channel', default='master')
+add_boolean_argument(parser, 'stable', default=False)
+parser.add_argument('-p', '--prefix', dest='prefix', default='')
+args = parser.parse_args()
+
+def cmd(cmd):
+    import subprocess
+    import shlex
+    return subprocess.check_output(shlex.split(cmd)).rstrip('\r\n')
+
+LibTarget = namedtuple("LibTarget", ("path", "external", "copy_as"))
+ 
+inspect = list()
+ 
+inspected = set()
+ 
+build_path = args.dir
+build_path = build_path.replace("\\ ", " ")
+ 
+def add(name, external=False, copy_as=None):
+	if external and copy_as is None:
+		copy_as = name.split("/")[-1]
+	if name[0] != "/":
+		name = build_path+"/"+name
+	t = LibTarget(name, external, copy_as)
+	if t in inspected:
+		return
+	inspect.append(t)
+	inspected.add(t)
+
+
+for i in candidate_paths:
+	print("Checking " + i)
+	for root, dirs, files in walk(build_path+"/"+i):
+		for file_ in files:
+			path = root + "/" + file_
+			try:
+				out = check_output("{0}otool -L '{1}'".format(args.prefix, path), shell=True,
+						universal_newlines=True)
+				if "is not an object file" in out:
+					continue
+			except:
+				continue
+			rel_path = path[len(build_path)+1:]
+			print(repr(path), repr(rel_path))
+			add(rel_path)
+ 
+def add_plugins(path, replace):
+	for img in glob(path.replace(
+		"lib/QtCore.framework/Versions/5/QtCore",
+		"plugins/%s/*"%replace).replace(
+			"Library/Frameworks/QtCore.framework/Versions/5/QtCore",
+			"share/qt5/plugins/%s/*"%replace)):
+		if "_debug" in img:
+			continue
+		add(img, True, img.split("plugins/")[-1])
+
+actual_sparkle_path = '@loader_path/Frameworks/Sparkle.framework/Versions/A/Sparkle'
+
+while inspect:
+	target = inspect.pop()
+	print("inspecting", repr(target))
+	path = target.path
+	if path[0] == "@":
+		continue
+	out = check_output("{0}otool -L '{1}'".format(args.prefix, path), shell=True,
+			universal_newlines=True)
+ 
+	if "QtCore" in path:
+		add_plugins(path, "platforms")
+		add_plugins(path, "imageformats")
+		add_plugins(path, "accessible")
+ 
+ 
+	for line in out.split("\n")[1:]:
+		new = line.strip().split(" (")[0]
+		if '@' in new and "sparkle.framework" in new.lower():
+			actual_sparkle_path = new
+			print "Using sparkle path:", repr(actual_sparkle_path)
+		if not new or new[0] == "@" or new.endswith(path.split("/")[-1]):
+			continue
+		whitelisted = False
+		for i in whitelist:
+			if new.startswith(i):
+				whitelisted = True
+		if not whitelisted:
+			blacklisted = False
+			for i in blacklist:
+				if new.startswith(i):
+					blacklisted = True
+					break
+			if blacklisted:
+				continue
+		add(new, True)
+
+changes = list()
+for path, external, copy_as in inspected:
+	if not external:
+		continue #built with install_rpath hopefully
+	changes.append("-change '%s' '@rpath/%s'"%(path, copy_as))
+changes = " ".join(changes)
+
+info = plistlib.readPlist(plist_path)
+
+latest_tag = cmd('git describe --tags --abbrev=0')
+log = cmd('git log --pretty=oneline {0}...HEAD'.format(latest_tag))
+
+from os import path
+# set version
+if args.stable:
+    info["CFBundleVersion"] = latest_tag
+    info["CFBundleShortVersionString"] = latest_tag
+    info["SUFeedURL"] = '{0}/stable/updates.xml'.format(args.base_url)
+else:
+    info["CFBundleVersion"] = args.build_number
+    info["CFBundleShortVersionString"] = '{0}.{1}'.format(latest_tag, args.build_number)
+    info["SUFeedURL"] = '{0}/{1}/{2}/updates.xml'.format(args.base_url, args.user, args.channel)
+
+info["SUPublicDSAKeyFile"] = path.basename(args.public_key)
+info["OBSFeedsURL"] = '{0}/feeds.xml'.format(args.base_url)
+
+app_name = info["CFBundleName"]+".app"
+icon_file = "tmp/Contents/Resources/%s"%info["CFBundleIconFile"]
+
+copytree(build_path, "tmp/Contents/Resources/", symlinks=True)
+copy(icon_path, icon_file)
+plistlib.writePlist(info, "tmp/Contents/Info.plist")
+makedirs("tmp/Contents/MacOS")
+copy(run_path, "tmp/Contents/MacOS/%s"%info["CFBundleExecutable"])
+try:
+	copy(args.public_key, "tmp/Contents/Resources")
+except:
+	pass
+
+if args.sparkle is not None:
+    copytree(args.sparkle, "tmp/Contents/Frameworks/Sparkle.framework", symlinks=True)
+
+prefix = "tmp/Contents/Resources/"
+sparkle_path = '@loader_path/{0}/Frameworks/Sparkle.framework/Versions/A/Sparkle'
+
+cmd('{0}install_name_tool -change {1} {2} {3}/bin/obs'.format(
+    args.prefix, actual_sparkle_path, sparkle_path.format('../..'), prefix))
+
+
+
+for path, external, copy_as in inspected:
+	id_ = ""
+	filename = path
+	rpath = ""
+	if external:
+		id_ = "-id '@rpath/%s'"%copy_as
+		filename = prefix + "bin/" +copy_as
+		rpath = "-add_rpath @loader_path/ -add_rpath @executable_path/"
+		if "/" in copy_as:
+			try:
+				dirs = copy_as.rsplit("/", 1)[0]
+				makedirs(prefix + "bin/" + dirs)
+			except:
+				pass
+		copy(path, filename)
+	else:
+		filename = path[len(build_path)+1:]
+		id_ = "-id '@rpath/../%s'"%filename
+		if not filename.startswith("bin"):
+			print(filename)
+			rpath = "-add_rpath '@loader_path/{}/'".format(ospath.relpath("bin/", ospath.dirname(filename)))
+		filename = prefix + filename
+ 
+	cmd = "{0}install_name_tool {1} {2} {3} '{4}'".format(args.prefix, changes, id_, rpath, filename)
+	call(cmd, shell=True)
+
+try:
+	rename("tmp", app_name)
+except:
+	print("App already exists")
+	rmtree("tmp")
diff --git a/CI/install/osx/obs.png b/CI/install/osx/obs.png
new file mode 100644
index 0000000..364211c
--- /dev/null
+++ b/CI/install/osx/obs.png
@@ -0,0 +1,703 @@
+
+
+
+
+<!DOCTYPE html>
+<html lang="en" class=" emoji-size-boost is-u2f-enabled">
+  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#">
+    <meta charset='utf-8'>
+    
+
+    <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/frameworks-c9ae4d373fcb2c40952201451cd449e00d6dbcedc778b79c9dfb2d076d04993b.css" integrity="sha256-ya5NNz/LLECVIgFFHNRJ4A1tvO3HeLecnfstB20EmTs=" media="all" rel="stylesheet" />
+    <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/github-4d14493830801ffc6d6d6363f3fcef8a6e41fd9e74776dce15fa2c18b2a9bb72.css" integrity="sha256-TRRJODCAH/xtbWNj8/zvim5B/Z50d23OFfosGLKpu3I=" media="all" rel="stylesheet" />
+    
+    
+    
+    
+
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta http-equiv="Content-Language" content="en">
+    <meta name="viewport" content="width=device-width">
+    
+    <title>obs-studio-utils/obs.png at master · kc5nra/obs-studio-utils</title>
+    <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
+    <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
+    <link rel="apple-touch-icon" href="/apple-touch-icon.png">
+    <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
+    <meta property="fb:app_id" content="1401488693436528">
+
+      <meta content="https://avatars0.githubusercontent.com/u/231018?v=3&s=400" name="twitter:image:src" /><meta content="@github" name="twitter:site" /><meta content="summary" name="twitter:card" /><meta content="kc5nra/obs-studio-utils" name="twitter:title" /><meta content="Contribute to obs-studio-utils development by creating an account on GitHub." name="twitter:description" />
+      <meta content="https://avatars0.githubusercontent.com/u/231018?v=3&s=400" property="og:image" /><meta content="GitHub" property="og:site_name" /><meta content="object" property="og:type" /><meta content="kc5nra/obs-studio-utils" property="og:title" /><meta content="https://github.com/kc5nra/obs-studio-utils" property="og:url" /><meta content="Contribute to obs-studio-utils development by creating an account on GitHub." property="og:description" />
+      <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">
+    <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">
+    <link rel="assets" href="https://assets-cdn.github.com/">
+    <link rel="web-socket" href="wss://live.github.com/_sockets/VjI6NTA0OTIxMTc6ZDJjMjcyYzA1MjZiMGM4MGI5MmU2NzBkMTMyMWNiYWZhMjZiZGQ0MGQxOGY1MWNkYmI1NzA0NjhlZTdjM2E2OA==--561fd74d4042c982502dd897714172236351f238">
+    <meta name="pjax-timeout" content="1000">
+    <link rel="sudo-modal" href="/sessions/sudo_modal">
+    <meta name="request-id" content="683BCFFA:2DABC:EE980D1:587831B3" data-pjax-transient>
+
+    <meta name="msapplication-TileImage" content="/windows-tile.png">
+    <meta name="msapplication-TileColor" content="#ffffff">
+    <meta name="selected-link" value="repo_source" data-pjax-transient>
+
+    <meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU">
+<meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA">
+    <meta name="google-analytics" content="UA-3769691-2">
+
+<meta content="collector.githubapp.com" name="octolytics-host" /><meta content="github" name="octolytics-app-id" /><meta content="683BCFFA:2DABC:EE980D1:587831B3" name="octolytics-dimension-request_id" /><meta content="207897" name="octolytics-actor-id" /><meta content="DDRBoxman" name="octolytics-actor-login" /><meta content="951d1462a992f6b4236b5008d6b11c4331eba4c658fe50ec7c9882e14af522bd" name="octolytics-actor-hash" />
+<meta content="/<user-name>/<repo-name>/blob/show" data-pjax-transient="true" name="analytics-location" />
+
+
+
+  <meta class="js-ga-set" name="dimension1" content="Logged In">
+
+
+
+        <meta name="hostname" content="github.com">
+    <meta name="user-login" content="DDRBoxman">
+
+        <meta name="expected-hostname" content="github.com">
+      <meta name="js-proxy-site-detection-payload" content="ZDQzNzZjM2MwNTlmYWFjNzhmNWJlMzY0MzNkMjdiOThhM2U2OTI0ZjlmMzFlYzJmODdjYjMxNDQ5OTBkNjc4NXx7InJlbW90ZV9hZGRyZXNzIjoiMTA0LjU5LjIwNy4yNTAiLCJyZXF1ZXN0X2lkIjoiNjgzQkNGRkE6MkRBQkM6RUU5ODBEMTo1ODc4MzFCMyIsInRpbWVzdGFtcCI6MTQ4NDI3MjA1NiwiaG9zdCI6ImdpdGh1Yi5jb20ifQ==">
+
+
+      <link rel="mask-icon" href="https://assets-cdn.github.com/pinned-octocat.svg" color="#000000">
+      <link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico">
+
+    <meta name="html-safe-nonce" content="0a420a0a7ff0cff8568da5f27c46880ec53370cf">
+
+    <meta http-equiv="x-pjax-version" content="f36bd54ef0fdb145d68369e21555ea6f">
+    
+
+      
+  <meta name="description" content="Contribute to obs-studio-utils development by creating an account on GitHub.">
+  <meta name="go-import" content="github.com/kc5nra/obs-studio-utils git https://github.com/kc5nra/obs-studio-utils.git">
+
+  <meta content="231018" name="octolytics-dimension-user_id" /><meta content="kc5nra" name="octolytics-dimension-user_login" /><meta content="24656398" name="octolytics-dimension-repository_id" /><meta content="kc5nra/obs-studio-utils" name="octolytics-dimension-repository_nwo" /><meta content="true" name="octolytics-dimension-repository_public" /><meta content="false" name="octolytics-dimension-repository_is_fork" /><meta content="24656398" name="octolytics-dimension-repository_network_root_id" /><meta content="kc5nra/obs-studio-utils" name="octolytics-dimension-repository_network_root_nwo" />
+  <link href="https://github.com/kc5nra/obs-studio-utils/commits/master.atom" rel="alternate" title="Recent Commits to obs-studio-utils:master" type="application/atom+xml">
+
+
+      <link rel="canonical" href="https://github.com/kc5nra/obs-studio-utils/blob/master/install/osx/obs.png" data-pjax-transient>
+  </head>
+
+
+  <body class="logged-in  env-production macintosh vis-public page-blob">
+    <div id="js-pjax-loader-bar" class="pjax-loader-bar"><div class="progress"></div></div>
+    <a href="#start-of-content" tabindex="1" class="accessibility-aid js-skip-to-content">Skip to content</a>
+
+    
+    
+    
+
+
+
+        <div class="header header-logged-in true" role="banner">
+  <div class="container clearfix">
+
+    <a class="header-logo-invertocat" href="https://github.com/" data-hotkey="g d" aria-label="Homepage" data-ga-click="Header, go to dashboard, icon:logo">
+  <svg aria-hidden="true" class="octicon octicon-mark-github" height="28" version="1.1" viewBox="0 0 16 16" width="28"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
+</a>
+
+
+        <div class="header-search scoped-search site-scoped-search js-site-search" role="search">
+  <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/kc5nra/obs-studio-utils/search" class="js-site-search-form" data-scoped-search-url="/kc5nra/obs-studio-utils/search" data-unscoped-search-url="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
+    <label class="form-control header-search-wrapper js-chromeless-input-container">
+      <div class="header-search-scope">This repository</div>
+      <input type="text"
+        class="form-control header-search-input js-site-search-focus js-site-search-field is-clearable"
+        data-hotkey="s"
+        name="q"
+        placeholder="Search"
+        aria-label="Search this repository"
+        data-unscoped-placeholder="Search GitHub"
+        data-scoped-placeholder="Search"
+        autocapitalize="off">
+    </label>
+</form></div>
+
+
+      <ul class="header-nav float-left" role="navigation">
+        <li class="header-nav-item">
+          <a href="/pulls" aria-label="Pull requests you created" class="js-selected-navigation-item header-nav-link" data-ga-click="Header, click, Nav menu - item:pulls context:user" data-hotkey="g p" data-selected-links="/pulls /pulls/assigned /pulls/mentioned /pulls">
+            Pull requests
+</a>        </li>
+        <li class="header-nav-item">
+          <a href="/issues" aria-label="Issues you created" class="js-selected-navigation-item header-nav-link" data-ga-click="Header, click, Nav menu - item:issues context:user" data-hotkey="g i" data-selected-links="/issues /issues/assigned /issues/mentioned /issues">
+            Issues
+</a>        </li>
+          <li class="header-nav-item">
+            <a class="header-nav-link" href="https://gist.github.com/" data-ga-click="Header, go to gist, text:gist">Gist</a>
+          </li>
+      </ul>
+
+    
+<ul class="header-nav user-nav float-right" id="user-links">
+  <li class="header-nav-item">
+    
+    <a href="/notifications" aria-label="You have no unread notifications" class="header-nav-link notification-indicator tooltipped tooltipped-s js-socket-channel js-notification-indicator" data-channel="tenant:1:notification-changed:207897" data-ga-click="Header, go to notifications, icon:read" data-hotkey="g n">
+        <span class="mail-status "></span>
+        <svg aria-hidden="true" class="octicon octicon-bell" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M14 12v1H0v-1l.73-.58c.77-.77.81-2.55 1.19-4.42C2.69 3.23 6 2 6 2c0-.55.45-1 1-1s1 .45 1 1c0 0 3.39 1.23 4.16 5 .38 1.88.42 3.66 1.19 4.42l.66.58H14zm-7 4c1.11 0 2-.89 2-2H5c0 1.11.89 2 2 2z"/></svg>
+</a>
+  </li>
+
+  <li class="header-nav-item dropdown js-menu-container">
+    <a class="header-nav-link tooltipped tooltipped-s js-menu-target" href="/new"
+       aria-label="Create new…"
+       data-ga-click="Header, create new, icon:add">
+      <svg aria-hidden="true" class="octicon octicon-plus float-left" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 9H7v5H5V9H0V7h5V2h2v5h5z"/></svg>
+      <span class="dropdown-caret"></span>
+    </a>
+
+    <div class="dropdown-menu-content js-menu-content">
+      <ul class="dropdown-menu dropdown-menu-sw">
+        
+<a class="dropdown-item" href="/new" data-ga-click="Header, create new repository">
+  New repository
+</a>
+
+  <a class="dropdown-item" href="/new/import" data-ga-click="Header, import a repository">
+    Import repository
+  </a>
+
+<a class="dropdown-item" href="https://gist.github.com/" data-ga-click="Header, create new gist">
+  New gist
+</a>
+
+  <a class="dropdown-item" href="/organizations/new" data-ga-click="Header, create new organization">
+    New organization
+  </a>
+
+
+
+  <div class="dropdown-divider"></div>
+  <div class="dropdown-header">
+    <span title="kc5nra/obs-studio-utils">This repository</span>
+  </div>
+    <a class="dropdown-item" href="/kc5nra/obs-studio-utils/issues/new" data-ga-click="Header, create new issue">
+      New issue
+    </a>
+
+      </ul>
+    </div>
+  </li>
+
+  <li class="header-nav-item dropdown js-menu-container">
+    <a class="header-nav-link name tooltipped tooltipped-sw js-menu-target" href="/DDRBoxman"
+       aria-label="View profile and more"
+       data-ga-click="Header, show menu, icon:avatar">
+      <img alt="@DDRBoxman" class="avatar" height="20" src="https://avatars3.githubusercontent.com/u/207897?v=3&s=40" width="20" />
+      <span class="dropdown-caret"></span>
+    </a>
+
+    <div class="dropdown-menu-content js-menu-content">
+      <div class="dropdown-menu dropdown-menu-sw">
+        <div class="dropdown-header header-nav-current-user css-truncate">
+          Signed in as <strong class="css-truncate-target">DDRBoxman</strong>
+        </div>
+
+        <div class="dropdown-divider"></div>
+
+        <a class="dropdown-item" href="/DDRBoxman" data-ga-click="Header, go to profile, text:your profile">
+          Your profile
+        </a>
+        <a class="dropdown-item" href="/DDRBoxman?tab=stars" data-ga-click="Header, go to starred repos, text:your stars">
+          Your stars
+        </a>
+        <a class="dropdown-item" href="/explore" data-ga-click="Header, go to explore, text:explore">
+          Explore
+        </a>
+          <a class="dropdown-item" href="/integrations" data-ga-click="Header, go to integrations, text:integrations">
+            Integrations
+          </a>
+        <a class="dropdown-item" href="https://help.github.com" data-ga-click="Header, go to help, text:help">
+          Help
+        </a>
+
+        <div class="dropdown-divider"></div>
+
+        <a class="dropdown-item" href="/settings/profile" data-ga-click="Header, go to settings, icon:settings">
+          Settings
+        </a>
+
+        <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/logout" class="logout-form" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="mbjQPqcKKO6Yuqt3Dvczikt53JctIh6E47+gkXyZ3vFinTikSLP4X/o4pVzB6UDZReamEALdVHKN3UNUxVdRFQ==" /></div>
+          <button type="submit" class="dropdown-item dropdown-signout" data-ga-click="Header, sign out, icon:logout">
+            Sign out
+          </button>
+</form>      </div>
+    </div>
+  </li>
+</ul>
+
+
+    
+  </div>
+</div>
+
+
+      
+
+
+    <div id="start-of-content" class="accessibility-aid"></div>
+
+      <div id="js-flash-container">
+</div>
+
+
+    <div role="main">
+        <div itemscope itemtype="http://schema.org/SoftwareSourceCode">
+    <div id="js-repo-pjax-container" data-pjax-container>
+      
+<div class="pagehead repohead instapaper_ignore readability-menu experiment-repo-nav">
+  <div class="container repohead-details-container">
+
+    
+
+<ul class="pagehead-actions">
+
+  <li>
+        <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/notifications/subscribe" class="js-social-container" data-autosubmit="true" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="7woW5zqjJpvg5IbCp+Gf47Op+jJvsrXFlv5u5Cwuwg3CsPTT6eYZ7inxEYqPhx9rxluEnL+P7mYdgOYTMzC6HQ==" /></div>      <input class="form-control" id="repository_id" name="repository_id" type="hidden" value="24656398" />
+
+        <div class="select-menu js-menu-container js-select-menu">
+          <a href="/kc5nra/obs-studio-utils/subscription"
+            class="btn btn-sm btn-with-count select-menu-button js-menu-target" role="button" tabindex="0" aria-haspopup="true"
+            data-ga-click="Repository, click Watch settings, action:blob#show">
+            <span class="js-select-button">
+              <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
+              Watch
+            </span>
+          </a>
+          <a class="social-count js-social-count"
+            href="/kc5nra/obs-studio-utils/watchers"
+            aria-label="6 users are watching this repository">
+            6
+          </a>
+
+        <div class="select-menu-modal-holder">
+          <div class="select-menu-modal subscription-menu-modal js-menu-content" aria-hidden="true">
+            <div class="select-menu-header js-navigation-enable" tabindex="-1">
+              <svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
+              <span class="select-menu-title">Notifications</span>
+            </div>
+
+              <div class="select-menu-list js-navigation-container" role="menu">
+
+                <div class="select-menu-item js-navigation-item selected" role="menuitem" tabindex="0">
+                  <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
+                  <div class="select-menu-item-text">
+                    <input checked="checked" id="do_included" name="do" type="radio" value="included" />
+                    <span class="select-menu-item-heading">Not watching</span>
+                    <span class="description">Be notified when participating or @mentioned.</span>
+                    <span class="js-select-button-text hidden-select-button-text">
+                      <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
+                      Watch
+                    </span>
+                  </div>
+                </div>
+
+                <div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0">
+                  <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
+                  <div class="select-menu-item-text">
+                    <input id="do_subscribed" name="do" type="radio" value="subscribed" />
+                    <span class="select-menu-item-heading">Watching</span>
+                    <span class="description">Be notified of all conversations.</span>
+                    <span class="js-select-button-text hidden-select-button-text">
+                      <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
+                      Unwatch
+                    </span>
+                  </div>
+                </div>
+
+                <div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0">
+                  <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
+                  <div class="select-menu-item-text">
+                    <input id="do_ignore" name="do" type="radio" value="ignore" />
+                    <span class="select-menu-item-heading">Ignoring</span>
+                    <span class="description">Never be notified.</span>
+                    <span class="js-select-button-text hidden-select-button-text">
+                      <svg aria-hidden="true" class="octicon octicon-mute" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8 2.81v10.38c0 .67-.81 1-1.28.53L3 10H1c-.55 0-1-.45-1-1V7c0-.55.45-1 1-1h2l3.72-3.72C7.19 1.81 8 2.14 8 2.81zm7.53 3.22l-1.06-1.06-1.97 1.97-1.97-1.97-1.06 1.06L11.44 8 9.47 9.97l1.06 1.06 1.97-1.97 1.97 1.97 1.06-1.06L13.56 8l1.97-1.97z"/></svg>
+                      Stop ignoring
+                    </span>
+                  </div>
+                </div>
+
+              </div>
+
+            </div>
+          </div>
+        </div>
+</form>
+  </li>
+
+  <li>
+      <div class="js-toggler-container js-social-container starring-container ">
+    <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/kc5nra/obs-studio-utils/unstar" class="starred" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="uNPwxvmyPhwAsjUibCbKxZPg+6FNyS0wqv8HPlluJPjUflJmxafLWYbN3BQrvfH8Lc0ZHtLc/rWvAedO7AIezw==" /></div>
+      <button
+        type="submit"
+        class="btn btn-sm btn-with-count js-toggler-target"
+        aria-label="Unstar this repository" title="Unstar kc5nra/obs-studio-utils"
+        data-ga-click="Repository, click unstar button, action:blob#show; text:Unstar">
+        <svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"/></svg>
+        Unstar
+      </button>
+        <a class="social-count js-social-count" href="/kc5nra/obs-studio-utils/stargazers"
+           aria-label="8 users starred this repository">
+          8
+        </a>
+</form>
+    <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/kc5nra/obs-studio-utils/star" class="unstarred" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="/sSbA/aj/l81g7HuzKrbvT/fZClJWTOY1T6jjNOGbTpB0vtZBytYMlHPt25VUZnhDcnvUHq56bYpHx4cSnYfgA==" /></div>
+      <button
+        type="submit"
+        class="btn btn-sm btn-with-count js-toggler-target"
+        aria-label="Star this repository" title="Star kc5nra/obs-studio-utils"
+        data-ga-click="Repository, click star button, action:blob#show; text:Star">
+        <svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"/></svg>
+        Star
+      </button>
+        <a class="social-count js-social-count" href="/kc5nra/obs-studio-utils/stargazers"
+           aria-label="8 users starred this repository">
+          8
+        </a>
+</form>  </div>
+
+  </li>
+
+  <li>
+          <a href="#fork-destination-box" class="btn btn-sm btn-with-count"
+              title="Fork your own copy of kc5nra/obs-studio-utils to your account"
+              aria-label="Fork your own copy of kc5nra/obs-studio-utils to your account"
+              rel="facebox"
+              data-ga-click="Repository, show fork modal, action:blob#show; text:Fork">
+              <svg aria-hidden="true" class="octicon octicon-repo-forked" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path fill-rule="evenodd" d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
+            Fork
+          </a>
+
+          <div id="fork-destination-box" style="display: none;">
+            <h2 class="facebox-header" data-facebox-id="facebox-header">Where should we fork this repository?</h2>
+            <include-fragment src=""
+                class="js-fork-select-fragment fork-select-fragment"
+                data-url="/kc5nra/obs-studio-utils/fork?fragment=1">
+              <img alt="Loading" height="64" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-128.gif" width="64" />
+            </include-fragment>
+          </div>
+
+    <a href="/kc5nra/obs-studio-utils/network" class="social-count"
+       aria-label="4 users forked this repository">
+      4
+    </a>
+  </li>
+</ul>
+
+    <h1 class="public ">
+  <svg aria-hidden="true" class="octicon octicon-repo" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z"/></svg>
+  <span class="author" itemprop="author"><a href="/kc5nra" class="url fn" rel="author">kc5nra</a></span><!--
+--><span class="path-divider">/</span><!--
+--><strong itemprop="name"><a href="/kc5nra/obs-studio-utils" data-pjax="#js-repo-pjax-container">obs-studio-utils</a></strong>
+
+</h1>
+
+  </div>
+  <div class="container">
+    
+<nav class="reponav js-repo-nav js-sidenav-container-pjax"
+     itemscope
+     itemtype="http://schema.org/BreadcrumbList"
+     role="navigation"
+     data-pjax="#js-repo-pjax-container">
+
+  <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
+    <a href="/kc5nra/obs-studio-utils" class="js-selected-navigation-item selected reponav-item" data-hotkey="g c" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /kc5nra/obs-studio-utils" itemprop="url">
+      <svg aria-hidden="true" class="octicon octicon-code" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z"/></svg>
+      <span itemprop="name">Code</span>
+      <meta itemprop="position" content="1">
+</a>  </span>
+
+    <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
+      <a href="/kc5nra/obs-studio-utils/issues" class="js-selected-navigation-item reponav-item" data-hotkey="g i" data-selected-links="repo_issues repo_labels repo_milestones /kc5nra/obs-studio-utils/issues" itemprop="url">
+        <svg aria-hidden="true" class="octicon octicon-issue-opened" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"/></svg>
+        <span itemprop="name">Issues</span>
+        <span class="counter">1</span>
+        <meta itemprop="position" content="2">
+</a>    </span>
+
+  <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
+    <a href="/kc5nra/obs-studio-utils/pulls" class="js-selected-navigation-item reponav-item" data-hotkey="g p" data-selected-links="repo_pulls /kc5nra/obs-studio-utils/pulls" itemprop="url">
+      <svg aria-hidden="true" class="octicon octicon-git-pull-request" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
+      <span itemprop="name">Pull requests</span>
+      <span class="counter">0</span>
+      <meta itemprop="position" content="3">
+</a>  </span>
+
+  <a href="/kc5nra/obs-studio-utils/projects" class="js-selected-navigation-item reponav-item" data-selected-links="repo_projects new_repo_project repo_project /kc5nra/obs-studio-utils/projects">
+    <svg aria-hidden="true" class="octicon octicon-project" height="16" version="1.1" viewBox="0 0 15 16" width="15"><path fill-rule="evenodd" d="M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4 4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1z"/></svg>
+    Projects
+    <span class="counter">0</span>
+</a>
+    <a href="/kc5nra/obs-studio-utils/wiki" class="js-selected-navigation-item reponav-item" data-hotkey="g w" data-selected-links="repo_wiki /kc5nra/obs-studio-utils/wiki">
+      <svg aria-hidden="true" class="octicon octicon-book" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M3 5h4v1H3V5zm0 3h4V7H3v1zm0 2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1 1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45 1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z"/></svg>
+      Wiki
+</a>
+
+  <a href="/kc5nra/obs-studio-utils/pulse" class="js-selected-navigation-item reponav-item" data-selected-links="pulse /kc5nra/obs-studio-utils/pulse">
+    <svg aria-hidden="true" class="octicon octicon-pulse" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0v2h3.6l.9-1.8.9 5.4L9 8.5l1.6 1.5H14V8z"/></svg>
+    Pulse
+</a>
+  <a href="/kc5nra/obs-studio-utils/graphs" class="js-selected-navigation-item reponav-item" data-selected-links="repo_graphs repo_contributors /kc5nra/obs-studio-utils/graphs">
+    <svg aria-hidden="true" class="octicon octicon-graph" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z"/></svg>
+    Graphs
+</a>
+
+</nav>
+
+  </div>
+</div>
+
+<div class="container new-discussion-timeline experiment-repo-nav">
+  <div class="repository-content">
+
+    
+
+<a href="/kc5nra/obs-studio-utils/blob/b3ffed1c23a254e44d3dcdd2af3f9b13f63d7939/install/osx/obs.png" class="d-none js-permalink-shortcut" data-hotkey="y">Permalink</a>
+
+<!-- blob contrib key: blob_contributors:v21:6c7ce207313616b1dc79697595d24fe7 -->
+
+<div class="file-navigation js-zeroclipboard-container">
+  
+<div class="select-menu branch-select-menu js-menu-container js-select-menu float-left">
+  <button class="btn btn-sm select-menu-button js-menu-target css-truncate" data-hotkey="w"
+    
+    type="button" aria-label="Switch branches or tags" tabindex="0" aria-haspopup="true">
+    <i>Branch:</i>
+    <span class="js-select-button css-truncate-target">master</span>
+  </button>
+
+  <div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax aria-hidden="true">
+
+    <div class="select-menu-modal">
+      <div class="select-menu-header">
+        <svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
+        <span class="select-menu-title">Switch branches/tags</span>
+      </div>
+
+      <div class="select-menu-filters">
+        <div class="select-menu-text-filter">
+          <input type="text" aria-label="Filter branches/tags" id="context-commitish-filter-field" class="form-control js-filterable-field js-navigation-enable" placeholder="Filter branches/tags">
+        </div>
+        <div class="select-menu-tabs">
+          <ul>
+            <li class="select-menu-tab">
+              <a href="#" data-tab-filter="branches" data-filter-placeholder="Filter branches/tags" class="js-select-menu-tab" role="tab">Branches</a>
+            </li>
+            <li class="select-menu-tab">
+              <a href="#" data-tab-filter="tags" data-filter-placeholder="Find a tag…" class="js-select-menu-tab" role="tab">Tags</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+
+      <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches" role="menu">
+
+        <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
+
+
+            <a class="select-menu-item js-navigation-item js-navigation-open selected"
+               href="/kc5nra/obs-studio-utils/blob/master/install/osx/obs.png"
+               data-name="master"
+               data-skip-pjax="true"
+               rel="nofollow">
+              <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
+              <span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
+                master
+              </span>
+            </a>
+        </div>
+
+          <div class="select-menu-no-results">Nothing to show</div>
+      </div>
+
+      <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags">
+        <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
+
+
+        </div>
+
+        <div class="select-menu-no-results">Nothing to show</div>
+      </div>
+
+    </div>
+  </div>
+</div>
+
+  <div class="BtnGroup float-right">
+    <a href="/kc5nra/obs-studio-utils/find/master"
+          class="js-pjax-capture-input btn btn-sm BtnGroup-item"
+          data-pjax
+          data-hotkey="t">
+      Find file
+    </a>
+    <button aria-label="Copy file path to clipboard" class="js-zeroclipboard btn btn-sm BtnGroup-item tooltipped tooltipped-s" data-copied-hint="Copied!" type="button">Copy path</button>
+  </div>
+  <div class="breadcrumb js-zeroclipboard-target">
+    <span class="repo-root js-repo-root"><span class="js-path-segment"><a href="/kc5nra/obs-studio-utils"><span>obs-studio-utils</span></a></span></span><span class="separator">/</span><span class="js-path-segment"><a href="/kc5nra/obs-studio-utils/tree/master/install"><span>install</span></a></span><span class="separator">/</span><span class="js-path-segment"><a href="/kc5nra/obs-studio-utils/tree/master/install/osx"><span>osx</span></a></span><span class="separator">/</span><strong class="final-path">obs.png</strong>
+  </div>
+</div>
+
+
+  <div class="commit-tease">
+      <span class="float-right">
+        <a class="commit-tease-sha" href="/kc5nra/obs-studio-utils/commit/b83a806a64ffd96f547029d64ed28aad49e20d5b" data-pjax>
+          b83a806
+        </a>
+        <relative-time datetime="2014-10-01T22:46:15Z">Oct 1, 2014</relative-time>
+      </span>
+      <div>
+        <img alt="@kc5nra" class="avatar" height="20" src="https://avatars3.githubusercontent.com/u/231018?v=3&s=40" width="20" />
+        <a href="/kc5nra" class="user-mention" rel="author">kc5nra</a>
+          <a href="/kc5nra/obs-studio-utils/commit/b83a806a64ffd96f547029d64ed28aad49e20d5b" class="message" data-pjax="true" title="Png more transparent, obs bundle id and img loc">Png more transparent, obs bundle id and img loc</a>
+      </div>
+
+    <div class="commit-tease-contributors">
+      <button type="button" class="btn-link muted-link contributors-toggle" data-facebox="#blob_contributors_box">
+        <strong>1</strong>
+         contributor
+      </button>
+      
+    </div>
+
+    <div id="blob_contributors_box" style="display:none">
+      <h2 class="facebox-header" data-facebox-id="facebox-header">Users who have contributed to this file</h2>
+      <ul class="facebox-user-list" data-facebox-id="facebox-description">
+          <li class="facebox-user-list-item">
+            <img alt="@kc5nra" height="24" src="https://avatars1.githubusercontent.com/u/231018?v=3&s=48" width="24" />
+            <a href="/kc5nra">kc5nra</a>
+          </li>
+      </ul>
+    </div>
+  </div>
+
+
+<div class="file">
+  <div class="file-header">
+  <div class="file-actions">
+
+    <div class="BtnGroup">
+      <a href="/kc5nra/obs-studio-utils/raw/master/install/osx/obs.png" class="btn btn-sm BtnGroup-item" id="raw-url">Download</a>
+      <a href="/kc5nra/obs-studio-utils/commits/master/install/osx/obs.png" class="btn btn-sm BtnGroup-item" rel="nofollow">History</a>
+    </div>
+
+        <a class="btn-octicon tooltipped tooltipped-nw"
+           href="github-mac://openRepo/https://github.com/kc5nra/obs-studio-utils?branch=master&filepath=install%2Fosx%2Fobs.png"
+           aria-label="Open this file in GitHub Desktop"
+           data-ga-click="Repository, open with desktop, type:mac">
+            <svg aria-hidden="true" class="octicon octicon-device-desktop" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M15 2H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5.34c-.25.61-.86 1.39-2.34 2h8c-1.48-.61-2.09-1.39-2.34-2H15c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm0 9H1V3h14v8z"/></svg>
+        </a>
+
+        <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/kc5nra/obs-studio-utils/delete/master/install/osx/obs.png" class="inline-form" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="uGzTDUGxcZBqCvnvwWvHWxzog35RyhtwqPCf9WmjMskKj0JcMzGgzzfI9Vg2tnJjAjFGp9psbMbIg54+M9+7/A==" /></div>
+          <button class="btn-octicon btn-octicon-danger tooltipped tooltipped-nw" type="submit"
+            aria-label="Delete the file in your fork of this project" data-disable-with>
+            <svg aria-hidden="true" class="octicon octicon-trashcan" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z"/></svg>
+          </button>
+</form>  </div>
+
+  <div class="file-info">
+    52.8 KB
+  </div>
+</div>
+
+  
+
+  <div itemprop="text" class="blob-wrapper data type-text">
+      <div class="image">
+          <span class="border-wrap"><img src="/kc5nra/obs-studio-utils/blob/master/install/osx/obs.png?raw=true" alt="obs.png"></span>
+      </div>
+  </div>
+
+</div>
+
+<button type="button" data-facebox="#jump-to-line" data-facebox-class="linejump" data-hotkey="l" class="d-none">Jump to Line</button>
+<div id="jump-to-line" style="display:none">
+  <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="" class="js-jump-to-line-form" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
+    <input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line…" aria-label="Jump to line" autofocus>
+    <button type="submit" class="btn">Go</button>
+</form></div>
+
+  </div>
+  <div class="modal-backdrop js-touch-events"></div>
+</div>
+
+
+    </div>
+  </div>
+
+    </div>
+
+        <div class="container site-footer-container">
+  <div class="site-footer" role="contentinfo">
+    <ul class="site-footer-links float-right">
+        <li><a href="https://github.com/contact" data-ga-click="Footer, go to contact, text:contact">Contact GitHub</a></li>
+      <li><a href="https://developer.github.com" data-ga-click="Footer, go to api, text:api">API</a></li>
+      <li><a href="https://training.github.com" data-ga-click="Footer, go to training, text:training">Training</a></li>
+      <li><a href="https://shop.github.com" data-ga-click="Footer, go to shop, text:shop">Shop</a></li>
+        <li><a href="https://github.com/blog" data-ga-click="Footer, go to blog, text:blog">Blog</a></li>
+        <li><a href="https://github.com/about" data-ga-click="Footer, go to about, text:about">About</a></li>
+
+    </ul>
+
+    <a href="https://github.com" aria-label="Homepage" class="site-footer-mark" title="GitHub">
+      <svg aria-hidden="true" class="octicon octicon-mark-github" height="24" version="1.1" viewBox="0 0 16 16" width="24"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
+</a>
+    <ul class="site-footer-links">
+      <li>© 2017 <span title="0.13223s from github-fe143-cp1-prd.iad.github.net">GitHub</span>, Inc.</li>
+        <li><a href="https://github.com/site/terms" data-ga-click="Footer, go to terms, text:terms">Terms</a></li>
+        <li><a href="https://github.com/site/privacy" data-ga-click="Footer, go to privacy, text:privacy">Privacy</a></li>
+        <li><a href="https://github.com/security" data-ga-click="Footer, go to security, text:security">Security</a></li>
+        <li><a href="https://status.github.com/" data-ga-click="Footer, go to status, text:status">Status</a></li>
+        <li><a href="https://help.github.com" data-ga-click="Footer, go to help, text:help">Help</a></li>
+    </ul>
+  </div>
+</div>
+
+
+
+    
+
+    <div id="ajax-error-message" class="ajax-error-message flash flash-error">
+      <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
+      <button type="button" class="flash-close js-flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
+        <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
+      </button>
+      You can't perform that action at this time.
+    </div>
+
+
+      
+      <script crossorigin="anonymous" integrity="sha256-uzmufYSNQNbwHmc1XigpZPVPo5E3wOzJ/E7Dfn1GlQg=" src="https://assets-cdn.github.com/assets/frameworks-bb39ae7d848d40d6f01e67355e282964f54fa39137c0ecc9fc4ec37e7d469508.js"></script>
+      <script async="async" crossorigin="anonymous" integrity="sha256-/48DIbQkaCd8FbKJGEm8s5jOpo2/L4j5LZ+RY+umtSU=" src="https://assets-cdn.github.com/assets/github-ff8f0321b42468277c15b2891849bcb398cea68dbf2f88f92d9f9163eba6b525.js"></script>
+      
+      
+      
+      
+    <div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner d-none">
+      <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
+      <span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
+      <span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
+    </div>
+    <div class="facebox" id="facebox" style="display:none;">
+  <div class="facebox-popup">
+    <div class="facebox-content" role="dialog" aria-labelledby="facebox-header" aria-describedby="facebox-description">
+    </div>
+    <button type="button" class="facebox-close js-facebox-close" aria-label="Close modal">
+      <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
+    </button>
+  </div>
+</div>
+
+  </body>
+</html>
+
diff --git a/CI/install/osx/package_util.py b/CI/install/osx/package_util.py
new file mode 100644
index 0000000..2ab0b94
--- /dev/null
+++ b/CI/install/osx/package_util.py
@@ -0,0 +1,94 @@
+def cmd(cmd):
+    import subprocess
+    import shlex
+    return subprocess.check_output(shlex.split(cmd)).rstrip('\r\n')
+
+def get_tag_info(tag):
+    rev = cmd('git rev-parse {0}'.format(latest_tag))
+    anno = cmd('git cat-file -p {0}'.format(rev))
+    tag_info = []
+    for i, v in enumerate(anno.splitlines()):
+        if i <= 4:
+            continue
+        tag_info.append(v.lstrip())
+
+    return tag_info
+
+def gen_html(github_user, latest_tag):
+
+    url = 'https://github.com/{0}/obs-studio/commit/%H'.format(github_user)
+
+    with open('readme.html', 'w') as f:
+        f.write("<html><body>")
+        log_cmd = """git log {0}...HEAD --pretty=format:'<li>• <a href="{1}">(view)</a> %s</li>'"""
+        log_res = cmd(log_cmd.format(latest_tag, url))
+        if len(log_res.splitlines()):
+            f.write('<p>Changes since {0}: (Newest to oldest)</p>'.format(latest_tag))
+            f.write(log_res)
+
+        ul = False
+        f.write('<p>')
+        import re
+
+        for l in get_tag_info(latest_tag):
+            if not len(l):
+                continue
+            if l.startswith('*'):
+                ul = True
+                if not ul:
+                    f.write('<ul>')
+                f.write('<li>• {0}</li>'.format(re.sub(r'^(\s*)?[*](\s*)?', '', l)))
+            else:
+                if ul:
+                    f.write('</ul><p/>')
+                ul = False
+                f.write('<p>{0}</p>'.format(l))
+        if ul:
+            f.write('</ul>')
+        f.write('</p></body></html>')
+
+    cmd('textutil -convert rtf readme.html -output readme.rtf')
+    cmd("""sed -i '' 's/Times-Roman/Verdana/g' readme.rtf""")
+
+def save_manifest(latest_tag, user, jenkins_build, branch, stable):
+    log = cmd('git log --pretty=oneline {0}...HEAD'.format(latest_tag))
+    manifest = {}
+    manifest['commits'] = []
+    for v in log.splitlines():
+        manifest['commits'].append(v)
+    manifest['tag'] = {
+        'name': latest_tag,
+        'description': get_tag_info(latest_tag)
+    }
+
+    manifest['version'] = cmd('git rev-list HEAD --count')
+    manifest['sha1'] = cmd('git rev-parse HEAD')
+    manifest['jenkins_build'] = jenkins_build
+
+    manifest['user'] = user
+    manifest['branch'] = branch
+    manifest['stable'] = stable
+
+    import cPickle
+    with open('manifest', 'w') as f:
+        cPickle.dump(manifest, f)
+
+def prepare_pkg(project, package_id):
+    cmd('packagesutil --file "{0}" set package-1 identifier {1}'.format(project, package_id))
+    cmd('packagesutil --file "{0}" set package-1 version {1}'.format(project, '1.0'))
+
+
+import argparse
+parser = argparse.ArgumentParser(description='obs-studio package util')
+parser.add_argument('-u', '--user', dest='user', default='jp9000')
+parser.add_argument('-p', '--package-id', dest='package_id', default='org.obsproject.pkg.obs-studio')
+parser.add_argument('-f', '--project-file', dest='project', default='OBS.pkgproj')
+parser.add_argument('-j', '--jenkins-build', dest='jenkins_build', default='0')
+parser.add_argument('-b', '--branch', dest='branch', default='master')
+parser.add_argument('-s', '--stable', dest='stable', required=False, action='store_true', default=False)
+args = parser.parse_args()
+
+latest_tag = cmd('git describe --tags --abbrev=0')
+gen_html(args.user, latest_tag)
+prepare_pkg(args.project, args.package_id)
+save_manifest(latest_tag, args.user, args.jenkins_build, args.branch, args.stable)
diff --git a/CI/install/osx/post-install.sh b/CI/install/osx/post-install.sh
new file mode 100644
index 0000000..f55ae58
--- /dev/null
+++ b/CI/install/osx/post-install.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+# Fix permissions on CEF
+chmod 744 "/Library/Application Support/obs-studio/plugins/obs-browser/bin/CEF.app/Contents/Info.plist"
+chmod 744 "/Library/Application Support/obs-studio/plugins/obs-browser/bin/CEF.app/Contents/Frameworks/CEF Helper.app/Contents/Info.plist"
diff --git a/CI/osxcert/Certificates.p12.enc b/CI/osxcert/Certificates.p12.enc
new file mode 100644
index 0000000..0fb42bc
Binary files /dev/null and b/CI/osxcert/Certificates.p12.enc differ
diff --git a/CI/util/build-package-deps-osx.sh b/CI/util/build-package-deps-osx.sh
new file mode 100755
index 0000000..bf950d7
--- /dev/null
+++ b/CI/util/build-package-deps-osx.sh
@@ -0,0 +1,130 @@
+#!/usr/bin/env bash
+
+CURDIR=$(pwd)
+
+# the temp directory
+WORK_DIR=`mktemp -d`
+
+# deletes the temp directory
+function cleanup {
+  #rm -rf "$WORK_DIR"
+  echo "Deleted temp working directory $WORK_DIR"
+}
+
+# register the cleanup function to be called on the EXIT signal
+trap cleanup EXIT
+
+cd $WORK_DIR
+
+DEPS_DEST=$WORK_DIR/obsdeps
+
+# make dest dirs
+mkdir $DEPS_DEST
+mkdir $DEPS_DEST/bin
+mkdir $DEPS_DEST/include
+
+# OSX COMPAT
+export MACOSX_DEPLOYMENT_TARGET=10.9
+
+# If you need an olders SDK and Xcode won't give it to you
+# https://github.com/phracker/MacOSX-SDKs
+
+# libopus
+curl -L -O http://downloads.xiph.org/releases/opus/opus-1.1.3.tar.gz
+tar -xf opus-1.1.3.tar.gz
+cd ./opus-1.1.3
+mkdir build
+cd ./build
+../configure --disable-shared --enable-static --prefix="/tmp/obsdeps"
+make -j 12
+make install
+
+cd $WORK_DIR
+
+# libogg
+curl -L -O http://downloads.xiph.org/releases/ogg/libogg-1.3.2.tar.gz
+tar -xf libogg-1.3.2.tar.gz
+cd ./libogg-1.3.2
+mkdir build
+cd ./build
+../configure --disable-shared --enable-static --prefix="/tmp/obsdeps"
+make -j 12
+make install
+
+cd $WORK_DIR
+
+# libvorbis
+curl -L -O http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.5.tar.gz
+tar -xf libvorbis-1.3.5.tar.gz
+cd ./libvorbis-1.3.5
+mkdir build
+cd ./build
+../configure --disable-shared --enable-static --prefix="/tmp/obsdeps"
+make -j 12
+make install
+
+cd $WORK_DIR
+
+# libvpx
+curl -L -O http://storage.googleapis.com/downloads.webmproject.org/releases/webm/libvpx-1.6.0.tar.bz2
+tar -xf libvpx-1.6.0.tar.bz2
+cd ./libvpx-1.6.0
+mkdir build
+cd ./build
+../configure --disable-shared --libdir="/tmp/obsdeps/bin"
+make -j 12
+make install
+
+cd $WORK_DIR
+
+# x264
+git clone git://git.videolan.org/x264.git
+cd ./x264
+mkdir build
+cd ./build
+../configure --extra-ldflags="-mmacosx-version-min=10.9" --enable-static --prefix="/tmp/obsdeps"
+make -j 12
+make install
+../configure --extra-ldflags="-mmacosx-version-min=10.9" --enable-shared --libdir="/tmp/obsdeps/bin" --prefix="/tmp/obsdeps"
+make -j 12
+ln -f -s libx264.*.dylib libx264.dylib
+find . -name \*.dylib -exec cp \{\} $DEPS_DEST/bin/ \;
+rsync -avh --include="*/" --include="*.h" --exclude="*" ../* $DEPS_DEST/include/
+rsync -avh --include="*/" --include="*.h" --exclude="*" ./* $DEPS_DEST/include/
+
+cd $WORK_DIR
+
+# janson
+curl -L -O http://www.digip.org/jansson/releases/jansson-2.9.tar.gz
+tar -xf jansson-2.9.tar.gz
+cd jansson-2.9
+mkdir build
+cd ./build
+../configure --libdir="/tmp/obsdeps/bin" --enable-shared --disable-static
+make -j 12
+find . -name \*.dylib -exec cp \{\} $DEPS_DEST/bin/ \;
+rsync -avh --include="*/" --include="*.h" --exclude="*" ../* $DEPS_DEST/include/
+rsync -avh --include="*/" --include="*.h" --exclude="*" ./* $DEPS_DEST/include/
+
+cd $WORK_DIR
+
+export LDFLAGS="-L/tmp/obsdeps/lib"
+export CFLAGS="-I/tmp/obsdeps/include"
+
+# FFMPEG
+curl -L -O https://github.com/FFmpeg/FFmpeg/archive/n3.2.2.zip
+unzip ./n3.2.2.zip
+cd ./FFmpeg-n3.2.2
+mkdir build
+cd ./build
+../configure --extra-ldflags="-mmacosx-version-min=10.9" --enable-shared --disable-static --shlibdir="/tmp/obsdeps/bin" --enable-gpl --disable-doc --enable-libx264 --enable-libopus --enable-libvorbis --enable-libvpx
+make -j 12
+find . -name \*.dylib -exec cp \{\} $DEPS_DEST/bin/ \;
+rsync -avh --include="*/" --include="*.h" --exclude="*" ../* $DEPS_DEST/include/
+rsync -avh --include="*/" --include="*.h" --exclude="*" ./* $DEPS_DEST/include/
+
+cd $WORK_DIR
+
+tar -czf osx-deps.tar.gz obsdeps
+
+cp ./osx-deps.tar.gz $CURDIR
\ No newline at end of file
diff --git a/CI/util/win32.sh b/CI/util/win32.sh
new file mode 100755
index 0000000..a1a2919
--- /dev/null
+++ b/CI/util/win32.sh
@@ -0,0 +1,69 @@
+#/bin/bash
+
+cd x264
+make clean
+LDFLAGS="-static-libgcc" ./configure --enable-shared --enable-win32thread --disable-avs --disable-ffms --disable-gpac --disable-interlaced --disable-lavf --cross-prefix=i686-w64-mingw32- --host=i686-pc-mingw32 --prefix="/home/jim/packages/win32"
+make -j6 fprofiled VIDS="CITY_704x576_60_orig_01.yuv"
+make install
+i686-w64-mingw32-dlltool -z /home/jim/packages/win32/bin/x264.orig.def --export-all-symbols /home/jim/packages/win32/bin/libx264-148.dll
+grep "EXPORTS\|x264" /home/jim/packages/win32/bin/x264.orig.def > /home/jim/packages/win32/bin/x264.def
+rm -f /home/jim/packages/win32/bin/x264.org.def
+sed -i -e "/\\t.*DATA/d" -e "/\\t\".*/d" -e "s/\s at .*//" /home/jim/packages/win32/bin/x264.def
+i686-w64-mingw32-dlltool -m i386 -d /home/jim/packages/win32/bin/x264.def -l /home/jim/packages/win32/bin/x264.lib -D /home/jim/win32/packages/bin/libx264-148.dll
+cd ..
+
+cd opus
+make clean
+LDFLAGS="-static-libgcc" ./configure -host=i686-w64-mingw32 --prefix="/home/jim/packages/win32" --enable-shared
+make -j6
+make install
+cd ..
+
+cd zlib/build32
+make clean
+cmake .. -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc -DCMAKE_INSTALL_PREFIX=/home/jim/packages/win32 -DINSTALL_PKGCONFIG_DIR=/home/jim/packages/win32/lib/pkgconfig -DCMAKE_RC_COMPILER=i686-w64-mingw32-windres -DCMAKE_SHARED_LINKER_FLAGS="-static-libgcc"
+make -j6
+make install
+mv ../../win32/lib/libzlib.dll.a ../../win32/lib/libz.dll.a
+mv ../../win32/lib/libzlibstatic.a ../../win32/lib/libz.a
+cp ../win32/zlib.def /home/jim/packages/win32/bin
+i686-w64-mingw32-dlltool -m i386 -d ../win32/zlib.def -l /home/jim/packages/win32/bin/zlib.lib -D /home/jim/win32/packages/bin/zlib.dll
+cd ../..
+
+cd libpng
+make clean
+PKG_CONFIG_PATH="/home/jim/packages/win32/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win32/lib -static-libgcc" CPPFLAGS="-I/home/jim/packages/win32/include" ./configure -host=i686-w64-mingw32 --prefix="/home/jim/packages/win32" --enable-shared
+make -j6
+make install
+cd ..
+
+cd libogg
+make clean
+PKG_CONFIG_PATH="/home/jim/packages/win32/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win32/lib -static-libgcc" CPPFLAGS="-I/home/jim/packages/win32/include" ./configure -host=i686-w64-mingw32 --prefix="/home/jim/packages/win32" --enable-shared
+make -j6
+make install
+cd ..
+
+cd libvorbis
+make clean
+PKG_CONFIG_PATH="/home/jim/packages/win32/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win32/lib -static-libgcc" CPPFLAGS="-I/home/jim/packages/win32/include" ./configure -host=i686-w64-mingw32 --prefix="/home/jim/packages/win32" --enable-shared --with-ogg="/home/jim/packages/win32"
+make -j6
+make install
+cd ..
+
+cd libvpxbuild
+make clean
+PKG_CONFIG_PATH="/home/jim/packages/win32/lib/pkgconfig" CROSS=i686-w64-mingw32- LDFLAGS="-static-libgcc" ../libvpx/configure --prefix=/home/jim/packages/win32 --enable-vp8 --enable-vp9 --disable-docs --disable-examples --enable-shared --disable-static --enable-runtime-cpu-detect --enable-realtime-only --disable-install-bins --disable-install-docs --disable-unit-tests --target=x86-win32-gcc
+make -j6
+make install
+i686-w64-mingw32-dlltool -m i386 -d libvpx.def -l /home/jim/packages/win32/bin/vpx.lib -D /home/jim/win32/packages/bin/libvpx-1.dll
+cd ..
+
+cd ffmpeg
+make clean
+cp /media/sf_linux/nvEncodeAPI.h /home/jim/packages/win32/include
+PKG_CONFIG_PATH="/home/jim/packages/win32/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win32/lib -static-libgcc" CFLAGS="-I/home/jim/packages/win32/include" ./configure --enable-memalign-hack --enable-gpl --disable-programs --disable-doc --arch=x86 --enable-shared --enable-nvenc --enable-libx264 --enable-libopus --enable-libvorbis --enable-libvpx --disable-debug --cross-prefix=i686-w64-mingw32- --target-os=mingw32 --pkg-config=pkg-config --prefix="/home/jim/packages/win32" --disable-postproc
+read -n1 -r -p "Press any key to continue building FFmpeg..." key
+make -j6
+make install
+cd ..
diff --git a/CI/util/win64.sh b/CI/util/win64.sh
new file mode 100755
index 0000000..1ff9788
--- /dev/null
+++ b/CI/util/win64.sh
@@ -0,0 +1,69 @@
+#/bin/bash
+
+cd x264
+make clean
+LDFLAGS="-static-libgcc" ./configure --enable-shared --enable-win32thread --disable-avs --disable-ffms --disable-gpac --disable-interlaced --disable-lavf --cross-prefix=x86_64-w64-mingw32- --host=x86_64-pc-mingw32 --prefix="/home/jim/packages/win64"
+make -j6 fprofiled VIDS="CITY_704x576_60_orig_01.yuv"
+make install
+x86_64-w64-mingw32-dlltool -z /home/jim/packages/win64/bin/x264.orig.def --export-all-symbols /home/jim/packages/win64/bin/libx264-148.dll
+grep "EXPORTS\|x264" /home/jim/packages/win64/bin/x264.orig.def > /home/jim/packages/win64/bin/x264.def
+rm -f /home/jim/packages/win64/bin/x264.org.def
+sed -i -e "/\\t.*DATA/d" -e "/\\t\".*/d" -e "s/\s at .*//" /home/jim/packages/win64/bin/x264.def
+x86_64-w64-mingw32-dlltool -m i386:x86-64 -d /home/jim/packages/win64/bin/x264.def -l /home/jim/packages/win64/bin/x264.lib -D /home/jim/win64/packages/bin/libx264-148.dll
+cd ..
+
+cd opus
+make clean
+LDFLAGS="-static-libgcc" ./configure -host=x86_64-w64-mingw32 --prefix="/home/jim/packages/win64" --enable-shared
+make -j6
+make install
+cd ..
+
+cd zlib/build64
+make clean
+cmake .. -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc -DCMAKE_INSTALL_PREFIX=/home/jim/packages/win64 -DCMAKE_RC_COMPILER=x86_64-w64-mingw32-windres -DCMAKE_SHARED_LINKER_FLAGS="-static-libgcc"
+make -j6
+make install
+mv ../../win64/lib/libzlib.dll.a ../../win64/lib/libz.dll.a
+mv ../../win64/lib/libzlibstatic.a ../../win64/lib/libz.a
+cp ../win64/zlib.def /home/jim/packages/win64/bin
+x86_64-w64-mingw32-dlltool -m i386:x86-64 -d ../win32/zlib.def -l /home/jim/packages/win64/bin/zlib.lib -D /home/jim/win64/packages/bin/zlib.dll
+cd ../..
+
+cd libpng
+make clean
+PKG_CONFIG_PATH="/home/jim/packages/win64/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win64/lib" CPPFLAGS="-I/home/jim/packages/win64/include" ./configure -host=x86_64-w64-mingw32 --prefix="/home/jim/packages/win64" --enable-shared
+make -j6
+make install
+cd ..
+
+cd libogg
+make clean
+PKG_CONFIG_PATH="/home/jim/packages/win64/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win64/lib -static-libgcc" CPPFLAGS="-I/home/jim/packages/win64/include" ./configure -host=x86_64-w64-mingw32 --prefix="/home/jim/packages/win64" --enable-shared
+make -j6
+make install
+cd ..
+
+cd libvorbis
+make clean
+PKG_CONFIG_PATH="/home/jim/packages/win64/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win64/lib -static-libgcc" CPPFLAGS="-I/home/jim/packages/win64/include" ./configure -host=x86_64-w64-mingw32 --prefix="/home/jim/packages/win64" --enable-shared --with-ogg="/home/jim/packages/win64"
+make -j6
+make install
+cd ..
+
+cd libvpxbuild
+make clean
+PKG_CONFIG_PATH="/home/jim/packages/win64/lib/pkgconfig" CROSS=x86_64-w64-mingw32- LDFLAGS="-static-libgcc" ../libvpx/configure --prefix=/home/jim/packages/win64 --enable-vp8 --enable-vp9 --disable-docs --disable-examples --enable-shared --disable-static --enable-runtime-cpu-detect --enable-realtime-only --disable-install-bins --disable-install-docs --disable-unit-tests --target=x86_64-win64-gcc
+make -j6
+make install
+x86_64-w64-mingw32-dlltool -m i386:x86-64 -d libvpx.def -l /home/jim/packages/win64/bin/vpx.lib -D /home/jim/win64/packages/bin/libvpx-1.dll
+cd ..
+
+cd ffmpeg
+make clean
+cp /media/sf_linux/nvEncodeAPI.h /home/jim/packages/win64/include
+PKG_CONFIG_PATH="/home/jim/packages/win64/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win64/lib" CPPFLAGS="-I/home/jim/packages/win64/include" ./configure --enable-memalign-hack --enable-gpl --disable-doc --arch=x86_64 --enable-shared --enable-nvenc --enable-libx264 --enable-libopus --enable-libvorbis --enable-libvpx --disable-debug --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32 --pkg-config=pkg-config --prefix="/home/jim/packages/win64" --disable-postproc
+read -n1 -r -p "Press any key to continue building FFmpeg..." key
+make -j6
+make install
+cd ..
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fafd698..4e14579 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,6 +2,23 @@ cmake_minimum_required(VERSION 2.8.12)
 
 project(obs-studio)
 
+option(BUILD_CAPTIONS "Build captions" FALSE)
+
+if(WIN32)
+	if (QTDIR OR DEFINED ENV{QTDIR} OR DEFINED ENV{QTDIR32} OR DEFINED ENV{QTDIR64})
+		# Qt path set by user or env var
+	else()
+		set(QTDIR "" CACHE PATH "Path to Qt (e.g. C:/Qt/5.7/msvc2015_64)")
+		message(WARNING "QTDIR variable is missing.  Please set this variable to specify path to Qt (e.g. C:/Qt/5.7/msvc2015_64)")
+	endif()
+	if (DepsPath OR DEFINED ENV{DepsPath} OR DEFINED ENV{DepsPath32} OR DEFINED ENV{DepsPath64})
+		# Dependencies path set by user or env var
+	else()
+		set(DepsPath "" CACHE PATH "Path to compiled dependencies (e.g. D:/dependencies/win64)")
+		message(WARNING "DepsPath variable is missing.  Please set this variable to specify path to compiled dependencies (e.g. D:/dependencies/win64)")
+	endif()
+endif()
+
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
 
 include(ObsHelpers)
@@ -45,7 +62,7 @@ elseif(MSVC)
 endif()
 
 if(WIN32)
-	add_definitions(-DUNICODE -D_UNICODE)
+	add_definitions(-DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS)
 endif()
 
 if(MSVC)
diff --git a/UI/CMakeLists.txt b/UI/CMakeLists.txt
index 69cd693..0dae204 100644
--- a/UI/CMakeLists.txt
+++ b/UI/CMakeLists.txt
@@ -14,6 +14,8 @@ add_subdirectory(obs-frontend-api)
 
 project(obs)
 
+set(ENABLE_WIN_UPDATER FALSE CACHE BOOL "Enable the windows updater")
+
 if(DEFINED QTDIR${_lib_suffix})
 	list(APPEND CMAKE_PREFIX_PATH "${QTDIR${_lib_suffix}}")
 elseif(DEFINED QTDIR)
@@ -52,9 +54,27 @@ include_directories(${LIBCURL_INCLUDE_DIRS})
 add_definitions(${LIBCURL_DEFINITIONS})
 
 if(WIN32)
+	include_directories(${OBS_JANSSON_INCLUDE_DIRS})
+	include_directories(${BLAKE2_INCLUDE_DIR})
+
 	set(obs_PLATFORM_SOURCES
 		platform-windows.cpp
+		win-update/update-window.cpp
+		win-update/win-update.cpp
+		win-update/win-update-helpers.cpp
 		obs.rc)
+	set(obs_PLATFORM_HEADERS
+		win-update/update-window.hpp
+		win-update/win-update.hpp
+		win-update/win-update-helpers.hpp)
+	set(obs_PLATFORM_LIBRARIES
+		crypt32
+		blake2
+		${OBS_JANSSON_IMPORT})
+
+	if(ENABLE_WIN_UPDATER)
+		add_definitions(-DENABLE_WIN_UPDATER)
+	endif()
 elseif(APPLE)
 	set(obs_PLATFORM_SOURCES
 		platform-osx.mm)
@@ -83,19 +103,7 @@ elseif(UNIX)
 	set(obs_PLATFORM_SOURCES
 		platform-x11.cpp)
 
-	find_package(XCB COMPONENTS XCB REQUIRED RANDR REQUIRED XINERAMA REQUIRED)
-	
-	include_directories(
-		${XCB_INCLUDE_DIRS}
-		${X11_XCB_INCLUDE_DIRS})
-		
-	add_definitions(
-		${XCB_DEFINITIONS}
-		${X11_XCB_DEFINITIONS})
-
-	set(obs_PLATFORM_LIBRARIES
-		${XCB_LIBRARIES}
-		${X11_XCB_LIBRARIES}
+        set(obs_PLATFORM_LIBRARIES
                 Qt5::X11Extras)
 endif()
 
@@ -144,6 +152,7 @@ set(obs_SOURCES
 	qt-wrappers.cpp)
 
 set(obs_HEADERS
+	${obs_PLATFORM_HEADERS}
 	obs-app.hpp
 	platform.hpp
 	window-main.hpp
@@ -196,6 +205,7 @@ set(obs_UI
 	forms/OBSBasicSettings.ui
 	forms/OBSBasicSourceSelect.ui
 	forms/OBSBasicInteraction.ui
+	forms/OBSUpdate.ui
 	forms/OBSRemux.ui)
 
 set(obs_QRC
@@ -242,3 +252,6 @@ if (UNIX AND UNIX_STRUCTURE AND NOT APPLE)
 endif()
 
 add_subdirectory(frontend-plugins)
+if(WIN32)
+	add_subdirectory(win-update/updater)
+endif()
diff --git a/UI/adv-audio-control.cpp b/UI/adv-audio-control.cpp
index c17f900..b7bfd4d 100644
--- a/UI/adv-audio-control.cpp
+++ b/UI/adv-audio-control.cpp
@@ -2,9 +2,11 @@
 #include <QGridLayout>
 #include <QLabel>
 #include <QSpinBox>
+#include <QComboBox>
 #include <QCheckBox>
 #include <QSlider>
 #include "qt-wrappers.hpp"
+#include "obs-app.hpp"
 #include "adv-audio-control.hpp"
 
 #ifndef NSEC_PER_MSEC
@@ -30,11 +32,16 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_)
 	volume                         = new QSpinBox();
 	forceMono                      = new QCheckBox();
 	panning                        = new QSlider(Qt::Horizontal);
+#if defined(_WIN32) || defined(__APPLE__)
+	monitoringType                 = new QComboBox();
+#endif
 	syncOffset                     = new QSpinBox();
 	mixer1                         = new QCheckBox();
 	mixer2                         = new QCheckBox();
 	mixer3                         = new QCheckBox();
 	mixer4                         = new QCheckBox();
+	mixer5                         = new QCheckBox();
+	mixer6                         = new QCheckBox();
 
 	volChangedSignal.Connect(handler, "volume", OBSSourceVolumeChanged,
 			this);
@@ -85,6 +92,19 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_)
 	syncOffset->setMaximum(20000);
 	syncOffset->setValue(int(cur_sync / NSEC_PER_MSEC));
 
+	int idx;
+#if defined(_WIN32) || defined(__APPLE__)
+	monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.None"),
+			(int)OBS_MONITORING_TYPE_NONE);
+	monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.MonitorOnly"),
+			(int)OBS_MONITORING_TYPE_MONITOR_ONLY);
+	monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.Both"),
+			(int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT);
+	int mt = (int)obs_source_get_monitoring_type(source);
+	idx = monitoringType->findData(mt);
+	monitoringType->setCurrentIndex(idx);
+#endif
+
 	mixer1->setText("1");
 	mixer1->setChecked(mixers & (1<<0));
 	mixer2->setText("2");
@@ -93,6 +113,10 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_)
 	mixer3->setChecked(mixers & (1<<2));
 	mixer4->setText("4");
 	mixer4->setChecked(mixers & (1<<3));
+	mixer5->setText("5");
+	mixer5->setChecked(mixers & (1<<4));
+	mixer6->setText("6");
+	mixer6->setChecked(mixers & (1<<5));
 
 	panningContainer->layout()->addWidget(labelL);
 	panningContainer->layout()->addWidget(panning);
@@ -103,6 +127,8 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_)
 	mixerContainer->layout()->addWidget(mixer2);
 	mixerContainer->layout()->addWidget(mixer3);
 	mixerContainer->layout()->addWidget(mixer4);
+	mixerContainer->layout()->addWidget(mixer5);
+	mixerContainer->layout()->addWidget(mixer6);
 
 	QWidget::connect(volume, SIGNAL(valueChanged(int)),
 			this, SLOT(volumeChanged(int)));
@@ -112,6 +138,10 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_)
 			this, SLOT(panningChanged(int)));
 	QWidget::connect(syncOffset, SIGNAL(valueChanged(int)),
 			this, SLOT(syncOffsetChanged(int)));
+#if defined(_WIN32) || defined(__APPLE__)
+	QWidget::connect(monitoringType, SIGNAL(currentIndexChanged(int)),
+			this, SLOT(monitoringTypeChanged(int)));
+#endif
 	QWidget::connect(mixer1, SIGNAL(clicked(bool)),
 			this, SLOT(mixer1Changed(bool)));
 	QWidget::connect(mixer2, SIGNAL(clicked(bool)),
@@ -120,15 +150,23 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_)
 			this, SLOT(mixer3Changed(bool)));
 	QWidget::connect(mixer4, SIGNAL(clicked(bool)),
 			this, SLOT(mixer4Changed(bool)));
+	QWidget::connect(mixer5, SIGNAL(clicked(bool)),
+			this, SLOT(mixer5Changed(bool)));
+	QWidget::connect(mixer6, SIGNAL(clicked(bool)),
+			this, SLOT(mixer6Changed(bool)));
 
 	int lastRow = layout->rowCount();
 
-	layout->addWidget(nameLabel, lastRow, 0);
-	layout->addWidget(volume, lastRow, 1);
-	layout->addWidget(forceMonoContainer, lastRow, 2);
-	layout->addWidget(panningContainer, lastRow, 3);
-	layout->addWidget(syncOffset, lastRow, 4);
-	layout->addWidget(mixerContainer, lastRow, 5);
+	idx = 0;
+	layout->addWidget(nameLabel, lastRow, idx++);
+	layout->addWidget(volume, lastRow, idx++);
+	layout->addWidget(forceMonoContainer, lastRow, idx++);
+	layout->addWidget(panningContainer, lastRow, idx++);
+	layout->addWidget(syncOffset, lastRow, idx++);
+#if defined(_WIN32) || defined(__APPLE__)
+	layout->addWidget(monitoringType, lastRow, idx++);
+#endif
+	layout->addWidget(mixerContainer, lastRow, idx++);
 	layout->layout()->setAlignment(mixerContainer,
 			Qt::AlignHCenter | Qt::AlignVCenter);
 }
@@ -140,6 +178,9 @@ OBSAdvAudioCtrl::~OBSAdvAudioCtrl()
 	forceMonoContainer->deleteLater();
 	panningContainer->deleteLater();
 	syncOffset->deleteLater();
+#if defined(_WIN32) || defined(__APPLE__)
+	monitoringType->deleteLater();
+#endif
 	mixerContainer->deleteLater();
 }
 
@@ -209,6 +250,8 @@ void OBSAdvAudioCtrl::SourceMixersChanged(uint32_t mixers)
 	setCheckboxState(mixer2, mixers & (1<<1));
 	setCheckboxState(mixer3, mixers & (1<<2));
 	setCheckboxState(mixer4, mixers & (1<<3));
+	setCheckboxState(mixer5, mixers & (1<<4));
+	setCheckboxState(mixer6, mixers & (1<<5));
 }
 
 /* ------------------------------------------------------------------------- */
@@ -250,6 +293,29 @@ void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds)
 				int64_t(milliseconds) * NSEC_PER_MSEC);
 }
 
+void OBSAdvAudioCtrl::monitoringTypeChanged(int index)
+{
+	int mt = monitoringType->itemData(index).toInt();
+	obs_source_set_monitoring_type(source, (obs_monitoring_type)mt);
+
+	const char *type = nullptr;
+
+	switch (mt) {
+	case OBS_MONITORING_TYPE_NONE:
+		type = "none";
+		break;
+	case OBS_MONITORING_TYPE_MONITOR_ONLY:
+		type = "monitor only";
+		break;
+	case OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT:
+		type = "monitor and output";
+		break;
+	}
+
+	blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s",
+			obs_source_get_name(source), type);
+}
+
 static inline void setMixer(obs_source_t *source, const int mixerIdx,
 		const bool checked)
 {
@@ -281,3 +347,13 @@ void OBSAdvAudioCtrl::mixer4Changed(bool checked)
 {
 	setMixer(source, 3, checked);
 }
+
+void OBSAdvAudioCtrl::mixer5Changed(bool checked)
+{
+	setMixer(source, 4, checked);
+}
+
+void OBSAdvAudioCtrl::mixer6Changed(bool checked)
+{
+	setMixer(source, 5, checked);
+}
diff --git a/UI/adv-audio-control.hpp b/UI/adv-audio-control.hpp
index 1b16c6e..38d7608 100644
--- a/UI/adv-audio-control.hpp
+++ b/UI/adv-audio-control.hpp
@@ -9,6 +9,7 @@ class QLabel;
 class QSpinBox;
 class QCheckBox;
 class QSlider;
+class QComboBox;
 
 class OBSAdvAudioCtrl : public QObject {
 	Q_OBJECT
@@ -27,10 +28,13 @@ private:
 	QPointer<QLabel>       labelL;
 	QPointer<QLabel>       labelR;
 	QPointer<QSpinBox>     syncOffset;
+	QPointer<QComboBox>    monitoringType;
 	QPointer<QCheckBox>    mixer1;
 	QPointer<QCheckBox>    mixer2;
 	QPointer<QCheckBox>    mixer3;
 	QPointer<QCheckBox>    mixer4;
+	QPointer<QCheckBox>    mixer5;
+	QPointer<QCheckBox>    mixer6;
 
 	OBSSignal              volChangedSignal;
 	OBSSignal              syncOffsetSignal;
@@ -58,8 +62,11 @@ public slots:
 	void downmixMonoChanged(bool checked);
 	void panningChanged(int val);
 	void syncOffsetChanged(int milliseconds);
+	void monitoringTypeChanged(int index);
 	void mixer1Changed(bool checked);
 	void mixer2Changed(bool checked);
 	void mixer3Changed(bool checked);
 	void mixer4Changed(bool checked);
+	void mixer5Changed(bool checked);
+	void mixer6Changed(bool checked);
 };
diff --git a/UI/api-interface.cpp b/UI/api-interface.cpp
index 390c1da..4612100 100644
--- a/UI/api-interface.cpp
+++ b/UI/api-interface.cpp
@@ -231,7 +231,22 @@ struct OBSStudioAPI : obs_frontend_callbacks {
 
 	bool obs_frontend_recording_active(void) override
 	{
-		return main->outputHandler->StreamingActive();
+		return main->outputHandler->RecordingActive();
+	}
+
+	void obs_frontend_replay_buffer_start(void) override
+	{
+		QMetaObject::invokeMethod(main, "StartReplayBuffer");
+	}
+
+	void obs_frontend_replay_buffer_stop(void) override
+	{
+		QMetaObject::invokeMethod(main, "StopReplayBuffer");
+	}
+
+	bool obs_frontend_replay_buffer_active(void) override
+	{
+		return main->outputHandler->ReplayBufferActive();
 	}
 
 	void *obs_frontend_add_tools_menu_qaction(const char *name) override
@@ -286,6 +301,13 @@ struct OBSStudioAPI : obs_frontend_callbacks {
 		return out;
 	}
 
+	obs_output_t *obs_frontend_get_replay_buffer_output(void) override
+	{
+		OBSOutput out = main->outputHandler->replayBuffer;
+		obs_output_addref(out);
+		return out;
+	}
+
 	config_t *obs_frontend_get_profile_config(void) override
 	{
 		return main->basicConfig;
diff --git a/UI/data/locale/ar-SA.ini b/UI/data/locale/ar-SA.ini
index af10eca..f4ad127 100644
--- a/UI/data/locale/ar-SA.ini
+++ b/UI/data/locale/ar-SA.ini
@@ -49,6 +49,7 @@ Right="يمين"
 Top="أعلى"
 Bottom="أسفل"
 
+
 QuickTransitions.SwapScenes="التبديل بين مشهدي المعاينة و الاخراج بعد عملية الانتقال"
 QuickTransitions.SwapScenesTT="يقوم بتبديل مشهد المعاينة مع مشهد الاخراج بعد عملية الانتقال بين المشاهد (اذا كان مشهد الاخراج الاصلي لازال موجوداً) \n هذا لن يقوم بالتراجع عن اي تغييرات قمت بها على مشهد الاخراج الأصلي."
 QuickTransitions.DuplicateScene="استنساخ المشهد"
@@ -58,7 +59,6 @@ QuickTransitions.EditPropertiesTT="عند تحرير المشهد نفسه، ي
 QuickTransitions.HotkeyName="الانتقال السريع: %1"
 
 Basic.AddTransition="إضافة المراحل الانتقالية للتكوين"
-Basic.RemoveTransition="سلاو"
 Basic.TransitionProperties="خصائص تأثير الإنتقال"
 Basic.SceneTransitions="تأثير انتقال المشهد"
 Basic.TransitionDuration="مدة الانتقال"
@@ -88,6 +88,7 @@ ConfirmExit.Text="OBS حالياً نشط، كافة عمليات البث/ال
 ConfirmRemove.Title="تأكيد الإزالة"
 ConfirmRemove.Text="هل أنت متأكد من رغبتك في إزالة '$1' ?"
 
+
 Output.ConnectFail.Title="فشل في الاتصال"
 Output.ConnectFail.BadPath="مسار أو رابط الاتصال غير صالح. الرجاء التحقق من الإعدادات للتحقق من كونه صالح."
 Output.ConnectFail.ConnectFailed="فشل الاتصال بالسيرفر"
@@ -148,6 +149,7 @@ ScaleFiltering.Point="نقطة"
 
 Deinterlacing.Discard="تجاهل"
 
+
 Basic.Main.AddSceneDlg.Title="أضف المشهد"
 Basic.Main.AddSceneDlg.Text="الرجاء إدخال اسم المشهد"
 
diff --git a/UI/data/locale/bg-BG.ini b/UI/data/locale/bg-BG.ini
index 260ebfe..33ddabe 100644
--- a/UI/data/locale/bg-BG.ini
+++ b/UI/data/locale/bg-BG.ini
@@ -45,6 +45,7 @@ ResetOSXVSyncOnExit="Рестартиране на OSX V-синхронизац
 
 
 
+
 TitleBar.Profile="Профил"
 TitleBar.Scenes="Сцени"
 
@@ -61,6 +62,7 @@ ConfirmExit.Title="Изход от OBS?"
 ConfirmRemove.Title="Потвърди премахване"
 ConfirmRemove.Text="Наистина ли искате да премахнете \"$1\"?"
 
+
 Output.ConnectFail.Title="Неуспешно свързване"
 Output.ConnectFail.BadPath="Невалиден път или URL. Проверете дали настройките ви са валидни."
 Output.ConnectFail.ConnectFailed="Неуспешна връзка със сървъра"
@@ -112,6 +114,7 @@ Basic.Main.PreviewConextMenu.Enable="Разреши преглед"
 
 
 
+
 Basic.Main.AddSceneDlg.Title="Добави сцена"
 Basic.Main.AddSceneDlg.Text="Моля, въведете името на сцената"
 
@@ -284,10 +287,6 @@ Basic.AdvAudio.Volume="Сила на звука (%)"
 
 Basic.Settings.Hotkeys="Горещи клавиши"
 
-Basic.Hotkeys.StartStreaming="Започни стрийм"
-Basic.Hotkeys.StopStreaming="Спри стрийм"
-Basic.Hotkeys.StartRecording="Започни запис"
-Basic.Hotkeys.StopRecording="Спри запис"
 Basic.Hotkeys.SelectScene="Премини към сцена"
 
 
diff --git a/UI/data/locale/ca-ES.ini b/UI/data/locale/ca-ES.ini
index a688099..8242139 100644
--- a/UI/data/locale/ca-ES.ini
+++ b/UI/data/locale/ca-ES.ini
@@ -49,13 +49,33 @@ Right="Dreta"
 Top="Part superior"
 Bottom="Part inferior"
 Reset="Restableix"
+Hours="Hores"
+Minutes="Minuts"
+Seconds="Segons"
+Deprecated="Obsolet"
+ReplayBuffer="Memòria intermèdia de reproducció"
+Import="Importa"
+Export="Exporta"
+
+Updater.Title="Nova actualització disponible"
+Updater.Text="Hi ha una nova actualització disponible:"
+Updater.UpdateNow="Actualitza ara"
+Updater.RemindMeLater="Recordeu-m'ho més tard"
+Updater.Skip="Omet la versió"
+Updater.Running.Title="Programa actualment actiu"
+Updater.Running.Text="Les sortides estan actives actualment, apagueu qualsevol sortida activa abans d'intentar actualitzar"
+Updater.NoUpdatesAvailable.Title="No hi ha actualitzacions disponibles"
+Updater.NoUpdatesAvailable.Text="Actualment no hi ha actualitzacions disponibles"
+Updater.FailedToLaunch="No s'han pogut executar l'actualitzador"
+Updater.GameCaptureActive.Title="Captura de joc activa"
+Updater.GameCaptureActive.Text="La llibreria de captura de jocs està actualment en ús. Tanqueu qualsevol joc/programa que estigui sent capturat (o reinicieu Windows) i proveu-ho de nou."
 
 QuickTransitions.SwapScenes="Canvia la vista prèvia i sortida d'escenes després de la transició"
 QuickTransitions.SwapScenesTT="Canvia la vista prèvia i sortida d'escenes després de la transició (si encara existeix l'escena original de la sortida). \nAixò no desfarà qualsevol canvi que pugui haver fet a l'escena original de la sortida."
 QuickTransitions.DuplicateScene="Duplica l'escena"
-QuickTransitions.DuplicateSceneTT="Al editar la misma escena, permite la edición transformar/visibilidad de fuentes sin modificar las salida.\nPer editar les propietats de les fonts sense modificar la sortida, activi 'Duplicar Fonts'.\nCanviant aquest valor restablirà l'escena actual de sortida (si encara existeix)."
+QuickTransitions.DuplicateSceneTT="En editar la mateixa escena, permet editar la visibilitat i transformació de les fonts sense modificar la sortida.\nPer editar les propietats de les fonts sense modificar la sortida, activeu «Duplicar Fonts».\nSi canvieu aquest valor es restablirà l'escena actual de la sortida (si encara existeix)."
 QuickTransitions.EditProperties="Duplica les fonts"
-QuickTransitions.EditPropertiesTT="En editar la mateixa escena, permeti editar propietats de fonts sense modificar la sortida.\n Això només es pot utilitzar si està activat 'Duplicar l'escena'.\nCertes fonts (tals com a fonts de captura o els mitjans de comunicació) no són compatibles amb això i no es poden editar per separat.\nCanviant aquest valor restablirà l'escena actual de sortida (si encara existeix).\n\nAdvertiment: com es duplicaran les fonts, això requerirà un extra de recursos del sistema i de vídeo."
+QuickTransitions.EditPropertiesTT="En editar la mateixa escena, permet editar les propietats de les fonts sense modificar la sortida.\nAixò només es pot utilitzar si s'ha activat «Duplicar l'escena».\nAlgunes fonts (com dispositius de captura o mèdia) no ho permeten i no es poden editar per separat.\nSi canvieu aquest valor es restablirà l'escena actual de la sortida (si encara existeix).\n\nAtenció: com que es duplicaran les fonts, poden ser necessaris més recursos del sistema o de vídeo."
 QuickTransitions.HotkeyName="Transició Ràpida: %1"
 
 Basic.AddTransition="Afegir transició configurable"
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Confirmeu la supressió"
 ConfirmRemove.Text="Esteu segur que voleu suprimir «$1»?"
 ConfirmRemove.TextMultiple="¿Segur que vols esborrar %1 elements?"
 
+Output.StartStreamFailed="No s'ha pogut iniciar la transmissió"
+Output.StartRecordingFailed="No s'ha pogut iniciar la gravació"
+Output.StartReplayFailed="No s'ha pogut iniciar la memòria intermèdia de reproducció"
+Output.StartFailedGeneric="Error en iniciar la sortida. Comproveu el registre per més detalls.\n\nAvís: Si utilitzeu els codificadors NVENC o AMD, assegureu-vos que els controladors de vídeo estan actualitzats."
+
 Output.ConnectFail.Title="Error en connectar"
 Output.ConnectFail.BadPath="Ruta o adreça URL no vàlida.  Si us plau, comproveu la configuració per confirmar que són vàlids."
 Output.ConnectFail.ConnectFailed="No ha pogut connectar al servidor"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="Espai de disc insuficient"
 Output.RecordNoSpace.Msg="No hi ha prou espai de disc per continuar la gravació."
 Output.RecordError.Title="Error en l'enregistrament"
 Output.RecordError.Msg="S'ha produït un error desconegut mentre es gravava."
+Output.ReplayBuffer.NoHotkey.Title="Cap tecla d'accés ràpid!"
+Output.ReplayBuffer.NoHotkey.Msg="Cap tecla d'accés ràpid establerta per la memòria intermèdia de reproducció. Configureu la tecla d'accés \"Desa\" per desar els enregistraments de reproducció."
 
 Output.BadPath.Title="Ruta de l'arxiu incorrecta"
 Output.BadPath.Text="La ruta configurada pel fitxer de sortida no és vàlida.  Si us plau, comproveu la configuració per confirmar que s'ha creat una ruta de fitxer vàlida."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Camp superior primer"
 Deinterlacing.BottomFieldFirst="Camp inferior primer"
 
+VolControl.SliderUnmuted="Control lliscant del volum per '%1': %2"
+VolControl.SliderMuted="Control lliscant del volum per '%1': %2 (silenciat)"
+VolControl.Mute="Silencia '%1'"
+VolControl.Properties="Propietats per '%1'"
+
 Basic.Main.AddSceneDlg.Title="Afegeix una escena"
 Basic.Main.AddSceneDlg.Text="Introduïu el nom de l'escena"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Escenes"
 Basic.Main.Sources="Orígens"
 Basic.Main.Connecting="S'està connectant..."
 Basic.Main.StartRecording="Inicia l'enregistrament"
-Basic.Main.StartStreaming="Inicia l'enregistrament"
+Basic.Main.StartReplayBuffer="Inicia la reproducció de la memòria intermèdia"
+Basic.Main.StartStreaming="Inicia la transmissió"
 Basic.Main.StopRecording="Atura l'enregistrament"
 Basic.Main.StoppingRecording="Aturant l'enregistrament..."
+Basic.Main.StopReplayBuffer="Atura la reproducció de la memòria intermèdia"
+Basic.Main.StoppingReplayBuffer="S'està aturant la reproducció de la memòria intermèdia..."
 Basic.Main.StopStreaming="Atura l'enregistrament"
 Basic.Main.StoppingStreaming="Aturant la transmissió..."
 Basic.Main.ForceStopStreaming="Atura l'enregistrament (descarta el retard)"
@@ -270,7 +305,7 @@ Basic.MainMenu.File.Export="&Exporta"
 Basic.MainMenu.File.Import="&Importa"
 Basic.MainMenu.File.ShowRecordings="Mostra els en&registraments"
 Basic.MainMenu.File.Remux="Converteix format de gravacions"
-Basic.MainMenu.File.Settings="&Paràmetres"
+Basic.MainMenu.File.Settings="&Configuració"
 Basic.MainMenu.File.ShowSettingsFolder="Mostrar carpeta de configuració"
 Basic.MainMenu.File.ShowProfileFolder="Mostra la carpeta del perfil"
 Basic.MainMenu.AlwaysOnTop="&Sempre al davant"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="&Refés"
 Basic.MainMenu.Edit.UndoAction="&Desfés $1"
 Basic.MainMenu.Edit.RedoAction="&Refés $1"
 Basic.MainMenu.Edit.LockPreview="&Bloquejar vista prèvia"
+Basic.MainMenu.Edit.Scale="Vista prèvia i escalat"
+Basic.MainMenu.Edit.Scale.Window="Ajusta a la finestra"
+Basic.MainMenu.Edit.Scale.Canvas="Tela (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Sortida (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Transforma"
 Basic.MainMenu.Edit.Transform.EditTransform="&Editar Transformació..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Copia la transformació"
+Basic.MainMenu.Edit.Transform.PasteTransform="Enganxa la transformació"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Reinicialitza Transformació"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Gira 90 graus a la dreta"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Gira 90 graus a l'esquerra"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="Barra d'estat"
 
 Basic.MainMenu.SceneCollection="&Col·lecció d'escenes"
 Basic.MainMenu.Profile="&Perfil"
+Basic.MainMenu.Profile.Import="Importació del perfil"
+Basic.MainMenu.Profile.Export="Exportació del perfil"
+Basic.MainMenu.SceneCollection.Import="Importa col·lecció d'escenes"
+Basic.MainMenu.SceneCollection.Export="Exporta la col·lecció d'escenes"
+Basic.MainMenu.Profile.Exists="El perfil ja existeix"
+Basic.MainMenu.SceneCollection.Exists="La col·lecció d'escenes ja existeix"
 
 Basic.MainMenu.Tools="&Eines"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="Hi han canvis no desats.  Voleu desar els canvis?"
 Basic.Settings.General="General"
 Basic.Settings.General.Theme="Tema"
 Basic.Settings.General.Language="Llengua"
+Basic.Settings.General.EnableAutoUpdates="Comprova si hi ha actualitzacions automàticament a l'inici"
 Basic.Settings.General.WarnBeforeStartingStream="Mostra diàleg de confirmació quan s'iniciï una transmissió"
 Basic.Settings.General.WarnBeforeStoppingStream="Mostra diàleg de confirmació quan s'aturi una transmissió"
+Basic.Settings.General.Projectors="Projectors"
 Basic.Settings.General.HideProjectorCursor="Amaga el cursor sobre projectors"
 Basic.Settings.General.ProjectorAlwaysOnTop="Projectors sempre en la part superior"
 Basic.Settings.General.Snapping="Ajustament d'alineació de la font"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Ajustar les fonts a altres fonts"
 Basic.Settings.General.SnapDistance="Ajusta la sensibilitat"
 Basic.Settings.General.RecordWhenStreaming="Enregistra automàticament quan es transmet"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Mantenir l'enregistrament quan s'atura la transmissió"
-Basic.Settings.General.SysTrayEnabled="Activar icona a la safata del sistema"
+Basic.Settings.General.ReplayBufferWhileStreaming="Inicia la reproducció de la memòria intermèdia automàticament durant la transmissió"
+Basic.Settings.General.KeepReplayBufferStreamStops="Mantén activa la memòria intermèdia de reproducció quan la transmissió s'aturi"
+Basic.Settings.General.SysTray="Safata del sistema"
 Basic.Settings.General.SysTrayWhenStarted="Minimitzar a la safata del sistema en iniciar"
+Basic.Settings.General.SystemTrayHideMinimize="Minimitza sempre a la safata del sistema en lloc de la barra de tasques"
+Basic.Settings.General.SaveProjectors="Desa els projectors en sortir"
 
 Basic.Settings.Stream="Directe"
 Basic.Settings.Stream.StreamType="Tipus de directe"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="Mode de sortida"
 Basic.Settings.Output.Mode.Simple="Simple"
 Basic.Settings.Output.Mode.Adv="Avançat"
 Basic.Settings.Output.Mode.FFmpeg="Sortida FFmpeg"
+Basic.Settings.Output.UseReplayBuffer="Activa la reproducció de la memòria intermèdia"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Temps de reproducció màxim (segons)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memòria màxima (MB)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Ús aproximat de memòria: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="No es pot estimar l'ús de memòria. Establiu el límit màxim de memòria."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Nota: Assegureu-vos d'establir una tecla d'accés ràpid per la memòria intermèdia de reproducció a la secció de tecles ràpides)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Prefix del nom del fitxer de la memòria intermèdia"
+Basic.Settings.Output.ReplayBuffer.Suffix="Sufix"
 Basic.Settings.Output.Simple.SavePath="Camí d'enregistrament"
 Basic.Settings.Output.Simple.RecordingQuality="Qualitat de l'enregistrament"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Mateixa que en directe"
@@ -369,6 +430,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Advertiment de qualitat sense
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Advertència: No es poden utilitzar diversos descodificadors QSV separats en transmetre i enregistrar al mateix temps. Per transmetre i engrestriar al mateix temps, si us plau modifiqueu-los, ja sigui el codificador de gravació o el codificador de transmissió."
 Basic.Settings.Output.Simple.Encoder.Software="Programari (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Maquinari (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Maquinari (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Maquinari (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Programari (preconfiguració de x264 amb baix ús de CPU, augmenta la mida del fitxer)"
 Basic.Settings.Output.VideoBitrate="Bitrate de vídeo"
@@ -390,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Pista 1"
 Basic.Settings.Output.Adv.Audio.Track2="Pista 2"
 Basic.Settings.Output.Adv.Audio.Track3="Pista 3"
 Basic.Settings.Output.Adv.Audio.Track4="Pista 4"
+Basic.Settings.Output.Adv.Audio.Track5="Pista 5"
+Basic.Settings.Output.Adv.Audio.Track6="Pista 6"
 
 Basic.Settings.Output.Adv.Recording="Enregistrament"
 Basic.Settings.Output.Adv.Recording.Type="Tipus"
@@ -417,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Configuració del codificador
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador d'àudio"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Configuració de codificador d'àudio (si escau)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Configuració del convertidor (si escau)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Interval de fotogrames clau (fotogrames)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Mostra tots els codificadors (encara que siguin potencialment incompatibles)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -470,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="Espai de color YUV"
 Basic.Settings.Advanced.Video.ColorRange="Gamma de color YUV"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Parcial"
 Basic.Settings.Advanced.Video.ColorRange.Full="Màxima"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositiu de monitorització d'àudio"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Per defecte"
 Basic.Settings.Advanced.StreamDelay="Retard del directe"
 Basic.Settings.Advanced.StreamDelay.Duration="Durada (en segons)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Preservar el punt de tall (augmenta retard) quan s'estigui reconnectant"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Ús de memòria estimat: %1 MB"
 Basic.Settings.Advanced.Network="Xarxa"
 Basic.Settings.Advanced.Network.BindToIP="Enllaçar amb"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Activa el nou codi de xarxa"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mode de baixa latència"
 
 Basic.AdvAudio="&Propietats avançades d'àudio"
 Basic.AdvAudio.Name="Nom"
@@ -483,19 +553,19 @@ Basic.AdvAudio.Volume="Volum (%)"
 Basic.AdvAudio.Mono="Mescla a Mono"
 Basic.AdvAudio.Panning="Balanç"
 Basic.AdvAudio.SyncOffset="Correcció de sincronització (ms)"
+Basic.AdvAudio.Monitoring="Monitorització d'àudio"
+Basic.AdvAudio.Monitoring.None="Monitorització desactivada"
+Basic.AdvAudio.Monitoring.MonitorOnly="Només monitorizació (silencia la sortida)"
+Basic.AdvAudio.Monitoring.Both="Monitorització i sortida"
 Basic.AdvAudio.AudioTracks="Pistes"
 
 Basic.Settings.Hotkeys="Dreceres de teclat"
 Basic.Settings.Hotkeys.Pair="Combinacions de tecles compartides amb '%1' actuen com a palanques"
 
-Basic.Hotkeys.StartStreaming="Inicia el directe"
-Basic.Hotkeys.StopStreaming="Atura el directe"
-Basic.Hotkeys.StartRecording="Inicia l'enregistrament"
-Basic.Hotkeys.StopRecording="Atura l'enregistrament"
 Basic.Hotkeys.SelectScene="Canviar a escena"
 
 Basic.SystemTray.Show="Mostra"
-Basic.SystemTray.Hide="Oculta"
+Basic.SystemTray.Hide="Amaga"
 
 Basic.SystemTray.Message.Reconnecting="Desconnectat. Tornant a connectar..."
 
@@ -545,4 +615,5 @@ SceneItemHide="Amaga «%1»"
 
 OutputWarnings.NoTracksSelected="Heu de seleccionar almenys una cançó"
 OutputWarnings.MultiTrackRecording="Advertiment: Alguns formats (com FLV) no suporten múltiples cançons per gravació"
+OutputWarnings.MP4Recording="Advertència: Els enregistraments desats en MP4 seran irrecuperables si l'arxiu no va poder finalitzar (p.ex. com a resultat de BSODs, pèrdues de potència, etc.). Si voleu enregistrar diverses pistes d'àudio utilitzi MKV i multiplexeu l'enregistrament a MP4 després que acabi (Fitxer-> Multiplexació d'enregistraments)"
 
diff --git a/UI/data/locale/cs-CZ.ini b/UI/data/locale/cs-CZ.ini
index 3504259..838de27 100644
--- a/UI/data/locale/cs-CZ.ini
+++ b/UI/data/locale/cs-CZ.ini
@@ -49,6 +49,26 @@ Right="Vpravo"
 Top="Nahoře"
 Bottom="Dole"
 Reset="Resetovat"
+Hours="Hodiny"
+Minutes="Minuty"
+Seconds="Vteřiny"
+Deprecated="Zastaralé"
+ReplayBuffer="Záznam do paměti"
+Import="Importovat"
+Export="Exportovat"
+
+Updater.Title="Aktualizace"
+Updater.Text="K dispozici je nová verze:"
+Updater.UpdateNow="Aktualizovat nyní"
+Updater.RemindMeLater="Upozornit později"
+Updater.Skip="Přeskočit verzi"
+Updater.Running.Title="Program je stále aktivní"
+Updater.Running.Text="Některé výstupy jsou stále aktivní, zastavte je, prosím, před další pokusem o aktualizaci"
+Updater.NoUpdatesAvailable.Title="Žádná aktualizace"
+Updater.NoUpdatesAvailable.Text="Není dostupná žádná novější verze"
+Updater.FailedToLaunch="Nepodařilo se spustit aktualizátor"
+Updater.GameCaptureActive.Title="Snímání hry"
+Updater.GameCaptureActive.Text="Knihovna pro snímání her je aktivní. Ukončete prosím všechny snímané hry/programy (nebo restartujte Windows) a zkuste to znovu."
 
 QuickTransitions.SwapScenes="Prohodit scény náhledu a výstupu po přechodu"
 QuickTransitions.SwapScenesTT="Prohodí scény náhledu a výstupu po přechodu (pokud originální výstupní scéna stále existuje).\nTato funkce nevrátí provedené změny, které byly provedeny v originální scéně výstupu."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Potvrzení odebrání"
 ConfirmRemove.Text="Opravdu si přejete odebrat '$1'?"
 ConfirmRemove.TextMultiple="Opravdu si přejete odebrat %1 položky ?"
 
+Output.StartStreamFailed="Chyba při spouštění vysílání"
+Output.StartRecordingFailed="Chyba při spouštění nahrávání"
+Output.StartReplayFailed="Chyba při spouštění nahrávání do paměti"
+Output.StartFailedGeneric="Nastala chyba při začátku nahrávání. Zkontrolujte, prosím, textový záznam pro další podrobnosti.\n\nPoznámka: Pokud používáte enkodér NVENC či AMD, zkontrolujte zda používáte aktuální verzi grafického ovladače."
+
 Output.ConnectFail.Title="Spojení se nezdařilo"
 Output.ConnectFail.BadPath="Chybná cesta nebo adresa připojení. Zkontrolujte, prosím, správnost svých nastavení."
 Output.ConnectFail.ConnectFailed="K serveru se nepodařilo připojit"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="Nedostatek místa na disku"
 Output.RecordNoSpace.Msg="Pro pokračování nahrávání není dostatek místa na disku."
 Output.RecordError.Title="Chyba při nahrávání"
 Output.RecordError.Msg="Při nahrávání došlo k nespecifikované chybě."
+Output.ReplayBuffer.NoHotkey.Title="Nepřiřazena žádná klávesová zkratka!"
+Output.ReplayBuffer.NoHotkey.Msg="Není nastavena žádná klávesová zkratka pro uložení záznamu. Nastavte ji prosím, abyste jej mohli ukládat."
 
 Output.BadPath.Title="Špatná cesta k souboru"
 Output.BadPath.Text="Nastavená cesta k výstupnímu souboru je chybná. Zkontrolujte nastavení, zda není cesta špatně napsána."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Svrchní řádek dříve"
 Deinterlacing.BottomFieldFirst="Spodní řádek dříve"
 
+VolControl.SliderUnmuted="Posuvník hlasitosti pro '%1': %2"
+VolControl.SliderMuted="Posuvník hlasitosti pro '%1': %2 (ztlumeno)"
+VolControl.Mute="Ztlumit '%1'"
+VolControl.Properties="Vlastnosti pro \"%1\""
+
 Basic.Main.AddSceneDlg.Title="Přidat scénu"
 Basic.Main.AddSceneDlg.Text="Prosím, zadejte jméno scény"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Scény"
 Basic.Main.Sources="Zdroje"
 Basic.Main.Connecting="Připojování..."
 Basic.Main.StartRecording="Začít nahrávat"
+Basic.Main.StartReplayBuffer="Spustit záznam do paměti"
 Basic.Main.StartStreaming="Začít vysílat"
 Basic.Main.StopRecording="Zastavit nahrávání"
 Basic.Main.StoppingRecording="Zastavuji nahrávání..."
+Basic.Main.StopReplayBuffer="Zastavit záznam do paměti"
+Basic.Main.StoppingReplayBuffer="Zastavuji záznam do paměti..."
 Basic.Main.StopStreaming="Zastavit vysílání"
 Basic.Main.StoppingStreaming="Zastavuji vysílání..."
 Basic.Main.ForceStopStreaming="Zastavit vysání (bez zpoždění)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="Znovu (&R)"
 Basic.MainMenu.Edit.UndoAction="Zpět $1 (&U)"
 Basic.MainMenu.Edit.RedoAction="Znovu $1 (&R)"
 Basic.MainMenu.Edit.LockPreview="Uzamknout náh&led"
+Basic.MainMenu.Edit.Scale="Škálování náhledu (&S)"
+Basic.MainMenu.Edit.Scale.Window="Škálovat na okno"
+Basic.MainMenu.Edit.Scale.Canvas="Editor (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Výstup (%1x%2)"
 Basic.MainMenu.Edit.Transform="Pozicování (&T)"
 Basic.MainMenu.Edit.Transform.EditTransform="Upravit pozici... (&E)"
+Basic.MainMenu.Edit.Transform.CopyTransform="Kopírovat transformaci"
+Basic.MainMenu.Edit.Transform.PasteTransform="Vložit transformaci"
 Basic.MainMenu.Edit.Transform.ResetTransform="Obnovit pozici (&R)"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Otočit o 90 stupňů vpravo"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Otočit o 90 stupňů vlevo"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="&Stavový řádek"
 
 Basic.MainMenu.SceneCollection="Kolekce &scén"
 Basic.MainMenu.Profile="&Profil"
+Basic.MainMenu.Profile.Import="Importovat profil"
+Basic.MainMenu.Profile.Export="Exportovat profil"
+Basic.MainMenu.SceneCollection.Import="Importovat kolekci scén"
+Basic.MainMenu.SceneCollection.Export="Exportovat kolekci scén"
+Basic.MainMenu.Profile.Exists="Tento profil již existuje"
+Basic.MainMenu.SceneCollection.Exists="Tato kolekce scén již existuje"
 
 Basic.MainMenu.Tools="Nás&troje"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="Některé změny nejsou uložené. Chcete je uložit nyn
 Basic.Settings.General="Hlavní"
 Basic.Settings.General.Theme="Vzhled"
 Basic.Settings.General.Language="Jazyk"
+Basic.Settings.General.EnableAutoUpdates="Automaticky kontrolovat aktualizace při spuštění"
 Basic.Settings.General.WarnBeforeStartingStream="Vyžadovat potvrzení pro spuštění vysílání"
 Basic.Settings.General.WarnBeforeStoppingStream="Vyžadovat potvrzení pro ukončení vysílání"
+Basic.Settings.General.Projectors="Projektory"
 Basic.Settings.General.HideProjectorCursor="Skrýt kurzor přes projektor"
 Basic.Settings.General.ProjectorAlwaysOnTop="Zobrazovat projektor vždy navrchu"
 Basic.Settings.General.Snapping="Přichycování zdrojů"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Přichytávat zdroje k ostatním zdrojům
 Basic.Settings.General.SnapDistance="Citlivost přichycení"
 Basic.Settings.General.RecordWhenStreaming="Automaticky nahrávat při vysílání"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Pokračovat v nahrávání i po zastavení vysílání"
-Basic.Settings.General.SysTrayEnabled="Zobrazit ikonu v oznamovací oblasti"
+Basic.Settings.General.ReplayBufferWhileStreaming="Automaticky zapnout záznam do paměti se začátkem vysílání"
+Basic.Settings.General.KeepReplayBufferStreamStops="Ponechat záznam do paměti aktivní i po ukončení vysílání"
+Basic.Settings.General.SysTray="Systémová lišta"
 Basic.Settings.General.SysTrayWhenStarted="Minimalizovat do systémové lišty při spuštění"
+Basic.Settings.General.SystemTrayHideMinimize="Vždy minimalizovat do systémové lišty místo hlavního panelu"
+Basic.Settings.General.SaveProjectors="Při ukončení uložit projektory"
 
 Basic.Settings.Stream="Vysílání"
 Basic.Settings.Stream.StreamType="Typ vysílání"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="Režim výstupu"
 Basic.Settings.Output.Mode.Simple="Jednoduché"
 Basic.Settings.Output.Mode.Adv="Rozšířené"
 Basic.Settings.Output.Mode.FFmpeg="Výstup FFmpeg"
+Basic.Settings.Output.UseReplayBuffer="Povolit záznam od paměti"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximální čas záznamu (s)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximální využití paměti (MB)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Přibližné využití paměti: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nedokáži odhadnout využití paměti. Nastavte, prosím, maximální využití paměti."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Poznámka: Nezapomeňte si nastavit klávesovou zkratku pro tuto funkci)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Přípona souboru záznamu do paměti"
+Basic.Settings.Output.ReplayBuffer.Suffix="Přípona"
 Basic.Settings.Output.Simple.SavePath="Cesta pro nahrávání"
 Basic.Settings.Output.Simple.RecordingQuality="Nahrávací kvalita"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Stejná jako vysílaná"
@@ -369,6 +430,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Varování nastavené kvality!
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Varování: Není možné použit více oddělených QSV enkodérů pro streamování a nahrávání ve stejnou dobu. Pokud chcete tuto limitaci obejít, tak změňte použitý enkodér pro streamování či nahrávání."
 Basic.Settings.Output.Simple.Encoder.Software="Softwarový (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardwarový (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardwarový (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardwarový (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softwarový (x264 předvolba nízkého zatížení CPU, větší soubory)"
 Basic.Settings.Output.VideoBitrate="Bitrate videa"
@@ -390,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Stopa 1"
 Basic.Settings.Output.Adv.Audio.Track2="Stopa 2"
 Basic.Settings.Output.Adv.Audio.Track3="Stopa 3"
 Basic.Settings.Output.Adv.Audio.Track4="Stopa 4"
+Basic.Settings.Output.Adv.Audio.Track5="Stopa 5"
+Basic.Settings.Output.Adv.Audio.Track6="Stopa 6"
 
 Basic.Settings.Output.Adv.Recording="Nahrávání"
 Basic.Settings.Output.Adv.Recording.Type="Typ"
@@ -417,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Nastavení enkodéru obrazu (
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Enkodér zvuku"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Nastavení enkodéru zvuku (pokud existuje)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Nastavení směšovače (pokud existuje)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Interval klíčových snímků (snímky)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Zobrazit všechny kodeky (i když je možné, že nejsou kompatibilní)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -470,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="Barevný prostor YUV"
 Basic.Settings.Advanced.Video.ColorRange="Oblast barev YUV"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Částečné"
 Basic.Settings.Advanced.Video.ColorRange.Full="Plné"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Zařízení pro monitorování zvuku"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Výchozí"
 Basic.Settings.Advanced.StreamDelay="Zpoždění vysílání"
 Basic.Settings.Advanced.StreamDelay.Duration="Délka (vteřiny)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Zachovat zpoždění při obnovení spojení (zvýšení zpoždění)"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Přibližné využití paměti: %1 MB"
 Basic.Settings.Advanced.Network="Síť"
 Basic.Settings.Advanced.Network.BindToIP="Svázat s adresou"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Použít nový síťový kód"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Režim nízké odezvy"
 
 Basic.AdvAudio="Rozšířené vlastnosti zvuku"
 Basic.AdvAudio.Name="Název"
@@ -483,15 +553,15 @@ Basic.AdvAudio.Volume="Hlasitost (%)"
 Basic.AdvAudio.Mono="Převést na Mono"
 Basic.AdvAudio.Panning="Pozicování"
 Basic.AdvAudio.SyncOffset="Zpoždění synchronizace (ms)"
+Basic.AdvAudio.Monitoring="Monitorování zvuku"
+Basic.AdvAudio.Monitoring.None="Monitorování vypnuto"
+Basic.AdvAudio.Monitoring.MonitorOnly="Pouhé monitorování (ztlumit výstup)"
+Basic.AdvAudio.Monitoring.Both="Monitorovat a odesílat na výstup"
 Basic.AdvAudio.AudioTracks="Stopy"
 
 Basic.Settings.Hotkeys="Zkratky"
 Basic.Settings.Hotkeys.Pair="Kombinace kláves je sdílená s '%1' funguje jako přepínač"
 
-Basic.Hotkeys.StartStreaming="Začít vysílat"
-Basic.Hotkeys.StopStreaming="Zastavit vysílání"
-Basic.Hotkeys.StartRecording="Začít nahrávat"
-Basic.Hotkeys.StopRecording="Zastavit nahrávání"
 Basic.Hotkeys.SelectScene="Přepnout na scénu"
 
 Basic.SystemTray.Show="Zobrazit"
@@ -545,4 +615,5 @@ SceneItemHide="Skrýt '%1'"
 
 OutputWarnings.NoTracksSelected="Musíte vybrat alespoň jednu stopu"
 OutputWarnings.MultiTrackRecording="Varování: Některé formáty (např. FLV) nepodporují více zvukových stop na nahrávku"
+OutputWarnings.MP4Recording="Varování: Nahrávky uložené v MP4 nebude možné obnovit, pokud soubor nemohl být dokončen (např. po BSOD, výpadku napájení atp.). Pokud chcete nahrávat více zvukových stop, promyslete použití MKV a poté převodení do MP4 (Soubor -> Převést nahrávky)"
 
diff --git a/UI/data/locale/da-DK.ini b/UI/data/locale/da-DK.ini
index 251a738..097e923 100644
--- a/UI/data/locale/da-DK.ini
+++ b/UI/data/locale/da-DK.ini
@@ -4,11 +4,11 @@ Region="Danmark"
 
 OK="OK"
 Apply="Anvend"
-Cancel="Annuller"
+Cancel="Annullér"
 Close="Luk"
 Save="Gem"
 Discard="Kassér"
-Disable="Deaktiver"
+Disable="Deaktivér"
 Yes="Ja"
 No="Nej"
 Add="Tilføj"
@@ -27,10 +27,10 @@ Mixer="Mixer"
 Browse="Browse"
 Mono="Mono"
 Stereo="Stereo"
-DroppedFrames="Taber frames %1 (%2%)"
-PreviewProjector="Fuldskærms projektering (forhåndsvisning)"
-SceneProjector="Fuldskærms projektering (scene)"
-SourceProjector="Fuldskærms projektering (kilde)"
+DroppedFrames="Tabte frames %1 (%2%)"
+PreviewProjector="Fuldskærmsprojektering (forhåndsvisning)"
+SceneProjector="Fuldskærmsprojektering (scene)"
+SourceProjector="Fuldskærmsprojektering (kilde)"
 Clear="Ryd"
 Revert="Gendan"
 Show="Vis"
@@ -49,10 +49,33 @@ Right="Højre"
 Top="Top"
 Bottom="Bund"
 Reset="Nulstil"
+Hours="Timer"
+Minutes="Minutter"
+Seconds="Sekunder"
+Deprecated="Ophørt"
+ReplayBuffer="Genafspilningsbuffer"
+Import="Importér"
+Export="Eksportér"
+
+Updater.Title="Ny opdatering tilgængelig"
+Updater.Text="Der er en ny opdatering tilgængelig:"
+Updater.UpdateNow="Opdater nu"
+Updater.RemindMeLater="PÃ¥mind mig senere"
+Updater.Skip="Spring versionen over"
+Updater.Running.Title="Program er aktivt i øjeblikket"
+Updater.Running.Text="Outputs er aktive i øjeblikket. Luk venligst alle aktive outputs før forsøg på opdatering"
+Updater.NoUpdatesAvailable.Title="Ingen opdateringer tilgængelige"
+Updater.NoUpdatesAvailable.Text="Ingen opdateringer er tilgængelige i øjeblikket"
+Updater.FailedToLaunch="Kunne ikke starte opdatering"
+Updater.GameCaptureActive.Title="Spil capture aktiv"
+Updater.GameCaptureActive.Text="Spil capture fangstbibliotek er i brug i øjeblikket. Luk venligst alle spil/programmer der bliver captured (eller genstart windows) og prøv igen."
 
 QuickTransitions.SwapScenes="Byt om på forhåndsvisning/output scener efter overgang"
+QuickTransitions.SwapScenesTT="Ombytter uddrag- og output-scener efter omskiftning (hvis oprindelige output-scene stadig eksisterer).\nDette vil ikke omgøre eventuelle ændringer, der måtte været udført på den oprindelige output-scene."
 QuickTransitions.DuplicateScene="Dupliker scene"
+QuickTransitions.DuplicateSceneTT="Muliggør, ved redigere af den samme, scene, redigering af transformering/synlighed af kilder uden at ændre på output. \nFor at rediger egenskaber for kilder uden at ændre på output, aktivér 'Duplikér Kilder'.\nÆndring af denne værd vil nulstille den nuværende output-scene (hvis den stadig findes)."
 QuickTransitions.EditProperties="Dupliker kilder"
+QuickTransitions.EditPropertiesTT="Muliggør, ved redigering af den samme scene, redigering af egenskaber for kilder uden at ændre på output.\nDette kan kun benyttes, hvis 'Duplikér Scene' er aktiv. \nVisse kilder (såsom optagne kilder eller mediekilder) understøtter ikke dette og kan ikke redigeres separat.\nÆndring af denne værdi vil nulstille den nuværende output-scene (hvis den stadig findes).\n\nAdvarsel: Da kilder vil blive duplikeret, kan dette kræve ekstra system- eller videoressourcer."
 QuickTransitions.HotkeyName="Hurtig overgang: %1"
 
 Basic.AddTransition="Tilføj konfigurerbar overgang"
@@ -85,6 +108,12 @@ ConfirmExit.Text="OBS er aktiv i øjeblikket. Alle streams/optagelser vil blive
 
 ConfirmRemove.Title="Bekræfte fjern"
 ConfirmRemove.Text="Er du sikker på du ønsker at fjerne '$1'?"
+ConfirmRemove.TextMultiple="Er du sikker på at du vil fjerne %1 elementer?"
+
+Output.StartStreamFailed="Kunne ikke starte streaming"
+Output.StartRecordingFailed="Kunne ikke begynde optagelsen"
+Output.StartReplayFailed="Kunne ikke starte replay buffer"
+Output.StartFailedGeneric="Start af output mislykkedes. Kontroller venligst loggen for oplysninger.\n\nBemærk: Hvis du bruger NVENC eller AMD encoder, så sørg for at dine video drivere er opdateret."
 
 Output.ConnectFail.Title="Kunne ikke oprette forbindelse"
 Output.ConnectFail.BadPath="Ugyldig sti eller forbindelses URL.  Kontroller indstillinger for at bekræfte, at de er gyldige."
@@ -99,6 +128,8 @@ Output.RecordNoSpace.Title="Utilstrækkelig diskplads"
 Output.RecordNoSpace.Msg="Der er ikke tilstrækkelig diskplads til at fortsætte optagelsen."
 Output.RecordError.Title="Optagelsesfejl"
 Output.RecordError.Msg="Der opstod en uangivet fejl under optagelsen."
+Output.ReplayBuffer.NoHotkey.Title="Ingen genvejstast sat!"
+Output.ReplayBuffer.NoHotkey.Msg="Ingen Gem-genvejstast sat til genafspilningsbuffer. Sæt venligst \"Gem\"-genvejstasten til brug for at gemme genafspilningsoptagelser."
 
 Output.BadPath.Title="DÃ¥rlig filsti"
 Output.BadPath.Text="Den konfigureret output sti er ugyldig. Kontroller indstillinger for at bekræfte, at en gyldig filsti er angivet."
@@ -116,6 +147,7 @@ LicenseAgreement.Exit="Afslut"
 Remux.SourceFile="OBS optagelse"
 Remux.TargetFile="Destinationsfil"
 Remux.Remux="Remux"
+Remux.OBSRecording="OBS optagelse"
 Remux.FinishedTitle="Remuxing færdigt"
 Remux.Finished="Optagelse remuxed"
 Remux.FinishedError="Optagelse remuxed, men filen kan være ufuldstændige"
@@ -129,8 +161,8 @@ Remux.ExitUnfinished="Remuxing er ikke færdig. Hvis du stopper nu, kan du gøre
 UpdateAvailable="Ny opdatering tilgængelig"
 UpdateAvailable.Text="Version %1.%2.%3 er nu tilgængelig.  <a href='%4'>Klik her for at downloade</a>"
 
-Basic.DesktopDevice1="Desktop lyd"
-Basic.DesktopDevice2="Desktop lyd 2"
+Basic.DesktopDevice1="Skrivebordslyd"
+Basic.DesktopDevice2="Skrivebordslyd 2"
 Basic.AuxDevice1="Mic/Aux"
 Basic.AuxDevice2="Mic/Aux 2"
 Basic.AuxDevice3="Mic/Aux 3"
@@ -141,12 +173,28 @@ Basic.DisplayCapture="Indfang display"
 
 Basic.Main.PreviewConextMenu.Enable="Aktiver visning"
 
+ScaleFiltering="Skala filtrering"
+ScaleFiltering.Point="Punkt"
+ScaleFiltering.Bilinear="Bilinear"
+ScaleFiltering.Bicubic="Bikubisk"
+ScaleFiltering.Lanczos="Lanczos"
 
 Deinterlacing="Deinterlacing"
 Deinterlacing.Discard="Kassér"
 Deinterlacing.Retro="Retro"
+Deinterlacing.Blend="Bland"
+Deinterlacing.Blend2x="Blend 2x"
 Deinterlacing.Linear="Lineær"
 Deinterlacing.Linear2x="Lineær 2x"
+Deinterlacing.Yadif="Yadif"
+Deinterlacing.Yadif2x="Yadif 2x"
+Deinterlacing.TopFieldFirst="Øverste felt først"
+Deinterlacing.BottomFieldFirst="Nederste felt først"
+
+VolControl.SliderUnmuted="Lydstyrkeskyder for '%1': %2"
+VolControl.SliderMuted="Lydstyrkeskyder for '%1': %2 (lyd i øjeblikket slået fra)"
+VolControl.Mute="Gør '%1' tavs"
+VolControl.Properties="Egenskaber for '%1'"
 
 Basic.Main.AddSceneDlg.Title="Tilføje scene"
 Basic.Main.AddSceneDlg.Text="Angiv navnet på scene"
@@ -178,7 +226,9 @@ Basic.PropertiesWindow.ConfirmTitle="Indstillinger ændret"
 Basic.PropertiesWindow.Confirm="Der er ændringer, som ikke er gemt.  Vil du gerne beholde dem?"
 Basic.PropertiesWindow.NoProperties="Ingen egenskaber tilgængelige"
 Basic.PropertiesWindow.AddFiles="Tilføj filer"
+Basic.PropertiesWindow.AddDir="Tilføj mappe"
 Basic.PropertiesWindow.AddURL="Tilføj sti/url"
+Basic.PropertiesWindow.AddEditableListDir="Tilføj mappe til '%1'"
 Basic.PropertiesWindow.AddEditableListFiles="Tilføj filer til '%1'"
 Basic.PropertiesWindow.AddEditableListEntry="Tilføj emne til '%1'"
 Basic.PropertiesWindow.EditEditableListEntry="Rediger emne fra '%1'"
@@ -240,9 +290,14 @@ Basic.Main.Scenes="Scener"
 Basic.Main.Sources="Kilder"
 Basic.Main.Connecting="Forbinder..."
 Basic.Main.StartRecording="Start optagelse"
+Basic.Main.StartReplayBuffer="Start Genafspilningsbuffer"
 Basic.Main.StartStreaming="Start streaming"
 Basic.Main.StopRecording="Stop optagelse"
+Basic.Main.StoppingRecording="Stopper optagelse..."
+Basic.Main.StopReplayBuffer="Stop Genafspilningsbuffer"
+Basic.Main.StoppingReplayBuffer="Stopper Genafspilningsbuffer..."
 Basic.Main.StopStreaming="Stop streaming"
+Basic.Main.StoppingStreaming="Stopper stream..."
 Basic.Main.ForceStopStreaming="Stop streaming (ignorer forsinkelse)"
 
 Basic.MainMenu.File="&Fil"
@@ -261,8 +316,15 @@ Basic.MainMenu.Edit.Undo="Fortryd (&U)"
 Basic.MainMenu.Edit.Redo="&Redo"
 Basic.MainMenu.Edit.UndoAction="Fortryd $1 (&U)"
 Basic.MainMenu.Edit.RedoAction="&Redo $1"
+Basic.MainMenu.Edit.LockPreview="&Lås forhåndsvisning"
+Basic.MainMenu.Edit.Scale="Forhåndsvisning & Skalering"
+Basic.MainMenu.Edit.Scale.Window="Skalér til vindue"
+Basic.MainMenu.Edit.Scale.Canvas="Lærred (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Output (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Transformering"
-Basic.MainMenu.Edit.Transform.EditTransform="Redigere transformering... (&E)"
+Basic.MainMenu.Edit.Transform.EditTransform="Rediger transformering... (&E)"
+Basic.MainMenu.Edit.Transform.CopyTransform="Kopiér transformation"
+Basic.MainMenu.Edit.Transform.PasteTransform="Indsæt transformation"
 Basic.MainMenu.Edit.Transform.ResetTransform="Nulstille transformering (&R)"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Roter 90 grader CW"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Roter 90 grader CCW"
@@ -275,14 +337,26 @@ Basic.MainMenu.Edit.Transform.CenterToScreen="&Center til skærm"
 Basic.MainMenu.Edit.Order="Rækkefølge (&O)"
 Basic.MainMenu.Edit.Order.MoveUp="Flyt Op (&U)"
 Basic.MainMenu.Edit.Order.MoveDown="Flyt Ned (&D)"
-Basic.MainMenu.Edit.Order.MoveToTop="Flyt til &Toppen"
+Basic.MainMenu.Edit.Order.MoveToTop="Flyt til &toppen"
 Basic.MainMenu.Edit.Order.MoveToBottom="Flyt til &Bunden"
 Basic.MainMenu.Edit.AdvAudio="&Avancerede lydegenskaber"
 
+Basic.MainMenu.View="&Vis"
+Basic.MainMenu.View.Toolbars="&Værktøjslinjer"
+Basic.MainMenu.View.Toolbars.Listboxes="&Listebokse"
+Basic.MainMenu.View.SceneTransitions="S&cene overgange"
+Basic.MainMenu.View.StatusBar="&Statuslinje"
 
 Basic.MainMenu.SceneCollection="&Scenesamling"
 Basic.MainMenu.Profile="&Profil"
+Basic.MainMenu.Profile.Import="Importér profil"
+Basic.MainMenu.Profile.Export="Eksportér profil"
+Basic.MainMenu.SceneCollection.Import="Importér scenesamling"
+Basic.MainMenu.SceneCollection.Export="Eksportér scenesamling"
+Basic.MainMenu.Profile.Exists="Profilen findes allerede"
+Basic.MainMenu.SceneCollection.Exists="Scenesamlingen findes allerede"
 
+Basic.MainMenu.Tools="Værk&tøjer"
 
 Basic.MainMenu.Help="&Hjælp"
 Basic.MainMenu.Help.Website="Besøg &websted"
@@ -300,13 +374,25 @@ Basic.Settings.Confirm="Du har ugemte ændringer.  Skal ændringerne gemmes?"
 Basic.Settings.General="Generelt"
 Basic.Settings.General.Theme="Tema"
 Basic.Settings.General.Language="Sprog"
+Basic.Settings.General.EnableAutoUpdates="Automatisk søgning efter opdateringer ved opstart"
 Basic.Settings.General.WarnBeforeStartingStream="Vis bekræftelses-dialog ved opstart af stream"
 Basic.Settings.General.WarnBeforeStoppingStream="Vis bekræftelses-dialog ved afslutning af stream"
+Basic.Settings.General.Projectors="Projektorer"
+Basic.Settings.General.HideProjectorCursor="Skjul markør over projektorer"
+Basic.Settings.General.ProjectorAlwaysOnTop="Hav altid projektorer øverst"
 Basic.Settings.General.Snapping="Kilde justeringsfastgørelse"
 Basic.Settings.General.ScreenSnapping="Fastgør kilder til kanten af skærmen"
 Basic.Settings.General.CenterSnapping="Fastgør kilder til horisontalt og vertikalt centrum"
 Basic.Settings.General.SourceSnapping="Fastgør kilder til andre kilder"
 Basic.Settings.General.SnapDistance="Fastgørings-følsomhed"
+Basic.Settings.General.RecordWhenStreaming="Optag automatisk ved streaming"
+Basic.Settings.General.KeepRecordingWhenStreamStops="Bliv ved med at optage når stream stopper"
+Basic.Settings.General.ReplayBufferWhileStreaming="Start automatisk replay buffer ved streaming"
+Basic.Settings.General.KeepReplayBufferStreamStops="Hold replay buffer aktiv når stream stopper"
+Basic.Settings.General.SysTray="Processlinjen"
+Basic.Settings.General.SysTrayWhenStarted="Minimer til proceslinjen ved start"
+Basic.Settings.General.SystemTrayHideMinimize="Minimer altid til processlinjen i stedet for værktøjslinjen"
+Basic.Settings.General.SaveProjectors="Gem projektorer ved afslutning"
 
 Basic.Settings.Stream="Stream"
 Basic.Settings.Stream.StreamType="Streamtype"
@@ -321,21 +407,41 @@ Basic.Settings.Output.Mode="Output tilstand"
 Basic.Settings.Output.Mode.Simple="Simpel"
 Basic.Settings.Output.Mode.Adv="Avanceret"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg output"
+Basic.Settings.Output.UseReplayBuffer="Aktivér Genafspilningsbuffer"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksimal genafspilningstid (sek.)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimal hukommelse (MB)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Anslået hukommelsesforbrug: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Ikke kan beregne hukommelsesforbrug. Sæt venligst maks. hukommelsesgrænse."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Bemærk: Sørg for at sætte en genvejstast til genafspilningsbufferen i sektionen for genvejstaster)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Genafspilningsbuffer filnavn præfiks"
+Basic.Settings.Output.ReplayBuffer.Suffix="Endelse"
 Basic.Settings.Output.Simple.SavePath="Optagelsessti"
 Basic.Settings.Output.Simple.RecordingQuality="Optagelseskvalitet"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Samme som stream"
 Basic.Settings.Output.Simple.RecordingQuality.Small="Høj kvalitet, medium filstørrelse"
 Basic.Settings.Output.Simple.RecordingQuality.HQ="Samme kvalitet, stor filstørrelse"
 Basic.Settings.Output.Simple.RecordingQuality.Lossless="Tabsfri kvalitet, utrolig stor filstørrelse"
+Basic.Settings.Output.Simple.Warn.VideoBitrate="Advarsel: Video-streaming bitraten sættes til %1, som er den øvre grænse for den aktuelle streaming-tjeneste.  Er du sikker på, at du vil at gå over %1, så aktivér venligst avancerede valg for encoder og afmarkér \"Gennemtving streaming-tjenestes bitratebegrænsninger\"."
+Basic.Settings.Output.Simple.Warn.AudioBitrate="Advarsel: Audio-streaming bitraten sættes til %1, som er den øvre grænse for den aktuelle streaming-tjeneste.  Er du sikker på, at du vil at gå over %1, så aktivér venligst avancerede valg for encoder og afmarkér \"Gennemtving streaming-tjenestes bitratebegrænsninger\"."
+Basic.Settings.Output.Simple.Warn.Encoder="Advarsel: Optagelse med en software-encoder i en anden kvalitet end det streamede vil medføre ekstra CPU-forbrug, hvis du streamer og optager samtidigt."
+Basic.Settings.Output.Simple.Warn.Lossless="Advarsel: Tabsfri kvalitet genererer gevaldigt store filstørrelser!  Tabsfri kvalitet kan bruge op til 7 GB diskplads pr. minut ved høje opløsninger og billedhastigheder.  Tabsfri tilstand anbefales ikke til lange optagelser, medmindre du har en meget stor mængde tilgængelig diskplads."
+Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sikker på, at du vil benytte tabsfri kvalitet?"
+Basic.Settings.Output.Simple.Warn.Lossless.Title="Tabsfri kvalitet-advarsel!"
+Basic.Settings.Output.Simple.Warn.MultipleQSV="Advarsel: Du kan ikke benytte flere særskilte QSV-encoders ved streaming og optagelse på samme tid.  Ønsker du at streame og optage samtidig, bedes du ændre enten optagelses- eller stream-encoder."
 Basic.Settings.Output.Simple.Encoder.Software="Software (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)"
+Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 lav, forudindstillet CPU-forbrug, øger filstørrelsen)"
 Basic.Settings.Output.VideoBitrate="Video Bitrate"
 Basic.Settings.Output.AudioBitrate="Audio Bitrate"
 Basic.Settings.Output.Reconnect="Automatisk Reconnect"
 Basic.Settings.Output.RetryDelay="Retry forsinkelse (sekunder)"
 Basic.Settings.Output.MaxRetries="Maksimum forsøg"
 Basic.Settings.Output.Advanced="Aktiver avancerede Encoder indstillinger"
+Basic.Settings.Output.EncoderPreset="Encoder forudindstilling (hurtigere= mindre CPU-kraft)"
+Basic.Settings.Output.CustomEncoderSettings="Tilpasset Encoder-indstillinger"
+Basic.Settings.Output.CustomMuxerSettings="Tilpasset Muxer-indstillinger"
 Basic.Settings.Output.NoSpaceFileName="Opret filnavne uden mellemrum"
 
 Basic.Settings.Output.Adv.Rescale="Om-skalere output"
@@ -346,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Spor 1"
 Basic.Settings.Output.Adv.Audio.Track2="Spor 2"
 Basic.Settings.Output.Adv.Audio.Track3="Spor 3"
 Basic.Settings.Output.Adv.Audio.Track4="Spor 4"
+Basic.Settings.Output.Adv.Audio.Track5="Sport 5"
+Basic.Settings.Output.Adv.Audio.Track6="Spor 6"
 
 Basic.Settings.Output.Adv.Recording="Optagelse"
 Basic.Settings.Output.Adv.Recording.Type="Type"
@@ -357,12 +465,15 @@ Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Overskriv hvis filen eksi
 Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg outputtype"
 Basic.Settings.Output.Adv.FFmpeg.Type.URL="Output til URL"
 Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Output til fil"
+Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Almindelige optagelsesformater"
 Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Alle filer"
 Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Filsti eller URL"
 Basic.Settings.Output.Adv.FFmpeg.Format="Containerformat"
 Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Lyd"
 Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Video"
 Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Standard format"
+Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Container-format beskrivelse"
+Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Lyd/Video-codec gættet fra filsti eller URL"
 Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Standard encoder"
 Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Deaktiver encoder"
 Basic.Settings.Output.Adv.FFmpeg.VEncoder="Video encoder"
@@ -370,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Video encoder indstillinger (
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Lyd encoder"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Lyd encoder indstillinger (hvis nogen)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer indstillinger (hvis nogen)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Keyframe-Interval (billeder)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Vis alle codecs (selv potentielt inkompatible)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -399,40 +512,62 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Skarp skalering, 32 prøv
 Basic.Settings.Audio="Lyd"
 Basic.Settings.Audio.SampleRate="Sample Rate"
 Basic.Settings.Audio.Channels="Kanaler"
-Basic.Settings.Audio.DesktopDevice="Desktop lydenhed"
-Basic.Settings.Audio.DesktopDevice2="Desktop lydenhed 2"
+Basic.Settings.Audio.DesktopDevice="Skrivebord lydenhed"
+Basic.Settings.Audio.DesktopDevice2="Skrivebord lydenhed 2"
 Basic.Settings.Audio.AuxDevice="Mic/Auxiliary lydenhed"
 Basic.Settings.Audio.AuxDevice2="Mic/Auxiliary lydenhed 2"
 Basic.Settings.Audio.AuxDevice3="Mic/Auxiliary lydenhed 3"
 Basic.Settings.Audio.EnablePushToMute="Aktiver tryk-for-stilhed"
+Basic.Settings.Audio.PushToMuteDelay="Tryk for at gøre tavs-forsinkelse"
 Basic.Settings.Audio.EnablePushToTalk="Aktiver tryk-for-tale"
+Basic.Settings.Audio.PushToTalkDelay="Tryk for at gøre hørbar-forsinkelse"
 Basic.Settings.Audio.UnknownAudioDevice="[Enhed ikke tilsluttet eller ikke tilgængelig]"
 
 Basic.Settings.Advanced="Avanceret"
+Basic.Settings.Advanced.General.ProcessPriority="Proces prioritet"
+Basic.Settings.Advanced.General.ProcessPriority.High="Høj"
+Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Over normal"
+Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal"
+Basic.Settings.Advanced.General.ProcessPriority.Idle="Ikke aktiv"
+Basic.Settings.Advanced.FormatWarning="Advarsel: Farveformater ud over NV12 er primært beregnet til optagelse, og de anbefales ikke under streaming. Streaming kan medføre øget CPU-forbrug grundet farveformatkonvertering."
+Basic.Settings.Advanced.Audio.BufferingTime="Lyd-bufferinterval"
 Basic.Settings.Advanced.Video.ColorFormat="Farveformat"
 Basic.Settings.Advanced.Video.ColorSpace="YUV farverum"
 Basic.Settings.Advanced.Video.ColorRange="YUV farveområde"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Delvis"
 Basic.Settings.Advanced.Video.ColorRange.Full="Fuld"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Lyd overvågningsenhed"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standard"
 Basic.Settings.Advanced.StreamDelay="Stream forsinkelse"
 Basic.Settings.Advanced.StreamDelay.Duration="Varighed (sekunder)"
+Basic.Settings.Advanced.StreamDelay.Preserve="Bevar afskæringspunkt (forøg forsinkelse) ved forbindelsesgendannelse"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Anslået hukommelsesbrug: %1 MB"
+Basic.Settings.Advanced.Network="Netværk"
+Basic.Settings.Advanced.Network.BindToIP="Bind til IP"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Aktivér ny netværkskode"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Lav forsinkelsestilstand"
 
 Basic.AdvAudio="Avancerede lydegenskaber"
 Basic.AdvAudio.Name="Navn"
 Basic.AdvAudio.Volume="Volumen (%)"
+Basic.AdvAudio.Mono="Nedmix til Mono"
 Basic.AdvAudio.Panning="Panorering"
+Basic.AdvAudio.SyncOffset="Synkr-forskydning (ms)"
+Basic.AdvAudio.Monitoring="Lydovervågning"
+Basic.AdvAudio.Monitoring.None="Overvågning fra"
+Basic.AdvAudio.Monitoring.MonitorOnly="Kun overvågning (mute output)"
+Basic.AdvAudio.Monitoring.Both="Overvåg og output"
 Basic.AdvAudio.AudioTracks="Spor"
 
 Basic.Settings.Hotkeys="Genvejstaster"
+Basic.Settings.Hotkeys.Pair="Tastekombinationer delt med '%1' fungerer som omskiftere"
 
-Basic.Hotkeys.StartStreaming="Start streaming"
-Basic.Hotkeys.StopStreaming="Stop streaming"
-Basic.Hotkeys.StartRecording="Start optagelse"
-Basic.Hotkeys.StopRecording="Stop optagelse"
 Basic.Hotkeys.SelectScene="Skift til scene"
 
+Basic.SystemTray.Show="Vis"
+Basic.SystemTray.Hide="Skjul"
 
+Basic.SystemTray.Message.Reconnecting="Afbrudt. Forbinder igen..."
 
 Hotkeys.Insert="Insert"
 Hotkeys.Delete="Delete"
@@ -478,4 +613,7 @@ Push-to-talk="Tryk-for-tale"
 SceneItemShow="Vis '%1'"
 SceneItemHide="Skjul '%1'"
 
+OutputWarnings.NoTracksSelected="Du skal vælge minimum ét spor"
+OutputWarnings.MultiTrackRecording="Advarsel: Visse formater (såsom FLV) understøtter ikke flere spor pr. optagelse"
+OutputWarnings.MP4Recording="Advarsel: MP4-optagelser vil ikke kunne genoprettes, hvis filen ikke kan færdiggøres (f.eks. som følge af BSODs, strømafbrydelse m.v.). Ønsker du at optage flere lydspor, overvej da at benytte MKV, og remuxe optagelsen til MP4, efter at den er færdiggjort (fil-> Remux optagelser)"
 
diff --git a/UI/data/locale/de-DE.ini b/UI/data/locale/de-DE.ini
index b42c6c8..1c43078 100644
--- a/UI/data/locale/de-DE.ini
+++ b/UI/data/locale/de-DE.ini
@@ -3,7 +3,7 @@ Language="Deutsch"
 Region="Deutschland"
 
 OK="OK"
-Apply="Anwenden"
+Apply="Ãœbernehmen"
 Cancel="Abbrechen"
 Close="Schließen"
 Save="Speichern"
@@ -41,7 +41,7 @@ Duplicate="Klonen"
 Enable="Aktivieren"
 DisableOSXVSync="OSX V-Sync deaktivieren"
 ResetOSXVSyncOnExit="OSX V-Sync beim Beenden zurücksetzen"
-HighResourceUsage="Kodierung überlastet! Erwägen Sie Ihre Video-Einstellungen zu verringern, oder benutzen Sie eine schnellere Encoder-Voreinstellung."
+HighResourceUsage="Codierung überlastet! Erwägen Sie Ihre Video-Einstellungen zu verringern, oder benutzen Sie eine schnellere Codierer-Voreinstellung."
 Transition="Ãœbergang"
 QuickTransitions="Schnelle Übergänge"
 Left="Links"
@@ -49,6 +49,26 @@ Right="Rechts"
 Top="Oben"
 Bottom="Unten"
 Reset="Zurücksetzen"
+Hours="Stunde(n)"
+Minutes="Minute(n)"
+Seconds="Sekunde(n)"
+Deprecated="Veraltet"
+ReplayBuffer="Replaypuffer"
+Import="Importieren"
+Export="Exportieren"
+
+Updater.Title="Neues Update verfügbar"
+Updater.Text="Es ist ein neues Update verfügbar:"
+Updater.UpdateNow="Jetzt updaten"
+Updater.RemindMeLater="Später erinnern"
+Updater.Skip="Version überspringen"
+Updater.Running.Title="Programm derzeit aktiv"
+Updater.Running.Text="Ausgänge sind derzeit aktiv. Bitte beenden Sie alle aktiven Ausgänge, bevor Sie versuchen OBS zu aktualisieren."
+Updater.NoUpdatesAvailable.Title="Keine Updates verfügbar"
+Updater.NoUpdatesAvailable.Text="Zurzeit sind keine Updates verfügbar"
+Updater.FailedToLaunch="Konnte den Updater nicht starten"
+Updater.GameCaptureActive.Title="Spielaufnahme aktiv"
+Updater.GameCaptureActive.Text="Spielaufnahme Hook Bibliothek wird zurzeit verwendet. Bitte schließen Sie alle derzeitigen Spiele / Programme die aufgenommen werden (oder starten Sie Windows neu) und versuchen Sie es erneut."
 
 QuickTransitions.SwapScenes="Tausche Vorschau/Ausgabe-Szenen nach dem Ãœbergang"
 QuickTransitions.SwapScenesTT="Vertauscht die Vorschau- und Ausgabe-Szenen nach dem Übergang (falls die ursprüngliche Ausgabe-Szene noch vorhanden ist).\nEventuelle Änderungen an der original Ausgabe-Szene werden hierbei nicht rückgängig gemacht."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Entfernen bestätigen"
 ConfirmRemove.Text="Sind Sie sicher, dass Sie '$1' entfernen möchten?"
 ConfirmRemove.TextMultiple="Sind Sie sicher, dass Sie %1 Elemente löschen möchten?"
 
+Output.StartStreamFailed="Fehler beim Start des Streams"
+Output.StartRecordingFailed="Fehler beim Starten der Aufnahme"
+Output.StartReplayFailed="Fehler beim Starten des Replaypuffers"
+Output.StartFailedGeneric="Start der Ausgabe fehlgeschlagen. Bitte überprüfen Sie die Logdatei für Details.\n\nHinweis: Wenn Sie die NVENC- oder AMD-Encoder verwenden, stellen Sie sicher, dass Ihre Videotreiber aktuell sind."
+
 Output.ConnectFail.Title="Verbindung fehlgeschlagen"
 Output.ConnectFail.BadPath="Ungültiger Pfad oder Verbindungs-URL. Bitte überprüfen Sie Ihre Einstellungen und stellen Sie sicher, dass diese korrekt sind."
 Output.ConnectFail.ConnectFailed="Verbindung zum Server fehlgeschlagen"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="Nicht genügend Speicherplatz"
 Output.RecordNoSpace.Msg="Es gibt nicht genügend Speicherplatz, um die Aufnahme fortzusetzen."
 Output.RecordError.Title="Aufnahmefehler"
 Output.RecordError.Msg="Während der Aufnahme ist ein unbekannter Fehler aufgetreten."
+Output.ReplayBuffer.NoHotkey.Title="Kein Hotkey festgelegt!"
+Output.ReplayBuffer.NoHotkey.Msg="Kein Speichern Hotkey festgelegt für Replaypuffer. Legen Sie bitte den \"Speichern\" Hotkey fest, der zum Speichern der Replayaufnahmen verwendet werden soll."
 
 Output.BadPath.Title="Ungültiger Dateipfad"
 Output.BadPath.Text="Der konfigurierte Ausgabepfad ist ungültig. Bitte überprüfen Sie Ihre Einstellungen und stellen Sie sicher, dass ein gültiger Pfad angegeben wurde."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Oberes Feld zuerst"
 Deinterlacing.BottomFieldFirst="Unteres Feld zuerst"
 
+VolControl.SliderUnmuted="Lautstärke-Schieberegler für '%1': %2"
+VolControl.SliderMuted="Lautstärke-Schieberegler für '%1': %2 (derzeit stumm geschaltet)"
+VolControl.Mute="'%1' stumm schalten"
+VolControl.Properties="Eigenschaften von '%1'"
+
 Basic.Main.AddSceneDlg.Title="Szene hinzufügen"
 Basic.Main.AddSceneDlg.Text="Bitte geben Sie einen Namen für die Szene ein"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Szenen"
 Basic.Main.Sources="Quellen"
 Basic.Main.Connecting="Verbinden..."
 Basic.Main.StartRecording="Aufnahme starten"
+Basic.Main.StartReplayBuffer="Replaypuffer starten"
 Basic.Main.StartStreaming="Streaming starten"
 Basic.Main.StopRecording="Aufnahme stoppen"
 Basic.Main.StoppingRecording="Stoppe Aufnahme..."
+Basic.Main.StopReplayBuffer="Replaypuffer stoppen"
+Basic.Main.StoppingReplayBuffer="Stoppe Replaypuffer..."
 Basic.Main.StopStreaming="Streaming stoppen"
 Basic.Main.StoppingStreaming="Stoppe Stream..."
 Basic.Main.ForceStopStreaming="Streaming stoppen (Verzögerung verwerfen)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="Wiede&rherstellen"
 Basic.MainMenu.Edit.UndoAction="$1 rückgängig machen (&U)"
 Basic.MainMenu.Edit.RedoAction="$1 Wiede&rherstellen"
 Basic.MainMenu.Edit.LockPreview="Vorschau sperren (&L)"
+Basic.MainMenu.Edit.Scale="Vorschau&skalierung"
+Basic.MainMenu.Edit.Scale.Window="An Fenstergröße anpassen"
+Basic.MainMenu.Edit.Scale.Canvas="Leinwand (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Ausgabe (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Transformieren"
 Basic.MainMenu.Edit.Transform.EditTransform="Transformation b&earbeiten..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Transformation kopieren"
+Basic.MainMenu.Edit.Transform.PasteTransform="Transformation einfügen"
 Basic.MainMenu.Edit.Transform.ResetTransform="Transformation zu&rücksetzen"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Um 90° im Uhrzeigersinn drehen"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Um 90° gegen den Uhrzeigersinn drehen"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="&Statusleiste"
 
 Basic.MainMenu.SceneCollection="&Szenen-Sammlung"
 Basic.MainMenu.Profile="&Profil"
+Basic.MainMenu.Profile.Import="Profil importieren"
+Basic.MainMenu.Profile.Export="Profil exportieren"
+Basic.MainMenu.SceneCollection.Import="Szenen-Sammlung importieren"
+Basic.MainMenu.SceneCollection.Export="Szenen-Sammlung exportieren"
+Basic.MainMenu.Profile.Exists="Das Profil ist bereits vorhanden"
+Basic.MainMenu.SceneCollection.Exists="Die Szenen-Sammlung existiert bereits"
 
 Basic.MainMenu.Tools="Werkzeuge (&T)"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="Sie haben ungespeicherte Änderungen. Änderungen speich
 Basic.Settings.General="Allgemein"
 Basic.Settings.General.Theme="Motiv"
 Basic.Settings.General.Language="Sprache"
+Basic.Settings.General.EnableAutoUpdates="Beim Start nach Updates suchen"
 Basic.Settings.General.WarnBeforeStartingStream="Bestätigungsdialog beim Streamstart anzeigen"
 Basic.Settings.General.WarnBeforeStoppingStream="Bestätigungsdialog beim Streamstop anzeigen"
+Basic.Settings.General.Projectors="Projektoren"
 Basic.Settings.General.HideProjectorCursor="Mauszeiger über Projektoren verstecken"
 Basic.Settings.General.ProjectorAlwaysOnTop="Projektoren immer im Vordergrund anzeigen"
 Basic.Settings.General.Snapping="Quellenausrichtung"
@@ -336,17 +385,21 @@ Basic.Settings.General.ScreenSnapping="Quellen am Bildschirmrand ausrichten"
 Basic.Settings.General.CenterSnapping="Quellen zur horizontalen und vertikalen Mitte ausrichten"
 Basic.Settings.General.SourceSnapping="Quellen an anderen Quellen ausrichten"
 Basic.Settings.General.SnapDistance="Ausrichtungsempfindlichkeit"
-Basic.Settings.General.RecordWhenStreaming="Stream automatisch aufnehmen"
+Basic.Settings.General.RecordWhenStreaming="Livestream automatisch aufnehmen"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Weiter aufnehmen, wenn der Livestream stoppt"
-Basic.Settings.General.SysTrayEnabled="Symbol in der Taskleiste aktivieren"
-Basic.Settings.General.SysTrayWhenStarted="Beim Start zur Taskleiste minimieren"
+Basic.Settings.General.ReplayBufferWhileStreaming="Replaypuffer automatisch starten, beim Streamen"
+Basic.Settings.General.KeepReplayBufferStreamStops="Replaypuffer weiter aktiv lassen, wenn der Livestream stoppt"
+Basic.Settings.General.SysTray="Infobereich"
+Basic.Settings.General.SysTrayWhenStarted="Beim Start zum Infobereich minimieren"
+Basic.Settings.General.SystemTrayHideMinimize="Immer zum Infobereich. statt zur Taskleiste minimieren"
+Basic.Settings.General.SaveProjectors="Projektoren beim Beenden speichern"
 
 Basic.Settings.Stream="Stream"
 Basic.Settings.Stream.StreamType="Stream Typ"
 
 Basic.Settings.Output="Ausgabe"
 Basic.Settings.Output.Format="Aufnahmeformat"
-Basic.Settings.Output.Encoder="Encoder"
+Basic.Settings.Output.Encoder="Codierer"
 Basic.Settings.Output.SelectDirectory="Wählen Sie das Aufnahmeverzeichnis"
 Basic.Settings.Output.SelectFile="Wählen Sie die Aufnahmedatei"
 Basic.Settings.Output.EnforceBitrate="Erzwinge Bitratenlimit des Streamingdiensts"
@@ -354,19 +407,27 @@ Basic.Settings.Output.Mode="Ausgabemodus"
 Basic.Settings.Output.Mode.Simple="Einfach"
 Basic.Settings.Output.Mode.Adv="Erweitert"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg Ausgabe"
+Basic.Settings.Output.UseReplayBuffer="Replaypuffer aktivieren"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximale Replayzeit (Sekunden)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximale Speichernutzung (RAM) in Megabyte"
+Basic.Settings.Output.ReplayBuffer.Estimate="Geschätzte Speichernutzung (RAM): %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Speichernutzung kann nicht geschätzt werden.  Stellen Sie bitte die maximale Speichergrenze ein."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Hinweis: Achten Sie darauf, einen Hotkey für den Replaypuffer im Abschnitt Hotkeys festzulegen)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Replaypuffer Dateiname Prefix"
+Basic.Settings.Output.ReplayBuffer.Suffix="Suffix"
 Basic.Settings.Output.Simple.SavePath="Aufnahmepfad"
 Basic.Settings.Output.Simple.RecordingQuality="Aufnahmequalität"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Gleiche wie Stream"
 Basic.Settings.Output.Simple.RecordingQuality.Small="Hohe Qualität, mittelgroße Dateien"
 Basic.Settings.Output.Simple.RecordingQuality.HQ="Ununterscheidbare Qualität, große Dateien"
 Basic.Settings.Output.Simple.RecordingQuality.Lossless="Verlustfreie Qualität, enorm große Dateien"
-Basic.Settings.Output.Simple.Warn.VideoBitrate="Warnung: Die Videobitrate beim streamen wird auf %1 festlegt, was der Obergrenze des aktuellen Streamingdiensts entspricht.  Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie \"Erzwinge Bitratenlimit des Streamingdiensts\" in den erweiterten Encodereinstellungen."
-Basic.Settings.Output.Simple.Warn.AudioBitrate="Warnung: Die Audiobitrate beim streamen wird auf %1 festlegt, was der Obergrenze des aktuellen Streamingdiensts entspricht.  Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie \"Erzwinge Bitratenlimit des Streamingdiensts\" in den erweiterten Encodereinstellungen."
-Basic.Settings.Output.Simple.Warn.Encoder="Warnung: Mit einem Software-Encoder in einer anderen Qualität als der des Stream aufzunehmen wird zusätzliche CPU-Auslastung erzeugen, wenn Sie gleichzeitig streamen und aufzeichnen."
+Basic.Settings.Output.Simple.Warn.VideoBitrate="Warnung: Die Videobitrate beim streamen wird auf %1 festlegt, was der Obergrenze des aktuellen Streamingdiensts entspricht.  Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie \"Erzwinge Bitratenlimit des Streamingdiensts\" in den erweiterten Codierereinstellungen."
+Basic.Settings.Output.Simple.Warn.AudioBitrate="Warnung: Die Audiobitrate beim streamen wird auf %1 festlegt, was der Obergrenze des aktuellen Streamingdiensts entspricht.  Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie \"Erzwinge Bitratenlimit des Streamingdiensts\" in den erweiterten Codierereinstellungen."
+Basic.Settings.Output.Simple.Warn.Encoder="Warnung: Mit einem Software-Codierer in einer anderen Qualität als der des Stream aufzunehmen wird zusätzliche CPU-Auslastung erzeugen, wenn Sie gleichzeitig streamen und aufzeichnen."
 Basic.Settings.Output.Simple.Warn.Lossless="Warnung: Verlustfreie Qualität erzeugt enorm große Dateien!  Verlustfreie Qualität, kann mehr als 7 Gigabyte Speicherplatz pro Minute, bei hohen Auflösungen und Frameraten in Anspruch nehmen.  Verlustfrei ist für lange Aufnahmen nicht empfohlen, es sei denn, Sie haben eine sehr große Menge an Speicherplatz zur Verfügung."
 Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sind Sie sicher, dass Sie verlustfreie Qualität verwenden möchten?"
 Basic.Settings.Output.Simple.Warn.Lossless.Title="Verlustfreie Qualität-Warnung!"
-Basic.Settings.Output.Simple.Warn.MultipleQSV="Achtung: Sie können nicht mehrere separate QSV-Encoder beim streamen und aufnehmen gleichzeitig verwenden.  Wenn Sie zur gleichen Zeit streamen und aufnehmen möchten, dann ändern Sie bitte entweder den Aufnahme-Encoder oder den Stream-Encoder."
+Basic.Settings.Output.Simple.Warn.MultipleQSV="Achtung: Sie können nicht mehrere separate QSV-Codierer beim streamen und aufnehmen gleichzeitig verwenden.  Wenn Sie zur gleichen Zeit streamen und aufnehmen möchten, dann ändern Sie bitte entweder den Aufnahmecodierer oder den Streamcodierer."
 Basic.Settings.Output.Simple.Encoder.Software="Software (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)"
 Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)"
@@ -377,26 +438,28 @@ Basic.Settings.Output.AudioBitrate="Audiobitrate"
 Basic.Settings.Output.Reconnect="Automatisch wiederverbinden"
 Basic.Settings.Output.RetryDelay="Wiederverbindungsverzögerung (Sekunden)"
 Basic.Settings.Output.MaxRetries="Maximale Wiederholungsversuche"
-Basic.Settings.Output.Advanced="Erweiterte Encodereinstellungen aktivieren"
-Basic.Settings.Output.EncoderPreset="Encoder-Voreinstellung (höher = weniger CPU Auslastung)"
-Basic.Settings.Output.CustomEncoderSettings="Benutzerdefinierte Encoder-Einstellungen"
+Basic.Settings.Output.Advanced="Erweiterte Codierereinstellungen aktivieren"
+Basic.Settings.Output.EncoderPreset="Codierer-Voreinstellung (höher = weniger CPU Auslastung)"
+Basic.Settings.Output.CustomEncoderSettings="Benutzerdefinierte Codierer-Einstellungen"
 Basic.Settings.Output.CustomMuxerSettings="Benutzerdefinierte Muxereinstellungen"
 Basic.Settings.Output.NoSpaceFileName="Dateinamen ohne Leerzeichen generieren"
 
 Basic.Settings.Output.Adv.Rescale="Ausgabe umskalieren"
 Basic.Settings.Output.Adv.AudioTrack="Audiospur"
 Basic.Settings.Output.Adv.Streaming="Streamen"
-Basic.Settings.Output.Adv.ApplyServiceSettings="Erzwinge Streamingdienst-Encodereinstellungen"
+Basic.Settings.Output.Adv.ApplyServiceSettings="Erzwinge Streamingdienst-Codierereinstellungen"
 Basic.Settings.Output.Adv.Audio.Track1="Spur 1"
 Basic.Settings.Output.Adv.Audio.Track2="Spur 2"
 Basic.Settings.Output.Adv.Audio.Track3="Spur 3"
 Basic.Settings.Output.Adv.Audio.Track4="Spur 4"
+Basic.Settings.Output.Adv.Audio.Track5="Spur 5"
+Basic.Settings.Output.Adv.Audio.Track6="Spur 6"
 
 Basic.Settings.Output.Adv.Recording="Aufnehmen"
 Basic.Settings.Output.Adv.Recording.Type="Art"
 Basic.Settings.Output.Adv.Recording.Type.Standard="Normal"
 Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Benutzerdefinierte Ausgabe (FFmpeg)"
-Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Benutze Streamencoder)"
+Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Benutze Streamcodierer)"
 Basic.Settings.Output.Adv.Recording.Filename="Dateinameformatierung"
 Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Ãœberschreiben, wenn die Datei vorhanden ist"
 Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg-Ausgabetyp"
@@ -411,13 +474,15 @@ Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Video"
 Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Standardformat"
 Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Container-Formatbeschreibung"
 Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Audio- / Videocodec wird aus Dateipfad oder URL erraten."
-Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Standard-Encoder"
-Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Encoder deaktivieren"
-Basic.Settings.Output.Adv.FFmpeg.VEncoder="Video-Encoder"
-Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Video Encoder-Einstellungen (falls gewünscht)"
-Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio-Encoder"
-Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio Encoder-Einstellungen (falls gewünscht)"
+Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Standard-Codierer"
+Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Codierer deaktivieren"
+Basic.Settings.Output.Adv.FFmpeg.VEncoder="Video-Codierer"
+Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Video Codierer-Einstellungen (falls gewünscht)"
+Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio-Codierer"
+Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio Codierer-Einstellungen (falls gewünscht)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer Einstellungen (falls vorhanden)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Keyframeintervall (Frames)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Zeige alle Codecs (auch wenn möglicherweise nicht kompatibel)"
 
 FilenameFormatting.completer="%DD-%MM-%CCYY %hh-%mm-%ss\n%DD-%MM-%YY %hh-%mm-%ss\n%d-%m-%Y %H-%M-%S\n%d-%m-%y %H-%M-%S\n%a %d-%m-%Y %H-%M-%S\n%A %d-%m-%Y %H-%M-%S\n%d-%b-%Y %H-%M-%S\n%d-%B-%Y %H-%M-%S"
 
@@ -471,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV-Farbmatrix"
 Basic.Settings.Advanced.Video.ColorRange="YUV Farbbereich"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Begrenzt"
 Basic.Settings.Advanced.Video.ColorRange.Full="Voll"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Audiomonitoringgerät"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standard"
 Basic.Settings.Advanced.StreamDelay="Stream-Verzögerung"
 Basic.Settings.Advanced.StreamDelay.Duration="Dauer (Sekunden)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Lückenloses Wiederverbinden (erhöht Verzögerung, um Videoverlust zu vermeiden)"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Geschätzte Speichernutzung: %1 MB"
 Basic.Settings.Advanced.Network="Netzwerk"
 Basic.Settings.Advanced.Network.BindToIP="Interface"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Neuen Netzwerkcode aktivieren"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Niedriger Latenzmodus"
 
 Basic.AdvAudio="Erweiterte Audioeigenschaften"
 Basic.AdvAudio.Name="Name"
@@ -484,21 +553,21 @@ Basic.AdvAudio.Volume="Lautstärke (%)"
 Basic.AdvAudio.Mono="Heruntermischen zu Mono"
 Basic.AdvAudio.Panning="Schwenken"
 Basic.AdvAudio.SyncOffset="Sync Verschiebung (ms)"
+Basic.AdvAudio.Monitoring="Audiomonitoring"
+Basic.AdvAudio.Monitoring.None="Monitor aus"
+Basic.AdvAudio.Monitoring.MonitorOnly="Nur Monitor (Ausgabe stumm schalten)"
+Basic.AdvAudio.Monitoring.Both="Monitor und Ausgabe"
 Basic.AdvAudio.AudioTracks="Spuren"
 
 Basic.Settings.Hotkeys="Hotkeys"
 Basic.Settings.Hotkeys.Pair="Mit '%1' geteilte Tastenkombinationen funktionieren als Schalter"
 
-Basic.Hotkeys.StartStreaming="Streaming starten"
-Basic.Hotkeys.StopStreaming="Streaming stoppen"
-Basic.Hotkeys.StartRecording="Aufnahme starten"
-Basic.Hotkeys.StopRecording="Aufnahme stoppen"
 Basic.Hotkeys.SelectScene="Zu Szene wechseln"
 
 Basic.SystemTray.Show="Anzeigen"
 Basic.SystemTray.Hide="Ausblenden"
 
-Basic.SystemTray.Message.Reconnecting="Verbindung verloren.  Verbinde erneut..."
+Basic.SystemTray.Message.Reconnecting="Verbindung verloren. Verbinde erneut..."
 
 Hotkeys.Insert="Einfügen"
 Hotkeys.Delete="Entfernen"
@@ -546,4 +615,5 @@ SceneItemHide="'%1' verstecken"
 
 OutputWarnings.NoTracksSelected="Sie müssen mindestens eine Spur auswählen"
 OutputWarnings.MultiTrackRecording="Warnung: Bestimmte Formate (z. B. FLV) unterstützen nicht mehrere Spuren pro Aufnahme"
+OutputWarnings.MP4Recording="Warnung: Aufnahmen, die in MP4 gespeichert werden, sind nicht wiederherstellbar, wenn die Datei nicht abgeschlossen werden kann (zum Beispiel als Folge von BSODs, Stromausfälle, etc). Wenn Sie mehrere Audiospuren aufnehmen möchten, sollten Sie MKV verwenden und die Aufnahme zu MP4 remuxen, nachdem sie fertig ist. (Datei-> Remuxe Aufnahmen)"
 
diff --git a/UI/data/locale/el-GR.ini b/UI/data/locale/el-GR.ini
index 4ecdca7..59839a4 100644
--- a/UI/data/locale/el-GR.ini
+++ b/UI/data/locale/el-GR.ini
@@ -8,6 +8,7 @@ Cancel="Ακύρωση"
 Close="Κλείσιμο"
 Save="Αποθήκευση"
 Discard="Απόρριψη"
+Disable="Απενεργοποίηση"
 Yes="Ναι"
 No="Όχι"
 Add="Προσθήκη"
@@ -39,6 +40,14 @@ New="Νέο"
 Duplicate="Διπλότυπη εγγραφή"
 Enable="Ενεργοποίηση"
 DisableOSXVSync="Απενεργοποίηση OSX V-Sync"
+Left="Αριστερά"
+Right="Δεξιά"
+Top="Επάνω"
+Bottom="Κάτω"
+Hours="Ώρες"
+Minutes="Λεπτά"
+Seconds="Δευτερόλεπτα"
+
 
 
 Basic.TransitionDuration="Διάρκεια"
@@ -61,6 +70,7 @@ ConfirmExit.Title="Έξοδος από το OBS;"
 ConfirmRemove.Title="Επιβεβαίωση Αφαίρεσης"
 ConfirmRemove.Text="Είστε βέβαιοι ότι θέλετε να καταργήσετε \"$1\";"
 
+
 Output.ConnectFail.Title="Η σύνδεση απέτυχε"
 Output.ConnectFail.BadPath="Μη έγκυρη Διαδρομή ή URL Σύνδεσης.  Παρακαλώ ελέγξτε τις ρυθμίσεις σας και επιβεβαιώστε ότι είναι έγκυρες."
 Output.ConnectFail.ConnectFailed="Απέτυχε η σύνδεση στον διακομιστή"
@@ -113,6 +123,7 @@ Basic.Main.PreviewConextMenu.Enable="Ενεργοποίηση Προεπισκό
 
 
 
+
 Basic.Main.AddSceneDlg.Title="Προσθήκη Σκηνής"
 Basic.Main.AddSceneDlg.Text="Παρακαλώ εισάγετε το όνομα της σκηνής"
 
@@ -353,10 +364,6 @@ Basic.AdvAudio.SyncOffset="Μετατόπιση Συγχρονισμού (ms)"
 Basic.AdvAudio.AudioTracks="Κομμάτια"
 
 
-Basic.Hotkeys.StartStreaming="Έναρξη Μετάδοσης"
-Basic.Hotkeys.StopStreaming="Διακοπή Μετάδοσης"
-Basic.Hotkeys.StartRecording="Έναρξη Καταγραφής"
-Basic.Hotkeys.StopRecording="Διακοπή Καταγραφής"
 Basic.Hotkeys.SelectScene="Μετάβαση σε σκηνή"
 
 
diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini
index 3d6f196..1d3b3f9 100644
--- a/UI/data/locale/en-US.ini
+++ b/UI/data/locale/en-US.ini
@@ -54,6 +54,27 @@ Right="Right"
 Top="Top"
 Bottom="Bottom"
 Reset="Reset"
+Hours="Hours"
+Minutes="Minutes"
+Seconds="Seconds"
+Deprecated="Deprecated"
+ReplayBuffer="Replay Buffer"
+Import="Import"
+Export="Export"
+
+# updater
+Updater.Title="New update available"
+Updater.Text="There is a new update available:"
+Updater.UpdateNow="Update Now"
+Updater.RemindMeLater="Remind me Later"
+Updater.Skip="Skip Version"
+Updater.Running.Title="Program currently active"
+Updater.Running.Text="Outputs are currently active, please shut down any active outputs before attempting to update"
+Updater.NoUpdatesAvailable.Title="No updates available"
+Updater.NoUpdatesAvailable.Text="No updates are currently available"
+Updater.FailedToLaunch="Failed to launch updater"
+Updater.GameCaptureActive.Title="Game capture active"
+Updater.GameCaptureActive.Text="Game capture hook library is currently in use.  Please close any games/programs being captured (or restart windows) and try again."
 
 # quick transitions
 QuickTransitions.SwapScenes="Swap Preview/Output Scenes After Transitioning"
@@ -104,6 +125,12 @@ ConfirmRemove.Title="Confirm Remove"
 ConfirmRemove.Text="Are you sure you wish to remove '$1'?"
 ConfirmRemove.TextMultiple="Are you sure you wish to remove %1 items?"
 
+# output start messages
+Output.StartStreamFailed="Failed to start streaming"
+Output.StartRecordingFailed="Failed to start recording"
+Output.StartReplayFailed="Failed to start replay buffer"
+Output.StartFailedGeneric="Starting the output failed.  Please check the log for details.\n\nNote: If you are using the NVENC or AMD encoders, make sure your video drivers are up to date."
+
 # output connect messages
 Output.ConnectFail.Title="Failed to connect"
 Output.ConnectFail.BadPath="Invalid Path or Connection URL.  Please check your settings to confirm that they are valid."
@@ -119,6 +146,8 @@ Output.RecordNoSpace.Title="Insufficient disk space"
 Output.RecordNoSpace.Msg="There is not sufficient disk space to continue recording."
 Output.RecordError.Title="Recording error"
 Output.RecordError.Msg="An unspecified error occurred while recording."
+Output.ReplayBuffer.NoHotkey.Title="No hotkey set!"
+Output.ReplayBuffer.NoHotkey.Msg="No save hotkey set for replay buffer.  Please set the \"Save\" hotkey to use for saving replay recordings."
 
 # output recording messages
 Output.BadPath.Title="Bad File Path"
@@ -190,6 +219,12 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Top Field First"
 Deinterlacing.BottomFieldFirst="Bottom Field First"
 
+# volume control accessibility text
+VolControl.SliderUnmuted="Volume slider for '%1': %2"
+VolControl.SliderMuted="Volume slider for '%1': %2 (currently muted)"
+VolControl.Mute="Mute '%1'"
+VolControl.Properties="Properties for '%1'"
+
 # add scene dialog
 Basic.Main.AddSceneDlg.Title="Add Scene"
 Basic.Main.AddSceneDlg.Text="Please enter the name of the scene"
@@ -300,9 +335,12 @@ Basic.Main.Scenes="Scenes"
 Basic.Main.Sources="Sources"
 Basic.Main.Connecting="Connecting..."
 Basic.Main.StartRecording="Start Recording"
+Basic.Main.StartReplayBuffer="Start Replay Buffer"
 Basic.Main.StartStreaming="Start Streaming"
 Basic.Main.StopRecording="Stop Recording"
 Basic.Main.StoppingRecording="Stopping Recording..."
+Basic.Main.StopReplayBuffer="Stop Replay Buffer"
+Basic.Main.StoppingReplayBuffer="Stopping Replay Buffer..."
 Basic.Main.StopStreaming="Stop Streaming"
 Basic.Main.StoppingStreaming="Stopping Stream..."
 Basic.Main.ForceStopStreaming="Stop Streaming (discard delay)"
@@ -326,8 +364,14 @@ Basic.MainMenu.Edit.Redo="&Redo"
 Basic.MainMenu.Edit.UndoAction="&Undo $1"
 Basic.MainMenu.Edit.RedoAction="&Redo $1"
 Basic.MainMenu.Edit.LockPreview="&Lock Preview"
+Basic.MainMenu.Edit.Scale="Preview &Scaling"
+Basic.MainMenu.Edit.Scale.Window="Scale to Window"
+Basic.MainMenu.Edit.Scale.Canvas="Canvas (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Output (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Transform"
 Basic.MainMenu.Edit.Transform.EditTransform="&Edit Transform..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Copy Transform"
+Basic.MainMenu.Edit.Transform.PasteTransform="Paste Transform"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Reset Transform"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Rotate 90 degrees CW"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotate 90 degrees CCW"
@@ -354,6 +398,12 @@ Basic.MainMenu.View.StatusBar="&Status Bar"
 # basic mode profile/scene collection menus
 Basic.MainMenu.SceneCollection="&Scene Collection"
 Basic.MainMenu.Profile="&Profile"
+Basic.MainMenu.Profile.Import="Import Profile"
+Basic.MainMenu.Profile.Export="Export Profile"
+Basic.MainMenu.SceneCollection.Import="Import Scene Collection"
+Basic.MainMenu.SceneCollection.Export="Export Scene Collection"
+Basic.MainMenu.Profile.Exists="The profile already exists"
+Basic.MainMenu.SceneCollection.Exists="The scene collection already exists"
 
 # basic mode help menu
 Basic.MainMenu.Tools="&Tools"
@@ -377,8 +427,10 @@ Basic.Settings.Confirm="You have unsaved changes.  Save changes?"
 Basic.Settings.General="General"
 Basic.Settings.General.Theme="Theme"
 Basic.Settings.General.Language="Language"
+Basic.Settings.General.EnableAutoUpdates="Automatically check for updates on startup"
 Basic.Settings.General.WarnBeforeStartingStream="Show confirmation dialog when starting streams"
 Basic.Settings.General.WarnBeforeStoppingStream="Show confirmation dialog when stopping streams"
+Basic.Settings.General.Projectors="Projectors"
 Basic.Settings.General.HideProjectorCursor="Hide cursor over projectors"
 Basic.Settings.General.ProjectorAlwaysOnTop="Make projectors always on top"
 Basic.Settings.General.Snapping="Source Alignment Snapping"
@@ -388,8 +440,12 @@ Basic.Settings.General.SourceSnapping="Snap Sources to other sources"
 Basic.Settings.General.SnapDistance="Snap Sensitivity"
 Basic.Settings.General.RecordWhenStreaming="Automatically record when streaming"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Keep recording when stream stops"
-Basic.Settings.General.SysTrayEnabled="Enable system tray icon"
+Basic.Settings.General.ReplayBufferWhileStreaming="Automatically start replay buffer when streaming"
+Basic.Settings.General.KeepReplayBufferStreamStops="Keep replay buffer active when stream stops"
+Basic.Settings.General.SysTray="System Tray"
 Basic.Settings.General.SysTrayWhenStarted="Minimize to system tray when started"
+Basic.Settings.General.SystemTrayHideMinimize="Always minimize to system tray instead of task bar"
+Basic.Settings.General.SaveProjectors="Save projectors on exit"
 
 # basic mode 'stream' settings
 Basic.Settings.Stream="Stream"
@@ -406,6 +462,14 @@ Basic.Settings.Output.Mode="Output Mode"
 Basic.Settings.Output.Mode.Simple="Simple"
 Basic.Settings.Output.Mode.Adv="Advanced"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg Output"
+Basic.Settings.Output.UseReplayBuffer="Enable Replay Buffer"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximum Replay Time (Seconds)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximum Memory (Megabytes)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Estimated memory usage: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Cannot estimate memory usage.  Please set maximum memory limit."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Note: Make sure to set a hotkey for the replay buffer in the hotkeys section)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Replay Buffer Filename Prefix"
+Basic.Settings.Output.ReplayBuffer.Suffix="Suffix"
 Basic.Settings.Output.Simple.SavePath="Recording Path"
 Basic.Settings.Output.Simple.RecordingQuality="Recording Quality"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Same as stream"
@@ -444,6 +508,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Track 1"
 Basic.Settings.Output.Adv.Audio.Track2="Track 2"
 Basic.Settings.Output.Adv.Audio.Track3="Track 3"
 Basic.Settings.Output.Adv.Audio.Track4="Track 4"
+Basic.Settings.Output.Adv.Audio.Track5="Track 5"
+Basic.Settings.Output.Adv.Audio.Track6="Track 6"
 
 # basic mode 'output' settings - advanced section - recording subsection
 Basic.Settings.Output.Adv.Recording="Recording"
@@ -472,12 +538,14 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Video Encoder Settings (if an
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio Encoder"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio Encoder Settings (if any)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer Settings (if any)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Keyframe interval (frames)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Show all codecs (even if potentially incompatible)"
 
 # basic mode 'output' settings - advanced section - recording subsection - completer
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
 # basic mode 'output' settings - advanced section - recording subsection - TT
-FilenameFormatting.TT="%CCYY		Year, four digits\n%YY		Year, last two digits (00-99)\n%MM		Month as a decimal number (01-12)\n%DD		Day of the month, zero-padded (01-31)\n%hh		Hour in 24h format (00-23)\n%mm		Minute (00-59)\n%ss		Second (00-61)\n%%		A % sign\n%a		Abbreviated weekday name\n%A		Full weekday name\n%b		Abbreviated month name\n%B		Full month name\n%d		Day of the month, zero-padded (01-31)\n%H		Hour in 24h format (00-23)\n%I		Hour in 12h format (01-12)\n%m		Month as a decimal number (01-12)\n%M		Minute (00-59)\n%p		AM or PM designation\n%S		Second (00-61)\n%y		Year, last two digits (00-99)\n%Y		Year\n%z		ISO 8601 offset from UTC or timezone\n		name or abbreviation\n%Z		Timezone name or abbreviation\n"
+FilenameFormatting.TT="%CCYY	Year, four digits\n%YY		Year, last two digits (00-99)\n%MM		Month as a decimal number (01-12)\n%DD		Day of the month, zero-padded (01-31)\n%hh		Hour in 24h format (00-23)\n%mm		Minute (00-59)\n%ss		Second (00-61)\n%%		A % sign\n%a		Abbreviated weekday name\n%A		Full weekday name\n%b		Abbreviated month name\n%B		Full month name\n%d		Day of the month, zero-padded (01-31)\n%H		Hour in 24h format (00-23)\n%I		Hour in 12h format (01-12)\n%m		Month as a decimal number (01-12)\n%M		Minute (00-59)\n%p		AM or PM designation\n%S		Second (00-61)\n%y		Year, last two digits (00-99)\n%Y		Year\n%z		ISO 8601 offset from UTC or timezone\n		name or abbreviation\n%Z		Timezone name or abbreviation\n"
 
 # basic mode 'video' settings
 Basic.Settings.Video="Video"
@@ -531,12 +599,16 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV Color Space"
 Basic.Settings.Advanced.Video.ColorRange="YUV Color Range"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Partial"
 Basic.Settings.Advanced.Video.ColorRange.Full="Full"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Audio Monitoring Device"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Default"
 Basic.Settings.Advanced.StreamDelay="Stream Delay"
 Basic.Settings.Advanced.StreamDelay.Duration="Duration (seconds)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Preserve cutoff point (increase delay) when reconnecting"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Estimated Memory Usage: %1 MB"
 Basic.Settings.Advanced.Network="Network"
 Basic.Settings.Advanced.Network.BindToIP="Bind to IP"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Enable new networking code"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Low latency mode"
 
 # advanced audio properties
 Basic.AdvAudio="Advanced Audio Properties"
@@ -545,6 +617,10 @@ Basic.AdvAudio.Volume="Volume (%)"
 Basic.AdvAudio.Mono="Downmix to Mono"
 Basic.AdvAudio.Panning="Panning"
 Basic.AdvAudio.SyncOffset="Sync Offset (ms)"
+Basic.AdvAudio.Monitoring="Audio Monitoring"
+Basic.AdvAudio.Monitoring.None="Monitor Off"
+Basic.AdvAudio.Monitoring.MonitorOnly="Monitor Only (mute output)"
+Basic.AdvAudio.Monitoring.Both="Monitor and Output"
 Basic.AdvAudio.AudioTracks="Tracks"
 
 # basic mode 'hotkeys' settings
@@ -552,10 +628,6 @@ Basic.Settings.Hotkeys="Hotkeys"
 Basic.Settings.Hotkeys.Pair="Key combinations shared with '%1' act as toggles"
 
 # basic mode hotkeys
-Basic.Hotkeys.StartStreaming="Start Streaming"
-Basic.Hotkeys.StopStreaming="Stop Streaming"
-Basic.Hotkeys.StartRecording="Start Recording"
-Basic.Hotkeys.StopRecording="Stop Recording"
 Basic.Hotkeys.SelectScene="Switch to scene"
 
 # system tray
@@ -615,3 +687,4 @@ SceneItemHide="Hide '%1'"
 # Output warnings
 OutputWarnings.NoTracksSelected="You must select at least one track"
 OutputWarnings.MultiTrackRecording="Warning: Certain formats (such as FLV) do not support multiple tracks per recording"
+OutputWarnings.MP4Recording="Warning: Recordings saved to MP4 will be unrecoverable if the file cannot be finalized (e.g. as a result of BSODs, power losses, etc.). If you want to record multiple audio tracks consider using MKV and remux the recording to mp4 after it is finished (File->Remux Recordings)"
diff --git a/UI/data/locale/es-ES.ini b/UI/data/locale/es-ES.ini
index e988ac9..76aed31 100644
--- a/UI/data/locale/es-ES.ini
+++ b/UI/data/locale/es-ES.ini
@@ -49,6 +49,26 @@ Right="Derecha"
 Top="Arriba"
 Bottom="Abajo"
 Reset="Reiniciar"
+Hours="Horas"
+Minutes="Minutos"
+Seconds="Segundos"
+Deprecated="Obsoleto"
+ReplayBuffer="Búfer de reproducción"
+Import="Importar"
+Export="Exportar"
+
+Updater.Title="Nueva actualización disponible"
+Updater.Text="Hay una nueva versión disponible:"
+Updater.UpdateNow="Actualizar ahora"
+Updater.RemindMeLater="Recordármelo más tarde"
+Updater.Skip="Saltar Versión"
+Updater.Running.Title="Programa actualmente activo"
+Updater.Running.Text="Las salidas están activas actualmente, por favor apague cualquier salida activa antes de intentar actualizar"
+Updater.NoUpdatesAvailable.Title="No hay actualizaciones disponibles"
+Updater.NoUpdatesAvailable.Text="No hay actualizaciones disponibles actualmente"
+Updater.FailedToLaunch="No se pudo iniciar el actualizador"
+Updater.GameCaptureActive.Title="Captura de juego activa"
+Updater.GameCaptureActive.Text="La libreria de captura de juegos esta actualmente en uso. Por favor, cierra cualquier juego/programa que este siendo capturado (o reinicia windows) e intentalo de nuevo."
 
 QuickTransitions.SwapScenes="Cambiar vista previa y salida escenas después de la transición"
 QuickTransitions.SwapScenesTT="Cambia la vista previa y salida escenas después de la transición (si todavía existe la escena original de la salida). \nEsto no deshará cualquier cambio que pueda haber hecho a la escena original de la salida."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Confirmar borrado"
 ConfirmRemove.Text="¿Seguro que desea eliminar '$1'?"
 ConfirmRemove.TextMultiple="¿Seguro que quieres eliminar %1 elementos?"
 
+Output.StartStreamFailed="No se pudo iniciar la emisión"
+Output.StartRecordingFailed="No se pudo iniciar grabación"
+Output.StartReplayFailed="No se pudo iniciar el buffer de replay"
+Output.StartFailedGeneric="No se pudo iniciar la salida. Por favor compruebe los logs para mas detalles. \n\nNota: Si estas usando los codificadores de NVENC o AMD, asegúrate que tus drivers de vídeo están actualizados."
+
 Output.ConnectFail.Title="Error al conectarse"
 Output.ConnectFail.BadPath="URL ruta de acceso o conexión no válida.  Por favor, compruebe su configuración para confirmar que está correcta."
 Output.ConnectFail.ConnectFailed="No se pudo conectar al servidor"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="No hay suficiente espacio en disco"
 Output.RecordNoSpace.Msg="No hay suficiente espacio en disco para continuar grabando."
 Output.RecordError.Title="Error en la grabación"
 Output.RecordError.Msg="Se ha producido un error no especificado durante la grabación."
+Output.ReplayBuffer.NoHotkey.Title="¡Sin tecla de acceso rápido!"
+Output.ReplayBuffer.NoHotkey.Msg="Sin tecla de acceso rápido establecida para el búfer de reproducción. Configure la tecla de acceso \"Guardar\" para guardar las grabaciones de reproducción."
 
 Output.BadPath.Title="Ruta de archivo incorrecta"
 Output.BadPath.Text="La ruta de salida de archivos establecida no es válida.  Por favor, compruebe su configuración para confirmar que se ha establecido una ruta de archivos válida."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Campo Superior Primero"
 Deinterlacing.BottomFieldFirst="Campo Inferior Primero"
 
+VolControl.SliderUnmuted="Deslizador de volumen para '%1': %2"
+VolControl.SliderMuted="Deslizador de volumen para '%1': %2 (silenciado)"
+VolControl.Mute="Silenciar '%1'"
+VolControl.Properties="Propiedades para '%1'"
+
 Basic.Main.AddSceneDlg.Title="Añadir escena"
 Basic.Main.AddSceneDlg.Text="Por favor, introduzca el nombre de la escena"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Escenas"
 Basic.Main.Sources="Fuentes"
 Basic.Main.Connecting="Conectando..."
 Basic.Main.StartRecording="Iniciar grabación"
+Basic.Main.StartReplayBuffer="Iniciar la reproducción del búfer"
 Basic.Main.StartStreaming="Iniciar Transmisión"
 Basic.Main.StopRecording="Detener grabación"
 Basic.Main.StoppingRecording="Deteniendo la grabación..."
+Basic.Main.StopReplayBuffer="Detener la reproducción del búfer"
+Basic.Main.StoppingReplayBuffer="Deteniendo la reproducción del búfer..."
 Basic.Main.StopStreaming="Detener Transmisión"
 Basic.Main.StoppingStreaming="Deteniendo la trasmisión..."
 Basic.Main.ForceStopStreaming="Parar Transmisión (descartar retraso)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="Reh&acer"
 Basic.MainMenu.Edit.UndoAction="&Deshacer $1"
 Basic.MainMenu.Edit.RedoAction="&Rehacer $1"
 Basic.MainMenu.Edit.LockPreview="&Bloquear vista previa"
+Basic.MainMenu.Edit.Scale="Vista previa y escala"
+Basic.MainMenu.Edit.Scale.Window="Ajustar a la ventana"
+Basic.MainMenu.Edit.Scale.Canvas="Lienzo (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Salida (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Transformar"
 Basic.MainMenu.Edit.Transform.EditTransform="&Editar Transformación..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Copiar transformación"
+Basic.MainMenu.Edit.Transform.PasteTransform="Pegar trasformación"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Restablecer transformación"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Girar 90 grados en el sentido de las agujas del reloj"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Girar 90 grados contra el sentido de las agujas del reloj"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="&Barra de Estado"
 
 Basic.MainMenu.SceneCollection="&Colección de Escenas"
 Basic.MainMenu.Profile="&Perfil"
+Basic.MainMenu.Profile.Import="Importar perfil"
+Basic.MainMenu.Profile.Export="Exportar perfil"
+Basic.MainMenu.SceneCollection.Import="Importar colección de escenas"
+Basic.MainMenu.SceneCollection.Export="Exportar colección de escenas"
+Basic.MainMenu.Profile.Exists="El perfil ya existe"
+Basic.MainMenu.SceneCollection.Exists="La colección de escenas ya existe"
 
 Basic.MainMenu.Tools="&Herramientas"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="Hay cambios sin guardar.  ¿Guardar los cambios?"
 Basic.Settings.General="General"
 Basic.Settings.General.Theme="Tema"
 Basic.Settings.General.Language="Idioma"
+Basic.Settings.General.EnableAutoUpdates="Comprobar actualizaciones automáticamente al inicio"
 Basic.Settings.General.WarnBeforeStartingStream="Mostrar diálogo de confirmación cuando se inicia una transmisión"
 Basic.Settings.General.WarnBeforeStoppingStream="Mostrar diálogo de confirmación cuando se para una transmisión"
+Basic.Settings.General.Projectors="Proyectores"
 Basic.Settings.General.HideProjectorCursor="Ocultar el cursor sobre proyectores"
 Basic.Settings.General.ProjectorAlwaysOnTop="Proyectores siempre en la parte superior"
 Basic.Settings.General.Snapping="Ajuste de alineación de la fuente"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Ajustar las fuentes a otras fuentes"
 Basic.Settings.General.SnapDistance="Ajustar la sensibilidad"
 Basic.Settings.General.RecordWhenStreaming="Grabar automáticamente cuando se transmite"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Mantener la grabación cuando se detiene la trasmision"
-Basic.Settings.General.SysTrayEnabled="Activar icono en la bandeja del sistema"
+Basic.Settings.General.ReplayBufferWhileStreaming="Iniciar la reproducción del búfer automáticamente durante la transmisión"
+Basic.Settings.General.KeepReplayBufferStreamStops="Mantener activo el búfer de reproducción cuando la transmisión se detenga"
+Basic.Settings.General.SysTray="Bandeja del sistema"
 Basic.Settings.General.SysTrayWhenStarted="Minimizar a la bandeja del sistema al iniciar"
+Basic.Settings.General.SystemTrayHideMinimize="Minimizar siempre en la bandeja del sistema en lugar de la barra de tareas"
+Basic.Settings.General.SaveProjectors="Guardar los proyectores al salir"
 
 Basic.Settings.Stream="Emision"
 Basic.Settings.Stream.StreamType="Tipo de Emision"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="Modo de salida"
 Basic.Settings.Output.Mode.Simple="Sencillo"
 Basic.Settings.Output.Mode.Adv="Avanzado"
 Basic.Settings.Output.Mode.FFmpeg="Salida de FFmpeg"
+Basic.Settings.Output.UseReplayBuffer="Activar la reproducción del búfer"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Tiempo de reproducción máximo (segundos)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memoria máxima (MB)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Uso estimado de memoria: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="No se puede estimar el uso de memoria. Establezca el límite máximo de memoria."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Nota: Asegúrese de establecer una tecla de acceso rápido para el búfer de reproducción en la sección de teclas rápidas)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Prefijo del nombre de archivo del búfer"
+Basic.Settings.Output.ReplayBuffer.Suffix="Sufijo"
 Basic.Settings.Output.Simple.SavePath="Ruta de grabación"
 Basic.Settings.Output.Simple.RecordingQuality="Calidad de grabación"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Igual a la emision"
@@ -391,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Pista 1"
 Basic.Settings.Output.Adv.Audio.Track2="Pista 2"
 Basic.Settings.Output.Adv.Audio.Track3="Pista 3"
 Basic.Settings.Output.Adv.Audio.Track4="Pista 4"
+Basic.Settings.Output.Adv.Audio.Track5="Pista 5"
+Basic.Settings.Output.Adv.Audio.Track6="Pista 6"
 
 Basic.Settings.Output.Adv.Recording="Grabando"
 Basic.Settings.Output.Adv.Recording.Type="Tipo"
@@ -418,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Configuración de codificador
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador de audio"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Configuración de codificador de vídeo (si existe)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Ajustes de Muxer (en caso de que haya)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Intervalo de fotogramas clave (en Fotogramas)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Mostrar todos los codecs (aunque sean potencialmente incompatibles)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -471,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="Espacio de color YUV"
 Basic.Settings.Advanced.Video.ColorRange="Gama de Color YUV"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Parcial"
 Basic.Settings.Advanced.Video.ColorRange.Full="Completo"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo de monitorización de audio"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Por defecto"
 Basic.Settings.Advanced.StreamDelay="Retraso de la transmisión"
 Basic.Settings.Advanced.StreamDelay.Duration="Duración (segundos)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Preservar el punto de corte (aumento de retraso) al volver a conectar"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Uso estimado de memoria: %1 MB"
 Basic.Settings.Advanced.Network="Red"
 Basic.Settings.Advanced.Network.BindToIP="Enlazar con IP"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Habilitar el nuevo código de red"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Modo de baja latencia"
 
 Basic.AdvAudio="Propiedades de Audio avanzadas"
 Basic.AdvAudio.Name="Nombre"
@@ -484,15 +553,15 @@ Basic.AdvAudio.Volume="Volumen (%)"
 Basic.AdvAudio.Mono="Remezclar a Mono"
 Basic.AdvAudio.Panning="Panorámica"
 Basic.AdvAudio.SyncOffset="Sincronización Offset (ms)"
+Basic.AdvAudio.Monitoring="Monitorización de audio"
+Basic.AdvAudio.Monitoring.None="Monitorización desactivada"
+Basic.AdvAudio.Monitoring.MonitorOnly="Solo monitorización (silenciar la salida)"
+Basic.AdvAudio.Monitoring.Both="Monitorización y salida"
 Basic.AdvAudio.AudioTracks="Pistas"
 
 Basic.Settings.Hotkeys="Atajos"
 Basic.Settings.Hotkeys.Pair="Combinaciones de teclas con '%1' actúan como interruptores"
 
-Basic.Hotkeys.StartStreaming="Iniciar Transmisión"
-Basic.Hotkeys.StopStreaming="Detener Transmisión"
-Basic.Hotkeys.StartRecording="Iniciar grabación"
-Basic.Hotkeys.StopRecording="Detener grabación"
 Basic.Hotkeys.SelectScene="Cambiar a la escena"
 
 Basic.SystemTray.Show="Mostrar"
@@ -546,4 +615,5 @@ SceneItemHide="Ocultar '%1'"
 
 OutputWarnings.NoTracksSelected="Debe seleccionar al menos una pista"
 OutputWarnings.MultiTrackRecording="ADVERTENCIA: Ciertos formatos (como FLV) no admiten varias pistas por grabación"
+OutputWarnings.MP4Recording="ADVERTENCIA: Las grabaciones guardadas en MP4 será irrecuperables si el archivo no puede finalizarse (e.g. como resultado de BSODs, pérdidas de potencia, etcetera). Si quieres grabar varias pistas de audio utiliza MKV y reune la grabación a mp4 después de que termine (archivo-> Remux de grabaciones)"
 
diff --git a/UI/data/locale/et-EE.ini b/UI/data/locale/et-EE.ini
index 2c31217..8362469 100644
--- a/UI/data/locale/et-EE.ini
+++ b/UI/data/locale/et-EE.ini
@@ -48,10 +48,31 @@ Left="Vasakult"
 Right="Paremalt"
 Top="Ãœlalt"
 Bottom="Alt"
+Reset="Lähtesta"
+Hours="Tundi"
+Minutes="Minutit"
+Seconds="Sekundit"
+Deprecated="Aegunud"
+ReplayBuffer="Taasesituse puhver"
+Import="Impordi"
+Export="Ekspordi"
+
+Updater.Title="Uus värskendus saadaval"
+Updater.Text="Uus värskendus on saadaval:"
+Updater.UpdateNow="Värskenda kohe"
+Updater.RemindMeLater="Tuleta mulle hiljem meelde"
+Updater.Skip="Jäta vahele versioon"
+Updater.Running.Title="Programm on hetkel aktiivne"
+Updater.Running.Text="Väljundid on hetkel aktiivsed, palun sulgege aktiivsed väljundid enne uuendamist"
+Updater.NoUpdatesAvailable.Title="Uusi värskendusi pole saadaval"
+Updater.NoUpdatesAvailable.Text="Värskendusi pole praegu saadaval"
+Updater.FailedToLaunch="Uuendaja käivitamine nurjus"
+Updater.GameCaptureActive.Title="Mängu hõive on aktiivne"
 
 QuickTransitions.SwapScenes="Vaheta üleminekul eelvaade ja väljund"
 QuickTransitions.SwapScenesTT="Vahetab pärast üleminekut eelvaate ja väljundi stseenid (kui väljundi esialgne stseen on veel olemas).\nEsialgsele stseenile tehtud muudatusi ei pöörata tagasi."
 QuickTransitions.DuplicateScene="Tee stseenist koopia"
+QuickTransitions.EditProperties="Dubleeritud allikad"
 QuickTransitions.HotkeyName="Valitud üleminek: %1"
 
 Basic.AddTransition="Lisa seadistatav üleminek"
@@ -85,13 +106,19 @@ ConfirmExit.Text="OBS on hetkel aktiivne. Kõik voogedastused ja salvestused pea
 ConfirmRemove.Title="Ãœmbernimetamise kinnitamine"
 ConfirmRemove.Text="Kas soovid kindlasti eemaldada '$1'?"
 
+Output.StartStreamFailed="Voogedastuse alustamine nurjus"
+Output.StartRecordingFailed="Salvestamise alustamine nurjus"
+
 Output.ConnectFail.Title="Ühendamine ei õnnestunud"
 Output.ConnectFail.BadPath="Vigane rada või ühenduse URL. Palun veendu, et valitud sätted on õiged."
 Output.ConnectFail.ConnectFailed="Serveriga ühendamine ebaõnnestus"
 
+Output.RecordError.Title="Salvestamise tõrge"
 
 
+LogReturnDialog.CopyURL="Kopeeri aadress"
 
+LicenseAgreement.IAgree="Nõustun"
 LicenseAgreement.Exit="Välju"
 
 Remux.SourceFile="OBS-i salvestus"
@@ -118,14 +145,20 @@ Basic.Scene="Stseen"
 
 Basic.Main.PreviewConextMenu.Enable="Lülita eelvaade sisse"
 
+ScaleFiltering.Point="Punkt"
+
 
+VolControl.Properties="'%1' atribuudid"
 
 Basic.Main.AddSceneDlg.Title="Stseeni lisamine"
 Basic.Main.AddSceneDlg.Text="Sisesta stseeni nimi"
 
 Basic.Main.DefaultSceneName.Text="Stseen %1"
 
+Basic.Main.AddSceneCollection.Title="Lisada stseeni kogumik"
+Basic.Main.AddSceneCollection.Text="Palun sisestage stseeni kogumiku nimi"
 
+Basic.Main.RenameSceneCollection.Title="Nimeta ümber stseeni kogumik"
 
 AddProfile.Title="Profiili lisamine"
 AddProfile.Text="Sisesta uue profiili nimi"
@@ -140,6 +173,9 @@ Basic.SourceSelect.AddExisting="Lisa olemasolev"
 Basic.SourceSelect.AddVisible="Tee allikas nähtavaks"
 
 Basic.PropertiesWindow="'%1' omadused"
+Basic.PropertiesWindow.AddFiles="Lisa failid"
+Basic.PropertiesWindow.AddDir="Lisa kataloog"
+Basic.PropertiesWindow.AddURL="Lisa tee/URL"
 
 
 
@@ -148,6 +184,7 @@ Basic.Filters="Filtrid"
 Basic.Filters.AudioFilters="Helifiltrid"
 Basic.Filters.AddFilter.Title="Filtri nimi"
 
+Basic.TransformWindow.Position="Asukoht"
 Basic.TransformWindow.Rotation="Pööramine"
 Basic.TransformWindow.Size="Suurus"
 Basic.TransformWindow.Alignment="Joondamine"
@@ -187,27 +224,51 @@ Basic.MainMenu.File.Exit="Välju (&X)"
 
 Basic.MainMenu.Edit="Muuda (&E)"
 Basic.MainMenu.Edit.Undo="Võta tagasi (&U)"
-
-
+Basic.MainMenu.Edit.UndoAction="&Võta tagasi $1"
+Basic.MainMenu.Edit.Transform.Rotate90CW="Pööra 90 kraadi paremale"
+Basic.MainMenu.Edit.Transform.Rotate90CCW="Pööra 90 kraadi vasakule"
+Basic.MainMenu.Edit.Transform.Rotate180="Pööra 180 kraadi"
+Basic.MainMenu.Edit.Transform.FitToScreen="&Sobita ekraanile"
+Basic.MainMenu.Edit.Transform.StretchToScreen="&Venita ekraanile"
+Basic.MainMenu.Edit.Order="&Järjekord"
+Basic.MainMenu.Edit.Order.MoveUp="Liiguta &Ãœles"
+Basic.MainMenu.Edit.Order.MoveDown="Liiguta &Alla"
+Basic.MainMenu.Edit.Order.MoveToTop="Liiguta &Esimeseks"
+Basic.MainMenu.Edit.Order.MoveToBottom="Liiguta &Viimaseks"
+Basic.MainMenu.Edit.AdvAudio="&Täpsemad Heliatribuudid"
+
+Basic.MainMenu.View="&Vaade"
+Basic.MainMenu.View.Toolbars="&Tööriistaribad"
+Basic.MainMenu.View.SceneTransitions="S&tseeni üleminekud"
+Basic.MainMenu.View.StatusBar="&Olekuriba"
+
+Basic.MainMenu.SceneCollection="&Stseeni kogumik"
+Basic.MainMenu.Profile="&Profiil"
 
 
 Basic.MainMenu.Help.Logs="&Logifailid"
 Basic.MainMenu.Help.CheckForUpdates="Otsi värskendusi"
 
 
+Basic.Settings.General.Theme="Teema"
 Basic.Settings.General.Language="Keel"
+Basic.Settings.General.Projectors="Projektorid"
 
 Basic.Settings.Stream="Voogedastus"
 Basic.Settings.Stream.StreamType="Voogedastuse tüüp"
 
 Basic.Settings.Output="Väljund"
 Basic.Settings.Output.Format="Salvestusvorming"
+Basic.Settings.Output.Encoder="Kodeerija"
 Basic.Settings.Output.SelectDirectory="Vali salvestuskaust"
 Basic.Settings.Output.Mode="Väljundrežiim"
 Basic.Settings.Output.Mode.Simple="Lihtne"
 Basic.Settings.Output.Mode.Adv="Täpsemad seaded"
 Basic.Settings.Output.Simple.Encoder.Software="Tarkvara (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Riistvara (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Riistvara (AMD)"
+Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Riistvara (NVENC)"
+Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Tarkvara (x264 madal CPU kasutus, suurendab faili suurust)"
 
 Basic.Settings.Output.Adv.AudioTrack="Helirada"
 Basic.Settings.Output.Adv.Streaming="Voogedastus"
@@ -238,6 +299,8 @@ Basic.Settings.Video.Denominator="Nimetaja:"
 Basic.Settings.Video.InvalidResolution="Eraldusvõime ei sobi. See peab olema kujul [width]x[height] (nt 1920x1080)"
 
 
+Basic.Settings.Audio.DesktopDevice="Töölaua heliseade"
+Basic.Settings.Audio.DesktopDevice2="Töölaua heliseade 2"
 
 Basic.Settings.Advanced.Video.ColorRange.Partial="Osaline"
 Basic.Settings.Advanced.Video.ColorRange.Full="Täielik"
diff --git a/UI/data/locale/eu-ES.ini b/UI/data/locale/eu-ES.ini
index d2ac30d..98208a6 100644
--- a/UI/data/locale/eu-ES.ini
+++ b/UI/data/locale/eu-ES.ini
@@ -49,6 +49,26 @@ Right="Eskuinean"
 Top="Goian"
 Bottom="Behean"
 Reset="Berrezarri"
+Hours="ordu"
+Minutes="minutu"
+Seconds="segundo"
+Deprecated="Zaharkitua"
+ReplayBuffer="Erreprodukzio bufferra"
+Import="Inportatu"
+Export="Esportatu"
+
+Updater.Title="Eguneraketa berria eskuragarri"
+Updater.Text="Eguneraketa berri bat eskuragarri dago:"
+Updater.UpdateNow="Eguneratu orain"
+Updater.RemindMeLater="Gogoratu geroago"
+Updater.Skip="Baztertu bertsioa"
+Updater.Running.Title="Uneko programa aktiboa"
+Updater.Running.Text="Une honetan irteerak aktibo daude, itzali aktibo dauden irteerak eguneratzen saiatu aurretik"
+Updater.NoUpdatesAvailable.Title="Ez dago eguneraketarik eskuragarri"
+Updater.NoUpdatesAvailable.Text="Une honetan ez dago eguneraketarik eskuragarri"
+Updater.FailedToLaunch="Huts egin du eguneratzailea abiarazten"
+Updater.GameCaptureActive.Title="Jolasen kaptura aktiboa"
+Updater.GameCaptureActive.Text="Jolasen kapturaren liburutegia erabiltzen ari da. Itxi kapturatzen ari den  jolasa/programa (edo berrabiarazi Windows) eta saiatu berriro."
 
 QuickTransitions.SwapScenes="Trukatu Aurrebista/Irteera-eszenak trantsizioen ondoren"
 QuickTransitions.SwapScenesTT="Trukatu aurrebistak eta irteera-eszenak trantsizioen ondoren (baldin eta irteerakoaren jatorrizkoa eszena badago).\n Honek ez du desegingo irteerakoaren jatorrizko eszenari egindako aldaketak."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Baieztatu kentzea"
 ConfirmRemove.Text="Ziur zaude '$1' kendu nahi duzula?"
 ConfirmRemove.TextMultiple="Seguru zaude %1 elementuak ezabatu nahi dituzula?"
 
+Output.StartStreamFailed="Huts egin du transmisioak"
+Output.StartRecordingFailed="Huts egin du grabazioak"
+Output.StartReplayFailed="Huts egin du erreprodukzio bufferrak"
+Output.StartFailedGeneric="Huts egin du irteeraren abioak. Begiratu erregistroa zehaztasunak ikusteko.\n\nOharra: NVENC edo AMD kodetzaileak erabiltzen ari bazara segurtatu haien kontrolatzaileak eguneratuta daudela."
+
 Output.ConnectFail.Title="Huts egin du konektatzean"
 Output.ConnectFail.BadPath="Helburu edo konexio-URL okerra. Egiaztatu zure ezarpenak baliozkoak direla baieztatzeko."
 Output.ConnectFail.ConnectFailed="Huts egin du zerbitzariarekin konektatzean"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="Ez dago nahiko tokirik diskoan"
 Output.RecordNoSpace.Msg="Ez dago nahikoa tokirik diskoan grabatzen jarraitzeko."
 Output.RecordError.Title="Grabazio akatsa"
 Output.RecordError.Msg="Zehaztugabeko akats bat gertatu da grabatzerakoan."
+Output.ReplayBuffer.NoHotkey.Title="Laster tekla ezarri gabe!"
+Output.ReplayBuffer.NoHotkey.Msg="Ez da ezarri gordetzeko laster teklarik erreprodukzio bufferrerako. Ezarri \"Gorde\" laster tekla  erreprodukzio bufferrak gordetzeko."
 
 Output.BadPath.Title="Fitxategi-bide okerra"
 Output.BadPath.Text="Ezarritako fitxategiaren irteera-bidea baliogabea da. Egiaztatu zure ezarpenak baieztatzeko baliozko fitxategi-bidea ezarri dela."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Goiko eremua lehenik"
 Deinterlacing.BottomFieldFirst="Beheko eremua lehenik"
 
+VolControl.SliderUnmuted="Bolumen graduatzailea '%1'-rentzat: %2"
+VolControl.SliderMuted="Bolumen graduatzailea '%1'-rentzat: %2 (une honetan mutu)"
+VolControl.Mute="Mututu '%1'"
+VolControl.Properties="'%1'-ren ezaugarriak"
+
 Basic.Main.AddSceneDlg.Title="Gehitu eszena"
 Basic.Main.AddSceneDlg.Text="Sartu eszenaren izena"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Eszenak"
 Basic.Main.Sources="Iturburuak"
 Basic.Main.Connecting="Konektatzen..."
 Basic.Main.StartRecording="Hasi grabazioa"
+Basic.Main.StartReplayBuffer="Abiatu erreprodukzio bufferra"
 Basic.Main.StartStreaming="Hasi transmisioa"
 Basic.Main.StopRecording="Gelditu grabazioa"
 Basic.Main.StoppingRecording="Grabazioa gelditzen..."
+Basic.Main.StopReplayBuffer="Gelditu erreprodukzio buferra"
+Basic.Main.StoppingReplayBuffer="Erreprodukzio bufferra gelditzen..."
 Basic.Main.StopStreaming="Gelditu transmisioa"
 Basic.Main.StoppingStreaming="Transmisioa gelditzen..."
 Basic.Main.ForceStopStreaming="Gelditu transmisioa (baztertu atzerapena)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="&Berregin"
 Basic.MainMenu.Edit.UndoAction="&Desegin $1"
 Basic.MainMenu.Edit.RedoAction="&Berregin $1"
 Basic.MainMenu.Edit.LockPreview="Blokeatu aurrebista"
+Basic.MainMenu.Edit.Scale="Aurrebistaren eskala"
+Basic.MainMenu.Edit.Scale.Window="Eskalatu leihora"
+Basic.MainMenu.Edit.Scale.Canvas="Oihala (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Irteera (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Eraldatu"
 Basic.MainMenu.Edit.Transform.EditTransform="E&ditatu eraldaketa..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Kopiatu eraldaketa"
+Basic.MainMenu.Edit.Transform.PasteTransform="Itsatsi eraldaketa"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Berrezarri eraldaketa"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Biratu 90 gradu erlojuaren norabidean"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Biratu 90 gradu erlojuaren kontrako norabidean"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="Egoera-barra"
 
 Basic.MainMenu.SceneCollection="&Eszena-bilduma"
 Basic.MainMenu.Profile="&Profila"
+Basic.MainMenu.Profile.Import="Inportatu profila"
+Basic.MainMenu.Profile.Export="Esportatu profila"
+Basic.MainMenu.SceneCollection.Import="Inportatu eszena bilduma"
+Basic.MainMenu.SceneCollection.Export="Esportatu eszena bilduma"
+Basic.MainMenu.Profile.Exists="Profila lehendik ere badago"
+Basic.MainMenu.SceneCollection.Exists="Eszena bilduma lehendik ere badago"
 
 Basic.MainMenu.Tools="&Tresnak"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="Gordegabeko aldaketak dituzu. Gorde aldaketak?"
 Basic.Settings.General="Orokorra"
 Basic.Settings.General.Theme="Gaia"
 Basic.Settings.General.Language="Hizkuntza"
+Basic.Settings.General.EnableAutoUpdates="Abiaraztean begiratu automatikoki eguneraketarik ba ote dagoen"
 Basic.Settings.General.WarnBeforeStartingStream="Erakutsi baieztapen elkarrizketa transmisioak hasterakoan"
-Basic.Settings.General.WarnBeforeStoppingStream="Erakutsi baieztapen elkarrizketa transmisioak gelditzerakoan"
+Basic.Settings.General.WarnBeforeStoppingStream="Erakutsi baieztapen elkarrizketa transmisioak gelditzean"
+Basic.Settings.General.Projectors="Projektoreak"
 Basic.Settings.General.HideProjectorCursor="Ezkutatu kurtsorea proiekzioetan"
 Basic.Settings.General.ProjectorAlwaysOnTop="Proiektoreak beti gainean"
 Basic.Settings.General.Snapping="Iturburuaren lerrokatzearen doitzea"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Doitu iturburuak beste iturburuetara"
 Basic.Settings.General.SnapDistance="Doitu sentikortasuna"
 Basic.Settings.General.RecordWhenStreaming="Grabatu automatikoki transmisioa egitean"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Mantendu grabazioa transmisioa gelditzean"
-Basic.Settings.General.SysTrayEnabled="Gaitu sistemaren erretiluko ikonoa"
+Basic.Settings.General.ReplayBufferWhileStreaming="Hasi erreprodukzio bufferra automatikoki transmititzean"
+Basic.Settings.General.KeepReplayBufferStreamStops="Mantendu erreprodukzio bufferra aktiboa transmisioa gelditzean"
+Basic.Settings.General.SysTray="Sistemaren erretilua"
 Basic.Settings.General.SysTrayWhenStarted="Minimizatu sistemaren erretilura hastean"
+Basic.Settings.General.SystemTrayHideMinimize="Minimizatu beti sistemaren erretilura ataza barrara egin ordez"
+Basic.Settings.General.SaveProjectors="Gorde proiekzioak irtetean"
 
 Basic.Settings.Stream="Transmisioa"
 Basic.Settings.Stream.StreamType="Transmisio-mota"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="Irteera-modua"
 Basic.Settings.Output.Mode.Simple="Arrunta"
 Basic.Settings.Output.Mode.Adv="Aurreratua"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg Irteera"
+Basic.Settings.Output.UseReplayBuffer="Gaitu erreprodukzio bufferra"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Erreprodukzioaren gehienezko denbora (segundotan)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Gehienezko memoria (megabytetan)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Ustezko memoria erabilera: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Ezin da kalkulatu memoria erabilera. Ezarri gehienezko memoria."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Oharra: Aseguratu bufferraren erreprodukziorako laster tekla bat ezarri duzula laster teklen atalean)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Erreprodukzio bufferraren fitxategi aurrizkia"
+Basic.Settings.Output.ReplayBuffer.Suffix="Atzizkia"
 Basic.Settings.Output.Simple.SavePath="Grabazio-bidea"
 Basic.Settings.Output.Simple.RecordingQuality="Grabazio-kalitatea"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Transmisioaren berdina"
@@ -369,6 +430,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Galerarik gabeko kalitateaz oh
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Kontuz: Ezin dituzu QSV kodeatzaile ugari bananduta erabili aldiberean jariotu eta grabatzerakoan.  Aldiberean jariotu eta grabatzea nahi baduzu, mesedez aldatu bietako bat, grabaketa kodeatzailea edo jariotze kodeatzailea."
 Basic.Settings.Output.Simple.Encoder.Software="Softwarea (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardwarea (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardwarea (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardwarea (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softwarea (x264 PUZ erabilpen apaleko aurre-ezarpena, fitxategiaren tamaina handitzen du)"
 Basic.Settings.Output.VideoBitrate="Bideo bit-emaria"
@@ -390,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="1 pista"
 Basic.Settings.Output.Adv.Audio.Track2="2 pista"
 Basic.Settings.Output.Adv.Audio.Track3="3 pista"
 Basic.Settings.Output.Adv.Audio.Track4="4 pista"
+Basic.Settings.Output.Adv.Audio.Track5="5. pista"
+Basic.Settings.Output.Adv.Audio.Track6="6. pista"
 
 Basic.Settings.Output.Adv.Recording="Grabatzen"
 Basic.Settings.Output.Adv.Recording.Type="Mota"
@@ -417,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Bideo kodetzailearen ezarpena
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio kodetzailea"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio kodetzailearen ezarpenak (egonez gero)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Bihurtzailearen ezarpenak (egonez gero)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Gako-fotogramen tartea (fotogramak)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Erakutsi kodek guztiak (bateragarriak ez balira ere)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -470,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV kolore-espazioa"
 Basic.Settings.Advanced.Video.ColorRange="YUV kolore-barrutia"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Partziala"
 Basic.Settings.Advanced.Video.ColorRange.Full="Osoa"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Audioa kontrolatzeko gailua"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Lehenetsia"
 Basic.Settings.Advanced.StreamDelay="Taansmisio-atzerapena"
 Basic.Settings.Advanced.StreamDelay.Duration="Iraupena (segundoak)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Mantendu ebaketa puntua (handitu atzerapena) birkonektatzean"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Estimatutako memoria erabilpena: %1 MB"
 Basic.Settings.Advanced.Network="Sarea"
 Basic.Settings.Advanced.Network.BindToIP="IP bidez lotu"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Gaitu sare kode berria"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Latentzia txikiko modua"
 
 Basic.AdvAudio="Audio propietate aurreratuak"
 Basic.AdvAudio.Name="Izena"
@@ -483,15 +553,15 @@ Basic.AdvAudio.Volume="Bolumena (%)"
 Basic.AdvAudio.Mono="Nahasketa monora murriztu"
 Basic.AdvAudio.Panning="Panoramika"
 Basic.AdvAudio.SyncOffset="Sinkronizazioaren desplazamendua (ms)"
+Basic.AdvAudio.Monitoring="Adioaren kontrola"
+Basic.AdvAudio.Monitoring.None="Audioa itzalita"
+Basic.AdvAudio.Monitoring.MonitorOnly="Kontrola bakarrik (irteera mututua)"
+Basic.AdvAudio.Monitoring.Both="Kontrola eta irteera"
 Basic.AdvAudio.AudioTracks="Pistak"
 
 Basic.Settings.Hotkeys="Laster-teklak"
 Basic.Settings.Hotkeys.Pair="'%1'-rekin egindako tekla konbinazioek txandakatze moduan jokatzen dute"
 
-Basic.Hotkeys.StartStreaming="Hasi transmisioa"
-Basic.Hotkeys.StopStreaming="Gelditu transmisioa"
-Basic.Hotkeys.StartRecording="Hasi Grabazioa"
-Basic.Hotkeys.StopRecording="Gelditu grabazioa"
 Basic.Hotkeys.SelectScene="Aldatu eszenara"
 
 Basic.SystemTray.Show="Erakutsi"
@@ -545,4 +615,5 @@ SceneItemHide="Ezkutatu '%1'"
 
 OutputWarnings.NoTracksSelected="Gutxienez pista bat hautatu behar duzu"
 OutputWarnings.MultiTrackRecording="Oharra: Zenbait formatuk (esaterako FLV-k) ez ditu pista anitzak onartzen grabazioan"
+OutputWarnings.MP4Recording="Kontuz: MP4 formatuz gordetako grabazioak izan daitezke berreskuraezinak fitxategia ezin bada bukatu (esate baterako energia etenagatik). Hainbat audio pista grabatu nahi baduzu erabil dezakezu MKV formatua eta mp4 bihurtu grabazioa bukatu ondoren (Fitxategia->Bihurtu grabazioak)"
 
diff --git a/UI/data/locale/fi-FI.ini b/UI/data/locale/fi-FI.ini
index b8c5ff7..cb8d84d 100644
--- a/UI/data/locale/fi-FI.ini
+++ b/UI/data/locale/fi-FI.ini
@@ -49,6 +49,26 @@ Right="Oikea"
 Top="Ylhäältä"
 Bottom="Alhaalta"
 Reset="Palauta"
+Hours="Tuntia"
+Minutes="Minuuttia"
+Seconds="Sekuntia"
+Deprecated="Vanhentunut"
+ReplayBuffer="Toistopuskuri"
+Import="Tuo"
+Export="Vie"
+
+Updater.Title="Uusi päivitys on saatavilla"
+Updater.Text="Uusi päivitys on saatavilla:"
+Updater.UpdateNow="Päivitä nyt"
+Updater.RemindMeLater="Muistuta myöhemmin"
+Updater.Skip="Ohita versio"
+Updater.Running.Title="Ohjelma on käytössä"
+Updater.Running.Text="Tallentaminen/lähetys on aktiivinen. Sulje kaikki ulostulo ennen päivityksen jatkamista"
+Updater.NoUpdatesAvailable.Title="Päivityksiä ei ole saatavilla"
+Updater.NoUpdatesAvailable.Text="Päivityksiä ei ole tällä hetkellä saatavilla"
+Updater.FailedToLaunch="Päivittäjän käynnistäminen epäonnistui"
+Updater.GameCaptureActive.Title="Game capture on aktiivinen"
+Updater.GameCaptureActive.Text="Game capture -kirjasto on yhä käytössä. Sulje kaikki pelit/ohjelmat, joita on kaapattu tai käynnistä tietokone uudelleen."
 
 QuickTransitions.SwapScenes="Vaihda esikatselu- ja ulostulo-skenet siirtymän jälkeen"
 QuickTransitions.SwapScenesTT="Vaihda esikatselu- ja ulostulo-skenet siirtymän jälkeen (jos ulostulon alkuperäinen skene on yhä olemassa).\nTämä ei peruuta muutoksia joita on tehty alkuperäiseen skeneen."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Vahvista poisto"
 ConfirmRemove.Text="Haluatko varmasti poistaa '$1'?"
 ConfirmRemove.TextMultiple="Haluatko varmasti poistaa %1 kohdetta?"
 
+Output.StartStreamFailed="Lähetyksen aloittaminen epäonnistui"
+Output.StartRecordingFailed="Tallennuksen aloittaminen epäonnistui"
+Output.StartReplayFailed="Toistopuskurin käynnistäminen epäonnistui"
+Output.StartFailedGeneric="Ulostulon käynnistäminen epäonnistui. Tarkista loki lisätietoja varten.\n\nHuomio: Jos käytät NVENC tai AMD -enkoodereita, varmista, että näytönohjaimen ajurit on päivitetty ajantasalle."
+
 Output.ConnectFail.Title="Yhdistäminen epäonnistui"
 Output.ConnectFail.BadPath="Viallinen polku tai yhteysosoite.  Tarkista, että asetuksesi ovat kunnossa."
 Output.ConnectFail.ConnectFailed="Palvelimelle yhdistäminen epäonnistui"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="Liian vähän levytilaa"
 Output.RecordNoSpace.Msg="Levytilaa ei ole riittävästi tallennuksen jatkamiseen."
 Output.RecordError.Title="Tallennusvirhe"
 Output.RecordError.Msg="Tallennuksen aikana tapahtui määrittelemätön virhe."
+Output.ReplayBuffer.NoHotkey.Title="Pikanäppäintä ei ole asetettu!"
+Output.ReplayBuffer.NoHotkey.Msg="Tallennuksen pikanäppäintä ei ole asetettu toistopuskurille. Aseta \"Tallenna\"-pikanäppäin tallentaaksesi uusinnat."
 
 Output.BadPath.Title="Viallinen tiedostopolku"
 Output.BadPath.Text="Asetettu tiedostopolku on viallinen.  Tarkista asetuksistasi, että tiedostopolku on asetettu oikein."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Ylin kenttä ensin"
 Deinterlacing.BottomFieldFirst="Alin kenttä ensin"
 
+VolControl.SliderUnmuted="Äänenvoimakkuus \"%1\": %2"
+VolControl.SliderMuted="Äänenvoimakkuus \"%1\": %2 (mykistetty)"
+VolControl.Mute="Mykistä %1"
+VolControl.Properties="Ominaisuudet %1:lle"
+
 Basic.Main.AddSceneDlg.Title="Lisää skene"
 Basic.Main.AddSceneDlg.Text="Aseta skenen nimi"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Skenet"
 Basic.Main.Sources="Lähteet"
 Basic.Main.Connecting="Yhdistetään..."
 Basic.Main.StartRecording="Aloita tallennus"
+Basic.Main.StartReplayBuffer="Käynnistä toistopuskuri"
 Basic.Main.StartStreaming="Aloita lähetys"
 Basic.Main.StopRecording="Pysäytä tallennus"
 Basic.Main.StoppingRecording="Pysäytetään tallennusta..."
+Basic.Main.StopReplayBuffer="Pysäytä toistopuskuri"
+Basic.Main.StoppingReplayBuffer="Pysäytetään toistopuskuri..."
 Basic.Main.StopStreaming="Pysäytä lähetys"
 Basic.Main.StoppingStreaming="Pysäytetään lähetystä..."
 Basic.Main.ForceStopStreaming="Lopeta lähetys (ohita viive)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="&Tee uudelleen"
 Basic.MainMenu.Edit.UndoAction="Kum&oa $1"
 Basic.MainMenu.Edit.RedoAction="T&ee uudelleen $1"
 Basic.MainMenu.Edit.LockPreview="&Lukitse esikatselu"
+Basic.MainMenu.Edit.Scale="Esikatselun &skaalaus"
+Basic.MainMenu.Edit.Scale.Window="Skaalaa ikkunaan"
+Basic.MainMenu.Edit.Scale.Canvas="Kanvaasi (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Ulostulo (%1x%2)"
 Basic.MainMenu.Edit.Transform="Muu&nna"
 Basic.MainMenu.Edit.Transform.EditTransform="M&uokkaa muunnosta..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Kopioi muunnos"
+Basic.MainMenu.Edit.Transform.PasteTransform="Liitä muunnos"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Nollaa muunnos"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Kierrä 90 astetta myötäpäivään"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Kierrä 90 astetta vastapäivään"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="&Tilapalkki"
 
 Basic.MainMenu.SceneCollection="&Skene-kokoelma"
 Basic.MainMenu.Profile="&Profiili"
+Basic.MainMenu.Profile.Import="Tuo profiili"
+Basic.MainMenu.Profile.Export="Vie profiili"
+Basic.MainMenu.SceneCollection.Import="Tuo skene-kokoelma"
+Basic.MainMenu.SceneCollection.Export="Vie skene-kokoelma"
+Basic.MainMenu.Profile.Exists="Profiili on jo olemassa"
+Basic.MainMenu.SceneCollection.Exists="Skene-kokoelma on jo olemassa"
 
 Basic.MainMenu.Tools="T&yökalut"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="Sinulla on tallentamattomia muutoksia.  Tallennetaanko?"
 Basic.Settings.General="Yleiset"
 Basic.Settings.General.Theme="Teema"
 Basic.Settings.General.Language="Kieli"
+Basic.Settings.General.EnableAutoUpdates="Tarkista päivitykset automaattisesti käynnistäessä"
 Basic.Settings.General.WarnBeforeStartingStream="Näytä varmistus-ikkuna kun lähetys aloitetaan"
 Basic.Settings.General.WarnBeforeStoppingStream="Näytä varmistus-ikkuna kun lähetys pysäytetään"
+Basic.Settings.General.Projectors="Peilaukset"
 Basic.Settings.General.HideProjectorCursor="Piilota osoitin peilattaessa"
 Basic.Settings.General.ProjectorAlwaysOnTop="Pidä peilatut esikatselut aina päällimmäisenä"
 Basic.Settings.General.Snapping="Lähteiden kiinnitys"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Kiinnitä lähteitä muihin lähteisiin"
 Basic.Settings.General.SnapDistance="Kiinnityksen herkkyys"
 Basic.Settings.General.RecordWhenStreaming="Tallenna automaattisesti kun lähetetään"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Jatka tallennusta lähetyksen loputtua"
-Basic.Settings.General.SysTrayEnabled="Ota järjestelmäkuvake käyttöön"
+Basic.Settings.General.ReplayBufferWhileStreaming="Käynnistä toistopuskuri automaattisesti lähetettäessä"
+Basic.Settings.General.KeepReplayBufferStreamStops="Pidä toistopuskuri käytössä kun lähetys loppuu"
+Basic.Settings.General.SysTray="Ilmaisinalue"
 Basic.Settings.General.SysTrayWhenStarted="Pienennä ilmaisinalueelle käynnistyessä"
+Basic.Settings.General.SystemTrayHideMinimize="Pienennä aina tilapalkkiin tehtäväpalkin sijaan"
+Basic.Settings.General.SaveProjectors="Tallenna peilaus poistuessa"
 
 Basic.Settings.Stream="Lähetys"
 Basic.Settings.Stream.StreamType="Lähetystyyppi"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="Ulostulon tila"
 Basic.Settings.Output.Mode.Simple="Yksinkertainen"
 Basic.Settings.Output.Mode.Adv="Kehittynyt"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg ulostulo"
+Basic.Settings.Output.UseReplayBuffer="Ota toistopuskuri käyttöön"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Uusinnan pisin aika (Sekunteina)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Muistiraja (Megatavuja)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Arvioitu muistinkäyttö: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Muistin käyttöä ei voida arvioida.  Valitse muistiraja."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Huomio: Varmista että toistopuskurin pikanäppäin on asetettuna asetuksista)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Toistopuskurin tiedostonimen etuliite"
+Basic.Settings.Output.ReplayBuffer.Suffix="Pääte"
 Basic.Settings.Output.Simple.SavePath="Tallennuksen polku"
 Basic.Settings.Output.Simple.RecordingQuality="Tallennuksen laatu"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Sama kuin lähetyksessä"
@@ -369,6 +430,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Häviötön laatu!"
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Varoitus: Et voi käyttää useampaa QSV-enkooderia lähettäessä ja tallentaessa samaan aikaan. Jos haluat tehdä molempia yhtä aikaa, vaihda lähetys tai tallennus-enkooderi."
 Basic.Settings.Output.Simple.Encoder.Software="Ohjelmistopohjainen (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Laitteistopohjainen (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Laitteisto (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Laitteistopohjainen (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Ohjelmistopohjainen (x264 matala CPU-käyttö, lisää tiedostokokoa)"
 Basic.Settings.Output.VideoBitrate="Kuvan bitrate"
@@ -390,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Raita 1"
 Basic.Settings.Output.Adv.Audio.Track2="Raita 2"
 Basic.Settings.Output.Adv.Audio.Track3="Raita 3"
 Basic.Settings.Output.Adv.Audio.Track4="Raita 4"
+Basic.Settings.Output.Adv.Audio.Track5="Raita 5"
+Basic.Settings.Output.Adv.Audio.Track6="Raita 6"
 
 Basic.Settings.Output.Adv.Recording="Tallennus"
 Basic.Settings.Output.Adv.Recording.Type="Tyyppi"
@@ -417,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Videoenkooderin asetukset"
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Äänienkooderi"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Äänienkooderin asetukset"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muunnon asetukset"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Keyframe-väli (frameina)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Näytä kaikki koodekit (myös mahdollisesti yhteensopimattomat)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -470,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV väriavaruus"
 Basic.Settings.Advanced.Video.ColorRange="YUV värialue"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Osittainen"
 Basic.Settings.Advanced.Video.ColorRange.Full="Täysi"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Äänen monitorointilaite"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Oletusarvo"
 Basic.Settings.Advanced.StreamDelay="Lähetyksen viive"
 Basic.Settings.Advanced.StreamDelay.Duration="Kesto (sekunteina)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Säilytä katkaisupiste (lisää viivettä) uudelleenyhdistettäessä"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Arvioitu muistinkäyttö: %1 MB"
 Basic.Settings.Advanced.Network="Verkko"
 Basic.Settings.Advanced.Network.BindToIP="Liitä IP:seen"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Käytä uutta verkkokoodia"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Alhaisen latenssin tila"
 
 Basic.AdvAudio="Äänen lisäominaisuudet"
 Basic.AdvAudio.Name="Nimi"
@@ -483,15 +553,15 @@ Basic.AdvAudio.Volume="Äänenvoimakkuus (%)"
 Basic.AdvAudio.Mono="Miksaa yksikanavaiseksi"
 Basic.AdvAudio.Panning="Balanssi"
 Basic.AdvAudio.SyncOffset="Synkronoinnin viivästys (ms)"
+Basic.AdvAudio.Monitoring="Äänen monitorointi"
+Basic.AdvAudio.Monitoring.None="Monitorointi pois"
+Basic.AdvAudio.Monitoring.MonitorOnly="Vain monitorointi (hiljennä ulostulo)"
+Basic.AdvAudio.Monitoring.Both="Monitorointi ja ulostulo"
 Basic.AdvAudio.AudioTracks="Raidat"
 
 Basic.Settings.Hotkeys="Pikanäppäimet"
 Basic.Settings.Hotkeys.Pair="Yhteiset näppäinyhdistelmät '%1':n kanssa toimivat 'togglena'"
 
-Basic.Hotkeys.StartStreaming="Aloita lähetys"
-Basic.Hotkeys.StopStreaming="Pysäytä lähetys"
-Basic.Hotkeys.StartRecording="Aloita tallennus"
-Basic.Hotkeys.StopRecording="Pysäytä tallennus"
 Basic.Hotkeys.SelectScene="Vaihda skeneen"
 
 Basic.SystemTray.Show="Näytä"
@@ -545,4 +615,5 @@ SceneItemHide="Piilota '%1'"
 
 OutputWarnings.NoTracksSelected="Sinun täytyy valita ainakin yksi raita"
 OutputWarnings.MultiTrackRecording="Varoitus: Jotkin muodot (kuten FLV), eivät tue useampaa raitaa per tallennus"
+OutputWarnings.MP4Recording="Varoitus: MP4-muotoon tallentaessa tiedostoista tulee lukukelvottomia, mikäli niitä ei voi viimeistellä. (esim. johtuen BSOD:sta, sähkökatkosta jne.) Jos haluat tallentaa useampaa ääniraitaa, kannattaa käyttää MKV-muotoa ja muuntaa jälkikäteen MP4:ksi. (Tiedosto->Muunna tallenne)"
 
diff --git a/UI/data/locale/fr-FR.ini b/UI/data/locale/fr-FR.ini
index 781e993..fc438bf 100644
--- a/UI/data/locale/fr-FR.ini
+++ b/UI/data/locale/fr-FR.ini
@@ -27,7 +27,7 @@ Mixer="Mixage audio"
 Browse="Parcourir"
 Mono="Mono"
 Stereo="Stéréo"
-DroppedFrames="Images Perdues %1 (%2%)"
+DroppedFrames="Images perdues : %1 (%2%)"
 PreviewProjector="Projecteur plein écran (aperçu)"
 SceneProjector="Projecteur plein écran (scène)"
 SourceProjector="Projecteur plein écran (source)"
@@ -49,6 +49,26 @@ Right="À droite"
 Top="En haut"
 Bottom="En bas"
 Reset="Réinitialiser"
+Hours="Heures"
+Minutes="Minutes"
+Seconds="Secondes"
+Deprecated="Obsolète"
+ReplayBuffer="Tampon de relecture"
+Import="Importer"
+Export="Exporter"
+
+Updater.Title="Nouvelle mise à jour disponible"
+Updater.Text="Une nouvelle mise à jour est disponible :"
+Updater.UpdateNow="Mettre à jour maintenant"
+Updater.RemindMeLater="Me le rappeler ultérieurement"
+Updater.Skip="Ignorer la version"
+Updater.Running.Title="Programme actuellement en cours d’exécution"
+Updater.Running.Text="Des sorties sont actuellement actives, veuillez fermer toutes les sorties actives avant d'essayer de mettre à jour"
+Updater.NoUpdatesAvailable.Title="Aucune mise à jour disponible"
+Updater.NoUpdatesAvailable.Text="Aucune mise à jour n’est actuellement disponible"
+Updater.FailedToLaunch="Impossible de démarrer la mise à jour"
+Updater.GameCaptureActive.Title="Capture de jeu active"
+Updater.GameCaptureActive.Text="La bibliothèque « hook » de capture de jeu est actuellement active. Veuillez fermer tous les jeux/programmes en cours de capture (ou redémarrez Windows) et réessayez."
 
 QuickTransitions.SwapScenes="Permuter les scènes d'aperçu et de sortie après la transition"
 QuickTransitions.SwapScenesTT="Permute les scènes d'aperçu et de sortie après la transition (si la scène d'origine de la sortie existe toujours). \nCela n'annulera pas les modifications qui auront pu être faites sur la scène d'origine de la sortie."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Confirmer la suppression"
 ConfirmRemove.Text="Êtes-vous sûr de vouloir supprimer « $1 » ?"
 ConfirmRemove.TextMultiple="Voulez-vous vraiment supprimer %1 éléments ?"
 
+Output.StartStreamFailed="Impossible de démarrer le streaming"
+Output.StartRecordingFailed="Impossible de démarrer l'enregistrement"
+Output.StartReplayFailed="Impossible de démarrer le tampon de relecture"
+Output.StartFailedGeneric="Le démarrage de la sortie a échoué. Veuillez consulter le journal pour plus de détails.\n\nRemarque : si vous utilisez les encodeurs NVENC ou AMD, assurez-vous que vos pilotes vidéo soient à jour."
+
 Output.ConnectFail.Title="Échec de la connexion"
 Output.ConnectFail.BadPath="Adresse de connexion ou chemin invalide. Veuillez vérifier vos paramètres afin de confirmer leur validité."
 Output.ConnectFail.ConnectFailed="Échec de la connexion au serveur"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="Espace disque insuffisant"
 Output.RecordNoSpace.Msg="Il n'y a pas suffisamment d'espace disque pour continuer l'enregistrement."
 Output.RecordError.Title="Erreur d'enregistrement"
 Output.RecordError.Msg="Une erreur non spécifiée s'est produite lors de l'enregistrement."
+Output.ReplayBuffer.NoHotkey.Title="Aucun raccourci clavier défini !"
+Output.ReplayBuffer.NoHotkey.Msg="Aucun raccourci clavier défini pour le tampon de relecture. Veuillez en définir un pour utiliser cette fonction."
 
 Output.BadPath.Title="Chemin d'accès au fichier incorrect"
 Output.BadPath.Text="Le chemin configuré pour le flux sortant est invalide. Veuillez vérifier vos paramètres pour confirmer la présence d'un chemin valide."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Champ du haut prioritaire"
 Deinterlacing.BottomFieldFirst="Champ du bas prioritaire"
 
+VolControl.SliderUnmuted="Curseur de volume pour « %1 » : %2"
+VolControl.SliderMuted="Curseur de volume pour « %1 » : %2 (actuellement désactivé)"
+VolControl.Mute="Muet '%1'"
+VolControl.Properties="Propriétés pour '%1'"
+
 Basic.Main.AddSceneDlg.Title="Ajouter une scène"
 Basic.Main.AddSceneDlg.Text="Veuillez entrer le nom de la scène"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Scènes"
 Basic.Main.Sources="Sources"
 Basic.Main.Connecting="Connexion en cours..."
 Basic.Main.StartRecording="Démarrer l'enregistrement"
+Basic.Main.StartReplayBuffer="Démarrer le tampon de relecture"
 Basic.Main.StartStreaming="Commencer le streaming"
 Basic.Main.StopRecording="Arrêter l'enregistrement"
 Basic.Main.StoppingRecording="Arrêt de l'enregistrement..."
+Basic.Main.StopReplayBuffer="Arrêter le tampon de relecture"
+Basic.Main.StoppingReplayBuffer="Arrêt du tampon de relecture..."
 Basic.Main.StopStreaming="Arrêter le streaming"
 Basic.Main.StoppingStreaming="Arrêt du stream..."
 Basic.Main.ForceStopStreaming="Arrêter le streaming (annule le retard)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="&Rétablir"
 Basic.MainMenu.Edit.UndoAction="&Annuler $1"
 Basic.MainMenu.Edit.RedoAction="&Rétablir $1"
 Basic.MainMenu.Edit.LockPreview="Verrouiller la prévisualisation"
+Basic.MainMenu.Edit.Scale="Mi&se à l'échelle de l'aperçu"
+Basic.MainMenu.Edit.Scale.Window="Adapter à la fenêtre"
+Basic.MainMenu.Edit.Scale.Canvas="Canvas (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Sortie (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Transformer"
 Basic.MainMenu.Edit.Transform.EditTransform="Éditer la transformation..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Copier la transformation"
+Basic.MainMenu.Edit.Transform.PasteTransform="Coller la transformation"
 Basic.MainMenu.Edit.Transform.ResetTransform="Réinitialiser la transformation"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Rotation de 90° sens horaire"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotation de 90° sens antihoraire"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="&Barre d'état"
 
 Basic.MainMenu.SceneCollection="Collection de &scènes"
 Basic.MainMenu.Profile="&Profil"
+Basic.MainMenu.Profile.Import="Importer un profil"
+Basic.MainMenu.Profile.Export="Exporter un profil"
+Basic.MainMenu.SceneCollection.Import="Importer une collection de scènes"
+Basic.MainMenu.SceneCollection.Export="Exporter une collection de scènes"
+Basic.MainMenu.Profile.Exists="Ce profil existe déjà"
+Basic.MainMenu.SceneCollection.Exists="Cette collection de scène existe déjà"
 
 Basic.MainMenu.Tools="Outils"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="Vous avez des modifications non enregistrées. Voulez-vo
 Basic.Settings.General="Général"
 Basic.Settings.General.Theme="Thème"
 Basic.Settings.General.Language="Langue"
+Basic.Settings.General.EnableAutoUpdates="Vérifier automatiquement les mises à jour au démarrage"
 Basic.Settings.General.WarnBeforeStartingStream="Afficher une boîte de dialogue de confirmation au démarrage d'un stream"
 Basic.Settings.General.WarnBeforeStoppingStream="Afficher une boîte de dialogue de confirmation à l'arrêt d'un stream"
+Basic.Settings.General.Projectors="Projecteurs"
 Basic.Settings.General.HideProjectorCursor="Cacher le curseur sur les projecteurs"
 Basic.Settings.General.ProjectorAlwaysOnTop="Projecteurs toujours au premier plan"
 Basic.Settings.General.Snapping="Déclenchement d'alignement des sources"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Déclencher avec d'autres sources"
 Basic.Settings.General.SnapDistance="Sensibilité du déclenchement"
 Basic.Settings.General.RecordWhenStreaming="Enregistrer automatiquement lors d'un stream"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Continuer à enregistrer lorsque le stream s’arrête"
-Basic.Settings.General.SysTrayEnabled="Afficher une icône dans la zone de notification"
+Basic.Settings.General.ReplayBufferWhileStreaming="Démarrer automatiquement le tampon de relecture lors d'un stream"
+Basic.Settings.General.KeepReplayBufferStreamStops="Garder le tampon de relecture actif lors de l'arrêt du stream"
+Basic.Settings.General.SysTray="Zone de notifications"
 Basic.Settings.General.SysTrayWhenStarted="Réduire dans la zone de notification dès le démarrage"
+Basic.Settings.General.SystemTrayHideMinimize="Toujours réduire dans la zone de notification au lieu de la barre des tâches"
+Basic.Settings.General.SaveProjectors="Enregistrer les projecteurs en quittant"
 
 Basic.Settings.Stream="Flux"
 Basic.Settings.Stream.StreamType="Type de diffusion"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="Mode de sortie"
 Basic.Settings.Output.Mode.Simple="Simple"
 Basic.Settings.Output.Mode.Adv="Avancé"
 Basic.Settings.Output.Mode.FFmpeg="Sortie FFmpeg"
+Basic.Settings.Output.UseReplayBuffer="Activer le tampon de relecture"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Temps de relecture maximal (secondes)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Mémoire maximum (mégaoctets)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Estimation de la mémoire utilisée : %1 Mo"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Impossible d'estimer l'utilisation de la mémoire. Veuillez définir une limite de mémoire maximale."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Remarque : veillez à définir un raccourci clavier pour le tampon de relecture dans la section des raccourcis clavier)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Nom du fichier du tampon commençant par"
+Basic.Settings.Output.ReplayBuffer.Suffix="Finissant par"
 Basic.Settings.Output.Simple.SavePath="Chemin d'accès de l'enregistrement"
 Basic.Settings.Output.Simple.RecordingQuality="Qualité d'enregistrement"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Identique au stream"
@@ -391,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Piste 1"
 Basic.Settings.Output.Adv.Audio.Track2="Piste 2"
 Basic.Settings.Output.Adv.Audio.Track3="Piste 3"
 Basic.Settings.Output.Adv.Audio.Track4="Piste 4"
+Basic.Settings.Output.Adv.Audio.Track5="Piste 5"
+Basic.Settings.Output.Adv.Audio.Track6="Piste 6"
 
 Basic.Settings.Output.Adv.Recording="Enregistrement"
 Basic.Settings.Output.Adv.Recording.Type="Type "
@@ -418,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Paramètres de l'encodeur vid
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Encodeur audio"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Paramètres de l'encodeur audio (le cas échéant)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Paramètres du muxer (le cas échéant)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Intervalle d'images clés (en images)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Afficher tous les codecs (même si potentiellement incompatibles)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -471,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="Espace de couleur YUV"
 Basic.Settings.Advanced.Video.ColorRange="Gamme de couleurs YUV"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Partielle"
 Basic.Settings.Advanced.Video.ColorRange.Full="Complète"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositif de surveillance audio"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Par défaut"
 Basic.Settings.Advanced.StreamDelay="Retard du stream"
 Basic.Settings.Advanced.StreamDelay.Duration="Durée (en secondes)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Préserver le point de coupure (augmente le retard) lors d'une reconnexion"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Utilisation estimée de la mémoire : %1 Mo"
 Basic.Settings.Advanced.Network="Carte réseau (adresse IP source du flux)"
 Basic.Settings.Advanced.Network.BindToIP="Lier à :"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Activer le nouveau code réseau"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mode faible latence"
 
 Basic.AdvAudio="Propriétés audio avancées"
 Basic.AdvAudio.Name="Nom"
@@ -484,15 +553,15 @@ Basic.AdvAudio.Volume="Volume (%)"
 Basic.AdvAudio.Mono="Passer en mono"
 Basic.AdvAudio.Panning="Panoramique polyphonique"
 Basic.AdvAudio.SyncOffset="Décalage de la synchronisation (ms)"
+Basic.AdvAudio.Monitoring="Surveillance audio"
+Basic.AdvAudio.Monitoring.None="Désactivé"
+Basic.AdvAudio.Monitoring.MonitorOnly="Surveillance uniquement (couper la sortie)"
+Basic.AdvAudio.Monitoring.Both="Surveillance et sortie"
 Basic.AdvAudio.AudioTracks="Pistes"
 
 Basic.Settings.Hotkeys="Raccourcis clavier"
 Basic.Settings.Hotkeys.Pair="Les combinaisons de touches partagées avec '%1' agissent comme déclancheur"
 
-Basic.Hotkeys.StartStreaming="Commencer le streaming"
-Basic.Hotkeys.StopStreaming="Arrêter le streaming"
-Basic.Hotkeys.StartRecording="Démarrer l'enregistrement"
-Basic.Hotkeys.StopRecording="Arrêter l'enregistrement"
 Basic.Hotkeys.SelectScene="Passer à la scène"
 
 Basic.SystemTray.Show="Restaurer"
@@ -546,4 +615,5 @@ SceneItemHide="Cacher '%1'"
 
 OutputWarnings.NoTracksSelected="Vous devez sélectionner au moins une piste"
 OutputWarnings.MultiTrackRecording="Attention : Certains formats (comme FLV) ne supportent pas les pistes multiples pour un même enregistrement"
+OutputWarnings.MP4Recording="Avertissement: Les enregistrements sauvegardés sur MP4 seront irrécupérables si le fichier ne peut pas être finalisé (par exemple, à cause des BSOD, des pertes de puissance, etc.). Si vous voulez enregistrer plusieurs pistes audio, pensez à utiliser MKV et remux l'enregistrement au mp4 après qu'il est terminé (File-> Remux Recordings)"
 
diff --git a/UI/data/locale/gl-ES.ini b/UI/data/locale/gl-ES.ini
index eb8b1ee..4ba0744 100644
--- a/UI/data/locale/gl-ES.ini
+++ b/UI/data/locale/gl-ES.ini
@@ -47,6 +47,7 @@ Top="Arriba"
 Bottom="Abaixo"
 
 
+
 Basic.AddTransition="Engadir transición configurable"
 Basic.RemoveTransition="Eliminar transición configurable"
 Basic.TransitionProperties="Propiedades da transición"
@@ -75,6 +76,7 @@ ConfirmExit.Title="Saír de OBS?"
 ConfirmRemove.Title="Confirmar a eliminación"
 ConfirmRemove.Text="Tes a certeza de querer eliminar '$1'?"
 
+
 Output.ConnectFail.Title="Erro ao se conectar"
 Output.ConnectFail.BadPath="Camiño ou URL de conexión non válidos. Por favor, comproba a configuración para confirmar de que son correctos."
 Output.ConnectFail.ConnectFailed="Erro ao conectar co servidor"
@@ -126,6 +128,7 @@ Basic.Main.PreviewConextMenu.Enable="Habilitar vista previa"
 
 
 
+
 Basic.Main.AddSceneDlg.Title="Engadir escena"
 Basic.Main.AddSceneDlg.Text="Por favor, insire un nome para a escena"
 
@@ -362,10 +365,6 @@ Basic.AdvAudio.SyncOffset="Sincronización Offset (ms)"
 Basic.AdvAudio.AudioTracks="Pistas"
 
 
-Basic.Hotkeys.StartStreaming="Iniciar retransmisión"
-Basic.Hotkeys.StopStreaming="Deter retransmisión"
-Basic.Hotkeys.StartRecording="Iniciar gravación"
-Basic.Hotkeys.StopRecording="Deter gravación"
 
 
 
diff --git a/UI/data/locale/he-IL.ini b/UI/data/locale/he-IL.ini
index cbeab9b..c4470c9 100644
--- a/UI/data/locale/he-IL.ini
+++ b/UI/data/locale/he-IL.ini
@@ -49,6 +49,7 @@ Right="ימין"
 Top="עליון"
 Bottom="תחתון"
 
+
 QuickTransitions.SwapScenes="החלף סצינות תצוגה מקדימה/פלט לאחר המעבר"
 QuickTransitions.SwapScenesTT="החלף הסצינות של התצוגה המקדימה ושל הפלט לאחר המעבר (באם הסצינה המקורית של הפלט עדיין קיימת). \n פעולה זו לא תבטל כל שינוי שייתכן ובוצע לסצינה המקורית של הפלט."
 QuickTransitions.DuplicateScene="הכפל סצינה"
@@ -89,6 +90,7 @@ ConfirmRemove.Title="אשר הסרה"
 ConfirmRemove.Text="האם אתה בטוח שברצונך להסיר את '$1'?"
 ConfirmRemove.TextMultiple="האם אתה בטוח שברצונך להסיר %1 פריטים?"
 
+
 Output.ConnectFail.Title="ההתחברות נכשלה"
 Output.ConnectFail.BadPath="URL לא חוקי של נתיב או חיבור.  נא בדוק את ההגדרות שלך כדי לוודא כי הם נכונים."
 Output.ConnectFail.ConnectFailed="ההתחברות לשרת נכשלה"
@@ -163,6 +165,7 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="שדה עליון ראשון"
 Deinterlacing.BottomFieldFirst="שדה תחתון ראשון"
 
+
 Basic.Main.AddSceneDlg.Title="הוסף סצנה"
 Basic.Main.AddSceneDlg.Text="אנא הזן את השם של הסצנה"
 
@@ -483,10 +486,6 @@ Basic.AdvAudio.AudioTracks="ערוצים"
 Basic.Settings.Hotkeys="מקשי קיצור"
 Basic.Settings.Hotkeys.Pair="צירופי מקשים משותים עם '%1' משמשים כמחליפים"
 
-Basic.Hotkeys.StartStreaming="התחל הזרמת נתונים"
-Basic.Hotkeys.StopStreaming="עצור הזרמת נתונים"
-Basic.Hotkeys.StartRecording="התחל הקלטה"
-Basic.Hotkeys.StopRecording="עצור הקלטה"
 Basic.Hotkeys.SelectScene="עבור לסצנה"
 
 Basic.SystemTray.Show="הצג"
diff --git a/UI/data/locale/hr-HR.ini b/UI/data/locale/hr-HR.ini
index 497e1a9..8fb1343 100644
--- a/UI/data/locale/hr-HR.ini
+++ b/UI/data/locale/hr-HR.ini
@@ -48,6 +48,12 @@ Left="Sleva"
 Right="Zdesna"
 Top="Odozgo"
 Bottom="Odozdo"
+Reset="Poništi"
+Hours="Sati"
+Minutes="Minuta"
+Seconds="Sekundi"
+Deprecated="Prevaziđeno"
+
 
 QuickTransitions.SwapScenes="Zameni scene pregleda/izlaza nakon prelaza"
 QuickTransitions.SwapScenesTT="Zamenjuje scene pregleda i izlaza nakon prelaza (ako originalna scena izlaza još uvek postoji).\nOvo neće poništiti promene koje su načinjene nad originalnom scenom izlaza."
@@ -89,6 +95,7 @@ ConfirmRemove.Title="Potvrdi izbacivanje"
 ConfirmRemove.Text="Da li ste sigurni da želite izbaciti '$1'?"
 ConfirmRemove.TextMultiple="Da li ste sigurni da želite izbaciti %1 stavke?"
 
+
 Output.ConnectFail.Title="Neuspešno povezivanje"
 Output.ConnectFail.BadPath="Neispravna putanja ili URL konekcije. Molim proverite vaša podešavanja da potvrdite njihovu ispravnost."
 Output.ConnectFail.ConnectFailed="Neuspešno povezivanje na server"
@@ -163,6 +170,7 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Prvo gornje polje"
 Deinterlacing.BottomFieldFirst="Prvo donje polje"
 
+
 Basic.Main.AddSceneDlg.Title="Dodaj scenu"
 Basic.Main.AddSceneDlg.Text="Molim unesite ime scene"
 
@@ -281,6 +289,10 @@ Basic.MainMenu.Edit.Redo="U&radi ponovo"
 Basic.MainMenu.Edit.UndoAction="Vrati $1 (&U)"
 Basic.MainMenu.Edit.RedoAction="U&radi ponovo $1"
 Basic.MainMenu.Edit.LockPreview="Zak&ljučaj prikaz"
+Basic.MainMenu.Edit.Scale="Pregled &skaliranja"
+Basic.MainMenu.Edit.Scale.Window="Skaliraj na veličinu prozora"
+Basic.MainMenu.Edit.Scale.Canvas="Platno (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Izlaz (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Transformiši"
 Basic.MainMenu.Edit.Transform.EditTransform="Izm&eni transformaciju..."
 Basic.MainMenu.Edit.Transform.ResetTransform="Poništi t&ransformaciju"
@@ -337,7 +349,6 @@ Basic.Settings.General.SourceSnapping="Privlačenje izvora ka drugim izvorima"
 Basic.Settings.General.SnapDistance="Osetljivost privlačenja"
 Basic.Settings.General.RecordWhenStreaming="Automatsko snimanje pri emitovanju"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Nastavi snimati kada se emitovanje zaustavi"
-Basic.Settings.General.SysTrayEnabled="Omogući ikonicu u sistemskom panelu"
 Basic.Settings.General.SysTrayWhenStarted="Pri pokretanju minimiziraj na ikonicu u sistemskom panelu"
 
 Basic.Settings.Stream="Strim"
@@ -368,6 +379,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Upozorenje za kvalitet bez gub
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Upozorenje: Ne možete koristi više odvojenih QSV enkodera kada emitujete i snimate u isto vreme. Ako želite da emitujete i snimate u isto vreme, molim promenite ili enkoder snimanja ili enkoder emitovanja."
 Basic.Settings.Output.Simple.Encoder.Software="Softverski (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Mašinski (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Mašinski (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Mašinski (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softverski (x264 niska upotreba procesora, povećava veličinu datoteke)"
 Basic.Settings.Output.VideoBitrate="Protok videa"
@@ -487,10 +499,6 @@ Basic.AdvAudio.AudioTracks="Izvori"
 Basic.Settings.Hotkeys="Prečice"
 Basic.Settings.Hotkeys.Pair="Kombinacije tastera deljene sa '%1' se ponašaju kao prekidači"
 
-Basic.Hotkeys.StartStreaming="Započni strimovanje"
-Basic.Hotkeys.StopStreaming="Zaustavi strimovanje"
-Basic.Hotkeys.StartRecording="Počni snimanje"
-Basic.Hotkeys.StopRecording="Zaustavi snimanje"
 Basic.Hotkeys.SelectScene="Prebaci na scenu"
 
 Basic.SystemTray.Show="Prikaži"
diff --git a/UI/data/locale/hu-HU.ini b/UI/data/locale/hu-HU.ini
index f83119b..e5a74be 100644
--- a/UI/data/locale/hu-HU.ini
+++ b/UI/data/locale/hu-HU.ini
@@ -49,6 +49,26 @@ Right="Jobb"
 Top="Felső"
 Bottom="Alsó"
 Reset="Újraindít"
+Hours="Óra"
+Minutes="Perc"
+Seconds="Másodperc"
+Deprecated="Elavult"
+ReplayBuffer="Visszajátszás puffer"
+Import="Importálás"
+Export="Exportálás"
+
+Updater.Title="Új frissítés elérhető"
+Updater.Text="Új frissítés elérhető:"
+Updater.UpdateNow="Frissítés most"
+Updater.RemindMeLater="Emlékeztessen később"
+Updater.Skip="Verzió átugrása"
+Updater.Running.Title="A program jelenleg aktív"
+Updater.Running.Text="Valamely kimenet jelenleg aktív, állítsa le az aktív kimenetet, mielőtt frissíteni próbál"
+Updater.NoUpdatesAvailable.Title="Nincs elérhető frissítés"
+Updater.NoUpdatesAvailable.Text="Jelenleg nincs elérhető frissítés"
+Updater.FailedToLaunch="Frissítő alkalmazás indítása sikertelen"
+Updater.GameCaptureActive.Title="Játék felvétel aktív"
+Updater.GameCaptureActive.Text="Játékfelvétel hook könyvtár jelenleg használatban. Zárjon be minden játékot/programot, amelyet felvesz (vagy indítsa újra a számítógépét) és próbálkozzon újra."
 
 QuickTransitions.SwapScenes="Előnézeti/Kimeneti Jelenetek cseréje átmenet után"
 QuickTransitions.SwapScenesTT="Az előnézet és a kimeneti jelenet cseréje átmenet után (ha a kimenet eredeti jelenete még létezik).\nEz nincs kihatással a kimenet eredeti jelenetére."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Eltávolítás megerősítése"
 ConfirmRemove.Text="\"$1\" eltávolítására készül, biztos benne?"
 ConfirmRemove.TextMultiple="\"%1\" elem eltávolítására készül, biztos benne?"
 
+Output.StartStreamFailed="Stream indítása sikertelen"
+Output.StartRecordingFailed="Felvétel indítása sikertelen"
+Output.StartReplayFailed="Visszajátszás puffer indítása sikertelen"
+Output.StartFailedGeneric="Kimenet indítása sikertelen. Kérem ellenőrizze az eseménynaplóban a részleteket.\n\nMegjegyzés: NVENC vagy AMD kódoló használata esetén, győződjön meg róla, hogy az illesztőprogramok naprakészek!"
+
 Output.ConnectFail.Title="Csatlakozás sikertelen"
 Output.ConnectFail.BadPath="Érvénytelen elérési út vagy kapcsolati URL cím. Kérem, ellenőrizze a beállításokat és győződjön meg az érvényességükről."
 Output.ConnectFail.ConnectFailed="Nem sikerült kapcsolódni a szerverhez"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="Nincs elég szabad lemezterület"
 Output.RecordNoSpace.Msg="Nincs elegendő lemezterület a felvétel folytatásához."
 Output.RecordError.Title="Felvételi hiba"
 Output.RecordError.Msg="Ismeretlen hiba lépett fel a felvétel során."
+Output.ReplayBuffer.NoHotkey.Title="Nincs gyorsbillentyű beállítva!"
+Output.ReplayBuffer.NoHotkey.Msg="Nincs mentés gyorsbillentyű a visszajátszási pufferhez. Kérem állítson be egy \"Mentés\" gyorsbillentyűt a visszajátszások felvételeinek mentésére."
 
 Output.BadPath.Title="A fájl elérési útja hibás"
 Output.BadPath.Text="A beállított elérési útvonal érvénytelen. Kérem ellenőrizze a beállításait és győződjön meg arról, hogy a fájl elérési útja érvényes."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Felső mező először"
 Deinterlacing.BottomFieldFirst="Alsó mező először"
 
+VolControl.SliderUnmuted="Hangerő csúszka a '%1'-hez: %2"
+VolControl.SliderMuted="Hangerő csúszka '%1'-hez: %2 (jelenleg némítva)"
+VolControl.Mute="Némítás '%1'"
+VolControl.Properties="Tulajdonságok a '%1'-hez"
+
 Basic.Main.AddSceneDlg.Title="Jelenet hozzáadása"
 Basic.Main.AddSceneDlg.Text="Kérem adja meg a jelenet nevét"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Jelenetek"
 Basic.Main.Sources="Források"
 Basic.Main.Connecting="Kapcsolódás..."
 Basic.Main.StartRecording="Felvétel indítása"
+Basic.Main.StartReplayBuffer="Visszajátszás puffer indítása"
 Basic.Main.StartStreaming="Stream indítása"
 Basic.Main.StopRecording="Felvétel leállítása"
 Basic.Main.StoppingRecording="Felvétel leállítása..."
+Basic.Main.StopReplayBuffer="Visszajátszás puffer megállítása"
+Basic.Main.StoppingReplayBuffer="Visszajátszás puffer leáll..."
 Basic.Main.StopStreaming="Stream leállítása"
 Basic.Main.StoppingStreaming="Stream leállítása..."
 Basic.Main.ForceStopStreaming="Stream leállítása (Késleltetés elvetése)"
@@ -269,7 +304,7 @@ Basic.MainMenu.File="&Fájl"
 Basic.MainMenu.File.Export="&Exportálás"
 Basic.MainMenu.File.Import="&Importálás"
 Basic.MainMenu.File.ShowRecordings="&Felvételek megjelenítése"
-Basic.MainMenu.File.Remux="Re&mux felvételek"
+Basic.MainMenu.File.Remux="Felvételek re&muxolása"
 Basic.MainMenu.File.Settings="&Beállítások"
 Basic.MainMenu.File.ShowSettingsFolder="Beállítási mappa megjelenítése"
 Basic.MainMenu.File.ShowProfileFolder="Profilmappa megjelenítése"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="&Ismét"
 Basic.MainMenu.Edit.UndoAction="&Visszavonás $1"
 Basic.MainMenu.Edit.RedoAction="&Ismét $1"
 Basic.MainMenu.Edit.LockPreview="&Előnézet zárolás"
+Basic.MainMenu.Edit.Scale="Előnézet &méretezés"
+Basic.MainMenu.Edit.Scale.Window="Ablakhoz igazítás"
+Basic.MainMenu.Edit.Scale.Canvas="Vászon (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Kimenet (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Alakítás"
 Basic.MainMenu.Edit.Transform.EditTransform="&Alakítás átszerkesztése..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Alakítás másolása"
+Basic.MainMenu.Edit.Transform.PasteTransform="Átalakítás beillesztése"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Alakítás visszaállítása"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Forgatás 90 fokkal balra"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Forgatás 90 fokkal jobbra"
@@ -308,16 +349,22 @@ Basic.MainMenu.View.StatusBar="&Állapotsor"
 
 Basic.MainMenu.SceneCollection="&Jelenet gyűjtemény"
 Basic.MainMenu.Profile="&Profil"
+Basic.MainMenu.Profile.Import="Profil importálása"
+Basic.MainMenu.Profile.Export="Profil exportálása"
+Basic.MainMenu.SceneCollection.Import="Jelenet gyűjtemény importálása"
+Basic.MainMenu.SceneCollection.Export="Jelenet gyűjtemény exportálása"
+Basic.MainMenu.Profile.Exists="A profil már létezik"
+Basic.MainMenu.SceneCollection.Exists="A jelenet gyűjtemény már létezik"
 
-Basic.MainMenu.Tools="&Eszközők"
+Basic.MainMenu.Tools="&Eszközök"
 
 Basic.MainMenu.Help="&Segítség"
-Basic.MainMenu.Help.Website="Weboldal meglátogatása"
+Basic.MainMenu.Help.Website="Weboldal megtekintése"
 Basic.MainMenu.Help.Logs="&Naplófájlok"
 Basic.MainMenu.Help.Logs.ShowLogs="&Naplófájlok megjelenítése"
 Basic.MainMenu.Help.Logs.UploadCurrentLog="&Aktuális Naplófájl feltöltése"
 Basic.MainMenu.Help.Logs.UploadLastLog="&Utolsó Naplófájl feltöltése"
-Basic.MainMenu.Help.Logs.ViewCurrentLog="&Jelenlegi napló megtekintése"
+Basic.MainMenu.Help.Logs.ViewCurrentLog="&Jelenlegi Naplófájl megtekintése"
 Basic.MainMenu.Help.CheckForUpdates="Frissítések ellenőrzése"
 
 Basic.Settings.ProgramRestart="A beállítások érvénybe lépéséhez a program újraindítása szükséges."
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="Nem mentette a módosításokat. Menti a változtatások
 Basic.Settings.General="Általános"
 Basic.Settings.General.Theme="Téma"
 Basic.Settings.General.Language="Nyelv"
+Basic.Settings.General.EnableAutoUpdates="Indításkor a frissítések automatikus ellenőrzése"
 Basic.Settings.General.WarnBeforeStartingStream="Megerősítő párbeszédpanel megjelenítése stream indításakor"
 Basic.Settings.General.WarnBeforeStoppingStream="Megerősítő párbeszédpanel megjelenítése stream leállításakor"
+Basic.Settings.General.Projectors="Projektorok"
 Basic.Settings.General.HideProjectorCursor="Projektor nézetben a kurzor elrejtése"
 Basic.Settings.General.ProjectorAlwaysOnTop="Projektorok mindig legfelül"
 Basic.Settings.General.Snapping="Forrás pozicionálásának igazítása"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Források igazítása más forrásokhoz"
 Basic.Settings.General.SnapDistance="Igazítás érzékenysége"
 Basic.Settings.General.RecordWhenStreaming="Automatikus felvétel stream esetén"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Felvétel folytatása a stream leállása esetén"
-Basic.Settings.General.SysTrayEnabled="Tálca ikon elhelyezése"
+Basic.Settings.General.ReplayBufferWhileStreaming="Automatikusan induljon a visszajátszás puffer stream megkezdésekor"
+Basic.Settings.General.KeepReplayBufferStreamStops="Visszajátszás puffer aktívan tartása stream leállása esetén"
+Basic.Settings.General.SysTray="Tálca"
 Basic.Settings.General.SysTrayWhenStarted="Indításkor ikonként a tálcán"
+Basic.Settings.General.SystemTrayHideMinimize="Mindig a rendszertálcára minimalizálás tálca helyett"
+Basic.Settings.General.SaveProjectors="Projektorok mentése kilépéskor"
 
 Basic.Settings.Stream="Stream"
 Basic.Settings.Stream.StreamType="Stream típusa"
@@ -349,19 +402,27 @@ Basic.Settings.Output.Format="Felvétel formátuma"
 Basic.Settings.Output.Encoder="Kódoló"
 Basic.Settings.Output.SelectDirectory="Felvételi könyvtár kiválasztása"
 Basic.Settings.Output.SelectFile="Felvétel fájljának kiválasztása"
-Basic.Settings.Output.EnforceBitrate="Stream kiszolgáló bitráta korlátainak kényszerítése"
+Basic.Settings.Output.EnforceBitrate="Stream kiszolgáló bitsebesség korlátainak kényszerítése"
 Basic.Settings.Output.Mode="Kimeneti mód"
 Basic.Settings.Output.Mode.Simple="Egyszerű"
 Basic.Settings.Output.Mode.Adv="Haladó"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg kimenet"
+Basic.Settings.Output.UseReplayBuffer="Visszajátszás puffer engedélyezése"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximális visszajátszási idő (Másodperc)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximális memória (Megabájt)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Becsült memóriaigény: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nem lehet megbecsülni a memóriaigényt. Kérem állítson be egy maximális memória limitet."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Megjegyzés: Bizonyosodjon meg róla, hogy beállított egy billentyűparancsot az újrajátszás pufferre a gyorsbillentyű szekcióban)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Visszajátszási puffer fájlév előtag"
+Basic.Settings.Output.ReplayBuffer.Suffix="Utótag"
 Basic.Settings.Output.Simple.SavePath="Felvétel helye"
 Basic.Settings.Output.Simple.RecordingQuality="Felvétel minősége"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Ugyanaz, mint a stream"
 Basic.Settings.Output.Simple.RecordingQuality.Small="Jó minőség, közepes fájlméret"
 Basic.Settings.Output.Simple.RecordingQuality.HQ="Megkülönböztethetetlen minőség, nagy fájlméret"
 Basic.Settings.Output.Simple.RecordingQuality.Lossless="Veszteségmentes minőség, hatalmas fájlméret"
-Basic.Settings.Output.Simple.Warn.VideoBitrate="Figyelem: Az adás videó bitrátája %1 értéken áll, ami a kiválasztott kiszolgáló felső határértéke. Amennyiben túl kívánja lépni a megadott %1 értéket, úgy engedélyezze a haladó kódolási opciókat és törölje a \"stream kiszolgáló bitráta korlátainak kényszerítése\" opciót."
-Basic.Settings.Output.Simple.Warn.AudioBitrate="Figyelem: Az adás audio bitrátája %1 értéken áll, ami a kiválasztott kiszolgáló felső határértéke. Amennyiben túl kívánja lépni a megadott %1 értéket, úgy engedélyezze a haladó kódolási opciókat és törölje a \"stream kiszolgáló bitráta korlátainak kényszerítése\" opciót."
+Basic.Settings.Output.Simple.Warn.VideoBitrate="Figyelem: Az adás videó bitsebessége %1 értéken áll, ami a kiválasztott kiszolgáló felső határértéke. Amennyiben túl kívánja lépni a megadott %1 értéket, úgy engedélyezze a haladó kódolási opciókat és törölje a \"stream kiszolgáló bitsebesség korlátainak kényszerítése\" opciót."
+Basic.Settings.Output.Simple.Warn.AudioBitrate="Figyelem: Az adás audio bitsebessége %1 értéken áll, ami a kiválasztott kiszolgáló felső határértéke. Amennyiben túl kívánja lépni a megadott %1 értéket, úgy engedélyezze a haladó kódolási opciókat és törölje a \"stream kiszolgáló bitsebesség korlátainak kényszerítése\" opciót."
 Basic.Settings.Output.Simple.Warn.Encoder="Figyelem: A streamtől eltérő minőséggel történő rögzítés, további CPU erőforrásokat igényel, ha egyidejűleg használja mindkettőt."
 Basic.Settings.Output.Simple.Warn.Lossless="Figyelem: A veszteségmentes minőséggel történő felvétel hatalmas fájlméretet generál. Ezzel a minőséggel percenként akár 7 gigabájt adatot is generálhat nagy felbontáson és képkockasebességen. Ez az eljárás nem ajánlott hosszú felvételekhez, kivéve ha hatalmas lemezterület áll rendelkezésre."
 Basic.Settings.Output.Simple.Warn.Lossless.Msg="Biztos benne, hogy veszteségmentes minőséget kíván használni?"
@@ -372,8 +433,8 @@ Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardver (QSV)"
 Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardver (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardver (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Szoftveres (x264 alacsony CPU használati készlet, növekvő fájlméret)"
-Basic.Settings.Output.VideoBitrate="Videó bitráta"
-Basic.Settings.Output.AudioBitrate="Audio bitráta"
+Basic.Settings.Output.VideoBitrate="Videó bitsebesség"
+Basic.Settings.Output.AudioBitrate="Audio bitsebesség"
 Basic.Settings.Output.Reconnect="Automatikus újracsatlakozás"
 Basic.Settings.Output.RetryDelay="Újrapróbálkozás késleltetése (másodperc)"
 Basic.Settings.Output.MaxRetries="Újrapróbálkozások maximális száma"
@@ -391,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Sáv 1"
 Basic.Settings.Output.Adv.Audio.Track2="Sáv 2"
 Basic.Settings.Output.Adv.Audio.Track3="Sáv 3"
 Basic.Settings.Output.Adv.Audio.Track4="Sáv 4"
+Basic.Settings.Output.Adv.Audio.Track5="Sáv 5"
+Basic.Settings.Output.Adv.Audio.Track6="Sáv 6"
 
 Basic.Settings.Output.Adv.Recording="Rögzítés"
 Basic.Settings.Output.Adv.Recording.Type="Típus"
@@ -418,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Videó kódoló beállításo
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio kódoló"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio kódoló beállítások (ha van)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer beállítások (ha van)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Kulcsképkocka időköz (képkockák)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Minden kodek mutatása (még ha inkompatibilisek is)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -471,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV színtér"
 Basic.Settings.Advanced.Video.ColorRange="YUV színtartomány"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Részleges"
 Basic.Settings.Advanced.Video.ColorRange.Full="Teljes"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Hangfigyelő eszköz"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Alapértelmezett"
 Basic.Settings.Advanced.StreamDelay="Stream késleltetés"
 Basic.Settings.Advanced.StreamDelay.Duration="Időtartam (másodperc)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Töréspont megőrzése (Késleltetés növeléssel) újrakapcsolódás esetén"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Becsült memóriahasználat: %1 MB"
 Basic.Settings.Advanced.Network="Hálózat"
 Basic.Settings.Advanced.Network.BindToIP="IP-hez rendelés"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Új hálózatkezelő kód engedélyezése"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Alacsony késleltetésű mód"
 
 Basic.AdvAudio="Speciális hangtulajdonságok"
 Basic.AdvAudio.Name="Név"
@@ -484,15 +553,15 @@ Basic.AdvAudio.Volume="Hangerő (%)"
 Basic.AdvAudio.Mono="Monora lekeverés"
 Basic.AdvAudio.Panning="Keverő"
 Basic.AdvAudio.SyncOffset="Szinkron eltolás (ms)"
+Basic.AdvAudio.Monitoring="Hangfigyelés"
+Basic.AdvAudio.Monitoring.None="Figyelés kikapcsolása"
+Basic.AdvAudio.Monitoring.MonitorOnly="Csak figyelés (kimenet némítása)"
+Basic.AdvAudio.Monitoring.Both="Figyelés és kimenet"
 Basic.AdvAudio.AudioTracks="Sávok"
 
 Basic.Settings.Hotkeys="Gyorsbillentyűk"
 Basic.Settings.Hotkeys.Pair="Azonos billentyűkombináció a '%1' mezővel, ezért kapcsolóként működik"
 
-Basic.Hotkeys.StartStreaming="Stream indítása"
-Basic.Hotkeys.StopStreaming="Stream leállítása"
-Basic.Hotkeys.StartRecording="Felvétel indítása"
-Basic.Hotkeys.StopRecording="Felvétel leállítása"
 Basic.Hotkeys.SelectScene="Jelenethez kapcsolás"
 
 Basic.SystemTray.Show="Mutat"
@@ -546,4 +615,5 @@ SceneItemHide="Elrejti '%1'"
 
 OutputWarnings.NoTracksSelected="Ki kell jelölnie legalább egy sávot!"
 OutputWarnings.MultiTrackRecording="Figyelem: Bizonyos formátumok (mint az FLV) nem támogatják a több sávot felvételenként"
+OutputWarnings.MP4Recording="Figyelem: Az MP4-be mentett állományok javíthatatlanok, ha a fájl nem kerül lezárásra (pl: BSOD vagy áramkimaradás esetén, stb.). Ha mindenképpen több hangsávval kíván felvételt készíteni, akkor használja az MKV állományt és remuxolja a felvételt MP4-be, miután elkészült. (Fájl->Felvételek remuxolása)"
 
diff --git a/UI/data/locale/it-IT.ini b/UI/data/locale/it-IT.ini
index db93731..c35ed2b 100644
--- a/UI/data/locale/it-IT.ini
+++ b/UI/data/locale/it-IT.ini
@@ -20,7 +20,7 @@ Properties="Proprietà"
 MoveUp="Sposta su"
 MoveDown="Sposta giù"
 Settings="Impostazioni"
-Display="Display"
+Display="Schermo"
 Name="Nome"
 Exit="Esci"
 Mixer="Mixer"
@@ -28,31 +28,40 @@ Browse="Sfoglia"
 Mono="Mono"
 Stereo="Stereo"
 DroppedFrames="Fotogrammi persi %1 (%2%)"
-PreviewProjector="Proiettore Schermo intero (Anteprima)"
-SceneProjector="Proiettore Schermo intero (Scena)"
-SourceProjector="Proiettore Schermo intero (Sorgente)"
+PreviewProjector="Proiettore a schermo intero (anteprima)"
+SceneProjector="Proiettore a schermo intero (scena)"
+SourceProjector="Proiettore a schermo intero (sorgente)"
 Clear="Svuota"
 Revert="Ripristina"
 Show="Mostra"
 Hide="Nascondi"
-Untitled="Senza Titolo"
+Untitled="Senza titolo"
 New="Nuovo"
 Duplicate="Duplica"
 Enable="Abilita"
-DisableOSXVSync="Disabilita il V-Sync OSX"
-ResetOSXVSyncOnExit="Reimpostare V-Sync OSX in uscita"
-HighResourceUsage="Codifica in sovraccarico!  È consigliabile abbassare le impostazioni video o utilizzare un settaggio predefinito di codifica più veloce."
+DisableOSXVSync="Disabilita V-Sync OSX"
+ResetOSXVSyncOnExit="Reimposta V-Sync OSX in uscita"
+HighResourceUsage="Codifica in sovraccarico!  È consigliabile abbassare le impostazioni video o utilizzare una preimpostazione predefinita di codifica più veloce."
 Transition="Transizione"
 QuickTransitions="Transizioni rapide"
 Left="Sinistra"
 Right="Destra"
 Top="Alto"
 Bottom="Basso"
-
-QuickTransitions.SwapScenes="Scambia Scena Preview/Uscita dopo la Transizione"
-QuickTransitions.SwapScenesTT="Scambia la scena in uniscita con quella in preview dopo la transizione (ammesso che la scena in uscita originale ci sia ancora).\nQuesto non modificherà eventuali cambiamenti apportati alla scena di uscita originale."
-QuickTransitions.DuplicateScene="Duplica Scena"
-QuickTransitions.DuplicateSceneTT="Quando si modifica la stessa scena, permette di modificare la trasformazione/visibilità di source senza modificare l'output. \nPer modificare le proprietà delle source senza modificare l'output, abilità 'Source duplicate'.\nCambiare questo valore resetterà la scena output attuale (se esite ancora)."
+Reset="Ripristina"
+Hours="Ore"
+Minutes="Minuti"
+Seconds="Secondi"
+Deprecated="Deprecato"
+ReplayBuffer="Buffer di replay"
+Import="Importa"
+Export="Esporta"
+
+
+QuickTransitions.SwapScenes="Scambia scene di anteprima/uscita dopo la transizione"
+QuickTransitions.SwapScenesTT="Scambia le scene di uscita con quella in anteprima dopo la transizione (ammesso che la scena in uscita originale ci sia ancora).\nQuesto non modificherà eventuali cambiamenti apportati alla scena di uscita originale."
+QuickTransitions.DuplicateScene="Duplica scena"
+QuickTransitions.DuplicateSceneTT="Quando si modifica la stessa scena, permette di modificare la trasformazione/visibilità delle sorgenti senza modificare l'uscita.\nPer modificare le proprietà delle source senza modificare l'uscita, abilità 'Sorgenti duplicate'.\nCambiare questo valore ripristinerà la scena di uscita attuale (se esiste ancora)."
 QuickTransitions.EditProperties="Duplica Risorsa"
 QuickTransitions.EditPropertiesTT="Quando si modifica la stessa scena, consente la modifica di risorse senza modificarne l'output. \nQuesto può essere usato solo se 'Scene doppia' è attivo. \nCerte risorse (come media o catture) non lo supportano e devono essere modificate separatamente. \nCambiare questo valore resetterà l'attuale scena di output (se esiste ancora). \n\nAttenzione: Dato che la risorsa verrà duplicata, questo potrebbe richiedere risorse di sistema o video aggiuntive."
 QuickTransitions.HotkeyName="Transizioni rapide: %1"
@@ -64,7 +73,7 @@ Basic.SceneTransitions="Transizioni di scena"
 Basic.TransitionDuration="Durata"
 Basic.TogglePreviewProgramMode="Modalità studio"
 
-TransitionNameDlg.Text="Per favore inserisci il nome della transizione"
+TransitionNameDlg.Text="Inserisci il nome della transizione"
 TransitionNameDlg.Title="Nome transizione"
 
 TitleBar.Profile="Profilo"
@@ -76,19 +85,20 @@ NameExists.Text="Il nome è già in uso."
 NoNameEntered.Title="Inserisci un nome valido"
 NoNameEntered.Text="Non è possibile utilizzare nomi vuoti."
 
-ConfirmStart.Title="Inizia diretta?"
+ConfirmStart.Title="Vuoi iniziare la trasmissione?"
 ConfirmStart.Text="Sei sicuro di voler iniziare una diretta?"
 
-ConfirmStop.Title="Interrompere diretta?"
-ConfirmStop.Text="Sei sicuro di voler interrompere questa diretta?"
+ConfirmStop.Title="Vuoi fermare la trasmissione?"
+ConfirmStop.Text="Sei sicuro di voler interrompere questa trasmissione?"
 
-ConfirmExit.Title="Uscire da OBS?"
+ConfirmExit.Title="Vuoi uscire da OBS?"
 ConfirmExit.Text="OBS è attualmente attivo. Tutte le dirette/registrazioni saranno fermate. Sei sicuro di voler uscire?"
 
 ConfirmRemove.Title="Conferma la rimozione"
 ConfirmRemove.Text="Sei sicuro di voler rimuovere '$1'?"
 ConfirmRemove.TextMultiple="Sei sicuro di volere rimuovere %1 elementi?"
 
+
 Output.ConnectFail.Title="Impossibile connettersi"
 Output.ConnectFail.BadPath="Percorso o URL di connessione non valido. Controlla le tue impostazioni per confermare che siano valide."
 Output.ConnectFail.ConnectFailed="Connessione al server fallita"
@@ -102,6 +112,8 @@ Output.RecordNoSpace.Title="Spazio su disco insufficiente"
 Output.RecordNoSpace.Msg="Non c'è abbastanza spazio su disco per continuazre la registrazione."
 Output.RecordError.Title="Errore di registrazione"
 Output.RecordError.Msg="Si è verificato un errore non specificato durante la registrazione."
+Output.ReplayBuffer.NoHotkey.Title="Nessuna scorciatoia assegnata!"
+Output.ReplayBuffer.NoHotkey.Msg="Nessuna scorciatoia impostata per salvare il buffer di replay. Impostare la scorciatoia \"Salva\" per poter salvare le registrazioni in replay."
 
 Output.BadPath.Title="Percorso di file invalido"
 Output.BadPath.Text="Il percorso configurato per il file di output non è valido. Controlla le tue impostazioni per confermare che un percorso di file valido è stato impostato."
@@ -122,8 +134,8 @@ Remux.Remux="Converti"
 Remux.OBSRecording="Registrazione OBS"
 Remux.FinishedTitle="Conversione finita"
 Remux.Finished="Registrazione convertita"
-Remux.FinishedError="Registrazione convertita, ma il file potrebbe essere incompleta"
-Remux.SelectRecording="Selezionare registrazione OBS …"
+Remux.FinishedError="Registrazione convertita, ma il file potrebbe essere incompleto"
+Remux.SelectRecording="Selezionare registrazione OBS…"
 Remux.SelectTarget="Selezionare il file di destinazione…"
 Remux.FileExistsTitle="Il file di destinazione esiste"
 Remux.FileExists="Il file di destinazione esiste, si desidera sostituirlo?"
@@ -143,7 +155,7 @@ Basic.AuxDevice4="Mic/Aux 4"
 Basic.Scene="Scena"
 Basic.DisplayCapture="Mostra cattura"
 
-Basic.Main.PreviewConextMenu.Enable="Abilita Anteprima"
+Basic.Main.PreviewConextMenu.Enable="Abilita anteprima"
 
 ScaleFiltering="Scala di filtraggio"
 ScaleFiltering.Point="Punto"
@@ -163,6 +175,7 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Priorità livello superiore"
 Deinterlacing.BottomFieldFirst="Priorità livello inferiore"
 
+
 Basic.Main.AddSceneDlg.Title="Aggiungi scena"
 Basic.Main.AddSceneDlg.Text="Inserisci il nome della scena"
 
@@ -257,9 +270,12 @@ Basic.Main.Scenes="Scene"
 Basic.Main.Sources="Origini"
 Basic.Main.Connecting="Connessione..."
 Basic.Main.StartRecording="Avvia registrazione"
+Basic.Main.StartReplayBuffer="Avvia Buffer di Replay"
 Basic.Main.StartStreaming="Avvia trasmissione"
 Basic.Main.StopRecording="Ferma registrazione"
 Basic.Main.StoppingRecording="Fermando la registrazione..."
+Basic.Main.StopReplayBuffer="Termina Buffer di Replay"
+Basic.Main.StoppingReplayBuffer="Fermando il Buffer di Replay..."
 Basic.Main.StopStreaming="Ferma trasmissione"
 Basic.Main.StoppingStreaming="Arresto diretta..."
 Basic.Main.ForceStopStreaming="Ferma Diretta (annulla ritardo)"
@@ -273,16 +289,22 @@ Basic.MainMenu.File.Settings="&Impostazioni"
 Basic.MainMenu.File.ShowSettingsFolder="Visualizza cartella impostazioni"
 Basic.MainMenu.File.ShowProfileFolder="Mostra la cartella del profilo"
 Basic.MainMenu.AlwaysOnTop="&Sempre in primo piano"
-Basic.MainMenu.File.Exit="Esci (&X)"
+Basic.MainMenu.File.Exit="E&sci"
 
 Basic.MainMenu.Edit="&Modifica"
 Basic.MainMenu.Edit.Undo="&Annulla"
 Basic.MainMenu.Edit.Redo="&Ripristina"
 Basic.MainMenu.Edit.UndoAction="&Ripristina $1"
 Basic.MainMenu.Edit.RedoAction="&Ripristina $1"
-Basic.MainMenu.Edit.LockPreview="&Blocca Anteprima"
+Basic.MainMenu.Edit.LockPreview="&Blocca anteprima"
+Basic.MainMenu.Edit.Scale="Anteprima ridimen&sionamento"
+Basic.MainMenu.Edit.Scale.Window="Scala alla finestra"
+Basic.MainMenu.Edit.Scale.Canvas="Tela (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Uscita (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Trasforma"
 Basic.MainMenu.Edit.Transform.EditTransform="&Modifica e trasforma..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Copia Trasformazione"
+Basic.MainMenu.Edit.Transform.PasteTransform="Incolla Trasformazione"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Reset e trasforma"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Ruota di 90 gradi DW"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Ruota di 90 gradi CCW"
@@ -297,7 +319,7 @@ Basic.MainMenu.Edit.Order.MoveUp="Muovi &Sopra"
 Basic.MainMenu.Edit.Order.MoveDown="Sposta in &basso"
 Basic.MainMenu.Edit.Order.MoveToTop="Sposta in &primo piano"
 Basic.MainMenu.Edit.Order.MoveToBottom="Sposta in &fondo"
-Basic.MainMenu.Edit.AdvAudio="Proprietà Audio &Avanzate"
+Basic.MainMenu.Edit.AdvAudio="Proprietà audio &avanzate"
 
 Basic.MainMenu.View="&Visualizza"
 Basic.MainMenu.View.Toolbars="&Barre degli strumenti"
@@ -307,9 +329,16 @@ Basic.MainMenu.View.StatusBar="&Barra di stato"
 
 Basic.MainMenu.SceneCollection="&Collezione scene"
 Basic.MainMenu.Profile="&Profilo"
+Basic.MainMenu.Profile.Import="Importa profilo"
+Basic.MainMenu.Profile.Export="Esporta profilo"
+Basic.MainMenu.SceneCollection.Import="Importa collezione scene"
+Basic.MainMenu.SceneCollection.Export="Esporta collezione scene"
+Basic.MainMenu.Profile.Exists="Il profilo esiste già"
+Basic.MainMenu.SceneCollection.Exists="La collezione di scene già esiste"
 
+Basic.MainMenu.Tools="&Strumenti"
 
-Basic.MainMenu.Help="Aiuto (&H)"
+Basic.MainMenu.Help="&Aiuto"
 Basic.MainMenu.Help.Website="Visita il sito"
 Basic.MainMenu.Help.Logs="File di &log"
 Basic.MainMenu.Help.Logs.ShowLogs="&Visualizza i file di Log"
@@ -328,6 +357,7 @@ Basic.Settings.General.Language="Lingua"
 Basic.Settings.General.WarnBeforeStartingStream="Chiedi conferma quando si avvia una diretta"
 Basic.Settings.General.WarnBeforeStoppingStream="Chiedi conferma quando si termina una diretta"
 Basic.Settings.General.HideProjectorCursor="Nascondi cursore sopra proiettori"
+Basic.Settings.General.ProjectorAlwaysOnTop="Rendono i proiettori sempre in primo piano"
 Basic.Settings.General.Snapping="Allineamento Snapping Source"
 Basic.Settings.General.ScreenSnapping="Snap source nei bordi dello schermo"
 Basic.Settings.General.CenterSnapping="Snap source al centro orizzontale e verticale"
@@ -335,6 +365,8 @@ Basic.Settings.General.SourceSnapping="Snap sources ad altre sources"
 Basic.Settings.General.SnapDistance="Sensibilità Snap"
 Basic.Settings.General.RecordWhenStreaming="Registra automaticamente quando si è in diretta"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Continua a registrare quando la diretta s'interrompe"
+Basic.Settings.General.SysTrayWhenStarted="Minimizza all'area di notifica all'avvio"
+Basic.Settings.General.SystemTrayHideMinimize="Minimizza sempre nel vassoio di sistema invece che nella barra delle applicazioni"
 
 Basic.Settings.Stream="Stream"
 Basic.Settings.Stream.StreamType="Tipo di stream"
@@ -349,6 +381,14 @@ Basic.Settings.Output.Mode="Modalità di output"
 Basic.Settings.Output.Mode.Simple="Semplice"
 Basic.Settings.Output.Mode.Adv="Avanzate"
 Basic.Settings.Output.Mode.FFmpeg="Uscita FFmpeg"
+Basic.Settings.Output.UseReplayBuffer="Abilita il Buffer di Replay"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo massimo di Replay (Secondi)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memoria Massima (Megabytes)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Uso della memoria stimato: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Impossibile stimare la memoria utilizzata. Impostare un limite massimo di memoria."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Nota: Assicurati di aver impostato una hotkey per il Buffer di Replay nella sezione delle hotkeys)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Prefisso del file per i Buffer di Replay"
+Basic.Settings.Output.ReplayBuffer.Suffix="Suffisso"
 Basic.Settings.Output.Simple.SavePath="Percorso registrazione"
 Basic.Settings.Output.Simple.RecordingQuality="Qualità della registrazione"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Stesso della diretta"
@@ -364,6 +404,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Avviso sulla qualità lossless
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Attenzione: Non è possibile usare più encoder QSV quando si è in diretta e si registra allo stesso tempo. Se vuoi andare in diretta e registrare allo stesso tempo, cambia l'encoder per la registrazione o l'encoder per la diretta."
 Basic.Settings.Output.Simple.Encoder.Software="Software (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 Preset con basso utilizzo della CPU, aumenta le dimensioni del file)"
 Basic.Settings.Output.VideoBitrate="Bitrate video"
@@ -385,13 +426,15 @@ Basic.Settings.Output.Adv.Audio.Track1="Traccia 1"
 Basic.Settings.Output.Adv.Audio.Track2="Traccia 2"
 Basic.Settings.Output.Adv.Audio.Track3="Traccia 3"
 Basic.Settings.Output.Adv.Audio.Track4="Traccia 4"
+Basic.Settings.Output.Adv.Audio.Track5="Traccia 5"
+Basic.Settings.Output.Adv.Audio.Track6="Traccia 6"
 
 Basic.Settings.Output.Adv.Recording="Registrazione"
 Basic.Settings.Output.Adv.Recording.Type="Tipo"
 Basic.Settings.Output.Adv.Recording.Type.Standard="Standard"
 Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Output personalizzato (FFmpeg)"
 Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Utilizzare il codificatore del flusso)"
-Basic.Settings.Output.Adv.Recording.Filename="Formattazione del nome del file"
+Basic.Settings.Output.Adv.Recording.Filename="Formattazione nome del file"
 Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Sovrascrivi il file se già esistente"
 Basic.Settings.Output.Adv.FFmpeg.Type="Tipo di Output FFmpeg"
 Basic.Settings.Output.Adv.FFmpeg.Type.URL="Output in URL"
@@ -465,6 +508,8 @@ Basic.Settings.Advanced.Video.ColorSpace="Spazio colore YUV"
 Basic.Settings.Advanced.Video.ColorRange="Gamma di colore YUV"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Parziale"
 Basic.Settings.Advanced.Video.ColorRange.Full="Intero"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo monitor audio"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Predefinito"
 Basic.Settings.Advanced.StreamDelay="Ritardo Diretta"
 Basic.Settings.Advanced.StreamDelay.Duration="Durata (secondi)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Preserva il punto di taglio (aumenta ritardo) durante la riconnessione"
@@ -472,24 +517,27 @@ Basic.Settings.Advanced.StreamDelay.MemoryUsage="Utilizzo di memoria stimato: %1
 Basic.Settings.Advanced.Network="Rete"
 Basic.Settings.Advanced.Network.BindToIP="Associa a IP"
 
-Basic.AdvAudio="Proprietà Audio Avanzate"
+Basic.AdvAudio="Proprietà audio avanzate"
 Basic.AdvAudio.Name="Nome"
 Basic.AdvAudio.Volume="Volume (%)"
 Basic.AdvAudio.Mono="Downmix to Mono"
 Basic.AdvAudio.Panning="Panning"
 Basic.AdvAudio.SyncOffset="Sync Offset (ms)"
+Basic.AdvAudio.Monitoring="Monitor audio"
+Basic.AdvAudio.Monitoring.None="Monitor spento"
+Basic.AdvAudio.Monitoring.MonitorOnly="Solo monitor (uscita silenziata)"
+Basic.AdvAudio.Monitoring.Both="Monitor e uscita"
 Basic.AdvAudio.AudioTracks="Tracce"
 
 Basic.Settings.Hotkeys="Tasti di scelta rapida"
 Basic.Settings.Hotkeys.Pair="La combinazione di chiavi condivisa con '%1' funziona da commutatore"
 
-Basic.Hotkeys.StartStreaming="Inizia diretta"
-Basic.Hotkeys.StopStreaming="Termina diretta"
-Basic.Hotkeys.StartRecording="Inizia registrazione"
-Basic.Hotkeys.StopRecording="Ferma registrazione"
 Basic.Hotkeys.SelectScene="Passa alla scena"
 
+Basic.SystemTray.Show="Mostra"
+Basic.SystemTray.Hide="Nascondi"
 
+Basic.SystemTray.Message.Reconnecting="Disconnesso.  Riconnessione..."
 
 Hotkeys.Insert="Ins"
 Hotkeys.Delete="Canc"
diff --git a/UI/data/locale/ja-JP.ini b/UI/data/locale/ja-JP.ini
index 9fcd29c..4225e00 100644
--- a/UI/data/locale/ja-JP.ini
+++ b/UI/data/locale/ja-JP.ini
@@ -49,6 +49,26 @@ Right="右"
 Top="上"
 Bottom="下"
 Reset="リセット"
+Hours="時間"
+Minutes="分"
+Seconds="秒"
+Deprecated="非推奨"
+ReplayBuffer="リプレイバッファー"
+Import="インポート"
+Export="エクスポート"
+
+Updater.Title="利用可能な更新"
+Updater.Text="利用可能な更新があります:"
+Updater.UpdateNow="今すぐ更新"
+Updater.RemindMeLater="後で通知"
+Updater.Skip="バージョンをスキップする"
+Updater.Running.Title="現在アクティブなプログラム"
+Updater.Running.Text="出力が現在アクティブです。更新を試みる前にアクティブな出力をシャットダウンしてください。"
+Updater.NoUpdatesAvailable.Title="利用可能な更新はありません"
+Updater.NoUpdatesAvailable.Text="現在利用可能な更新はありません"
+Updater.FailedToLaunch="アップデータの起動に失敗しました"
+Updater.GameCaptureActive.Title="ゲームキャプチャがアクティブ"
+Updater.GameCaptureActive.Text="ゲームキャプチャフックライブラリが現在使用中です。キャプチャされているすべてのゲーム/プログラムを閉じて (またはwindowsを再起動して) からもう一度やり直してください。"
 
 QuickTransitions.SwapScenes="トランジション後にプレビュー/出力シーンを入れ替え"
 QuickTransitions.SwapScenesTT="(出力のオリジナルシーンがまだ存在する場合)、トランジション後のプレビューと出力シーンを入れ替えます。\nこれは出力のオリジナルシーンに加えられた可能性があるすべての変更を元に戻しません。"
@@ -90,6 +110,11 @@ ConfirmRemove.Title="削除の確認"
 ConfirmRemove.Text="'$1' を削除してもよろしいですか?"
 ConfirmRemove.TextMultiple="選択した %1 項目を削除してもよろしいですか?"
 
+Output.StartStreamFailed="配信開始に失敗しました"
+Output.StartRecordingFailed="録画開始に失敗しました"
+Output.StartReplayFailed="リプレイバッファーの開始に失敗しました"
+Output.StartFailedGeneric="出力開始に失敗しました。詳細はログを確認してください。\n\n注: NVENCまたはAMDエンコーダを使用している場合は、ビデオドライバが最新のものであるかを確認してください。"
+
 Output.ConnectFail.Title="接続失敗"
 Output.ConnectFail.BadPath="パスかURLが無効です。再確認して下さい。"
 Output.ConnectFail.ConnectFailed="サーバーへの接続に失敗しました"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="ディスク領域の不足"
 Output.RecordNoSpace.Msg="録画を継続する十分なディスク領域がありません。"
 Output.RecordError.Title="録画エラー"
 Output.RecordError.Msg="録画中に不明なエラーが発生しました。"
+Output.ReplayBuffer.NoHotkey.Title="ホットキーが設定されていません!"
+Output.ReplayBuffer.NoHotkey.Msg="リプレイバッファー保存のホットキー設定がありません。 リプレイ録画保存用に使用する「保存」のホットキーを設定してください。"
 
 Output.BadPath.Title="無効なパス"
 Output.BadPath.Text="設定されたファイルの出力パスが無効です。有効なファイルパスが設定されていることを確認してください。"
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="トップフィールドが先"
 Deinterlacing.BottomFieldFirst="ボトムフィールドが先"
 
+VolControl.SliderUnmuted="'%1' の音量スライダー: %2"
+VolControl.SliderMuted="'%1' の音量スライダー: %2 (現在ミュート)"
+VolControl.Mute="'%1' をミュート"
+VolControl.Properties="'%1' のプロパティ"
+
 Basic.Main.AddSceneDlg.Title="シーン追加"
 Basic.Main.AddSceneDlg.Text="シーンの名前を入力してください"
 
@@ -258,11 +290,14 @@ Basic.Main.Scenes="シーン"
 Basic.Main.Sources="ソース"
 Basic.Main.Connecting="接続中..."
 Basic.Main.StartRecording="録画開始"
+Basic.Main.StartReplayBuffer="リプレイバッファー開始"
 Basic.Main.StartStreaming="配信開始"
 Basic.Main.StopRecording="録画終了"
-Basic.Main.StoppingRecording="録画を停止しています..."
+Basic.Main.StoppingRecording="録画停止処理中..."
+Basic.Main.StopReplayBuffer="リプレイバッファー停止"
+Basic.Main.StoppingReplayBuffer="リプレイバッファー停止処理中..."
 Basic.Main.StopStreaming="配信終了"
-Basic.Main.StoppingStreaming="配信を停止しています..."
+Basic.Main.StoppingStreaming="配信停止処理中..."
 Basic.Main.ForceStopStreaming="配信停止 (遅延破棄)"
 
 Basic.MainMenu.File="ファイル(&F)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="やり直し(&R)"
 Basic.MainMenu.Edit.UndoAction="$1 を元に戻す(&U)"
 Basic.MainMenu.Edit.RedoAction="$1 をやり直す(&R)"
 Basic.MainMenu.Edit.LockPreview="ロックプレビュー(&L)"
+Basic.MainMenu.Edit.Scale="プレビュースケーリング(&S)"
+Basic.MainMenu.Edit.Scale.Window="ウィンドウサイズにスケーリング表示"
+Basic.MainMenu.Edit.Scale.Canvas="基本(キャンバス) (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="出力(スケーリング) (%1x%2)"
 Basic.MainMenu.Edit.Transform="変換(&T)"
 Basic.MainMenu.Edit.Transform.EditTransform="変換の編集...(&E)"
+Basic.MainMenu.Edit.Transform.CopyTransform="変換をコピー"
+Basic.MainMenu.Edit.Transform.PasteTransform="変換を貼り付け"
 Basic.MainMenu.Edit.Transform.ResetTransform="変換をリセット(&R)"
 Basic.MainMenu.Edit.Transform.Rotate90CW="時計回りに 90 度回転"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="反時計回りに 90 度回転"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="ステータスバー(&S)"
 
 Basic.MainMenu.SceneCollection="シーンコレクション(&S)"
 Basic.MainMenu.Profile="プロファイル(&P)"
+Basic.MainMenu.Profile.Import="プロファイルをインポート"
+Basic.MainMenu.Profile.Export="プロファイルをエクスポート"
+Basic.MainMenu.SceneCollection.Import="シーンコレクションをインポート"
+Basic.MainMenu.SceneCollection.Export="シーンコレクションをエクスポート"
+Basic.MainMenu.Profile.Exists="プロファイルは既に存在します"
+Basic.MainMenu.SceneCollection.Exists="シーンコレクションは既に存在します"
 
 Basic.MainMenu.Tools="ツール(&T)"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="保存していない変更があります。変更を
 Basic.Settings.General="一般"
 Basic.Settings.General.Theme="テーマ"
 Basic.Settings.General.Language="言語"
+Basic.Settings.General.EnableAutoUpdates="起動時に自動的に更新を確認する"
 Basic.Settings.General.WarnBeforeStartingStream="配信を開始するときに確認ダイアログを表示する"
 Basic.Settings.General.WarnBeforeStoppingStream="配信を停止するときに確認ダイアログを表示する"
+Basic.Settings.General.Projectors="プロジェクター"
 Basic.Settings.General.HideProjectorCursor="プロジェクター上のカーソルを非表示にする"
 Basic.Settings.General.ProjectorAlwaysOnTop="プロジェクタを常に手前に表示させる"
 Basic.Settings.General.Snapping="ソース配置のスナップ"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="他のソースにソースをスナッ
 Basic.Settings.General.SnapDistance="スナップ感度"
 Basic.Settings.General.RecordWhenStreaming="配信時に自動的に録画"
 Basic.Settings.General.KeepRecordingWhenStreamStops="配信が停止しても録画を継続"
-Basic.Settings.General.SysTrayEnabled="システムトレイアイコンを有効にする"
+Basic.Settings.General.ReplayBufferWhileStreaming="配信時に自動的にリプレイバッファーを開始"
+Basic.Settings.General.KeepReplayBufferStreamStops="配信停止時にリプレイバッファーをアクティブにしておく"
+Basic.Settings.General.SysTray="システムトレイ"
 Basic.Settings.General.SysTrayWhenStarted="起動時にシステムトレイへ最小化"
+Basic.Settings.General.SystemTrayHideMinimize="タスクバーの代わりにシステムトレイに常に最小化する"
+Basic.Settings.General.SaveProjectors="終了時にプロジェクターを保存する"
 
 Basic.Settings.Stream="配信"
 Basic.Settings.Stream.StreamType="配信種別"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="出力モード"
 Basic.Settings.Output.Mode.Simple="基本"
 Basic.Settings.Output.Mode.Adv="詳細"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg の出力"
+Basic.Settings.Output.UseReplayBuffer="リプレイバッファーを有効にする"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="最大リプレイ時間 (秒)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="最大メモリ (メガバイト)"
+Basic.Settings.Output.ReplayBuffer.Estimate="概算メモリ使用量: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="メモリ使用量を見積もることができません。 最大メモリ制限を設定してください。"
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(注: ホットキーでリプレイバッファーのホットキーを設定してください)"
+Basic.Settings.Output.ReplayBuffer.Prefix="リプレイバッファーのファイル名の接頭辞"
+Basic.Settings.Output.ReplayBuffer.Suffix="接尾辞"
 Basic.Settings.Output.Simple.SavePath="録画ファイルのパス"
 Basic.Settings.Output.Simple.RecordingQuality="録画品質"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="配信と同じ"
@@ -391,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="トラック 1"
 Basic.Settings.Output.Adv.Audio.Track2="トラック 2"
 Basic.Settings.Output.Adv.Audio.Track3="トラック 3"
 Basic.Settings.Output.Adv.Audio.Track4="トラック 4"
+Basic.Settings.Output.Adv.Audio.Track5="トラック 5"
+Basic.Settings.Output.Adv.Audio.Track6="トラック 6"
 
 Basic.Settings.Output.Adv.Recording="録画"
 Basic.Settings.Output.Adv.Recording.Type="種別"
@@ -418,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="映像エンコーダ設定 (
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="音声エンコーダ"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="音声エンコーダ設定 (ある場合)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="マルチプレクサーの設定 (ある場合)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="キーフレーム間隔 (フレーム)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="すべてのコーデックを表示 (潜在的に互換性がない場合でも)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -471,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV 色空間"
 Basic.Settings.Advanced.Video.ColorRange="YUV 色範囲"
 Basic.Settings.Advanced.Video.ColorRange.Partial="一部"
 Basic.Settings.Advanced.Video.ColorRange.Full="全部"
+Basic.Settings.Advanced.Audio.MonitoringDevice="音声モニタリングデバイス"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="既定"
 Basic.Settings.Advanced.StreamDelay="遅延配信"
 Basic.Settings.Advanced.StreamDelay.Duration="継続時間 (秒)"
 Basic.Settings.Advanced.StreamDelay.Preserve="再接続時にカットオフポイントを保持する (増加遅延)"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="概算メモリ使用量: %1 MB"
 Basic.Settings.Advanced.Network="ネットワーク"
 Basic.Settings.Advanced.Network.BindToIP="IP選択"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="新しいネットワークコードを有効にする"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="低遅延モード"
 
 Basic.AdvAudio="オーディオの詳細プロパティ"
 Basic.AdvAudio.Name="名称"
@@ -484,15 +553,15 @@ Basic.AdvAudio.Volume="音量 (%)"
 Basic.AdvAudio.Mono="モノラルにダウンミックス"
 Basic.AdvAudio.Panning="パンニング"
 Basic.AdvAudio.SyncOffset="同期オフセット (ミリ秒)"
+Basic.AdvAudio.Monitoring="音声モニタリング"
+Basic.AdvAudio.Monitoring.None="モニターオフ"
+Basic.AdvAudio.Monitoring.MonitorOnly="モニターのみ (出力はミュート)"
+Basic.AdvAudio.Monitoring.Both="モニターと出力"
 Basic.AdvAudio.AudioTracks="トラック"
 
 Basic.Settings.Hotkeys="ホットキー"
 Basic.Settings.Hotkeys.Pair="'%1' との組合せでトグルスイッチとして機能します"
 
-Basic.Hotkeys.StartStreaming="配信開始"
-Basic.Hotkeys.StopStreaming="配信終了"
-Basic.Hotkeys.StartRecording="録画開始"
-Basic.Hotkeys.StopRecording="録画終了"
 Basic.Hotkeys.SelectScene="シーン切り替え"
 
 Basic.SystemTray.Show="表示"
@@ -546,4 +615,5 @@ SceneItemHide="'%1' を非表示"
 
 OutputWarnings.NoTracksSelected="少なくとも 1 つのトラックを選択する必要があります"
 OutputWarnings.MultiTrackRecording="警告: 特定のフォーマット (FLVなど) は1つの録画で複数のトラックをサポートしていません"
+OutputWarnings.MP4Recording="警告: ファイルをファイナライズ出来ない場合 (例えば、BSOD、電力損失などの結果として) はMP4に保存された録画は回復不能になります。 複数の音声トラックを録画する場合はMKVの利用を検討して録画の終了後にMP4に再多重化してください。(ファイル -> 録画の再多重化)"
 
diff --git a/UI/data/locale/ko-KR.ini b/UI/data/locale/ko-KR.ini
index 50353f0..9c62f0e 100644
--- a/UI/data/locale/ko-KR.ini
+++ b/UI/data/locale/ko-KR.ini
@@ -49,6 +49,26 @@ Right="오른쪽"
 Top="위"
 Bottom="아래"
 Reset="초기화"
+Hours="시"
+Minutes="분"
+Seconds="ì´ˆ"
+Deprecated="사용하지 않음"
+ReplayBuffer="리플레이 버퍼"
+Import="가져오기"
+Export="내보내기"
+
+Updater.Title="사용가능한 판올림이 있습니다"
+Updater.Text="새 판올림이 준비되었습니다:"
+Updater.UpdateNow="지금 판올림하기"
+Updater.RemindMeLater="나중에 다시 알림"
+Updater.Skip="이번 버전 건너뛰기"
+Updater.Running.Title="현재 활성화된 프로그램"
+Updater.Running.Text="판올림 전에 활성화되어 있는 출력을 먼저 꺼주세요"
+Updater.NoUpdatesAvailable.Title="가능한 판올림이 없습니다"
+Updater.NoUpdatesAvailable.Text="현재 사용가능한 판올림이 없습니다"
+Updater.FailedToLaunch="판올림 도우미를 실행할 수 없습니다"
+Updater.GameCaptureActive.Title="게임 캡쳐 기능이 활성화 중"
+Updater.GameCaptureActive.Text="게임 캡쳐 기능을 현재 사용 중입니다. 캡쳐 중인 게임이나 프로그램을 종료(혹은 윈도우를 재시작) 한 다음 다시 시도하세요."
 
 QuickTransitions.SwapScenes="전환 후 미리 보기/출력 장면을 교체"
 QuickTransitions.SwapScenesTT="(만약 출력 쪽 원본 장면이 있을 때) 전환 작업 이후 미리 보기와 출력 장면을 교체합니다. \n출력 쪽 원본 장면에서 변경한 내용은 사라지지 않습니다."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="제거 확인"
 ConfirmRemove.Text="'$1'을 정말로 제거하시겠습니까?"
 ConfirmRemove.TextMultiple="정말로 %1 개의 항목을 제거하겠습니까?"
 
+Output.StartStreamFailed="방송을 시작하지 못했습니다"
+Output.StartRecordingFailed="녹화를 시작하지 못했습니다"
+Output.StartReplayFailed="리플레이 버퍼를 시작하지 못했습니다"
+Output.StartFailedGeneric="출력을 시작하지 못했습니다. 기록 파일을 확인하십시오.\n\n참고: NVENC 혹은 AMD 인코더를 사용하고 있다면 드라이버를 최신 버전으로 유지하십시오."
+
 Output.ConnectFail.Title="연결에 실패했음"
 Output.ConnectFail.BadPath="잘못된 경로 혹은 연결 주소입니다. 유효한 값인지 설정을 확인하시기 바랍니다. "
 Output.ConnectFail.ConnectFailed="서버에 연결하지 못했습니다"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="디스크 공간 부족"
 Output.RecordNoSpace.Msg="녹화를 계속하기 위한 디스크 공간이 부족합니다."
 Output.RecordError.Title="녹화 오류"
 Output.RecordError.Msg="녹화 중 예기치 못한 오류가 발생했습니다."
+Output.ReplayBuffer.NoHotkey.Title="단축키가 없습니다!"
+Output.ReplayBuffer.NoHotkey.Msg="리플레이를 저장하는 단축키를 지정하지 않았습니다. 리플레이 녹화 기능을 사용하려면 \"저장\" 단축키를 지정하십시오."
 
 Output.BadPath.Title="잘못된 파일 경로"
 Output.BadPath.Text="설정된 출력 파일 경로가 올바르지 않습니다. 경로가 제대로 설정이 되었는지 확인하십시오. "
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="야디프 2x"
 Deinterlacing.TopFieldFirst="상위 필드 우선"
 Deinterlacing.BottomFieldFirst="하단 필드 우선"
 
+VolControl.SliderUnmuted="'%1'의 음량 조절: %2"
+VolControl.SliderMuted="'%1'의 음량 조절: %2 (현재 음소거)"
+VolControl.Mute="음소거 '%1'"
+VolControl.Properties="'%1' 속성"
+
 Basic.Main.AddSceneDlg.Title="장면 추가"
 Basic.Main.AddSceneDlg.Text="장면의 이름을 입력하십시오"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="장면 목록:"
 Basic.Main.Sources="소스 목록:"
 Basic.Main.Connecting="연결 중..."
 Basic.Main.StartRecording="녹화 시작"
+Basic.Main.StartReplayBuffer="리플레이 버퍼 시작"
 Basic.Main.StartStreaming="방송 시작"
 Basic.Main.StopRecording="녹화 중단"
 Basic.Main.StoppingRecording="녹화를 중단합니다...."
+Basic.Main.StopReplayBuffer="리플레이 버퍼 중단"
+Basic.Main.StoppingReplayBuffer="리플레이 버퍼를 멈추고 있습니다..,"
 Basic.Main.StopStreaming="방송 중단"
 Basic.Main.StoppingStreaming="방송을 중지합니다..."
 Basic.Main.ForceStopStreaming="방송 중지(지연된 분량도 마무리없이 즉시 송출 중단)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="다시 실행(&R)"
 Basic.MainMenu.Edit.UndoAction="$1 실행 취소(&U)"
 Basic.MainMenu.Edit.RedoAction="$1 되돌리기(&R)"
 Basic.MainMenu.Edit.LockPreview="미리보기 잠금(&L)"
+Basic.MainMenu.Edit.Scale="미리보기 비율(&S)"
+Basic.MainMenu.Edit.Scale.Window="창에 맞추기"
+Basic.MainMenu.Edit.Scale.Canvas="캔버스 (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="출력 (%1x%2)"
 Basic.MainMenu.Edit.Transform="변환(&T)"
 Basic.MainMenu.Edit.Transform.EditTransform="변환 편집(&E)"
+Basic.MainMenu.Edit.Transform.CopyTransform="변환 복사"
+Basic.MainMenu.Edit.Transform.PasteTransform="변환 붙여넣기"
 Basic.MainMenu.Edit.Transform.ResetTransform="변환 초기화(&R)"
 Basic.MainMenu.Edit.Transform.Rotate90CW="시계 방향으로 90도 회전"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="반시계 방향으로 90도 회전"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="상태 표시줄(&S)"
 
 Basic.MainMenu.SceneCollection="장면 모음(&S)"
 Basic.MainMenu.Profile="프로파일(&P)"
+Basic.MainMenu.Profile.Import="프로파일 가져오기"
+Basic.MainMenu.Profile.Export="프로파일 내보내기"
+Basic.MainMenu.SceneCollection.Import="장면 모음 가져오기"
+Basic.MainMenu.SceneCollection.Export="장면 모음 내보내기"
+Basic.MainMenu.Profile.Exists="그 프로파일은 이미 존재합니다."
+Basic.MainMenu.SceneCollection.Exists="그 장면 모음은 이미 존재합니다."
 
 Basic.MainMenu.Tools="도구(&T)"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="저장하지 않은 설정이 있습니다. 저장하시
 Basic.Settings.General="일반"
 Basic.Settings.General.Theme="테마"
 Basic.Settings.General.Language="언어"
+Basic.Settings.General.EnableAutoUpdates="프로그램을 시작할 때 자동으로 판올림이 있나 확인"
 Basic.Settings.General.WarnBeforeStartingStream="방송을 시작할 때 확인 대화 상자 표시"
 Basic.Settings.General.WarnBeforeStoppingStream="방송을 중단할 때 확인 대화 상자 표시"
+Basic.Settings.General.Projectors="프로젝터"
 Basic.Settings.General.HideProjectorCursor="프로젝터 위 커서 숨기기"
 Basic.Settings.General.ProjectorAlwaysOnTop="프로젝터를 항상 위로"
 Basic.Settings.General.Snapping="소스를 자석처럼 달라붙여서 정렬"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="소스를 다른 소스에 붙임"
 Basic.Settings.General.SnapDistance="자석 감도"
 Basic.Settings.General.RecordWhenStreaming="방송 시 자동으로 녹화"
 Basic.Settings.General.KeepRecordingWhenStreamStops="방송을 중단하더라도 녹화는 유지"
-Basic.Settings.General.SysTrayEnabled="시스템 트레이 아이콘 활성화"
+Basic.Settings.General.ReplayBufferWhileStreaming="방송 시 리플레이 버퍼를 자동으로 시작"
+Basic.Settings.General.KeepReplayBufferStreamStops="방송 중단에도 리플레이 버퍼를 계속 활성화"
+Basic.Settings.General.SysTray="시스템 트레이"
 Basic.Settings.General.SysTrayWhenStarted="시작할 때 시스템 트레이로 최소화"
+Basic.Settings.General.SystemTrayHideMinimize="작업 표시줄 대신 시스템 트레이에 항상 최소화"
+Basic.Settings.General.SaveProjectors="종료 시 프로젝터 저장"
 
 Basic.Settings.Stream="방송"
 Basic.Settings.Stream.StreamType="방송 형식"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="출력 모드"
 Basic.Settings.Output.Mode.Simple="단순"
 Basic.Settings.Output.Mode.Adv="고급"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg 출력"
+Basic.Settings.Output.UseReplayBuffer="리플레이 버퍼 활성화"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="최대 리플레이 시간 (초 단위)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="최대 메모리 (메가바이트 단위)"
+Basic.Settings.Output.ReplayBuffer.Estimate="예상되는 메모리 사용량: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="메모리 사용량을 계산할 수 없습니다. 최대 메모리 사용량을 설정하세요."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(참고: 단축키 설정에서 리플레이 버퍼의 단축키를 꼭 지정하세요)"
+Basic.Settings.Output.ReplayBuffer.Prefix="리플레이 버퍼 파일이름 접두사"
+Basic.Settings.Output.ReplayBuffer.Suffix="접미사"
 Basic.Settings.Output.Simple.SavePath="녹화 경로"
 Basic.Settings.Output.Simple.RecordingQuality="녹화 품질"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="방송 품질과 동일하게"
@@ -369,6 +430,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="무손실 품질 설정 경고
 Basic.Settings.Output.Simple.Warn.MultipleQSV="경고: 방송과 녹화를 동시에 하고 있을 때 여러 개의 독립된 QSV 인코더를 사용할 수 없습니다. 두 작업을 동시에 하려면 녹화 혹은 방송 인코더 둘 중 하나를 바꿔야 합니다."
 Basic.Settings.Output.Simple.Encoder.Software="소프트웨어 (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="하드웨어 (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="하드웨어 (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="하드웨어 (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="소프트웨어 (x264 CPU 부담이 적지만 파일 크기가 증가)"
 Basic.Settings.Output.VideoBitrate="비디오 비트레이트"
@@ -390,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="트랙 1"
 Basic.Settings.Output.Adv.Audio.Track2="트랙 2"
 Basic.Settings.Output.Adv.Audio.Track3="트랙 3"
 Basic.Settings.Output.Adv.Audio.Track4="트랙 4"
+Basic.Settings.Output.Adv.Audio.Track5="트랙 5"
+Basic.Settings.Output.Adv.Audio.Track6="트랙 6"
 
 Basic.Settings.Output.Adv.Recording="녹화"
 Basic.Settings.Output.Adv.Recording.Type="형식"
@@ -417,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="비디오 인코더 설정 (
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="오디오 인코더"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="오디오 인코더 설정 (지원되는 경우)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="다중화 설정 (제공되는 경우)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="키프레임 간격 (프레임 단위)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="모든 코덱을 표시 (호환이 안되는 것도 포함)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -470,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV 색 공간"
 Basic.Settings.Advanced.Video.ColorRange="YUV 색상 범위"
 Basic.Settings.Advanced.Video.ColorRange.Partial="부분"
 Basic.Settings.Advanced.Video.ColorRange.Full="ì „ì²´"
+Basic.Settings.Advanced.Audio.MonitoringDevice="오디오 모니터링 장치"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="기본값"
 Basic.Settings.Advanced.StreamDelay="방송 지연"
 Basic.Settings.Advanced.StreamDelay.Duration="기간 (초)"
 Basic.Settings.Advanced.StreamDelay.Preserve="재접속 시 잘려나간 지점 보관 (지연시간 증가)"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="예상되는 메모리 사용량: %1 MB"
 Basic.Settings.Advanced.Network="네트워크"
 Basic.Settings.Advanced.Network.BindToIP="IP에 고정"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="새로운 네트워크 코드 활성화"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="짧은 지연시간 모드"
 
 Basic.AdvAudio="오디오 고급 설정"
 Basic.AdvAudio.Name="이름"
@@ -483,15 +553,15 @@ Basic.AdvAudio.Volume="볼륨 (%)"
 Basic.AdvAudio.Mono="모노로 강제 송출"
 Basic.AdvAudio.Panning="패닝"
 Basic.AdvAudio.SyncOffset="싱크 오프셋 (ms)"
+Basic.AdvAudio.Monitoring="오디오 모니터링"
+Basic.AdvAudio.Monitoring.None="모니터링 끔"
+Basic.AdvAudio.Monitoring.MonitorOnly="모니터링만 (출력은 제거)"
+Basic.AdvAudio.Monitoring.Both="모니터링과 출력"
 Basic.AdvAudio.AudioTracks="트랙"
 
 Basic.Settings.Hotkeys="단축키"
 Basic.Settings.Hotkeys.Pair="'%1'과 공유하는 키 조합을 토글 형식으로 설정"
 
-Basic.Hotkeys.StartStreaming="방송 시작"
-Basic.Hotkeys.StopStreaming="방송 중단"
-Basic.Hotkeys.StartRecording="녹화 시작"
-Basic.Hotkeys.StopRecording="녹화 중단"
 Basic.Hotkeys.SelectScene="장면 전환"
 
 Basic.SystemTray.Show="보이기"
@@ -545,4 +615,5 @@ SceneItemHide="'%1' 숨기기"
 
 OutputWarnings.NoTracksSelected="최소 하나의 트랙을 선택해야 합니다"
 OutputWarnings.MultiTrackRecording="경고: 일부 형식(예를 들어 FLV)은 녹화 하나에 여러 개의 트랙을 지원하지 않습니다"
+OutputWarnings.MP4Recording="경고: MP4로 녹화를 하면 파일이 마무리가 되지 않았을 때 (예를 들어 컴퓨터가 급작스럽게 꺼지거나 블루 스크린 오류가 일어나는 경우) 복구할 수 없습니다. 여러 개의 오디오 트랙을 녹음하고 싶다면 MKV 확장자로 녹화 한 뒤 재다중화 작업을 통해 mp4로 전환하십시오. (파일->재다중화 녹화)"
 
diff --git a/UI/data/locale/lt-LT.ini b/UI/data/locale/lt-LT.ini
index d3f837b..ad0fa96 100644
--- a/UI/data/locale/lt-LT.ini
+++ b/UI/data/locale/lt-LT.ini
@@ -49,6 +49,7 @@ Right="Iš dešinės"
 Top="Iš viršaus"
 Bottom="Iš apačios"
 
+
 QuickTransitions.SwapScenes="Sukeisti Peržiūros/Išvesties scenas po Perėjimo"
 QuickTransitions.SwapScenesTT="Sukeičia peržiūros ir išvesties scenas po perėjimo įvykdymo (jei originali išvesties scena vis dar egzistuoja).\nTai neatšauks jokių pakeitimų kurie galima buvo atlikti originalioje išvesties scenoje."
 QuickTransitions.DuplicateScene="Dubliuoti ScenÄ…"
@@ -86,6 +87,7 @@ ConfirmExit.Text="OBS metu yra aktyvus. Visos transliacijos/įrašymai bus išju
 ConfirmRemove.Title="Pašalinimo patvirtinimas"
 ConfirmRemove.Text="Ar tikrai norite pašalinti '$1'?"
 
+
 Output.ConnectFail.Title="Nepavyko prisijungti"
 Output.ConnectFail.BadPath="Neteisingas kelias arba jungimosi URL. Prašome patikrinti nustatymus ir įsitikinti, kad jie teisingi."
 Output.ConnectFail.ConnectFailed="Nepavyko prisijungti prie serverio"
@@ -159,6 +161,7 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Piršutinis puskadris pirmas"
 Deinterlacing.BottomFieldFirst="Apatinis puskadris pirmas"
 
+
 Basic.Main.AddSceneDlg.Title="PridÄ—ti scenÄ…"
 Basic.Main.AddSceneDlg.Text="Įveskite pasirinktą scenos pavadinimą"
 
diff --git a/UI/data/locale/ms-MY.ini b/UI/data/locale/ms-MY.ini
index 3970dbb..82da14e 100644
--- a/UI/data/locale/ms-MY.ini
+++ b/UI/data/locale/ms-MY.ini
@@ -23,11 +23,11 @@ Settings="Tetapan"
 Display="Paparan"
 Name="Nama"
 Exit="Keluar"
-Mixer="Pengadun(suara)"
+Mixer="Pengadun suara"
 Browse="Cari"
 Mono="Mono"
 Stereo="Stereo"
-DroppedFrames="Gambar-gambar Terjatuh %1 (%2%)"
+DroppedFrames="%1 Gambar Hilang (%2%)"
 PreviewProjector="Paparan Projektor penuh (Pratonton)"
 SceneProjector="Paparan Projektor penuh (Adegan)"
 SourceProjector="Paparan Projektor penuh (Sumber)"
@@ -36,29 +36,34 @@ Revert="Ubah kembali"
 Show="Tunjuk"
 Hide="Sembunyi"
 Untitled="Tiada tajuk"
-New="Baru"
-Duplicate="Salin"
+New="Baharu"
+Duplicate="Salin semula"
 Enable="Benarkan"
-DisableOSXVSync="Nyahaktifkan OSX V-Sync"
-ResetOSXVSyncOnExit="Tetapkan semula OSX V-Sync apabila keluar"
-HighResourceUsage="Pengekodan terbeban! Cuba turunkan tetapan video ataupun gunakan pratetapan pengekodan yang lebih cepat."
+DisableOSXVSync="Nyahaktifkan V-Sync OSX"
+ResetOSXVSyncOnExit="Set semula OSX V-Sync apabila keluar"
+HighResourceUsage="Pengekodan terbeban! Cuba turunkan tetapan video ataupun gunakan pratetap pengekodan yang lebih laju."
 Transition="Peralihan"
 QuickTransitions="Peralihan Pantas"
 Left="Kiri"
 Right="Kanan"
 Top="Atas"
 Bottom="Bawah"
+Reset="Set semula"
+Hours="Jam"
+Minutes="Minit"
+Seconds="Saat"
 
-QuickTransitions.SwapScenes="Tukar Pratonton/Output Adegan-adegan Selepas Peralihan"
-QuickTransitions.SwapScenesTT="Menukarkan pratonton dan output adegan-adegan sleeps peralihan(jika output adegan mash wujud).\nIni tidak akan mengundurkan semarang perubahan yang mungkin telah dibuat pada output adegan yang asal."
+
+QuickTransitions.SwapScenes="Tukar Pratonton/Pengeluaran Adegan Selepas Peralihan"
+QuickTransitions.SwapScenesTT="Menukarkan pratonton dan pengeluaran adegan-adegan selepas peralihan(jika pengeluaran adegan mash wujud).\nIni tidak akan mengundurkan sebarang perubahan yang mungkin telah dilakukan pada pengeluaran adegan yang asal."
 QuickTransitions.DuplicateScene="Klonkan Adegan"
-QuickTransitions.DuplicateSceneTT="Apabila menyunting adegan yang sama, ini membolehkan penyuntingan perubahan/keterlihatan tanpa mengubah output..\nUntuk edit sifat-sifat adegan-adegan tanpa mengubah suai output, aktifkan 'Klonkan Adegan'.\nPengubahan nilai ini akan menetapkan semula output adegan (jika adegan masih wujud)."
+QuickTransitions.DuplicateSceneTT="Apabila menyunting adegan yang sama, ini membolehkan penyuntingan perubahan/keterlihatan tanpa mengubah pengeluaran.\nUntuk edit sifat-sifat adegan tanpa mengubah suai pengeluaran, aktifkan 'Klonkan Adegan'.\nPengubahan nilai ini akan menetapkan semula pengeluaran adegan (jika adegan masih wujud)."
 QuickTransitions.EditProperties="Klonkan Sumber"
-QuickTransitions.EditPropertiesTT="Apabila menyunting adegan yang sama, ini membolehkan penyuntingan sumber-sumber tanpa mengubah output.\nIni hanya boleh dilakukan jika 'Klonkan Adegan' diaktifkan.\nSebahagian sumber (seperti sumber-sumber tangkapan atau media) tidak menyokong tetapan ini dan tidak boleh disunting secara berasingan.\nPenukaran nilai ini akan menetapkan semula output adegan yang sedang digunakan (jika adegan masih wujud).\n\nAmaran: Kerana sumber-sumber akan diklonkan, ini mungkin memerlukan penambahan sumber-sumber sistem/video."
+QuickTransitions.EditPropertiesTT="Apabila menyunting adegan yang sama, ini membolehkan penyuntingan sumber-sumber tanpa mengubah pengeluaran.\nIni hanya boleh dilakukan jika 'Klonkan Adegan' diaktifkan.\nSebahagian sumber (seperti sumber-sumber penangkapan atau media) tidak menyokong tetapan ini dan tidak boleh disunting secara berasingan.\nPenukaran nilai ini akan menetapkan semula pengeluaran adegan yang sedang digunakan (jika adegan masih wujud).\n\nAmaran: Pilihan ini mungkin memerlukan sumber-sumber sistem/audio tambahan kerana sumber-sumber akan diklonkan."
 QuickTransitions.HotkeyName="Peralihan Pantas: %1"
 
-Basic.AddTransition="Tambah Peralihan Yang Boleh Diubahsuai"
-Basic.RemoveTransition="Buang Peralihan Yang Boleh Diubahsuai"
+Basic.AddTransition="Tambah Peralihan yang Boleh Diubahsuai"
+Basic.RemoveTransition="Buang Peralihan yang Boleh Diubahsuai"
 Basic.TransitionProperties="Sifat-sifat Peralihan"
 Basic.SceneTransitions="Peralihan-peralihan Adegan"
 Basic.TransitionDuration="Tempoh"
@@ -87,24 +92,27 @@ ConfirmExit.Text="OBS kini sedang aktif. Semua 'stream'/rakaman akan ditutup. Ad
 
 ConfirmRemove.Title="Pengesahan untuk Buang"
 ConfirmRemove.Text="Adakah anda pasti untuk buang '$1'?"
+ConfirmRemove.TextMultiple="Adakah anda yakin untuk buang %1 barang?"
+
 
 Output.ConnectFail.Title="Penyambungan gagal"
 Output.ConnectFail.BadPath="Sambungan URL atau Laluan yang tidak sah. Sila semak semula tetapan anda to mengesahkan bahawa semuanya sah."
 Output.ConnectFail.ConnectFailed="Penyambungan ke pelayan gagal"
+Output.ConnectFail.InvalidStream="Tidak dapat mencapai saluran yang ditetapkan/kata kunci 'stream', sila semak semula kata kunci 'stream'. Jika ia betul, kemungkinan ada masalah menyambung kepada pelayan."
 Output.ConnectFail.Error="Ralat tidak dijangka berlaku sewaktu percubaan menyambung ke pelayan. Maklumat lanjut di dalam fail log."
 Output.ConnectFail.Disconnected="Terputus daripada pelayan."
 
 Output.RecordFail.Title="Gagal memulakan rakaman"
-Output.RecordFail.Unsupported="Output format adalah tidak disokong atau tidak membenarkan lebih daripada satu 'audio track'. Sila semak tetapan anda dan cuba lagi."
+Output.RecordFail.Unsupported="Format pengeluaran tidak disokong atau tidak membenarkan lebih daripada satu trek audio. Sila semak tetapan anda dan cuba lagi."
 Output.RecordNoSpace.Title="Ruang simpanan tidak cukup"
 Output.RecordNoSpace.Msg="Tiada ruang simpanan yang cukup untuk meneruskan rakaman."
 Output.RecordError.Title="Ralat rakaman"
 Output.RecordError.Msg="Ralat yang tidak ditetapkan berlaku semasa rakaman."
 
 Output.BadPath.Title="Laluan Fail Rosak"
-Output.BadPath.Text="Laluan output fail yang dikonfigurasikan tidak sah.Sila semak semula tetapan anda untuk mengesahkan laluan fail yang sah telah ditetapkan."
+Output.BadPath.Text="Laluan pengeluaran fail yang dikonfigurasikan tidak sah. Sila semak semula tetapan anda untuk mengesahkan laluan fail yang sah telah ditetapkan."
 
-LogReturnDialog="Memuat naik Log Berjaya"
+LogReturnDialog="Muat naik Log Berjaya"
 LogReturnDialog.CopyURL="Salin URL"
 LogReturnDialog.ErrorUploadingLog="Ralat memuat naikkan fail log"
 
@@ -115,30 +123,52 @@ LicenseAgreement.IAgree="Saya Setuju"
 LicenseAgreement.Exit="Keluar"
 
 Remux.SourceFile="Rakaman OBS"
-Remux.TargetFile="Fail sasaran"
+Remux.TargetFile="Fail Sasaran"
+Remux.Remux="Tukar format"
 Remux.OBSRecording="Rakaman OBS"
+Remux.FinishedTitle="Penukaran format selesai"
+Remux.Finished="Format rakaman ditukar"
+Remux.FinishedError="Format rakaman ditukar, tetapi fail itu mungkin tidak lengkap"
 Remux.SelectRecording="Pilih Rakaman OBS …"
 Remux.SelectTarget="Pilih fail sasaran …"
 Remux.FileExistsTitle="Fail sasaran wujud"
 Remux.FileExists="Fail sasaran wujud, adakah anda mahu gantikannya?"
+Remux.ExitUnfinishedTitle="Penukaran format sedang dijalankan"
+Remux.ExitUnfinished="Penukaran format masih belum selesai, menghentikannya sekarang boleh menyebabkan fail sasaran tidak boleh digunakan.\nAdakah anda pasti untuk memberhentikan proses ini?"
 
 UpdateAvailable="Ada Versi Baru"
 UpdateAvailable.Text="Versi %1.%2.%3 kini ada. <a href='%4'>Klik sini untuk memuat turun</a>"
 
 Basic.DesktopDevice1="Audio Desktop"
-Basic.DesktopDevice2="Audio Desktop"
+Basic.DesktopDevice2="Audio Desktop 2"
 Basic.AuxDevice1="Mic/Aux"
 Basic.AuxDevice2="Mic/Aux 2"
 Basic.AuxDevice3="Mic/Aux 3"
 Basic.AuxDevice4="Mic/Aux 4"
 
 Basic.Scene="Adegan"
+Basic.DisplayCapture="Paparan Penuh"
 
 Basic.Main.PreviewConextMenu.Enable="Benarkan Pratonton"
 
+ScaleFiltering="Skala Tapisan"
+ScaleFiltering.Point="Point"
+ScaleFiltering.Bilinear="Bilinear"
+ScaleFiltering.Bicubic="Bicubic"
+ScaleFiltering.Lanczos="Lanczos"
 
+Deinterlacing="Deinterlacing"
+Deinterlacing.Discard="Discard"
 Deinterlacing.Retro="Retro"
+Deinterlacing.Blend="Blend"
+Deinterlacing.Blend2x="Blend 2x"
 Deinterlacing.Linear="Linear"
+Deinterlacing.Linear2x="Linear 2x"
+Deinterlacing.Yadif="Yadif"
+Deinterlacing.Yadif2x="Yadif 2x"
+Deinterlacing.TopFieldFirst="Bahagian Atas Dahulu"
+Deinterlacing.BottomFieldFirst="Bahagian Bawah Dahulu"
+
 
 Basic.Main.AddSceneDlg.Title="Tambah Adegan"
 Basic.Main.AddSceneDlg.Text="Sila taip nama adegan"
@@ -170,14 +200,16 @@ Basic.PropertiesWindow.ConfirmTitle="Perubahan Tetapan"
 Basic.PropertiesWindow.Confirm="Ada perubahan yang belum disimpan. Adakah anda mahu menyimpannya?"
 Basic.PropertiesWindow.NoProperties="Tiada sifat-sifat disediakan"
 Basic.PropertiesWindow.AddFiles="Tambah Fail-Fail"
+Basic.PropertiesWindow.AddDir="Tambah Direktori"
 Basic.PropertiesWindow.AddURL="Tambah laluan/URL"
+Basic.PropertiesWindow.AddEditableListDir="Tambah direktori ke '%1'"
 Basic.PropertiesWindow.AddEditableListFiles="Tambah fail ke '%1'"
 Basic.PropertiesWindow.AddEditableListEntry="Tambah entri ke '%1'"
 Basic.PropertiesWindow.EditEditableListEntry="Sunting entri daripada '%1'"
 
-Basic.PropertiesView.FPS.Simple="Nilai-nilai mudah FPS"
-Basic.PropertiesView.FPS.Rational="Nilai-nilai pecahan FPS"
-Basic.PropertiesView.FPS.ValidFPSRanges="Julat sah FPS:"
+Basic.PropertiesView.FPS.Simple="Nilai-nilai FPS mudah"
+Basic.PropertiesView.FPS.Rational="Nilai-nilai FPS pecahan"
+Basic.PropertiesView.FPS.ValidFPSRanges="Julat FPS sah:"
 
 Basic.InteractionWindow="Berinteraksi dengan '%1'"
 
@@ -201,6 +233,8 @@ Basic.TransformWindow="Pengubahan Item Adegan"
 Basic.TransformWindow.Position="Kedudukan"
 Basic.TransformWindow.Rotation="Pusingan"
 Basic.TransformWindow.Size="Saiz"
+Basic.TransformWindow.Alignment="Kedudukan Penjajaran"
+Basic.TransformWindow.Crop="Potong"
 
 Basic.TransformWindow.Alignment.TopLeft="Kiri Atas"
 Basic.TransformWindow.Alignment.TopCenter="Tengah Atas"
@@ -224,13 +258,16 @@ Basic.Main.Connecting="Menyambung..."
 Basic.Main.StartRecording="Mula rakaman"
 Basic.Main.StartStreaming="Mula 'streaming'"
 Basic.Main.StopRecording="Hentikan rakaman"
+Basic.Main.StoppingRecording="Menghentikan rakaman..."
 Basic.Main.StopStreaming="Hentikan 'streaming'"
+Basic.Main.StoppingStreaming="Menghentikan 'streaming'..."
 Basic.Main.ForceStopStreaming="Berhenti 'streaming' (buang kelewatan)"
 
 Basic.MainMenu.File="&Fail"
 Basic.MainMenu.File.Export="&Export"
 Basic.MainMenu.File.Import="&Import"
 Basic.MainMenu.File.ShowRecordings="Papar &Rakaman"
+Basic.MainMenu.File.Remux="Format& rakaman"
 Basic.MainMenu.File.Settings="&Tetapan"
 Basic.MainMenu.File.ShowSettingsFolder="Tunjukkan Folder Tetapan"
 Basic.MainMenu.File.ShowProfileFolder="Tunjukkan Folder Profil"
@@ -242,11 +279,14 @@ Basic.MainMenu.Edit.Undo="&Ubah Balik"
 Basic.MainMenu.Edit.Redo="Buat Semula (&R)"
 Basic.MainMenu.Edit.UndoAction="&Ubah Balik $1"
 Basic.MainMenu.Edit.RedoAction="&Ubah Semula $1"
+Basic.MainMenu.Edit.LockPreview="&Kunci Pratonton"
 Basic.MainMenu.Edit.Transform="&Ubah"
 Basic.MainMenu.Edit.Transform.EditTransform="&Sunting Perubahan..."
 Basic.MainMenu.Edit.Transform.Rotate90CW="Putarkan 90 darjah mengikut arah jam"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Putarkan 90 darjah melawan arah jam"
 Basic.MainMenu.Edit.Transform.Rotate180="Putarkan 180 darjah"
+Basic.MainMenu.Edit.Transform.FlipHorizontal="Flip secara &Mendatar"
+Basic.MainMenu.Edit.Transform.FlipVertical="Flip secara &Menegak"
 Basic.MainMenu.Edit.Transform.FitToScreen="&Muat di skrin"
 Basic.MainMenu.Edit.Transform.StretchToScreen="&Regangkan ke skrin"
 Basic.MainMenu.Edit.Order.MoveUp="Gerakkan ke &atas"
@@ -260,8 +300,11 @@ Basic.MainMenu.Help.Website="Lawat laman &Web"
 Basic.MainMenu.Help.Logs="Fail &Log"
 Basic.MainMenu.Help.Logs.ShowLogs="&Tunjukkan Fail-Fail Log"
 Basic.MainMenu.Help.Logs.UploadCurrentLog="Muat naik Fail Log &Kini"
+Basic.MainMenu.Help.Logs.UploadLastLog="Muat naik &Fail Log Terakhir"
+Basic.MainMenu.Help.Logs.ViewCurrentLog="&Paparkan Log Semasa"
 Basic.MainMenu.Help.CheckForUpdates="Semak Versi Baharu"
 
+Basic.Settings.ProgramRestart="Program ini mesti dimulakan semula untuk tetapan-tetapan ini berkesan."
 Basic.Settings.ConfirmTitle="Sahkan Perubahan"
 Basic.Settings.Confirm="Anda mempunyai perubahan yang tidak disimpan. Simpan perubahan?"
 
@@ -270,38 +313,109 @@ Basic.Settings.General.Theme="Tema"
 Basic.Settings.General.Language="Bahasa"
 Basic.Settings.General.WarnBeforeStartingStream="Tunjukkan dialog pengesahan ketika memulakan 'stream'"
 Basic.Settings.General.WarnBeforeStoppingStream="Tunjukkan dialog pengesahan ketika menghentikan 'stream'"
+Basic.Settings.General.HideProjectorCursor="Sembunyikan tetikus atas projektor"
+Basic.Settings.General.ProjectorAlwaysOnTop="Jadikan projektor sentiasa di atas"
+Basic.Settings.General.SnapDistance="Kepekaan 'snap'"
+Basic.Settings.General.RecordWhenStreaming="Rakam apabila 'streaming' secara automatik"
+Basic.Settings.General.KeepRecordingWhenStreamStops="Tetap rakam selepas 'stream' berhenti"
 
 Basic.Settings.Stream="'Stream'"
 Basic.Settings.Stream.StreamType="Jenis 'Stream'"
 
+Basic.Settings.Output="Hasil"
 Basic.Settings.Output.Format="Format Rakaman"
 Basic.Settings.Output.SelectFile="Pilih Fail Rakaman"
+Basic.Settings.Output.EnforceBitrate="Kuatkuasakan had nilai bit perkhidmatan 'streaming'"
+Basic.Settings.Output.Mode.Simple="Mudah"
+Basic.Settings.Output.Mode.Adv="Lanjutan"
 Basic.Settings.Output.Simple.RecordingQuality="Kualiti Rakaman"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Sama seperti 'stream'"
 Basic.Settings.Output.Simple.Encoder.Software="Perisian (x264)"
+Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)"
+Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)"
+Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (Preset x264: pengunaan CPU rendah, menaikkan saiz fail)"
+Basic.Settings.Output.VideoBitrate="Nilai Bit Video"
+Basic.Settings.Output.AudioBitrate="Nilai Bit Audio"
 Basic.Settings.Output.Reconnect="Sambung semula secara automatik"
 Basic.Settings.Output.RetryDelay="Kelewatan Percubaan (saat)"
 Basic.Settings.Output.MaxRetries="Cubaan Maksimum"
 
+Basic.Settings.Output.Adv.AudioTrack="Trek Audio"
+Basic.Settings.Output.Adv.Streaming="'Streaming'"
+Basic.Settings.Output.Adv.Audio.Track1="Trek 1"
+Basic.Settings.Output.Adv.Audio.Track2="Trek 2"
+Basic.Settings.Output.Adv.Audio.Track3="Trek 3"
+Basic.Settings.Output.Adv.Audio.Track4="Trek 4"
 
 Basic.Settings.Output.Adv.Recording="Rakaman"
 Basic.Settings.Output.Adv.Recording.Type="Jenis"
+Basic.Settings.Output.Adv.Recording.Type.Standard="Bias"
+Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Gantikan jika fail wujud"
 Basic.Settings.Output.Adv.FFmpeg.Type="Jenis Output FFmpeg"
+Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Semua Fail"
+Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Laluan fail atau URL"
+Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Audio"
+Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Video"
+Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Format Asal"
 
 
 
 
 
+Basic.Settings.Audio.EnablePushToMute="Benarkan Tekan-untuk-senyap"
+Basic.Settings.Audio.PushToMuteDelay="Kelewatan Tekan-untuk-senyap"
+Basic.Settings.Audio.EnablePushToTalk="Benarkan Tekan-untuk-cakap"
+Basic.Settings.Audio.PushToTalkDelay="Kelewatan Tekan-untuk-cakap"
+Basic.Settings.Audio.UnknownAudioDevice="[Peranti tidak disambung atau tiada]"
 
+Basic.Settings.Advanced="Lanjutan"
+Basic.Settings.Advanced.General.ProcessPriority="Keutamaan Proses"
+Basic.Settings.Advanced.General.ProcessPriority.High="Tinggi"
+Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Atas Normal"
+Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal"
 Basic.Settings.Advanced.FormatWarning="Amaran:Format warna selain daripada 'NV12' lebih digunakan untuk rakaman,dan tidak disyorkan apabila 'streaming'.'Streaming' mungkin menyebabkan peningkatan penggunaan CPU disebabkan oleh penukaran format warna."
-
-
-
-
-
-
+Basic.Settings.Advanced.Video.ColorFormat="Format Warna"
+Basic.Settings.Advanced.Video.ColorRange.Partial="Sebahagian"
+Basic.Settings.Advanced.Video.ColorRange.Full="Penuh"
+Basic.Settings.Advanced.StreamDelay="Kelewatan 'Stream'"
+Basic.Settings.Advanced.StreamDelay.MemoryUsage="Anggaran Penggunaan Memori: %1 MB"
+Basic.Settings.Advanced.Network="Rangkaian"
+
+Basic.AdvAudio.Name="Nama"
+Basic.AdvAudio.AudioTracks="Trek-trek"
+
+Basic.Settings.Hotkeys="Kekunci Pantas"
+
+
+Basic.SystemTray.Show="Papar"
+Basic.SystemTray.Hide="Sembunyi"
+
+Basic.SystemTray.Message.Reconnecting="Terputus. Menyambung semula..."
+
+Hotkeys.Insert="Insert"
+Hotkeys.Delete="Delete"
+Hotkeys.Home="Home"
+Hotkeys.End="End"
+Hotkeys.PageUp="Page Up"
+Hotkeys.PageDown="Page Down"
+Hotkeys.NumLock="Num Lock"
+Hotkeys.ScrollLock="Scroll Lock"
+Hotkeys.CapsLock="Caps Lock"
+Hotkeys.Backspace="Backspace"
+Hotkeys.Tab="Tab"
+Hotkeys.Print="Print"
+Hotkeys.Pause="Pause"
+Hotkeys.Left="Left"
+Hotkeys.Right="Right"
+Hotkeys.Up="Up"
+Hotkeys.Down="Down"
+Hotkeys.Windows="Windows"
 Hotkeys.NumpadDecimal="Perpuluhan Numpad"
 
+Mute="Senyap"
+Push-to-mute="Tekan-untuk-senyap"
+Push-to-talk="Tekan-untuk-cakap"
 
 
 
diff --git a/UI/data/locale/nb-NO.ini b/UI/data/locale/nb-NO.ini
index 1fafc39..c60250b 100644
--- a/UI/data/locale/nb-NO.ini
+++ b/UI/data/locale/nb-NO.ini
@@ -48,6 +48,23 @@ Left="Venstre"
 Right="Høyre"
 Top="Topp"
 Bottom="Bunn"
+Reset="Tilbakestill"
+Hours="Timer"
+Minutes="Minutter"
+Seconds="Sekunder"
+Deprecated="Foreldet"
+ReplayBuffer="Omspill Buffer"
+Import="Importer"
+Export="Eksporter"
+
+Updater.Title="Ny oppdatering tilgjengelig"
+Updater.Text="Det finnes en ny oppdatering:"
+Updater.UpdateNow="Oppdater nå"
+Updater.RemindMeLater="PÃ¥minn meg senere"
+Updater.Skip="Hopp over versjon"
+Updater.Running.Title="Programmet er aktiv"
+Updater.NoUpdatesAvailable.Title="Ingen oppdateringer er tilgjengelig"
+Updater.NoUpdatesAvailable.Text="Ingen oppdateringer er tilgjengelig"
 
 QuickTransitions.SwapScenes="Bytt forhåndsvisnings-/utgangsscener etter overgang"
 QuickTransitions.SwapScenesTT="Bytter forhåndsvisnings- og utgangsscenen etter overgang, hvis den originale utgangsscenen fortsatt eksisterer.\nDette vil ikke tilbakestille endringer på den originale utgangsscenen."
@@ -87,6 +104,10 @@ ConfirmExit.Text="OBS er aktiv. Alle strømmer og opptak vil bli stoppet. Er du
 
 ConfirmRemove.Title="Bekreft Fjerning"
 ConfirmRemove.Text="Er du sikker på at du vil fjerne '$1'?"
+ConfirmRemove.TextMultiple="Er du sikker du ønsker å fjerne %1 filer?"
+
+Output.StartStreamFailed="Kan ikke starte streaming"
+Output.StartRecordingFailed="Kan ikke starte innspillingen"
 
 Output.ConnectFail.Title="Tilkobling misklytes"
 Output.ConnectFail.BadPath="Ugyldig filbane eller tilkoblings-URL. Vennligst bekreft at instillingene dine er riktige."
@@ -101,6 +122,8 @@ Output.RecordNoSpace.Title="Ikke nok diskplass"
 Output.RecordNoSpace.Msg="Det er ikke nok diskplass til å fortsette opptaket."
 Output.RecordError.Title="Innspillingsfeil"
 Output.RecordError.Msg="Det oppstod en uspesifisert feil under opptaket."
+Output.ReplayBuffer.NoHotkey.Title="Ingen hurtigtast satt!"
+Output.ReplayBuffer.NoHotkey.Msg="Ingen lagrings hurtigtast satt for omspillings buffer. Venligst sett \"Lagre\" hurtigtasten i bruk for å lagre opptak."
 
 Output.BadPath.Title="Ugyldig Filbane"
 Output.BadPath.Text="Den oppgitte fillagringsbanen er ugyldig. Vennligst kontrollér instillingene dine og bekreft at filbanen er gyldig."
@@ -144,6 +167,11 @@ Basic.DisplayCapture="Skjermopptak"
 
 Basic.Main.PreviewConextMenu.Enable="Aktiver forhåndsvisning"
 
+ScaleFiltering="Skala Filtrering"
+ScaleFiltering.Point="Punkt"
+ScaleFiltering.Bilinear="Bilineær"
+ScaleFiltering.Bicubic="Bikubisk"
+ScaleFiltering.Lanczos="Lanczos"
 
 Deinterlacing="Avsammenfletting"
 Deinterlacing.Discard="Forkast"
@@ -157,6 +185,7 @@ Deinterlacing.Yadif2x="Dobbelyadif"
 Deinterlacing.TopFieldFirst="Øverste felt først"
 Deinterlacing.BottomFieldFirst="Nederste felt først"
 
+
 Basic.Main.AddSceneDlg.Title="Ny Scene"
 Basic.Main.AddSceneDlg.Text="Vennligst gi et navn til scenen."
 
@@ -251,9 +280,12 @@ Basic.Main.Scenes="Scener"
 Basic.Main.Sources="Kilder"
 Basic.Main.Connecting="Kobler til…"
 Basic.Main.StartRecording="Start Opptak"
+Basic.Main.StartReplayBuffer="Start Omspill Buffer"
 Basic.Main.StartStreaming="Start Strømming"
 Basic.Main.StopRecording="Stopp Opptak"
 Basic.Main.StoppingRecording="Stanser innspilling…"
+Basic.Main.StopReplayBuffer="Stopp Omspill Buffer"
+Basic.Main.StoppingReplayBuffer="Stopper Omspill Bufferen..."
 Basic.Main.StopStreaming="Stopp Strømming"
 Basic.Main.StoppingStreaming="Stanser strøm…"
 Basic.Main.ForceStopStreaming="Stopp strømming (forkast forsinkelse)"
@@ -274,8 +306,12 @@ Basic.MainMenu.Edit.Undo="&Angre"
 Basic.MainMenu.Edit.Redo="&Gjør om"
 Basic.MainMenu.Edit.UndoAction="&Angre $1"
 Basic.MainMenu.Edit.RedoAction="&Gjør om $1"
+Basic.MainMenu.Edit.LockPreview="Lås Forhåndsvisning"
+Basic.MainMenu.Edit.Scale="Forhåndsvisning & Skalering"
+Basic.MainMenu.Edit.Scale.Window="Tilpass til vindu"
 Basic.MainMenu.Edit.Transform="&Transformer"
 Basic.MainMenu.Edit.Transform.EditTransform="&Redigér transformering..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Kopiere transformering"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Angre transformering"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Rotér 90 grader med klokka"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotér 90 grader mot klokka"
@@ -292,10 +328,21 @@ Basic.MainMenu.Edit.Order.MoveToTop="Legg på &toppen"
 Basic.MainMenu.Edit.Order.MoveToBottom="Legg på &bunnen"
 Basic.MainMenu.Edit.AdvAudio="&Avanserte lydinstillinger"
 
+Basic.MainMenu.View="&Vis"
+Basic.MainMenu.View.Toolbars="%Verktøylinje"
+Basic.MainMenu.View.SceneTransitions="Sceneoverganger"
+Basic.MainMenu.View.StatusBar="Statuslinje"
 
 Basic.MainMenu.SceneCollection="&Scenesamling"
 Basic.MainMenu.Profile="&Profil"
+Basic.MainMenu.Profile.Import="Importer Profil"
+Basic.MainMenu.Profile.Export="Eksporter Profil"
+Basic.MainMenu.SceneCollection.Import="Importer Scenesamling"
+Basic.MainMenu.SceneCollection.Export="Eskporter Scenesamling"
+Basic.MainMenu.Profile.Exists="Profilen eksisterer allerede"
+Basic.MainMenu.SceneCollection.Exists="Scenesamlingen eksisterer allerede"
 
+Basic.MainMenu.Tools="&Verktøy"
 
 Basic.MainMenu.Help="&Hjelp"
 Basic.MainMenu.Help.Website="Besøk &nettsted"
@@ -315,6 +362,7 @@ Basic.Settings.General.Theme="Tema"
 Basic.Settings.General.Language="Språk"
 Basic.Settings.General.WarnBeforeStartingStream="Vis bekreftelsesdialogboks når du starter strømming"
 Basic.Settings.General.WarnBeforeStoppingStream="Vis bekreftelsesdialogboks når stanser strømming"
+Basic.Settings.General.Projectors="Projektorer"
 Basic.Settings.General.HideProjectorCursor="Skjul musepekeren over projektorer"
 Basic.Settings.General.Snapping="Festing ved kildejustering"
 Basic.Settings.General.ScreenSnapping="Fest kilder til kanten av skjermen"
@@ -323,6 +371,7 @@ Basic.Settings.General.SourceSnapping="Fest kilder til andre kilder"
 Basic.Settings.General.SnapDistance="Festingfølsomhet"
 Basic.Settings.General.RecordWhenStreaming="Spill inn automatisk ved strømming"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Fortsett innspilling etter strømming"
+Basic.Settings.General.SysTrayWhenStarted="Minimer til systemstatusfelt ved oppstart"
 
 Basic.Settings.Stream="Strøm"
 Basic.Settings.Stream.StreamType="Strømmetype"
@@ -337,6 +386,13 @@ Basic.Settings.Output.Mode="Utgangsmodus"
 Basic.Settings.Output.Mode.Simple="Enkel"
 Basic.Settings.Output.Mode.Adv="Avansert"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg-utgang"
+Basic.Settings.Output.UseReplayBuffer="Aktiver Omspill Buffer"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksimal Omspill Tid (sekunder)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimalt Minne (Megabytes)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Anslått minne bruk. %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Kan ikke beregne minnebruk. Vennligst sett maksimalt minnebrukgrense."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Merk: Sørg for å angi en hurtigtast for omspill bufferen i hurtigtast innstillingen)"
+Basic.Settings.Output.ReplayBuffer.Suffix="Suffiks"
 Basic.Settings.Output.Simple.SavePath="Opptaksbane"
 Basic.Settings.Output.Simple.RecordingQuality="Opptakskvalitet"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Samme som strøm"
@@ -352,6 +408,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Tapsfri kvalitet advarsel!"
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Advarsel: du kan ikke bruke flere separate QSV-kodere når du strømmer og tar opp samtidig. Hvis du ønsker gjøre begge på samme tid må du endre strømme- eller opptakskoderen."
 Basic.Settings.Output.Simple.Encoder.Software="Programvare (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Maskinvare (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Maskinvare (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Maskinvare (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Programvare (x264 forhåndsinstilling for liten prosessorbruk, øker filstørrelsen)"
 Basic.Settings.Output.VideoBitrate="Bildeoverføringshastighet"
@@ -373,6 +430,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Spor 1"
 Basic.Settings.Output.Adv.Audio.Track2="Spor 2"
 Basic.Settings.Output.Adv.Audio.Track3="Spor 3"
 Basic.Settings.Output.Adv.Audio.Track4="Spor 4"
+Basic.Settings.Output.Adv.Audio.Track5="Spor 5"
+Basic.Settings.Output.Adv.Audio.Track6="Spor 6"
 
 Basic.Settings.Output.Adv.Recording="Opptak"
 Basic.Settings.Output.Adv.Recording.Type="Type"
@@ -441,6 +500,11 @@ Basic.Settings.Audio.PushToTalkDelay="Snakk-ved-trykk forsinkelse"
 Basic.Settings.Audio.UnknownAudioDevice="[Enhet ikke tilkoblet eller ikke tilgjengelig]"
 
 Basic.Settings.Advanced="Avansert"
+Basic.Settings.Advanced.General.ProcessPriority="Prosessprioritet"
+Basic.Settings.Advanced.General.ProcessPriority.High="Høy"
+Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Over Normal"
+Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal"
+Basic.Settings.Advanced.General.ProcessPriority.Idle="Inaktiv"
 Basic.Settings.Advanced.FormatWarning="Advarsel: Fargeformater andre enn NV12 er ment for opptak. Disse formatene anbefales ikke ved strømming, da det fører til økt prosessorbruk som følge av fargeformatkonvertering."
 Basic.Settings.Advanced.Audio.BufferingTime="Lydbuffertid"
 Basic.Settings.Advanced.Video.ColorFormat="Fargeformat"
@@ -452,6 +516,8 @@ Basic.Settings.Advanced.StreamDelay="Strømforsinkelse"
 Basic.Settings.Advanced.StreamDelay.Duration="Varighet (sekunder)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Bevar avkuttingspunktet (øk forsinkelse) ved tilbakekobling"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Anslått minnebruk: %1 MB"
+Basic.Settings.Advanced.Network="Nettverk"
+Basic.Settings.Advanced.Network.BindToIP="Bind til IP"
 
 Basic.AdvAudio="Avanserte lydinstillinger"
 Basic.AdvAudio.Name="Navn"
@@ -464,13 +530,12 @@ Basic.AdvAudio.AudioTracks="Spor"
 Basic.Settings.Hotkeys="Hurtigtaster"
 Basic.Settings.Hotkeys.Pair="Tastekombinasjoner delt med '%1' vil veksle"
 
-Basic.Hotkeys.StartStreaming="Start strømming"
-Basic.Hotkeys.StopStreaming="Stopp strømming"
-Basic.Hotkeys.StartRecording="Start opptak"
-Basic.Hotkeys.StopRecording="Stopp opptak"
 Basic.Hotkeys.SelectScene="Bytt til scene"
 
+Basic.SystemTray.Show="Vis"
+Basic.SystemTray.Hide="Skjul"
 
+Basic.SystemTray.Message.Reconnecting="Frakoblet. Kobler til på nytt..."
 
 Hotkeys.Insert="Insert"
 Hotkeys.Delete="Delete"
diff --git a/UI/data/locale/nl-NL.ini b/UI/data/locale/nl-NL.ini
index 93c31a0..169d48c 100644
--- a/UI/data/locale/nl-NL.ini
+++ b/UI/data/locale/nl-NL.ini
@@ -49,6 +49,26 @@ Right="Rechts"
 Top="Boven"
 Bottom="Onder"
 Reset="Herstellen"
+Hours="Uren"
+Minutes="Minuten"
+Seconds="Seconden"
+Deprecated="Verouderd"
+ReplayBuffer="Replay Buffer"
+Import="Importeer"
+Export="Exporteer"
+
+Updater.Title="Update beschikbaar"
+Updater.Text="Er is een update beschikbaar:"
+Updater.UpdateNow="Nu updaten"
+Updater.RemindMeLater="Herinner mij later"
+Updater.Skip="Sla deze versie over"
+Updater.Running.Title="Programma actief"
+Updater.Running.Text="Er is momenteel uitvoer actief, stop alle actieve uitvoer voor je probeert te updaten"
+Updater.NoUpdatesAvailable.Title="Geen updates beschikbaar"
+Updater.NoUpdatesAvailable.Text="Er zijn momenteel geen updates beschikbaar"
+Updater.FailedToLaunch="Starten van updater is mislukt"
+Updater.GameCaptureActive.Title="Game capture actief"
+Updater.GameCaptureActive.Text="Er is momenteel een game capture hook in gebruik. Sluit alle games/programma's af die opgenomen worden (of herstart Windows) en probeer het opnieuw."
 
 QuickTransitions.SwapScenes="Preview-/uitvoerscenes verwisselen na overgang"
 QuickTransitions.SwapScenesTT="Verwisselt de preview- en uitvoercenes na een overgang (als de originele uitvoerscène nog bestaat.)\nDit zal geen veranderingen ongedaan maken die mogelijk zijn gemaakt aan de originele uitvoerscène."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Bevestig het verwijderen"
 ConfirmRemove.Text="Weet je zeker dat je '$1' wil verwijderen?"
 ConfirmRemove.TextMultiple="Weet je zeker dat je %1 elementen wil verwijderen?"
 
+Output.StartStreamFailed="Het starten van de stream is mislukt"
+Output.StartRecordingFailed="Het starten van de opname is mislukt"
+Output.StartReplayFailed="Het starten van de replay buffer is mislukt"
+Output.StartFailedGeneric="Het starten van de uitvoer is mislukt. Controleer de logbestanden voor meer informatie.\n\nLet op: Als je gebruik maakt van de NVENC of AMD encoders, controleer of de drivers up to date zijn."
+
 Output.ConnectFail.Title="Kan geen verbinding maken"
 Output.ConnectFail.BadPath="Ongeldig pad of verbindings-url. Controleer a.u.b. of je instellingen geldig zijn."
 Output.ConnectFail.ConnectFailed="Kan geen verbinding maken met de server"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="Onvoldoende schijfruimte"
 Output.RecordNoSpace.Msg="Er is niet voldoende schijfruimte om door te gaan met opnemen."
 Output.RecordError.Title="Opnamefout"
 Output.RecordError.Msg="Er is een onbekende fout opgetreden tijdens het opnemen."
+Output.ReplayBuffer.NoHotkey.Title="Er is geen sneltoets ingesteld!"
+Output.ReplayBuffer.NoHotkey.Msg="Er is geen opslaan sneltoets ingesteld voor de replay buffer. Zet aub de \"Opslaan\" sneltoets voor het opslaan van replay-opnames."
 
 Output.BadPath.Title="Ongeldig Bestandspad"
 Output.BadPath.Text="Het geconfigureerde bestandsuitvoerpad is ongeldig. Controleer a.u.b. je instellingen om te bevestigen dat er een geldig bestandspad is ingesteld."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Bovenste Veld Eerst"
 Deinterlacing.BottomFieldFirst="Onderste Veld Eerst"
 
+VolControl.SliderUnmuted="Volumeregelaar voor '%1': %2"
+VolControl.SliderMuted="Volumeregelaar voor '%1': %2 (momenteel muted)"
+VolControl.Mute="Mute '%1'"
+VolControl.Properties="Eigenschappen van '%1'"
+
 Basic.Main.AddSceneDlg.Title="Scène Toevoegen"
 Basic.Main.AddSceneDlg.Text="Voer a.u.b. de naam van de scène in"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Scènes"
 Basic.Main.Sources="Bronnen"
 Basic.Main.Connecting="Verbinden..."
 Basic.Main.StartRecording="Opname Starten"
+Basic.Main.StartReplayBuffer="Start Replay Buffer"
 Basic.Main.StartStreaming="Stream Starten"
 Basic.Main.StopRecording="Opname Stoppen"
 Basic.Main.StoppingRecording="Opname Stoppen..."
+Basic.Main.StopReplayBuffer="Stop Replay Buffer"
+Basic.Main.StoppingReplayBuffer="Replay Buffer aan het stoppen..."
 Basic.Main.StopStreaming="Stream Stoppen"
 Basic.Main.StoppingStreaming="Stream Stoppen..."
 Basic.Main.ForceStopStreaming="Stop Stream (vertraging negeren)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="Opnieuw (&R)"
 Basic.MainMenu.Edit.UndoAction="$1 ongedaan maken (&U)"
 Basic.MainMenu.Edit.RedoAction="$1 opnieuw toepassen (&R)"
 Basic.MainMenu.Edit.LockPreview="Preview vergrende&len"
+Basic.MainMenu.Edit.Scale="Preview &schalen"
+Basic.MainMenu.Edit.Scale.Window="Schaal naar venster"
+Basic.MainMenu.Edit.Scale.Canvas="Canvas (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Uitvoer (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Transformeren"
 Basic.MainMenu.Edit.Transform.EditTransform="Transformatie bewerken... (&E)"
+Basic.MainMenu.Edit.Transform.CopyTransform="Kopieer transformatie"
+Basic.MainMenu.Edit.Transform.PasteTransform="Plak transformatie"
 Basic.MainMenu.Edit.Transform.ResetTransform="Transformatie herstellen (&R)"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Rechtsom kantelen"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Linksom kantelen"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="&Statusbalk"
 
 Basic.MainMenu.SceneCollection="&Scèneverzameling"
 Basic.MainMenu.Profile="&Profiel"
+Basic.MainMenu.Profile.Import="Importeer profiel"
+Basic.MainMenu.Profile.Export="Exporteer profiel"
+Basic.MainMenu.SceneCollection.Import="Importeer scèneverzameling"
+Basic.MainMenu.SceneCollection.Export="Exporteer scèneverzameling"
+Basic.MainMenu.Profile.Exists="Het profiel bestaat al"
+Basic.MainMenu.SceneCollection.Exists="De scèneverzameling bestaat al"
 
 Basic.MainMenu.Tools="&Tools"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="Je hebt onopgeslagen wijzigingen. Wijzigingen opslaan?"
 Basic.Settings.General="Algemeen"
 Basic.Settings.General.Theme="Thema"
 Basic.Settings.General.Language="Taal"
+Basic.Settings.General.EnableAutoUpdates="Automatisch controleren op updates tijdens het opstarten"
 Basic.Settings.General.WarnBeforeStartingStream="Laat bevestigingsvenster zien bij het starten van streams"
 Basic.Settings.General.WarnBeforeStoppingStream="Laat bevestiginsvenster zien bij het stoppen van streams"
+Basic.Settings.General.Projectors="Projectoren"
 Basic.Settings.General.HideProjectorCursor="Verberg cursor boven projectors"
 Basic.Settings.General.ProjectorAlwaysOnTop="Houd projectoren altijd bovenaan"
 Basic.Settings.General.Snapping="Bronuitlijning"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Bronnen uitlijnen op andere bronnen"
 Basic.Settings.General.SnapDistance="Gevoeligheid"
 Basic.Settings.General.RecordWhenStreaming="Stream automatisch opnemen"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Opname voortzetten als de stream stopt"
-Basic.Settings.General.SysTrayEnabled="Systeemvakicoon weergeven"
+Basic.Settings.General.ReplayBufferWhileStreaming="Replay buffer tegelijk starten met stream"
+Basic.Settings.General.KeepReplayBufferStreamStops="Replay buffer actief houden als stream stopt"
+Basic.Settings.General.SysTray="Systeemvak"
 Basic.Settings.General.SysTrayWhenStarted="Naar systeemvak minimaliseren bij opstarten"
+Basic.Settings.General.SystemTrayHideMinimize="Altijd minimaliseren naar het systeemvak in plaats van de taakbalk"
+Basic.Settings.General.SaveProjectors="Projectors opslaan bij afsluiten"
 
 Basic.Settings.Stream="Stream"
 Basic.Settings.Stream.StreamType="Stream Type"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="Uitvoermodus"
 Basic.Settings.Output.Mode.Simple="Simpel"
 Basic.Settings.Output.Mode.Adv="Geavanceerd"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg-uitvoer"
+Basic.Settings.Output.UseReplayBuffer="Replay Buffer Inschakelen"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximale Replay-tijd (Seconden)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximale hoeveelheid geheugen (Megabytes)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Geschat geheugengebruik: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Kan geheugengebruik niet inschatten. Stel een limiet in op het geheugengebruik."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Let op: Maak een sneltoets voor de replay buffer in de Sneltoetsen sectie)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Replay Buffer Bestandsnaam Prefix"
+Basic.Settings.Output.ReplayBuffer.Suffix="Achtervoegsel"
 Basic.Settings.Output.Simple.SavePath="Opnamepad"
 Basic.Settings.Output.Simple.RecordingQuality="Opnamekwaliteit"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Hetzelfde als de stream"
@@ -391,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Spoor 1"
 Basic.Settings.Output.Adv.Audio.Track2="Spoor 2"
 Basic.Settings.Output.Adv.Audio.Track3="Spoor 3"
 Basic.Settings.Output.Adv.Audio.Track4="Spoor 4"
+Basic.Settings.Output.Adv.Audio.Track5="Spoor 5"
+Basic.Settings.Output.Adv.Audio.Track6="Spoor 6"
 
 Basic.Settings.Output.Adv.Recording="Opnemen"
 Basic.Settings.Output.Adv.Recording.Type="Type"
@@ -471,6 +534,8 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV-Kleurruimte"
 Basic.Settings.Advanced.Video.ColorRange="YUV-Kleurbereik"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Partial"
 Basic.Settings.Advanced.Video.ColorRange.Full="Full"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Audio monitoring apparaat"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standaard"
 Basic.Settings.Advanced.StreamDelay="Streamvertraging"
 Basic.Settings.Advanced.StreamDelay.Duration="Duur (seconden)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Hervat op het eindpunt (verhoog vertraging) bij opnieuw verbinden"
@@ -484,15 +549,15 @@ Basic.AdvAudio.Volume="Volume (%)"
 Basic.AdvAudio.Mono="Downmixen naar Mono"
 Basic.AdvAudio.Panning="Pannen"
 Basic.AdvAudio.SyncOffset="Sync Offset (ms)"
+Basic.AdvAudio.Monitoring="Audio monitoring"
+Basic.AdvAudio.Monitoring.None="Niet monitoren"
+Basic.AdvAudio.Monitoring.MonitorOnly="Alleen monitoren (uitvoer gedempt)"
+Basic.AdvAudio.Monitoring.Both="Monitoren en uitvoeren"
 Basic.AdvAudio.AudioTracks="Sporen"
 
 Basic.Settings.Hotkeys="Sneltoetsen"
 Basic.Settings.Hotkeys.Pair="Toetsencombinaties gedeeld met '%1' werken als toggle"
 
-Basic.Hotkeys.StartStreaming="Stream Starten"
-Basic.Hotkeys.StopStreaming="Stream Stoppen"
-Basic.Hotkeys.StartRecording="Opname Starten"
-Basic.Hotkeys.StopRecording="Opname Stoppen"
 Basic.Hotkeys.SelectScene="Wissel naar scène"
 
 Basic.SystemTray.Show="Weergeven"
diff --git a/UI/data/locale/pl-PL.ini b/UI/data/locale/pl-PL.ini
index 14018ad..79eb1ba 100644
--- a/UI/data/locale/pl-PL.ini
+++ b/UI/data/locale/pl-PL.ini
@@ -49,6 +49,26 @@ Right="Od prawej"
 Top="Od góry"
 Bottom="Od dołu"
 Reset="Reset"
+Hours="Godziny"
+Minutes="Minuty"
+Seconds="Sekundy"
+Deprecated="Wycofywane"
+ReplayBuffer="Buffer replayu"
+Import="Importuj"
+Export="Eksportuj"
+
+Updater.Title="Dostępna jest nowa aktualizacja"
+Updater.Text="Dostępna jest nowa aktualizacja:"
+Updater.UpdateNow="Uaktualnij teraz"
+Updater.RemindMeLater="Przypomnij mi później"
+Updater.Skip="Pomiń wersję"
+Updater.Running.Title="Aplikacja jest uruchomiona"
+Updater.Running.Text="Wyjścia są aktualnie aktywne, proszę zamknąć wszystkie aktywne wyjścia przed rozpoczęciem procesu aktualizacji"
+Updater.NoUpdatesAvailable.Title="Brak dostępnych aktualizacji"
+Updater.NoUpdatesAvailable.Text="Brak dostępnych aktualizacji"
+Updater.FailedToLaunch="Nie udało się uruchomić aktualizacji"
+Updater.GameCaptureActive.Title="Przechwytywanie gry aktywne"
+Updater.GameCaptureActive.Text="Przechwytywanie gry jest aktywne. Proszę o zamknięcie wszelkich przechwytywanych gier/aplikacji (lub ponowne uruchomienie systemu) i spróbowanie później."
 
 QuickTransitions.SwapScenes="Zamień podgląd/wyjście scen po przejściu"
 QuickTransitions.SwapScenesTT="Zamienia podgląd i wyjście scen po przejściu (jeżeli wyjście oryginalnej sceny istnieje).\nNie przywraca to zmian jakie zostały dokonane w oryginalnej scenie."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Potwierdź usunięcie"
 ConfirmRemove.Text="Czy na pewno chcesz usunąć '$1'?"
 ConfirmRemove.TextMultiple="Liczba elementów do usunięcia: %1. Czy na pewno chcesz je usunąć?"
 
+Output.StartStreamFailed="Nie udało się rozpocząć streamowania"
+Output.StartRecordingFailed="Nie udało się rozpocząć nagrywania"
+Output.StartReplayFailed="Nie udało się rozpocząć nagrywania powtórek"
+Output.StartFailedGeneric="Nie udało się uruchomić wyjścia. Sprawdź szczegóły w plikach dziennika.\n\nUwaga: Sprawdź, czy posiadasz aktualne sterowniki karty graficznej, jeżeli używasz enkodera NVENC lub AMD."
+
 Output.ConnectFail.Title="Nie udało się połączyć"
 Output.ConnectFail.BadPath="Nieprawidłowa ścieżka lub adres URL połączenia. Sprawdź poprawność ustawień."
 Output.ConnectFail.ConnectFailed="Nie udało się połączyć z serwerem"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="Za mało miejsca na dysku"
 Output.RecordNoSpace.Msg="Za mało miejsca na dysku, aby kontynuować nagrywanie."
 Output.RecordError.Title="BÅ‚Ä…d nagrywania"
 Output.RecordError.Msg="Wystąpił nieokreślony błąd podczas nagrywania."
+Output.ReplayBuffer.NoHotkey.Title="Brak klawisza skrótu!"
+Output.ReplayBuffer.NoHotkey.Msg="Klawisz skrótu nie jest zapisany dla buforu replay. Ustaw skrót  \"Zapisz\" aby zapisać nagrania replay."
 
 Output.BadPath.Title="Nieprawidłowa ścieżka pliku"
 Output.BadPath.Text="Ustawiona ścieżka pliku wynikowego jest nieprawidłowa. Proszę sprawdzić ustawienia."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Najpierw pole górne"
 Deinterlacing.BottomFieldFirst="Najpierw pole dolne"
 
+VolControl.SliderUnmuted="Suwak głośności dla '%1': %2"
+VolControl.SliderMuted="Suwak głośności dla '%1': %2 (obecnie wyciszony)"
+VolControl.Mute="Wycisz '%1'"
+VolControl.Properties="Właściwości dla '%1'"
+
 Basic.Main.AddSceneDlg.Title="Dodaj scenÄ™"
 Basic.Main.AddSceneDlg.Text="Podaj nazwÄ™ sceny"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Sceny"
 Basic.Main.Sources="Źródła obrazu"
 Basic.Main.Connecting="Łączenie..."
 Basic.Main.StartRecording="Rozpocznij nagrywanie"
+Basic.Main.StartReplayBuffer="Rozpocznij bufor replayu"
 Basic.Main.StartStreaming="Rozpocznij stream"
 Basic.Main.StopRecording="Zatrzymaj nagrywanie"
 Basic.Main.StoppingRecording="Zatrzymywanie nagrywania..."
+Basic.Main.StopReplayBuffer="Zatrzymaj bufor replayu"
+Basic.Main.StoppingReplayBuffer="Zatrzymywanie buforu replay..."
 Basic.Main.StopStreaming="Zatrzymaj stream"
 Basic.Main.StoppingStreaming="Zatrzymywanie streamowania..."
 Basic.Main.ForceStopStreaming="Zatrzymaj stream (anuluj opóźnienie)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="&Wykonaj ponownie"
 Basic.MainMenu.Edit.UndoAction="&Cofnij $1"
 Basic.MainMenu.Edit.RedoAction="&Wykonaj ponownie $1"
 Basic.MainMenu.Edit.LockPreview="Zab&lokuj podglÄ…d"
+Basic.MainMenu.Edit.Scale="&Skalowanie widoku"
+Basic.MainMenu.Edit.Scale.Window="Skaluj do okna"
+Basic.MainMenu.Edit.Scale.Canvas="Powierzchnia robocza (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Powierzchnia wyjściowa (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Przekształcanie obrazu"
 Basic.MainMenu.Edit.Transform.EditTransform="&Edycja przekształceń..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Skopiuj transformacje"
+Basic.MainMenu.Edit.Transform.PasteTransform="Wklej transformacje"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Reset przekształceń"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Obróć o 90 stopni zgodnie z ruchem wskazówkek zegara"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Obróć o 90 stopni przeciwnie do ruchu wskazówek zegara"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="Pasek &stanu"
 
 Basic.MainMenu.SceneCollection="Zbiór &scen"
 Basic.MainMenu.Profile="P&rofil"
+Basic.MainMenu.Profile.Import="Importuj profil"
+Basic.MainMenu.Profile.Export="Eksportuj profil"
+Basic.MainMenu.SceneCollection.Import="Importuj kolekcje sceny"
+Basic.MainMenu.SceneCollection.Export="Exportuj kolekcje sceny"
+Basic.MainMenu.Profile.Exists="Profil już istnieje"
+Basic.MainMenu.SceneCollection.Exists="Kolekcja sceny już istnieje"
 
 Basic.MainMenu.Tools="&Narzędzia"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="Zmiany nie zostały zapisane. Czy zapisać zmiany?"
 Basic.Settings.General="Główne"
 Basic.Settings.General.Theme="Motyw"
 Basic.Settings.General.Language="Język"
+Basic.Settings.General.EnableAutoUpdates="Automatycznie sprawdzaj dostępność aktualizacji"
 Basic.Settings.General.WarnBeforeStartingStream="Pokaż komunikat potwierdzenia uruchomienia streamowania"
 Basic.Settings.General.WarnBeforeStoppingStream="Pokaż komunikat potwierdzenia zatrzymania streamowania"
+Basic.Settings.General.Projectors="Projektory"
 Basic.Settings.General.HideProjectorCursor="Ukryj kursor podglądu na pełnym ekranie"
 Basic.Settings.General.ProjectorAlwaysOnTop="Podgląd na pełnym ekranie zawsze na wierzchu"
 Basic.Settings.General.Snapping="Przyciąganie elementów źródłowych"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Przyciągaj źródła do innych źródeł
 Basic.Settings.General.SnapDistance="Czułość przyciągania"
 Basic.Settings.General.RecordWhenStreaming="Automatyczne nagrywanie streamu"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Zachowaj nagranie po zatrzymaniu streamu"
-Basic.Settings.General.SysTrayEnabled="Wyświetlaj ikonę w zasobniku systemowym"
+Basic.Settings.General.ReplayBufferWhileStreaming="Automatycznie rozpocznij nagrywanie powtórek w przypadku streamowania"
+Basic.Settings.General.KeepReplayBufferStreamStops="Kontynuuj nagrywanie powtórek po zatrzymaniu streamowania"
+Basic.Settings.General.SysTray="Zasobnik systemowy"
 Basic.Settings.General.SysTrayWhenStarted="Minimalizuj do zasobnika systemowego podczas uruchamiania"
+Basic.Settings.General.SystemTrayHideMinimize="Zawsze minimalizuj do zasobnika systemowego zamiast do paska zadań"
+Basic.Settings.General.SaveProjectors="Zapisz konfigurację podglądów na pełnym ekranie przy zamknięciu aplikacji"
 
 Basic.Settings.Stream="Stream"
 Basic.Settings.Stream.StreamType="Typ streamu"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="Tryb wyjścia"
 Basic.Settings.Output.Mode.Simple="Proste"
 Basic.Settings.Output.Mode.Adv="Zaawansowane"
 Basic.Settings.Output.Mode.FFmpeg="Wyjście FFmpeg"
+Basic.Settings.Output.UseReplayBuffer="WÅ‚Ä…cz bufor replay"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksymalny czas replay (w sekundach)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksymalna ilość pamięci (w megabajtach)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Szacowane użycie pamięci: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nie można oszacować użycie pamięci.  Należy ustawić limit maksymalnej pamięci."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Uwaga: Upewnij się aby ustawić klawisz skrótu dla buforu replay w sekcji Skróty klawiszowe)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Prefiks nazwy pliku buforu replay"
+Basic.Settings.Output.ReplayBuffer.Suffix="Sufiks"
 Basic.Settings.Output.Simple.SavePath="Ścieżka pliku"
 Basic.Settings.Output.Simple.RecordingQuality="Jakość nagrywania"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Taki sam jak stream"
@@ -391,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Ścieżka 1"
 Basic.Settings.Output.Adv.Audio.Track2="Ścieżka 2"
 Basic.Settings.Output.Adv.Audio.Track3="Ścieżka 3"
 Basic.Settings.Output.Adv.Audio.Track4="Ścieżka 4"
+Basic.Settings.Output.Adv.Audio.Track5="Ścieżka 5"
+Basic.Settings.Output.Adv.Audio.Track6="Ścieżka 6"
 
 Basic.Settings.Output.Adv.Recording="Nagrywanie"
 Basic.Settings.Output.Adv.Recording.Type="Typ"
@@ -418,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Ustawienia enkodera video (je
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Enkoder dźwięku"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Ustawienia enkodera audio (jeśli są)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Ustawienia muxera (jeżeli są)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Odstęp między klatkami kluczowymi (klatki)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Pokaż wszystkie kodeki (nawet potencjalnie niezgodne)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -471,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="Przestrzeń kolorów YUV"
 Basic.Settings.Advanced.Video.ColorRange="Zakres kolorów YUV"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Częściowy"
 Basic.Settings.Advanced.Video.ColorRange.Full="Pełny"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Monitorowane urzÄ…dzenie audio"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Domyślne"
 Basic.Settings.Advanced.StreamDelay="Opóźnienie streamu"
 Basic.Settings.Advanced.StreamDelay.Duration="Czas trwania (s)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Zachowuj punkt przerwania (zwiększ opóźnienie) podczas ponownego łączenia"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Szacowane zużycie pamięci: %1 MB"
 Basic.Settings.Advanced.Network="Sieć"
 Basic.Settings.Advanced.Network.BindToIP="Przypisane IP"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Aktywuj nowy kod sieciowy"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Tryb niskich opóźnień"
 
 Basic.AdvAudio="Zaawansowane ustawienia dźwięku"
 Basic.AdvAudio.Name="Nazwa"
@@ -484,15 +553,15 @@ Basic.AdvAudio.Volume="Głośność (%)"
 Basic.AdvAudio.Mono="Downmix do Mono"
 Basic.AdvAudio.Panning="Rozciągnięcie dźwięku"
 Basic.AdvAudio.SyncOffset="Przesunięcie dźwięku (ms)"
+Basic.AdvAudio.Monitoring="Monitorowanie urzÄ…dzenia audio"
+Basic.AdvAudio.Monitoring.None="Wyłączone"
+Basic.AdvAudio.Monitoring.MonitorOnly="Tylko monitorowanie (wyjście wyłączone)"
+Basic.AdvAudio.Monitoring.Both="Monitorowanie i przekazywanie na wyjście"
 Basic.AdvAudio.AudioTracks="Ścieżki"
 
 Basic.Settings.Hotkeys="Skróty klawiszowe"
 Basic.Settings.Hotkeys.Pair="Komibnacje klawiszy wspólne z '%1' działają jako przełączniki"
 
-Basic.Hotkeys.StartStreaming="Rozpocznij stream"
-Basic.Hotkeys.StopStreaming="Zakończ stream"
-Basic.Hotkeys.StartRecording="Rozpocznij nagrywanie"
-Basic.Hotkeys.StopRecording="Zatrzymaj nagrywanie"
 Basic.Hotkeys.SelectScene="Przełącz na scenę"
 
 Basic.SystemTray.Show="Pokaż"
@@ -546,4 +615,5 @@ SceneItemHide="Ukryj '%1'"
 
 OutputWarnings.NoTracksSelected="Musisz wybrać przynajmniej jedną ścieżkę"
 OutputWarnings.MultiTrackRecording="Ostrzeżenie: Pewne formaty plików (np. FLV) nie obsługują wielu ścieżek dźwiękowych"
+OutputWarnings.MP4Recording="Ostrzeżenie: Nagrania zapisanego w formacie mp4 nie będzie można odzyskać, jeśli plik nie zostanie zakończony poprawnie (np. w wyniku BSOD, braku prądu, itp.). Jeśli chcesz nagrać wiele ścieżek audio należy rozważyć użycie formatu mkv i remux nagrania do mp4 po zakończeniu (Plik -> Przepakuj nagrania)."
 
diff --git a/UI/data/locale/pt-BR.ini b/UI/data/locale/pt-BR.ini
index 15cf8d3..4fb7cce 100644
--- a/UI/data/locale/pt-BR.ini
+++ b/UI/data/locale/pt-BR.ini
@@ -48,6 +48,14 @@ Left="Esquerda"
 Right="Direita"
 Top="Topo"
 Bottom="Baixo"
+Reset="Redefinir"
+Hours="Horas"
+Minutes="Minutos"
+Seconds="Segundos"
+Deprecated="Obsoleto"
+ReplayBuffer="Buffer do Replay"
+Export="Exportar"
+
 
 QuickTransitions.SwapScenes="Trocar Cenas de Prévia/Saída após a Transição"
 QuickTransitions.SwapScenesTT="Troca a preview e a saída após transicionar (se a a cena original de saída ainda exisitr).\nIsto não irá desfazer nenhuma mudança que foi feita na cena original da saída."
@@ -89,6 +97,7 @@ ConfirmRemove.Title="Confirmar a Remoção"
 ConfirmRemove.Text="Tem certeza que deseja remover '$1'?"
 ConfirmRemove.TextMultiple="Você tem certeza que quer remover esses %1 itens?"
 
+
 Output.ConnectFail.Title="Falha ao conectar"
 Output.ConnectFail.BadPath="Caminho inválido ou URL inválida. Por favor verifique se as configurações estão válidas."
 Output.ConnectFail.ConnectFailed="Falha ao conectar com o Servidor"
@@ -102,6 +111,8 @@ Output.RecordNoSpace.Title="Espaço em disco insuficiente"
 Output.RecordNoSpace.Msg="Não há espaço em disco suficiente para continuar a gravação."
 Output.RecordError.Title="Erro de gravação"
 Output.RecordError.Msg="Ocorreu um erro não especificado durante a gravação."
+Output.ReplayBuffer.NoHotkey.Title="Tecla de Atalho não configurada!"
+Output.ReplayBuffer.NoHotkey.Msg="Tecla de Atalho para salvar o Buffer do replay não definida. Por favor, configure uma tecla de atalho para salvar gravações de replays."
 
 Output.BadPath.Title="Caminho de Arquivo Inválido"
 Output.BadPath.Text="O caminho do arquivo de saída é inválido. Por Favor, certifique-se de que um caminho válido foi informado."
@@ -149,6 +160,7 @@ ScaleFiltering="Filtragem de escala"
 ScaleFiltering.Point="Ponto"
 ScaleFiltering.Bilinear="Bilinear"
 ScaleFiltering.Bicubic="Bicúbico"
+ScaleFiltering.Lanczos="Lanczos"
 
 Deinterlacing="Desentrelaçamento"
 Deinterlacing.Discard="Descartar"
@@ -162,6 +174,7 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Campo Superior Primeiro"
 Deinterlacing.BottomFieldFirst="Campo Inferior Primeiro"
 
+
 Basic.Main.AddSceneDlg.Title="Adicionar Cena"
 Basic.Main.AddSceneDlg.Text="Por favor, digite o nome da cena"
 
@@ -256,9 +269,12 @@ Basic.Main.Scenes="Cenas"
 Basic.Main.Sources="Fontes"
 Basic.Main.Connecting="Conectando..."
 Basic.Main.StartRecording="Iniciar gravação"
+Basic.Main.StartReplayBuffer="Iniciar Buffer do Replay"
 Basic.Main.StartStreaming="Iniciar Transmissão"
 Basic.Main.StopRecording="Parar Gravação"
 Basic.Main.StoppingRecording="Parando de Gravar..."
+Basic.Main.StopReplayBuffer="Parar Buffer do Replay"
+Basic.Main.StoppingReplayBuffer="Parando Buffer do Replay..."
 Basic.Main.StopStreaming="Parar Transmissão"
 Basic.Main.StoppingStreaming="Parando Transmissão..."
 Basic.Main.ForceStopStreaming="Pare de transmitir (descartar atraso)"
@@ -280,8 +296,14 @@ Basic.MainMenu.Edit.Redo="&Refazer"
 Basic.MainMenu.Edit.UndoAction="&Desfazer $1"
 Basic.MainMenu.Edit.RedoAction="&Refazer $1"
 Basic.MainMenu.Edit.LockPreview="&Bloquear pré-visualização"
+Basic.MainMenu.Edit.Scale="Visualização e dimensionamento"
+Basic.MainMenu.Edit.Scale.Window="Escala para janela"
+Basic.MainMenu.Edit.Scale.Canvas="Lona (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Saída (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Transformar"
 Basic.MainMenu.Edit.Transform.EditTransform="&Editar Transformação..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Copiar Transformação"
+Basic.MainMenu.Edit.Transform.PasteTransform="Colar Transformação"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Limpar Transformação"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Girar 90º sentido Horário"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Girar 90º sentido Anti-Horário"
@@ -306,6 +328,12 @@ Basic.MainMenu.View.StatusBar="Barra de Status"
 
 Basic.MainMenu.SceneCollection="&Coleção de cena"
 Basic.MainMenu.Profile="&Perfil"
+Basic.MainMenu.Profile.Import="Importar Perfil"
+Basic.MainMenu.Profile.Export="Exportar Perfil"
+Basic.MainMenu.SceneCollection.Import="Importar Grupo de Cenas"
+Basic.MainMenu.SceneCollection.Export="Exportar Grupo de Cenas"
+Basic.MainMenu.Profile.Exists="Perfil já existe"
+Basic.MainMenu.SceneCollection.Exists="O Grupo de Cenas já existe"
 
 Basic.MainMenu.Tools="Ferramentas (&T)"
 
@@ -336,8 +364,8 @@ Basic.Settings.General.SourceSnapping="Encaixar fontes com outras fontes"
 Basic.Settings.General.SnapDistance="Sensibilidade de Encaixamento"
 Basic.Settings.General.RecordWhenStreaming="Gravar automaticamente quando estiver transmitindo"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Continuar gravando quando a transmissão parar"
-Basic.Settings.General.SysTrayEnabled="Habilitar o ícone de bandeja do sistema"
 Basic.Settings.General.SysTrayWhenStarted="Minimizar para a bandeja do sistema quando iniciar"
+Basic.Settings.General.SaveProjectors="Salvar projetores ao sair"
 
 Basic.Settings.Stream="Stream"
 Basic.Settings.Stream.StreamType="Tipo de Stream"
@@ -352,6 +380,14 @@ Basic.Settings.Output.Mode="Modo de Saída"
 Basic.Settings.Output.Mode.Simple="Simples"
 Basic.Settings.Output.Mode.Adv="Avançado"
 Basic.Settings.Output.Mode.FFmpeg="Saída de FFmpeg"
+Basic.Settings.Output.UseReplayBuffer="Habilitar Buffer de Repetição"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo de Replay máximo (Segundos)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memória Máxima (Megabytes)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Uso de memória estimado: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Impossível estimar o uso de memória. Por favor, defina o limite máximo de memória."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Nota: Não se esqueça de configurar uma Tecla de Atalho para o Buffer de Replay na seção Teclas de Atalhos)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Prefixo do Buffer de Repetição"
+Basic.Settings.Output.ReplayBuffer.Suffix="Sufixo"
 Basic.Settings.Output.Simple.SavePath="Caminho de gravação"
 Basic.Settings.Output.Simple.RecordingQuality="Qualidade da gravação"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Mesmo que a stream"
@@ -367,6 +403,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Aviso de qualidade lossless!"
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Aviso: Você não pode usar vários codificadores QSV separados quando estiver transmitindo e gravando ao mesmo tempo.  Se você deseja transmitir e gravar ao mesmo tempo, por favor altere o codificador de gravação ou o de transmissão."
 Basic.Settings.Output.Simple.Encoder.Software="Software (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (preset x264 de baixa utilização de CPU, aumenta o tamanho do arquivo)"
 Basic.Settings.Output.VideoBitrate="Taxa de Bits do Vídeo"
@@ -388,6 +425,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Faixa 1"
 Basic.Settings.Output.Adv.Audio.Track2="Faixa 2"
 Basic.Settings.Output.Adv.Audio.Track3="Faixa 3"
 Basic.Settings.Output.Adv.Audio.Track4="Faixa 4"
+Basic.Settings.Output.Adv.Audio.Track5="Faixa 5"
+Basic.Settings.Output.Adv.Audio.Track6="Faixa 6"
 
 Basic.Settings.Output.Adv.Recording="Gravação"
 Basic.Settings.Output.Adv.Recording.Type="Tipo"
@@ -416,7 +455,7 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador de áudio"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Configurações do codificador de áudio(se houver)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Configurações do Muxer (se houver)"
 
-FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
+FilenameFormatting.completer="%CCYY-% MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %H-%M-%S\n%A %d-%Y-%m %Y-%m-%d %H-%M-%S\n%Y-%b-123_2_ 16_321 %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H %M - %S-%Z"
 
 FilenameFormatting.TT="%CCYY		Ano, quatro dígitos\n%YY		Ano, dois dígitos (00-99)\n%MM		Mês como um número decimal (01-12)\n%DD		Dia do mês, começando com 0 (01-31)\n%hh		Hora, em formato de 24h (00-23)\n%mm		Minuto (00-59)\n%ss		Segundo (00-61)\n%%		A % sign\n%a		Dia da Semana abreviado\n%A		Nome da Semana completo\n%b		Nome do Mês abreviado\n%B		Nome do Mês completo\n%d		Dia do Mês, começando com 0 (01-31)\n%H		Hora, no formato de 24h (00-23)\n%I		Hora no formato de 12h (01-12)\n%m		Mês como um número decimal (01-12)\n%M		Minuto (00-59)\n%p		Designação AM ou PM\n%S		Segundo (00-61)\n%y		Ano, últimos dois dígitos (00-99)\n%Y		Ano\n%z		ISO 8601 diferença de fuso horário ou de UTC\n		nome ou abreviação\n%Z		Nome do Fuso Horário ou abreviação\n"
 
@@ -468,6 +507,7 @@ Basic.Settings.Advanced.Video.ColorSpace="Espaço de cor YUV"
 Basic.Settings.Advanced.Video.ColorRange="Gama de cores YUV"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Limitado"
 Basic.Settings.Advanced.Video.ColorRange.Full="Completo"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Padrão"
 Basic.Settings.Advanced.StreamDelay="Atraso da transmissão"
 Basic.Settings.Advanced.StreamDelay.Duration="Duração (segundos)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Preservar o ponto de corte (aumento de atraso) quando reconectar"
@@ -486,10 +526,6 @@ Basic.AdvAudio.AudioTracks="Faixas"
 Basic.Settings.Hotkeys="Teclas de atalho"
 Basic.Settings.Hotkeys.Pair="Combinações de teclas compartilhadas com '%1' agem como alternaçoes"
 
-Basic.Hotkeys.StartStreaming="Iniciar transmissão"
-Basic.Hotkeys.StopStreaming="Parar transmissão"
-Basic.Hotkeys.StartRecording="Iniciar gravação"
-Basic.Hotkeys.StopRecording="Parar gravação"
 Basic.Hotkeys.SelectScene="Mudar de cena"
 
 Basic.SystemTray.Show="Exibir"
diff --git a/UI/data/locale/pt-PT.ini b/UI/data/locale/pt-PT.ini
index 6edac0a..24feb7d 100644
--- a/UI/data/locale/pt-PT.ini
+++ b/UI/data/locale/pt-PT.ini
@@ -48,6 +48,11 @@ Left="Esquerda"
 Right="Direita"
 Top="Cima"
 Bottom="Baixo"
+Reset="Repor"
+Hours="Horas"
+Minutes="Minutos"
+Seconds="Segundos"
+
 
 QuickTransitions.SwapScenes="Trocar pré-visualização/saída de cenas Depois de uma Transição"
 QuickTransitions.DuplicateScene="Duplicar cena"
@@ -85,6 +90,8 @@ ConfirmExit.Text="O OBS está ligado. Todas as transmissões e gravações serã
 
 ConfirmRemove.Title="Comfirmar Remover"
 ConfirmRemove.Text="Tem a certeza que quer remover '$1'?"
+ConfirmRemove.TextMultiple="Tem a certeza de que pretende remover %1 itens?"
+
 
 Output.ConnectFail.Title="Falha ao ligar"
 Output.ConnectFail.BadPath="Caminho ou endereço de ligação inválido. Por favor, verifique as suas definições para confirmar que são válidas."
@@ -155,6 +162,7 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Campo Superior Primeiro"
 Deinterlacing.BottomFieldFirst="Campo Inferior Primeiro"
 
+
 Basic.Main.AddSceneDlg.Title="Adicionar Cena"
 Basic.Main.AddSceneDlg.Text="Por favor introduza o nome da cena"
 
@@ -185,7 +193,9 @@ Basic.PropertiesWindow.ConfirmTitle="Definições alteradas"
 Basic.PropertiesWindow.Confirm="Há alterações não guardadas. Pretende mantê-las?"
 Basic.PropertiesWindow.NoProperties="Sem propriedades disponíveis"
 Basic.PropertiesWindow.AddFiles="Adicionar ficheiros"
+Basic.PropertiesWindow.AddDir="Adicionar diretório"
 Basic.PropertiesWindow.AddURL="Adicionar caminho ou endereço"
+Basic.PropertiesWindow.AddEditableListDir="Adicionar diretório a '%1'"
 Basic.PropertiesWindow.AddEditableListFiles="Adicionar ficheiros a '%1'"
 Basic.PropertiesWindow.AddEditableListEntry="Adicionar entrada a '%1'"
 Basic.PropertiesWindow.EditEditableListEntry="Editar entrada a '%1'"
@@ -249,7 +259,9 @@ Basic.Main.Connecting="A ligar..."
 Basic.Main.StartRecording="Começar Gravação"
 Basic.Main.StartStreaming="Iniciar transmissão"
 Basic.Main.StopRecording="Parar Gravação"
+Basic.Main.StoppingRecording="A parar gravação..."
 Basic.Main.StopStreaming="Parar transmissão"
+Basic.Main.StoppingStreaming="A parar transmissão..."
 Basic.Main.ForceStopStreaming="Parar transmissão (ignorar atraso)"
 
 Basic.MainMenu.File="&Ficheiro"
@@ -268,6 +280,7 @@ Basic.MainMenu.Edit.Undo="Desfazer"
 Basic.MainMenu.Edit.Redo="&Refazer"
 Basic.MainMenu.Edit.UndoAction="Desfazer $1"
 Basic.MainMenu.Edit.RedoAction="&Refazer $1"
+Basic.MainMenu.Edit.LockPreview="B&loquear pré-visualização"
 Basic.MainMenu.Edit.Transform="&Transformar"
 Basic.MainMenu.Edit.Transform.EditTransform="&Editar Transformação..."
 Basic.MainMenu.Edit.Transform.ResetTransform="&Reset Transform"
@@ -286,10 +299,15 @@ Basic.MainMenu.Edit.Order.MoveToTop="Mover para p &Topo"
 Basic.MainMenu.Edit.Order.MoveToBottom="Mover para o Fundo"
 Basic.MainMenu.Edit.AdvAudio="Propriedades &avançadas de áudio"
 
+Basic.MainMenu.View="&Ver"
+Basic.MainMenu.View.Toolbars="Barras de ferramen&tas"
+Basic.MainMenu.View.SceneTransitions="Transições de &cenas"
+Basic.MainMenu.View.StatusBar="&Barra de estado"
 
 Basic.MainMenu.SceneCollection="Coleção de cena"
 Basic.MainMenu.Profile="&Perfil"
 
+Basic.MainMenu.Tools="&Ferramentas"
 
 Basic.MainMenu.Help="&Ajuda"
 Basic.MainMenu.Help.Website="Visitar &website"
@@ -311,6 +329,9 @@ Basic.Settings.General.WarnBeforeStartingStream="Mostrar caixa de diálogo de co
 Basic.Settings.General.WarnBeforeStoppingStream="Mostrar caixa de diálogo de confirmação ao parar transmissões"
 Basic.Settings.General.Snapping="Alinhamentos com encaixe na Cena"
 Basic.Settings.General.SnapDistance="Sensibilidade do Snap"
+Basic.Settings.General.RecordWhenStreaming="Gravar automaticamente quando estiver a transmitir"
+Basic.Settings.General.KeepRecordingWhenStreamStops="Continuar a gravar quando a transmissão parar"
+Basic.Settings.General.SysTrayWhenStarted="Minimizar para a área de notificações quando iniciado"
 
 Basic.Settings.Stream="Transmissão"
 Basic.Settings.Stream.StreamType="Tipo de transmissão"
@@ -423,6 +444,11 @@ Basic.Settings.Audio.PushToTalkDelay="Atraso do push-to-talk"
 Basic.Settings.Audio.UnknownAudioDevice="[Dispositivo não conectado ou não disponível]"
 
 Basic.Settings.Advanced="Avançado"
+Basic.Settings.Advanced.General.ProcessPriority="Prioridade do precesso"
+Basic.Settings.Advanced.General.ProcessPriority.High="Alta"
+Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Acima do normal"
+Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal"
+Basic.Settings.Advanced.General.ProcessPriority.Idle="Inativo"
 Basic.Settings.Advanced.FormatWarning="Aviso: Formatos de cor diferentes de NV12 destinam-se principalmente a gravação e não são recomendados durante a transmissão. A transmissão pode incorrer numa maior utilização do processador devido à conversão do formato de cor."
 Basic.Settings.Advanced.Audio.BufferingTime="Tempo de carregamento do áudio"
 Basic.Settings.Advanced.Video.ColorFormat="Formato de cor"
@@ -434,6 +460,8 @@ Basic.Settings.Advanced.StreamDelay="Atraso na trasmissão"
 Basic.Settings.Advanced.StreamDelay.Duration="Duração (segundos)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Preservar o ponto de corte (aumentar atraso) quando reconectar"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Utilização estimada de memória: %1 MB"
+Basic.Settings.Advanced.Network="Rede"
+Basic.Settings.Advanced.Network.BindToIP="Ligar pelo IP"
 
 Basic.AdvAudio="Propriedades avançadas de áudio"
 Basic.AdvAudio.Name="Nome"
@@ -446,13 +474,12 @@ Basic.AdvAudio.AudioTracks="Faixas"
 Basic.Settings.Hotkeys="Teclas de atalho"
 Basic.Settings.Hotkeys.Pair="Combinações de teclas partilhadas com '%1' atuam como alavancas"
 
-Basic.Hotkeys.StartStreaming="Iniciar transmissão"
-Basic.Hotkeys.StopStreaming="Parar transmissão"
-Basic.Hotkeys.StartRecording="Iniciar gravação"
-Basic.Hotkeys.StopRecording="Parar gravação"
 Basic.Hotkeys.SelectScene="Mudar para cena"
 
+Basic.SystemTray.Show="Mostrar"
+Basic.SystemTray.Hide="Ocultar"
 
+Basic.SystemTray.Message.Reconnecting="Desligado. A religar..."
 
 Hotkeys.Insert="Insert"
 Hotkeys.Delete="Delete"
diff --git a/UI/data/locale/ro-RO.ini b/UI/data/locale/ro-RO.ini
index e58bc14..d39fc9b 100644
--- a/UI/data/locale/ro-RO.ini
+++ b/UI/data/locale/ro-RO.ini
@@ -48,6 +48,13 @@ Left="Stânga"
 Right="Dreapta"
 Top="Sus"
 Bottom="Jos"
+Hours="Ore"
+Minutes="Minute"
+Seconds="Secunde"
+Deprecated="Invechit"
+Import="Importă"
+Export="Exportă"
+
 
 QuickTransitions.SwapScenes="Comută între previzualizare/scenele de ieșire după tranziționare"
 QuickTransitions.SwapScenesTT="Schimba previzualizarea si scenele de output dupa tranzitionare (în cazul în care încă există outputul scenei originale). \nAceasta nu va anula nicio modificăre care au fost făcute la outputul scenei originale."
@@ -87,6 +94,8 @@ ConfirmExit.Text="OBS este în prezent activ.  Toate streamurile/înregistrăril
 
 ConfirmRemove.Title="Confirmă eliminarea"
 ConfirmRemove.Text="Sigur dorești să elimini „$1”?"
+ConfirmRemove.TextMultiple="Sigur doriți sa eliminați %1 obiecte?"
+
 
 Output.ConnectFail.Title="Eșec la conectare"
 Output.ConnectFail.BadPath="URL-ul conexiunii sau calea este invalidă.  Te rugăm să verifici setările pentru a confirma că acestea sunt valide."
@@ -118,6 +127,7 @@ LicenseAgreement.Exit="Ieși"
 Remux.SourceFile="ÃŽnregistrare OBS"
 Remux.TargetFile="Fișier țintă"
 Remux.Remux="Remux"
+Remux.OBSRecording="ÃŽnregistrare OBS"
 Remux.FinishedTitle="Remuxing încheiat"
 Remux.Finished="Înregistrare remuxată"
 Remux.FinishedError="Înregistrare remuxată, însă fișierul poate fi incomplet"
@@ -143,6 +153,9 @@ Basic.DisplayCapture="Captură de display"
 
 Basic.Main.PreviewConextMenu.Enable="Activează previzualizarea"
 
+ScaleFiltering.Bilinear="Biliniar"
+ScaleFiltering.Bicubic="Bicubic"
+ScaleFiltering.Lanczos="Lanczos"
 
 Deinterlacing="Deîntrețesere"
 Deinterlacing.Discard="Înlătură"
@@ -156,6 +169,7 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Câmpul de sus prima oară"
 Deinterlacing.BottomFieldFirst="Câmpul de jos prima oară"
 
+
 Basic.Main.AddSceneDlg.Title="Adaugă scenă"
 Basic.Main.AddSceneDlg.Text="Te rugăm să introduci numele scenei"
 
@@ -290,7 +304,11 @@ Basic.MainMenu.Edit.AdvAudio="Proprietăți audio &avansate"
 
 Basic.MainMenu.SceneCollection="Colecție de &scene"
 Basic.MainMenu.Profile="&Profil"
+Basic.MainMenu.Profile.Import="Importă Profil"
+Basic.MainMenu.Profile.Export="Exportă profil"
+Basic.MainMenu.Profile.Exists="Profilul deja există"
 
+Basic.MainMenu.Tools="&Unelte"
 
 Basic.MainMenu.Help="&Ajutor"
 Basic.MainMenu.Help.Website="Vizitează site-ul &web"
@@ -329,6 +347,8 @@ Basic.Settings.Output.Mode="Mod de ieșire"
 Basic.Settings.Output.Mode.Simple="Simplu"
 Basic.Settings.Output.Mode.Adv="Avansat"
 Basic.Settings.Output.Mode.FFmpeg="Ieșire FFmpeg"
+Basic.Settings.Output.ReplayBuffer.Estimate="Utilizare estimată a memoriei: %1 MB"
+Basic.Settings.Output.ReplayBuffer.Suffix="Sufix"
 Basic.Settings.Output.Simple.SavePath="Cale de înregistrare"
 Basic.Settings.Output.Simple.RecordingQuality="Calitatea înregistrării"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="La fel cu cea a streamului"
@@ -432,6 +452,11 @@ Basic.Settings.Audio.PushToTalkDelay="Întârziere push-to-talk"
 Basic.Settings.Audio.UnknownAudioDevice="[Dispozitivul nu este disponibil sau nu este conectat]"
 
 Basic.Settings.Advanced="Avansate"
+Basic.Settings.Advanced.General.ProcessPriority="Prioritate Proces"
+Basic.Settings.Advanced.General.ProcessPriority.High="Ridicată"
+Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Peste Normal"
+Basic.Settings.Advanced.General.ProcessPriority.Normal="Normală"
+Basic.Settings.Advanced.General.ProcessPriority.Idle="Inactiv"
 Basic.Settings.Advanced.FormatWarning="Atentie: Formatele de culori diferite de NV12 sunt facute pentru inregistrare si nu sunt recomandate in cazul streaming-ului. Streaming-ul e posibil sa ceara mai multe resurse CPU datorita conversiei formatului culorii."
 Basic.Settings.Advanced.Audio.BufferingTime="Timp de buffering pentru audio"
 Basic.Settings.Advanced.Video.ColorFormat="Format de culoare"
@@ -443,6 +468,8 @@ Basic.Settings.Advanced.StreamDelay="Întârziere pentru stream"
 Basic.Settings.Advanced.StreamDelay.Duration="Durată (secunde)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Păstrează punctul de tăiere (crește întârzierea) la reconectare"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Utilizare estimată a memoriei: %1 MB"
+Basic.Settings.Advanced.Network="Rețea"
+Basic.Settings.Advanced.Network.BindToIP="Leagă de IP"
 
 Basic.AdvAudio="Proprietăți audio avansate"
 Basic.AdvAudio.Name="Nume"
@@ -455,13 +482,12 @@ Basic.AdvAudio.AudioTracks="Piste"
 Basic.Settings.Hotkeys="Taste rapide"
 Basic.Settings.Hotkeys.Pair="Combinațiile de taste partajate cu '%1' acționează ca comutatoare"
 
-Basic.Hotkeys.StartStreaming="Pornește streamingul"
-Basic.Hotkeys.StopStreaming="Oprește streamingul"
-Basic.Hotkeys.StartRecording="Pornește înregistrarea"
-Basic.Hotkeys.StopRecording="Oprește înregistrarea"
 Basic.Hotkeys.SelectScene="Comută la scenă"
 
+Basic.SystemTray.Show="Afișează"
+Basic.SystemTray.Hide="Ascunde"
 
+Basic.SystemTray.Message.Reconnecting="Deconectat. Reconectare..."
 
 Hotkeys.Insert="Inserează"
 Hotkeys.Delete="Șterge"
diff --git a/UI/data/locale/ru-RU.ini b/UI/data/locale/ru-RU.ini
index b170c8b..2a184b1 100644
--- a/UI/data/locale/ru-RU.ini
+++ b/UI/data/locale/ru-RU.ini
@@ -49,6 +49,26 @@ Right="Справа"
 Top="Сверху"
 Bottom="Снизу"
 Reset="Сбросить"
+Hours="Часов"
+Minutes="Минут"
+Seconds="Секунд"
+Deprecated="Устаревшее"
+ReplayBuffer="Буфер повтора"
+Import="Импорт"
+Export="Экспорт"
+
+Updater.Title="Доступно обновление"
+Updater.Text="Доступно новое обновление:"
+Updater.UpdateNow="Обновить сейчас"
+Updater.RemindMeLater="Напомнить позже"
+Updater.Skip="Пропустить версию"
+Updater.Running.Title="Программа в настоящее время активна"
+Updater.Running.Text="Обнаружена активная операция вывода. Перед обновлением необходимо отключить все активные операции вывода"
+Updater.NoUpdatesAvailable.Title="Нет доступных обновлений"
+Updater.NoUpdatesAvailable.Text="Обновления не обнаружены"
+Updater.FailedToLaunch="Не удалось проверить обновления"
+Updater.GameCaptureActive.Title="Производится захват игры"
+Updater.GameCaptureActive.Text="Библиотека захвата игр уже используется. Закройте захватываемые игры/программы (или перезапустите Windows) и попробуйте ещё раз."
 
 QuickTransitions.SwapScenes="Замена Просмотра/Вывода Сцены После Перехода"
 QuickTransitions.SwapScenesTT="Замена просмотра и вывода сцены после перехода (если выходная оригинальная сцена до сих пор существует).\nЭто будет не отмена каких-либо изменений, что, возможно, было сделано в выходной оригинальной сцены."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Подтвердить удаление"
 ConfirmRemove.Text="Вы уверены, что хотите удалить '$1'?"
 ConfirmRemove.TextMultiple="Вы уверены, что вы хотите удалить %1 элементов?"
 
+Output.StartStreamFailed="Не удалось запустить вещание"
+Output.StartRecordingFailed="Не удалось начать запись"
+Output.StartReplayFailed="Не удалось запустить воспроизведение из буфера"
+Output.StartFailedGeneric="Сбой вывода. Подробности отражены в журнале.\n\nПримечание: Если вы используете кодировщики NVENC или AMD, убедитесь что у вас установлена последняя версия видеорайвера."
+
 Output.ConnectFail.Title="Не удалось подключиться"
 Output.ConnectFail.BadPath="Неверный путь или URL соединения. Пожалуйста, проверьте настройки, чтобы подтвердить, что они являются действительными."
 Output.ConnectFail.ConnectFailed="Не удалось подключиться к серверу"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="Недостаточно места на диске"
 Output.RecordNoSpace.Msg="На диске недостаточно места для продолжения записи."
 Output.RecordError.Title="Ошибка записи"
 Output.RecordError.Msg="Во время записи произошла неопознанная ошибка."
+Output.ReplayBuffer.NoHotkey.Title="Нет набора горячих клавиш!"
+Output.ReplayBuffer.NoHotkey.Msg="Не установлено клавиши для сохранения повтора. Пожалуйста, установите горячую клавишу для сохранения записей повторов."
 
 Output.BadPath.Title="Неправильный путь к файлу"
 Output.BadPath.Text="Некорректный путь к файлу.  Пожалуйста, проверьте настройки, чтобы убедиться в корректности установленного пути."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Верхнее поле первое"
 Deinterlacing.BottomFieldFirst="Нижнее поле первое"
 
+VolControl.SliderUnmuted="Регулятор громкости '%1': %2"
+VolControl.SliderMuted="Регулятор громкости '%1': %2 (сейчас заглушен)"
+VolControl.Mute="Заглушить '%1'"
+VolControl.Properties="Свойства '%1'"
+
 Basic.Main.AddSceneDlg.Title="Добавить сцену"
 Basic.Main.AddSceneDlg.Text="Пожалуйста, введите название сцены"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Сцены"
 Basic.Main.Sources="Источники"
 Basic.Main.Connecting="Соединение..."
 Basic.Main.StartRecording="Начать запись"
+Basic.Main.StartReplayBuffer="Запустить повтор"
 Basic.Main.StartStreaming="Запустить трансляцию"
 Basic.Main.StopRecording="Остановить запись"
 Basic.Main.StoppingRecording="Остановка Записи..."
+Basic.Main.StopReplayBuffer="Остановить повтор"
+Basic.Main.StoppingReplayBuffer="Остановка повтора..."
 Basic.Main.StopStreaming="Остановить трансляцию"
 Basic.Main.StoppingStreaming="Остановка вещания..."
 Basic.Main.ForceStopStreaming="Остановить передачу (отменить задержку)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="&Повторить"
 Basic.MainMenu.Edit.UndoAction="&Отменить $1"
 Basic.MainMenu.Edit.RedoAction="&Повторить $1"
 Basic.MainMenu.Edit.LockPreview="&Заблокировать предпросмотр"
+Basic.MainMenu.Edit.Scale="Просмотр и масштабирование"
+Basic.MainMenu.Edit.Scale.Window="Масштаб окна"
+Basic.MainMenu.Edit.Scale.Canvas="Холст (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Вывод (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Преобразовать"
 Basic.MainMenu.Edit.Transform.EditTransform="&Изменить преобразование..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Копировать преобразование"
+Basic.MainMenu.Edit.Transform.PasteTransform="Вставить преобразование"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Сбросить преобразование"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Повернуть на 90 градусов по часовой"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Повернуть на 90 градусов против часовой"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="&Строка состояния"
 
 Basic.MainMenu.SceneCollection="Коллекция сцен"
 Basic.MainMenu.Profile="Профиль"
+Basic.MainMenu.Profile.Import="Импортировать профиль"
+Basic.MainMenu.Profile.Export="Экспортировать профиль"
+Basic.MainMenu.SceneCollection.Import="Импортировать коллекцию сцен"
+Basic.MainMenu.SceneCollection.Export="Экспортировать коллекцию сцен"
+Basic.MainMenu.Profile.Exists="Профиль уже существует"
+Basic.MainMenu.SceneCollection.Exists="Коллекция сцен уже существует"
 
 Basic.MainMenu.Tools="&Инструменты"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="У вас есть несохраненные измен
 Basic.Settings.General="Общие"
 Basic.Settings.General.Theme="Тема"
 Basic.Settings.General.Language="Язык"
+Basic.Settings.General.EnableAutoUpdates="Проверять наличие обновлений при запуске"
 Basic.Settings.General.WarnBeforeStartingStream="Показывать окно подтверждения при запуске трансляции"
 Basic.Settings.General.WarnBeforeStoppingStream="Показывать окно подтверждения при остановке трансляции"
+Basic.Settings.General.Projectors="Проекторы"
 Basic.Settings.General.HideProjectorCursor="Скрыть курсор за проекторы"
 Basic.Settings.General.ProjectorAlwaysOnTop="Показывать проекторы поверх всего остального"
 Basic.Settings.General.Snapping="Привязка расположения источника"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Привязка к другим исто
 Basic.Settings.General.SnapDistance="Чувствительность привязки"
 Basic.Settings.General.RecordWhenStreaming="Автоматическая запись при стриме"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Продолжить запись, когда стрим остановится"
-Basic.Settings.General.SysTrayEnabled="Показывать иконку в системном трее"
+Basic.Settings.General.ReplayBufferWhileStreaming="Автоматически запускать буфер повтора во время трансляции"
+Basic.Settings.General.KeepReplayBufferStreamStops="Сохранять буфер повтора активным когда останавливается трансляция"
+Basic.Settings.General.SysTray="Системный трей"
 Basic.Settings.General.SysTrayWhenStarted="Скрывать окно в системный трей при запуске"
+Basic.Settings.General.SystemTrayHideMinimize="Всегда сворачивать в трей вместо панели задач"
+Basic.Settings.General.SaveProjectors="Сохранять проекторы при выходе"
 
 Basic.Settings.Stream="Вещание"
 Basic.Settings.Stream.StreamType="Тип вещания"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="Режим вывода"
 Basic.Settings.Output.Mode.Simple="Простой"
 Basic.Settings.Output.Mode.Adv="Расширенные"
 Basic.Settings.Output.Mode.FFmpeg="Вывод FFmpeg"
+Basic.Settings.Output.UseReplayBuffer="Включить Буфер повтора"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Максимальное время повтора (секунд)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Максимальный объем памяти (МБ)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Предполагаемое использование памяти: %1 МБ"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Невозможно оценить использование памяти.  Пожалуйста, установите максимальный объем памяти."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Примечание: Убедитесь, что установили горячую клавишу для воспроизведения буфера в разделе горячие клавиши)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Префикс имени файла повтора"
+Basic.Settings.Output.ReplayBuffer.Suffix="Суффикс"
 Basic.Settings.Output.Simple.SavePath="Путь к записи"
 Basic.Settings.Output.Simple.RecordingQuality="Качество записи"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="То же, что у трансляции"
@@ -391,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Дорожка 1"
 Basic.Settings.Output.Adv.Audio.Track2="Дорожка 2"
 Basic.Settings.Output.Adv.Audio.Track3="Дорожка 3"
 Basic.Settings.Output.Adv.Audio.Track4="Дорожка 4"
+Basic.Settings.Output.Adv.Audio.Track5="Дорожка 5"
+Basic.Settings.Output.Adv.Audio.Track6="Дорожка 6"
 
 Basic.Settings.Output.Adv.Recording="Запись"
 Basic.Settings.Output.Adv.Recording.Type="Тип"
@@ -418,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Настройки кодир
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Кодировщик аудио"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Настройки кодировщика аудио (если есть)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Настройки мультиплексора (если есть)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Интервал ключевых кадров (кадры)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Показать все кодеки (даже потенциально несовместимые)"
 
 FilenameFormatting.completer="%DD-%MM-%CCYY %hh-%mm-%ss\n%DD-%MM-%YY %hh-%mm-%ss\n%d-%m-%Y %H-%M-%S\n%d-%m-%y %H-%M-%S\n%a %d-%m-%Y %H-%M-%S\n%A %d-%m-%Y %H-%M-%S\n%d-%b-%Y %H-%M-%S\n%d-%B-%Y %H-%M-%S"
 
@@ -471,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="Цветовое пространст
 Basic.Settings.Advanced.Video.ColorRange="Цветовой диапазон YUV"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Частичный"
 Basic.Settings.Advanced.Video.ColorRange.Full="Полный"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Устройство прослушивания аудио"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="По умолчанию"
 Basic.Settings.Advanced.StreamDelay="Задержка потока"
 Basic.Settings.Advanced.StreamDelay.Duration="Продолжительность (секунд)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Сохранить точку отсечки (увеличить задержку) при переподключении"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Предполагаемое использование памяти: %1 МБ"
 Basic.Settings.Advanced.Network="Сеть"
 Basic.Settings.Advanced.Network.BindToIP="Привязать к IP"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Включить новый сетевой код"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Режим низкой задержки"
 
 Basic.AdvAudio="Расширенные свойства аудио"
 Basic.AdvAudio.Name="Название"
@@ -484,15 +553,15 @@ Basic.AdvAudio.Volume="Громкость (%)"
 Basic.AdvAudio.Mono="Объединение в один канал"
 Basic.AdvAudio.Panning="Панорамирование"
 Basic.AdvAudio.SyncOffset="Смещение синхронизации (мс)"
+Basic.AdvAudio.Monitoring="Аудио прослушивание"
+Basic.AdvAudio.Monitoring.None="Выключить прослушивание"
+Basic.AdvAudio.Monitoring.MonitorOnly="Только прослушивание (заглушить вывод)"
+Basic.AdvAudio.Monitoring.Both="Прослушивание и вывод"
 Basic.AdvAudio.AudioTracks="Дорожки"
 
 Basic.Settings.Hotkeys="Горячие клавиши"
 Basic.Settings.Hotkeys.Pair="Сочетания клавиш вместе с '%1' действуют как переключатели"
 
-Basic.Hotkeys.StartStreaming="Запустить трансляцию"
-Basic.Hotkeys.StopStreaming="Остановить трансляцию"
-Basic.Hotkeys.StartRecording="Начать запись"
-Basic.Hotkeys.StopRecording="Остановить запись"
 Basic.Hotkeys.SelectScene="Перейти на сцену"
 
 Basic.SystemTray.Show="Показать"
@@ -546,4 +615,5 @@ SceneItemHide="Скрыть '%1'"
 
 OutputWarnings.NoTracksSelected="Вы должны выбрать хотя бы одну звуковую дорожку"
 OutputWarnings.MultiTrackRecording="Предупреждение: Некоторые форматы (такие как FLV) не поддерживают множественные звуковые дорожки"
+OutputWarnings.MP4Recording="Внимание: Записи, сохраненные в MP4 будут нечитаемы, если файл не будет завершен (например, в результате BSOD'а, потери напряжения в сети и т.д.). Если вы хотите записывать несколько аудио дорожек, рассмотрите использование MKV, и последующее ремультиплексирование в MP4 после завершения записи (Файл -> Ремультиплексирование записей)"
 
diff --git a/UI/data/locale/sk-SK.ini b/UI/data/locale/sk-SK.ini
index bec05a6..4b292f0 100644
--- a/UI/data/locale/sk-SK.ini
+++ b/UI/data/locale/sk-SK.ini
@@ -8,16 +8,19 @@ Cancel="Zrušiť"
 Close="Zatvoriť"
 Save="Uložiť"
 Discard="Zahodiť"
+Disable="Zakázané"
 Yes="Áno"
 No="Nie"
 Add="Pridať"
 Remove="Odobrať"
 Rename="Premenovať"
+Filters="Filtre"
 Properties="Vlastnosti"
 MoveUp="Posunúť vyššie"
 MoveDown="Posunúť nižšie"
 Settings="Nastavenia"
 Display="Monitor"
+Name="Meno"
 Exit="Ukončiť"
 Mixer="Zmiešavač"
 Browse="Prehľadávať"
@@ -32,8 +35,22 @@ Untitled="Bez názvu"
 New="Nový"
 Duplicate="Duplikovať"
 Enable="Povoliť"
+Transition="Prechod"
+QuickTransitions="Rýchle prechody"
+Left="Vľavo"
+Right="Vpravo"
+Top="Hore"
+Bottom="Dole"
+Reset="Vynulovať"
+Hours="Hodín"
+Minutes="Minúty"
+Seconds="Sekundy"
 
 
+QuickTransitions.DuplicateScene="Duplikovať scénu"
+
+Basic.TransitionDuration="Trvanie"
+Basic.TogglePreviewProgramMode="Štúdiový režim"
 
 
 TitleBar.Profile="Profil"
@@ -45,7 +62,11 @@ NameExists.Text="Tento názov sa už používa."
 NoNameEntered.Title="Prosím, zadajte platný názov"
 NoNameEntered.Text="Nemôžete použiť prázdne názvy."
 
+ConfirmStart.Title="Spustiť stream?"
+ConfirmStart.Text="Naozaj chcete spustiť stream?"
 
+ConfirmStop.Title="Zastaviť stream?"
+ConfirmStop.Text="Naozaj chcete zastaviť stream?"
 
 ConfirmExit.Title="Ukončiť OBS?"
 ConfirmExit.Text="OBS je momentálne aktívny.  Všetky prúdy údajov/záznamy sa ukončia.  Naozaj pokračovať?"
@@ -53,10 +74,14 @@ ConfirmExit.Text="OBS je momentálne aktívny.  Všetky prúdy údajov/záznamy
 ConfirmRemove.Title="Potvrdenie odobratia"
 ConfirmRemove.Text="Naozaj si prajete odobrať '$1'?"
 
+
 Output.ConnectFail.Title="Spojenie sa nepodarilo"
 Output.ConnectFail.BadPath="Neplatná cesta alebo URL. Prosím, skontrolujte, či sú vaše nastavenia správne."
 Output.ConnectFail.ConnectFailed="Spojenie so serverom sa nepodarilo"
 
+Output.RecordFail.Title="Nepodarilo sa spustiť nahrávanie"
+Output.RecordNoSpace.Title="Nedostatok miesta na disku"
+Output.RecordError.Title="Chyba nahrávania"
 
 Output.BadPath.Title="Nesprávna cesta k súboru"
 
@@ -68,6 +93,7 @@ LicenseAgreement.Exit="Ukončiť"
 
 Remux.SourceFile="OBS nahrávka"
 Remux.TargetFile="Cieľový súbor"
+Remux.OBSRecording="OBS nahrávanie"
 Remux.SelectRecording="Vybrať OBS nahrávku …"
 Remux.SelectTarget="Vyberte cieľový súbor …"
 Remux.FileExistsTitle="Cieľový súbor existuje"
@@ -83,6 +109,7 @@ Basic.DisplayCapture="Zachytávanie monitora"
 
 
 
+
 Basic.Main.AddSceneDlg.Title="Pridať scénu"
 Basic.Main.AddSceneDlg.Text="Prosím, zadajte názov scény"
 
@@ -176,7 +203,9 @@ Basic.MainMenu.Edit.Order.MoveToTop="Premies&tniť navrch"
 Basic.MainMenu.Edit.Order.MoveToBottom="Premiestniť naspodok (&B)"
 
 
+Basic.MainMenu.Profile="&Profil"
 
+Basic.MainMenu.Tools="Nás&troje"
 
 Basic.MainMenu.Help="Pomoc (&H)"
 Basic.MainMenu.Help.Logs="&Log súbory"
@@ -188,12 +217,15 @@ Basic.Settings.ConfirmTitle="Potvrdenie zmien"
 Basic.Settings.Confirm="Máte neuložené zmeny. Chcete uložiť zmeny?"
 
 Basic.Settings.General="Všeobecné"
+Basic.Settings.General.Theme="Vzhľad"
+Basic.Settings.General.Language="Jazyk"
 
 Basic.Settings.Stream="Stream"
 Basic.Settings.Stream.StreamType="Typ streamu"
 
 Basic.Settings.Output="Výstup"
 Basic.Settings.Output.Mode="Režim výstupu"
+Basic.Settings.Output.Mode.Simple="Jednoduchý"
 Basic.Settings.Output.VideoBitrate="Bitrate videa"
 Basic.Settings.Output.AudioBitrate="Bitrate zvuku"
 Basic.Settings.Output.Reconnect="Automaticky znovupripájať"
@@ -201,7 +233,12 @@ Basic.Settings.Output.RetryDelay="ÄŒas medzi pokusmi (sekundy)"
 Basic.Settings.Output.MaxRetries="Maximálny počet pokusov"
 Basic.Settings.Output.Advanced="Povoliť pokročilé nastavenia enkodéra"
 
+Basic.Settings.Output.Adv.Audio.Track1="Stopa 1"
+Basic.Settings.Output.Adv.Audio.Track2="Stopa 2"
+Basic.Settings.Output.Adv.Audio.Track3="Stopa 3"
+Basic.Settings.Output.Adv.Audio.Track4="Stopa 4"
 
+Basic.Settings.Output.Adv.Recording.Type="Typ"
 
 
 
diff --git a/UI/data/locale/sl-SI.ini b/UI/data/locale/sl-SI.ini
index 780c52f..ac0a831 100644
--- a/UI/data/locale/sl-SI.ini
+++ b/UI/data/locale/sl-SI.ini
@@ -31,6 +31,7 @@ DroppedFrames="Izpuščene sličice %1 (%2 %)"
 
 
 
+
 NameExists.Title="Ime že obstaja"
 NameExists.Text="Ime je že v uporabi."
 
@@ -44,6 +45,7 @@ ConfirmExit.Title="Zapusti OBS?"
 ConfirmRemove.Title="Potrdite odstranitev"
 ConfirmRemove.Text="Ali ste prepričani, da želite odstraniti '$ 1'?"
 
+
 Output.ConnectFail.Title="Povezava ni uspela"
 Output.ConnectFail.BadPath="Neveljavna pot ali URL povezava. Prosimo, preverite vaše nastavitve za potrditev, da so veljavne."
 Output.ConnectFail.ConnectFailed="Ni uspelo povezati s strežnikom"
@@ -81,6 +83,7 @@ Basic.DisplayCapture="Zajemanje zaslona"
 
 
 
+
 Basic.Main.AddSceneDlg.Title="Dodaj seceno"
 Basic.Main.AddSceneDlg.Text="Prosimo, vnesite ime scene"
 
diff --git a/UI/data/locale/sr-CS.ini b/UI/data/locale/sr-CS.ini
index 2097d04..cc86301 100644
--- a/UI/data/locale/sr-CS.ini
+++ b/UI/data/locale/sr-CS.ini
@@ -48,6 +48,12 @@ Left="Sleva"
 Right="Zdesna"
 Top="Odozgo"
 Bottom="Odozdo"
+Reset="Poništi"
+Hours="Sati"
+Minutes="Minuta"
+Seconds="Sekundi"
+Deprecated="Prevaziđeno"
+
 
 QuickTransitions.SwapScenes="Zameni scene pregleda/izlaza nakon prelaza"
 QuickTransitions.SwapScenesTT="Zamenjuje scene pregleda i izlaza nakon prelaza (ako originalna scena izlaza još uvek postoji).\nOvo neće poništiti promene koje su načinjene nad originalnom scenom izlaza."
@@ -89,6 +95,7 @@ ConfirmRemove.Title="Potvrdi izbacivanje"
 ConfirmRemove.Text="Da li ste sigurni da želite izbaciti '$1'?"
 ConfirmRemove.TextMultiple="Da li ste sigurni da želite izbaciti %1 stavke?"
 
+
 Output.ConnectFail.Title="Neuspešno povezivanje"
 Output.ConnectFail.BadPath="Neispravna putanja ili URL konekcije. Molim proverite vaša podešavanja da potvrdite njihovu ispravnost."
 Output.ConnectFail.ConnectFailed="Neuspešno povezivanje na server"
@@ -163,6 +170,7 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Prvo gornje polje"
 Deinterlacing.BottomFieldFirst="Prvo donje polje"
 
+
 Basic.Main.AddSceneDlg.Title="Dodaj scenu"
 Basic.Main.AddSceneDlg.Text="Molim unesite ime scene"
 
@@ -281,6 +289,10 @@ Basic.MainMenu.Edit.Redo="U&radi ponovo"
 Basic.MainMenu.Edit.UndoAction="Vrati $1 (&U)"
 Basic.MainMenu.Edit.RedoAction="U&radi ponovo $1"
 Basic.MainMenu.Edit.LockPreview="Zak&ljučaj prikaz"
+Basic.MainMenu.Edit.Scale="Pregled &skaliranja"
+Basic.MainMenu.Edit.Scale.Window="Skaliraj na veličinu prozora"
+Basic.MainMenu.Edit.Scale.Canvas="Platno (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Izlaz (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Transformiši"
 Basic.MainMenu.Edit.Transform.EditTransform="Izm&eni transformaciju..."
 Basic.MainMenu.Edit.Transform.ResetTransform="Poništi t&ransformaciju"
@@ -337,7 +349,6 @@ Basic.Settings.General.SourceSnapping="Privlačenje izvora ka drugim izvorima"
 Basic.Settings.General.SnapDistance="Osetljivost privlačenja"
 Basic.Settings.General.RecordWhenStreaming="Automatsko snimanje pri emitovanju"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Nastavi snimati kada se emitovanje zaustavi"
-Basic.Settings.General.SysTrayEnabled="Omogući ikonicu u sistemskom panelu"
 Basic.Settings.General.SysTrayWhenStarted="Pri pokretanju minimiziraj na ikonicu u sistemskom panelu"
 
 Basic.Settings.Stream="Strim"
@@ -368,6 +379,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Upozorenje za kvalitet bez gub
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Upozorenje: Ne možete koristi više odvojenih QSV enkodera kada emitujete i snimate u isto vreme. Ako želite da emitujete i snimate u isto vreme, molim promenite ili enkoder snimanja ili enkoder emitovanja."
 Basic.Settings.Output.Simple.Encoder.Software="Softverski (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Mašinski (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Mašinski (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Mašinski (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softverski (x264 niska upotreba procesora, povećava veličinu datoteke)"
 Basic.Settings.Output.VideoBitrate="Protok videa"
@@ -487,10 +499,6 @@ Basic.AdvAudio.AudioTracks="Izvori"
 Basic.Settings.Hotkeys="Prečice"
 Basic.Settings.Hotkeys.Pair="Kombinacije tastera deljene sa '%1' se ponašaju kao prekidači"
 
-Basic.Hotkeys.StartStreaming="Započni strimovanje"
-Basic.Hotkeys.StopStreaming="Zaustavi strimovanje"
-Basic.Hotkeys.StartRecording="Počni snimanje"
-Basic.Hotkeys.StopRecording="Zaustavi snimanje"
 Basic.Hotkeys.SelectScene="Prebaci na scenu"
 
 Basic.SystemTray.Show="Prikaži"
diff --git a/UI/data/locale/sr-SP.ini b/UI/data/locale/sr-SP.ini
index a9c5a44..f76cb37 100644
--- a/UI/data/locale/sr-SP.ini
+++ b/UI/data/locale/sr-SP.ini
@@ -48,6 +48,12 @@ Left="Слева"
 Right="Здесна"
 Top="Одозго"
 Bottom="Одоздо"
+Reset="Поништи"
+Hours="Сати"
+Minutes="Минута"
+Seconds="Секунди"
+Deprecated="Превазиђено"
+
 
 QuickTransitions.SwapScenes="Замени сцене прегледа/излаза након прелаза"
 QuickTransitions.SwapScenesTT="Замењује сцене прегледа и излаза након прелаза (ако оригинална сцена још увек постоји).\nОво неће поништити промене које су начињене над оригиналном сценом излаза."
@@ -89,6 +95,7 @@ ConfirmRemove.Title="Потврди избацивање"
 ConfirmRemove.Text="Да ли сте сигурни да желите избацити '$1'?"
 ConfirmRemove.TextMultiple="Да ли сте сигурни да желите избацити %1 ставке?"
 
+
 Output.ConnectFail.Title="Неуспешно повезивање"
 Output.ConnectFail.BadPath="Неисправна путања или URL конекције. Молим проверите ваша подешавања да потврдите њихову исправност."
 Output.ConnectFail.ConnectFailed="Неуспешно повезивање на сервер"
@@ -163,6 +170,7 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Прво горње поље"
 Deinterlacing.BottomFieldFirst="Прво доње поље"
 
+
 Basic.Main.AddSceneDlg.Title="Додај сцену"
 Basic.Main.AddSceneDlg.Text="Молим унесите име сцене"
 
@@ -281,6 +289,10 @@ Basic.MainMenu.Edit.Redo="Уради поново (&R)"
 Basic.MainMenu.Edit.UndoAction="Врати $1 (&U)"
 Basic.MainMenu.Edit.RedoAction="Уради поново $1 (&R)"
 Basic.MainMenu.Edit.LockPreview="Закључај приказ (&L)"
+Basic.MainMenu.Edit.Scale="Преглед скалирања (&s)"
+Basic.MainMenu.Edit.Scale.Window="Скалирај на величину прозора"
+Basic.MainMenu.Edit.Scale.Canvas="Платно (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Излаз (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Трансформиши"
 Basic.MainMenu.Edit.Transform.EditTransform="Изм&ени трансформацију..."
 Basic.MainMenu.Edit.Transform.ResetTransform="Поништи трансформацију (&R)"
@@ -337,7 +349,6 @@ Basic.Settings.General.SourceSnapping="Привлачење извора ка д
 Basic.Settings.General.SnapDistance="Осетљивост привлачења"
 Basic.Settings.General.RecordWhenStreaming="Аутоматско снимање при емитовању"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Настави снимати када се емитовање заустави"
-Basic.Settings.General.SysTrayEnabled="Омогући иконицу у системском панелу"
 Basic.Settings.General.SysTrayWhenStarted="При покретању минимизирај на иконицу у системском панелу"
 
 Basic.Settings.Stream="Стрим"
@@ -368,6 +379,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Упозорење за ква
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Упозорење: Не можете користити више одвојених QSV енкодера када емитујете и снимате у исто време. Ако желите да емитујете и снимате у исто време, молим промените или енкодер снимања или енкодер емитовања."
 Basic.Settings.Output.Simple.Encoder.Software="Софтверски (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Машински (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Машински (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Машински (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Софтверски (x264 ниска употреба процесора, повећава величину датотеке)"
 Basic.Settings.Output.VideoBitrate="Проток видеа"
@@ -487,10 +499,6 @@ Basic.AdvAudio.AudioTracks="Извори"
 Basic.Settings.Hotkeys="Пречице"
 Basic.Settings.Hotkeys.Pair="Комбинације тастера дељене са '%1' се понашају као прекидачи"
 
-Basic.Hotkeys.StartStreaming="Почни стримовање"
-Basic.Hotkeys.StopStreaming="Заустави стримовање"
-Basic.Hotkeys.StartRecording="Почни снимање"
-Basic.Hotkeys.StopRecording="Заустави снимање"
 Basic.Hotkeys.SelectScene="Пребаци на сцену"
 
 Basic.SystemTray.Show="Прикажи"
diff --git a/UI/data/locale/sv-SE.ini b/UI/data/locale/sv-SE.ini
index 81c34c1..c18a4ae 100644
--- a/UI/data/locale/sv-SE.ini
+++ b/UI/data/locale/sv-SE.ini
@@ -28,9 +28,9 @@ Browse="Bläddra"
 Mono="Mono"
 Stereo="Stereo"
 DroppedFrames="Tappade bildrutor %1 (%2%)"
-PreviewProjector="Fullskärm projektor (Förhandsvisa)"
-SceneProjector="Fullskärm projektor (scen)"
-SourceProjector="Fullskärm projektor (källa)"
+PreviewProjector="Fullskärmsprojektor (förhandsvisning)"
+SceneProjector="Fullskärmsprojektor (scen)"
+SourceProjector="Fullskärmsprojektor (källa)"
 Clear="Rensa"
 Revert="Återgå"
 Show="Visa"
@@ -49,11 +49,33 @@ Right="Höger"
 Top="Överkant"
 Bottom="Nederkant"
 Reset="Återställ"
+Hours="timmar"
+Minutes="minuter"
+Seconds="sekunder"
+Deprecated="Föråldrat"
+ReplayBuffer="Reprisbuffert"
+Import="Importera"
+Export="Exportera"
+
+Updater.Title="Ny uppdatering tillgänglig"
+Updater.Text="Det finns en ny uppdatering tillgänglig:"
+Updater.UpdateNow="Uppdatera nu"
+Updater.RemindMeLater="PÃ¥minn mig senare"
+Updater.Skip="Hoppa över version"
+Updater.Running.Title="Programmet körs för tillfället"
+Updater.Running.Text="Utmatningar pågår för tillfället, stäng ned alla aktiva utmatningar innan du uppdaterar"
+Updater.NoUpdatesAvailable.Title="Inga tillgängliga uppdateringar"
+Updater.NoUpdatesAvailable.Text="Inga uppdateringar är tillgängliga för närvarande"
+Updater.FailedToLaunch="Misslyckades att starta uppdateringen"
+Updater.GameCaptureActive.Title="Spelkälla aktiv"
+Updater.GameCaptureActive.Text="Hook-biblioteket för spelkällor används för tillfället. Stäng alla spel/program som spelas in (eller starta om Windows) och försök igen."
 
 QuickTransitions.SwapScenes="Byt plats på Förhandsvisnings-/utdatascenerna efter skifte"
 QuickTransitions.SwapScenesTT="Byter plats på förhandsvisnings- och utdatascenerna efter övergång (om utdatans originalscen fortfarande finns). \nDet här kommer inte att ångra några förändringar i utdatans originalscen."
 QuickTransitions.DuplicateScene="Duplicera scen"
-QuickTransitions.EditProperties="Duplicera källa"
+QuickTransitions.DuplicateSceneTT="När du redigerar samma scen kan du redigera transformering/synligheten för källor utan att modifiera utmatningen.\nFör att redigera egenskaper för källor utan att modifiera utmatningen aktiverar du 'Duplicera källor'.\nNär detta värde ändras kommer den aktuella utmatningsscenen återställas (om den fortfarande finns)."
+QuickTransitions.EditProperties="Duplicera källor"
+QuickTransitions.EditPropertiesTT="När du redigerar samma scen kan du redigera egenskaperna för källor utan att modifiera utmatningen.\nDetta fungerar endast om 'Duplicera scen' är aktiverad.\nVissa källor (som mediakällor) stöder inte detta och kan inte redigeras separat.\nNär detta värde ändras kommer den aktuella utmatningsscenen återställas (om den fortfarande finns).\n\nVarning: Eftersom källor kommer att dupliceras kan detta kräva extra system- eller videoresurser."
 QuickTransitions.HotkeyName="Snabba övergång: %1"
 
 Basic.AddTransition="Lägg till konfigurerbar övergång"
@@ -88,6 +110,11 @@ ConfirmRemove.Title="Bekräfta borttagning"
 ConfirmRemove.Text="Vill du verkligen ta bort '$1'?"
 ConfirmRemove.TextMultiple="Är du säker på att du vill ta bort %1 poster?"
 
+Output.StartStreamFailed="Misslyckades att starta strömning"
+Output.StartRecordingFailed="Misslyckades att starta inspelning"
+Output.StartReplayFailed="Misslyckades att starta reprisbuffert"
+Output.StartFailedGeneric="Misslyckades att starta utmatningen.  Kolla loggen för detaljer.\n\nOBS: Om du använder kodarna NVENC eller AMD, se till att dina grafikdrivrutiner är uppdaterade."
+
 Output.ConnectFail.Title="Anslutning misslyckades"
 Output.ConnectFail.BadPath="Ogiltig sökväg eller anslutnings-URL. Kontrollera att dina inställningar är korrekta."
 Output.ConnectFail.ConnectFailed="Kunde inte ansluta till servern"
@@ -101,6 +128,8 @@ Output.RecordNoSpace.Title="Otillräckligt diskutrymme"
 Output.RecordNoSpace.Msg="Det finns inte tillräckligt med diskutrymme för att fortsätta inspelningen."
 Output.RecordError.Title="Inspelningsfel"
 Output.RecordError.Msg="Ett okänt fel uppstod vid inspelning."
+Output.ReplayBuffer.NoHotkey.Title="Ingen angivet kortkommando!"
+Output.ReplayBuffer.NoHotkey.Msg="Inget kortkommando för att spara reprisbufferten har angivits. Ange kortkommandot \"Spara\" för att kunna spara reprisinspelningar."
 
 Output.BadPath.Title="Ogiltig sökväg"
 Output.BadPath.Text="Den angivna sökvägen för utmatningsfil är ogiltig. Kontrollera att dina inställningar är korrekta och att en giltig sökväg har angetts."
@@ -142,7 +171,7 @@ Basic.AuxDevice4="Mic/Aux 4"
 Basic.Scene="Scen"
 Basic.DisplayCapture="Bildskärmskälla"
 
-Basic.Main.PreviewConextMenu.Enable="Förhandsvisa"
+Basic.Main.PreviewConextMenu.Enable="Aktivera förhandsvisning"
 
 ScaleFiltering="Skalningsfiltrering"
 ScaleFiltering.Point="Punkt"
@@ -162,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Övre fältet först"
 Deinterlacing.BottomFieldFirst="Nedre fältet först"
 
+VolControl.SliderUnmuted="Volymreglage för \"%1\": %2"
+VolControl.SliderMuted="Volymreglage för \"%1\": %2 (tyst för tillfället)"
+VolControl.Mute="Tysta \"%1\""
+VolControl.Properties="Egenskaper för \"%1\""
+
 Basic.Main.AddSceneDlg.Title="Lägg till scen"
 Basic.Main.AddSceneDlg.Text="Vänligen ange ett namn för scenen"
 
@@ -256,9 +290,12 @@ Basic.Main.Scenes="Scener"
 Basic.Main.Sources="Källor"
 Basic.Main.Connecting="Ansluter..."
 Basic.Main.StartRecording="Starta inspelning"
+Basic.Main.StartReplayBuffer="Starta reprisbuffert"
 Basic.Main.StartStreaming="Börja strömma"
 Basic.Main.StopRecording="Stoppa inspelning"
 Basic.Main.StoppingRecording="Stoppar inspelning..."
+Basic.Main.StopReplayBuffer="Stoppa reprisbuffert"
+Basic.Main.StoppingReplayBuffer="Stoppar reprisbuffert..."
 Basic.Main.StopStreaming="Sluta strömma"
 Basic.Main.StoppingStreaming="Stoppar ström..."
 Basic.Main.ForceStopStreaming="Sluta strömma (ignorera fördröjning)"
@@ -267,7 +304,7 @@ Basic.MainMenu.File="&Arkiv"
 Basic.MainMenu.File.Export="&Exportera"
 Basic.MainMenu.File.Import="&Importera"
 Basic.MainMenu.File.ShowRecordings="Visa &inspelningar"
-Basic.MainMenu.File.Remux="Re&mux Inspelningar"
+Basic.MainMenu.File.Remux="Re&muxa inspelningar"
 Basic.MainMenu.File.Settings="&Inställningar"
 Basic.MainMenu.File.ShowSettingsFolder="Visa inställningsmapp"
 Basic.MainMenu.File.ShowProfileFolder="Visa profilmapp"
@@ -280,8 +317,14 @@ Basic.MainMenu.Edit.Redo="&Gör om"
 Basic.MainMenu.Edit.UndoAction="&Ã…ngra $1"
 Basic.MainMenu.Edit.RedoAction="&Gör om $1"
 Basic.MainMenu.Edit.LockPreview="&Lås förhandsvisning"
+Basic.MainMenu.Edit.Scale="Förhandsvisa &skalning"
+Basic.MainMenu.Edit.Scale.Window="Skala till fönster"
+Basic.MainMenu.Edit.Scale.Canvas="Kanvas (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Utmatning (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Omvandla"
 Basic.MainMenu.Edit.Transform.EditTransform="&Redigera omvandling..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Kopiera transformering"
+Basic.MainMenu.Edit.Transform.PasteTransform="Klistra in transformering"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Återställ omvandling"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Rotera 90 grader medsols &>"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotera 90 grader motsols &<"
@@ -306,6 +349,12 @@ Basic.MainMenu.View.StatusBar="&Statusfält"
 
 Basic.MainMenu.SceneCollection="&Scensamling"
 Basic.MainMenu.Profile="&Profil"
+Basic.MainMenu.Profile.Import="Importera profil"
+Basic.MainMenu.Profile.Export="Exportera profil"
+Basic.MainMenu.SceneCollection.Import="Importera scensamling"
+Basic.MainMenu.SceneCollection.Export="Exportera scensamling"
+Basic.MainMenu.Profile.Exists="Profilen finns redan"
+Basic.MainMenu.SceneCollection.Exists="Scensamlingen finns redan"
 
 Basic.MainMenu.Tools="&Verktyg"
 
@@ -325,8 +374,10 @@ Basic.Settings.Confirm="Du har osparade ändringar. Vill du spara ändringarna?"
 Basic.Settings.General="Allmänt"
 Basic.Settings.General.Theme=" Tema"
 Basic.Settings.General.Language="Språk"
+Basic.Settings.General.EnableAutoUpdates="Sök efter uppdateringar automatiskt vid start"
 Basic.Settings.General.WarnBeforeStartingStream="Visa bekräftelsedialog när ström startas"
 Basic.Settings.General.WarnBeforeStoppingStream="Visa bekräftelsedialog när ström stoppas"
+Basic.Settings.General.Projectors="Projektorer"
 Basic.Settings.General.HideProjectorCursor="Dölj pekaren över projektorer"
 Basic.Settings.General.ProjectorAlwaysOnTop="Lägg alltid projektorer överst"
 Basic.Settings.General.Snapping="Fäst justerbara källor"
@@ -336,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Fäst källor till andra källor"
 Basic.Settings.General.SnapDistance="Fästkänslighet"
 Basic.Settings.General.RecordWhenStreaming="Spela automatiskt in vid strömning"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Fortsätt spela in när strömmen stoppas"
-Basic.Settings.General.SysTrayEnabled="Aktivera ikon i meddelandefältet"
+Basic.Settings.General.ReplayBufferWhileStreaming="Starta reprisbufferten automatiskt vid strömning"
+Basic.Settings.General.KeepReplayBufferStreamStops="Håll reprisbufferten aktiv när ström stoppas"
+Basic.Settings.General.SysTray="Systemfält"
 Basic.Settings.General.SysTrayWhenStarted="Minimera till meddelandefältet vid start"
+Basic.Settings.General.SystemTrayHideMinimize="Minimera alltid till meddelandefältet i stället för aktivitetsfältet"
+Basic.Settings.General.SaveProjectors="Spara projektorer vid avslut"
 
 Basic.Settings.Stream="Ström"
 Basic.Settings.Stream.StreamType="Strömtyp"
@@ -352,6 +407,14 @@ Basic.Settings.Output.Mode="Utmatningsläge"
 Basic.Settings.Output.Mode.Simple="Simpel"
 Basic.Settings.Output.Mode.Adv="Avancerat"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg-utmatning"
+Basic.Settings.Output.UseReplayBuffer="Aktivera reprisbuffert"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximal repristid (sekunder)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximalt minne (Megabyte)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Uppskattad minnesanvändning: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Kan inte uppskatta minnesanvändningen. Ange maximal minnesgräns."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(OBS: Se till att ange ett kortkommando för reprisbufferten i avsnittet för kortkommandon)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Filnamnsprefix för reprisbuffert"
+Basic.Settings.Output.ReplayBuffer.Suffix="Suffix"
 Basic.Settings.Output.Simple.SavePath="Inspelningssökväg"
 Basic.Settings.Output.Simple.RecordingQuality="Inspelningskvalitet"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Samma som ström"
@@ -367,6 +430,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Varning angående förlustfri
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Varning: Du kan inte använda flera separata QSV-kodare när du streamar och spelar in samtidigt. Om du vill streama och spela in samtidigt, vänligen ändra inspelnings-kodek eller streaming-kodek."
 Basic.Settings.Output.Simple.Encoder.Software="Programvara (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="HÃ¥rdvara (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="HÃ¥rdvara (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="HÃ¥rdvara (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Mjukvaru-kodek (x264-förinställning för lågt CPU-användning, ökar filstorleken)"
 Basic.Settings.Output.VideoBitrate="Bithastighet för video"
@@ -388,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Spår 1"
 Basic.Settings.Output.Adv.Audio.Track2="Spår 2"
 Basic.Settings.Output.Adv.Audio.Track3="Spår 3"
 Basic.Settings.Output.Adv.Audio.Track4="Spår 4"
+Basic.Settings.Output.Adv.Audio.Track5="Spår 5"
+Basic.Settings.Output.Adv.Audio.Track6="Spår 6"
 
 Basic.Settings.Output.Adv.Recording="Inspelning"
 Basic.Settings.Output.Adv.Recording.Type="Typ"
@@ -415,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Videokodar-inställningar (om
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Ljudkodare"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Ljudkodar-inställningar (om något)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxerinställningar (om det finns)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Intervall för keyframes (bildrutor)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Visa alla kodekar (även de som eventuellt inte är kompatibla)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -468,11 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV-färgrymd"
 Basic.Settings.Advanced.Video.ColorRange="YUV färgområde"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Partiell"
 Basic.Settings.Advanced.Video.ColorRange.Full="Full"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Ljuduppspelningsenhet"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standard"
 Basic.Settings.Advanced.StreamDelay="Strömfördröjning"
 Basic.Settings.Advanced.StreamDelay.Duration="Varaktighet (sekunder)"
+Basic.Settings.Advanced.StreamDelay.Preserve="Behåll stoppunkten (öka fördröjningen) vid återanslutning"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Uppskattad minnesanvändning: %1 MB"
 Basic.Settings.Advanced.Network="Nätverk"
 Basic.Settings.Advanced.Network.BindToIP="Bind till IP"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Aktivera ny nätverkskod"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Låg latens-läge"
 
 Basic.AdvAudio="Avancerade ljudinställningar"
 Basic.AdvAudio.Name="Namn"
@@ -480,14 +553,14 @@ Basic.AdvAudio.Volume="Volym (%)"
 Basic.AdvAudio.Mono="Nedmixa till mono"
 Basic.AdvAudio.Panning="Panorering"
 Basic.AdvAudio.SyncOffset="Sync Offset (ms)"
+Basic.AdvAudio.Monitoring="Ljuduppspelning"
+Basic.AdvAudio.Monitoring.None="Monitor av"
+Basic.AdvAudio.Monitoring.Both="Monitor och utgång"
 Basic.AdvAudio.AudioTracks="Spår"
 
 Basic.Settings.Hotkeys="Kortkommandon"
+Basic.Settings.Hotkeys.Pair="Tangentkombinationer som delas med \"%1\" fungerar som strömbrytare"
 
-Basic.Hotkeys.StartStreaming="Börja strömma"
-Basic.Hotkeys.StopStreaming="Sluta strömma"
-Basic.Hotkeys.StartRecording="Starta inspelning"
-Basic.Hotkeys.StopRecording="Stoppa inspelning"
 Basic.Hotkeys.SelectScene="Byt till scen"
 
 Basic.SystemTray.Show="Visa"
@@ -541,4 +614,5 @@ SceneItemHide="Dölj '%1'"
 
 OutputWarnings.NoTracksSelected="Du måste välja minst ett spår"
 OutputWarnings.MultiTrackRecording="Varning: En del format (t.ex. FLV) stöder inte flera spår för varje inspelning"
+OutputWarnings.MP4Recording="Varning: Inspelningar som sparas som MP4 kommer inte att kunna återställas om filen inte kan slutföras (d.v.s. om en datorkrasch, strömavbrott, etc. skulle inträffa). Om du vill spela in flera ljudspår, överväg att använda MKV och remuxa inspelningen till mp4 när den är färdig (Arkiv->Remuxa inspelningar)"
 
diff --git a/UI/data/locale/ta-IN.ini b/UI/data/locale/ta-IN.ini
index c79b30b..8a8cce8 100644
--- a/UI/data/locale/ta-IN.ini
+++ b/UI/data/locale/ta-IN.ini
@@ -92,3 +92,6 @@ New="புதிய"
 
 
 
+
+
+
diff --git a/UI/data/locale/th-TH.ini b/UI/data/locale/th-TH.ini
index 0509a7c..0d149d4 100644
--- a/UI/data/locale/th-TH.ini
+++ b/UI/data/locale/th-TH.ini
@@ -5,19 +5,35 @@ Region="ประเทศไทย"
 OK="ตกลง"
 Apply="นำไปใช้"
 Cancel="ยกเลิก"
+Close="ปิด"
+Save="บันทึก"
+Discard="ละทิ้ง"
+Disable="ไม่ใช้"
 Yes="ใช่"
 No="ไม่"
 Add="เพิ่ม"
 Remove="ลบ"
 Rename="เปลี่ยนชื่อ"
+Filters="ฟิลเตอร์"
 Properties="คุณสมบัติ"
 MoveUp="เลื่อนขึ้น"
 MoveDown="เลื่อนลง"
 Settings="ตั้งค่า"
+Display="แสดงผล"
+Name="ชื่อ"
 Exit="ออก"
 Browse="เปิดหา"
 Mono="โมโน"
 Stereo="สเตอริโอ"
+PreviewProjector="แสดงผลแบบเต็มจอ (ตัวอย่าง)"
+Clear="ล้าง"
+Revert="กลับค่าเดิม"
+Show="แสดง"
+Hide="ซ่อน"
+Untitled="ไม่มีชื่อ"
+New="ใหม่"
+Enable="เปิดใช้งาน"
+
 
 
 
@@ -31,6 +47,7 @@ Stereo="สเตอริโอ"
 ConfirmRemove.Title="ยืนยันการลบ"
 ConfirmRemove.Text="คุณแน่ใจแล้วหรือที่จะลบ '$1'?"
 
+
 Output.ConnectFail.Title="ไม่สามารถเชื่อมต่อได้"
 Output.ConnectFail.ConnectFailed="ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์"
 Output.ConnectFail.Disconnected="ถูกตัดออกจากเซิร์ฟเวอร์"
@@ -51,6 +68,7 @@ Basic.Scene="ฉาก"
 
 
 
+
 Basic.Main.AddSceneDlg.Title="เพิ่มฉาก"
 
 Basic.Main.DefaultSceneName.Text="ฉาก %1"
diff --git a/UI/data/locale/tr-TR.ini b/UI/data/locale/tr-TR.ini
index e7c88e4..c33cad1 100644
--- a/UI/data/locale/tr-TR.ini
+++ b/UI/data/locale/tr-TR.ini
@@ -8,7 +8,7 @@ Cancel="Ä°ptal"
 Close="Kapat"
 Save="Kaydet"
 Discard="Vazgeç"
-Disable="Devre dışı bırak"
+Disable="Devre Dışı Bırak"
 Yes="Evet"
 No="Hayır"
 Add="Ekle"
@@ -20,7 +20,7 @@ Properties="Özellikler"
 MoveUp="Yukarı Taşı"
 MoveDown="Aşağı Taşı"
 Settings="Ayarlar"
-Display="Görüntüle"
+Display="Ekran"
 Name="Ä°sim"
 Exit="Çık"
 Mixer="Karıştırıcı"
@@ -39,34 +39,80 @@ Untitled="Ä°simsiz"
 New="Yeni"
 Duplicate="Çoğalt"
 Enable="EtkinleÅŸtir"
-DisableOSXVSync="OSX V-Sync Devre Dışı Bırakma"
+DisableOSXVSync="OSX V-Sync Devre Dışı Bırak"
+ResetOSXVSyncOnExit="OSX V-Sync'i Çıkışta Sıfırla"
+HighResourceUsage="Kodlama aşırı yüklendi!  Video ayarlarını kapatmayı veya daha hızlı bir kodlama ön ayarını kullanmayı düşünün."
 Transition="Geçiş"
 QuickTransitions="Hızlı Geçiş"
 Left="Sol"
 Right="SaÄŸ"
 Top="Ãœst"
 Bottom="Alt"
-
-
+Reset="Sıfırla"
+Hours="Saat"
+Minutes="Dakika"
+Seconds="Saniye"
+Deprecated="Kullanım dışı"
+ReplayBuffer="Tekrar Oynatma ArabelleÄŸi"
+Import="İçe Aktar"
+Export="Dışa Aktar"
+
+Updater.Title="Yeni güncelleme mevcut"
+Updater.Text="Mevcut yeni bir güncelleme var:"
+Updater.UpdateNow="Şimdi Güncelle"
+Updater.RemindMeLater="Daha sonra hatırlat"
+Updater.Skip="Sürümü Atla"
+Updater.Running.Title="Program ÅŸu anda etkin"
+Updater.Running.Text="Çıkışlar hala etkin, lütfen güncellemeye çalışmadan önce aktif çıkışları kapatın"
+Updater.NoUpdatesAvailable.Title="Güncelleme mevcut değil"
+Updater.NoUpdatesAvailable.Text="Şu anda mevcut hiçbir güncelleme yok"
+Updater.FailedToLaunch="Güncelleyici başlatılamadı"
+Updater.GameCaptureActive.Title="Oyun yakalama etkin"
+Updater.GameCaptureActive.Text="Oyun yakalama kanca kütüphanesi hala kullanımda. Lütfen yakalanmakta olan oyunları/programları kapatın (veya Windows'u yeniden başlatın) ve yeniden deneyin."
+
+QuickTransitions.SwapScenes="Geçişten Sonra Önizleme/Çıkış Sahnelerini Değiştir"
+QuickTransitions.SwapScenesTT="Geçişten sonra çıkış ve ön izleme sahnelerinin yerini değiştirir (çıkışın orijinal sahnesi hala mevcutsa).\n Bu çıkışın orijinal sahnesine yapılan değişiklikleri geri almayacaktır."
+QuickTransitions.DuplicateScene="Sahneyi Çoğalt"
+QuickTransitions.DuplicateSceneTT="Aynı sahneyi düzenlerken, çıkışı değiştirmeden kaynakların dönüşümünü veya görünülürlüğünü düzenlemeye izin verir.\nKaynakların özelliklerini çıkışı değiştirmeden düzenlemek için 'Kaynakları Çoğalt'ı etkinleştirin.\nBu değeri değiştirmek mevcut çıkış sahnesini sıfırlar (hala varsa)."
+QuickTransitions.EditProperties="Kaynakları Çoğalt"
+QuickTransitions.EditPropertiesTT="Aynı sahneyi düzenlerken, çıkışı değiştirmeden kaynakların özelliklerinin düzenlenmesine izin verir.\nSadece 'Sahneyi Çoğalt' etkinse kullanılabilir.\nBelli kaynaklar (yakalama ve medya kaynakları gibi) bunu desteklemez ve ayrı olarak düzenlenemez.\nBu değeri değiştirmek mevcut çıkış sahnesini sıfırlar (hala varsa).\n\nUyarı: Kaynaklar çoğaltılacağından, ek sistem ve video kaynağı gerektirebilir."
+QuickTransitions.HotkeyName="Hızlı Geçiş: %1"
+
+Basic.AddTransition="Yapılandırılabilir Geçiş Ekle"
+Basic.RemoveTransition="Yapılandırılabilir Geçiş Kaldır"
+Basic.TransitionProperties="Geçiş Özellikleri"
+Basic.SceneTransitions="Sahne Geçişleri"
 Basic.TransitionDuration="Süre"
+Basic.TogglePreviewProgramMode="Stüdyo Modu"
 
+TransitionNameDlg.Text="Lütfen geçiş adını girin"
+TransitionNameDlg.Title="Geçiş Adı"
 
 TitleBar.Profile="Profil"
 TitleBar.Scenes="Sahneler"
 
-NameExists.Title="Bu isim zaten mevcut"
+NameExists.Title="Ä°sim zaten mevcut"
 NameExists.Text="Bu isim zaten kullanılıyor."
 
 NoNameEntered.Title="Lütfen geçerli bir isim girin"
-NoNameEntered.Text="İsmi boş kullanamazsınız."
+NoNameEntered.Text="Ä°sim boÅŸ olamaz."
 
+ConfirmStart.Title="Yayın Başlatılsın Mı?"
+ConfirmStart.Text="Yayını gerçekten başlatmak istiyor musunuz?"
 
+ConfirmStop.Title="Yayın Durdurulsun Mu?"
+ConfirmStop.Text="Yayını gerçekten durdurmak istiyor musunuz?"
 
 ConfirmExit.Title="OBS'den Çıkılsın mı?"
 ConfirmExit.Text="OBS şu anda etkin. Tüm yayınlar / kayıtlar kapatılacak. Çıkmak istediğinize emin misiniz?"
 
 ConfirmRemove.Title="Kaldırmayı Onayla"
 ConfirmRemove.Text="'$1''i kaldırmak istediğinizden emin misiniz?"
+ConfirmRemove.TextMultiple="%1 öğeyi kaldırmak istediğinizden emin misiniz?"
+
+Output.StartStreamFailed="Yayın işlemi başarısız oldu"
+Output.StartRecordingFailed="Kayıt işlemi başarısız oldu"
+Output.StartReplayFailed="Tekrar oynatma arabelleği başarısız oldu"
 
 Output.ConnectFail.Title="Bağlantı kurulamadı"
 Output.ConnectFail.BadPath="Bağlantı adresiniz geçersiz. Ayarlarınızı kontrol edin ve geçerli bir adres giriniz."
@@ -80,6 +126,8 @@ Output.RecordNoSpace.Title="Yetersiz disk alanı"
 Output.RecordNoSpace.Msg="Kayıt'aa devam etmek yeterli disk alanı yok."
 Output.RecordError.Title="Kayıt Hatası"
 Output.RecordError.Msg="Kayıt anında bir hata oluştu."
+Output.ReplayBuffer.NoHotkey.Title="Kısayol tuşu ayarlanmadı!"
+Output.ReplayBuffer.NoHotkey.Msg="Yeniden oynatma arabelleği için ayarlı bir kısayol tuşu yok. Lütfen yeniden oynatma kayıtlarını kaydetmek için \"Kaydet\" kısayol tuşunu ayarlayın."
 
 Output.BadPath.Title="Dosya Yolu Geçersiz"
 Output.BadPath.Text="Ayarlanan dosya kayıt yolu geçersiz. Lütfen ayarlarınızı kontrol ederek geçerli bir dosya yolunun girilmiş olduğundan emin olunuz."
@@ -123,12 +171,33 @@ Basic.DisplayCapture="Ekran Yakalama"
 
 Basic.Main.PreviewConextMenu.Enable="Önizlemeyi Etkinleştir"
 
-
+ScaleFiltering="Boyut Filtreleme"
+ScaleFiltering.Point="Nokta"
+ScaleFiltering.Bilinear="Bilinear"
+ScaleFiltering.Bicubic="Bikübik"
+ScaleFiltering.Lanczos="Lanczos"
+
+Deinterlacing="Deinterlacing"
+Deinterlacing.Discard="Discard"
+Deinterlacing.Retro="Retro"
+Deinterlacing.Blend="Blend"
+Deinterlacing.Blend2x="Blend 2x"
+Deinterlacing.Linear="Linear"
+Deinterlacing.Linear2x="Linear 2x"
+Deinterlacing.Yadif="Yadif"
+Deinterlacing.Yadif2x="Yadif 2x"
+Deinterlacing.TopFieldFirst="Önce Üst Alan"
+Deinterlacing.BottomFieldFirst="Önce Alt Alan"
+
+VolControl.SliderUnmuted="'%1' için ses kaydırıcı: %2"
+VolControl.SliderMuted="Повзунок гучності для '%1': %2 (şu anda sessiz)"
+VolControl.Mute="Sessiz '%1'"
+VolControl.Properties="'%1' için özellikler"
 
 Basic.Main.AddSceneDlg.Title="Sahne Ekle"
 Basic.Main.AddSceneDlg.Text="Lütfen sahne adını giriniz"
 
-Basic.Main.DefaultSceneName.Text="%1 Sahnesi"
+Basic.Main.DefaultSceneName.Text="Sahne %1"
 
 Basic.Main.AddSceneCollection.Title="Sahne Koleksiyonu Ekle"
 Basic.Main.AddSceneCollection.Text="Sahne koleksiyonunun isimini giriniz"
@@ -155,11 +224,16 @@ Basic.PropertiesWindow.ConfirmTitle="Ayarlar DeÄŸiÅŸtirildi"
 Basic.PropertiesWindow.Confirm="Kaydedilmeyen değişikler var. Yaptığınız değişikleri kaydetmek istiyor musunuz?"
 Basic.PropertiesWindow.NoProperties="Hiçbir özellik mevcut değil"
 Basic.PropertiesWindow.AddFiles="Dosya Ekle"
+Basic.PropertiesWindow.AddDir="Dizin Ekle"
 Basic.PropertiesWindow.AddURL="DosyaYolu/URL Ekle"
+Basic.PropertiesWindow.AddEditableListDir="'%1' dizinine ekle"
 Basic.PropertiesWindow.AddEditableListFiles="Dosyaları '%1' 'e ekle"
 Basic.PropertiesWindow.AddEditableListEntry="GiriÅŸi '%1' 'e ekle"
 Basic.PropertiesWindow.EditEditableListEntry="'%1' 'den giriÅŸ ekle"
 
+Basic.PropertiesView.FPS.Simple="Basit FPS DeÄŸerleri"
+Basic.PropertiesView.FPS.Rational="Rasyonel FPS DeÄŸerleri"
+Basic.PropertiesView.FPS.ValidFPSRanges="Geçerli Kare Aralıkları:"
 
 Basic.InteractionWindow="Etkileşime geçilen '%1'"
 
@@ -200,9 +274,9 @@ Basic.TransformWindow.Alignment.BottomCenter="Alt Orta"
 Basic.TransformWindow.Alignment.BottomRight="SaÄŸ alt"
 
 Basic.TransformWindow.BoundsType.None="Sınırsız"
-Basic.TransformWindow.BoundsType.MaxOnly="Yalnızca en büyük boyutu"
-Basic.TransformWindow.BoundsType.ScaleInner="İç sınırlara ölçekle"
-Basic.TransformWindow.BoundsType.ScaleOuter="Dış sınırlara göre boyutlandır"
+Basic.TransformWindow.BoundsType.MaxOnly="Yalnızca maksimum boyut"
+Basic.TransformWindow.BoundsType.ScaleInner="İç sınırlara boyutlandır"
+Basic.TransformWindow.BoundsType.ScaleOuter="Dış sınırlara boyutlandır"
 Basic.TransformWindow.BoundsType.ScaleToWidth="Sınır genişliğinde boyutlandır"
 Basic.TransformWindow.BoundsType.ScaleToHeight="Sınır yüksekliğinde boyutlandır"
 Basic.TransformWindow.BoundsType.Stretch="Sınırlara genişlet"
@@ -214,11 +288,15 @@ Basic.Main.Scenes="Sahneler"
 Basic.Main.Sources="Kaynaklar"
 Basic.Main.Connecting="Bağlanıyor..."
 Basic.Main.StartRecording="Kaydı Başlat"
+Basic.Main.StartReplayBuffer="Tekrar Oynatma ArabelleÄŸini BaÅŸlat"
 Basic.Main.StartStreaming="Yayını Başlat"
 Basic.Main.StopRecording="Kaydı Durdur"
 Basic.Main.StoppingRecording="Kayıt Durduruluyor..."
+Basic.Main.StopReplayBuffer="Tekrar Oynatma ArabelleÄŸini Durdur"
+Basic.Main.StoppingReplayBuffer="Tekrar Oynatma ArabelleÄŸi Durduruluyor..."
 Basic.Main.StopStreaming="Yayını Durdur"
 Basic.Main.StoppingStreaming="Canlı Yayın Durduruluyor..."
+Basic.Main.ForceStopStreaming="Yayını Durdur (gecikmeyi yoksay)"
 
 Basic.MainMenu.File="&Dosya"
 Basic.MainMenu.File.Export="Dışa Aktar"
@@ -228,6 +306,7 @@ Basic.MainMenu.File.Remux="Re&mux Kayıtları"
 Basic.MainMenu.File.Settings="&Ayarlar"
 Basic.MainMenu.File.ShowSettingsFolder="Ayarlar Dosyasını Göster"
 Basic.MainMenu.File.ShowProfileFolder="Profil Dosyasını Göster"
+Basic.MainMenu.AlwaysOnTop="&Her Zaman Ãœstte"
 Basic.MainMenu.File.Exit="Ç&ıkış"
 
 Basic.MainMenu.Edit="&Düzenle"
@@ -235,8 +314,15 @@ Basic.MainMenu.Edit.Undo="&Geri al"
 Basic.MainMenu.Edit.Redo="&Tekrar Yap"
 Basic.MainMenu.Edit.UndoAction="&$1 Geri al"
 Basic.MainMenu.Edit.RedoAction="&$1 Yinele"
+Basic.MainMenu.Edit.LockPreview="&Önizlemeyi Kilitle"
+Basic.MainMenu.Edit.Scale="Boyutlandırmayı &Önizle"
+Basic.MainMenu.Edit.Scale.Window="Pencereye Boyutlandır"
+Basic.MainMenu.Edit.Scale.Canvas="Tuval (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Çıkış (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Dönüştür"
 Basic.MainMenu.Edit.Transform.EditTransform="&Dönüştürmeyi Düzenle..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Dönüştürmeyi Kopyala"
+Basic.MainMenu.Edit.Transform.PasteTransform="Dönüştürmeyi Yapıştır"
 Basic.MainMenu.Edit.Transform.ResetTransform="&Dönüştürmeyi Sıfırla"
 Basic.MainMenu.Edit.Transform.Rotate90CW="90 derece saat yönüne döndür"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="90 derece saatin tersi yönüne döndür"
@@ -253,10 +339,22 @@ Basic.MainMenu.Edit.Order.MoveToTop="En &Üste Taşı"
 Basic.MainMenu.Edit.Order.MoveToBottom="En &Alta Taşı"
 Basic.MainMenu.Edit.AdvAudio="&Gelişmiş Ses Özellikleri"
 
+Basic.MainMenu.View="&Görünüm"
+Basic.MainMenu.View.Toolbars="&Araç Çubukları"
+Basic.MainMenu.View.Toolbars.Listboxes="&Liste Kutuları"
+Basic.MainMenu.View.SceneTransitions="S&ahne Geçişleri"
+Basic.MainMenu.View.StatusBar="&Durum Çubuğu"
 
 Basic.MainMenu.SceneCollection="&Sahne Koleksiyonu"
 Basic.MainMenu.Profile="&Profil"
+Basic.MainMenu.Profile.Import="Profili İçe Aktar"
+Basic.MainMenu.Profile.Export="Profili Dışa Aktar"
+Basic.MainMenu.SceneCollection.Import="Sahne Koleksiyonunu İçe Aktar"
+Basic.MainMenu.SceneCollection.Export="Sahne Koleksiyonunu Dışa Aktar"
+Basic.MainMenu.Profile.Exists="Profil zaten var"
+Basic.MainMenu.SceneCollection.Exists="Sahne koleksiyonu zaten var"
 
+Basic.MainMenu.Tools="&Araçlar"
 
 Basic.MainMenu.Help="&Yardım"
 Basic.MainMenu.Help.Website="&Siteyi Ziyaret Et"
@@ -274,6 +372,25 @@ Basic.Settings.Confirm="Kayıt edilmemiş değişiklikleriniz var. Değişiklikl
 Basic.Settings.General="Genel"
 Basic.Settings.General.Theme="Tema"
 Basic.Settings.General.Language="Dil"
+Basic.Settings.General.EnableAutoUpdates="Başlangıçta güncellemeleri otomatik olarak kontrol et"
+Basic.Settings.General.WarnBeforeStartingStream="Yayın başlatırken onay iletişim kutusunu göster"
+Basic.Settings.General.WarnBeforeStoppingStream="Yayın durduğunda onay iletişim kutusunu göster"
+Basic.Settings.General.Projectors="Projektörler"
+Basic.Settings.General.HideProjectorCursor="Projektörler üzerinde imleci gizle"
+Basic.Settings.General.ProjectorAlwaysOnTop="Projektörleri her zaman üstte tut"
+Basic.Settings.General.Snapping="Kaynak Hizalama"
+Basic.Settings.General.ScreenSnapping="Kaynakları ekranın kenarına yasla"
+Basic.Settings.General.CenterSnapping="Kaynakları dikey ve yatay merkeze yasla"
+Basic.Settings.General.SourceSnapping="Kaynakları diğer kaynaklara yasla"
+Basic.Settings.General.SnapDistance="Yaslama Hassasiyeti"
+Basic.Settings.General.RecordWhenStreaming="Yayın sırasında otomatik olarak kayıt yap"
+Basic.Settings.General.KeepRecordingWhenStreamStops="Yayın durduğunda kaydı tut"
+Basic.Settings.General.ReplayBufferWhileStreaming="Yayın sırasında tekrar oynatma arabelleğini otomatik olarak başlat"
+Basic.Settings.General.KeepReplayBufferStreamStops="Yayın durduğunda tekrar oynatma arabelleğini tut"
+Basic.Settings.General.SysTray="Sistem tepsisi"
+Basic.Settings.General.SysTrayWhenStarted="Başladığında sistem tepsisine küçült"
+Basic.Settings.General.SystemTrayHideMinimize="Her zaman görev çubuğu yerine sistem tepsisine küçült"
+Basic.Settings.General.SaveProjectors="Çıkışta projektörleri kaydet"
 
 Basic.Settings.Stream="Yayın"
 Basic.Settings.Stream.StreamType="Yayın Türü"
@@ -283,10 +400,19 @@ Basic.Settings.Output.Format="Kayıt Biçimi"
 Basic.Settings.Output.Encoder="Kodlayıcı"
 Basic.Settings.Output.SelectDirectory="Kayıt Dizinini Seçin"
 Basic.Settings.Output.SelectFile="Kayıt Dosyasını Seçin"
+Basic.Settings.Output.EnforceBitrate="Yayın hizmetini bit hızı sınırlarına zorla"
 Basic.Settings.Output.Mode="Çıkış modu"
 Basic.Settings.Output.Mode.Simple="Basit"
 Basic.Settings.Output.Mode.Adv="GeliÅŸmiÅŸ"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg Çıkışı"
+Basic.Settings.Output.UseReplayBuffer="Tekrar Oynatma ArabelleÄŸini EtkinleÅŸtir"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksimum Yeniden Oynatma Süresi (Seconds)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimum Bellek (Megabayt)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Tahmini bellek kullanımı: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Bellek kullanımını tahmin edemezsin. Lütfen maksimum bellek sınırını ayarlayın."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Not: kısayol tuşları bölümünde yeniden oynatma ara belleği için kısayol tuşu ayarladığınızdan emin olun)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Tekrar Oynatma Arabelleği Dosya Adı Öneki"
+Basic.Settings.Output.ReplayBuffer.Suffix="Suffix"
 Basic.Settings.Output.Simple.SavePath="Kayıt Yolu"
 Basic.Settings.Output.Simple.RecordingQuality="Kayıt Kalitesi"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Canlı Yayın ile Aynı"
@@ -296,31 +422,38 @@ Basic.Settings.Output.Simple.RecordingQuality.Lossless="Kayıpsız Kalite, Çok
 Basic.Settings.Output.Simple.Warn.Lossless.Msg="Kayıpsız kalitede kullanmak istediğinizden emin misiniz?"
 Basic.Settings.Output.Simple.Warn.Lossless.Title="Kayıpsız kalite uyarısı!"
 Basic.Settings.Output.Simple.Encoder.Software="Yazılım (x264)"
+Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Donanım (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Donanım (AMD)"
+Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Donanım (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Yazılım (x264 düşük CPU kullanım önayarı, dosya boyutunu artırır)"
-Basic.Settings.Output.VideoBitrate="Video Bithızı"
-Basic.Settings.Output.AudioBitrate="Ses Bithızı"
+Basic.Settings.Output.VideoBitrate="Video Bit Hızı"
+Basic.Settings.Output.AudioBitrate="Ses Bit Hızı"
 Basic.Settings.Output.Reconnect="Otomatik Yeniden BaÄŸlan"
 Basic.Settings.Output.RetryDelay="Yeniden Deneme Gecikmesi (saniye)"
-Basic.Settings.Output.MaxRetries="En fazla yeniden deneme sayısı"
+Basic.Settings.Output.MaxRetries="Maksimum Deneme Sayısı"
 Basic.Settings.Output.Advanced="Gelişmiş Kodlayıcı Ayarlarını Etkinleştir"
 Basic.Settings.Output.EncoderPreset="Kodlayıcı Önayarı (yüksek = daha az İŞLEMCİ)"
 Basic.Settings.Output.CustomEncoderSettings="Özel Kodlayıcı Ayarları"
+Basic.Settings.Output.CustomMuxerSettings="Özel Muxer Ayarları"
 Basic.Settings.Output.NoSpaceFileName="Dosya ismini boÅŸluk olmadan oluÅŸtur"
 
-Basic.Settings.Output.Adv.Rescale="Çıkışı Yeniden Ölçeklendir"
+Basic.Settings.Output.Adv.Rescale="Çıkışı Yeniden Boyutlandır"
 Basic.Settings.Output.Adv.AudioTrack="Ses Parçası"
 Basic.Settings.Output.Adv.Streaming="Yayın"
-Basic.Settings.Output.Adv.ApplyServiceSettings="Gerçek zamanlı ayayın hizmeti kodlayıcı ayarlarını zorla"
+Basic.Settings.Output.Adv.ApplyServiceSettings="Yayın hizmetini kodlayıcı ayarlarına zorla"
 Basic.Settings.Output.Adv.Audio.Track1="Parça 1"
 Basic.Settings.Output.Adv.Audio.Track2="Ses Ä°zi 2"
 Basic.Settings.Output.Adv.Audio.Track3="Ses Ä°zi 3"
 Basic.Settings.Output.Adv.Audio.Track4="Ses Ä°zi 4"
+Basic.Settings.Output.Adv.Audio.Track5="Parça 5"
+Basic.Settings.Output.Adv.Audio.Track6="Parça 6"
 
 Basic.Settings.Output.Adv.Recording="Kayıt"
 Basic.Settings.Output.Adv.Recording.Type="Tür"
 Basic.Settings.Output.Adv.Recording.Type.Standard="Standart"
 Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Özel Çıkış (FFmpeg)"
 Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Yayın kodlayıcı kullan)"
+Basic.Settings.Output.Adv.Recording.Filename="Dosya Adı Biçimi"
 Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Dosya varsa üzerine yaz"
 Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg Çıkış Türü"
 Basic.Settings.Output.Adv.FFmpeg.Type.URL="URL'ye Çıkış"
@@ -341,15 +474,18 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Video Kodlayıcı Ayarları (
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Ses Kodlayıcı"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Ses Kodlayıcı Ayarları (var ise)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer Ayarları (eğer varsa)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Anahtar Kare Aralığı (kare)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Tüm kodekleri göster (potansiyel olarak uyumsuz olsa bile)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
+FilenameFormatting.TT="%CCYY	Yıl, dört hane\n%YY		Yıl, son iki hane (00-99)\n%MM		Ay rakamla (01-12)\n%DD		Ayın günü, önü-sıfırlı (01-31)\n%hh		Saat 24s formatlı (00-23)\n%mm		Dakika (00-59)\n%ss		Saniye (00-61)\n%%		A % sign\n%a		Kısaltılmış gün adı\n%A		Tam gün adı\n%b		Kısaltılmış ay adı\n%B		Tam ay adı\n%d		Ayın günü, önü-sıfırlı (01-31)\n%H		Saat 24s formatlı (00-23)\n%I		Saat 12s formatlı (01-12)\n%m		Ay rakamla (01-12)\n%M		Dakika (00-59)\n%p		AM veya PM belirteci\n%S		Saniye (00-61)\n%y		Yıl, son iki hane (00-99)\n%Y		Yıl\n%z		UTC'ye göre ISO 8601 farkı veya zaman dilimi\n		adı veya kısaltması\n%Z		Zaman dilimi adı veya kısaltması\n"
 
 Basic.Settings.Video="Video"
 Basic.Settings.Video.Adapter="Video Bağdaştırıcı:"
 Basic.Settings.Video.BaseResolution="Temel (Tuval) Çözünürlüğü:"
-Basic.Settings.Video.ScaledResolution="Çıkış (Ölçekli) Çözünürlüğü:"
-Basic.Settings.Video.DownscaleFilter="Filtreyi Azalt:"
+Basic.Settings.Video.ScaledResolution="Çıkış (Boyutlandırılmış) Çözünürlüğü:"
+Basic.Settings.Video.DownscaleFilter="Boyut Azaltma Filtresi:"
 Basic.Settings.Video.DisableAeroWindows="Aero'yu Devre Dışı Bırak (yalnızca Windows)"
 Basic.Settings.Video.FPS="FPS:"
 Basic.Settings.Video.FPSCommon="Ortak FPS DeÄŸerleri"
@@ -362,6 +498,9 @@ Basic.Settings.Video.InvalidResolution="Geçersiz çözünürlük değeri. [Geni
 Basic.Settings.Video.CurrentlyActive="Video çıkışı şu anda etkin durumda.  Video ayarlarını değiştirmek için lütfen bütün çıkışları kapalı duruma getirin."
 Basic.Settings.Video.DisableAero="Aero'yu Devre Dışı Bırak"
 
+Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (En hızlı, ancak boyutlandırmada bulanık görüntü)"
+Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Keskinleştirilmiş boyutlandırma, 16 örnek)"
+Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Keskinleştirilmiş boyutlandırma, 32 örnek)"
 
 Basic.Settings.Audio="Ses"
 Basic.Settings.Audio.SampleRate="Örnekleme Sıklığı"
@@ -378,9 +517,11 @@ Basic.Settings.Audio.PushToTalkDelay="Bas-KonuÅŸ gecikmesi"
 Basic.Settings.Audio.UnknownAudioDevice="[Cihaz bağlı yada kullanılabilir değil]"
 
 Basic.Settings.Advanced="GeliÅŸmiÅŸ"
+Basic.Settings.Advanced.General.ProcessPriority="İşlem Önceliği"
 Basic.Settings.Advanced.General.ProcessPriority.High="Yüksek"
 Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Normalin Üstünde"
 Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal"
+Basic.Settings.Advanced.General.ProcessPriority.Idle="BoÅŸta"
 Basic.Settings.Advanced.FormatWarning="Uyarı: NV12 dışındaki renk biçimleri esas olarak kayıt için tasarlanmıştır ve yayın anında kullanma önerilmez. Yayın nedeni ile renk biçimini dönüştürme çok fazla İŞLEMCİ kullanımına sebep olabilir."
 Basic.Settings.Advanced.Audio.BufferingTime="Ses Ön Bellekleme Süresi"
 Basic.Settings.Advanced.Video.ColorFormat="Renk Biçimi"
@@ -388,30 +529,43 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV Renk Alanı"
 Basic.Settings.Advanced.Video.ColorRange="YUV Renk Aralığı"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Kısmi"
 Basic.Settings.Advanced.Video.ColorRange.Full="Tam"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Ses İzleme Aygıtı"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Varsayılan"
 Basic.Settings.Advanced.StreamDelay="Yayın Gecikmesi"
 Basic.Settings.Advanced.StreamDelay.Duration="Süre (saniye)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Tatbik ederken kesim noktasını (gecikme artışı) koru"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Tahmini Bellek Kullanımı: %1 MB"
+Basic.Settings.Advanced.Network="AÄŸ"
+Basic.Settings.Advanced.Network.BindToIP="IP BaÄŸla"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Yeni aÄŸ kodunu etkinleÅŸtir"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Düşük gecike modu"
 
 Basic.AdvAudio="Gelişmiş Ses Özellikleri"
 Basic.AdvAudio.Name="Ä°sim"
 Basic.AdvAudio.Volume="Ses Düzeyi (%)"
 Basic.AdvAudio.Mono="Mono Karıştırmayı Azalt"
+Basic.AdvAudio.Panning="Kaydırma"
+Basic.AdvAudio.SyncOffset="Eşitleme Uzaklığı (ms)"
+Basic.AdvAudio.Monitoring="Ses Ä°zleme"
+Basic.AdvAudio.Monitoring.None="Ekran Kapalı"
+Basic.AdvAudio.Monitoring.MonitorOnly="Sadece Ekran (sessiz çıkış)"
+Basic.AdvAudio.Monitoring.Both="Ekran ve Çıkış"
 Basic.AdvAudio.AudioTracks="Parçalar"
 
 Basic.Settings.Hotkeys="Kısayollar"
+Basic.Settings.Hotkeys.Pair="'%1' ile paylaşılan tuş kombinasyonu açma/kapama olarak çalışır"
 
-Basic.Hotkeys.StartStreaming="Yayını Başlat"
-Basic.Hotkeys.StopStreaming="Yayını Durdur"
-Basic.Hotkeys.StartRecording="Kaydı Başlat"
-Basic.Hotkeys.StopRecording="Kaydı Durdur"
 Basic.Hotkeys.SelectScene="Sahneye geçiş yap"
 
+Basic.SystemTray.Show="Göster"
+Basic.SystemTray.Hide="Gizle"
 
+Basic.SystemTray.Message.Reconnecting="Bağlantı kesildi.  Yeniden bağlanılıyor..."
 
 Hotkeys.Insert="Ekle"
 Hotkeys.Delete="Sil"
 Hotkeys.Home="Ana Sayfa"
+Hotkeys.End="End"
 Hotkeys.PageUp="Page Up"
 Hotkeys.PageDown="Page Down"
 Hotkeys.NumLock="Num Lock"
@@ -420,6 +574,7 @@ Hotkeys.CapsLock="Caps Lock"
 Hotkeys.Backspace="Backspace"
 Hotkeys.Tab="Tab"
 Hotkeys.Print="Yazdır"
+Hotkeys.Pause="Duraklat"
 Hotkeys.Left="Sol"
 Hotkeys.Right="SaÄŸ"
 Hotkeys.Up="Yukarı"
@@ -429,6 +584,11 @@ Hotkeys.Super="Süper"
 Hotkeys.Menu="Menü"
 Hotkeys.Space="BoÅŸluk"
 Hotkeys.NumpadNum="Numpad %1"
+Hotkeys.NumpadMultiply="Numpad *"
+Hotkeys.NumpadDivide="Numpad /"
+Hotkeys.NumpadAdd="Numpad Ekle"
+Hotkeys.NumpadSubtract="Numpad -"
+Hotkeys.NumpadDecimal="Numpad ,"
 Hotkeys.AppleKeypadNum="%1 (Tuş takımı)"
 Hotkeys.AppleKeypadMultiply="* (Tuş takımı)"
 Hotkeys.AppleKeypadDivide="/ (Tuş takımı)"
@@ -440,6 +600,7 @@ Hotkeys.MouseButton="%1 Fare"
 
 Mute="Sesi Kapat"
 Unmute="Sesi Aç"
+Push-to-mute="Bas-Sessize Al"
 Push-to-talk="Bas konuÅŸ"
 
 SceneItemShow="'%1' Göster"
@@ -447,4 +608,5 @@ SceneItemHide="'%1' Gizle"
 
 OutputWarnings.NoTracksSelected="En az bir ses parçası seçmelisiniz"
 OutputWarnings.MultiTrackRecording="Uyarı: Bazı biçimler (FLV gibi) kayıt başına birden fazla parçayı desteklemez"
+OutputWarnings.MP4Recording="Uyarı: MP4'e kaydedilen kayıtlar eğer dosya sonlandırılamazsa kurtarılamaz (örneğin: Mavi Hata Ekranı, güç kesintisi v.b.). Eğer çoklu ses izi kaydetmek istiyorsanız MKV kullanmayı düşünün ve bittikten sonra sonra kayıtı mp4'e remuxlayabilirsiniz (Dosya->Remux Kayıtları)"
 
diff --git a/UI/data/locale/uk-UA.ini b/UI/data/locale/uk-UA.ini
index de75835..073f921 100644
--- a/UI/data/locale/uk-UA.ini
+++ b/UI/data/locale/uk-UA.ini
@@ -49,13 +49,33 @@ Right="Зправа"
 Top="Зверху"
 Bottom="Знизу"
 Reset="Скинути"
+Hours="Годин"
+Minutes="Хвилин"
+Seconds="Секунд"
+Deprecated="Припинено підтримку"
+ReplayBuffer="Буфер Повторів"
+Import="Імпорт"
+Export="Експорт"
+
+Updater.Title="Доступне оновлення"
+Updater.Text="Існує нове оновлення:"
+Updater.UpdateNow="Оновити зараз"
+Updater.RemindMeLater="Нагадати пізніше"
+Updater.Skip="Пропустити цю версію"
+Updater.Running.Title="Програма зараз активна"
+Updater.Running.Text="Вивід активний в даний час, будь ласка, завершіть роботу будь-якого активного Виводу перед спробою оновлення"
+Updater.NoUpdatesAvailable.Title="Оновлень немає"
+Updater.NoUpdatesAvailable.Text="На даний час оновлень немає"
+Updater.FailedToLaunch="Не вдалося перевірити оновлення"
+Updater.GameCaptureActive.Title="Захват гри активний"
+Updater.GameCaptureActive.Text="Бібліотека для Захвату гри наразі використовується. Будь ласка, закрийте всі ігри/програми для яких використовувався захват (або перезавантажте Windows) та спробуйте знов."
 
 QuickTransitions.SwapScenes="Поміняти місцями сцени Перегляд/Вивід після Відео-переходу"
 QuickTransitions.SwapScenesTT="Міняє місцями сцени Перегляд та Вивід після закінчення Відео-переходу (якщо сцена Вивід ще існує).\nЗміни внесені до обох сцен залишаються."
 QuickTransitions.DuplicateScene="Використовувати копію сцени"
 QuickTransitions.DuplicateSceneTT="Під час редагування поточної сцени дозволяє зберегти Вивід без змін.\nДля можливості редагувати властивості Джерел, увімкніть також 'Використовувати копію Джерел'.\nЗміна цієї опції призведе до оновлення поточної сцени, яка йде на Вивід (якщо вона ще існує)."
 QuickTransitions.EditProperties="Використовувати копію Джерел"
-QuickTransitions.EditPropertiesTT="Під час редагування поточної сцени, дозволяє редагувати властивості Джерел не змінюючи Вивід.\nЦя опція можлива якщо 'Використовувати копію сцени' вибрана.\nДеякі джерела (наприклад медіа або прилади захвату зображень) не підтримують копіювання, тобто не можна внести окремі зміни у джерело.\nЗміна властивостей таких джерел миттєво змінить Вивід (якщо він ще існує).\n\nУвага: Так як джерела внутрішньо копіюються, то це може призвести до додаткового навантаження на систему та використання відео ресурсів."
+QuickTransitions.EditPropertiesTT="Під час редагування поточної сцени, дозволяє редагувати властивості Джерел не змінюючи Вивід.\nЦя опція можлива якщо 'Використовувати копію сцени' вибрана.\nДеякі джерела (наприклад медіа або пристрої захвату зображень) не підтримують копіювання, тобто не можна внести окремі зміни у джерело.\nЗміна властивостей таких джерел миттєво змінить Вивід (якщо він ще існує).\n\nУвага: Так як джерела внутрішньо копіюються, то це може призвести до додаткового навантаження на систему та використання відео ресурсів."
 QuickTransitions.HotkeyName="Швидкий відео-перехід: %1"
 
 Basic.AddTransition="Додати Відео-перехід що конфігурується"
@@ -90,6 +110,11 @@ ConfirmRemove.Title="Підтвердження видалення"
 ConfirmRemove.Text="Ви дійсно бажаєте видалити \"$1\"?"
 ConfirmRemove.TextMultiple="Ви впевнені, що хочете видалити %1 елементів?"
 
+Output.StartStreamFailed="Не вдалося розпочати трансляцію"
+Output.StartRecordingFailed="Не вдалося розпочати запис"
+Output.StartReplayFailed="Не вдалося запустити Буфер Повторів"
+Output.StartFailedGeneric="Помилка. Вивід не було розпочато.  За додатковою інформацією, будь ласка зверніться до файлу журналу.\n\nПримітка: якщо ви використовуєте NVENC або AMD енкодер, перевірте чи оновлений драйвер відео."
+
 Output.ConnectFail.Title="Не вдалося підключитися"
 Output.ConnectFail.BadPath="Шлях або URL-адреса недосяжні. Будь ласка, перевірте налаштування програмного забезпечення."
 Output.ConnectFail.ConnectFailed="Не вдалося підключитися до сервера"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="Недостатньо простору на дис
 Output.RecordNoSpace.Msg="На диску недостатньо простору для запису."
 Output.RecordError.Title="Помилка запису"
 Output.RecordError.Msg="Під час запису відбулася несподівана помилка."
+Output.ReplayBuffer.NoHotkey.Title="Гарячу клавішу не вказано!"
+Output.ReplayBuffer.NoHotkey.Msg="Гарячу клавішу для Буферу Повторів не вказано.  Будь ласка, встановіть гарячу клавішу на дію \"Зберегти Повтор\", щоб використовувати її для збереження повторів."
 
 Output.BadPath.Title="Недійсний шлях до файлу"
 Output.BadPath.Text="Шлях вказаний для виводу файлу недійсний. Будь ласка, перевірте у налаштуваннях, що шлях було вказано вірно."
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="Спочатку непарні рядки"
 Deinterlacing.BottomFieldFirst="Спочатку парні рядки"
 
+VolControl.SliderUnmuted="Повзунок гучності для '%1': %2"
+VolControl.SliderMuted="Повзунок гучності для '%1': %2 (в даний час звук вимкнено)"
+VolControl.Mute="Вимкнути звук '%1'"
+VolControl.Properties="Властивості для '%1'"
+
 Basic.Main.AddSceneDlg.Title="Додати Сцену"
 Basic.Main.AddSceneDlg.Text="Будь ласка, введіть назву для Сцени"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="Сцени"
 Basic.Main.Sources="Джерела"
 Basic.Main.Connecting="З'єднання..."
 Basic.Main.StartRecording="Почати запис"
+Basic.Main.StartReplayBuffer="Запустити Буфер Повторів"
 Basic.Main.StartStreaming="Почати трансляцію"
 Basic.Main.StopRecording="Зупинити запис"
 Basic.Main.StoppingRecording="Запис зупиняється..."
+Basic.Main.StopReplayBuffer="Зупинити Буфер Повторів"
+Basic.Main.StoppingReplayBuffer="Буфер Повторів зупиняється..."
 Basic.Main.StopStreaming="Закінчити трансляцію"
 Basic.Main.StoppingStreaming="Припинення трансляції..."
 Basic.Main.ForceStopStreaming="Закінчити трансляцію (миттєво)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="Від&новити"
 Basic.MainMenu.Edit.UndoAction="&Відмінити $1"
 Basic.MainMenu.Edit.RedoAction="Від&новити $1"
 Basic.MainMenu.Edit.LockPreview="&Зафіксувати вікно Перегляду"
+Basic.MainMenu.Edit.Scale="&Масштабувати вікно Перегляду"
+Basic.MainMenu.Edit.Scale.Window="В розмір вікна"
+Basic.MainMenu.Edit.Scale.Canvas="Як Полотно (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="Як Вивід (%1x%2)"
 Basic.MainMenu.Edit.Transform="&Розміри"
 Basic.MainMenu.Edit.Transform.EditTransform="Редагуват&и Розміри..."
+Basic.MainMenu.Edit.Transform.CopyTransform="Копіювати Розміри"
+Basic.MainMenu.Edit.Transform.PasteTransform="Вставити Розміри"
 Basic.MainMenu.Edit.Transform.ResetTransform="Розміри за &замовчуванням"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Повернути на 90 За годинниковою стрілкою"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Повернути на 90 Проти годинникової стрілки"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="Панель с&тану"
 
 Basic.MainMenu.SceneCollection="&Набір Сцен"
 Basic.MainMenu.Profile="&Профіль"
+Basic.MainMenu.Profile.Import="Імпорт Профілю"
+Basic.MainMenu.Profile.Export="Експорт Профілю"
+Basic.MainMenu.SceneCollection.Import="Імпорт Набору Сцен"
+Basic.MainMenu.SceneCollection.Export="Експорт Набору Сцен"
+Basic.MainMenu.Profile.Exists="Профіль вже існує"
+Basic.MainMenu.SceneCollection.Exists="Набір Сцен вже існує"
 
 Basic.MainMenu.Tools="Додаткові &засоби"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="Є незбережені зміни.  Зберегти
 Basic.Settings.General="Загальні"
 Basic.Settings.General.Theme="Тема"
 Basic.Settings.General.Language="Мова"
+Basic.Settings.General.EnableAutoUpdates="Автоматично перевіряти наявність оновлень під час запуску"
 Basic.Settings.General.WarnBeforeStartingStream="Показувати підтвердження для початку трансляції"
 Basic.Settings.General.WarnBeforeStoppingStream="Показувати підтвердження для закінчення трансляції"
+Basic.Settings.General.Projectors="Проектор"
 Basic.Settings.General.HideProjectorCursor="Приховати курсор у режимі Проектор"
 Basic.Settings.General.ProjectorAlwaysOnTop="Режим Проектор відображати поверх всіх вікон"
 Basic.Settings.General.Snapping="Прив'язка та вирівнювання"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="Примагнітити Джерело 
 Basic.Settings.General.SnapDistance="Чутливість примагничування"
 Basic.Settings.General.RecordWhenStreaming="Автоматично почати запис з початком трансляції"
 Basic.Settings.General.KeepRecordingWhenStreamStops="Не припиняти запис, якщо трансляцію закінчено"
-Basic.Settings.General.SysTrayEnabled="Відображати іконку системному треї, та згортати в трей"
+Basic.Settings.General.ReplayBufferWhileStreaming="Автоматично запустити Буфер Повторів з початком трансляції"
+Basic.Settings.General.KeepReplayBufferStreamStops="Не припиняти Буфер Повторів, якщо трансляцію закінчено"
+Basic.Settings.General.SysTray="Системний трей"
 Basic.Settings.General.SysTrayWhenStarted="Згорнути програму до трею при запуску"
+Basic.Settings.General.SystemTrayHideMinimize="Згортати в трей замість того, щоб мінімізувати до панелі завдань"
+Basic.Settings.General.SaveProjectors="Зберегти налаштування режиму Проектор при виході"
 
 Basic.Settings.Stream="Трансляція"
 Basic.Settings.Stream.StreamType="Тип Трансляції"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="Режим виводу"
 Basic.Settings.Output.Mode.Simple="Простий"
 Basic.Settings.Output.Mode.Adv="Розширений"
 Basic.Settings.Output.Mode.FFmpeg="Вивід FFmpeg"
+Basic.Settings.Output.UseReplayBuffer="Увімкнути Буфер Повторів"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Максимальна тривалість Повтору (у секундах)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Максимальний об'єм пам'яті (у мегабайтах)"
+Basic.Settings.Output.ReplayBuffer.Estimate="Буде використано пам'яті: %1 МБ"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Не вдалося оцінити об'єм використання пам'яті. Будь ласка, встановіть максимальний об'єм пам'яті для Буферу Повторів вручну."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Примітка: переконайтеся, що встановили гарячу клавішу для Буферу Повторів в розділі гарячі клавіші)"
+Basic.Settings.Output.ReplayBuffer.Prefix="Буфер Повторів, Ім'я файлу, Префікс"
+Basic.Settings.Output.ReplayBuffer.Suffix="Суфікс"
 Basic.Settings.Output.Simple.SavePath="Шлях до запису"
 Basic.Settings.Output.Simple.RecordingQuality="Якість запису"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Так само як трансляція"
@@ -369,6 +430,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="Якість Без втрат
 Basic.Settings.Output.Simple.Warn.MultipleQSV="Попередження: Не можна використовувати кілька окремих енкодерів QSV одночасно для запису і трансляції.  Якщо ви хочете транслювати і записувати одночасно, будь ласка, змінить або енкодер запису, або енкодер трансляції на інший."
 Basic.Settings.Output.Simple.Encoder.Software="Програмний (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Апаратний (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Апаратний (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Апаратний (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Програмний (x264, шаблон з низьким завантаженням ЦП, збільшує файл)"
 Basic.Settings.Output.VideoBitrate="Відео бітрейт"
@@ -390,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Доріжка 1"
 Basic.Settings.Output.Adv.Audio.Track2="Доріжка 2"
 Basic.Settings.Output.Adv.Audio.Track3="Доріжка 3"
 Basic.Settings.Output.Adv.Audio.Track4="Доріжка 4"
+Basic.Settings.Output.Adv.Audio.Track5="Доріжка 5"
+Basic.Settings.Output.Adv.Audio.Track6="Доріжка 6"
 
 Basic.Settings.Output.Adv.Recording="Запис"
 Basic.Settings.Output.Adv.Recording.Type="Тип"
@@ -417,10 +481,12 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Енкодер відео, п
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="Енкодер аудіо"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Енкодер аудіо, параметри користувача"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Мультиплексор, параметри користувача"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="Ключові кадри, період (кадрів)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Показати всі кодеки (навіть якщо потенційно несумісні)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
-FilenameFormatting.TT="%CCYY		Рік, чотири цифри\n%YY		Рік, останні дві цифри (00-99)\n%MM		Місяць за номером (01-12)\n%DD		День місяця, ноль попереду (01-31)\n%hh		Години у 24-год. форматі (00-23)\n%mm		Мінути (00-59)\n%ss		Секунди (00-61)\n%%		Знак % \n%a		Абревіатура дня тижня\n%A		День тижня повністю\n%b		Абревіатура місяця\n%B		Місяць повністю\n%d		День місяця, ноль попереду (01-31)\n%H		Години у 24-год. форматі (00-23)\n%I		Години у 12-год. форматі (01-12)\n%m		Місяць за номером (01-12)\n%M		Мінути (00-59)\n%p		ДП або ПП позначення\n%S		Секунди (00-61)\n%y		Рік, останні дві цифри (00-99)\n%Y		Рік\n%z		ISO 8601 поправка від UTC або часовий\n		пояс чи абревіатура\n%Z		Часовий пояс чи абревіатура\n"
+FilenameFormatting.TT="%CCYY	Рік, чотири цифри\n%YY		Рік, останні дві цифри (00-99)\n%MM		Місяць за номером (01-12)\n%DD		День місяця, ноль попереду (01-31)\n%hh		Години у 24-год. форматі (00-23)\n%mm		Мінути (00-59)\n%ss		Секунди (00-61)\n%%		Знак % \n%a		Абревіатура дня тижня\n%A		День тижня повністю\n%b		Абревіатура місяця\n%B		Місяць повністю\n%d		День місяця, ноль попереду (01-31)\n%H		Години у 24-год. форматі (00-23)\n%I		Години у 12-год. форматі (01-12)\n%m		Місяць за номером (01-12)\n%M		Мінути (00-59)\n%p		ДП або ПП позначення\n%S		Секунди (00-61)\n%y		Рік, останні дві цифри (00-99)\n%Y		Рік\n%z		ISO 8601 поправка від UTC або часовий\n		пояс чи абревіатура\n%Z		Часовий пояс чи абревіатура\n"
 
 Basic.Settings.Video="Відео"
 Basic.Settings.Video.Adapter="Відеокарта:"
@@ -470,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV, колірний простір"
 Basic.Settings.Advanced.Video.ColorRange="YUV, колірний діапазон"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Частковий"
 Basic.Settings.Advanced.Video.ColorRange.Full="Повний"
+Basic.Settings.Advanced.Audio.MonitoringDevice="Пристрій Тестування Аудіо (на слух)"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="За замовчанням"
 Basic.Settings.Advanced.StreamDelay="Затримка трансляції"
 Basic.Settings.Advanced.StreamDelay.Duration="Тривалість (секунди)"
 Basic.Settings.Advanced.StreamDelay.Preserve="Зберегати точку роз'єднання (збільшує затримку) під час встановлення нового зв'язку"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="Буде використано пам'яті: %1 МБ"
 Basic.Settings.Advanced.Network="Мережа"
 Basic.Settings.Advanced.Network.BindToIP="Прив'язати до адаптера (IP)"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="Увімкнути новий мережевий код"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="Режим з низькою затримкою"
 
 Basic.AdvAudio="Розширені Налаштування Аудіо"
 Basic.AdvAudio.Name="Назва"
@@ -483,15 +553,15 @@ Basic.AdvAudio.Volume="Гучність (%)"
 Basic.AdvAudio.Mono="Мікшувати до псевдо-Моно"
 Basic.AdvAudio.Panning="Баланс"
 Basic.AdvAudio.SyncOffset="Зсув синхронізації (мс)"
+Basic.AdvAudio.Monitoring="Тестування Аудіо (на слух)"
+Basic.AdvAudio.Monitoring.None="Тест вимкнено"
+Basic.AdvAudio.Monitoring.MonitorOnly="Слухати, але не Виводити"
+Basic.AdvAudio.Monitoring.Both="Слухати та Виводити"
 Basic.AdvAudio.AudioTracks="Доріжки"
 
 Basic.Settings.Hotkeys="Гарячі клавіші"
 Basic.Settings.Hotkeys.Pair="Однакові комбінації клавіш задані до '%1' діють як перемикач"
 
-Basic.Hotkeys.StartStreaming="Почати трансляцію"
-Basic.Hotkeys.StopStreaming="Закінчити трансляцію"
-Basic.Hotkeys.StartRecording="Почати запис"
-Basic.Hotkeys.StopRecording="Зупинити запис"
 Basic.Hotkeys.SelectScene="Перейти до сцени"
 
 Basic.SystemTray.Show="Показати"
@@ -545,4 +615,5 @@ SceneItemHide="Приховати '%1'"
 
 OutputWarnings.NoTracksSelected="Ви повинні вибрати хоча б одну аудіо-доріжку"
 OutputWarnings.MultiTrackRecording="Попередження: Певні формати (наприклад, FLV) не підтримують кілька треків на запис"
+OutputWarnings.MP4Recording="Попередження: Запис в MP4 може стати невиправно пошкодженим, якщо файл не буде завершено (наприклад, в результаті BSOD, втрати живлення і т.п.). Якщо ви хочете, мати запис декількох звукових доріжок спробуйте використати MKV та зробіть ремультиплексацію запису до mp4 після того, як запис буде закінчено (Файл->Ремультиплексація Записів)"
 
diff --git a/UI/data/locale/vi-VN.ini b/UI/data/locale/vi-VN.ini
index 22db6b2..dcd63c8 100644
--- a/UI/data/locale/vi-VN.ini
+++ b/UI/data/locale/vi-VN.ini
@@ -24,7 +24,7 @@ Display="Hiển thị"
 Name="Tên"
 Exit="Thoát"
 Mixer="Bá»™ trá»™n"
-Browse="trình duyệt"
+Browse="Chọn đường dẫn"
 Mono="Âm thanh đơn"
 Stereo="Âm thanh nổi"
 DroppedFrames="Khung rá»›t %1 (%2%)"
@@ -41,18 +41,31 @@ Duplicate="Tạo bản sao"
 Enable="Kích hoạt"
 DisableOSXVSync="Tắt OSX V-Sync"
 ResetOSXVSyncOnExit="Đặt lại OSX V-Sync khi Thoát"
-Transition="Chuyển tiếp"
+HighResourceUsage="Encoder quá tải!  Hãy xem xét giảm chất lượng video hoặc sử dụng 1 encoder nhanh hơn."
+Transition="Chuyển cảnh"
 QuickTransitions="C. cảnh nhanh"
 Left="Trái"
 Right="Phải"
 Top="Trên"
 Bottom="DÆ°á»›i"
+Reset="Thiết lập lại"
+Hours="Giờ"
+Minutes="Phút"
+Seconds="Giây"
+
 
 QuickTransitions.SwapScenes="Hoán đổi cảnh Xem trước/Đầu ra sau khi Chuyển cảnh"
 QuickTransitions.SwapScenesTT="Hoán đổi cảnh xem trước và cảnh đầu ra sau khi chuyển cảnh (nếu cảnh đầu ra gốc vẫn tồn tại).\nMọi thay đổi với cảnh đầu ra gốc sẽ không hoàn tác."
 QuickTransitions.DuplicateScene="Tạo bản sao cảnh"
+QuickTransitions.HotkeyName="C. cảnh nhanh: %1"
 
+Basic.AddTransition="Thêm cấu hình chuyển cảnh"
+Basic.RemoveTransition="Xóa cấu hình chuyển cảnh"
+Basic.TransitionDuration="Thời gian"
+Basic.TogglePreviewProgramMode="Chế độ Studio"
 
+TransitionNameDlg.Text="Vui lòng nhập tên của cảnh"
+TransitionNameDlg.Title="Tên chuyển cảnh"
 
 TitleBar.Profile="Cấu hình"
 TitleBar.Scenes="Cảnh"
@@ -63,18 +76,25 @@ NameExists.Text="Tên hiện đang sử dụng."
 NoNameEntered.Title="Vui lòng nhập tên hợp lệ"
 NoNameEntered.Text="Bạn không thể sử dụng tên có sản phẩm nào."
 
+ConfirmStart.Title="Bắt đầu Stream?"
+ConfirmStart.Text="Bạn có chắc muốn bắt đầu stream?"
 
+ConfirmStop.Title="Ngừng Stream?"
+ConfirmStop.Text="Bạn có chắc muốn dừng stream?"
 
 ConfirmExit.Title="Thoát OBS?"
-ConfirmExit.Text="OBS là hiện đang hoạt động.  Tất cả dòng/bản ghi sẽ được đóng cửa.  Bạn có chắc bạn muốn thoát khỏi không?"
+ConfirmExit.Text="OBS hiện đang hoạt động.  Tất cả các stream/quay video sẽ bị tắt.  Bạn có chắc muốn thoát không?"
 
 ConfirmRemove.Title="Xác nhận loại bỏ"
 ConfirmRemove.Text="Bạn có chắc bạn muốn loại bỏ '$1' không?"
+ConfirmRemove.TextMultiple="Bạn có chắc bạn muốn xóa %1 nội dung không?"
+
 
 Output.ConnectFail.Title="Không thể kết nối"
 Output.ConnectFail.BadPath="URL không hợp lệ của đường dẫn hoặc kết nối.  Xin vui lòng kiểm tra cài đặt của bạn để xác nhận rằng họ là hợp lệ."
 Output.ConnectFail.ConnectFailed="Không thể kết nối tới hệ phục vụ"
-Output.ConnectFail.Error="Lỗi bất ngờ xảy ra khi thử kết nối tới hệ phục vụ.  Biết thêm thông tin trong các tập tin log."
+Output.ConnectFail.InvalidStream="Không thể truy cập kênh chỉ định hoặc khóa stream, Vui lòng kiểm tra khóa stream của bạn.  Nếu nó đúng, có thể có một vấn đề về kết nối với máy chủ."
+Output.ConnectFail.Error="1 lỗi bất ngờ xảy ra khi thử kết nối tới máy chủ.  Thông tin thêm nằm trong log file."
 Output.ConnectFail.Disconnected="Ngắt kết nối từ máy chủ."
 
 Output.RecordFail.Title="Không thể bắt đầu ghi âm"
@@ -100,6 +120,7 @@ LicenseAgreement.Exit="Thoát"
 Remux.SourceFile="Ghi âm OBS"
 Remux.TargetFile="Tệp đích"
 Remux.Remux="Remux"
+Remux.OBSRecording="Ghi OBS"
 Remux.FinishedTitle="Remuxing đã hoàn thành"
 Remux.Finished="Ghi remuxed"
 Remux.FinishedError="Ghi âm remuxed, nhưng các tập tin có thể không đầy đủ"
@@ -125,6 +146,21 @@ Basic.DisplayCapture="Chụp màn hình"
 
 Basic.Main.PreviewConextMenu.Enable="Bật xem trước"
 
+ScaleFiltering="Scale Filtering"
+ScaleFiltering.Point="Point"
+ScaleFiltering.Bilinear="Bilinear"
+ScaleFiltering.Bicubic="Bicubic"
+ScaleFiltering.Lanczos="Lanczos"
+
+Deinterlacing="Deinterlacing"
+Deinterlacing.Discard="Discard"
+Deinterlacing.Retro="Retro"
+Deinterlacing.Blend="Blend"
+Deinterlacing.Blend2x="Blend 2x"
+Deinterlacing.Linear="Linear"
+Deinterlacing.Linear2x="Linear 2x"
+Deinterlacing.Yadif="Yadif"
+Deinterlacing.Yadif2x="Yadif 2x"
 
 
 Basic.Main.AddSceneDlg.Title="Thêm cảnh"
@@ -157,7 +193,9 @@ Basic.PropertiesWindow.ConfirmTitle="Thay đổi cài đặt"
 Basic.PropertiesWindow.Confirm="Có được lưu thay đổi.  Bạn có muốn giữ họ?"
 Basic.PropertiesWindow.NoProperties="Không có tài sản có sẵn"
 Basic.PropertiesWindow.AddFiles="Thêm tập tin"
+Basic.PropertiesWindow.AddDir="Thêm thư mục"
 Basic.PropertiesWindow.AddURL="Thêm đường dẫn/URL"
+Basic.PropertiesWindow.AddEditableListDir="Thêm thư mục vào '%1'"
 Basic.PropertiesWindow.AddEditableListFiles="Thêm các tệp vào '%1'"
 Basic.PropertiesWindow.AddEditableListEntry="Thêm mục nhập vào '%1'"
 Basic.PropertiesWindow.EditEditableListEntry="Chỉnh sửa mục nhập từ '%1'"
@@ -192,6 +230,7 @@ Basic.TransformWindow.Alignment="Vị trí liên kết"
 Basic.TransformWindow.BoundsType="Các giáp ranh hộp loại"
 Basic.TransformWindow.BoundsAlignment="Liên kết trong các giáp ranh hộp"
 Basic.TransformWindow.Bounds="Các giáp ranh hộp kích thước"
+Basic.TransformWindow.Crop="Cắt"
 
 Basic.TransformWindow.Alignment.TopLeft="Góc trên trái"
 Basic.TransformWindow.Alignment.TopCenter="Đỉnh Trung tâm"
@@ -217,49 +256,58 @@ Basic.Main.AddSourceHelp.Text="Bạn cần phải có ít nhất 1 cảnh để
 Basic.Main.Scenes="Cảnh"
 Basic.Main.Sources="Nguồn"
 Basic.Main.Connecting="Đang kết nối..."
-Basic.Main.StartRecording="Bắt đầu ghi âm"
+Basic.Main.StartRecording="Bắt đầu ghi"
 Basic.Main.StartStreaming="Bắt đầu Streaming"
-Basic.Main.StopRecording="Dừng ghi âm"
+Basic.Main.StopRecording="Dừng ghi"
+Basic.Main.StoppingRecording="Dừng ghi video..."
 Basic.Main.StopStreaming="Ngừng Streaming"
+Basic.Main.StoppingStreaming="Dừng stream..."
 Basic.Main.ForceStopStreaming="Ngừng Streaming (huỷ chậm trễ)"
 
 Basic.MainMenu.File="&Tập tin"
-Basic.MainMenu.File.Export="&Xuất khẩu"
-Basic.MainMenu.File.Import="&Nhập khẩu"
-Basic.MainMenu.File.ShowRecordings="Bản ghi âm & Hiển thị"
-Basic.MainMenu.File.Remux="Re & mux bản ghi âm"
+Basic.MainMenu.File.Export="&Xuất"
+Basic.MainMenu.File.Import="&Nhập"
+Basic.MainMenu.File.ShowRecordings="Hiển thị &Bản ghi"
+Basic.MainMenu.File.Remux="Re&mux bản ghi"
 Basic.MainMenu.File.Settings="&Cài đặt"
-Basic.MainMenu.File.ShowSettingsFolder="Hiển thị cài đặt thư mục"
+Basic.MainMenu.File.ShowSettingsFolder="Hiển thị thư mục cài đặt"
 Basic.MainMenu.File.ShowProfileFolder="Hiển thị thư mục hồ sơ"
+Basic.MainMenu.AlwaysOnTop="&Luôn trên đầu trang"
 Basic.MainMenu.File.Exit="&Thoát"
 
-Basic.MainMenu.Edit="& Chỉnh sửa"
-Basic.MainMenu.Edit.Undo="& Hoàn tác"
-Basic.MainMenu.Edit.Redo="& Làm lại"
-Basic.MainMenu.Edit.UndoAction="& Hoàn tác $1"
-Basic.MainMenu.Edit.RedoAction="& Làm lại $1"
-Basic.MainMenu.Edit.Transform="Biến đổi"
-Basic.MainMenu.Edit.Transform.EditTransform="& Chỉnh sửa biến đổi..."
-Basic.MainMenu.Edit.Transform.ResetTransform="& Đặt lại biến đổi"
+Basic.MainMenu.Edit="&Chỉnh sửa"
+Basic.MainMenu.Edit.Undo="&Hoàn tác"
+Basic.MainMenu.Edit.Redo="&Làm lại"
+Basic.MainMenu.Edit.UndoAction="&Hoàn tác $1"
+Basic.MainMenu.Edit.RedoAction="&Làm lại $1"
+Basic.MainMenu.Edit.LockPreview="&Khóa xem trước"
+Basic.MainMenu.Edit.Transform="&Biến đổi"
+Basic.MainMenu.Edit.Transform.EditTransform="&Chỉnh sửa biến đổi..."
+Basic.MainMenu.Edit.Transform.ResetTransform="&Đặt lại biến đổi"
 Basic.MainMenu.Edit.Transform.Rotate90CW="Xoay 90 độ bên phải"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Xoay 90 độ bên trái"
 Basic.MainMenu.Edit.Transform.Rotate180="Xoay 180 Ä‘á»™"
-Basic.MainMenu.Edit.Transform.FlipHorizontal="Flip & ngang"
-Basic.MainMenu.Edit.Transform.FlipVertical="Flip & dọc"
-Basic.MainMenu.Edit.Transform.FitToScreen="Phù hợp với màn hình"
-Basic.MainMenu.Edit.Transform.StretchToScreen="& Căng để màn hình"
+Basic.MainMenu.Edit.Transform.FlipHorizontal="Lật &Ngang"
+Basic.MainMenu.Edit.Transform.FlipVertical="Lật &Dọc"
+Basic.MainMenu.Edit.Transform.FitToScreen="&Vừa với màn hình"
+Basic.MainMenu.Edit.Transform.StretchToScreen="&Giãn ra để lấp đầy m.hình"
 Basic.MainMenu.Edit.Transform.CenterToScreen="& Trung tâm màn hình"
-Basic.MainMenu.Edit.Order="& Đặt hàng"
-Basic.MainMenu.Edit.Order.MoveUp="Chuyển Lên"
-Basic.MainMenu.Edit.Order.MoveDown="Chuyển xuống"
-Basic.MainMenu.Edit.Order.MoveToTop="Chuyển đến đầu trang"
-Basic.MainMenu.Edit.Order.MoveToBottom="Chuyển đến dưới cùng"
-Basic.MainMenu.Edit.AdvAudio="Thuộc tính âm thanh nâng cao"
+Basic.MainMenu.Edit.Order="&Đặt"
+Basic.MainMenu.Edit.Order.MoveUp="Chuyển &Lên"
+Basic.MainMenu.Edit.Order.MoveDown="Chuyển &Xuống"
+Basic.MainMenu.Edit.Order.MoveToTop="Chuyển đến &Đầu"
+Basic.MainMenu.Edit.Order.MoveToBottom="Chuyển xuống &Dưới"
+Basic.MainMenu.Edit.AdvAudio="Các thuộc tính âm thanh nâng cao"
 
+Basic.MainMenu.View="&Hiển thị"
+Basic.MainMenu.View.Toolbars="&Thanh công cụ"
+Basic.MainMenu.View.Toolbars.Listboxes="&Listboxes"
+Basic.MainMenu.View.StatusBar="&Thanh trạng thái"
 
-Basic.MainMenu.SceneCollection="& Cảnh bộ sưu tập"
-Basic.MainMenu.Profile="& Hồ sơ"
+Basic.MainMenu.SceneCollection="& Bộ sưu tập cảnh"
+Basic.MainMenu.Profile="&Hồ sơ"
 
+Basic.MainMenu.Tools="&Công cụ"
 
 Basic.MainMenu.Help="&Trợ giúp"
 Basic.MainMenu.Help.Website="Ghé thăm Website"
@@ -277,6 +325,8 @@ Basic.Settings.Confirm="Bạn đã lưu thay đổi.  Lưu thay đổi?"
 Basic.Settings.General="Chung"
 Basic.Settings.General.Theme="Theme"
 Basic.Settings.General.Language="Ngôn ngữ"
+Basic.Settings.General.HideProjectorCursor="Ẩn con trỏ chuột trên màn chiếu"
+Basic.Settings.General.ProjectorAlwaysOnTop="Làm cho màn chiếu luôn luôn trên đầu"
 
 Basic.Settings.Stream="Stream"
 Basic.Settings.Stream.StreamType="Kiểu Stream"
@@ -301,6 +351,9 @@ Basic.Settings.Output.Simple.Warn.Lossless="Cảnh báo: Lossless chất lượn
 Basic.Settings.Output.Simple.Warn.Lossless.Msg="Bạn có chắc bạn muốn sử dụng lossless chất lượng?"
 Basic.Settings.Output.Simple.Warn.Lossless.Title="Lossless chất lượng cảnh báo!"
 Basic.Settings.Output.Simple.Encoder.Software="Phần mềm (x 264)"
+Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Phần cứng (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Phần cứng (AMD)"
+Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Phần cứng (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Phần mềm (x 264 sử dụng CPU thấp cài sẵn, tăng kích thước)"
 Basic.Settings.Output.VideoBitrate="Video Bitrate"
 Basic.Settings.Output.AudioBitrate="Âm thanh Bitrate"
@@ -327,6 +380,8 @@ Basic.Settings.Output.Adv.Recording.Type="Loại"
 Basic.Settings.Output.Adv.Recording.Type.Standard="Chuản"
 Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Tùy chỉnh đầu ra (FFmpeg)"
 Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Sử dụng dòng mã hóa)"
+Basic.Settings.Output.Adv.Recording.Filename="Định dạng tệp tin"
+Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Ghi đè nếu tập tin tồn tại"
 Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg ra loại"
 Basic.Settings.Output.Adv.FFmpeg.Type.URL="Sản lượng để URL"
 Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Đầu ra vào tập tin"
@@ -374,27 +429,35 @@ Basic.Settings.Audio="Âm thanh"
 Basic.Settings.Audio.SampleRate="Tỷ lệ mẫu"
 Basic.Settings.Audio.Channels="Kênh Tivi"
 Basic.Settings.Audio.DesktopDevice="Thiết bị âm thanh máy tính"
-Basic.Settings.Audio.DesktopDevice2="Thiết bị âm thanh máy tính"
-Basic.Settings.Audio.AuxDevice="Mic/liên minh thiết bị âm thanh"
-Basic.Settings.Audio.AuxDevice2="Mic/liên minh thiết bị âm thanh 2"
-Basic.Settings.Audio.AuxDevice3="Mic/liên minh thiết bị âm thanh 3"
-Basic.Settings.Audio.EnablePushToMute="Sử đẩy để tắt tiếng"
-Basic.Settings.Audio.PushToMuteDelay="Sự chậm trễ đẩy để tắt tiếng"
-Basic.Settings.Audio.EnablePushToTalk="Sá»­ Push-to-talk"
-Basic.Settings.Audio.PushToTalkDelay="Push-to-talk chậm trễ"
+Basic.Settings.Audio.DesktopDevice2="Thiết bị âm thanh máy tính 2"
+Basic.Settings.Audio.AuxDevice="Thiết bị âm thanh mic/phụ trợ"
+Basic.Settings.Audio.AuxDevice2="Thiết bị âm thanh mic/phụ trợ 2"
+Basic.Settings.Audio.AuxDevice3="Thiết bị âm thanh mic/phụ trợ 3"
+Basic.Settings.Audio.EnablePushToMute="Bật bấm để tắt tiếng"
+Basic.Settings.Audio.PushToMuteDelay="Bấm để tắt tiếng trễ"
+Basic.Settings.Audio.EnablePushToTalk="Bật bắm để nói"
+Basic.Settings.Audio.PushToTalkDelay="Bấm để nói trễ"
+Basic.Settings.Audio.UnknownAudioDevice="[Thiết bị không được kết nối hoặc không sẵn dùng]"
 
 Basic.Settings.Advanced="Nâng cao"
-Basic.Settings.Advanced.FormatWarning="Cảnh báo: Định dạng màu sắc khác hơn so với NV12 chủ yếu dành cho ghi âm, và không được khuyến cáo khi streaming.  Trực tuyến có thể phải tăng sử dụng CPU do chuyển đổi định dạng màu sắc."
+Basic.Settings.Advanced.General.ProcessPriority="Chương trình ưu tiên"
+Basic.Settings.Advanced.General.ProcessPriority.High="Cao"
+Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Trên bình thường"
+Basic.Settings.Advanced.General.ProcessPriority.Normal="Thường"
+Basic.Settings.Advanced.General.ProcessPriority.Idle="Rảnh"
+Basic.Settings.Advanced.FormatWarning="Cảnh báo: Định dạng màu sắc khác với NV12 chủ yếu dành cho ghi âm và không được khuyến cáo khi streaming.  Stream có thể làm tăng sử dụng CPU do phải chuyển đổi định dạng màu sắc."
 Basic.Settings.Advanced.Audio.BufferingTime="Âm thanh thời gian đệm"
 Basic.Settings.Advanced.Video.ColorFormat="Định dạng màu sắc"
 Basic.Settings.Advanced.Video.ColorSpace="Không gian màu YUV"
 Basic.Settings.Advanced.Video.ColorRange="Phạm vi màu YUV"
 Basic.Settings.Advanced.Video.ColorRange.Partial="Một phần"
 Basic.Settings.Advanced.Video.ColorRange.Full="Đầy đủ"
-Basic.Settings.Advanced.StreamDelay="Sự chậm trễ Stream"
-Basic.Settings.Advanced.StreamDelay.Duration="Thời gian (phút)"
-Basic.Settings.Advanced.StreamDelay.Preserve="Bảo tồn cutoff điểm (tăng chậm trễ) khi kết nối lại"
-Basic.Settings.Advanced.StreamDelay.MemoryUsage="Sử dụng ước tính bộ nhớ: %1 MB"
+Basic.Settings.Advanced.StreamDelay="Stream trá»…"
+Basic.Settings.Advanced.StreamDelay.Duration="Thời gian (giây)"
+Basic.Settings.Advanced.StreamDelay.Preserve="Giữ điểm cắt (tăng chậm trễ) khi kết nối lại"
+Basic.Settings.Advanced.StreamDelay.MemoryUsage="Ước tính bộ nhớ sử dụng: %1 MB"
+Basic.Settings.Advanced.Network="Mạng"
+Basic.Settings.Advanced.Network.BindToIP="Liên kết với IP"
 
 Basic.AdvAudio="Thuộc tính âm thanh nâng cao"
 Basic.AdvAudio.Name="Tên"
@@ -407,13 +470,12 @@ Basic.AdvAudio.AudioTracks="Bài hát"
 Basic.Settings.Hotkeys="Phím nóng"
 Basic.Settings.Hotkeys.Pair="Tổ hợp phím được chia sẻ với '%1' hành động như chuyển"
 
-Basic.Hotkeys.StartStreaming="Bắt đầu Streaming"
-Basic.Hotkeys.StopStreaming="Ngừng Streaming"
-Basic.Hotkeys.StartRecording="Bắt đầu ghi âm"
-Basic.Hotkeys.StopRecording="Dừng ghi âm"
 Basic.Hotkeys.SelectScene="Chuyển cảnh"
 
+Basic.SystemTray.Show="Hiện"
+Basic.SystemTray.Hide="Ẩn"
 
+Basic.SystemTray.Message.Reconnecting="Ngắt kết nối.  Đang kết nối lại..."
 
 Hotkeys.Insert="Chèn"
 Hotkeys.Delete="Xoá"
@@ -453,12 +515,12 @@ Hotkeys.MouseButton="Chuá»™t %1"
 
 Mute="Tắt Tiếng"
 Unmute="Bật tiếng"
-Push-to-mute="Đẩy để tắt tiếng"
-Push-to-talk="Push-to-talk"
+Push-to-mute="Bấm để tắt tiếng"
+Push-to-talk="Bấm để nói"
 
 SceneItemShow="Hiển thị '%1'"
 SceneItemHide="Ẩn '%1'"
 
-OutputWarnings.NoTracksSelected="Bạn phải chọn ít nhất một ca khúc"
-OutputWarnings.MultiTrackRecording="Chú ý: Một số định dạng (chẳng hạn như FLV) không hỗ trợ nhiều bài hát cho một ghi âm"
+OutputWarnings.NoTracksSelected="Bạn phải chọn ít nhất một track"
+OutputWarnings.MultiTrackRecording="Chú ý: Một số định dạng (chẳng hạn như FLV) không hỗ trợ nhiều track cho mỗi video"
 
diff --git a/UI/data/locale/zh-CN.ini b/UI/data/locale/zh-CN.ini
index 2590603..bc07812 100644
--- a/UI/data/locale/zh-CN.ini
+++ b/UI/data/locale/zh-CN.ini
@@ -49,6 +49,26 @@ Right="右"
 Top="上"
 Bottom="下"
 Reset="重置"
+Hours="小时"
+Minutes="分钟"
+Seconds="秒"
+Deprecated="不推荐使用"
+ReplayBuffer="重拨缓存"
+Import="导入"
+Export="导出"
+
+Updater.Title="有可用的更新"
+Updater.Text="有可用的新版本:"
+Updater.UpdateNow="现在更新"
+Updater.RemindMeLater="稍后再提醒我"
+Updater.Skip="跳过版本"
+Updater.Running.Title="程序当前处于活跃状态"
+Updater.Running.Text="输出当前处于活动状态, 请关闭任何活跃的输出, 然后尝试更新"
+Updater.NoUpdatesAvailable.Title="无可用更新"
+Updater.NoUpdatesAvailable.Text="没有更新当前可用"
+Updater.FailedToLaunch="启动更新程序失败"
+Updater.GameCaptureActive.Title="游戏捕获活跃"
+Updater.GameCaptureActive.Text="游戏捕获钩子库正在使用中, 请关闭所有正在被捕获的游戏/程序(或重新启动 windows), 然后重试."
 
 QuickTransitions.SwapScenes="在过渡动画后交换预览/输出场景"
 QuickTransitions.SwapScenesTT="在过渡后,交换预览和输出场景(如果输出的原始场景仍然存在). \n 这个不会撤消任何可能对输出的原始场景的更改."
@@ -90,6 +110,11 @@ ConfirmRemove.Title="确认移除"
 ConfirmRemove.Text="确定要删除 '$1' 吗?"
 ConfirmRemove.TextMultiple="您确定要删除 %1 项目吗?"
 
+Output.StartStreamFailed="启动推流失败"
+Output.StartRecordingFailed="启动录像失败"
+Output.StartReplayFailed="启动回放缓存失败"
+Output.StartFailedGeneric="启动输出失败. 请检查日志来了解细节.\n\n注意: 如果你使用的是 NVENC 或 AMD 编码器, 请确保您的视频驱动程序是最新的."
+
 Output.ConnectFail.Title="连接失败"
 Output.ConnectFail.BadPath="无效的路径或URL。请检查您的设置以确认它们是有效的。"
 Output.ConnectFail.ConnectFailed="无法连接到服务器"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="磁盘空间不足"
 Output.RecordNoSpace.Msg="没有足够磁盘空间来继续录像."
 Output.RecordError.Title="录像错误"
 Output.RecordError.Msg="录像时发生未指定错误."
+Output.ReplayBuffer.NoHotkey.Title="没有快捷键设置!"
+Output.ReplayBuffer.NoHotkey.Msg="没有为回放缓存设置快捷键. 请设置保存跨借鉴来用于保存回放录像."
 
 Output.BadPath.Title="错误的文件路径"
 Output.BadPath.Text="无效的输出路径。请检查您的设置,确认文件路径是否有效。"
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="上场优先"
 Deinterlacing.BottomFieldFirst="下场优先"
 
+VolControl.SliderUnmuted="音量滑动条 '%1': %2"
+VolControl.SliderMuted="音量滑动条 '%1': %2 (当前静音)"
+VolControl.Mute="静音 '%1'"
+VolControl.Properties="属性 '%1'"
+
 Basic.Main.AddSceneDlg.Title="添加场景"
 Basic.Main.AddSceneDlg.Text="请输入场景名称"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="场景"
 Basic.Main.Sources="来源"
 Basic.Main.Connecting="连接中..."
 Basic.Main.StartRecording="开始录制"
+Basic.Main.StartReplayBuffer="开始回放缓存"
 Basic.Main.StartStreaming="开始串流"
 Basic.Main.StopRecording="停止录制"
 Basic.Main.StoppingRecording="停止录制..."
+Basic.Main.StopReplayBuffer="停止回放缓存"
+Basic.Main.StoppingReplayBuffer="正在停止回放缓存..."
 Basic.Main.StopStreaming="停止串流"
 Basic.Main.StoppingStreaming="停止推流..."
 Basic.Main.ForceStopStreaming="停止流 (放弃延迟)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="重做 (&R)"
 Basic.MainMenu.Edit.UndoAction="撤消 $1 (&U)"
 Basic.MainMenu.Edit.RedoAction="重做 $1 (&R)"
 Basic.MainMenu.Edit.LockPreview="锁定预览 (&L)"
+Basic.MainMenu.Edit.Scale="预览 & 缩放"
+Basic.MainMenu.Edit.Scale.Window="缩放至窗口"
+Basic.MainMenu.Edit.Scale.Canvas="背景 (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="输出 (%1x%2)"
 Basic.MainMenu.Edit.Transform="变换 (&T)"
 Basic.MainMenu.Edit.Transform.EditTransform="编辑变换 (&E)"
+Basic.MainMenu.Edit.Transform.CopyTransform="复制变换"
+Basic.MainMenu.Edit.Transform.PasteTransform="粘贴变换"
 Basic.MainMenu.Edit.Transform.ResetTransform="重置变换 (&R)"
 Basic.MainMenu.Edit.Transform.Rotate90CW="顺时针旋转 90 度(&9)"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="逆时针旋转 90 度(&D)"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="状态栏 (&S)"
 
 Basic.MainMenu.SceneCollection="场景集合 (&S)"
 Basic.MainMenu.Profile="配置文件 (&P)"
+Basic.MainMenu.Profile.Import="导入配置文件"
+Basic.MainMenu.Profile.Export="导出配置文件"
+Basic.MainMenu.SceneCollection.Import="导入场景集合"
+Basic.MainMenu.SceneCollection.Export="导出场景集合"
+Basic.MainMenu.Profile.Exists="配置文件已存在"
+Basic.MainMenu.SceneCollection.Exists="场景机会已存在"
 
 Basic.MainMenu.Tools="工具 (&T)"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="你有未保存的更改。保存更改吗?"
 Basic.Settings.General="通用"
 Basic.Settings.General.Theme="主题"
 Basic.Settings.General.Language="语言"
+Basic.Settings.General.EnableAutoUpdates="启动时自动检查更新"
 Basic.Settings.General.WarnBeforeStartingStream="启动流时显示确认对话框"
 Basic.Settings.General.WarnBeforeStoppingStream="停止流时显示确认对话框"
+Basic.Settings.General.Projectors="投影仪"
 Basic.Settings.General.HideProjectorCursor="隐藏投影仪上的光标"
 Basic.Settings.General.ProjectorAlwaysOnTop="使投影器总是置顶"
 Basic.Settings.General.Snapping="源对齐方式"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="对齐源跟其他的源"
 Basic.Settings.General.SnapDistance="对齐的敏感性"
 Basic.Settings.General.RecordWhenStreaming="当推流时自动录像"
 Basic.Settings.General.KeepRecordingWhenStreamStops="当推流停止时保持录像"
-Basic.Settings.General.SysTrayEnabled="启用系统托盘图标"
+Basic.Settings.General.ReplayBufferWhileStreaming="推流时自动启动重播缓冲区"
+Basic.Settings.General.KeepReplayBufferStreamStops="推流停止时重播缓冲区保持活动状态"
+Basic.Settings.General.SysTray="系统托盘"
 Basic.Settings.General.SysTrayWhenStarted="开始时最小化到系统托盘"
+Basic.Settings.General.SystemTrayHideMinimize="总是最小化到系统托盘, 而不是任务栏"
+Basic.Settings.General.SaveProjectors="退出时保存投影仪"
 
 Basic.Settings.Stream="串流"
 Basic.Settings.Stream.StreamType="串流类型"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="输出模式"
 Basic.Settings.Output.Mode.Simple="简单"
 Basic.Settings.Output.Mode.Adv="高级"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg 输出"
+Basic.Settings.Output.UseReplayBuffer="启用回放缓存"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="最大回放时间(秒)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="最大内存(Mb)"
+Basic.Settings.Output.ReplayBuffer.Estimate="估计内存使用率: %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="无法估计内存使用率. 请设置最大内存限制."
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(注意: 确保在快捷键部分设置一个回放缓冲区的快捷键)"
+Basic.Settings.Output.ReplayBuffer.Prefix="回放缓存文件名前缀"
+Basic.Settings.Output.ReplayBuffer.Suffix="后缀"
 Basic.Settings.Output.Simple.SavePath="录像路径"
 Basic.Settings.Output.Simple.RecordingQuality="录像质量"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="与流相同"
@@ -369,6 +430,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="无损质量警告!"
 Basic.Settings.Output.Simple.Warn.MultipleQSV="警告: 当同时推流和录像时, 你不能使用多个单独的 QSV 编码器.  如果你想要同时推流和录像, 请更改录像的编码器或者推流的编码器."
 Basic.Settings.Output.Simple.Encoder.Software="软件 (x264)"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="硬件 (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="硬件 (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="硬件 (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="软件 (x 264 低 CPU 使用率预设,增加文件大小)"
 Basic.Settings.Output.VideoBitrate="视频比特率"
@@ -390,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="轨道 1"
 Basic.Settings.Output.Adv.Audio.Track2="轨道 2"
 Basic.Settings.Output.Adv.Audio.Track3="轨道 3"
 Basic.Settings.Output.Adv.Audio.Track4="轨道 4"
+Basic.Settings.Output.Adv.Audio.Track5="轨道 5"
+Basic.Settings.Output.Adv.Audio.Track6="轨道 6"
 
 Basic.Settings.Output.Adv.Recording="录像"
 Basic.Settings.Output.Adv.Recording.Type="类型"
@@ -417,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="视频编码器设置 (如果
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="音频编码器"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="视频编码器设置 (如果有)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer 设置 (如果有)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="关键帧间隔 (帧)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="显示所有编解码器 (即使可能不兼容)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -470,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV 颜色空间"
 Basic.Settings.Advanced.Video.ColorRange="YUV 颜色范围"
 Basic.Settings.Advanced.Video.ColorRange.Partial="局部"
 Basic.Settings.Advanced.Video.ColorRange.Full="全部"
+Basic.Settings.Advanced.Audio.MonitoringDevice="音频监测设备"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="默认"
 Basic.Settings.Advanced.StreamDelay="流延迟"
 Basic.Settings.Advanced.StreamDelay.Duration="持续时间 (秒)"
 Basic.Settings.Advanced.StreamDelay.Preserve="重新连接时保持截止点 (增加延迟)"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="估计的内存使用率: %1 MB"
 Basic.Settings.Advanced.Network="网络"
 Basic.Settings.Advanced.Network.BindToIP="绑定 IP"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="启用新的网络代码"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="低延迟模式"
 
 Basic.AdvAudio="高级音频属性"
 Basic.AdvAudio.Name="名称"
@@ -483,15 +553,15 @@ Basic.AdvAudio.Volume="音量 (%)"
 Basic.AdvAudio.Mono="下降混合为单声道"
 Basic.AdvAudio.Panning="平移"
 Basic.AdvAudio.SyncOffset="同步偏移 (毫秒)"
+Basic.AdvAudio.Monitoring="音频监测"
+Basic.AdvAudio.Monitoring.None="关闭监视"
+Basic.AdvAudio.Monitoring.MonitorOnly="仅显示器(静音输出)"
+Basic.AdvAudio.Monitoring.Both="监视器和输出"
 Basic.AdvAudio.AudioTracks="轨道"
 
 Basic.Settings.Hotkeys="热键"
 Basic.Settings.Hotkeys.Pair="作为切换的键组合与 '%1' 共享"
 
-Basic.Hotkeys.StartStreaming="开始串流"
-Basic.Hotkeys.StopStreaming="停止串流"
-Basic.Hotkeys.StartRecording="开始录像"
-Basic.Hotkeys.StopRecording="停止录像"
 Basic.Hotkeys.SelectScene="切换到场景"
 
 Basic.SystemTray.Show="显示"
@@ -545,4 +615,5 @@ SceneItemHide="隐藏 '%1'"
 
 OutputWarnings.NoTracksSelected="您必须选择至少一个轨道"
 OutputWarnings.MultiTrackRecording="警告: 某些格式 (如 FLV) 不支持每个录像多个轨道"
+OutputWarnings.MP4Recording="警告︰ 录制保存到 MP4 将无法恢复,如果该文件不能完成 (例如由于蓝屏死机,掉电等)。如果您想要记录多个音频轨道考虑使用 MKV 然后在它完成后 remux 录制到 mp4 (文件 -> Remux 录制文件)"
 
diff --git a/UI/data/locale/zh-TW.ini b/UI/data/locale/zh-TW.ini
index 12e1fd6..674fa19 100644
--- a/UI/data/locale/zh-TW.ini
+++ b/UI/data/locale/zh-TW.ini
@@ -49,6 +49,26 @@ Right="右"
 Top="上"
 Bottom="下"
 Reset="重置"
+Hours="小時"
+Minutes="分鐘"
+Seconds="秒"
+Deprecated="不再維護"
+ReplayBuffer="重播緩衝"
+Import="匯入"
+Export="匯出"
+
+Updater.Title="有新更新"
+Updater.Text="有新更新︰"
+Updater.UpdateNow="立即更新"
+Updater.RemindMeLater="稍後提醒我"
+Updater.Skip="略過此版本"
+Updater.Running.Title="程式處於活動狀態"
+Updater.Running.Text="輸出處於活動狀態,請關閉活動中的輸出,然後再嘗試更新"
+Updater.NoUpdatesAvailable.Title="沒有更新"
+Updater.NoUpdatesAvailable.Text="沒有更新"
+Updater.FailedToLaunch="啟動更新程式失敗"
+Updater.GameCaptureActive.Title="遊戲擷取使用中"
+Updater.GameCaptureActive.Text="遊戲擷取函式庫正在使用中。 請關閉所有被擷取的遊戲/程式 (或重新開機 windows),然後重試。"
 
 QuickTransitions.SwapScenes="轉場後交換預覽/輸出場景"
 QuickTransitions.SwapScenesTT="(如果輸出的原始場景仍然存在) 轉場後交換預覽和輸出場景。\n這並不會復原任何對輸出原始場景所作的改動。"
@@ -90,6 +110,11 @@ ConfirmRemove.Title="確認刪除?"
 ConfirmRemove.Text="您確定要刪除「$1」?"
 ConfirmRemove.TextMultiple="您確定要移除這%1個項目嘛?"
 
+Output.StartStreamFailed="無法開始串流"
+Output.StartRecordingFailed="無法開始錄影"
+Output.StartReplayFailed="無法啟動重播緩衝區"
+Output.StartFailedGeneric="啟動輸出失敗。 詳情請看 Log 檔。\n\n注意︰ 如果你使用 NVENC 或 AMD 編碼器,請確保您的視頻驅動程式是最新。"
+
 Output.ConnectFail.Title="連線失敗"
 Output.ConnectFail.BadPath="無效的路徑或 URL。 請確認您的設定是正確的。"
 Output.ConnectFail.ConnectFailed="與伺服器連線失敗。"
@@ -103,6 +128,8 @@ Output.RecordNoSpace.Title="硬碟空間不足"
 Output.RecordNoSpace.Msg="沒有足夠的空間存放錄製影片"
 Output.RecordError.Title="錄製錯誤"
 Output.RecordError.Msg="在錄製時發生了預料外的錯誤。"
+Output.ReplayBuffer.NoHotkey.Title="沒有設定熱鍵 !"
+Output.ReplayBuffer.NoHotkey.Msg="沒有為重播緩衝設定儲存重播熱鍵。請設定\"儲存重播\"熱鍵以保存重播。"
 
 Output.BadPath.Title="無效的路徑"
 Output.BadPath.Text="無效的輸出路徑。 請確認您的檔案路徑是正確的。"
@@ -164,6 +191,11 @@ Deinterlacing.Yadif2x="Yadif 2x"
 Deinterlacing.TopFieldFirst="由偶數場開始"
 Deinterlacing.BottomFieldFirst="由奇數場開始"
 
+VolControl.SliderUnmuted="'%1' 的音量滑桿︰ %2"
+VolControl.SliderMuted="'%1' 的音量滑桿︰ %2 (目前靜音中)"
+VolControl.Mute="靜音 '%1'"
+VolControl.Properties="'%1' 的屬性"
+
 Basic.Main.AddSceneDlg.Title="新增場景"
 Basic.Main.AddSceneDlg.Text="請輸入場景名稱"
 
@@ -258,9 +290,12 @@ Basic.Main.Scenes="場景"
 Basic.Main.Sources="來源"
 Basic.Main.Connecting="連線中……"
 Basic.Main.StartRecording="開始錄製"
+Basic.Main.StartReplayBuffer="開始重播緩衝"
 Basic.Main.StartStreaming="開始串流"
 Basic.Main.StopRecording="停止錄製"
 Basic.Main.StoppingRecording="停止錄製..."
+Basic.Main.StopReplayBuffer="停止重播緩衝"
+Basic.Main.StoppingReplayBuffer="正在停止重播緩衝..."
 Basic.Main.StopStreaming="停止串流"
 Basic.Main.StoppingStreaming="停止串流..."
 Basic.Main.ForceStopStreaming="停止實況(丟棄延遲)"
@@ -282,8 +317,14 @@ Basic.MainMenu.Edit.Redo="重做 (&R)"
 Basic.MainMenu.Edit.UndoAction="復原 $1 (&U)"
 Basic.MainMenu.Edit.RedoAction="重做 $1 (&R)"
 Basic.MainMenu.Edit.LockPreview="鎖定預覽 (&L)"
+Basic.MainMenu.Edit.Scale="預覽與縮放"
+Basic.MainMenu.Edit.Scale.Window="縮放至視窗"
+Basic.MainMenu.Edit.Scale.Canvas="畫布 (%1x%2)"
+Basic.MainMenu.Edit.Scale.Output="輸出 (%1x%2)"
 Basic.MainMenu.Edit.Transform="變型 (&T)"
 Basic.MainMenu.Edit.Transform.EditTransform="編輯變型設定…… (&E)"
+Basic.MainMenu.Edit.Transform.CopyTransform="複製變型"
+Basic.MainMenu.Edit.Transform.PasteTransform="貼上變型"
 Basic.MainMenu.Edit.Transform.ResetTransform="重設變型設定 (&R)"
 Basic.MainMenu.Edit.Transform.Rotate90CW="順時針旋轉 90°"
 Basic.MainMenu.Edit.Transform.Rotate90CCW="逆時針旋轉 90°"
@@ -308,6 +349,12 @@ Basic.MainMenu.View.StatusBar="狀態列(&S)"
 
 Basic.MainMenu.SceneCollection="場景群組 (&S)"
 Basic.MainMenu.Profile="設定檔 (&P)"
+Basic.MainMenu.Profile.Import="匯入設定檔"
+Basic.MainMenu.Profile.Export="匯出設定檔"
+Basic.MainMenu.SceneCollection.Import="匯入場景群組"
+Basic.MainMenu.SceneCollection.Export="匯出場景群組"
+Basic.MainMenu.Profile.Exists="已有該設定檔"
+Basic.MainMenu.SceneCollection.Exists="已有該場景群組"
 
 Basic.MainMenu.Tools="工具(&T)"
 
@@ -327,8 +374,10 @@ Basic.Settings.Confirm="您有未儲存的修改。 是否儲存?"
 Basic.Settings.General="一般"
 Basic.Settings.General.Theme="佈景主題"
 Basic.Settings.General.Language="語言"
+Basic.Settings.General.EnableAutoUpdates="啟動時自動檢查更新"
 Basic.Settings.General.WarnBeforeStartingStream="啟動串流時顯示確認對話框"
 Basic.Settings.General.WarnBeforeStoppingStream="停止串流時顯示確認對話框"
+Basic.Settings.General.Projectors="投影"
 Basic.Settings.General.HideProjectorCursor="當游標在投影上時隱藏游標"
 Basic.Settings.General.ProjectorAlwaysOnTop="讓投影總是在最上層"
 Basic.Settings.General.Snapping="貼齊對準來源"
@@ -338,8 +387,12 @@ Basic.Settings.General.SourceSnapping="來源與其他來源貼齊"
 Basic.Settings.General.SnapDistance="貼齊敏感度"
 Basic.Settings.General.RecordWhenStreaming="串流時自動錄製"
 Basic.Settings.General.KeepRecordingWhenStreamStops="串流停止時繼續錄製"
-Basic.Settings.General.SysTrayEnabled="啟用系統列圖示"
+Basic.Settings.General.ReplayBufferWhileStreaming="串流時自動啟動重播緩衝"
+Basic.Settings.General.KeepReplayBufferStreamStops="串流停止時依然保持啟用重播緩衝"
+Basic.Settings.General.SysTray="系統工具列"
 Basic.Settings.General.SysTrayWhenStarted="開始時最小化至系統列"
+Basic.Settings.General.SystemTrayHideMinimize="總是最小化到系統列,而非工作列"
+Basic.Settings.General.SaveProjectors="退出時保存投影設定"
 
 Basic.Settings.Stream="串流"
 Basic.Settings.Stream.StreamType="串流類型"
@@ -354,6 +407,14 @@ Basic.Settings.Output.Mode="輸出模式"
 Basic.Settings.Output.Mode.Simple="簡易"
 Basic.Settings.Output.Mode.Adv="進階"
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg 輸出"
+Basic.Settings.Output.UseReplayBuffer="啟用重播緩衝"
+Basic.Settings.Output.ReplayBuffer.SecondsMax="最大重播時間(秒)"
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="最大記憶體使用量(MB)"
+Basic.Settings.Output.ReplayBuffer.Estimate="估計記憶體使用量︰ %1 MB"
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="無法預估記憶體使用量。請設定最大記憶體使用量。"
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(注意:請確定在熱鍵區有為重播緩衝設定熱鍵)"
+Basic.Settings.Output.ReplayBuffer.Prefix="重播緩衝檔案名稱前綴"
+Basic.Settings.Output.ReplayBuffer.Suffix="後綴"
 Basic.Settings.Output.Simple.SavePath="錄影路徑"
 Basic.Settings.Output.Simple.RecordingQuality="錄影畫質"
 Basic.Settings.Output.Simple.RecordingQuality.Stream="與串流同等畫質"
@@ -369,6 +430,7 @@ Basic.Settings.Output.Simple.Warn.Lossless.Title="無損畫質警告!"
 Basic.Settings.Output.Simple.Warn.MultipleQSV="警告︰同時串流和錄影時,不能使用多個不同的 QSV 編碼器。如果你想要在同一時間串流和錄影,請更改錄影編碼器或串流編碼器。"
 Basic.Settings.Output.Simple.Encoder.Software="軟體編碼( x264 )"
 Basic.Settings.Output.Simple.Encoder.Hardware.QSV="硬體編碼 (QSV)"
+Basic.Settings.Output.Simple.Encoder.Hardware.AMD="硬體 (AMD)"
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="硬體編碼 (NVENC)"
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="軟體編碼( x264 預設低 CPU 使用率,將增加檔案容量 )"
 Basic.Settings.Output.VideoBitrate="影像位元率(kbit/s)"
@@ -390,6 +452,8 @@ Basic.Settings.Output.Adv.Audio.Track1="音軌 1"
 Basic.Settings.Output.Adv.Audio.Track2="音軌 2"
 Basic.Settings.Output.Adv.Audio.Track3="音軌 3"
 Basic.Settings.Output.Adv.Audio.Track4="音軌 4"
+Basic.Settings.Output.Adv.Audio.Track5="音軌 5"
+Basic.Settings.Output.Adv.Audio.Track6="音軌 6"
 
 Basic.Settings.Output.Adv.Recording="錄影"
 Basic.Settings.Output.Adv.Recording.Type="é¡žåž‹"
@@ -417,6 +481,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="影像編碼設定(如果
 Basic.Settings.Output.Adv.FFmpeg.AEncoder="音效編碼器"
 Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="音效編碼設定(如果有才啟用)"
 Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer 設定(如果有才啟用)"
+Basic.Settings.Output.Adv.FFmpeg.GOPSize="關鍵訊框間隔 (訊框)"
+Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="顯示所有編碼解碼器 (即使可能不相容)"
 
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z"
 
@@ -470,12 +536,16 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV 色彩空間"
 Basic.Settings.Advanced.Video.ColorRange="YUV 顏色範圍"
 Basic.Settings.Advanced.Video.ColorRange.Partial="部份"
 Basic.Settings.Advanced.Video.ColorRange.Full="完整"
+Basic.Settings.Advanced.Audio.MonitoringDevice="音訊監測設備"
+Basic.Settings.Advanced.Audio.MonitoringDevice.Default="預設裝置"
 Basic.Settings.Advanced.StreamDelay="實況延遲"
 Basic.Settings.Advanced.StreamDelay.Duration="延遲(秒)"
 Basic.Settings.Advanced.StreamDelay.Preserve="重新連線時維持截止點 (增加延遲)"
 Basic.Settings.Advanced.StreamDelay.MemoryUsage="預計記憶體使用率: %1 MB"
 Basic.Settings.Advanced.Network="網路"
 Basic.Settings.Advanced.Network.BindToIP="綁定到 IP"
+Basic.Settings.Advanced.Network.EnableNewSocketLoop="啟用新的網路程式碼"
+Basic.Settings.Advanced.Network.EnableLowLatencyMode="低延遲模式"
 
 Basic.AdvAudio="進階音訊屬性"
 Basic.AdvAudio.Name="名稱"
@@ -483,15 +553,15 @@ Basic.AdvAudio.Volume="音量(%)"
 Basic.AdvAudio.Mono="混降為單聲道"
 Basic.AdvAudio.Panning="偏移"
 Basic.AdvAudio.SyncOffset="同步位移(ms)"
+Basic.AdvAudio.Monitoring="音訊監測"
+Basic.AdvAudio.Monitoring.None="關閉監測"
+Basic.AdvAudio.Monitoring.MonitorOnly="僅監測(輸出為靜音)"
+Basic.AdvAudio.Monitoring.Both="監測和輸出"
 Basic.AdvAudio.AudioTracks="音軌"
 
 Basic.Settings.Hotkeys="快捷鍵"
 Basic.Settings.Hotkeys.Pair="按鍵組合與'%1'共用作為切換鍵"
 
-Basic.Hotkeys.StartStreaming="開始串流"
-Basic.Hotkeys.StopStreaming="停止串流"
-Basic.Hotkeys.StartRecording="開始錄影"
-Basic.Hotkeys.StopRecording="停止錄影"
 Basic.Hotkeys.SelectScene="切換到場景"
 
 Basic.SystemTray.Show="顯示"
@@ -545,4 +615,5 @@ SceneItemHide="隱藏 「%1」"
 
 OutputWarnings.NoTracksSelected="您必須至少選擇一個軌道"
 OutputWarnings.MultiTrackRecording="警告:某些格式 (例如 FLV) 不支援多個軌道錄製"
+OutputWarnings.MP4Recording="警告︰ 如果檔案無法完成,儲存成 MP4 的紀錄將無法復原 (例如由於 BSOD,斷電等)。如果想要記錄多個音軌請考慮儲存成 MKV 並在完成後重新封裝成 mp4(檔案 -> 重新封裝)"
 
diff --git a/UI/display-helpers.hpp b/UI/display-helpers.hpp
index d175932..27ef174 100644
--- a/UI/display-helpers.hpp
+++ b/UI/display-helpers.hpp
@@ -41,6 +41,14 @@ static inline void GetScaleAndCenterPos(
 	y = windowCY/2 - newCY/2;
 }
 
+static inline void GetCenterPosFromFixedScale(
+		int baseCX, int baseCY, int windowCX, int windowCY,
+		int &x, int &y, float scale)
+{
+	x = (float(windowCX) - float(baseCX)*scale) / 2.0f;
+	y = (float(windowCY) - float(baseCY)*scale) / 2.0f;
+}
+
 static inline QSize GetPixelSize(QWidget *widget)
 {
 	return widget->size() * widget->devicePixelRatio();
diff --git a/UI/forms/OBSBasic.ui b/UI/forms/OBSBasic.ui
index 5b922bc..92aa8ed 100644
--- a/UI/forms/OBSBasic.ui
+++ b/UI/forms/OBSBasic.ui
@@ -608,6 +608,9 @@
                <height>0</height>
               </size>
              </property>
+             <property name="accessibleName">
+              <string>Transition</string>
+             </property>
             </widget>
            </item>
            <item>
@@ -754,10 +757,16 @@
                <property name="text">
                 <string>Basic.TransitionDuration</string>
                </property>
+               <property name="buddy">
+                <cstring>transitionDuration</cstring>
+               </property>
               </widget>
              </item>
              <item>
               <widget class="QSpinBox" name="transitionDuration">
+               <property name="accessibleName">
+                <string>Basic.TransitionDuration</string>
+               </property>
                <property name="suffix">
                 <string>ms</string>
                </property>
@@ -850,6 +859,8 @@
       <string>Basic.MainMenu.Edit.Transform</string>
      </property>
      <addaction name="actionEditTransform"/>
+     <addaction name="actionCopyTransform"/>
+     <addaction name="actionPasteTransform"/>
      <addaction name="actionResetTransform"/>
      <addaction name="separator"/>
      <addaction name="actionRotate90CW"/>
@@ -873,8 +884,17 @@
      <addaction name="actionMoveToTop"/>
      <addaction name="actionMoveToBottom"/>
     </widget>
+    <widget class="QMenu" name="scalingMenu">
+     <property name="title">
+      <string>Basic.MainMenu.Edit.Scale</string>
+     </property>
+     <addaction name="actionScaleWindow"/>
+     <addaction name="actionScaleCanvas"/>
+     <addaction name="actionScaleOutput"/>
+    </widget>
     <addaction name="transformMenu"/>
     <addaction name="orderMenu"/>
+    <addaction name="scalingMenu"/>
     <addaction name="actionLockPreview"/>
     <addaction name="separator"/>
     <addaction name="actionAdvAudioProperties"/>
@@ -887,6 +907,8 @@
     <addaction name="actionDupProfile"/>
     <addaction name="actionRenameProfile"/>
     <addaction name="actionRemoveProfile"/>
+    <addaction name="actionImportProfile"/>
+    <addaction name="actionExportProfile"/>
     <addaction name="separator"/>
    </widget>
    <widget class="QMenu" name="sceneCollectionMenu">
@@ -897,6 +919,8 @@
     <addaction name="actionDupSceneCollection"/>
     <addaction name="actionRenameSceneCollection"/>
     <addaction name="actionRemoveSceneCollection"/>
+    <addaction name="actionImportSceneCollection"/>
+    <addaction name="actionExportSceneCollection"/>
     <addaction name="separator"/>
    </widget>
    <widget class="QMenu" name="viewMenu">
@@ -1120,6 +1144,19 @@
     <string>Basic.MainMenu.Edit.Transform.EditTransform</string>
    </property>
   </action>
+  <action name="actionCopyTransform">
+   <property name="text">
+    <string>Basic.MainMenu.Edit.Transform.CopyTransform</string>
+   </property>
+  </action>
+  <action name="actionPasteTransform">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>Basic.MainMenu.Edit.Transform.PasteTransform</string>
+   </property>
+  </action>
   <action name="actionRotate90CW">
    <property name="text">
     <string>Basic.MainMenu.Edit.Transform.Rotate90CW</string>
@@ -1249,6 +1286,16 @@
     <string>Remove</string>
    </property>
   </action>
+  <action name="actionImportSceneCollection">
+   <property name="text">
+    <string>Import</string>
+   </property>
+  </action>
+  <action name="actionExportSceneCollection">
+   <property name="text">
+    <string>Export</string>
+   </property>
+  </action>
   <action name="actionNewProfile">
    <property name="text">
     <string>New</string>
@@ -1269,6 +1316,16 @@
     <string>Remove</string>
    </property>
   </action>
+  <action name="actionImportProfile">
+   <property name="text">
+    <string>Import</string>
+   </property>
+  </action>
+  <action name="actionExportProfile">
+   <property name="text">
+    <string>Export</string>
+   </property>
+  </action>
   <action name="actionShowSettingsFolder">
    <property name="text">
     <string>Basic.MainMenu.File.ShowSettingsFolder</string>
@@ -1328,6 +1385,30 @@
     <string>Basic.MainMenu.Edit.LockPreview</string>
    </property>
   </action>
+  <action name="actionScaleWindow">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Basic.MainMenu.Edit.Scale.Window</string>
+   </property>
+  </action>
+  <action name="actionScaleCanvas">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Basic.MainMenu.Edit.Scale.Canvas</string>
+   </property>
+  </action>
+  <action name="actionScaleOutput">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Basic.MainMenu.Edit.Scale.Output</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui
index ff50261..2d467aa 100644
--- a/UI/forms/OBSBasicSettings.ui
+++ b/UI/forms/OBSBasicSettings.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>981</width>
-    <height>667</height>
+    <height>748</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -116,221 +116,422 @@
         <number>0</number>
        </property>
        <widget class="QWidget" name="generalPage">
-        <layout class="QFormLayout" name="formLayout_2">
-         <property name="fieldGrowthPolicy">
-          <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+        <layout class="QVBoxLayout" name="verticalLayout_18">
+         <property name="leftMargin">
+          <number>0</number>
          </property>
-         <property name="labelAlignment">
-          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         <property name="topMargin">
+          <number>0</number>
          </property>
-         <item row="0" column="0">
-          <spacer name="verticalSpacer">
-           <property name="orientation">
-            <enum>Qt::Vertical</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>40</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item row="1" column="0">
-          <widget class="QLabel" name="label">
-           <property name="minimumSize">
-            <size>
-             <width>170</width>
-             <height>0</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Basic.Settings.General.Language</string>
-           </property>
-           <property name="alignment">
-            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-           </property>
-           <property name="buddy">
-            <cstring>language</cstring>
-           </property>
-          </widget>
-         </item>
-         <item row="1" column="1">
-          <widget class="QComboBox" name="language"/>
-         </item>
-         <item row="2" column="0">
-          <widget class="QLabel" name="label_42">
-           <property name="text">
-            <string>Basic.Settings.General.Theme</string>
-           </property>
-           <property name="buddy">
-            <cstring>theme</cstring>
-           </property>
-          </widget>
-         </item>
-         <item row="2" column="1">
-          <widget class="QComboBox" name="theme"/>
-         </item>
-         <item row="3" column="1">
-          <widget class="QCheckBox" name="warnBeforeStreamStart">
-           <property name="text">
-            <string>Basic.Settings.General.WarnBeforeStartingStream</string>
-           </property>
-          </widget>
-         </item>
-         <item row="4" column="1">
-          <widget class="QCheckBox" name="warnBeforeStreamStop">
-           <property name="text">
-            <string>Basic.Settings.General.WarnBeforeStoppingStream</string>
-           </property>
-          </widget>
-         </item>
-         <item row="7" column="1">
-          <widget class="QCheckBox" name="recordWhenStreaming">
-           <property name="text">
-            <string>Basic.Settings.General.RecordWhenStreaming</string>
-           </property>
-          </widget>
-         </item>
-         <item row="9" column="1">
-          <widget class="QCheckBox" name="systemTrayEnabled">
-           <property name="text">
-            <string>Basic.Settings.General.SysTrayEnabled</string>
-           </property>
-          </widget>
-         </item>
-         <item row="10" column="1">
-          <widget class="QCheckBox" name="systemTrayWhenStarted">
-           <property name="enabled">
-            <bool>false</bool>
-           </property>
-           <property name="text">
-            <string>Basic.Settings.General.SysTrayWhenStarted</string>
-           </property>
-          </widget>
-         </item>
-         <item row="11" column="0" colspan="2">
-          <widget class="Line" name="line_4">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-          </widget>
-         </item>
-         <item row="12" column="0" colspan="2">
-          <widget class="QGroupBox" name="groupBox_10">
-           <property name="enabled">
+         <property name="rightMargin">
+          <number>0</number>
+         </property>
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QScrollArea" name="scrollArea_2">
+           <property name="widgetResizable">
             <bool>true</bool>
            </property>
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="title">
-            <string>Basic.Settings.General.Snapping</string>
-           </property>
-           <property name="flat">
-            <bool>false</bool>
-           </property>
-           <layout class="QFormLayout" name="formLayout_21">
-            <property name="labelAlignment">
-             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           <widget class="QWidget" name="scrollAreaWidgetContents_2">
+            <property name="geometry">
+             <rect>
+              <x>0</x>
+              <y>0</y>
+              <width>818</width>
+              <height>697</height>
+             </rect>
             </property>
-            <item row="0" column="1">
-             <widget class="QCheckBox" name="snappingEnabled">
-              <property name="text">
-               <string>Enable</string>
-              </property>
-              <property name="checked">
-               <bool>true</bool>
-              </property>
-             </widget>
-            </item>
-            <item row="2" column="1">
-             <widget class="QCheckBox" name="screenSnapping">
-              <property name="text">
-               <string>Basic.Settings.General.ScreenSnapping</string>
-              </property>
-              <property name="checked">
-               <bool>true</bool>
-              </property>
-             </widget>
-            </item>
-            <item row="4" column="1">
-             <widget class="QCheckBox" name="centerSnapping">
-              <property name="text">
-               <string>Basic.Settings.General.CenterSnapping</string>
-              </property>
-              <property name="checked">
-               <bool>true</bool>
-              </property>
-             </widget>
-            </item>
-            <item row="3" column="1">
-             <widget class="QCheckBox" name="sourceSnapping">
-              <property name="text">
-               <string>Basic.Settings.General.SourceSnapping</string>
-              </property>
-              <property name="checked">
-               <bool>true</bool>
-              </property>
-             </widget>
-            </item>
-            <item row="1" column="1">
-             <widget class="QDoubleSpinBox" name="snapDistance">
-              <property name="decimals">
-               <number>1</number>
-              </property>
-              <property name="singleStep">
-               <double>0.500000000000000</double>
-              </property>
-              <property name="value">
-               <double>10.000000000000000</double>
-              </property>
-             </widget>
-            </item>
-            <item row="1" column="0">
-             <widget class="QLabel" name="label_9">
-              <property name="minimumSize">
-               <size>
-                <width>170</width>
-                <height>0</height>
-               </size>
-              </property>
-              <property name="text">
-               <string>Basic.Settings.General.SnapDistance</string>
-              </property>
-              <property name="alignment">
-               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-              </property>
-             </widget>
-            </item>
-           </layout>
-          </widget>
-         </item>
-         <item row="5" column="1">
-          <widget class="QCheckBox" name="hideProjectorCursor">
-           <property name="text">
-            <string>Basic.Settings.General.HideProjectorCursor</string>
-           </property>
-          </widget>
-         </item>
-         <item row="8" column="1">
-          <widget class="QCheckBox" name="keepRecordStreamStops">
-           <property name="enabled">
-            <bool>false</bool>
-           </property>
-           <property name="text">
-            <string>Basic.Settings.General.KeepRecordingWhenStreamStops</string>
-           </property>
-          </widget>
-         </item>
-         <item row="6" column="1">
-          <widget class="QCheckBox" name="projectorAlwaysOnTop">
-           <property name="text">
-            <string>Basic.Settings.General.ProjectorAlwaysOnTop</string>
-           </property>
+            <layout class="QVBoxLayout" name="verticalLayout_19">
+             <property name="leftMargin">
+              <number>0</number>
+             </property>
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <property name="rightMargin">
+              <number>0</number>
+             </property>
+             <property name="bottomMargin">
+              <number>9</number>
+             </property>
+             <item alignment="Qt::AlignTop">
+              <widget class="QWidget" name="widget_2" native="true">
+               <layout class="QVBoxLayout" name="verticalLayout_20">
+                <item>
+                 <widget class="QGroupBox" name="groupBox_15">
+                  <property name="title">
+                   <string>Basic.Settings.General</string>
+                  </property>
+                  <layout class="QFormLayout" name="formLayout_32">
+                   <property name="fieldGrowthPolicy">
+                    <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                   </property>
+                   <property name="labelAlignment">
+                    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                   </property>
+                   <property name="topMargin">
+                    <number>2</number>
+                   </property>
+                   <item row="0" column="0">
+                    <widget class="QLabel" name="label">
+                     <property name="text">
+                      <string>Basic.Settings.General.Language</string>
+                     </property>
+                     <property name="buddy">
+                      <cstring>language</cstring>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="0" column="1">
+                    <widget class="QComboBox" name="language"/>
+                   </item>
+                   <item row="1" column="0">
+                    <widget class="QLabel" name="label_42">
+                     <property name="text">
+                      <string>Basic.Settings.General.Theme</string>
+                     </property>
+                     <property name="buddy">
+                      <cstring>theme</cstring>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="1" column="1">
+                    <widget class="QComboBox" name="theme"/>
+                   </item>
+                   <item row="2" column="1">
+                    <widget class="QCheckBox" name="enableAutoUpdates">
+                     <property name="text">
+                      <string>Basic.Settings.General.EnableAutoUpdates</string>
+                     </property>
+                     <property name="checked">
+                      <bool>true</bool>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="2" column="0">
+                    <spacer name="horizontalSpacer_3">
+                     <property name="orientation">
+                      <enum>Qt::Horizontal</enum>
+                     </property>
+                     <property name="sizeType">
+                      <enum>QSizePolicy::Fixed</enum>
+                     </property>
+                     <property name="sizeHint" stdset="0">
+                      <size>
+                       <width>170</width>
+                       <height>5</height>
+                      </size>
+                     </property>
+                    </spacer>
+                   </item>
+                  </layout>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QGroupBox" name="groupBox_16">
+                  <property name="title">
+                   <string>Basic.Settings.Output</string>
+                  </property>
+                  <layout class="QFormLayout" name="formLayout_2">
+                   <property name="fieldGrowthPolicy">
+                    <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                   </property>
+                   <property name="topMargin">
+                    <number>2</number>
+                   </property>
+                   <item row="0" column="0">
+                    <spacer name="horizontalSpacer_5">
+                     <property name="orientation">
+                      <enum>Qt::Horizontal</enum>
+                     </property>
+                     <property name="sizeType">
+                      <enum>QSizePolicy::Fixed</enum>
+                     </property>
+                     <property name="sizeHint" stdset="0">
+                      <size>
+                       <width>170</width>
+                       <height>5</height>
+                      </size>
+                     </property>
+                    </spacer>
+                   </item>
+                   <item row="0" column="1">
+                    <widget class="QCheckBox" name="warnBeforeStreamStart">
+                     <property name="text">
+                      <string>Basic.Settings.General.WarnBeforeStartingStream</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="1" column="1">
+                    <widget class="QCheckBox" name="warnBeforeStreamStop">
+                     <property name="text">
+                      <string>Basic.Settings.General.WarnBeforeStoppingStream</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="2" column="1">
+                    <widget class="QCheckBox" name="recordWhenStreaming">
+                     <property name="text">
+                      <string>Basic.Settings.General.RecordWhenStreaming</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="3" column="1">
+                    <widget class="QCheckBox" name="keepRecordStreamStops">
+                     <property name="enabled">
+                      <bool>false</bool>
+                     </property>
+                     <property name="text">
+                      <string>Basic.Settings.General.KeepRecordingWhenStreamStops</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="4" column="1">
+                    <widget class="QCheckBox" name="replayWhileStreaming">
+                     <property name="text">
+                      <string>Basic.Settings.General.ReplayBufferWhileStreaming</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="5" column="1">
+                    <widget class="QCheckBox" name="keepReplayStreamStops">
+                     <property name="enabled">
+                      <bool>false</bool>
+                     </property>
+                     <property name="text">
+                      <string>Basic.Settings.General.KeepReplayBufferStreamStops</string>
+                     </property>
+                    </widget>
+                   </item>
+                  </layout>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QGroupBox" name="groupBox_10">
+                  <property name="enabled">
+                   <bool>true</bool>
+                  </property>
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="title">
+                   <string>Basic.Settings.General.Snapping</string>
+                  </property>
+                  <property name="flat">
+                   <bool>false</bool>
+                  </property>
+                  <layout class="QFormLayout" name="formLayout_21">
+                   <property name="fieldGrowthPolicy">
+                    <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                   </property>
+                   <property name="labelAlignment">
+                    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                   </property>
+                   <property name="topMargin">
+                    <number>2</number>
+                   </property>
+                   <item row="0" column="1">
+                    <widget class="QCheckBox" name="snappingEnabled">
+                     <property name="text">
+                      <string>Enable</string>
+                     </property>
+                     <property name="checked">
+                      <bool>true</bool>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="2" column="1">
+                    <widget class="QCheckBox" name="screenSnapping">
+                     <property name="text">
+                      <string>Basic.Settings.General.ScreenSnapping</string>
+                     </property>
+                     <property name="checked">
+                      <bool>true</bool>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="4" column="1">
+                    <widget class="QCheckBox" name="centerSnapping">
+                     <property name="text">
+                      <string>Basic.Settings.General.CenterSnapping</string>
+                     </property>
+                     <property name="checked">
+                      <bool>true</bool>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="3" column="1">
+                    <widget class="QCheckBox" name="sourceSnapping">
+                     <property name="text">
+                      <string>Basic.Settings.General.SourceSnapping</string>
+                     </property>
+                     <property name="checked">
+                      <bool>true</bool>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="1" column="1">
+                    <widget class="QDoubleSpinBox" name="snapDistance">
+                     <property name="decimals">
+                      <number>1</number>
+                     </property>
+                     <property name="singleStep">
+                      <double>0.500000000000000</double>
+                     </property>
+                     <property name="value">
+                      <double>10.000000000000000</double>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="1" column="0">
+                    <widget class="QLabel" name="label_9">
+                     <property name="text">
+                      <string>Basic.Settings.General.SnapDistance</string>
+                     </property>
+                     <property name="buddy">
+                      <cstring>snapDistance</cstring>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="3" column="0">
+                    <spacer name="horizontalSpacer_4">
+                     <property name="orientation">
+                      <enum>Qt::Horizontal</enum>
+                     </property>
+                     <property name="sizeType">
+                      <enum>QSizePolicy::Fixed</enum>
+                     </property>
+                     <property name="sizeHint" stdset="0">
+                      <size>
+                       <width>170</width>
+                       <height>5</height>
+                      </size>
+                     </property>
+                    </spacer>
+                   </item>
+                  </layout>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QGroupBox" name="groupBox_14">
+                  <property name="title">
+                   <string>Basic.Settings.General.Projectors</string>
+                  </property>
+                  <layout class="QFormLayout" name="formLayout_28">
+                   <property name="fieldGrowthPolicy">
+                    <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                   </property>
+                   <property name="topMargin">
+                    <number>2</number>
+                   </property>
+                   <item row="0" column="1">
+                    <widget class="QCheckBox" name="hideProjectorCursor">
+                     <property name="text">
+                      <string>Basic.Settings.General.HideProjectorCursor</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="1" column="1">
+                    <widget class="QCheckBox" name="projectorAlwaysOnTop">
+                     <property name="text">
+                      <string>Basic.Settings.General.ProjectorAlwaysOnTop</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="2" column="1">
+                    <widget class="QCheckBox" name="saveProjectors">
+                     <property name="text">
+                      <string>Basic.Settings.General.SaveProjectors</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="1" column="0">
+                    <spacer name="horizontalSpacer">
+                     <property name="orientation">
+                      <enum>Qt::Horizontal</enum>
+                     </property>
+                     <property name="sizeType">
+                      <enum>QSizePolicy::Fixed</enum>
+                     </property>
+                     <property name="sizeHint" stdset="0">
+                      <size>
+                       <width>170</width>
+                       <height>5</height>
+                      </size>
+                     </property>
+                    </spacer>
+                   </item>
+                  </layout>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QGroupBox" name="groupBox_13">
+                  <property name="title">
+                   <string>Basic.Settings.General.SysTray</string>
+                  </property>
+                  <layout class="QFormLayout" name="formLayout_29">
+                   <property name="fieldGrowthPolicy">
+                    <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                   </property>
+                   <property name="topMargin">
+                    <number>2</number>
+                   </property>
+                   <item row="0" column="1">
+                    <widget class="QCheckBox" name="systemTrayEnabled">
+                     <property name="text">
+                      <string>Enable</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="1" column="1">
+                    <widget class="QCheckBox" name="systemTrayWhenStarted">
+                     <property name="enabled">
+                      <bool>false</bool>
+                     </property>
+                     <property name="text">
+                      <string>Basic.Settings.General.SysTrayWhenStarted</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="2" column="1">
+                    <widget class="QCheckBox" name="systemTrayAlways">
+                     <property name="enabled">
+                      <bool>false</bool>
+                     </property>
+                     <property name="text">
+                      <string>Basic.Settings.General.SystemTrayHideMinimize</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="1" column="0">
+                    <spacer name="horizontalSpacer_2">
+                     <property name="orientation">
+                      <enum>Qt::Horizontal</enum>
+                     </property>
+                     <property name="sizeType">
+                      <enum>QSizePolicy::Fixed</enum>
+                     </property>
+                     <property name="sizeHint" stdset="0">
+                      <size>
+                       <width>170</width>
+                       <height>5</height>
+                      </size>
+                     </property>
+                    </spacer>
+                   </item>
+                  </layout>
+                 </widget>
+                </item>
+               </layout>
+              </widget>
+             </item>
+            </layout>
+           </widget>
           </widget>
          </item>
         </layout>
@@ -722,7 +923,7 @@
               </widget>
              </item>
              <item>
-              <widget class="QGroupBox" name="groupBox_9">
+              <widget class="QGroupBox" name="simpleRecordingGroupBox">
                <property name="sizePolicy">
                 <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
                  <horstretch>0</horstretch>
@@ -739,6 +940,25 @@
                 <property name="labelAlignment">
                  <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
                 </property>
+                <item row="0" column="0">
+                 <widget class="QLabel" name="label_18">
+                  <property name="minimumSize">
+                   <size>
+                    <width>170</width>
+                    <height>0</height>
+                   </size>
+                  </property>
+                  <property name="text">
+                   <string>Basic.Settings.Output.Simple.SavePath</string>
+                  </property>
+                  <property name="alignment">
+                   <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                  </property>
+                  <property name="buddy">
+                   <cstring>simpleOutputPath</cstring>
+                  </property>
+                 </widget>
+                </item>
                 <item row="0" column="1">
                  <layout class="QHBoxLayout" name="horizontalLayout_5">
                   <item>
@@ -760,32 +980,36 @@
                   </item>
                  </layout>
                 </item>
-                <item row="0" column="0">
-                 <widget class="QLabel" name="label_18">
-                  <property name="minimumSize">
-                   <size>
-                    <width>170</width>
-                    <height>0</height>
-                   </size>
-                  </property>
+                <item row="1" column="1">
+                 <widget class="QCheckBox" name="simpleNoSpace">
                   <property name="text">
-                   <string>Basic.Settings.Output.Simple.SavePath</string>
+                   <string>Basic.Settings.Output.NoSpaceFileName</string>
                   </property>
-                  <property name="alignment">
-                   <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                  <property name="checked">
+                   <bool>true</bool>
+                  </property>
+                 </widget>
+                </item>
+                <item row="2" column="0">
+                 <widget class="QLabel" name="label_26">
+                  <property name="text">
+                   <string>Basic.Settings.Output.Simple.RecordingQuality</string>
                   </property>
                   <property name="buddy">
-                   <cstring>simpleOutputPath</cstring>
+                   <cstring>simpleOutRecQuality</cstring>
                   </property>
                  </widget>
                 </item>
-                <item row="1" column="1">
-                 <widget class="QCheckBox" name="simpleNoSpace">
+                <item row="2" column="1">
+                 <widget class="QComboBox" name="simpleOutRecQuality"/>
+                </item>
+                <item row="3" column="0">
+                 <widget class="QLabel" name="simpleOutRecFormatLabel">
                   <property name="text">
-                   <string>Basic.Settings.Output.NoSpaceFileName</string>
+                   <string>Basic.Settings.Output.Format</string>
                   </property>
-                  <property name="checked">
-                   <bool>true</bool>
+                  <property name="buddy">
+                   <cstring>simpleOutRecFormat</cstring>
                   </property>
                  </widget>
                 </item>
@@ -823,54 +1047,116 @@
                   </item>
                  </widget>
                 </item>
-                <item row="3" column="0">
-                 <widget class="QLabel" name="simpleOutRecFormatLabel">
+                <item row="4" column="0">
+                 <widget class="QLabel" name="simpleOutRecEncoderLabel">
                   <property name="text">
-                   <string>Basic.Settings.Output.Format</string>
+                   <string>Basic.Settings.Output.Encoder</string>
                   </property>
                   <property name="buddy">
-                   <cstring>simpleOutRecFormat</cstring>
+                   <cstring>simpleOutRecEncoder</cstring>
                   </property>
                  </widget>
                 </item>
-                <item row="2" column="1">
-                 <widget class="QComboBox" name="simpleOutRecQuality"/>
+                <item row="4" column="1">
+                 <widget class="QComboBox" name="simpleOutRecEncoder"/>
                 </item>
-                <item row="2" column="0">
-                 <widget class="QLabel" name="label_26">
+                <item row="5" column="0">
+                 <widget class="QLabel" name="label_420">
                   <property name="text">
-                   <string>Basic.Settings.Output.Simple.RecordingQuality</string>
+                   <string>Basic.Settings.Output.CustomMuxerSettings</string>
                   </property>
                   <property name="buddy">
-                   <cstring>simpleOutRecQuality</cstring>
+                   <cstring>simpleOutMuxCustom</cstring>
                   </property>
                  </widget>
                 </item>
-                <item row="4" column="1">
-                 <widget class="QComboBox" name="simpleOutRecEncoder"/>
+                <item row="5" column="1">
+                 <widget class="QLineEdit" name="simpleOutMuxCustom"/>
                 </item>
-                <item row="4" column="0">
-                 <widget class="QLabel" name="simpleOutRecEncoderLabel">
+                <item row="6" column="1">
+                 <widget class="QCheckBox" name="simpleReplayBuf">
                   <property name="text">
-                   <string>Basic.Settings.Output.Encoder</string>
+                   <string>Basic.Settings.Output.UseReplayBuffer</string>
                   </property>
-                  <property name="buddy">
-                   <cstring>simpleOutRecEncoder</cstring>
+                  <property name="checked">
+                   <bool>true</bool>
                   </property>
                  </widget>
                 </item>
-                <item row="5" column="0">
-                 <widget class="QLabel" name="label_420">
+               </layout>
+              </widget>
+             </item>
+             <item>
+              <widget class="QGroupBox" name="replayBufferGroupBox">
+               <property name="title">
+                <string>ReplayBuffer</string>
+               </property>
+               <layout class="QFormLayout" name="formLayout_24">
+                <property name="fieldGrowthPolicy">
+                 <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                </property>
+                <property name="labelAlignment">
+                 <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                </property>
+                <item row="0" column="0">
+                 <widget class="QLabel" name="label_35">
                   <property name="text">
-                   <string>Basic.Settings.Output.CustomMuxerSettings</string>
+                   <string>Basic.Settings.Output.ReplayBuffer.SecondsMax</string>
                   </property>
-                  <property name="buddy">
-                   <cstring>simpleOutMuxCustom</cstring>
+                 </widget>
+                </item>
+                <item row="0" column="1">
+                 <widget class="QSpinBox" name="simpleRBSecMax">
+                  <property name="suffix">
+                   <string notr="true"> sec</string>
+                  </property>
+                  <property name="minimum">
+                   <number>5</number>
+                  </property>
+                  <property name="maximum">
+                   <number>21600</number>
+                  </property>
+                  <property name="value">
+                   <number>15</number>
                   </property>
                  </widget>
                 </item>
-                <item row="5" column="1">
-                 <widget class="QLineEdit" name="simpleOutMuxCustom"/>
+                <item row="1" column="0">
+                 <widget class="QLabel" name="simpleRBMegsMaxLabel">
+                  <property name="text">
+                   <string>Basic.Settings.Output.ReplayBuffer.MegabytesMax</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="1" column="1">
+                 <widget class="QSpinBox" name="simpleRBMegsMax">
+                  <property name="suffix">
+                   <string notr="true"> MB</string>
+                  </property>
+                  <property name="minimum">
+                   <number>20</number>
+                  </property>
+                  <property name="maximum">
+                   <number>8192</number>
+                  </property>
+                  <property name="value">
+                   <number>512</number>
+                  </property>
+                 </widget>
+                </item>
+                <item row="2" column="1">
+                 <widget class="QLabel" name="label_45">
+                  <property name="text">
+                   <string>Basic.Settings.Output.ReplayBuffer.HotkeyMessage</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="3" column="1">
+                 <widget class="QLabel" name="simpleRBEstimate">
+                  <property name="text">
+                   <string notr="true"/>
+                  </property>
+                 </widget>
                 </item>
                </layout>
               </widget>
@@ -1064,6 +1350,20 @@
                             </property>
                            </widget>
                           </item>
+                          <item>
+                           <widget class="QRadioButton" name="advOutTrack5">
+                            <property name="text">
+                             <string notr="true">5</string>
+                            </property>
+                           </widget>
+                          </item>
+                          <item>
+                           <widget class="QRadioButton" name="advOutTrack6">
+                            <property name="text">
+                             <string notr="true">6</string>
+                            </property>
+                           </widget>
+                          </item>
                          </layout>
                         </widget>
                        </item>
@@ -1407,6 +1707,20 @@
                                 </property>
                                </widget>
                               </item>
+                              <item>
+                               <widget class="QCheckBox" name="advOutRecTrack5">
+                                <property name="text">
+                                 <string notr="true">5</string>
+                                </property>
+                               </widget>
+                              </item>
+                              <item>
+                               <widget class="QCheckBox" name="advOutRecTrack6">
+                                <property name="text">
+                                 <string notr="true">6</string>
+                                </property>
+                               </widget>
+                              </item>
                              </layout>
                             </widget>
                            </item>
@@ -1614,7 +1928,7 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="6" column="0">
+                     <item row="7" column="0">
                       <widget class="QLabel" name="label_40">
                        <property name="text">
                         <string>Basic.Settings.Output.VideoBitrate</string>
@@ -1624,7 +1938,7 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="6" column="1">
+                     <item row="7" column="1">
                       <widget class="QSpinBox" name="advOutFFVBitrate">
                        <property name="minimum">
                         <number>0</number>
@@ -1637,7 +1951,27 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="7" column="0">
+                     <item row="8" column="1">
+                      <widget class="QSpinBox" name="advOutFFVGOPSize">
+                       <property name="maximum">
+                        <number>1000000000</number>
+                       </property>
+                       <property name="value">
+                        <number>250</number>
+                       </property>
+                      </widget>
+                     </item>
+                     <item row="8" column="0">
+                      <widget class="QLabel" name="label_63">
+                       <property name="text">
+                        <string>Basic.Settings.Output.Adv.FFmpeg.GOPSize</string>
+                       </property>
+                       <property name="buddy">
+                        <cstring>advOutFFVGOPSize</cstring>
+                       </property>
+                      </widget>
+                     </item>
+                     <item row="9" column="0">
                       <widget class="QCheckBox" name="advOutFFUseRescale">
                        <property name="sizePolicy">
                         <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
@@ -1653,7 +1987,7 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="7" column="1">
+                     <item row="9" column="1">
                       <widget class="QComboBox" name="advOutFFRescale">
                        <property name="enabled">
                         <bool>false</bool>
@@ -1663,7 +1997,14 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="8" column="0">
+                     <item row="10" column="1">
+                      <widget class="QCheckBox" name="advOutFFIgnoreCompat">
+                       <property name="text">
+                        <string>Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat</string>
+                       </property>
+                      </widget>
+                     </item>
+                     <item row="11" column="0">
                       <widget class="QLabel" name="label_37">
                        <property name="text">
                         <string>Basic.Settings.Output.Adv.FFmpeg.VEncoder</string>
@@ -1673,10 +2014,10 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="8" column="1">
+                     <item row="11" column="1">
                       <widget class="QComboBox" name="advOutFFVEncoder"/>
                      </item>
-                     <item row="10" column="0">
+                     <item row="13" column="0">
                       <widget class="QLabel" name="label_38">
                        <property name="text">
                         <string>Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings</string>
@@ -1686,10 +2027,10 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="10" column="1">
+                     <item row="13" column="1">
                       <widget class="QLineEdit" name="advOutFFVCfg"/>
                      </item>
-                     <item row="11" column="0">
+                     <item row="14" column="0">
                       <widget class="QLabel" name="label_41">
                        <property name="text">
                         <string>Basic.Settings.Output.AudioBitrate</string>
@@ -1699,7 +2040,7 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="11" column="1">
+                     <item row="14" column="1">
                       <widget class="QSpinBox" name="advOutFFABitrate">
                        <property name="minimum">
                         <number>32</number>
@@ -1715,14 +2056,14 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="12" column="0">
+                     <item row="15" column="0">
                       <widget class="QLabel" name="label_47">
                        <property name="text">
                         <string>Basic.Settings.Output.Adv.AudioTrack</string>
                        </property>
                       </widget>
                      </item>
-                     <item row="12" column="1">
+                     <item row="15" column="1">
                       <widget class="QWidget" name="widget_10" native="true">
                        <property name="sizePolicy">
                         <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
@@ -1774,10 +2115,24 @@
                           </property>
                          </widget>
                         </item>
+                        <item>
+                         <widget class="QRadioButton" name="advOutFFTrack5">
+                          <property name="text">
+                           <string notr="true">5</string>
+                          </property>
+                         </widget>
+                        </item>
+                        <item>
+                         <widget class="QRadioButton" name="advOutFFTrack6">
+                          <property name="text">
+                           <string notr="true">6</string>
+                          </property>
+                         </widget>
+                        </item>
                        </layout>
                       </widget>
                      </item>
-                     <item row="13" column="0">
+                     <item row="17" column="0">
                       <widget class="QLabel" name="label_39">
                        <property name="text">
                         <string>Basic.Settings.Output.Adv.FFmpeg.AEncoder</string>
@@ -1787,10 +2142,10 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="13" column="1">
+                     <item row="17" column="1">
                       <widget class="QComboBox" name="advOutFFAEncoder"/>
                      </item>
-                     <item row="14" column="0">
+                     <item row="18" column="0">
                       <widget class="QLabel" name="label_46">
                        <property name="text">
                         <string>Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings</string>
@@ -1800,7 +2155,7 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="14" column="1">
+                     <item row="18" column="1">
                       <widget class="QLineEdit" name="advOutFFACfg"/>
                      </item>
                      <item row="0" column="0">
@@ -1898,7 +2253,237 @@
                    </property>
                    <layout class="QVBoxLayout" name="verticalLayout_10">
                     <item>
-                     <widget class="QGroupBox" name="groupBox">
+                     <widget class="QGroupBox" name="groupBox">
+                      <property name="sizePolicy">
+                       <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+                        <horstretch>0</horstretch>
+                        <verstretch>0</verstretch>
+                       </sizepolicy>
+                      </property>
+                      <property name="title">
+                       <string>Basic.Settings.Output.Adv.Audio.Track1</string>
+                      </property>
+                      <layout class="QFormLayout" name="formLayout_10">
+                       <property name="fieldGrowthPolicy">
+                        <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                       </property>
+                       <property name="labelAlignment">
+                        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                       </property>
+                       <item row="0" column="1">
+                        <widget class="QComboBox" name="advOutTrack1Bitrate">
+                         <property name="currentIndex">
+                          <number>8</number>
+                         </property>
+                         <item>
+                          <property name="text">
+                           <string>32</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>48</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>64</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>80</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>96</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>112</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>128</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>160</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>192</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>256</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>320</string>
+                          </property>
+                         </item>
+                        </widget>
+                       </item>
+                       <item row="0" column="0">
+                        <widget class="QLabel" name="label_25">
+                         <property name="minimumSize">
+                          <size>
+                           <width>170</width>
+                           <height>0</height>
+                          </size>
+                         </property>
+                         <property name="text">
+                          <string>Basic.Settings.Output.AudioBitrate</string>
+                         </property>
+                         <property name="alignment">
+                          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                         </property>
+                         <property name="buddy">
+                          <cstring>advOutTrack1Bitrate</cstring>
+                         </property>
+                        </widget>
+                       </item>
+                       <item row="1" column="0">
+                        <widget class="QLabel" name="label_55">
+                         <property name="text">
+                          <string>Name</string>
+                         </property>
+                         <property name="buddy">
+                          <cstring>advOutTrack1Name</cstring>
+                         </property>
+                        </widget>
+                       </item>
+                       <item row="1" column="1">
+                        <widget class="QLineEdit" name="advOutTrack1Name"/>
+                       </item>
+                      </layout>
+                     </widget>
+                    </item>
+                    <item>
+                     <widget class="QGroupBox" name="groupBox_2">
+                      <property name="sizePolicy">
+                       <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+                        <horstretch>0</horstretch>
+                        <verstretch>0</verstretch>
+                       </sizepolicy>
+                      </property>
+                      <property name="title">
+                       <string>Basic.Settings.Output.Adv.Audio.Track2</string>
+                      </property>
+                      <layout class="QFormLayout" name="formLayout_11">
+                       <property name="fieldGrowthPolicy">
+                        <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                       </property>
+                       <property name="labelAlignment">
+                        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                       </property>
+                       <item row="0" column="0">
+                        <widget class="QLabel" name="label_49">
+                         <property name="minimumSize">
+                          <size>
+                           <width>170</width>
+                           <height>0</height>
+                          </size>
+                         </property>
+                         <property name="text">
+                          <string>Basic.Settings.Output.AudioBitrate</string>
+                         </property>
+                         <property name="alignment">
+                          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                         </property>
+                         <property name="buddy">
+                          <cstring>advOutTrack2Bitrate</cstring>
+                         </property>
+                        </widget>
+                       </item>
+                       <item row="0" column="1">
+                        <widget class="QComboBox" name="advOutTrack2Bitrate">
+                         <property name="currentIndex">
+                          <number>8</number>
+                         </property>
+                         <item>
+                          <property name="text">
+                           <string>32</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>48</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>64</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>80</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>96</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>112</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>128</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>160</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>192</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>256</string>
+                          </property>
+                         </item>
+                         <item>
+                          <property name="text">
+                           <string>320</string>
+                          </property>
+                         </item>
+                        </widget>
+                       </item>
+                       <item row="1" column="0">
+                        <widget class="QLabel" name="label_50">
+                         <property name="text">
+                          <string>Name</string>
+                         </property>
+                         <property name="buddy">
+                          <cstring>advOutTrack2Name</cstring>
+                         </property>
+                        </widget>
+                       </item>
+                       <item row="1" column="1">
+                        <widget class="QLineEdit" name="advOutTrack2Name"/>
+                       </item>
+                      </layout>
+                     </widget>
+                    </item>
+                    <item>
+                     <widget class="QGroupBox" name="groupBox_3">
                       <property name="sizePolicy">
                        <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
                         <horstretch>0</horstretch>
@@ -1906,17 +2491,36 @@
                        </sizepolicy>
                       </property>
                       <property name="title">
-                       <string>Basic.Settings.Output.Adv.Audio.Track1</string>
+                       <string>Basic.Settings.Output.Adv.Audio.Track3</string>
                       </property>
-                      <layout class="QFormLayout" name="formLayout_10">
+                      <layout class="QFormLayout" name="formLayout_12">
                        <property name="fieldGrowthPolicy">
                         <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
                        </property>
                        <property name="labelAlignment">
                         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
                        </property>
+                       <item row="0" column="0">
+                        <widget class="QLabel" name="label_51">
+                         <property name="minimumSize">
+                          <size>
+                           <width>170</width>
+                           <height>0</height>
+                          </size>
+                         </property>
+                         <property name="text">
+                          <string>Basic.Settings.Output.AudioBitrate</string>
+                         </property>
+                         <property name="alignment">
+                          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                         </property>
+                         <property name="buddy">
+                          <cstring>advOutTrack3Bitrate</cstring>
+                         </property>
+                        </widget>
+                       </item>
                        <item row="0" column="1">
-                        <widget class="QComboBox" name="advOutTrack1Bitrate">
+                        <widget class="QComboBox" name="advOutTrack3Bitrate">
                          <property name="currentIndex">
                           <number>8</number>
                          </property>
@@ -1977,43 +2581,24 @@
                          </item>
                         </widget>
                        </item>
-                       <item row="0" column="0">
-                        <widget class="QLabel" name="label_25">
-                         <property name="minimumSize">
-                          <size>
-                           <width>170</width>
-                           <height>0</height>
-                          </size>
-                         </property>
-                         <property name="text">
-                          <string>Basic.Settings.Output.AudioBitrate</string>
-                         </property>
-                         <property name="alignment">
-                          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-                         </property>
-                         <property name="buddy">
-                          <cstring>advOutTrack1Bitrate</cstring>
-                         </property>
-                        </widget>
-                       </item>
                        <item row="1" column="0">
-                        <widget class="QLabel" name="label_55">
+                        <widget class="QLabel" name="label_52">
                          <property name="text">
                           <string>Name</string>
                          </property>
                          <property name="buddy">
-                          <cstring>advOutTrack1Name</cstring>
+                          <cstring>advOutTrack3Name</cstring>
                          </property>
                         </widget>
                        </item>
                        <item row="1" column="1">
-                        <widget class="QLineEdit" name="advOutTrack1Name"/>
+                        <widget class="QLineEdit" name="advOutTrack3Name"/>
                        </item>
                       </layout>
                      </widget>
                     </item>
                     <item>
-                     <widget class="QGroupBox" name="groupBox_2">
+                     <widget class="QGroupBox" name="groupBox_4">
                       <property name="sizePolicy">
                        <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
                         <horstretch>0</horstretch>
@@ -2021,9 +2606,9 @@
                        </sizepolicy>
                       </property>
                       <property name="title">
-                       <string>Basic.Settings.Output.Adv.Audio.Track2</string>
+                       <string>Basic.Settings.Output.Adv.Audio.Track4</string>
                       </property>
-                      <layout class="QFormLayout" name="formLayout_11">
+                      <layout class="QFormLayout" name="formLayout_13">
                        <property name="fieldGrowthPolicy">
                         <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
                        </property>
@@ -2031,7 +2616,7 @@
                         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
                        </property>
                        <item row="0" column="0">
-                        <widget class="QLabel" name="label_49">
+                        <widget class="QLabel" name="label_53">
                          <property name="minimumSize">
                           <size>
                            <width>170</width>
@@ -2045,12 +2630,12 @@
                           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
                          </property>
                          <property name="buddy">
-                          <cstring>advOutTrack2Bitrate</cstring>
+                          <cstring>advOutTrack4Bitrate</cstring>
                          </property>
                         </widget>
                        </item>
                        <item row="0" column="1">
-                        <widget class="QComboBox" name="advOutTrack2Bitrate">
+                        <widget class="QComboBox" name="advOutTrack4Bitrate">
                          <property name="currentIndex">
                           <number>8</number>
                          </property>
@@ -2112,23 +2697,23 @@
                         </widget>
                        </item>
                        <item row="1" column="0">
-                        <widget class="QLabel" name="label_50">
+                        <widget class="QLabel" name="label_54">
                          <property name="text">
                           <string>Name</string>
                          </property>
                          <property name="buddy">
-                          <cstring>advOutTrack2Name</cstring>
+                          <cstring>advOutTrack4Name</cstring>
                          </property>
                         </widget>
                        </item>
                        <item row="1" column="1">
-                        <widget class="QLineEdit" name="advOutTrack2Name"/>
+                        <widget class="QLineEdit" name="advOutTrack4Name"/>
                        </item>
                       </layout>
                      </widget>
                     </item>
                     <item>
-                     <widget class="QGroupBox" name="groupBox_3">
+                     <widget class="QGroupBox" name="groupBox_9">
                       <property name="sizePolicy">
                        <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
                         <horstretch>0</horstretch>
@@ -2136,9 +2721,9 @@
                        </sizepolicy>
                       </property>
                       <property name="title">
-                       <string>Basic.Settings.Output.Adv.Audio.Track3</string>
+                       <string>Basic.Settings.Output.Adv.Audio.Track5</string>
                       </property>
-                      <layout class="QFormLayout" name="formLayout_12">
+                      <layout class="QFormLayout" name="formLayout_25">
                        <property name="fieldGrowthPolicy">
                         <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
                        </property>
@@ -2146,7 +2731,7 @@
                         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
                        </property>
                        <item row="0" column="0">
-                        <widget class="QLabel" name="label_51">
+                        <widget class="QLabel" name="label_59">
                          <property name="minimumSize">
                           <size>
                            <width>170</width>
@@ -2160,12 +2745,12 @@
                           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
                          </property>
                          <property name="buddy">
-                          <cstring>advOutTrack3Bitrate</cstring>
+                          <cstring>advOutTrack5Bitrate</cstring>
                          </property>
                         </widget>
                        </item>
                        <item row="0" column="1">
-                        <widget class="QComboBox" name="advOutTrack3Bitrate">
+                        <widget class="QComboBox" name="advOutTrack5Bitrate">
                          <property name="currentIndex">
                           <number>8</number>
                          </property>
@@ -2227,23 +2812,23 @@
                         </widget>
                        </item>
                        <item row="1" column="0">
-                        <widget class="QLabel" name="label_52">
+                        <widget class="QLabel" name="label_60">
                          <property name="text">
                           <string>Name</string>
                          </property>
                          <property name="buddy">
-                          <cstring>advOutTrack3Name</cstring>
+                          <cstring>advOutTrack5Name</cstring>
                          </property>
                         </widget>
                        </item>
                        <item row="1" column="1">
-                        <widget class="QLineEdit" name="advOutTrack3Name"/>
+                        <widget class="QLineEdit" name="advOutTrack5Name"/>
                        </item>
                       </layout>
                      </widget>
                     </item>
                     <item>
-                     <widget class="QGroupBox" name="groupBox_4">
+                     <widget class="QGroupBox" name="groupBox_12">
                       <property name="sizePolicy">
                        <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
                         <horstretch>0</horstretch>
@@ -2251,9 +2836,9 @@
                        </sizepolicy>
                       </property>
                       <property name="title">
-                       <string>Basic.Settings.Output.Adv.Audio.Track4</string>
+                       <string>Basic.Settings.Output.Adv.Audio.Track6</string>
                       </property>
-                      <layout class="QFormLayout" name="formLayout_13">
+                      <layout class="QFormLayout" name="formLayout_26">
                        <property name="fieldGrowthPolicy">
                         <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
                        </property>
@@ -2261,7 +2846,7 @@
                         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
                        </property>
                        <item row="0" column="0">
-                        <widget class="QLabel" name="label_53">
+                        <widget class="QLabel" name="label_61">
                          <property name="minimumSize">
                           <size>
                            <width>170</width>
@@ -2275,12 +2860,12 @@
                           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
                          </property>
                          <property name="buddy">
-                          <cstring>advOutTrack4Bitrate</cstring>
+                          <cstring>advOutTrack6Bitrate</cstring>
                          </property>
                         </widget>
                        </item>
                        <item row="0" column="1">
-                        <widget class="QComboBox" name="advOutTrack4Bitrate">
+                        <widget class="QComboBox" name="advOutTrack6Bitrate">
                          <property name="currentIndex">
                           <number>8</number>
                          </property>
@@ -2342,17 +2927,17 @@
                         </widget>
                        </item>
                        <item row="1" column="0">
-                        <widget class="QLabel" name="label_54">
+                        <widget class="QLabel" name="label_62">
                          <property name="text">
                           <string>Name</string>
                          </property>
                          <property name="buddy">
-                          <cstring>advOutTrack4Name</cstring>
+                          <cstring>advOutTrack6Name</cstring>
                          </property>
                         </widget>
                        </item>
                        <item row="1" column="1">
-                        <widget class="QLineEdit" name="advOutTrack4Name"/>
+                        <widget class="QLineEdit" name="advOutTrack6Name"/>
                        </item>
                       </layout>
                      </widget>
@@ -2545,8 +3130,8 @@
              <rect>
               <x>0</x>
               <y>0</y>
-              <width>80</width>
-              <height>16</height>
+              <width>98</width>
+              <height>28</height>
              </rect>
             </property>
            </widget>
@@ -2700,10 +3285,10 @@
              <item alignment="Qt::AlignTop">
               <widget class="QComboBox" name="fpsCommon">
                <property name="currentText">
-                <string notr="true">30</string>
+                <string notr="true">10</string>
                </property>
                <property name="currentIndex">
-                <number>3</number>
+                <number>0</number>
                </property>
                <item>
                 <property name="text">
@@ -2717,6 +3302,11 @@
                </item>
                <item>
                 <property name="text">
+                 <string>24 NTSC</string>
+                </property>
+               </item>
+               <item>
+                <property name="text">
                  <string notr="true">29.97</string>
                 </property>
                </item>
@@ -2911,8 +3501,8 @@
              <rect>
               <x>0</x>
               <y>0</y>
-              <width>559</width>
-              <height>681</height>
+              <width>803</width>
+              <height>738</height>
              </rect>
             </property>
             <layout class="QVBoxLayout" name="verticalLayout_16">
@@ -2937,6 +3527,9 @@
                    <string>Basic.Settings.General</string>
                   </property>
                   <layout class="QFormLayout" name="formLayout_22">
+                   <property name="fieldGrowthPolicy">
+                    <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                   </property>
                    <item row="0" column="0">
                     <widget class="QLabel" name="processPriorityLabel">
                      <property name="text">
@@ -2965,6 +3558,46 @@
                    <property name="labelAlignment">
                     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
                    </property>
+                   <item row="0" column="0">
+                    <widget class="QLabel" name="rendererLabel">
+                     <property name="text">
+                      <string>Basic.Settings.Video.Renderer</string>
+                     </property>
+                     <property name="buddy">
+                      <cstring>renderer</cstring>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="0" column="1">
+                    <widget class="QComboBox" name="renderer">
+                     <property name="currentText">
+                      <string notr="true"/>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="1" column="0">
+                    <widget class="QLabel" name="adapterLabel">
+                     <property name="text">
+                      <string>Basic.Settings.Video.Adapter</string>
+                     </property>
+                     <property name="alignment">
+                      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                     </property>
+                     <property name="buddy">
+                      <cstring>adapter</cstring>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="1" column="1">
+                    <widget class="QComboBox" name="adapter">
+                     <property name="enabled">
+                      <bool>false</bool>
+                     </property>
+                     <property name="currentText">
+                      <string notr="true"/>
+                     </property>
+                    </widget>
+                   </item>
                    <item row="2" column="0">
                     <widget class="QLabel" name="label_30">
                      <property name="minimumSize">
@@ -3008,97 +3641,120 @@
                      </item>
                     </widget>
                    </item>
-                   <item row="4" column="0">
-                    <widget class="QLabel" name="label_34">
-                     <property name="text">
-                      <string>Basic.Settings.Advanced.Video.ColorRange</string>
+                   <item row="4" column="1">
+                    <layout class="QHBoxLayout" name="horizontalLayout_18">
+                     <property name="leftMargin">
+                      <number>0</number>
                      </property>
-                     <property name="buddy">
-                      <cstring>colorRange</cstring>
+                     <property name="topMargin">
+                      <number>0</number>
                      </property>
-                    </widget>
-                   </item>
-                   <item row="4" column="1">
-                    <widget class="QComboBox" name="colorRange"/>
-                   </item>
-                   <item row="3" column="0">
-                    <widget class="QLabel" name="label_33">
-                     <property name="text">
-                      <string>Basic.Settings.Advanced.Video.ColorSpace</string>
+                     <property name="rightMargin">
+                      <number>0</number>
                      </property>
-                     <property name="buddy">
-                      <cstring>colorSpace</cstring>
+                     <property name="bottomMargin">
+                      <number>0</number>
                      </property>
-                    </widget>
-                   </item>
-                   <item row="3" column="1">
-                    <widget class="QComboBox" name="colorSpace">
                      <item>
-                      <property name="text">
-                       <string notr="true">709</string>
-                      </property>
+                      <widget class="QCheckBox" name="disableOSXVSync">
+                       <property name="text">
+                        <string>DisableOSXVSync</string>
+                       </property>
+                      </widget>
                      </item>
                      <item>
-                      <property name="text">
-                       <string notr="true">601</string>
-                      </property>
+                      <widget class="QCheckBox" name="resetOSXVSync">
+                       <property name="text">
+                        <string>ResetOSXVSyncOnExit</string>
+                       </property>
+                      </widget>
                      </item>
-                    </widget>
+                    </layout>
                    </item>
-                   <item row="0" column="0">
-                    <widget class="QLabel" name="rendererLabel">
-                     <property name="text">
-                      <string>Basic.Settings.Video.Renderer</string>
+                   <item row="3" column="1">
+                    <layout class="QHBoxLayout" name="horizontalLayout_20">
+                     <property name="leftMargin">
+                      <number>0</number>
                      </property>
-                     <property name="buddy">
-                      <cstring>renderer</cstring>
+                     <property name="topMargin">
+                      <number>0</number>
                      </property>
-                    </widget>
-                   </item>
-                   <item row="0" column="1">
-                    <widget class="QComboBox" name="renderer">
-                     <property name="currentText">
-                      <string notr="true"/>
+                     <property name="rightMargin">
+                      <number>0</number>
                      </property>
-                    </widget>
+                     <property name="bottomMargin">
+                      <number>0</number>
+                     </property>
+                     <item>
+                      <widget class="QComboBox" name="colorSpace">
+                       <item>
+                        <property name="text">
+                         <string notr="true">709</string>
+                        </property>
+                       </item>
+                       <item>
+                        <property name="text">
+                         <string notr="true">601</string>
+                        </property>
+                       </item>
+                      </widget>
+                     </item>
+                     <item>
+                      <widget class="QLabel" name="label_34">
+                       <property name="sizePolicy">
+                        <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+                         <horstretch>0</horstretch>
+                         <verstretch>0</verstretch>
+                        </sizepolicy>
+                       </property>
+                       <property name="text">
+                        <string>Basic.Settings.Advanced.Video.ColorRange</string>
+                       </property>
+                       <property name="buddy">
+                        <cstring>colorRange</cstring>
+                       </property>
+                      </widget>
+                     </item>
+                     <item>
+                      <widget class="QComboBox" name="colorRange"/>
+                     </item>
+                    </layout>
                    </item>
-                   <item row="1" column="0">
-                    <widget class="QLabel" name="adapterLabel">
+                   <item row="3" column="0">
+                    <widget class="QLabel" name="label_33">
                      <property name="text">
-                      <string>Basic.Settings.Video.Adapter</string>
-                     </property>
-                     <property name="alignment">
-                      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                      <string>Basic.Settings.Advanced.Video.ColorSpace</string>
                      </property>
                      <property name="buddy">
-                      <cstring>adapter</cstring>
-                     </property>
-                    </widget>
-                   </item>
-                   <item row="1" column="1">
-                    <widget class="QComboBox" name="adapter">
-                     <property name="enabled">
-                      <bool>false</bool>
-                     </property>
-                     <property name="currentText">
-                      <string notr="true"/>
+                      <cstring>colorSpace</cstring>
                      </property>
                     </widget>
                    </item>
-                   <item row="5" column="1">
-                    <widget class="QCheckBox" name="disableOSXVSync">
+                  </layout>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QGroupBox" name="advAudioGroupBox">
+                  <property name="title">
+                   <string>Basic.Settings.Audio</string>
+                  </property>
+                  <layout class="QFormLayout" name="formLayout_27">
+                   <property name="fieldGrowthPolicy">
+                    <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                   </property>
+                   <item row="0" column="0">
+                    <widget class="QLabel" name="monitoringDeviceLabel">
                      <property name="text">
-                      <string>DisableOSXVSync</string>
+                      <string>Basic.Settings.Advanced.Audio.MonitoringDevice</string>
                      </property>
-                    </widget>
-                   </item>
-                   <item row="6" column="1">
-                    <widget class="QCheckBox" name="resetOSXVSync">
-                     <property name="text">
-                      <string>ResetOSXVSyncOnExit</string>
+                     <property name="buddy">
+                      <cstring>monitoringDevice</cstring>
                      </property>
                     </widget>
                    </item>
+                   <item row="0" column="1">
+                    <widget class="QComboBox" name="monitoringDevice"/>
+                   </item>
                   </layout>
                  </widget>
                 </item>
@@ -3108,11 +3764,20 @@
                    <string>Basic.Settings.Output.Adv.Recording</string>
                   </property>
                   <layout class="QFormLayout" name="formLayout_17">
+                   <property name="fieldGrowthPolicy">
+                    <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                   </property>
+                   <property name="labelAlignment">
+                    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                   </property>
                    <item row="0" column="0">
                     <widget class="QLabel" name="label_7">
                      <property name="text">
                       <string>Basic.Settings.Output.Adv.Recording.Filename</string>
                      </property>
+                     <property name="buddy">
+                      <cstring>filenameFormatting</cstring>
+                     </property>
                     </widget>
                    </item>
                    <item row="0" column="1">
@@ -3125,6 +3790,48 @@
                      </property>
                     </widget>
                    </item>
+                   <item row="2" column="1">
+                    <layout class="QHBoxLayout" name="horizontalLayout_14">
+                     <property name="leftMargin">
+                      <number>0</number>
+                     </property>
+                     <property name="topMargin">
+                      <number>0</number>
+                     </property>
+                     <property name="rightMargin">
+                      <number>0</number>
+                     </property>
+                     <property name="bottomMargin">
+                      <number>0</number>
+                     </property>
+                     <item>
+                      <widget class="QLineEdit" name="simpleRBPrefix"/>
+                     </item>
+                     <item>
+                      <widget class="QLabel" name="label_58">
+                       <property name="text">
+                        <string>Basic.Settings.Output.ReplayBuffer.Suffix</string>
+                       </property>
+                       <property name="buddy">
+                        <cstring>simpleRBSuffix</cstring>
+                       </property>
+                      </widget>
+                     </item>
+                     <item>
+                      <widget class="QLineEdit" name="simpleRBSuffix"/>
+                     </item>
+                    </layout>
+                   </item>
+                   <item row="2" column="0">
+                    <widget class="QLabel" name="label_57">
+                     <property name="text">
+                      <string>Basic.Settings.Output.ReplayBuffer.Prefix</string>
+                     </property>
+                     <property name="buddy">
+                      <cstring>simpleRBPrefix</cstring>
+                     </property>
+                    </widget>
+                   </item>
                   </layout>
                  </widget>
                 </item>
@@ -3134,16 +3841,12 @@
                    <string>Basic.Settings.Advanced.StreamDelay</string>
                   </property>
                   <layout class="QFormLayout" name="formLayout_18">
-                   <item row="0" column="1">
-                    <widget class="QCheckBox" name="streamDelayEnable">
-                     <property name="text">
-                      <string>Enable</string>
-                     </property>
-                     <property name="checked">
-                      <bool>true</bool>
-                     </property>
-                    </widget>
-                   </item>
+                   <property name="fieldGrowthPolicy">
+                    <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+                   </property>
+                   <property name="topMargin">
+                    <number>2</number>
+                   </property>
                    <item row="1" column="0">
                     <widget class="QLabel" name="label_56">
                      <property name="text">
@@ -3220,6 +3923,16 @@
                      </property>
                     </widget>
                    </item>
+                   <item row="0" column="1">
+                    <widget class="QCheckBox" name="streamDelayEnable">
+                     <property name="text">
+                      <string>Enable</string>
+                     </property>
+                     <property name="checked">
+                      <bool>true</bool>
+                     </property>
+                    </widget>
+                   </item>
                   </layout>
                  </widget>
                 </item>
@@ -3232,16 +3945,6 @@
                    <property name="fieldGrowthPolicy">
                     <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
                    </property>
-                   <item row="1" column="0">
-                    <widget class="QLabel" name="label_17">
-                     <property name="text">
-                      <string>Basic.Settings.Output.RetryDelay</string>
-                     </property>
-                     <property name="buddy">
-                      <cstring>reconnectRetryDelay</cstring>
-                     </property>
-                    </widget>
-                   </item>
                    <item row="0" column="1">
                     <widget class="QCheckBox" name="reconnectEnable">
                      <property name="text">
@@ -3253,29 +3956,61 @@
                     </widget>
                    </item>
                    <item row="1" column="1">
-                    <widget class="QSpinBox" name="reconnectRetryDelay">
-                     <property name="maximum">
-                      <number>30</number>
+                    <layout class="QHBoxLayout" name="horizontalLayout_19">
+                     <property name="leftMargin">
+                      <number>0</number>
                      </property>
-                    </widget>
-                   </item>
-                   <item row="2" column="0">
-                    <widget class="QLabel" name="label_22">
-                     <property name="text">
-                      <string>Basic.Settings.Output.MaxRetries</string>
+                     <property name="topMargin">
+                      <number>0</number>
                      </property>
-                     <property name="buddy">
-                      <cstring>reconnectMaxRetries</cstring>
+                     <property name="rightMargin">
+                      <number>0</number>
                      </property>
-                    </widget>
+                     <property name="bottomMargin">
+                      <number>0</number>
+                     </property>
+                     <item>
+                      <widget class="QSpinBox" name="reconnectRetryDelay">
+                       <property name="maximum">
+                        <number>30</number>
+                       </property>
+                      </widget>
+                     </item>
+                     <item>
+                      <widget class="QLabel" name="label_22">
+                       <property name="sizePolicy">
+                        <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+                         <horstretch>0</horstretch>
+                         <verstretch>0</verstretch>
+                        </sizepolicy>
+                       </property>
+                       <property name="text">
+                        <string>Basic.Settings.Output.MaxRetries</string>
+                       </property>
+                       <property name="buddy">
+                        <cstring>reconnectMaxRetries</cstring>
+                       </property>
+                      </widget>
+                     </item>
+                     <item>
+                      <widget class="QSpinBox" name="reconnectMaxRetries">
+                       <property name="minimum">
+                        <number>1</number>
+                       </property>
+                       <property name="maximum">
+                        <number>10000</number>
+                       </property>
+                      </widget>
+                     </item>
+                    </layout>
                    </item>
-                   <item row="2" column="1">
-                    <widget class="QSpinBox" name="reconnectMaxRetries">
-                     <property name="minimum">
-                      <number>1</number>
+                   <item row="1" column="0">
+                    <widget class="QLabel" name="label_17">
+                     <property name="text">
+                      <string>Basic.Settings.Output.RetryDelay</string>
                      </property>
-                     <property name="maximum">
-                      <number>10000</number>
+                     <property name="buddy">
+                      <cstring>reconnectRetryDelay</cstring>
                      </property>
                     </widget>
                    </item>
@@ -3283,7 +4018,7 @@
                  </widget>
                 </item>
                 <item>
-                 <widget class="QGroupBox" name="groupBox_11">
+                 <widget class="QGroupBox" name="advNetworkGroupBox">
                   <property name="title">
                    <string>Basic.Settings.Advanced.Network</string>
                   </property>
@@ -3299,6 +4034,26 @@
                      <property name="text">
                       <string>Basic.Settings.Advanced.Network.BindToIP</string>
                      </property>
+                     <property name="buddy">
+                      <cstring>bindToIP</cstring>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="1" column="1">
+                    <widget class="QCheckBox" name="enableNewSocketLoop">
+                     <property name="text">
+                      <string>Basic.Settings.Advanced.Network.EnableNewSocketLoop</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="2" column="1">
+                    <widget class="QCheckBox" name="enableLowLatencyMode">
+                     <property name="enabled">
+                      <bool>false</bool>
+                     </property>
+                     <property name="text">
+                      <string>Basic.Settings.Advanced.Network.EnableLowLatencyMode</string>
+                     </property>
                     </widget>
                    </item>
                   </layout>
@@ -3354,8 +4109,146 @@
  </widget>
  <tabstops>
   <tabstop>listWidget</tabstop>
-  <tabstop>buttonBox</tabstop>
+  <tabstop>streamType</tabstop>
+  <tabstop>outputMode</tabstop>
+  <tabstop>simpleOutputVBitrate</tabstop>
+  <tabstop>simpleOutputABitrate</tabstop>
+  <tabstop>simpleOutAdvanced</tabstop>
+  <tabstop>simpleOutPreset</tabstop>
+  <tabstop>simpleOutCustom</tabstop>
+  <tabstop>simpleOutEnforce</tabstop>
+  <tabstop>simpleOutStrEncoder</tabstop>
+  <tabstop>simpleOutputPath</tabstop>
+  <tabstop>simpleOutputBrowse</tabstop>
+  <tabstop>simpleNoSpace</tabstop>
+  <tabstop>simpleOutRecQuality</tabstop>
+  <tabstop>simpleOutRecFormat</tabstop>
+  <tabstop>simpleOutRecEncoder</tabstop>
+  <tabstop>simpleOutMuxCustom</tabstop>
+  <tabstop>simpleReplayBuf</tabstop>
+  <tabstop>simpleRBSecMax</tabstop>
+  <tabstop>simpleRBMegsMax</tabstop>
+  <tabstop>advOutTabs</tabstop>
+  <tabstop>advOutTrack1</tabstop>
+  <tabstop>advOutTrack2</tabstop>
+  <tabstop>advOutTrack3</tabstop>
+  <tabstop>advOutTrack4</tabstop>
+  <tabstop>advOutTrack5</tabstop>
+  <tabstop>advOutTrack6</tabstop>
+  <tabstop>advOutEncoder</tabstop>
+  <tabstop>advOutApplyService</tabstop>
+  <tabstop>advOutUseRescale</tabstop>
+  <tabstop>advOutRescale</tabstop>
+  <tabstop>advOutRecType</tabstop>
+  <tabstop>advOutRecPath</tabstop>
+  <tabstop>advOutRecPathBrowse</tabstop>
+  <tabstop>advOutNoSpace</tabstop>
+  <tabstop>advOutRecFormat</tabstop>
+  <tabstop>advOutRecTrack1</tabstop>
+  <tabstop>advOutRecTrack2</tabstop>
+  <tabstop>advOutRecTrack3</tabstop>
+  <tabstop>advOutRecTrack4</tabstop>
+  <tabstop>advOutRecTrack5</tabstop>
+  <tabstop>advOutRecTrack6</tabstop>
+  <tabstop>advOutRecEncoder</tabstop>
+  <tabstop>advOutRecUseRescale</tabstop>
+  <tabstop>advOutRecRescale</tabstop>
+  <tabstop>advOutMuxCustom</tabstop>
+  <tabstop>advOutFFRecPath</tabstop>
+  <tabstop>advOutFFPathBrowse</tabstop>
+  <tabstop>advOutFFURL</tabstop>
+  <tabstop>advOutFFFormat</tabstop>
+  <tabstop>advOutFFVBitrate</tabstop>
+  <tabstop>advOutFFVGOPSize</tabstop>
+  <tabstop>advOutFFUseRescale</tabstop>
+  <tabstop>advOutFFRescale</tabstop>
+  <tabstop>advOutFFIgnoreCompat</tabstop>
+  <tabstop>advOutFFVEncoder</tabstop>
+  <tabstop>advOutFFVCfg</tabstop>
+  <tabstop>advOutFFABitrate</tabstop>
+  <tabstop>advOutFFTrack1</tabstop>
+  <tabstop>advOutFFTrack2</tabstop>
+  <tabstop>advOutFFTrack3</tabstop>
+  <tabstop>advOutFFTrack4</tabstop>
+  <tabstop>advOutFFTrack5</tabstop>
+  <tabstop>advOutFFTrack6</tabstop>
+  <tabstop>advOutFFAEncoder</tabstop>
+  <tabstop>advOutFFACfg</tabstop>
+  <tabstop>advOutFFType</tabstop>
+  <tabstop>advOutFFMCfg</tabstop>
+  <tabstop>advOutFFNoSpace</tabstop>
+  <tabstop>advOutTrack1Bitrate</tabstop>
+  <tabstop>advOutTrack1Name</tabstop>
+  <tabstop>advOutTrack2Bitrate</tabstop>
+  <tabstop>advOutTrack2Name</tabstop>
+  <tabstop>advOutTrack3Bitrate</tabstop>
+  <tabstop>advOutTrack3Name</tabstop>
+  <tabstop>advOutTrack4Bitrate</tabstop>
+  <tabstop>advOutTrack4Name</tabstop>
+  <tabstop>advOutTrack5Bitrate</tabstop>
+  <tabstop>advOutTrack5Name</tabstop>
+  <tabstop>advOutTrack6Bitrate</tabstop>
+  <tabstop>advOutTrack6Name</tabstop>
+  <tabstop>sampleRate</tabstop>
+  <tabstop>channelSetup</tabstop>
+  <tabstop>desktopAudioDevice1</tabstop>
+  <tabstop>desktopAudioDevice2</tabstop>
+  <tabstop>auxAudioDevice1</tabstop>
+  <tabstop>auxAudioDevice2</tabstop>
+  <tabstop>auxAudioDevice3</tabstop>
+  <tabstop>audioSourceScrollArea</tabstop>
+  <tabstop>baseResolution</tabstop>
+  <tabstop>outputResolution</tabstop>
+  <tabstop>downscaleFilter</tabstop>
+  <tabstop>fpsType</tabstop>
+  <tabstop>fpsCommon</tabstop>
+  <tabstop>fpsInteger</tabstop>
+  <tabstop>fpsNumerator</tabstop>
+  <tabstop>fpsDenominator</tabstop>
+  <tabstop>scrollArea</tabstop>
+  <tabstop>processPriority</tabstop>
+  <tabstop>renderer</tabstop>
+  <tabstop>adapter</tabstop>
+  <tabstop>colorFormat</tabstop>
+  <tabstop>colorSpace</tabstop>
+  <tabstop>colorRange</tabstop>
+  <tabstop>disableOSXVSync</tabstop>
+  <tabstop>resetOSXVSync</tabstop>
+  <tabstop>monitoringDevice</tabstop>
+  <tabstop>filenameFormatting</tabstop>
+  <tabstop>overwriteIfExists</tabstop>
+  <tabstop>simpleRBPrefix</tabstop>
+  <tabstop>simpleRBSuffix</tabstop>
+  <tabstop>streamDelayEnable</tabstop>
+  <tabstop>streamDelaySec</tabstop>
+  <tabstop>streamDelayPreserve</tabstop>
+  <tabstop>reconnectEnable</tabstop>
+  <tabstop>reconnectRetryDelay</tabstop>
+  <tabstop>reconnectMaxRetries</tabstop>
+  <tabstop>bindToIP</tabstop>
+  <tabstop>enableNewSocketLoop</tabstop>
+  <tabstop>enableLowLatencyMode</tabstop>
+  <tabstop>warnBeforeStreamStop</tabstop>
+  <tabstop>recordWhenStreaming</tabstop>
+  <tabstop>keepRecordStreamStops</tabstop>
+  <tabstop>replayWhileStreaming</tabstop>
+  <tabstop>keepReplayStreamStops</tabstop>
+  <tabstop>snappingEnabled</tabstop>
+  <tabstop>screenSnapping</tabstop>
+  <tabstop>centerSnapping</tabstop>
+  <tabstop>sourceSnapping</tabstop>
+  <tabstop>snapDistance</tabstop>
+  <tabstop>hideProjectorCursor</tabstop>
+  <tabstop>projectorAlwaysOnTop</tabstop>
+  <tabstop>saveProjectors</tabstop>
+  <tabstop>systemTrayEnabled</tabstop>
+  <tabstop>systemTrayWhenStarted</tabstop>
+  <tabstop>systemTrayAlways</tabstop>
+  <tabstop>enableAutoUpdates</tabstop>
+  <tabstop>warnBeforeStreamStart</tabstop>
+  <tabstop>scrollArea_2</tabstop>
   <tabstop>language</tabstop>
+  <tabstop>theme</tabstop>
  </tabstops>
  <resources>
   <include location="obs.qrc"/>
@@ -3384,12 +4277,12 @@
    <slot>setCurrentIndex(int)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>310</x>
-     <y>29</y>
+     <x>159</x>
+     <y>30</y>
     </hint>
     <hint type="destinationlabel">
      <x>241</x>
-     <y>34</y>
+     <y>30</y>
     </hint>
    </hints>
   </connection>
@@ -3400,8 +4293,8 @@
    <slot>setCurrentIndex(int)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>241</x>
+     <y>16</y>
     </hint>
     <hint type="destinationlabel">
      <x>250</x>
@@ -3416,12 +4309,12 @@
    <slot>setVisible(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>240</x>
+     <y>46</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>240</x>
+     <y>44</y>
     </hint>
    </hints>
   </connection>
@@ -3432,12 +4325,12 @@
    <slot>setVisible(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>240</x>
+     <y>46</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>160</x>
+     <y>44</y>
     </hint>
    </hints>
   </connection>
@@ -3448,12 +4341,12 @@
    <slot>setVisible(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>240</x>
+     <y>46</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>240</x>
+     <y>43</y>
     </hint>
    </hints>
   </connection>
@@ -3464,12 +4357,12 @@
    <slot>setVisible(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>240</x>
+     <y>46</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>160</x>
+     <y>43</y>
     </hint>
    </hints>
   </connection>
@@ -3480,12 +4373,12 @@
    <slot>setCurrentIndex(int)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>259</x>
-     <y>48</y>
+     <x>232</x>
+     <y>41</y>
     </hint>
     <hint type="destinationlabel">
      <x>241</x>
-     <y>30</y>
+     <y>53</y>
     </hint>
    </hints>
   </connection>
@@ -3496,12 +4389,12 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>259</x>
-     <y>60</y>
+     <x>168</x>
+     <y>67</y>
     </hint>
     <hint type="destinationlabel">
-     <x>228</x>
-     <y>50</y>
+     <x>250</x>
+     <y>67</y>
     </hint>
    </hints>
   </connection>
@@ -3512,12 +4405,12 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>259</x>
-     <y>39</y>
+     <x>168</x>
+     <y>52</y>
     </hint>
     <hint type="destinationlabel">
-     <x>228</x>
-     <y>29</y>
+     <x>232</x>
+     <y>52</y>
     </hint>
    </hints>
   </connection>
@@ -3528,12 +4421,12 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>259</x>
-     <y>60</y>
+     <x>168</x>
+     <y>56</y>
     </hint>
     <hint type="destinationlabel">
-     <x>228</x>
-     <y>50</y>
+     <x>232</x>
+     <y>56</y>
     </hint>
    </hints>
   </connection>
@@ -3544,252 +4437,252 @@
    <slot>setCurrentIndex(int)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>259</x>
-     <y>60</y>
+     <x>250</x>
+     <y>50</y>
     </hint>
     <hint type="destinationlabel">
-     <x>259</x>
-     <y>60</y>
+     <x>250</x>
+     <y>52</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>streamDelayEnable</sender>
+   <sender>simpleOutAdvanced</sender>
    <signal>toggled(bool)</signal>
-   <receiver>label_56</receiver>
-   <slot>setEnabled(bool)</slot>
+   <receiver>simpleOutEnforce</receiver>
+   <slot>setVisible(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>240</x>
+     <y>46</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>240</x>
+     <y>45</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>streamDelayEnable</sender>
+   <sender>systemTrayEnabled</sender>
    <signal>toggled(bool)</signal>
-   <receiver>streamDelayPreserve</receiver>
+   <receiver>systemTrayWhenStarted</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>730</x>
+     <y>556</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>746</x>
+     <y>579</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>streamDelayEnable</sender>
+   <sender>systemTrayEnabled</sender>
    <signal>toggled(bool)</signal>
-   <receiver>widget_12</receiver>
+   <receiver>systemTrayAlways</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>830</x>
+     <y>556</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>826</x>
+     <y>602</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>reconnectEnable</sender>
+   <sender>enableNewSocketLoop</sender>
    <signal>toggled(bool)</signal>
-   <receiver>label_17</receiver>
+   <receiver>enableLowLatencyMode</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>403</x>
+     <y>642</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>403</x>
+     <y>665</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>reconnectEnable</sender>
+   <sender>snappingEnabled</sender>
    <signal>toggled(bool)</signal>
-   <receiver>reconnectRetryDelay</receiver>
+   <receiver>label_9</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>733</x>
+     <y>317</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>347</x>
+     <y>343</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>reconnectEnable</sender>
+   <sender>snappingEnabled</sender>
    <signal>toggled(bool)</signal>
-   <receiver>label_22</receiver>
+   <receiver>snapDistance</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>774</x>
+     <y>317</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>782</x>
+     <y>343</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>reconnectEnable</sender>
+   <sender>snappingEnabled</sender>
    <signal>toggled(bool)</signal>
-   <receiver>reconnectMaxRetries</receiver>
+   <receiver>screenSnapping</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>820</x>
+     <y>317</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>837</x>
+     <y>366</y>
     </hint>
    </hints>
   </connection>
   <connection>
    <sender>snappingEnabled</sender>
    <signal>toggled(bool)</signal>
-   <receiver>label_9</receiver>
+   <receiver>sourceSnapping</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>720</x>
-     <y>280</y>
+     <x>881</x>
+     <y>317</y>
     </hint>
     <hint type="destinationlabel">
-     <x>346</x>
-     <y>306</y>
+     <x>890</x>
+     <y>389</y>
     </hint>
    </hints>
   </connection>
   <connection>
    <sender>snappingEnabled</sender>
    <signal>toggled(bool)</signal>
-   <receiver>snapDistance</receiver>
+   <receiver>centerSnapping</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>761</x>
-     <y>280</y>
+     <x>928</x>
+     <y>317</y>
     </hint>
     <hint type="destinationlabel">
-     <x>778</x>
-     <y>306</y>
+     <x>915</x>
+     <y>412</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>snappingEnabled</sender>
+   <sender>recordWhenStreaming</sender>
    <signal>toggled(bool)</signal>
-   <receiver>screenSnapping</receiver>
+   <receiver>keepRecordStreamStops</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>820</x>
-     <y>280</y>
+     <x>803</x>
+     <y>199</y>
     </hint>
     <hint type="destinationlabel">
-     <x>810</x>
-     <y>329</y>
+     <x>820</x>
+     <y>222</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>snappingEnabled</sender>
+   <sender>replayWhileStreaming</sender>
    <signal>toggled(bool)</signal>
-   <receiver>sourceSnapping</receiver>
+   <receiver>keepReplayStreamStops</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>862</x>
-     <y>280</y>
+     <x>747</x>
+     <y>245</y>
     </hint>
     <hint type="destinationlabel">
-     <x>859</x>
-     <y>352</y>
+     <x>753</x>
+     <y>268</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>snappingEnabled</sender>
+   <sender>streamDelayEnable</sender>
    <signal>toggled(bool)</signal>
-   <receiver>centerSnapping</receiver>
+   <receiver>label_56</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>866</x>
-     <y>280</y>
+     <x>431</x>
+     <y>422</y>
     </hint>
     <hint type="destinationlabel">
-     <x>866</x>
-     <y>375</y>
+     <x>356</x>
+     <y>443</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>simpleOutAdvanced</sender>
+   <sender>streamDelayEnable</sender>
    <signal>toggled(bool)</signal>
-   <receiver>simpleOutEnforce</receiver>
-   <slot>setVisible(bool)</slot>
+   <receiver>streamDelaySec</receiver>
+   <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>465</x>
+     <y>420</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>463</x>
+     <y>447</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>recordWhenStreaming</sender>
+   <sender>streamDelayEnable</sender>
    <signal>toggled(bool)</signal>
-   <receiver>keepRecordStreamStops</receiver>
+   <receiver>streamDelayInfo</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>404</x>
-     <y>193</y>
+     <x>533</x>
+     <y>420</y>
     </hint>
     <hint type="destinationlabel">
-     <x>404</x>
-     <y>219</y>
+     <x>557</x>
+     <y>446</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>systemTrayEnabled</sender>
+   <sender>streamDelayEnable</sender>
    <signal>toggled(bool)</signal>
-   <receiver>systemTrayWhenStarted</receiver>
+   <receiver>streamDelayPreserve</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>404</x>
-     <y>245</y>
+     <x>504</x>
+     <y>420</y>
     </hint>
     <hint type="destinationlabel">
-     <x>404</x>
-     <y>271</y>
+     <x>494</x>
+     <y>465</y>
     </hint>
    </hints>
   </connection>
diff --git a/UI/forms/OBSBasicTransform.ui b/UI/forms/OBSBasicTransform.ui
index c801b3d..971cd02 100644
--- a/UI/forms/OBSBasicTransform.ui
+++ b/UI/forms/OBSBasicTransform.ui
@@ -493,6 +493,25 @@
      </item>
      <item row="9" column="1">
       <layout class="QGridLayout" name="gridLayout">
+       <item row="0" column="1">
+        <widget class="QSpinBox" name="cropLeft">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>70</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximum">
+          <number>100000</number>
+         </property>
+        </widget>
+       </item>
        <item row="0" column="3">
         <widget class="QSpinBox" name="cropRight">
          <property name="sizePolicy">
@@ -602,25 +621,6 @@
          </property>
         </widget>
        </item>
-       <item row="0" column="1">
-        <widget class="QSpinBox" name="cropLeft">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>70</width>
-           <height>0</height>
-          </size>
-         </property>
-         <property name="maximum">
-          <number>100000</number>
-         </property>
-        </widget>
-       </item>
        <item row="0" column="4">
         <spacer name="horizontalSpacer">
          <property name="orientation">
@@ -648,5 +648,12 @@
   </layout>
  </widget>
  <resources/>
- <connections/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>OBSBasicTransform</receiver>
+   <slot>reject()</slot>
+  </connection>
+ </connections>
 </ui>
diff --git a/UI/forms/OBSUpdate.ui b/UI/forms/OBSUpdate.ui
new file mode 100644
index 0000000..f7a77e9
--- /dev/null
+++ b/UI/forms/OBSUpdate.ui
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OBSUpdate</class>
+ <widget class="QDialog" name="OBSUpdate">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>611</width>
+    <height>526</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Updater.Title</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Updater.Text</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QTextEdit" name="text">
+     <property name="readOnly">
+      <bool>true</bool>
+     </property>
+     <property name="html">
+      <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html></string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="Line" name="line">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="yes">
+       <property name="text">
+        <string>Updater.UpdateNow</string>
+       </property>
+       <property name="default">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="no">
+       <property name="text">
+        <string>Updater.RemindMeLater</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="skip">
+       <property name="text">
+        <string>Updater.Skip</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/UI/forms/images/obs.png b/UI/forms/images/obs.png
old mode 100644
new mode 100755
index 9a6a8cc..e187877
Binary files a/UI/forms/images/obs.png and b/UI/forms/images/obs.png differ
diff --git a/UI/forms/images/tray_active.png b/UI/forms/images/tray_active.png
old mode 100644
new mode 100755
index d8da1c5..4f6a012
Binary files a/UI/forms/images/tray_active.png and b/UI/forms/images/tray_active.png differ
diff --git a/UI/frontend-plugins/CMakeLists.txt b/UI/frontend-plugins/CMakeLists.txt
index 0a90a60..bd2d336 100644
--- a/UI/frontend-plugins/CMakeLists.txt
+++ b/UI/frontend-plugins/CMakeLists.txt
@@ -1,3 +1 @@
-if(WIN32 OR APPLE)
-	add_subdirectory(frontend-tools)
-endif()
+add_subdirectory(frontend-tools)
diff --git a/UI/frontend-plugins/frontend-tools/CMakeLists.txt b/UI/frontend-plugins/frontend-tools/CMakeLists.txt
index b15dc52..5586495 100644
--- a/UI/frontend-plugins/frontend-tools/CMakeLists.txt
+++ b/UI/frontend-plugins/frontend-tools/CMakeLists.txt
@@ -5,20 +5,53 @@ if(APPLE)
 	include_directories(${COCOA})
 endif()
 
+if(WIN32 OR APPLE)
+	set(frontend-tools_HEADERS
+		auto-scene-switcher.hpp
+		)
+	set(frontend-tools_SOURCES
+		auto-scene-switcher.cpp
+		)
+	set(frontend-tools_UI
+		forms/auto-scene-switcher.ui
+		)
+endif()
+
+configure_file(
+	"${CMAKE_CURRENT_SOURCE_DIR}/frontend-tools-config.h.in"
+	"${CMAKE_BINARY_DIR}/config/frontend-tools-config.h")
+
 set(frontend-tools_HEADERS
-	auto-scene-switcher.hpp
+	${frontend-tools_HEADERS}
+	"${CMAKE_BINARY_DIR}/config/frontend-tools-config.h"
+	output-timer.hpp
+	tool-helpers.hpp
 	)
 set(frontend-tools_SOURCES
+	${frontend-tools_SOURCES}
 	frontend-tools.c
-	auto-scene-switcher.cpp
+	output-timer.cpp
 	)
 set(frontend-tools_UI
-	forms/auto-scene-switcher.ui
+	${frontend-tools_UI}
+	forms/output-timer.ui
 	)
 
 if(WIN32)
 	set(frontend-tools_PLATFORM_SOURCES
 		auto-scene-switcher-win.cpp)
+
+	if(BUILD_CAPTIONS)
+		set(frontend-tools_PLATFORM_SOURCES
+			${frontend-tools_PLATFORM_SOURCES}
+			captions.cpp
+			captions-stream.cpp)
+		set(frontend-tools_PLATFORM_HEADERS
+			captions.hpp
+			captions-stream.hpp)
+		set(frontend-tools_PLATFORM_UI
+			forms/captions.ui)
+	endif()
 elseif(APPLE)
 	set(frontend-tools_PLATFORM_SOURCES
 		auto-scene-switcher-osx.mm)
@@ -29,13 +62,16 @@ elseif(APPLE)
 		${COCOA})
 endif()
 
-qt5_wrap_ui(frontend-tools_UI_HEADERS ${frontend-tools_UI})
+qt5_wrap_ui(frontend-tools_UI_HEADERS
+	${frontend-tools_UI}
+	${frontend-tools_PLATFORM_UI})
 
 add_library(frontend-tools MODULE
 	${frontend-tools_HEADERS}
 	${frontend-tools_SOURCES}
-	${frontend-tools_PLATFORM_SOURCES}
 	${frontend-tools_UI_HEADERS}
+	${frontend-tools_PLATFORM_SOURCES}
+	${frontend-tools_PLATFORM_HEADERS}
 	)
 target_link_libraries(frontend-tools
 	${frontend-tools_PLATFORM_LIBS}
diff --git a/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp b/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp
index 9c737bf..06c0307 100644
--- a/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp
+++ b/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp
@@ -3,8 +3,10 @@
 #include <obs.hpp>
 #include <util/util.hpp>
 #include <QMainWindow>
+#include <QMessageBox>
 #include <QAction>
 #include "auto-scene-switcher.hpp"
+#include "tool-helpers.hpp"
 
 #include <condition_variable>
 #include <chrono>
@@ -81,37 +83,6 @@ static inline QString MakeSwitchName(const QString &scene,
 	return QStringLiteral("[") + scene + QStringLiteral("]: ") + window;
 }
 
-static inline string GetWeakSourceName(obs_weak_source_t *weak_source)
-{
-	string name;
-
-	obs_source_t *source = obs_weak_source_get_source(weak_source);
-	if (source) {
-		name = obs_source_get_name(source);
-		obs_source_release(source);
-	}
-
-	return name;
-}
-
-static inline OBSWeakSource GetWeakSourceByName(const char *name)
-{
-	OBSWeakSource weak;
-	obs_source_t *source = obs_get_source_by_name(name);
-	if (source) {
-		weak = obs_source_get_weak_source(source);
-		obs_weak_source_release(weak);
-		obs_source_release(source);
-	}
-
-	return weak;
-}
-
-static inline OBSWeakSource GetWeakSourceByQString(const QString &name)
-{
-	return GetWeakSourceByName(name.toUtf8().constData());
-}
-
 SceneSwitcher::SceneSwitcher(QWidget *parent)
 	: QDialog(parent),
 	  ui(new Ui_SceneSwitcher)
@@ -231,13 +202,19 @@ void SceneSwitcher::on_add_clicked()
 	int idx = FindByData(windowName);
 
 	if (idx == -1) {
-		QListWidgetItem *item = new QListWidgetItem(text,
-				ui->switches);
-		item->setData(Qt::UserRole, v);
-
-		lock_guard<mutex> lock(switcher->m);
-		switcher->switches.emplace_back(source,
-				windowName.toUtf8().constData());
+		try {
+			lock_guard<mutex> lock(switcher->m);
+			switcher->switches.emplace_back(source,
+					windowName.toUtf8().constData());
+			
+			QListWidgetItem *item = new QListWidgetItem(text,
+					ui->switches);
+			item->setData(Qt::UserRole, v);
+		} catch (const regex_error &) {
+			QMessageBox::warning(this,
+					obs_module_text("InvalidRegex.Title"),
+					obs_module_text("InvalidRegex.Text"));
+		}
 	} else {
 		QListWidgetItem *item = ui->switches->item(idx);
 		item->setText(text);
diff --git a/UI/frontend-plugins/frontend-tools/captions-stream.cpp b/UI/frontend-plugins/frontend-tools/captions-stream.cpp
new file mode 100644
index 0000000..b983bad
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/captions-stream.cpp
@@ -0,0 +1,418 @@
+#include "captions-stream.hpp"
+#include <mmreg.h>
+#include <util/windows/CoTaskMemPtr.hpp>
+#include <util/threading.h>
+#include <util/base.h>
+
+using namespace std;
+
+#if 0
+#define debugfunc(format, ...) blog(LOG_DEBUG, "[Captions] %s(" format ")", \
+		__FUNCTION__, ##__VA_ARGS__)
+#else
+#define debugfunc(format, ...)
+#endif
+
+CaptionStream::CaptionStream(DWORD samplerate_) :
+	samplerate(samplerate_),
+	event(CreateEvent(nullptr, false, false, nullptr))
+{
+	buf_info.ulMsMinNotification = 50;
+	buf_info.ulMsBufferSize = 500;
+	buf_info.ulMsEventBias = 0;
+
+	format.wFormatTag = WAVE_FORMAT_PCM;
+	format.nChannels = 1;
+	format.nSamplesPerSec = 16000;
+	format.nAvgBytesPerSec = format.nSamplesPerSec * sizeof(uint16_t);
+	format.nBlockAlign = 2;
+	format.wBitsPerSample = 16;
+	format.cbSize = sizeof(format);
+
+	resampler.Reset(&format);
+}
+
+void CaptionStream::Stop()
+{
+	{
+		lock_guard<mutex> lock(m);
+		circlebuf_free(buf);
+	}
+
+	cv.notify_one();
+}
+
+void CaptionStream::PushAudio(const struct audio_data *data, bool muted)
+{
+	uint8_t *output[MAX_AV_PLANES] = {};
+	uint32_t frames = data->frames;
+	uint64_t ts_offset;
+	bool ready = false;
+
+	audio_resampler_resample(resampler, output, &frames, &ts_offset,
+			data->data, data->frames);
+
+	if (output[0]) {
+		if (muted)
+			memset(output[0], 0, frames * sizeof(int16_t));
+
+		lock_guard<mutex> lock(m);
+		circlebuf_push_back(buf, output[0], frames * sizeof(int16_t));
+		write_pos += frames * sizeof(int16_t);
+
+		if (wait_size && buf->size >= wait_size)
+			ready = true;
+	}
+
+	if (ready)
+		cv.notify_one();
+}
+
+// IUnknown methods
+
+STDMETHODIMP CaptionStream::QueryInterface(REFIID riid, void **ppv)
+{
+	if (riid == IID_IUnknown) {
+		AddRef();
+		*ppv = this;
+
+	} else if (riid == IID_IStream) {
+		AddRef();
+		*ppv = (IStream*)this;
+
+	} else if (riid == IID_ISpStreamFormat) {
+		AddRef();
+		*ppv = (ISpStreamFormat*)this;
+
+	} else if (riid == IID_ISpAudio) {
+		AddRef();
+		*ppv = (ISpAudio*)this;
+
+	} else {
+		*ppv = nullptr;
+		return E_NOINTERFACE;
+	}
+
+	return NOERROR;
+}
+
+STDMETHODIMP_(ULONG) CaptionStream::AddRef()
+{
+	return (ULONG)os_atomic_inc_long(&refs);
+}
+
+STDMETHODIMP_(ULONG) CaptionStream::Release()
+{
+	ULONG new_refs = (ULONG)os_atomic_dec_long(&refs);
+	if (!new_refs)
+		delete this;
+
+	return new_refs;
+}
+
+// ISequentialStream methods
+
+STDMETHODIMP CaptionStream::Read(void *data, ULONG bytes, ULONG *read_bytes)
+{
+	HRESULT hr = S_OK;
+	size_t cur_size;
+
+	debugfunc("data, %lu, read_bytes", bytes);
+	if (!data)
+		return STG_E_INVALIDPOINTER;
+
+	{
+		lock_guard<mutex> lock1(m);
+		wait_size = bytes;
+		cur_size = buf->size;
+	}
+
+	unique_lock<mutex> lock(m);
+
+	if (bytes > cur_size)
+		cv.wait(lock);
+
+	if (bytes > (ULONG)buf->size) {
+		bytes = (ULONG)buf->size;
+		hr = S_FALSE;
+	}
+	if (bytes)
+		circlebuf_pop_front(buf, data, bytes);
+	if (read_bytes)
+		*read_bytes = bytes;
+
+	wait_size = 0;
+	pos.QuadPart += bytes;
+	return hr;
+}
+
+STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes,
+		ULONG*)
+{
+	debugfunc("data, %lu, written_bytes", bytes);
+	UNUSED_PARAMETER(bytes);
+
+	return STG_E_INVALIDFUNCTION;
+}
+
+// IStream methods
+
+STDMETHODIMP CaptionStream::Seek(LARGE_INTEGER move, DWORD origin,
+		ULARGE_INTEGER *new_pos)
+{
+	debugfunc("%lld, %lx, new_pos", move, origin);
+	UNUSED_PARAMETER(move);
+	UNUSED_PARAMETER(origin);
+
+	if (!new_pos)
+		return E_POINTER;
+
+	if (origin != SEEK_CUR || move.QuadPart != 0)
+		return E_NOTIMPL;
+
+	*new_pos = pos;
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::SetSize(ULARGE_INTEGER new_size)
+{
+	debugfunc("%llu", new_size);
+	UNUSED_PARAMETER(new_size);
+	return STG_E_INVALIDFUNCTION;
+}
+
+STDMETHODIMP CaptionStream::CopyTo(IStream *stream, ULARGE_INTEGER bytes,
+		ULARGE_INTEGER *read_bytes,
+		ULARGE_INTEGER *written_bytes)
+{
+	HRESULT hr;
+
+	debugfunc("stream, %llu, read_bytes, written_bytes", bytes);
+
+	if (!stream)
+		return STG_E_INVALIDPOINTER;
+
+	ULONG written = 0;
+	if (bytes.QuadPart > (ULONGLONG)buf->size)
+		bytes.QuadPart = (ULONGLONG)buf->size;
+
+	lock_guard<mutex> lock(m);
+	temp_buf.resize((size_t)bytes.QuadPart);
+	circlebuf_peek_front(buf, &temp_buf[0], (size_t)bytes.QuadPart);
+
+	hr = stream->Write(temp_buf.data(), (ULONG)bytes.QuadPart, &written);
+
+	if (read_bytes)
+		*read_bytes = bytes;
+	if (written_bytes)
+		written_bytes->QuadPart = written;
+
+	return hr;
+}
+
+STDMETHODIMP CaptionStream::Commit(DWORD commit_flags)
+{
+	debugfunc("%lx", commit_flags);
+	UNUSED_PARAMETER(commit_flags);
+	/* TODO? */
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::Revert(void)
+{
+	debugfunc("");
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::LockRegion(ULARGE_INTEGER offset,
+		ULARGE_INTEGER size, DWORD type)
+{
+	debugfunc("%llu, %llu, %ld", offset, size, type);
+	UNUSED_PARAMETER(offset);
+	UNUSED_PARAMETER(size);
+	UNUSED_PARAMETER(type);
+	/* TODO? */
+	return STG_E_INVALIDFUNCTION;
+}
+
+STDMETHODIMP CaptionStream::UnlockRegion(ULARGE_INTEGER offset,
+		ULARGE_INTEGER size, DWORD type)
+{
+	debugfunc("%llu, %llu, %ld", offset, size, type);
+	UNUSED_PARAMETER(offset);
+	UNUSED_PARAMETER(size);
+	UNUSED_PARAMETER(type);
+	/* TODO? */
+	return STG_E_INVALIDFUNCTION;
+}
+
+static const wchar_t *stat_name = L"Caption stream";
+
+STDMETHODIMP CaptionStream::Stat(STATSTG *stg, DWORD flag)
+{
+	debugfunc("stg, %lu", flag);
+
+	if (!stg)
+		return E_POINTER;
+
+	lock_guard<mutex> lock(m);
+	*stg = {};
+	stg->type = STGTY_STREAM;
+	stg->cbSize.QuadPart = (ULONGLONG)buf->size;
+
+	if (flag == STATFLAG_DEFAULT) {
+		stg->pwcsName = (wchar_t*)CoTaskMemAlloc(sizeof(stat_name));
+		memcpy(stg->pwcsName, stat_name, sizeof(stat_name));
+	}
+
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::Clone(IStream **stream)
+{
+	debugfunc("stream");
+	*stream = nullptr;
+	return E_NOTIMPL;
+}
+
+// ISpStreamFormat methods
+
+STDMETHODIMP CaptionStream::GetFormat(GUID *guid,
+		WAVEFORMATEX **co_mem_wfex_out)
+{
+	debugfunc("guid, co_mem_wfex_out");
+
+	if (!guid || !co_mem_wfex_out)
+		return E_POINTER;
+
+	if (format.wFormatTag == 0) {
+		*co_mem_wfex_out = nullptr;
+		return S_OK;
+	}
+
+	void *wfex = CoTaskMemAlloc(sizeof(format));
+	memcpy(wfex, &format, sizeof(format));
+
+	*co_mem_wfex_out = (WAVEFORMATEX*)wfex;
+	return S_OK;
+}
+
+// ISpAudio methods
+
+STDMETHODIMP CaptionStream::SetState(SPAUDIOSTATE state_, ULONGLONG)
+{
+	debugfunc("%lu, reserved", state_);
+	state = state_;
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::SetFormat(REFGUID guid_ref,
+		const WAVEFORMATEX *wfex)
+{
+	debugfunc("guid, wfex");
+	if (!wfex)
+		return E_INVALIDARG;
+
+	if (guid_ref == SPDFID_WaveFormatEx) {
+		lock_guard<mutex> lock(m);
+		memcpy(&format, wfex, sizeof(format));
+		resampler.Reset(wfex);
+
+		/* 50 msec */
+		DWORD size = format.nSamplesPerSec / 20;
+		DWORD byte_size = size * format.nBlockAlign;
+		circlebuf_reserve(buf, (size_t)byte_size);
+	}
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::GetStatus(SPAUDIOSTATUS *status)
+{
+	debugfunc("status");
+
+	if (!status)
+		return E_POINTER;
+
+	/* TODO? */
+	lock_guard<mutex> lock(m);
+	*status = {};
+	status->cbNonBlockingIO = (ULONG)buf->size;
+	status->State = state;
+	status->CurSeekPos = pos.QuadPart;
+	status->CurDevicePos = write_pos;
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::SetBufferInfo(const SPAUDIOBUFFERINFO *buf_info_)
+{
+	debugfunc("buf_info");
+
+	/* TODO */
+	buf_info = *buf_info_;
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::GetBufferInfo(SPAUDIOBUFFERINFO *buf_info_)
+{
+	debugfunc("buf_info");
+	if (!buf_info_)
+		return E_POINTER;
+
+	*buf_info_ = buf_info;
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::GetDefaultFormat(GUID *format,
+		WAVEFORMATEX **co_mem_wfex_out)
+{
+	debugfunc("format, co_mem_wfex_out");
+
+	if (!format || !co_mem_wfex_out)
+		return E_POINTER;
+
+	void *wfex = CoTaskMemAlloc(sizeof(format));
+	memcpy(wfex, &format, sizeof(format));
+
+	*format = SPDFID_WaveFormatEx;
+	*co_mem_wfex_out = (WAVEFORMATEX*)wfex;
+	return S_OK;
+}
+
+STDMETHODIMP_(HANDLE) CaptionStream::EventHandle(void)
+{
+	debugfunc("");
+	return event;
+}
+
+STDMETHODIMP CaptionStream::GetVolumeLevel(ULONG *level)
+{
+	debugfunc("level");
+	if (!level)
+		return E_POINTER;
+
+	*level = vol;
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::SetVolumeLevel(ULONG level)
+{
+	debugfunc("%lu", level);
+	vol = level;
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::GetBufferNotifySize(ULONG *size)
+{
+	debugfunc("size");
+	if (!size)
+		return E_POINTER;
+	*size = notify_size;
+	return S_OK;
+}
+
+STDMETHODIMP CaptionStream::SetBufferNotifySize(ULONG size)
+{
+	debugfunc("%lu", size);
+	notify_size = size;
+	return S_OK;
+}
diff --git a/UI/frontend-plugins/frontend-tools/captions-stream.hpp b/UI/frontend-plugins/frontend-tools/captions-stream.hpp
new file mode 100644
index 0000000..5461b7d
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/captions-stream.hpp
@@ -0,0 +1,119 @@
+#include <windows.h>
+#include <sapi.h>
+#include <condition_variable>
+#include <mutex>
+#include <vector>
+#include <obs.h>
+#include <media-io/audio-resampler.h>
+#include <util/circlebuf.h>
+#include <util/windows/WinHandle.hpp>
+
+#include <fstream>
+
+class CircleBuf {
+	circlebuf buf = {};
+public:
+	inline ~CircleBuf() {circlebuf_free(&buf);}
+	inline operator circlebuf*() {return &buf;}
+	inline circlebuf *operator->() {return &buf;}
+};
+
+class Resampler {
+	audio_resampler_t *resampler = nullptr;
+
+public:
+	inline void Reset(const WAVEFORMATEX *wfex)
+	{
+		const struct audio_output_info *aoi =
+			audio_output_get_info(obs_get_audio());
+
+		struct resample_info src;
+		src.samples_per_sec = aoi->samples_per_sec;
+		src.format = aoi->format;
+		src.speakers = aoi->speakers;
+
+		struct resample_info dst;
+		dst.samples_per_sec = uint32_t(wfex->nSamplesPerSec);
+		dst.format = AUDIO_FORMAT_16BIT;
+		dst.speakers = (enum speaker_layout)wfex->nChannels;
+
+		if (resampler)
+			audio_resampler_destroy(resampler);
+		resampler = audio_resampler_create(&dst, &src);
+	}
+
+	inline ~Resampler() {audio_resampler_destroy(resampler);}
+	inline operator audio_resampler_t*() {return resampler;}
+};
+
+class CaptionStream : public ISpAudio {
+	volatile long refs = 1;
+	SPAUDIOBUFFERINFO buf_info = {};
+	ULONG notify_size = 0;
+	SPAUDIOSTATE state;
+	WinHandle event;
+	ULONG vol = 0;
+
+	std::condition_variable cv;
+	std::mutex m;
+	std::vector<int16_t> temp_buf;
+	WAVEFORMATEX format = {};
+	Resampler resampler;
+
+	CircleBuf buf;
+	ULONG wait_size = 0;
+	DWORD samplerate = 0;
+	ULARGE_INTEGER pos = {};
+	ULONGLONG write_pos = 0;
+
+public:
+	CaptionStream(DWORD samplerate);
+
+	void Stop();
+	void PushAudio(const struct audio_data *audio_data, bool muted);
+
+	// IUnknown methods
+	STDMETHODIMP QueryInterface(REFIID riid, void **ppv) override;
+	STDMETHODIMP_(ULONG) AddRef() override;
+	STDMETHODIMP_(ULONG) Release() override;
+
+	// ISequentialStream methods
+	STDMETHODIMP Read(void *data, ULONG bytes, ULONG *read_bytes) override;
+	STDMETHODIMP Write(const void *data, ULONG bytes, ULONG *written_bytes)
+		override;
+
+	// IStream methods
+	STDMETHODIMP Seek(LARGE_INTEGER move, DWORD origin,
+			ULARGE_INTEGER *new_pos) override;
+	STDMETHODIMP SetSize(ULARGE_INTEGER new_size) override;
+	STDMETHODIMP CopyTo(IStream *stream, ULARGE_INTEGER bytes,
+			ULARGE_INTEGER *read_bytes,
+			ULARGE_INTEGER *written_bytes) override;
+	STDMETHODIMP Commit(DWORD commit_flags) override;
+	STDMETHODIMP Revert(void) override;
+	STDMETHODIMP LockRegion(ULARGE_INTEGER offset, ULARGE_INTEGER size,
+			DWORD type) override;
+	STDMETHODIMP UnlockRegion(ULARGE_INTEGER offset, ULARGE_INTEGER size,
+			DWORD type) override;
+	STDMETHODIMP Stat(STATSTG *stg, DWORD flags) override;
+	STDMETHODIMP Clone(IStream **stream) override;
+
+	// ISpStreamFormat methods
+	STDMETHODIMP GetFormat(GUID *guid, WAVEFORMATEX **co_mem_wfex_out)
+		override;
+
+	// ISpAudio methods
+	STDMETHODIMP SetState(SPAUDIOSTATE state, ULONGLONG reserved) override;
+	STDMETHODIMP SetFormat(REFGUID guid_ref, const WAVEFORMATEX *wfex)
+		override;
+	STDMETHODIMP GetStatus(SPAUDIOSTATUS *status) override;
+	STDMETHODIMP SetBufferInfo(const SPAUDIOBUFFERINFO *buf_info) override;
+	STDMETHODIMP GetBufferInfo(SPAUDIOBUFFERINFO *buf_info) override;
+	STDMETHODIMP GetDefaultFormat(GUID *format,
+			WAVEFORMATEX **co_mem_wfex_out) override;
+	STDMETHODIMP_(HANDLE) EventHandle(void) override;
+	STDMETHODIMP GetVolumeLevel(ULONG *level) override;
+	STDMETHODIMP SetVolumeLevel(ULONG level) override;
+	STDMETHODIMP GetBufferNotifySize(ULONG *size) override;
+	STDMETHODIMP SetBufferNotifySize(ULONG size) override;
+};
diff --git a/UI/frontend-plugins/frontend-tools/captions.cpp b/UI/frontend-plugins/frontend-tools/captions.cpp
new file mode 100644
index 0000000..c26d5b9
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/captions.cpp
@@ -0,0 +1,533 @@
+#include <obs-frontend-api.h>
+#include "captions-stream.hpp"
+#include "captions.hpp"
+#include "tool-helpers.hpp"
+#include <sphelper.h>
+#include <util/dstr.hpp>
+#include <util/platform.h>
+#include <util/windows/HRError.hpp>
+#include <util/windows/ComPtr.hpp>
+#include <util/windows/CoTaskMemPtr.hpp>
+#include <util/threading.h>
+#include <obs-module.h>
+
+#include <string>
+#include <thread>
+#include <mutex>
+
+#define do_log(type, format, ...) blog(type, "[Captions] " format, \
+		##__VA_ARGS__)
+
+#define error(format, ...) do_log(LOG_ERROR, format, ##__VA_ARGS__)
+#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
+
+using namespace std;
+
+struct obs_captions {
+	thread th;
+	recursive_mutex m;
+	WinHandle stop_event;
+
+	string source_name;
+	OBSWeakSource source;
+	LANGID lang_id;
+
+	void main_thread();
+	void start();
+	void stop();
+
+	inline obs_captions() :
+		stop_event(CreateEvent(nullptr, false, false, nullptr)),
+		lang_id(GetUserDefaultUILanguage())
+	{
+	}
+
+	inline ~obs_captions() {stop();}
+};
+
+static obs_captions *captions = nullptr;
+
+/* ------------------------------------------------------------------------- */
+
+struct locale_info {
+	DStr name;
+	LANGID id;
+
+	inline locale_info() {}
+	inline locale_info(const locale_info &) = delete;
+	inline locale_info(locale_info &&li)
+		: name(std::move(li.name)),
+		  id(li.id)
+	{}
+};
+
+static void get_valid_locale_names(vector<locale_info> &names);
+static bool valid_lang(LANGID id);
+
+/* ------------------------------------------------------------------------- */
+
+CaptionsDialog::CaptionsDialog(QWidget *parent) :
+	QDialog(parent),
+	ui(new Ui_CaptionsDialog)
+{
+	ui->setupUi(this);
+
+	lock_guard<recursive_mutex> lock(captions->m);
+
+	auto cb = [this] (obs_source_t *source)
+	{
+		uint32_t caps = obs_source_get_output_flags(source);
+		QString name = obs_source_get_name(source);
+
+		if (caps & OBS_SOURCE_AUDIO)
+			ui->source->addItem(name);
+
+		OBSWeakSource weak = OBSGetWeakRef(source);
+		if (weak == captions->source)
+			ui->source->setCurrentText(name);
+		return true;
+	};
+
+	using cb_t = decltype(cb);
+
+	ui->source->blockSignals(true);
+	ui->source->addItem(QStringLiteral(""));
+	ui->source->setCurrentIndex(0);
+	obs_enum_sources([] (void *data, obs_source_t *source) {
+			return (*static_cast<cb_t*>(data))(source);}, &cb);
+	ui->source->blockSignals(false);
+
+	ui->enable->blockSignals(true);
+	ui->enable->setChecked(captions->th.joinable());
+	ui->enable->blockSignals(false);
+
+	vector<locale_info> locales;
+	get_valid_locale_names(locales);
+
+	bool set_language = false;
+
+	ui->language->blockSignals(true);
+	for (int idx = 0; idx < (int)locales.size(); idx++) {
+		locale_info &locale = locales[idx];
+
+		ui->language->addItem(locale.name->array, (int)locale.id);
+
+		if (locale.id == captions->lang_id) {
+			ui->language->setCurrentIndex(idx);
+			set_language = true;
+		}
+	}
+
+	if (!set_language && locales.size())
+		ui->language->setCurrentIndex(0);
+
+	ui->language->blockSignals(false);
+
+	if (!locales.size()) {
+		ui->source->setEnabled(false);
+		ui->enable->setEnabled(false);
+		ui->language->setEnabled(false);
+
+	} else if (!set_language) {
+		bool started = captions->th.joinable();
+		if (started)
+			captions->stop();
+
+		captions->m.lock();
+		captions->lang_id = locales[0].id;
+		captions->m.unlock();
+
+		if (started)
+			captions->start();
+	}
+}
+
+void CaptionsDialog::on_source_currentIndexChanged(int)
+{
+	bool started = captions->th.joinable();
+	if (started)
+		captions->stop();
+
+	captions->m.lock();
+	captions->source_name = ui->source->currentText().toUtf8().constData();
+	captions->source = GetWeakSourceByName(captions->source_name.c_str());
+	captions->m.unlock();
+
+	if (started)
+		captions->start();
+}
+
+void CaptionsDialog::on_enable_clicked(bool checked)
+{
+	if (checked)
+		captions->start();
+	else
+		captions->stop();
+}
+
+void CaptionsDialog::on_language_currentIndexChanged(int)
+{
+	bool started = captions->th.joinable();
+	if (started)
+		captions->stop();
+
+	captions->m.lock();
+	captions->lang_id = (LANGID)ui->language->currentData().toInt();
+	captions->m.unlock();
+
+	if (started)
+		captions->start();
+}
+
+/* ------------------------------------------------------------------------- */
+
+void obs_captions::main_thread()
+try {
+	ComPtr<CaptionStream>  audio;
+	ComPtr<ISpObjectToken> token;
+	ComPtr<ISpRecoGrammar> grammar;
+	ComPtr<ISpRecognizer>  recognizer;
+	ComPtr<ISpRecoContext> context;
+	HRESULT hr;
+
+	auto cb = [&] (const struct audio_data *audio_data,
+			bool muted)
+	{
+		audio->PushAudio(audio_data, muted);
+	};
+
+	using cb_t = decltype(cb);
+
+	auto pre_cb = [] (void *param, obs_source_t*,
+		const struct audio_data *audio_data, bool muted)
+	{
+		return (*static_cast<cb_t*>(param))(audio_data, muted);
+	};
+
+	os_set_thread_name(__FUNCTION__);
+
+	CoInitialize(nullptr);
+
+	wchar_t lang_str[32];
+	_snwprintf(lang_str, 31, L"language=%x", (int)captions->lang_id);
+
+	hr = SpFindBestToken(SPCAT_RECOGNIZERS, lang_str, nullptr, &token);
+	if (FAILED(hr))
+		throw HRError("SpFindBestToken failed", hr);
+
+	hr = CoCreateInstance(CLSID_SpInprocRecognizer, nullptr, CLSCTX_ALL,
+			__uuidof(ISpRecognizer), (void**)&recognizer);
+	if (FAILED(hr))
+		throw HRError("CoCreateInstance for recognizer failed", hr);
+
+	hr = recognizer->SetRecognizer(token);
+	if (FAILED(hr))
+		throw HRError("SetRecognizer failed", hr);
+
+	hr = recognizer->SetRecoState(SPRST_INACTIVE);
+	if (FAILED(hr))
+		throw HRError("SetRecoState(SPRST_INACTIVE) failed", hr);
+
+	hr = recognizer->CreateRecoContext(&context);
+	if (FAILED(hr))
+		throw HRError("CreateRecoContext failed", hr);
+
+	ULONGLONG interest = SPFEI(SPEI_RECOGNITION) |
+		SPFEI(SPEI_END_SR_STREAM);
+	hr = context->SetInterest(interest, interest);
+	if (FAILED(hr))
+		throw HRError("SetInterest failed", hr);
+
+	HANDLE notify;
+
+	hr = context->SetNotifyWin32Event();
+	if (FAILED(hr))
+		throw HRError("SetNotifyWin32Event", hr);
+
+	notify = context->GetNotifyEventHandle();
+	if (notify == INVALID_HANDLE_VALUE)
+		throw HRError("GetNotifyEventHandle failed", E_NOINTERFACE);
+
+	size_t sample_rate = audio_output_get_sample_rate(obs_get_audio());
+	audio = new CaptionStream((DWORD)sample_rate);
+	audio->Release();
+
+	hr = recognizer->SetInput(audio, false);
+	if (FAILED(hr))
+		throw HRError("SetInput failed", hr);
+
+	hr = context->CreateGrammar(1, &grammar);
+	if (FAILED(hr))
+		throw HRError("CreateGrammar failed", hr);
+
+	hr = grammar->LoadDictation(nullptr, SPLO_STATIC);
+	if (FAILED(hr))
+		throw HRError("LoadDictation failed", hr);
+
+	hr = grammar->SetDictationState(SPRS_ACTIVE);
+	if (FAILED(hr))
+		throw HRError("SetDictationState failed", hr);
+
+	hr = recognizer->SetRecoState(SPRST_ACTIVE);
+	if (FAILED(hr))
+		throw HRError("SetRecoState(SPRST_ACTIVE) failed", hr);
+
+	HANDLE events[] = {notify, stop_event};
+
+	{
+		captions->source = GetWeakSourceByName(
+				captions->source_name.c_str());
+		OBSSource strong = OBSGetStrongRef(source);
+		if (strong)
+			obs_source_add_audio_capture_callback(strong,
+					pre_cb, &cb);
+	}
+
+	for (;;) {
+		DWORD ret = WaitForMultipleObjects(2, events, false, INFINITE);
+		if (ret != WAIT_OBJECT_0)
+			break;
+
+		CSpEvent event;
+		bool exit = false;
+
+		while (event.GetFrom(context) == S_OK) {
+			if (event.eEventId == SPEI_RECOGNITION) {
+				ISpRecoResult *result = event.RecoResult();
+
+				CoTaskMemPtr<wchar_t> text;
+				hr = result->GetText((ULONG)-1, (ULONG)-1,
+						true, &text, nullptr);
+				if (FAILED(hr))
+					continue;
+
+				char text_utf8[512];
+				os_wcs_to_utf8(text, 0, text_utf8, 512);
+
+				obs_output_t *output =
+					obs_frontend_get_streaming_output();
+				if (output)
+					obs_output_output_caption_text1(output,
+							text_utf8);
+
+				debug("\"%s\"", text_utf8);
+
+				obs_output_release(output);
+
+			} else if (event.eEventId == SPEI_END_SR_STREAM) {
+				exit = true;
+				break;
+			}
+		}
+
+		if (exit)
+			break;
+	}
+
+	{
+		OBSSource strong = OBSGetStrongRef(source);
+		if (strong)
+			obs_source_remove_audio_capture_callback(strong,
+					pre_cb, &cb);
+	}
+
+	audio->Stop();
+
+	CoUninitialize();
+
+} catch (HRError err) {
+	error("%s failed: %s (%lX)", __FUNCTION__, err.str, err.hr);
+	CoUninitialize();
+	captions->th.detach();
+}
+
+void obs_captions::start()
+{
+	if (!captions->th.joinable()) {
+		ResetEvent(captions->stop_event);
+
+		if (valid_lang(captions->lang_id))
+			captions->th = thread([] () {captions->main_thread();});
+	}
+}
+
+void obs_captions::stop()
+{
+	if (!captions->th.joinable())
+		return;
+
+	SetEvent(captions->stop_event);
+	captions->th.join();
+}
+
+static bool get_locale_name(LANGID id, char *out)
+{
+	wchar_t name[256];
+
+	int size = GetLocaleInfoW(id, LOCALE_SENGLISHLANGUAGENAME, name, 256);
+	if (size <= 0)
+		return false;
+
+	os_wcs_to_utf8(name, 0, out, 256);
+	return true;
+}
+
+static bool valid_lang(LANGID id)
+{
+	ComPtr<ISpObjectToken> token;
+	wchar_t lang_str[32];
+	HRESULT hr;
+
+	_snwprintf(lang_str, 31, L"language=%x", (int)id);
+
+	hr = SpFindBestToken(SPCAT_RECOGNIZERS, lang_str, nullptr, &token);
+	return SUCCEEDED(hr);
+}
+
+static void get_valid_locale_names(vector<locale_info> &locales)
+{
+	locale_info cur;
+	char locale_name[256];
+
+	static const LANGID default_locales[] = {
+		0x0409,
+		0x0401,
+		0x0402,
+		0x0403,
+		0x0404,
+		0x0405,
+		0x0406,
+		0x0407,
+		0x0408,
+		0x040a,
+		0x040b,
+		0x040c,
+		0x040d,
+		0x040e,
+		0x040f,
+		0x0410,
+		0x0411,
+		0x0412,
+		0x0413,
+		0x0414,
+		0x0415,
+		0x0416,
+		0x0417,
+		0x0418,
+		0x0419,
+		0x041a,
+		0
+	};
+
+	/* ---------------------------------- */
+
+	LANGID def_id = GetUserDefaultUILanguage();
+	LANGID id = def_id;
+	if (valid_lang(id) && get_locale_name(id, locale_name)) {
+		dstr_copy(cur.name, obs_module_text(
+					"Captions.CurrentSystemLanguage"));
+		dstr_replace(cur.name, "%1", locale_name);
+		cur.id = id;
+
+		locales.push_back(std::move(cur));
+	}
+
+	/* ---------------------------------- */
+
+	const LANGID *locale = default_locales;
+
+	while (*locale) {
+		id = *locale;
+
+		if (id != def_id &&
+		    valid_lang(id) &&
+		    get_locale_name(id, locale_name)) {
+
+			dstr_copy(cur.name, locale_name);
+			cur.id = id;
+
+			locales.push_back(std::move(cur));
+		}
+
+		locale++;
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+extern "C" void FreeCaptions()
+{
+	delete captions;
+	captions = nullptr;
+}
+
+static void obs_event(enum obs_frontend_event event, void *)
+{
+	if (event == OBS_FRONTEND_EVENT_EXIT)
+		FreeCaptions();
+}
+
+static void save_caption_data(obs_data_t *save_data, bool saving, void*)
+{
+	if (saving) {
+		lock_guard<recursive_mutex> lock(captions->m);
+		obs_data_t *obj = obs_data_create();
+
+		obs_data_set_string(obj, "source",
+				captions->source_name.c_str());
+		obs_data_set_bool(obj, "enabled", captions->th.joinable());
+		obs_data_set_int(obj, "lang_id", captions->lang_id);
+
+		obs_data_set_obj(save_data, "captions", obj);
+		obs_data_release(obj);
+	} else {
+		captions->stop();
+
+		captions->m.lock();
+
+		obs_data_t *obj = obs_data_get_obj(save_data, "captions");
+		if (!obj)
+			obj = obs_data_create();
+
+		obs_data_set_default_int(obj, "lang_id",
+				GetUserDefaultUILanguage());
+
+		bool enabled = obs_data_get_bool(obj, "enabled");
+		captions->source_name = obs_data_get_string(obj, "source");
+		captions->lang_id = (int)obs_data_get_int(obj, "lang_id");
+		captions->source = GetWeakSourceByName(
+				captions->source_name.c_str());
+		obs_data_release(obj);
+
+		captions->m.unlock();
+
+		if (enabled)
+			captions->start();
+	}
+}
+
+extern "C" void InitCaptions()
+{
+	QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
+			obs_module_text("Captions"));
+
+	captions = new obs_captions;
+
+	auto cb = [] ()
+	{
+		obs_frontend_push_ui_translation(obs_module_get_string);
+
+		QWidget *window =
+			(QWidget*)obs_frontend_get_main_window();
+
+		CaptionsDialog dialog(window);
+		dialog.exec();
+
+		obs_frontend_pop_ui_translation();
+	};
+
+	obs_frontend_add_save_callback(save_caption_data, nullptr);
+	obs_frontend_add_event_callback(obs_event, nullptr);
+
+	action->connect(action, &QAction::triggered, cb);
+}
diff --git a/UI/frontend-plugins/frontend-tools/captions.hpp b/UI/frontend-plugins/frontend-tools/captions.hpp
new file mode 100644
index 0000000..d499755
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/captions.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <QDialog>
+#include <memory>
+
+#include "ui_captions.h"
+
+class CaptionsDialog : public QDialog {
+	Q_OBJECT
+
+	std::unique_ptr<Ui_CaptionsDialog> ui;
+
+public:
+	CaptionsDialog(QWidget *parent);
+
+public slots:
+	void on_source_currentIndexChanged(int idx);
+	void on_enable_clicked(bool checked);
+	void on_language_currentIndexChanged(int idx);
+};
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ca-ES.ini b/UI/frontend-plugins/frontend-tools/data/locale/ca-ES.ini
index 2b17855..509d1c9 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/ca-ES.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/ca-ES.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="No canviar"
 SceneSwitcher.OnNoMatch.SwitchTo="Canvia a:"
 SceneSwitcher.CheckInterval="Comprova el títol de la finestra activa cada:"
 SceneSwitcher.ActiveOrNotActive="El canviador de escena està:"
+InvalidRegex.Title="Expressió regular no vàlida"
+InvalidRegex.Text="La expressió regular que heu introduït no es vàlida."
 Active="Actiu"
 Inactive="Inactiu"
 Start="Inicia"
 Stop="Atura"
 
+Captions="Subtítols (Experimental)"
+Captions.AudioSource="Font d'àudio"
+Captions.CurrentSystemLanguage="Idioma actual del sistema (%1)"
+
+OutputTimer="Temporitzador de sortida"
+OutputTimer.Stream="Atura la transmissió després de:"
+OutputTimer.Record="Atura la gravació després de:"
+OutputTimer.Stream.StoppingIn="La transmissió s'aturarà en:"
+OutputTimer.Record.StoppingIn="La gravació s'aturarà en:"
+OutputTimer.Stream.EnableEverytime="Activa el temporitzador en cada transmissió"
+OutputTimer.Record.EnableEverytime="Activa el temporitzador en cada enregistrament"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/cs-CZ.ini b/UI/frontend-plugins/frontend-tools/data/locale/cs-CZ.ini
index c8a4565..832040c 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/cs-CZ.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/cs-CZ.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Nepřepínat"
 SceneSwitcher.OnNoMatch.SwitchTo="Přepnout na:"
 SceneSwitcher.CheckInterval="Kontrolovat titulek aktivního okna každých:"
 SceneSwitcher.ActiveOrNotActive="Přepínač scén je:"
+InvalidRegex.Title="Chybný regulární výraz"
+InvalidRegex.Text="Zadaný regulární výraz je chybný."
 Active="Aktivní"
 Inactive="Neaktivní"
 Start="Spustit"
 Stop="Zastavit"
 
+Captions="Titulky (experiment.)"
+Captions.AudioSource="Zdroj zvuku"
+Captions.CurrentSystemLanguage="Aktuální systémový jazyk (%1)"
+
+OutputTimer="Časovač"
+OutputTimer.Stream="Přestat vysílat po:"
+OutputTimer.Record="Přestat nahrávat po:"
+OutputTimer.Stream.StoppingIn="Vysílání se zastaví za:"
+OutputTimer.Record.StoppingIn="Nahrávání se zastaví za:"
+OutputTimer.Stream.EnableEverytime="Pokaždé povolit časovač vysílání"
+OutputTimer.Record.EnableEverytime="Pokaždé povolit časovač nahrávání"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini b/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini
index f72389c..f830d7c 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini
@@ -1,11 +1,25 @@
-SceneSwitcher="Automatisk sceneskifter"
-SceneSwitcher.OnNoMatch="NÃ¥r intet vindue svarer til:"
+SceneSwitcher="Automatisk sceneomskifter"
+SceneSwitcher.OnNoMatch="NÃ¥r intet vindue matcher:"
 SceneSwitcher.OnNoMatch.DontSwitch="Skift ikke"
 SceneSwitcher.OnNoMatch.SwitchTo="Skift til:"
 SceneSwitcher.CheckInterval="Kontroller aktivt vinduestitel hvert:"
-SceneSwitcher.ActiveOrNotActive="Sceneskifter er:"
+SceneSwitcher.ActiveOrNotActive="Sceneomskifter er:"
+InvalidRegex.Title="Ugyldigt regulært udtryk"
+InvalidRegex.Text="Det af dig angivne regulære udtryk er ugyldigt."
 Active="Aktiv"
 Inactive="Inaktiv"
 Start="Start"
 Stop="Stop"
 
+Captions="Undertekster (eksperimentel)"
+Captions.AudioSource="Lydkilde"
+Captions.CurrentSystemLanguage="Aktuelt systemsprog (%1)"
+
+OutputTimer="Output-timer"
+OutputTimer.Stream="Stands streaming efter:"
+OutputTimer.Record="Stands optagelse efter:"
+OutputTimer.Stream.StoppingIn="Streaming standser om:"
+OutputTimer.Record.StoppingIn="Streaming standser om:"
+OutputTimer.Stream.EnableEverytime="Aktivér streaming-timer hver gang"
+OutputTimer.Record.EnableEverytime="Aktivér optage-timer hver gang"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini b/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini
index 4caf47e..97d1909 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Nicht wechseln"
 SceneSwitcher.OnNoMatch.SwitchTo="Wechseln zu:"
 SceneSwitcher.CheckInterval="Titel des aktiven Fensters überprüfen alle:"
 SceneSwitcher.ActiveOrNotActive="Szenenwechsler ist:"
+InvalidRegex.Title="Ungültiger regulärer Ausdruck"
+InvalidRegex.Text="Der reguläre Ausdruck, den Sie eingegeben haben, ist ungültig."
 Active="Aktiv"
 Inactive="Inaktiv"
 Start="Start"
 Stop="Stop"
 
+Captions="Untertitel (experimentell)"
+Captions.AudioSource="Audioquelle"
+Captions.CurrentSystemLanguage="Aktuelle Systemsprache (%1)"
+
+OutputTimer="Ausgabetimer"
+OutputTimer.Stream="Stoppe Stream nach:"
+OutputTimer.Record="Stoppe Aufnahme nach:"
+OutputTimer.Stream.StoppingIn="Stream stoppt in:"
+OutputTimer.Record.StoppingIn="Aufnahme stoppt in:"
+OutputTimer.Stream.EnableEverytime="Streaming-Timer jedes Mal aktivieren"
+OutputTimer.Record.EnableEverytime="Aufnahme-Timer jedes Mal aktivieren"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/en-US.ini b/UI/frontend-plugins/frontend-tools/data/locale/en-US.ini
index 63a4673..daf4b31 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/en-US.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/en-US.ini
@@ -4,7 +4,21 @@ SceneSwitcher.OnNoMatch.DontSwitch="Don't switch"
 SceneSwitcher.OnNoMatch.SwitchTo="Switch to:"
 SceneSwitcher.CheckInterval="Check active window title every:"
 SceneSwitcher.ActiveOrNotActive="Scene Switcher is:"
+InvalidRegex.Title="Invalid Regular Expression"
+InvalidRegex.Text="The regular expression that you entered is invalid."
 Active="Active"
 Inactive="Inactive"
 Start="Start"
 Stop="Stop"
+
+Captions="Captions (Experimental)"
+Captions.AudioSource="Audio source"
+Captions.CurrentSystemLanguage="Current System Language (%1)"
+
+OutputTimer="Output Timer"
+OutputTimer.Stream="Stop streaming after:"
+OutputTimer.Record="Stop recording after:"
+OutputTimer.Stream.StoppingIn="Streaming stopping in:"
+OutputTimer.Record.StoppingIn="Recording stopping in:"
+OutputTimer.Stream.EnableEverytime="Enable streaming timer every time"
+OutputTimer.Record.EnableEverytime="Enable recording timer every time"
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini b/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini
index a08a8f9..4d76f15 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="No cambiar"
 SceneSwitcher.OnNoMatch.SwitchTo="Cambiar a:"
 SceneSwitcher.CheckInterval="Comprobar el título de la ventana activa cada:"
 SceneSwitcher.ActiveOrNotActive="El cambiador de escena está:"
+InvalidRegex.Title="Expresión regular no válida"
+InvalidRegex.Text="La expresión regular que ha introducido no es válida."
 Active="Activo"
 Inactive="Inactivo"
 Start="Iniciar"
 Stop="Detener"
 
+Captions="Subtítulos (Experimental)"
+Captions.AudioSource="Fuente de audio"
+Captions.CurrentSystemLanguage="Idioma actual del sistema (%1)"
+
+OutputTimer="Temporizador de salida"
+OutputTimer.Stream="Detener la transmisión después de:"
+OutputTimer.Record="Detener la grabación después de:"
+OutputTimer.Stream.StoppingIn="Finalizando transmisión en:"
+OutputTimer.Record.StoppingIn="Finalizando grabación en:"
+OutputTimer.Stream.EnableEverytime="Activar temporizador en cada transmisión"
+OutputTimer.Record.EnableEverytime="Activar temporizador en cada grabación"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/et-EE.ini b/UI/frontend-plugins/frontend-tools/data/locale/et-EE.ini
new file mode 100644
index 0000000..be17c53
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/data/locale/et-EE.ini
@@ -0,0 +1,21 @@
+SceneSwitcher="Automaatne stseeni vahetaja"
+SceneSwitcher.OnNoMatch="Kui üksi aken ei sobi:"
+SceneSwitcher.OnNoMatch.DontSwitch="Ära vaheta"
+SceneSwitcher.OnNoMatch.SwitchTo="Lülitu ümber:"
+SceneSwitcher.CheckInterval="Kontrollige aktiivse akna pealkiri iga:"
+SceneSwitcher.ActiveOrNotActive="Stseen vahetaja on:"
+Active="Aktiivne"
+Inactive="Inaktiivne"
+Start="Alusta"
+Stop="Lõpeta"
+
+Captions="Subtiitrid (eksperimentaalne)"
+Captions.AudioSource="Heli allikas"
+Captions.CurrentSystemLanguage="Praegune süsteemi keel (%1)"
+
+OutputTimer="Väljundi taimer"
+OutputTimer.Stream="Lõpeta voogedastus pärast:"
+OutputTimer.Record="Lõpeta voogedastus pärast:"
+OutputTimer.Stream.StoppingIn="Voogedastus lõppeb:"
+OutputTimer.Record.StoppingIn="Salvestamine lõppeb:"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/eu-ES.ini b/UI/frontend-plugins/frontend-tools/data/locale/eu-ES.ini
index 99076b3..79f760e 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/eu-ES.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/eu-ES.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Ez aldatu"
 SceneSwitcher.OnNoMatch.SwitchTo="Aldatu hona:"
 SceneSwitcher.CheckInterval="Leiho aktiboaren titulua egiaztatzeko maiztasuna:"
 SceneSwitcher.ActiveOrNotActive="Eszena aldatzailea dago:"
+InvalidRegex.Title="Adierazpen erregular baliogabea"
+InvalidRegex.Text="Sartu duzun adierazpen erregularra baliogabea da."
 Active="Aktiboa"
 Inactive="Inaktiboa"
 Start="Hasi"
 Stop="Gelditu"
 
+Captions="Epigrafeak (esperimentala)"
+Captions.AudioSource="Audio-iturburua"
+Captions.CurrentSystemLanguage="Sistemaren hizkuntza (%1)"
+
+OutputTimer="Irteera tenporizadorea"
+OutputTimer.Stream="Gelditu transmisioa hau pasata:"
+OutputTimer.Record="Gelditu grabazioa hau pasata:"
+OutputTimer.Stream.StoppingIn="Transmisioa geldituko da: hau barru:"
+OutputTimer.Record.StoppingIn="Grabazioa geldituko da hau barru:"
+OutputTimer.Stream.EnableEverytime="Gaitu transmisio tenporizadorea aldiro"
+OutputTimer.Record.EnableEverytime="Gaitu grabazio tenporizadorea aldiro"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/fi-FI.ini b/UI/frontend-plugins/frontend-tools/data/locale/fi-FI.ini
index 0f20868..77a4bc6 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/fi-FI.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/fi-FI.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Älä vaihda"
 SceneSwitcher.OnNoMatch.SwitchTo="Vaihda:"
 SceneSwitcher.CheckInterval="Tarkista aktiivisen ikkunan otsikko:"
 SceneSwitcher.ActiveOrNotActive="Skenen vaihtaja:"
+InvalidRegex.Title="Invalid Regular Expression"
+InvalidRegex.Text="The regular expression that you entered is invalid."
 Active="Aktiivinen"
 Inactive="Ei käytössä"
 Start="Käynnistä"
 Stop="Pysäytä"
 
+Captions="Kuvatekstit (Experimental)"
+Captions.AudioSource="Äänilähde"
+Captions.CurrentSystemLanguage="Järjestelmän kieli (%1)"
+
+OutputTimer="Ulostulo-ajastin"
+OutputTimer.Stream="Pysäyttää lähetyksen:"
+OutputTimer.Record="Pysäyttää tallennuksen:"
+OutputTimer.Stream.StoppingIn="Lähetys pysäytetään:"
+OutputTimer.Record.StoppingIn="Tallennus pysäytetään:"
+OutputTimer.Stream.EnableEverytime="Ota lähetysajastin käyttöön aina"
+OutputTimer.Record.EnableEverytime="Ota tallennusajastin käyttöön aina"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini b/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini
index 65d0b4c..1ffb41b 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Ne rien faire"
 SceneSwitcher.OnNoMatch.SwitchTo="Basculer vers :"
 SceneSwitcher.CheckInterval="Détecter le titre de la fenêtre active toutes les :"
 SceneSwitcher.ActiveOrNotActive="Etat du sélecteur automatique :"
+InvalidRegex.Title="Expression invalide"
+InvalidRegex.Text="L'expression régulière saisie est invalide."
 Active="Actif"
 Inactive="Inactif"
 Start="Démarrer"
 Stop="Arrêter"
 
+Captions="Sous-titres (expérimental)"
+Captions.AudioSource="Source audio"
+Captions.CurrentSystemLanguage="Langue du système (%1)"
+
+OutputTimer="Minuterie des sorties"
+OutputTimer.Stream="Arrêter le streaming dans :"
+OutputTimer.Record="Arrêter l'enregistrement dans :"
+OutputTimer.Stream.StoppingIn="Arrêt du streaming dans :"
+OutputTimer.Record.StoppingIn="Arrêt de l'enregistrement dans :"
+OutputTimer.Stream.EnableEverytime="Activer le minuteur automatiquement à chaque stream"
+OutputTimer.Record.EnableEverytime="Activer le minuteur automatiquement à chaque enregistrement"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/hr-HR.ini b/UI/frontend-plugins/frontend-tools/data/locale/hr-HR.ini
index fb81a54..ed94f35 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/hr-HR.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/hr-HR.ini
@@ -4,8 +4,19 @@ SceneSwitcher.OnNoMatch.DontSwitch="Ne menjaj"
 SceneSwitcher.OnNoMatch.SwitchTo="Promeni na:"
 SceneSwitcher.CheckInterval="Proveravaj naziv aktivnog prozora svakih:"
 SceneSwitcher.ActiveOrNotActive="Menjač scena je:"
+InvalidRegex.Title="Neispravan regularni izraz"
+InvalidRegex.Text="Regularni izraz koji ste uneli nije ispravan."
 Active="Aktivan"
 Inactive="Neaktivan"
 Start="Pokreni"
 Stop="Zaustavi"
 
+
+OutputTimer="Tempomat snimanja i emitovanja"
+OutputTimer.Stream="Zaustavi emitovanje nakon:"
+OutputTimer.Record="Zaustavi snimanje nakon:"
+OutputTimer.Stream.StoppingIn="Prekidanje emitovanja za:"
+OutputTimer.Record.StoppingIn="Prekidanje snimanja za:"
+OutputTimer.Stream.EnableEverytime="Omogući štopovanje emitovanja svaki put"
+OutputTimer.Record.EnableEverytime="Omogući štopovanje snimanja svaki put"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/hu-HU.ini b/UI/frontend-plugins/frontend-tools/data/locale/hu-HU.ini
index bfd99aa..94d6614 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/hu-HU.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/hu-HU.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Ne váltson"
 SceneSwitcher.OnNoMatch.SwitchTo="Váltson:"
 SceneSwitcher.CheckInterval="Aktív ablak ellenőrzése ennyi időközönként:"
 SceneSwitcher.ActiveOrNotActive="Jelenet váltó:"
+InvalidRegex.Title="Érvénytelen kifejezés"
+InvalidRegex.Text="A megadott kifejezés érvénytelen."
 Active="Aktív"
 Inactive="Inaktiv"
 Start="Start"
 Stop="Stop"
 
+Captions="Feliratok (Kísérleti)"
+Captions.AudioSource="Audio forrás"
+Captions.CurrentSystemLanguage="Rendszer aktuális nyelve (%1)"
+
+OutputTimer="Kimeneti időzítő"
+OutputTimer.Stream="Stream leállítása:"
+OutputTimer.Record="Felvétel leállítása:"
+OutputTimer.Stream.StoppingIn="A stream leáll:"
+OutputTimer.Record.StoppingIn="Felvétel leáll:"
+OutputTimer.Stream.EnableEverytime="Stream időzítő indítása minden alkalommal"
+OutputTimer.Record.EnableEverytime="Felvétel időzítő indítása minden alkalommal"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini b/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini
new file mode 100644
index 0000000..b8c6a87
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini
@@ -0,0 +1,25 @@
+SceneSwitcher="Cambia scena automatico"
+SceneSwitcher.OnNoMatch="Quando nessuna scena coincide a:"
+SceneSwitcher.OnNoMatch.DontSwitch="Non passare"
+SceneSwitcher.OnNoMatch.SwitchTo="Passa a:"
+SceneSwitcher.CheckInterval="Controlla il titolo della finestra attiva ogni:"
+SceneSwitcher.ActiveOrNotActive="Lo scene switcher è:"
+InvalidRegex.Title="Espressione regolare non valida"
+InvalidRegex.Text="L'espressione regolare che hai inserito non è valido."
+Active="Attivo"
+Inactive="Inattivo"
+Start="Inizio"
+Stop="Stop"
+
+Captions="Sottotitoli (Sperimentale)"
+Captions.AudioSource="Fonte audio"
+Captions.CurrentSystemLanguage="Lingua del sistema in uso (%1)"
+
+OutputTimer="Timer Output"
+OutputTimer.Stream="Termina diretta dopo:"
+OutputTimer.Record="Termina registrazione dopo:"
+OutputTimer.Stream.StoppingIn="La diretta terminerà in:"
+OutputTimer.Record.StoppingIn="La registrazione terminerà in:"
+OutputTimer.Stream.EnableEverytime="Abilita il timer per lo streaming ogni volta"
+OutputTimer.Record.EnableEverytime="Abilita il timer per la registrazione ogni volta"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ja-JP.ini b/UI/frontend-plugins/frontend-tools/data/locale/ja-JP.ini
index 714c79c..6005f8a 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/ja-JP.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/ja-JP.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="切り替えない"
 SceneSwitcher.OnNoMatch.SwitchTo="切り替える:"
 SceneSwitcher.CheckInterval="アクティブウィンドウタイトルを確認する間隔:"
 SceneSwitcher.ActiveOrNotActive="シーンスイッチャーは:"
+InvalidRegex.Title="無効な正規表現"
+InvalidRegex.Text="入力した正規表現は有効ではありません。"
 Active="アクティブ"
 Inactive="非アクティブ"
 Start="開始"
 Stop="停止"
 
+Captions="見出し (実験的)"
+Captions.AudioSource="音声ソース"
+Captions.CurrentSystemLanguage="現在のシステム言語 (%1)"
+
+OutputTimer="出力タイマー"
+OutputTimer.Stream="配信停止の時間設定:"
+OutputTimer.Record="録画停止の時間設定:"
+OutputTimer.Stream.StoppingIn="配信停止まで:"
+OutputTimer.Record.StoppingIn="録画停止まで:"
+OutputTimer.Stream.EnableEverytime="毎回配信タイマーを有効にする"
+OutputTimer.Record.EnableEverytime="毎回録画タイマーを有効にする"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ko-KR.ini b/UI/frontend-plugins/frontend-tools/data/locale/ko-KR.ini
index cbfee50..0bb7dc2 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/ko-KR.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/ko-KR.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="전환하지 않음"
 SceneSwitcher.OnNoMatch.SwitchTo="여기로 전환:"
 SceneSwitcher.CheckInterval="활성화된 윈도우 제목을 확인:"
 SceneSwitcher.ActiveOrNotActive="장면 전환기:"
+InvalidRegex.Title="유효하지 않은 정규 표현"
+InvalidRegex.Text="입력한 정규 표현이 유효하지 않습니다."
 Active="활성화"
 Inactive="비활성화"
 Start="시작"
 Stop="중단"
 
+Captions="자막 (실험적 기능)"
+Captions.AudioSource="오디오 소스"
+Captions.CurrentSystemLanguage="현재 시스템 언어 (%1)"
+
+OutputTimer="출력 시간 설정"
+OutputTimer.Stream="이 시간 이후 방송 중단:"
+OutputTimer.Record="이 시간 이후 녹화 중단:"
+OutputTimer.Stream.StoppingIn="방송 중지까지 남은 시간:"
+OutputTimer.Record.StoppingIn="녹화 중지까지 남은 시간:"
+OutputTimer.Stream.EnableEverytime="매번 방송 시간 기록기 활성화"
+OutputTimer.Record.EnableEverytime="매번 녹화 시간 기록기 활성화"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ms-MY.ini b/UI/frontend-plugins/frontend-tools/data/locale/ms-MY.ini
new file mode 100644
index 0000000..36ec39f
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/data/locale/ms-MY.ini
@@ -0,0 +1,11 @@
+Active="Aktif"
+Inactive="Tidak Aktif"
+Start="Mula"
+Stop="Berhenti"
+
+
+OutputTimer.Stream="Berhenti 'streaming' selepas:"
+OutputTimer.Record="Berhenti merakam selepas:"
+OutputTimer.Stream.StoppingIn="'Streaming' dihentikan dalam:"
+OutputTimer.Record.StoppingIn="Rakaman dihentikan dalam:"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/nb-NO.ini b/UI/frontend-plugins/frontend-tools/data/locale/nb-NO.ini
new file mode 100644
index 0000000..e525d27
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/data/locale/nb-NO.ini
@@ -0,0 +1,25 @@
+SceneSwitcher="Automatisk Scene Skifter"
+SceneSwitcher.OnNoMatch="NÃ¥r ingen vindu passer overens:"
+SceneSwitcher.OnNoMatch.DontSwitch="Ikke bytt"
+SceneSwitcher.OnNoMatch.SwitchTo="Bytt til:"
+SceneSwitcher.CheckInterval="Sjekk aktivt vindu hver:"
+SceneSwitcher.ActiveOrNotActive="Sceneskifter er:"
+InvalidRegex.Title="Ugyldig regulært utrykk"
+InvalidRegex.Text="Det regulære utrykket du har angitt er ugyldig."
+Active="Aktiv"
+Inactive="Inaktiv"
+Start="Start"
+Stop="Stopp"
+
+Captions="Bildetekster (eksperimentell)"
+Captions.AudioSource="Lyd kilde"
+Captions.CurrentSystemLanguage="Någjeldende System Språk"
+
+OutputTimer="Stoppeklokke"
+OutputTimer.Stream="Stopp streaming etter:"
+OutputTimer.Record="Stopp opptak etter:"
+OutputTimer.Stream.StoppingIn="Streaming stopper om:"
+OutputTimer.Record.StoppingIn="Opptak stopper om:"
+OutputTimer.Stream.EnableEverytime="Aktiver streaming timer hver gang"
+OutputTimer.Record.EnableEverytime="Aktiver opptaks timer hver gang"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/nl-NL.ini b/UI/frontend-plugins/frontend-tools/data/locale/nl-NL.ini
index b785c86..661d16c 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/nl-NL.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/nl-NL.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Wissel niet"
 SceneSwitcher.OnNoMatch.SwitchTo="Wissel naar:"
 SceneSwitcher.CheckInterval="Controleer actieve venstertitel elke:"
 SceneSwitcher.ActiveOrNotActive="Scènewisselaar is:"
+InvalidRegex.Title="Ongeldige Reguliere Expressie"
+InvalidRegex.Text="De ingevoerde reguliere expressie is ongeldig."
 Active="Actief"
 Inactive="Inactief"
 Start="Start"
 Stop="Stop"
 
+Captions="Ondertiteling (Experimenteel)"
+Captions.AudioSource="Audiobron"
+Captions.CurrentSystemLanguage="Huidige Systeemtaal (%1)"
+
+OutputTimer="Uitvoertimer"
+OutputTimer.Stream="Stop met streamen na:"
+OutputTimer.Record="Stop met opnemen na:"
+OutputTimer.Stream.StoppingIn="Stream stopt over:"
+OutputTimer.Record.StoppingIn="Opname stopt over:"
+OutputTimer.Stream.EnableEverytime="Schakel streaming timer elke keer in"
+OutputTimer.Record.EnableEverytime="Schakel opnametimer elke keer in"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini b/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini
index dd2d18d..79b8a6a 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Nie przełączaj"
 SceneSwitcher.OnNoMatch.SwitchTo="Przełącz na:"
 SceneSwitcher.CheckInterval="Sprawdź tytuł aktywnego okna co:"
 SceneSwitcher.ActiveOrNotActive="Przełączanie scen jest:"
+InvalidRegex.Title="Nieprawidłowe wyrażenie regularne"
+InvalidRegex.Text="Podane wyrażenie regularne jest nieprawidłowe."
 Active="Aktywne"
 Inactive="Nieaktywne"
 Start="Start"
 Stop="Stop"
 
+Captions="Podpisy (eksperymentalne)"
+Captions.AudioSource="Źródła dźwięku"
+Captions.CurrentSystemLanguage="Obecny język systemu (%1)"
+
+OutputTimer="Wyłącznik czasowy"
+OutputTimer.Stream="Zatrzymaj stream po:"
+OutputTimer.Record="Zatrzymaj nagrywanie po:"
+OutputTimer.Stream.StoppingIn="Zatrzymanie streamu za:"
+OutputTimer.Record.StoppingIn="Zatrzymanie nagrywania za:"
+OutputTimer.Stream.EnableEverytime="Włącz timer streamu za każdym razem"
+OutputTimer.Record.EnableEverytime="Włącz timer nagrywania za każdym razem"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/pt-BR.ini b/UI/frontend-plugins/frontend-tools/data/locale/pt-BR.ini
index 5a6a4eb..e3770c5 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/pt-BR.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/pt-BR.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Não alternar"
 SceneSwitcher.OnNoMatch.SwitchTo="Alternar para:"
 SceneSwitcher.CheckInterval="Checar o título da janela ativa a cada:"
 SceneSwitcher.ActiveOrNotActive="O alternador de cenas está:"
+InvalidRegex.Title="Expressão Regular inválida"
+InvalidRegex.Text="A expressão regular que você inseriu é inválida."
 Active="Ligado"
 Inactive="Desligado"
 Start="Iniciar"
 Stop="Parar"
 
+Captions="Legendas (Experimental)"
+Captions.AudioSource="Fonte de Áudio"
+Captions.CurrentSystemLanguage="Idioma Atual do Sistema (%1)"
+
+OutputTimer="Temporizador de saída"
+OutputTimer.Stream="Parar a transmissão após:"
+OutputTimer.Record="Parar a gravação após:"
+OutputTimer.Stream.StoppingIn="A transmissão irá parar em:"
+OutputTimer.Record.StoppingIn="A gravação irá parar em:"
+OutputTimer.Stream.EnableEverytime="Ativar o timer streaming o tempo todo"
+OutputTimer.Record.EnableEverytime="Ativar o timer de gravação o tempo todo"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/pt-PT.ini b/UI/frontend-plugins/frontend-tools/data/locale/pt-PT.ini
new file mode 100644
index 0000000..b9363bf
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/data/locale/pt-PT.ini
@@ -0,0 +1,20 @@
+SceneSwitcher="Troca automática de cenas"
+SceneSwitcher.OnNoMatch="Quando nenhuma janela corresponder:"
+SceneSwitcher.OnNoMatch.DontSwitch="Não trocar"
+SceneSwitcher.OnNoMatch.SwitchTo="Trocar para:"
+SceneSwitcher.CheckInterval="Verificar o nome da janela ativa a cada:"
+SceneSwitcher.ActiveOrNotActive="A troca de cenas está:"
+InvalidRegex.Title="Expressão regular inválida"
+InvalidRegex.Text="A expressão regular que introduziu é inválida."
+Active="Ativa"
+Inactive="Inativa"
+Start="Iniciar"
+Stop="Parar"
+
+
+OutputTimer="Temporizador de saída"
+OutputTimer.Stream="Para a transmissão após:"
+OutputTimer.Record="Parar a gravação após:"
+OutputTimer.Stream.StoppingIn="A transmissão irá parar em:"
+OutputTimer.Record.StoppingIn="A gravação irá parar em:"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ro-RO.ini b/UI/frontend-plugins/frontend-tools/data/locale/ro-RO.ini
new file mode 100644
index 0000000..2f223b9
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/data/locale/ro-RO.ini
@@ -0,0 +1,13 @@
+SceneSwitcher="Schimbator automat de scenă"
+SceneSwitcher.OnNoMatch="Cand nici o fereastra nu se potriveste:"
+SceneSwitcher.OnNoMatch.SwitchTo="Schimbă la:"
+Active="Activ"
+Inactive="Inactiv"
+Start="Pornire"
+Stop="Oprire"
+
+Captions.AudioSource="Sursa audio"
+Captions.CurrentSystemLanguage="Limba curentă a sistemului (%1)"
+
+OutputTimer.Record="Opriți inregistrarea dupa:"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini b/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini
index 831e0d0..84e8e53 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Не переключать"
 SceneSwitcher.OnNoMatch.SwitchTo="Переключать на:"
 SceneSwitcher.CheckInterval="Проверять имя активного окна каждые:"
 SceneSwitcher.ActiveOrNotActive="Переключатель сцен:"
+InvalidRegex.Title="Недопустимое регулярное выражение"
+InvalidRegex.Text="Регулярное выражение, которое вы ввели, содержит ошибки."
 Active="Активен"
 Inactive="Неактивен"
 Start="Запустить"
 Stop="Остановить"
 
+Captions="Субтитры (экспериментально)"
+Captions.AudioSource="Источник звука"
+Captions.CurrentSystemLanguage="Текущий язык системы (%1)"
+
+OutputTimer="Таймер записи и стрима"
+OutputTimer.Stream="Завершить стрим через:"
+OutputTimer.Record="Завершить запись через:"
+OutputTimer.Stream.StoppingIn="Стрим будет завершён через:"
+OutputTimer.Record.StoppingIn="Запись будет завершена через:"
+OutputTimer.Stream.EnableEverytime="Включать таймер стрима каждый раз"
+OutputTimer.Record.EnableEverytime="Включать таймер записи каждый раз"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/sk-SK.ini b/UI/frontend-plugins/frontend-tools/data/locale/sk-SK.ini
new file mode 100644
index 0000000..b5d2316
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/data/locale/sk-SK.ini
@@ -0,0 +1,10 @@
+SceneSwitcher.CheckInterval="Kontrolovať aktívne okno každých:"
+Active="Aktívny"
+Inactive="Neaktivní"
+Start="Spustiť"
+Stop="Zastaviť"
+
+
+OutputTimer.Stream="Zastaviť stream po:"
+OutputTimer.Record="Zastaviť nahrávanie po:"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/sr-CS.ini b/UI/frontend-plugins/frontend-tools/data/locale/sr-CS.ini
index fb81a54..ed94f35 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/sr-CS.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/sr-CS.ini
@@ -4,8 +4,19 @@ SceneSwitcher.OnNoMatch.DontSwitch="Ne menjaj"
 SceneSwitcher.OnNoMatch.SwitchTo="Promeni na:"
 SceneSwitcher.CheckInterval="Proveravaj naziv aktivnog prozora svakih:"
 SceneSwitcher.ActiveOrNotActive="Menjač scena je:"
+InvalidRegex.Title="Neispravan regularni izraz"
+InvalidRegex.Text="Regularni izraz koji ste uneli nije ispravan."
 Active="Aktivan"
 Inactive="Neaktivan"
 Start="Pokreni"
 Stop="Zaustavi"
 
+
+OutputTimer="Tempomat snimanja i emitovanja"
+OutputTimer.Stream="Zaustavi emitovanje nakon:"
+OutputTimer.Record="Zaustavi snimanje nakon:"
+OutputTimer.Stream.StoppingIn="Prekidanje emitovanja za:"
+OutputTimer.Record.StoppingIn="Prekidanje snimanja za:"
+OutputTimer.Stream.EnableEverytime="Omogući štopovanje emitovanja svaki put"
+OutputTimer.Record.EnableEverytime="Omogući štopovanje snimanja svaki put"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/sr-SP.ini b/UI/frontend-plugins/frontend-tools/data/locale/sr-SP.ini
index 983378f..f40fa5a 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/sr-SP.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/sr-SP.ini
@@ -4,8 +4,19 @@ SceneSwitcher.OnNoMatch.DontSwitch="Не мењај"
 SceneSwitcher.OnNoMatch.SwitchTo="Промени на:"
 SceneSwitcher.CheckInterval="Проверавај назив активног прозора сваких:"
 SceneSwitcher.ActiveOrNotActive="Мењач сцена је:"
+InvalidRegex.Title="Неисправан регуларни израз"
+InvalidRegex.Text="Регуларни израз који сте унели није исправан."
 Active="Активан"
 Inactive="Неактиван"
 Start="Покрени"
 Stop="Заустави"
 
+
+OutputTimer="Темпомат снимања и емитовања"
+OutputTimer.Stream="Заустави емитовање након:"
+OutputTimer.Record="Заустави снимање након:"
+OutputTimer.Stream.StoppingIn="Прекидање емитовања за:"
+OutputTimer.Record.StoppingIn="Прекидање снимања за:"
+OutputTimer.Stream.EnableEverytime="Омогући штоповање емитовање сваки пут"
+OutputTimer.Record.EnableEverytime="Омогући штоповање снимања сваки пут"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/sv-SE.ini b/UI/frontend-plugins/frontend-tools/data/locale/sv-SE.ini
index a2f6330..4740873 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/sv-SE.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/sv-SE.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Byt inte"
 SceneSwitcher.OnNoMatch.SwitchTo="Byt till:"
 SceneSwitcher.CheckInterval="Kontrollera aktiv fönstertitel varje:"
 SceneSwitcher.ActiveOrNotActive="Scenbytaren är:"
+InvalidRegex.Title="Ogiltigt reguljärt uttryck"
+InvalidRegex.Text="Det reguljära uttrycket du angav är ogiltigt."
 Active="Aktiv"
 Inactive="Inaktiv"
 Start="Starta"
 Stop="Stoppa"
 
+Captions="Undertexter (experimentell)"
+Captions.AudioSource="Ljudkälla"
+Captions.CurrentSystemLanguage="Aktuellt systemspråk (%1)"
+
+OutputTimer="Utdatatimer"
+OutputTimer.Stream="Sluta streama efter:"
+OutputTimer.Record="Stoppa inspelningen efter:"
+OutputTimer.Stream.StoppingIn="Streamen stoppas om:"
+OutputTimer.Record.StoppingIn="Inspelningen stoppas om:"
+OutputTimer.Stream.EnableEverytime="Aktivera strömtimer varje gång"
+OutputTimer.Record.EnableEverytime="Aktivera inspelningstimer varje gång"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/tr-TR.ini b/UI/frontend-plugins/frontend-tools/data/locale/tr-TR.ini
new file mode 100644
index 0000000..287208b
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/data/locale/tr-TR.ini
@@ -0,0 +1,25 @@
+SceneSwitcher="Otomatik Sahne DeÄŸiÅŸtirici"
+SceneSwitcher.OnNoMatch="Hiçbir pencere ile eşleşmez ise:"
+SceneSwitcher.OnNoMatch.DontSwitch="Geçiş yapma"
+SceneSwitcher.OnNoMatch.SwitchTo="Şuna geç:"
+SceneSwitcher.CheckInterval="Etkin pencere başlığını kontrol et:"
+SceneSwitcher.ActiveOrNotActive="Sahne DeÄŸiÅŸtirici:"
+InvalidRegex.Title="Geçersiz Kurallı İfade"
+InvalidRegex.Text="Girdiğiniz kurallı ifade geçersiz."
+Active="Etkin"
+Inactive="Devre Dışı"
+Start="BaÅŸlat"
+Stop="Durdur"
+
+Captions="Altyazı (Deneysel)"
+Captions.AudioSource="Ses kaynağı"
+Captions.CurrentSystemLanguage="Geçerli Sistem Dili (%1)"
+
+OutputTimer="Çıkış Zamanlayıcısı"
+OutputTimer.Stream="Şuradan sonra yayını durdur:"
+OutputTimer.Record="Şuradan sonra kaydı durdur:"
+OutputTimer.Stream.StoppingIn="Yayın durduruluyor:"
+OutputTimer.Record.StoppingIn="Kayıt durduruluyor:"
+OutputTimer.Stream.EnableEverytime="Her zaman yayın zamanlayıcıyı etkinleştir"
+OutputTimer.Record.EnableEverytime="Her zaman kayıt zamanlayıcıyı etkinleştir"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/uk-UA.ini b/UI/frontend-plugins/frontend-tools/data/locale/uk-UA.ini
index 12a1a0b..ba03f1b 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/uk-UA.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/uk-UA.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="Нічого не робити"
 SceneSwitcher.OnNoMatch.SwitchTo="Перейти до:"
 SceneSwitcher.CheckInterval="Перевіряти заголовок активного вікна кожні:"
 SceneSwitcher.ActiveOrNotActive="Автоматичний перехід між Сценами:"
+InvalidRegex.Title="Неприпустимий регулярний вираз"
+InvalidRegex.Text="Ви ввели неприпустимий регулярний вираз (шаблон)."
 Active="Активний"
 Inactive="Неактивний"
 Start="Запустити"
 Stop="Зупинити"
 
+Captions="Субтитри (експериментально)"
+Captions.AudioSource="Джерело Аудіо"
+Captions.CurrentSystemLanguage="Поточна мова Системи (%1)"
+
+OutputTimer="Таймер для Виводу"
+OutputTimer.Stream="Закінчити трансляцію за:"
+OutputTimer.Record="Зупинити запис за:"
+OutputTimer.Stream.StoppingIn="Трансляція припиниться за:"
+OutputTimer.Record.StoppingIn="Запис зупиниться за:"
+OutputTimer.Stream.EnableEverytime="Щоразу запускається трансляція - вмикати Таймер для Виводу"
+OutputTimer.Record.EnableEverytime="Щоразу починається запис - вмикати Таймер для Виводу"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/vi-VN.ini b/UI/frontend-plugins/frontend-tools/data/locale/vi-VN.ini
new file mode 100644
index 0000000..bd8a79c
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/data/locale/vi-VN.ini
@@ -0,0 +1,17 @@
+SceneSwitcher="Tự động chuyển cảnh"
+SceneSwitcher.OnNoMatch="Khi cửa sổ không khớp:"
+SceneSwitcher.OnNoMatch.DontSwitch="Không chuyển"
+SceneSwitcher.OnNoMatch.SwitchTo="Chuyển sang:"
+SceneSwitcher.CheckInterval="Kiểm tra tiêu đề cửa sổ mỗi:"
+SceneSwitcher.ActiveOrNotActive="Chuyển cảnh đang:"
+Active="Đang hoạt động"
+Inactive="Không hoạt động"
+Start="Bắt đầu"
+Stop="Dừng"
+
+
+OutputTimer.Stream="Dừng stream sau:"
+OutputTimer.Record="Dừng ghi video sau:"
+OutputTimer.Stream.StoppingIn="Stream sẽ dừng trong:"
+OutputTimer.Record.StoppingIn="Quay video sẽ dừng trong:"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini b/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini
index 1ae756f..eb09aa7 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="不切换"
 SceneSwitcher.OnNoMatch.SwitchTo="切换到:"
 SceneSwitcher.CheckInterval="检查活动窗口的标题,每:"
 SceneSwitcher.ActiveOrNotActive="场景切换器是:"
+InvalidRegex.Title="无效的正则表达式"
+InvalidRegex.Text="您输入的正则表达式是无效的。"
 Active="已激活"
 Inactive="未激活"
 Start="开始"
 Stop="停止"
 
+Captions="标题(实验)"
+Captions.AudioSource="音频源"
+Captions.CurrentSystemLanguage="当前系统语言 (%1)"
+
+OutputTimer="输出计时器"
+OutputTimer.Stream="停止流处理后:"
+OutputTimer.Record="停止录制后:"
+OutputTimer.Stream.StoppingIn="串流停止在:"
+OutputTimer.Record.StoppingIn="录制停止在:"
+OutputTimer.Stream.EnableEverytime="每次启用流计时器"
+OutputTimer.Record.EnableEverytime="每次启用录制计时器"
+
diff --git a/UI/frontend-plugins/frontend-tools/data/locale/zh-TW.ini b/UI/frontend-plugins/frontend-tools/data/locale/zh-TW.ini
index ac7668a..17412b8 100644
--- a/UI/frontend-plugins/frontend-tools/data/locale/zh-TW.ini
+++ b/UI/frontend-plugins/frontend-tools/data/locale/zh-TW.ini
@@ -4,8 +4,22 @@ SceneSwitcher.OnNoMatch.DontSwitch="不切換"
 SceneSwitcher.OnNoMatch.SwitchTo="切換到︰"
 SceneSwitcher.CheckInterval="檢查使用中視窗標題的頻率︰"
 SceneSwitcher.ActiveOrNotActive="場景切換器︰"
+InvalidRegex.Title="無效的正規表達式"
+InvalidRegex.Text="您輸入的正則運算式不正確"
 Active="啟動中"
 Inactive="未啟動"
 Start="開始"
 Stop="停止"
 
+Captions="標題 (實驗)"
+Captions.AudioSource="音訊源"
+Captions.CurrentSystemLanguage="目前系統語言 (%1)"
+
+OutputTimer="輸出計時器"
+OutputTimer.Stream="在下面時間後停止串流:"
+OutputTimer.Record="在下面時間後停止錄影:"
+OutputTimer.Stream.StoppingIn="串流將在下面時間內停止"
+OutputTimer.Record.StoppingIn="錄影將在下面時間內停止"
+OutputTimer.Stream.EnableEverytime="每次都啟動串流計時器"
+OutputTimer.Record.EnableEverytime="每次都啟動錄影計時器"
+
diff --git a/UI/frontend-plugins/frontend-tools/forms/captions.ui b/UI/frontend-plugins/frontend-tools/forms/captions.ui
new file mode 100644
index 0000000..4f08214
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/forms/captions.ui
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CaptionsDialog</class>
+ <widget class="QDialog" name="CaptionsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>519</width>
+    <height>140</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Captions</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QFormLayout" name="formLayout">
+     <property name="labelAlignment">
+      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+     </property>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Captions.AudioSource</string>
+       </property>
+       <property name="buddy">
+        <cstring>source</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QComboBox" name="source">
+       <property name="insertPolicy">
+        <enum>QComboBox::InsertAlphabetically</enum>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QCheckBox" name="enable">
+       <property name="text">
+        <string>Enable</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Basic.Settings.General.Language</string>
+       </property>
+       <property name="buddy">
+        <cstring>language</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="QComboBox" name="language"/>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="accept">
+       <property name="text">
+        <string>OK</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>accept</sender>
+   <signal>clicked()</signal>
+   <receiver>CaptionsDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>268</x>
+     <y>331</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>229</x>
+     <y>-11</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/UI/frontend-plugins/frontend-tools/forms/output-timer.ui b/UI/frontend-plugins/frontend-tools/forms/output-timer.ui
new file mode 100644
index 0000000..b9ea3d9
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/forms/output-timer.ui
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OutputTimer</class>
+   <widget class="QDialog" name="OutputTimer">
+    <property name="geometry">
+      <rect>
+        <x>0</x>
+        <y>0</y>
+        <width>600</width>
+        <height>200</height>
+      </rect>
+    </property>
+    <property name="windowTitle">
+      <string>OutputTimer</string>
+    </property>
+    <layout class="QGridLayout" name="timerLayout">
+      <item row="0" column="1">
+        <widget class="QLabel" name="streamingLabel">
+          <property name="text">
+            <string>OutputTimer.Stream</string>
+          </property>
+        </widget>
+      </item>
+      <item row="0" column="2">
+        <widget class="QSpinBox" name="streamingTimerHours">
+          <property name="minimum">
+            <number>0</number>
+          </property>
+          <property name="maximum">
+            <number>24</number>
+          </property>
+          <property name="value">
+            <number>0</number>
+          </property>
+        </widget>
+      </item>
+      <item row="0" column="3">
+        <widget class="QLabel" name="hoursLabel">
+          <property name="text">
+            <string>Hours</string>
+          </property>
+        </widget>
+      </item>
+      <item row="0" column="4">
+        <widget class="QSpinBox" name="streamingTimerMinutes">
+          <property name="maximum">
+            <number>59</number>
+          </property>
+          <property name="value">
+            <number>0</number>
+          </property>
+        </widget>
+      </item>
+      <item row="0" column="5">
+        <widget class="QLabel" name="minutesLabel">
+          <property name="text">
+            <string>Minutes</string>
+          </property>
+        </widget>
+      </item>
+      <item row="0" column="6">
+        <widget class="QSpinBox" name="streamingTimerSeconds">
+          <property name="minimum">
+            <number>0</number>
+          </property>
+          <property name="maximum">
+            <number>59</number>
+          </property>
+          <property name="value">
+            <number>30</number>
+          </property>
+        </widget>
+      </item>
+      <item row="0" column="7">
+        <widget class="QLabel" name="secondsLabel">
+          <property name="text">
+            <string>Seconds</string>
+          </property>
+        </widget>
+      </item>
+      <item row="0" column="8">
+        <widget class="QPushButton" name="outputTimerStream">
+          <property name="text">
+            <string>Start</string>
+          </property>
+        </widget>
+      </item>
+      <item row="2" column="1">
+        <widget class="QLabel" name="streamStoppingIn">
+          <property name="text">
+            <string>OutputTimer.Stream.StoppingIn</string>
+          </property>
+        </widget>
+      </item>
+      <item row="2" column="2">
+        <widget class="QLabel" name="streamTime">
+          <property name="text">
+            <string>00:00:00</string>
+          </property>
+        </widget>
+      </item>
+      <item row="3" column="1">
+        <widget class="QLabel" name="recordingLabel">
+          <property name="text">
+            <string>OutputTimer.Record</string>
+          </property>
+        </widget>
+      </item>
+      <item row="3" column="2">
+        <widget class="QSpinBox" name="recordingTimerHours">
+          <property name="minimum">
+            <number>0</number>
+          </property>
+          <property name="maximum">
+            <number>24</number>
+          </property>
+          <property name="value">
+            <number>0</number>
+          </property>
+        </widget>
+      </item>
+      <item row="3" column="3">
+        <widget class="QLabel" name="hoursLabel_2">
+          <property name="text">
+            <string>Hours</string>
+          </property>
+        </widget>
+      </item>
+      <item row="3" column="4">
+        <widget class="QSpinBox" name="recordingTimerMinutes">
+          <property name="minimum">
+            <number>0</number>
+          </property>
+          <property name="maximum">
+            <number>59</number>
+          </property>
+          <property name="value">
+            <number>0</number>
+          </property>
+        </widget>
+      </item>
+      <item row="3" column="5">
+        <widget class="QLabel" name="minutesLabel_2">
+          <property name="text">
+            <string>Minutes</string>
+          </property>
+        </widget>
+      </item>
+      <item row="3" column="6">
+        <widget class="QSpinBox" name="recordingTimerSeconds">
+          <property name="minimum">
+            <number>0</number>
+          </property>
+          <property name="maximum">
+            <number>59</number>
+          </property>
+          <property name="value">
+            <number>30</number>
+          </property>
+        </widget>
+      </item>
+      <item row="3" column="7">
+        <widget class="QLabel" name="secondsLabel_2">
+          <property name="text">
+            <string>Seconds</string>
+          </property>
+        </widget>
+      </item>
+      <item row="3" column="8">
+        <widget class="QPushButton" name="outputTimerRecord">
+          <property name="text">
+            <string>Start</string>
+          </property>
+        </widget>
+      </item>
+      <item row="5" column="1">
+        <widget class="QLabel" name="recordStoppingIn">
+          <property name="text">
+            <string>OutputTimer.Record.StoppingIn</string>
+          </property>
+        </widget>
+      </item>
+      <item row="5" column="2">
+        <widget class="QLabel" name="recordTime">
+          <property name="text">
+            <string>00:00:00</string>
+          </property>
+        </widget>
+      </item>
+      <item row="1" column="1" colspan="3">
+        <widget class="QCheckBox" name="autoStartStreamTimer">
+          <property name="text">
+            <string>OutputTimer.Stream.EnableEverytime</string>
+          </property>
+        </widget>
+      </item>
+      <item row="4" column="1" colspan="3">
+        <widget class="QCheckBox" name="autoStartRecordTimer">
+          <property name="text">
+            <string>OutputTimer.Record.EnableEverytime</string>
+          </property>
+        </widget>
+      </item>
+    </layout>
+  </widget>
+  <resources />
+  <connections />
+</ui>
diff --git a/UI/frontend-plugins/frontend-tools/frontend-tools-config.h.in b/UI/frontend-plugins/frontend-tools/frontend-tools-config.h.in
new file mode 100644
index 0000000..3389a42
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/frontend-tools-config.h.in
@@ -0,0 +1,3 @@
+#pragma once
+
+#define BUILD_CAPTIONS @BUILD_CAPTIONS@
diff --git a/UI/frontend-plugins/frontend-tools/frontend-tools.c b/UI/frontend-plugins/frontend-tools/frontend-tools.c
index 3826f04..a586b88 100644
--- a/UI/frontend-plugins/frontend-tools/frontend-tools.c
+++ b/UI/frontend-plugins/frontend-tools/frontend-tools.c
@@ -1,18 +1,41 @@
 #include <obs-module.h>
+#include "frontend-tools-config.h"
 
 OBS_DECLARE_MODULE()
 OBS_MODULE_USE_DEFAULT_LOCALE("frontend-tools", "en-US")
 
+#if defined(_WIN32) || defined(__APPLE__)
 void InitSceneSwitcher();
 void FreeSceneSwitcher();
+#endif
+
+#if defined(_WIN32) && BUILD_CAPTIONS
+void InitCaptions();
+void FreeCaptions();
+#endif
+
+void InitOutputTimer();
+void FreeOutputTimer();
 
 bool obs_module_load(void)
 {
+#if defined(_WIN32) || defined(__APPLE__)
 	InitSceneSwitcher();
+#endif
+#if defined(_WIN32) && BUILD_CAPTIONS
+	InitCaptions();
+#endif
+	InitOutputTimer();
 	return true;
 }
 
 void obs_module_unload(void)
 {
+#if defined(_WIN32) || defined(__APPLE__)
 	FreeSceneSwitcher();
+#endif
+#if defined(_WIN32) && BUILD_CAPTIONS
+	FreeCaptions();
+#endif
+	FreeOutputTimer();
 }
diff --git a/UI/frontend-plugins/frontend-tools/output-timer.cpp b/UI/frontend-plugins/frontend-tools/output-timer.cpp
new file mode 100644
index 0000000..441e929
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/output-timer.cpp
@@ -0,0 +1,312 @@
+#include <obs-frontend-api.h>
+#include <obs-module.h>
+#include <obs.hpp>
+#include <util/util.hpp>
+#include <QAction>
+#include <QMainWindow>
+#include <QTimer>
+#include <QObject>
+#include "output-timer.hpp"
+
+using namespace std;
+
+OutputTimer *ot;
+
+OutputTimer::OutputTimer(QWidget *parent)
+	: QDialog(parent),
+	ui(new Ui_OutputTimer)
+{
+	ui->setupUi(this);
+
+	QObject::connect(ui->outputTimerStream, SIGNAL(clicked()), this,
+		SLOT(StreamingTimerButton()));
+	QObject::connect(ui->outputTimerRecord, SIGNAL(clicked()), this,
+		SLOT(RecordingTimerButton()));
+
+	streamingTimer = new QTimer(this);
+	streamingTimerDisplay = new QTimer(this);
+
+	recordingTimer = new QTimer(this);
+	recordingTimerDisplay = new QTimer(this);
+}
+
+void OutputTimer::closeEvent(QCloseEvent*)
+{
+	obs_frontend_save();
+}
+
+void OutputTimer::StreamingTimerButton()
+{
+	if (!obs_frontend_streaming_active()) {
+		obs_frontend_streaming_start();
+	} else if (streamingAlreadyActive) {
+		StreamTimerStart();
+		streamingAlreadyActive = false;
+	} else if (obs_frontend_streaming_active()) {
+		obs_frontend_streaming_stop();
+	}
+}
+
+void OutputTimer::RecordingTimerButton()
+{
+	if (!obs_frontend_recording_active()) {
+		obs_frontend_recording_start();
+	} else if (recordingAlreadyActive) {
+		RecordTimerStart();
+		recordingAlreadyActive = false;
+	} else if (obs_frontend_recording_active()) {
+		obs_frontend_recording_stop();
+	}
+}
+
+void OutputTimer::StreamTimerStart()
+{
+	if (!isVisible() && ui->autoStartStreamTimer->isChecked() == false) {
+		streamingAlreadyActive = true;
+		return;
+	}
+
+	int hours = ui->streamingTimerHours->value();
+	int minutes = ui->streamingTimerMinutes->value();
+	int seconds = ui->streamingTimerSeconds->value();
+
+	int total = (((hours * 3600) +
+		(minutes * 60)) +
+		seconds) * 1000;
+
+	if (total == 0)
+		total = 1000;
+
+	streamingTimer->setInterval(total);
+	streamingTimer->setSingleShot(true);
+
+	QObject::connect(streamingTimer, SIGNAL(timeout()),
+		SLOT(EventStopStreaming()));
+
+	QObject::connect(streamingTimerDisplay, SIGNAL(timeout()), this,
+		SLOT(UpdateStreamTimerDisplay()));
+
+	streamingTimer->start();
+	streamingTimerDisplay->start(1000);
+	ui->outputTimerStream->setText(obs_module_text("Stop"));
+
+	UpdateStreamTimerDisplay();
+}
+
+void OutputTimer::RecordTimerStart()
+{
+	if (!isVisible() && ui->autoStartRecordTimer->isChecked() == false) {
+		recordingAlreadyActive = true;
+		return;
+	}
+
+	int hours = ui->recordingTimerHours->value();
+	int minutes = ui->recordingTimerMinutes->value();
+	int seconds = ui->recordingTimerSeconds->value();
+
+	int total = (((hours * 3600) +
+			(minutes * 60)) +
+			seconds) * 1000;
+
+	if (total == 0)
+		total = 1000;
+
+	recordingTimer->setInterval(total);
+	recordingTimer->setSingleShot(true);
+
+	QObject::connect(recordingTimer, SIGNAL(timeout()),
+		SLOT(EventStopRecording()));
+
+	QObject::connect(recordingTimerDisplay, SIGNAL(timeout()), this,
+		SLOT(UpdateRecordTimerDisplay()));
+
+	recordingTimer->start();
+	recordingTimerDisplay->start(1000);
+	ui->outputTimerRecord->setText(obs_module_text("Stop"));
+
+	UpdateRecordTimerDisplay();
+}
+
+void OutputTimer::StreamTimerStop()
+{
+	streamingAlreadyActive = false;
+
+	if (!isVisible() && streamingTimer->isActive() == false)
+		return;
+
+	if (streamingTimer->isActive())
+		streamingTimer->stop();
+
+	ui->outputTimerStream->setText(obs_module_text("Start"));
+
+	if (streamingTimerDisplay->isActive())
+		streamingTimerDisplay->stop();
+
+	ui->streamTime->setText("00:00:00");
+}
+
+void OutputTimer::RecordTimerStop()
+{
+	recordingAlreadyActive = false;
+
+	if (!isVisible() && recordingTimer->isActive() == false)
+		return;
+
+	if (recordingTimer->isActive())
+		recordingTimer->stop();
+
+	ui->outputTimerRecord->setText(obs_module_text("Start"));
+
+	if (recordingTimerDisplay->isActive())
+		recordingTimerDisplay->stop();
+
+	ui->recordTime->setText("00:00:00");
+}
+
+void OutputTimer::UpdateStreamTimerDisplay()
+{
+	int remainingTime = streamingTimer->remainingTime() / 1000;
+
+	int seconds = remainingTime % 60;
+	int minutes = (remainingTime % 3600) / 60;
+	int hours = remainingTime / 3600;
+
+	QString text;
+	text.sprintf("%02d:%02d:%02d", hours, minutes, seconds);
+	ui->streamTime->setText(text);
+}
+
+void OutputTimer::UpdateRecordTimerDisplay()
+{
+	int remainingTime = recordingTimer->remainingTime() / 1000;
+
+	int seconds = remainingTime % 60;
+	int minutes = (remainingTime % 3600) / 60;
+	int hours = remainingTime / 3600;
+
+	QString text;
+	text.sprintf("%02d:%02d:%02d", hours, minutes, seconds);
+	ui->recordTime->setText(text);
+}
+
+void OutputTimer::ShowHideDialog()
+{
+	if (!isVisible()) {
+		setVisible(true);
+		QTimer::singleShot(250, this, SLOT(show()));
+	} else {
+		setVisible(false);
+		QTimer::singleShot(250, this, SLOT(hide()));
+	}
+}
+
+void OutputTimer::EventStopStreaming()
+{
+	obs_frontend_streaming_stop();
+}
+
+void OutputTimer::EventStopRecording()
+{
+	obs_frontend_recording_stop();
+}
+
+static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *)
+{
+	if (saving) {
+		obs_data_t *obj = obs_data_create();
+
+		obs_data_set_int(obj, "streamTimerHours",
+				ot->ui->streamingTimerHours->value());
+		obs_data_set_int(obj, "streamTimerMinutes",
+				ot->ui->streamingTimerMinutes->value());
+		obs_data_set_int(obj, "streamTimerSeconds",
+				ot->ui->streamingTimerSeconds->value());
+
+		obs_data_set_int(obj, "recordTimerHours",
+				ot->ui->recordingTimerHours->value());
+		obs_data_set_int(obj, "recordTimerMinutes",
+				ot->ui->recordingTimerMinutes->value());
+		obs_data_set_int(obj, "recordTimerSeconds",
+				ot->ui->recordingTimerSeconds->value());
+
+		obs_data_set_bool(obj, "autoStartStreamTimer",
+				ot->ui->autoStartStreamTimer->isChecked());
+		obs_data_set_bool(obj, "autoStartRecordTimer",
+				ot->ui->autoStartRecordTimer->isChecked());
+
+		obs_data_set_obj(save_data, "output-timer", obj);
+
+		obs_data_release(obj);
+	} else {
+		obs_data_t *obj = obs_data_get_obj(save_data,
+				"output-timer");
+
+		if (!obj)
+			obj = obs_data_create();
+
+		ot->ui->streamingTimerHours->setValue(
+				obs_data_get_int(obj, "streamTimerHours"));
+		ot->ui->streamingTimerMinutes->setValue(
+				obs_data_get_int(obj, "streamTimerMinutes"));
+		ot->ui->streamingTimerSeconds->setValue(
+				obs_data_get_int(obj, "streamTimerSeconds"));
+
+		ot->ui->recordingTimerHours->setValue(
+				obs_data_get_int(obj, "recordTimerHours"));
+		ot->ui->recordingTimerMinutes->setValue(
+				obs_data_get_int(obj, "recordTimerMinutes"));
+		ot->ui->recordingTimerSeconds->setValue(
+				obs_data_get_int(obj, "recordTimerSeconds"));
+
+		ot->ui->autoStartStreamTimer->setChecked(
+				obs_data_get_bool(obj, "autoStartStreamTimer"));
+		ot->ui->autoStartRecordTimer->setChecked(
+				obs_data_get_bool(obj, "autoStartRecordTimer"));
+
+		obs_data_release(obj);
+	}
+}
+
+extern "C" void FreeOutputTimer()
+{
+}
+
+static void OBSEvent(enum obs_frontend_event event, void *)
+{
+	if (event == OBS_FRONTEND_EVENT_EXIT) {
+		obs_frontend_save();
+		FreeOutputTimer();
+	} else if (event == OBS_FRONTEND_EVENT_STREAMING_STARTED) {
+		ot->StreamTimerStart();
+	} else if (event == OBS_FRONTEND_EVENT_STREAMING_STOPPING) {
+		ot->StreamTimerStop();
+	} else if (event == OBS_FRONTEND_EVENT_RECORDING_STARTED) {
+		ot->RecordTimerStart();
+	} else if (event == OBS_FRONTEND_EVENT_RECORDING_STOPPING) {
+		ot->RecordTimerStop();
+	}
+}
+
+extern "C" void InitOutputTimer()
+{
+	QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
+			obs_module_text("OutputTimer"));
+
+	obs_frontend_push_ui_translation(obs_module_get_string);
+
+	QMainWindow *window = (QMainWindow*)obs_frontend_get_main_window();
+
+	ot = new OutputTimer(window);
+
+	auto cb = [] ()
+	{
+		ot->ShowHideDialog();
+	};
+
+	obs_frontend_pop_ui_translation();
+
+	obs_frontend_add_save_callback(SaveOutputTimer, nullptr);
+	obs_frontend_add_event_callback(OBSEvent, nullptr);
+
+	action->connect(action, &QAction::triggered, cb);
+}
diff --git a/UI/frontend-plugins/frontend-tools/output-timer.hpp b/UI/frontend-plugins/frontend-tools/output-timer.hpp
new file mode 100644
index 0000000..ff3b733
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/output-timer.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <QDialog>
+#include <memory>
+
+#include "ui_output-timer.h"
+
+class QCloseEvent;
+
+class OutputTimer : public QDialog {
+	Q_OBJECT
+
+public:
+	std::unique_ptr<Ui_OutputTimer> ui;
+	OutputTimer(QWidget *parent);
+
+	void closeEvent(QCloseEvent *event) override;
+
+public slots:
+	void StreamingTimerButton();
+	void RecordingTimerButton();
+	void StreamTimerStart();
+	void RecordTimerStart();
+	void StreamTimerStop();
+	void RecordTimerStop();
+	void UpdateStreamTimerDisplay();
+	void UpdateRecordTimerDisplay();
+	void ShowHideDialog();
+	void EventStopStreaming();
+	void EventStopRecording();
+
+private:
+	bool streamingAlreadyActive = false;
+	bool recordingAlreadyActive = false;
+
+	QTimer *streamingTimer;
+	QTimer *recordingTimer;
+	QTimer *streamingTimerDisplay;
+	QTimer *recordingTimerDisplay;
+};
diff --git a/UI/frontend-plugins/frontend-tools/tool-helpers.hpp b/UI/frontend-plugins/frontend-tools/tool-helpers.hpp
new file mode 100644
index 0000000..840e746
--- /dev/null
+++ b/UI/frontend-plugins/frontend-tools/tool-helpers.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <obs.hpp>
+#include <string>
+#include <QString>
+
+static inline OBSWeakSource GetWeakSourceByName(const char *name)
+{
+	OBSWeakSource weak;
+	obs_source_t *source = obs_get_source_by_name(name);
+	if (source) {
+		weak = obs_source_get_weak_source(source);
+		obs_weak_source_release(weak);
+		obs_source_release(source);
+	}
+
+	return weak;
+}
+
+static inline OBSWeakSource GetWeakSourceByQString(const QString &name)
+{
+	return GetWeakSourceByName(name.toUtf8().constData());
+}
+
+static inline std::string GetWeakSourceName(obs_weak_source_t *weak_source)
+{
+	std::string name;
+
+	obs_source_t *source = obs_weak_source_get_source(weak_source);
+	if (source) {
+		name = obs_source_get_name(source);
+		obs_source_release(source);
+	}
+
+	return name;
+}
diff --git a/UI/installer/mp-installer.nsi b/UI/installer/mp-installer.nsi
index 28c2229..23480b1 100644
--- a/UI/installer/mp-installer.nsi
+++ b/UI/installer/mp-installer.nsi
@@ -1,10 +1,18 @@
 ; Script generated with the Venis Install Wizard
 
+Unicode true
+
 ; Define your application name
 !define APPNAME "OBS Studio"
-!define APPVERSION "0.13.4"
-!define APPNAMEANDVERSION "OBS Studio ${APPVERSION}"
-; !define BROWSER
+
+!ifndef APPVERSION
+!define APPVERSION "17.0.2"
+!define SHORTVERSION "17.0.2"
+!endif
+
+!define APPNAMEANDVERSION "OBS Studio ${SHORTVERSION}"
+; !define FULL
+!define REALSENSE_PLUGIN
 
 ; Additional script dependencies
 !include WinVer.nsh
@@ -14,10 +22,10 @@
 Name "${APPNAMEANDVERSION}"
 InstallDir "$PROGRAMFILES32\obs-studio"
 InstallDirRegKey HKLM "Software\${APPNAME}" ""
-!ifdef BROWSER
-OutFile "OBS-Studio-${APPVERSION}-With-Browser-Installer.exe"
+!ifdef FULL
+OutFile "OBS-Studio-${SHORTVERSION}-Full-Installer.exe"
 !else
-OutFile "OBS-Studio-${APPVERSION}-Installer.exe"
+OutFile "OBS-Studio-${SHORTVERSION}-Small-Installer.exe"
 !endif
 
 ; Use compression
@@ -30,13 +38,18 @@ RequestExecutionLevel admin
 !include "MUI.nsh"
 
 !define MUI_ABORTWARNING
-!define MUI_FINISHPAGE_RUN "$INSTDIR\bin\32bit\obs32.exe"
+!define MUI_FINISHPAGE_RUN
+!define MUI_FINISHPAGE_RUN_TEXT "Launch OBS Studio ${SHORTVERSION}"
+!define MUI_FINISHPAGE_RUN_FUNCTION "LaunchOBS"
 
 !define MUI_PAGE_CUSTOMFUNCTION_LEAVE PreReqCheck
 
 !insertmacro MUI_PAGE_WELCOME
-!insertmacro MUI_PAGE_LICENSE "data\obs-studio\license\gplv2.txt"
+!insertmacro MUI_PAGE_LICENSE "new\core\data\obs-studio\license\gplv2.txt"
 !insertmacro MUI_PAGE_DIRECTORY
+!ifdef FULL
+	!insertmacro MUI_PAGE_COMPONENTS
+!endif
 !insertmacro MUI_PAGE_INSTFILES
 !insertmacro MUI_PAGE_FINISH
 
@@ -156,51 +169,68 @@ Function PreReqCheck
 	ClearErrors
 
 	; Check previous instance
-	FindProcDLL::FindProc "obs32.exe"
+
+	OBSInstallerUtils::IsProcessRunning "obs32.exe"
 	IntCmp $R0 1 0 notRunning1
 		MessageBox MB_OK|MB_ICONEXCLAMATION "${APPNAME} is already running. Please close it first before installing a new version." /SD IDOK
 		Quit
 	notRunning1:
+
 	${if} ${RunningX64}
-		FindProcDLL::FindProc "obs64.exe"
+		OBSInstallerUtils::IsProcessRunning "obs64.exe"
 		IntCmp $R0 1 0 notRunning2
 			MessageBox MB_OK|MB_ICONEXCLAMATION "${APPNAME} is already running. Please close it first before installing a new version." /SD IDOK
 			Quit
+		notRunning2:
 	${endif}
-	notRunning2:
 
+	OBSInstallerUtils::AddInUseFileCheck "$INSTDIR\data\obs-plugins\win-capture\graphics-hook32.dll"
+	OBSInstallerUtils::AddInUseFileCheck "$INSTDIR\data\obs-plugins\win-capture\graphics-hook64.dll"
+	OBSInstallerUtils::GetAppNameForInUseFiles
+	StrCmp $R0 "" gameCaptureNotRunning
+		MessageBox MB_OK|MB_ICONEXCLAMATION "Game Capture is still in use by the following applications:$\r$\n$\r$\n$R0$\r$\nPlease close these applications before installing a new version of OBS." /SD IDOK
+		Quit
+	gameCaptureNotRunning:
 FunctionEnd
 
 Function filesInUse
 	MessageBox MB_OK|MB_ICONEXCLAMATION "Some files were not able to be installed. If this is the first time you are installing OBS, please disable any anti-virus or other security software and try again. If you are re-installing or updating OBS, close any applications that may be have been hooked, or reboot and try again."  /SD IDOK
 FunctionEnd
 
+Function LaunchOBS
+	${if} ${RunningX64}
+		Exec '"$WINDIR\explorer.exe" "$SMPROGRAMS\OBS Studio\OBS Studio (64bit).lnk"'
+	${else}
+		Exec '"$WINDIR\explorer.exe" "$SMPROGRAMS\OBS Studio\OBS Studio (32bit).lnk"'
+	${endif}
+FunctionEnd
+
 Var outputErrors
 
-Section "OBS Studio" Section1
+Section "OBS Studio" SecCore
 
 	; Set Section properties
+	SectionIn RO
 	SetOverwrite on
 	AllowSkipFiles off
 
-	FindProcDLL::KillProc "obs-plugins\32bit\cef-bootstrap.exe"
-	FindProcDLL::KillProc "obs-plugins\64bit\cef-bootstrap.exe"
-
 	SetShellVarContext all
 
 	; Set Section Files and Shortcuts
 	SetOutPath "$INSTDIR"
-	File /r "data"
+	OBSInstallerUtils::KillProcess "obs-plugins\32bit\cef-bootstrap.exe"
+	OBSInstallerUtils::KillProcess "obs-plugins\64bit\cef-bootstrap.exe"
+	File /r "new\core\data"
 	SetOutPath "$INSTDIR\bin"
-	File /r "bin\32bit"
+	File /r "new\core\bin\32bit"
 	SetOutPath "$INSTDIR\obs-plugins"
-	File /r "obs-plugins\32bit"
+	File /r "new\core\obs-plugins\32bit"
 
 	${if} ${RunningX64}
 		SetOutPath "$INSTDIR\bin"
-		File /r "bin\64bit"
+		File /r "new\core\bin\64bit"
 		SetOutPath "$INSTDIR\obs-plugins"
-		File /r "obs-plugins\64bit"
+		File /r "new\core\obs-plugins\64bit"
 	${endif}
 
 	ClearErrors
@@ -218,8 +248,14 @@ Section "OBS Studio" Section1
 		Delete "$SMPROGRAMS\OBS Multiplatform\OBS Multiplatform (64bit).lnk"
 	${endif}
 
+	${if} ${RunningX64}
+		SetOutPath "$INSTDIR\bin\64bit"
+		CreateShortCut "$DESKTOP\OBS Studio.lnk" "$INSTDIR\bin\64bit\obs64.exe"
+	${else}
+		SetOutPath "$INSTDIR\bin\32bit"
+		CreateShortCut "$DESKTOP\OBS Studio.lnk" "$INSTDIR\bin\32bit\obs32.exe"
+	${endif}
 	SetOutPath "$INSTDIR\bin\32bit"
-	CreateShortCut "$DESKTOP\OBS Studio.lnk" "$INSTDIR\bin\32bit\obs32.exe"
 	CreateDirectory "$SMPROGRAMS\OBS Studio"
 	CreateShortCut "$SMPROGRAMS\OBS Studio\OBS Studio (32bit).lnk" "$INSTDIR\bin\32bit\obs32.exe"
 	CreateShortCut "$SMPROGRAMS\OBS Studio\Uninstall.lnk" "$INSTDIR\uninstall.exe"
@@ -235,6 +271,64 @@ Section "OBS Studio" Section1
 		Call filesInUse
 SectionEnd
 
+!ifdef FULL
+SectionGroup /e "Plugins" SecPlugins
+	Section "Browser plugin" SecPlugins_Browser
+		; Set Section properties
+		SetOverwrite on
+		AllowSkipFiles off
+		SetShellVarContext all
+
+		SetOutPath "$INSTDIR\obs-plugins"
+		OBSInstallerUtils::KillProcess "32bit\cef-bootstrap.exe"
+		File /r "new\obs-browser\obs-plugins\32bit"
+
+		${if} ${RunningX64}
+			OBSInstallerUtils::KillProcess "64bit\cef-bootstrap.exe"
+			File /r "new\obs-browser\obs-plugins\64bit"
+		${endif}
+
+		SetOutPath "$INSTDIR\bin\32bit"
+	SectionEnd
+
+	!ifdef REALSENSE_PLUGIN
+	Section /o "Realsense plugin" SecPlugins_Realsense
+		SetOverwrite on
+		AllowSkipFiles off
+		SetShellVarContext all
+
+		SetOutPath "$INSTDIR\obs-plugins"
+		File /r "new\realsense\32bit"
+
+		${if} ${RunningX64}
+			File /r "new\realsense\64bit"
+		${endif}
+
+		SetOutPath "$INSTDIR\data\obs-plugins"
+		File /r "new\realsense\data\obs-plugins\win-ivcam"
+
+		ExecWait '"$INSTDIR\data\obs-plugins\win-ivcam\seg_service.exe" /UnregServer'
+		ExecWait '"$INSTDIR\data\obs-plugins\win-ivcam\seg_service.exe" /RegServer'
+
+		ReadRegStr $0 HKLM "Software\Intel\RSSDK\Dispatch" "Core"
+		${if} ${Errors}
+			ReadRegStr $0 HKLM "Software\Intel\RSSDK\v10\Dispatch" "Core"
+		${endif}
+
+		${if} ${Errors}
+			InitPluginsDir
+			SetOutPath "$PLUGINSDIR\realsense"
+
+			File "intel_rs_sdk_runtime_websetup_10.0.26.0396.exe"
+			ExecWait '"$PLUGINSDIR\realsense\intel_rs_sdk_runtime_websetup_10.0.26.0396.exe" --finstall=personify --fnone=all'
+		${endif}
+
+		SetOutPath "$INSTDIR\bin\32bit"
+	SectionEnd
+	!endif
+SectionGroupEnd
+!endif
+
 Section -FinishSection
 
 	WriteRegStr HKLM "Software\${APPNAME}" "" "$INSTDIR"
@@ -250,11 +344,18 @@ SectionEnd
 
 ; Modern install component descriptions
 !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
-	!insertmacro MUI_DESCRIPTION_TEXT ${Section1} ""
+	!insertmacro MUI_DESCRIPTION_TEXT ${SecCore} "Core OBS Studio files"
+	!ifdef FULL
+		!insertmacro MUI_DESCRIPTION_TEXT ${SecPlugins} "Optional Plugins"
+		!insertmacro MUI_DESCRIPTION_TEXT ${SecPlugins_Browser} "Browser plugin (a source you can add to your scenes that displays web pages)"
+		!ifdef REALSENSE_PLUGIN
+			!insertmacro MUI_DESCRIPTION_TEXT ${SecPlugins_Realsense} "Plugin for Realsense cameras"
+		!endif
+	!endif
 !insertmacro MUI_FUNCTION_DESCRIPTION_END
 
 ;Uninstall section
-Section "un.obs-studio Program Files"
+Section "un.obs-studio Program Files" UninstallSection1
 
 	SectionIn RO
 
@@ -273,6 +374,11 @@ Section "un.obs-studio Program Files"
 		Delete "$SMPROGRAMS\OBS Studio\OBS Studio (64bit).lnk"
 	${endif}
 
+	IfFileExists "$INSTDIR\data\obs-plugins\win-ivcam\seg_service.exe" UnregisterSegService SkipUnreg
+	UnregisterSegService:
+	ExecWait '"$INSTDIR\data\obs-plugins\win-ivcam\seg_service.exe" /UnregServer'
+	SkipUnreg:
+
 	; Clean up OBS Studio
 	RMDir /r "$INSTDIR\bin"
 	RMDir /r "$INSTDIR\data"
@@ -284,17 +390,17 @@ Section "un.obs-studio Program Files"
 	RMDir "$INSTDIR\OBS Studio"
 SectionEnd
 
-Section /o "un.User Settings" Section2
+Section /o "un.User Settings" UninstallSection2
 	RMDir /R "$APPDATA\obs-studio"
 SectionEnd
 
 !insertmacro MUI_UNFUNCTION_DESCRIPTION_BEGIN
-	!insertmacro MUI_DESCRIPTION_TEXT ${Section1} "Remove the OBS program files."
-	!insertmacro MUI_DESCRIPTION_TEXT ${Section2} "Removes all settings, plugins, scenes and sources, profiles, log files and other application data."
+	!insertmacro MUI_DESCRIPTION_TEXT ${UninstallSection1} "Remove the OBS program files."
+	!insertmacro MUI_DESCRIPTION_TEXT ${UninstallSection2} "Removes all settings, plugins, scenes and sources, profiles, log files and other application data."
 !insertmacro MUI_UNFUNCTION_DESCRIPTION_END
 
 ; Version information
-VIProductVersion "0.${APPVERSION}"
+VIProductVersion "${APPVERSION}.0"
 VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "OBS Studio"
 VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "obsproject.com"
 VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "(c) 2012-2016"
diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp
index e7bb8f6..d233d77 100644
--- a/UI/obs-app.cpp
+++ b/UI/obs-app.cpp
@@ -20,6 +20,7 @@
 #include <wchar.h>
 #include <chrono>
 #include <ratio>
+#include <string>
 #include <sstream>
 #include <mutex>
 #include <util/bmem.h>
@@ -29,7 +30,9 @@
 #include <obs-config.h>
 #include <obs.hpp>
 
+#include <QGuiApplication>
 #include <QProxyStyle>
+#include <QScreen>
 
 #include "qt-wrappers.hpp"
 #include "obs-app.hpp"
@@ -49,6 +52,8 @@
 #include <signal.h>
 #endif
 
+#include <iostream>
+
 using namespace std;
 
 static log_handler_t def_log_handler;
@@ -57,12 +62,22 @@ static string currentLogFile;
 static string lastLogFile;
 
 static bool portable_mode = false;
+static bool log_verbose = false;
+static bool unfiltered_log = false;
 bool opt_start_streaming = false;
 bool opt_start_recording = false;
+bool opt_studio_mode = false;
+bool opt_start_replaybuffer = false;
+bool opt_minimize_tray = false;
 string opt_starting_collection;
 string opt_starting_profile;
 string opt_starting_scene;
 
+// AMD PowerXpress High Performance Flags
+#ifdef _MSC_VER
+extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
+#endif
+
 QObject *CreateShortcutFilter()
 {
 	return new OBSEventFilter([](QObject *obj, QEvent *event)
@@ -268,6 +283,10 @@ static inline bool too_many_repeated_entries(fstream &logFile, const char *msg,
 
 	lock_guard<mutex> guard(log_mutex);
 
+	if (unfiltered_log) {
+		return false;
+	}
+
 	if (last_msg_ptr == msg) {
 		int diff = std::abs(new_sum - last_char_sum);
 		if (diff < MAX_CHAR_VARIATION) {
@@ -303,8 +322,22 @@ static void do_log(int log_level, const char *msg, va_list args, void *param)
 	vsnprintf(str, 4095, msg, args);
 
 #ifdef _WIN32
-	OutputDebugStringA(str);
-	OutputDebugStringA("\n");
+	if (IsDebuggerPresent()) {
+		int wNum = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
+		if (wNum > 1) {
+			static wstring wide_buf;
+			static mutex wide_mutex;
+
+			lock_guard<mutex> lock(wide_mutex);
+			wide_buf.reserve(wNum + 1);
+			wide_buf.resize(wNum - 1);
+			MultiByteToWideChar(CP_UTF8, 0, str, -1, &wide_buf[0],
+					wNum);
+			wide_buf.push_back('\n');
+
+			OutputDebugStringW(wide_buf.c_str());
+		}
+	}
 #else
 	def_log_handler(log_level, msg, args2, nullptr);
 #endif
@@ -312,7 +345,7 @@ static void do_log(int log_level, const char *msg, va_list args, void *param)
 	if (too_many_repeated_entries(logFile, msg, str))
 		return;
 
-	if (log_level <= LOG_INFO)
+	if (log_level <= LOG_INFO || log_verbose)
 		LogStringChunk(logFile, str);
 
 #if defined(_WIN32) && defined(OBS_DEBUGBREAK_ON_ERROR)
@@ -330,6 +363,8 @@ bool OBSApp::InitGlobalConfigDefaults()
 	config_set_default_uint(globalConfig, "General", "MaxLogs", 10);
 	config_set_default_string(globalConfig, "General", "ProcessPriority",
 			"Normal");
+	config_set_default_bool(globalConfig, "General", "EnableAutoUpdates",
+			true);
 
 #if _WIN32
 	config_set_default_string(globalConfig, "Video", "Renderer",
@@ -365,6 +400,8 @@ bool OBSApp::InitGlobalConfigDefaults()
 	config_set_default_bool(globalConfig, "BasicWindow",
 			"SysTrayWhenStarted", false);
 	config_set_default_bool(globalConfig, "BasicWindow",
+			"SaveProjectors", false);
+	config_set_default_bool(globalConfig, "BasicWindow",
 			"ShowTransitions", true);
 	config_set_default_bool(globalConfig, "BasicWindow",
 			"ShowListboxToolbars", true);
@@ -413,7 +450,13 @@ static bool MakeUserDirs()
 		return false;
 	if (!do_mkdir(path))
 		return false;
+
+	if (GetConfigPath(path, sizeof(path), "obs-studio/updates") <= 0)
+		return false;
+	if (!do_mkdir(path))
+		return false;
 #endif
+
 	if (GetConfigPath(path, sizeof(path), "obs-studio/plugin_config") <= 0)
 		return false;
 	if (!do_mkdir(path))
@@ -448,7 +491,7 @@ static string GetProfileDirFromName(const char *name)
 	if (GetConfigPath(path, sizeof(path), "obs-studio/basic/profiles") <= 0)
 		return outputPath;
 
-	strcat(path, "/*.*");
+	strcat(path, "/*");
 
 	if (os_glob(path, 0, &glob) != 0)
 		return outputPath;
@@ -855,6 +898,9 @@ bool OBSApp::OBSInit()
 		if (!StartupOBS(locale.c_str(), GetProfilerNameStore()))
 			return false;
 
+		blog(LOG_INFO, "Portable mode: %s",
+				portable_mode ? "true" : "false");
+
 		mainWindow = new OBSBasic();
 
 		mainWindow->setAttribute(Qt::WA_DeleteOnClose, true);
@@ -906,6 +952,11 @@ string OBSApp::GetVersionString() const
 	return ver.str();
 }
 
+bool OBSApp::IsPortableMode()
+{
+	return portable_mode;
+}
+
 #ifdef __APPLE__
 #define INPUT_AUDIO_SOURCE  "coreaudio_input_capture"
 #define OUTPUT_AUDIO_SOURCE "coreaudio_output_capture"
@@ -1094,79 +1145,9 @@ string GenerateTimeDateFilename(const char *extension, bool noSpace)
 string GenerateSpecifiedFilename(const char *extension, bool noSpace,
 		const char *format)
 {
-	time_t now = time(0);
-	struct tm *cur_time;
-	cur_time = localtime(&now);
-
-	const size_t spec_count = 23;
-	const char *spec[][2] = {
-		{"%CCYY", "%Y"},
-		{"%YY",   "%y"},
-		{"%MM",   "%m"},
-		{"%DD",   "%d"},
-		{"%hh",   "%H"},
-		{"%mm",   "%M"},
-		{"%ss",   "%S"},
-		{"%%",    "%%"},
-
-		{"%a",    ""},
-		{"%A",    ""},
-		{"%b",    ""},
-		{"%B",    ""},
-		{"%d",    ""},
-		{"%H",    ""},
-		{"%I",    ""},
-		{"%m",    ""},
-		{"%M",    ""},
-		{"%p",    ""},
-		{"%S",    ""},
-		{"%y",    ""},
-		{"%Y",    ""},
-		{"%z",    ""},
-		{"%Z",    ""},
-	};
-
-	char convert[128] = {};
-	string sf = format;
-	string c;
-	size_t pos = 0, len;
-
-	while (pos < sf.length()) {
-		len = 0;
-		for (size_t i = 0; i < spec_count && len == 0; i++) {
-
-			if (sf.find(spec[i][0], pos) == pos) {
-				if (strlen(spec[i][1]))
-					strftime(convert, sizeof(convert),
-							spec[i][1], cur_time);
-				else
-					strftime(convert, sizeof(convert),
-							spec[i][0], cur_time);
-
-				len = strlen(spec[i][0]);
-
-				c = convert;
-				if (c.length() && c.find_first_not_of(' ') !=
-						std::string::npos)
-					sf.replace(pos, len, convert);
-			}
-		}
-
-		if (len)
-			pos += strlen(convert);
-		else if (!len && sf.at(pos) == '%')
-			sf.erase(pos,1);
-		else
-			pos++;
-	}
-
-	if (noSpace)
-		replace(sf.begin(), sf.end(), ' ', '_');
-
-	sf += '.';
-	sf += extension;
-
-	return (sf.length() < 256) ? sf : sf.substr(0, 255);
+	BPtr<char> filename = os_generate_formatted_filename(extension,
+			!noSpace, format);
+	return string(filename);
 }
 
 vector<pair<string, string>> GetLocaleNames()
@@ -1291,20 +1272,6 @@ static int run_program(fstream &logFile, int argc, char *argv[])
 	profiler_start();
 	profile_register_root(run_program_init, 0);
 
-	auto PrintInitProfile = [&]()
-	{
-		auto snap = GetSnapshot();
-
-		profiler_snapshot_filter_roots(snap.get(), [](void *data,
-					const char *name, bool *remove)
-		{
-			*remove = (*static_cast<const char**>(data)) != name;
-			return true;
-		}, static_cast<void*>(&run_program_init));
-
-		profiler_print(snap.get());
-	};
-
 	ScopeProfiler prof{run_program_init};
 
 	QCoreApplication::addLibraryPath(".");
@@ -1520,20 +1487,10 @@ bool GetClosestUnusedFileName(std::string &path, const char *extension)
 
 bool WindowPositionValid(QRect rect)
 {
-	vector<MonitorInfo> monitors;
-	GetMonitors(monitors);
-
-	for (auto &monitor : monitors) {
-		int left   = int(monitor.x);
-		int top    = int(monitor.y);
-		int right  = left + int(monitor.cx);
-		int bottom = top  + int(monitor.cy);
-
-		if ((rect.left() - right)  < 0 && (left - rect.right())  < 0 &&
-		    (rect.top()  - bottom) < 0 && (top  - rect.bottom()) < 0)
+	for (QScreen* screen: QGuiApplication::screens()) {
+		if (screen->availableGeometry().intersects(rect))
 			return true;
 	}
-
 	return false;
 }
 
@@ -1796,12 +1753,21 @@ int main(int argc, char *argv[])
 		if (arg_is(argv[i], "--portable", "-p")) {
 			portable_mode = true;
 
+		} else if (arg_is(argv[i], "--verbose", nullptr)) {
+			log_verbose = true;
+
+		} else if (arg_is(argv[i], "--unfiltered_log", nullptr)) {
+			unfiltered_log = true;
+
 		} else if (arg_is(argv[i], "--startstreaming", nullptr)) {
 			opt_start_streaming = true;
 
 		} else if (arg_is(argv[i], "--startrecording", nullptr)) {
 			opt_start_recording = true;
 
+		} else if (arg_is(argv[i], "--startreplaybuffer", nullptr)) {
+			opt_start_replaybuffer = true;
+
 		} else if (arg_is(argv[i], "--collection", nullptr)) {
 			if (++i < argc) opt_starting_collection = argv[i];
 
@@ -1810,6 +1776,36 @@ int main(int argc, char *argv[])
 
 		} else if (arg_is(argv[i], "--scene", nullptr)) {
 			if (++i < argc) opt_starting_scene = argv[i];
+
+		} else if (arg_is(argv[i], "--minimize-to-tray", nullptr)) {
+			opt_minimize_tray = true;
+
+		} else if (arg_is(argv[i], "--studio-mode", nullptr)) {
+			opt_studio_mode = true;
+
+		} else if (arg_is(argv[i], "--help", "-h")) {
+			std::cout <<
+			"--help, -h: Get list of available commands.\n\n" << 
+			"--startstreaming: Automatically start streaming.\n" <<
+			"--startrecording: Automatically start recording.\n" <<
+			"--startreplaybuffer: Start replay buffer.\n\n" <<
+			"--collection <string>: Use specific scene collection."
+				<< "\n" <<
+			"--profile <string>: Use specific profile.\n" <<
+			"--scene <string>: Start with specific scene.\n\n" <<
+			"--studio-mode: Enable studio mode.\n" <<
+			"--minimize-to-tray: Minimize to system tray.\n" <<
+			"--portable, -p: Use portable mode.\n\n" <<
+			"--verbose: Make log more verbose.\n" <<
+			"--unfiltered_log: Make log unfiltered.\n\n" <<
+			"--version, -V: Get current version.\n";
+
+			exit(0);
+
+		} else if (arg_is(argv[i], "--version", "-V")) {
+			std::cout << "OBS Studio - " << 
+				App()->GetVersionString() << "\n";
+			exit(0);
 		}
 	}
 
diff --git a/UI/obs-app.hpp b/UI/obs-app.hpp
index 9c45803..381f9d6 100644
--- a/UI/obs-app.hpp
+++ b/UI/obs-app.hpp
@@ -117,6 +117,7 @@ public:
 	const char *GetCurrentLog() const;
 
 	std::string GetVersionString() const;
+	bool IsPortableMode();
 
 	const char *InputAudioSource() const;
 	const char *OutputAudioSource() const;
@@ -177,4 +178,7 @@ static inline int GetProfilePath(char *path, size_t size, const char *file)
 
 extern bool opt_start_streaming;
 extern bool opt_start_recording;
+extern bool opt_start_replaybuffer;
+extern bool opt_minimize_tray;
+extern bool opt_studio_mode;
 extern std::string opt_starting_scene;
diff --git a/UI/obs-frontend-api/CMakeLists.txt b/UI/obs-frontend-api/CMakeLists.txt
index 38eefb6..1d5ca9a 100644
--- a/UI/obs-frontend-api/CMakeLists.txt
+++ b/UI/obs-frontend-api/CMakeLists.txt
@@ -17,4 +17,13 @@ add_library(obs-frontend-api SHARED
 target_link_libraries(obs-frontend-api
 	libobs)
 
+if(UNIX AND NOT APPLE)
+	set_target_properties(obs-frontend-api
+		PROPERTIES
+			OUTPUT_NAME obs-frontend-api
+			VERSION 0.0
+			SOVERSION 0
+			)
+endif()
+
 install_obs_core(obs-frontend-api)
diff --git a/UI/obs-frontend-api/obs-frontend-api.cpp b/UI/obs-frontend-api/obs-frontend-api.cpp
index 5d01b64..6951bc9 100644
--- a/UI/obs-frontend-api/obs-frontend-api.cpp
+++ b/UI/obs-frontend-api/obs-frontend-api.cpp
@@ -205,6 +205,23 @@ bool obs_frontend_recording_active(void)
 		: false;
 }
 
+void obs_frontend_replay_buffer_start(void)
+{
+	if (callbacks_valid()) c->obs_frontend_replay_buffer_start();
+}
+
+void obs_frontend_replay_buffer_stop(void)
+{
+	if (callbacks_valid()) c->obs_frontend_replay_buffer_stop();
+}
+
+bool obs_frontend_replay_buffer_active(void)
+{
+	return !!callbacks_valid()
+		? c->obs_frontend_replay_buffer_active()
+		: false;
+}
+
 void *obs_frontend_add_tools_menu_qaction(const char *name)
 {
 	return !!callbacks_valid()
@@ -248,6 +265,13 @@ obs_output_t *obs_frontend_get_recording_output(void)
 		: nullptr;
 }
 
+obs_output_t *obs_frontend_get_replay_buffer_output(void)
+{
+	return !!callbacks_valid()
+		? c->obs_frontend_get_replay_buffer_output()
+		: nullptr;
+}
+
 config_t *obs_frontend_get_profile_config(void)
 {
 	return !!callbacks_valid()
diff --git a/UI/obs-frontend-api/obs-frontend-api.h b/UI/obs-frontend-api/obs-frontend-api.h
index 8a6272a..7be113c 100644
--- a/UI/obs-frontend-api/obs-frontend-api.h
+++ b/UI/obs-frontend-api/obs-frontend-api.h
@@ -70,6 +70,10 @@ EXPORT void obs_frontend_recording_start(void);
 EXPORT void obs_frontend_recording_stop(void);
 EXPORT bool obs_frontend_recording_active(void);
 
+EXPORT void obs_frontend_replay_buffer_start(void);
+EXPORT void obs_frontend_replay_buffer_stop(void);
+EXPORT bool obs_frontend_replay_buffer_active(void);
+
 typedef void (*obs_frontend_cb)(void *private_data);
 
 EXPORT void *obs_frontend_add_tools_menu_qaction(const char *name);
@@ -94,7 +98,12 @@ enum obs_frontend_event {
 	OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED,
 	OBS_FRONTEND_EVENT_PROFILE_CHANGED,
 	OBS_FRONTEND_EVENT_PROFILE_LIST_CHANGED,
-	OBS_FRONTEND_EVENT_EXIT
+	OBS_FRONTEND_EVENT_EXIT,
+
+	OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTING,
+	OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTED,
+	OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPING,
+	OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPED
 };
 
 typedef void (*obs_frontend_event_cb)(enum obs_frontend_event event,
@@ -116,6 +125,7 @@ EXPORT void obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
 
 EXPORT obs_output_t *obs_frontend_get_streaming_output(void);
 EXPORT obs_output_t *obs_frontend_get_recording_output(void);
+EXPORT obs_output_t *obs_frontend_get_replay_buffer_output(void);
 
 EXPORT config_t *obs_frontend_get_profile_config(void);
 EXPORT config_t *obs_frontend_get_global_config(void);
diff --git a/UI/obs-frontend-api/obs-frontend-internal.hpp b/UI/obs-frontend-api/obs-frontend-internal.hpp
index cb8da96..5784eeb 100644
--- a/UI/obs-frontend-api/obs-frontend-internal.hpp
+++ b/UI/obs-frontend-api/obs-frontend-internal.hpp
@@ -6,6 +6,7 @@
 #include <string>
 
 struct obs_frontend_callbacks {
+	virtual ~obs_frontend_callbacks() {}
 	virtual void *obs_frontend_get_main_window(void)=0;
 	virtual void *obs_frontend_get_main_window_handle(void)=0;
 
@@ -39,6 +40,10 @@ struct obs_frontend_callbacks {
 	virtual void obs_frontend_recording_stop(void)=0;
 	virtual bool obs_frontend_recording_active(void)=0;
 
+	virtual void obs_frontend_replay_buffer_start(void)=0;
+	virtual void obs_frontend_replay_buffer_stop(void)=0;
+	virtual bool obs_frontend_replay_buffer_active(void)=0;
+
 	virtual void *obs_frontend_add_tools_menu_qaction(const char *name)=0;
 	virtual void obs_frontend_add_tools_menu_item(const char *name,
 			obs_frontend_cb callback, void *private_data)=0;
@@ -50,6 +55,7 @@ struct obs_frontend_callbacks {
 
 	virtual obs_output_t *obs_frontend_get_streaming_output(void)=0;
 	virtual obs_output_t *obs_frontend_get_recording_output(void)=0;
+	virtual obs_output_t *obs_frontend_get_replay_buffer_output(void)=0;
 
 	virtual config_t *obs_frontend_get_profile_config(void)=0;
 	virtual config_t *obs_frontend_get_global_config(void)=0;
diff --git a/UI/platform-osx.mm b/UI/platform-osx.mm
index d60f8ab..19b1a9c 100644
--- a/UI/platform-osx.mm
+++ b/UI/platform-osx.mm
@@ -36,17 +36,6 @@ bool GetDataFilePath(const char *data, string &output)
 	return !access(output.c_str(), R_OK);
 }
 
-void GetMonitors(vector<MonitorInfo> &monitors)
-{
-	monitors.clear();
-	for(NSScreen *screen : [NSScreen screens])
-	{
-		NSRect frame = [screen convertRectToBacking:[screen frame]];
-		monitors.emplace_back(frame.origin.x, frame.origin.y,
-				      frame.size.width, frame.size.height);
-	}
-}
-
 bool InitApplicationBundle()
 {
 #ifdef OBS_OSX_BUNDLE
diff --git a/UI/platform-windows.cpp b/UI/platform-windows.cpp
index 8edde6e..7386375 100644
--- a/UI/platform-windows.cpp
+++ b/UI/platform-windows.cpp
@@ -51,28 +51,6 @@ bool GetDataFilePath(const char *data, string &output)
 	return check_path(data, OBS_DATA_PATH "/obs-studio/", output);
 }
 
-static BOOL CALLBACK OBSMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor,
-		LPRECT rect, LPARAM param)
-{
-	vector<MonitorInfo> &monitors = *(vector<MonitorInfo> *)param;
-
-	monitors.emplace_back(
-			rect->left,
-			rect->top,
-			rect->right - rect->left,
-			rect->bottom - rect->top);
-
-	UNUSED_PARAMETER(hMonitor);
-	UNUSED_PARAMETER(hdcMonitor);
-	return true;
-}
-
-void GetMonitors(vector<MonitorInfo> &monitors)
-{
-	monitors.clear();
-	EnumDisplayMonitors(NULL, NULL, OBSMonitorEnumProc, (LPARAM)&monitors);
-}
-
 bool InitApplicationBundle()
 {
 	return true;
diff --git a/UI/platform-x11.cpp b/UI/platform-x11.cpp
index 1cca5da..c6b02b9 100644
--- a/UI/platform-x11.cpp
+++ b/UI/platform-x11.cpp
@@ -16,16 +16,12 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
 
-/* Here we use xinerama to fetch data about monitor geometry
- * Even if there are not multiple monitors, this should still work.
- */
-
 #include <obs-config.h>
 #include "obs-app.hpp"
 
-#include <xcb/xcb.h>
-#include <xcb/xinerama.h> 
-#include <xcb/randr.h> 
+#include <QGuiApplication>
+#include <QScreen>
+
 #include <unistd.h>
 #include <sstream>
 #include <locale.h>
@@ -63,59 +59,6 @@ bool GetDataFilePath(const char *data, string &output)
 	return false;
 }
 
-void GetMonitors(vector<MonitorInfo> &monitors)
-{
-	xcb_connection_t* xcb_conn;
-
-	monitors.clear();
-	xcb_conn = xcb_connect(NULL, NULL);
-
-	bool use_xinerama = false;
-	if (xcb_get_extension_data(xcb_conn, &xcb_xinerama_id)->present) {
-		xcb_xinerama_is_active_cookie_t xinerama_cookie;
-		xcb_xinerama_is_active_reply_t* xinerama_reply = NULL;
-
-		xinerama_cookie = xcb_xinerama_is_active(xcb_conn);
-		xinerama_reply = xcb_xinerama_is_active_reply(xcb_conn,
-						        xinerama_cookie, NULL);
-
-		if (xinerama_reply && xinerama_reply->state != 0)
-			use_xinerama = true;
-		free(xinerama_reply);
-	}
-
-	if (use_xinerama) {
-		xcb_xinerama_query_screens_cookie_t screens_cookie;
-		xcb_xinerama_query_screens_reply_t* screens_reply = NULL;
-		xcb_xinerama_screen_info_iterator_t iter;
-
-		screens_cookie = xcb_xinerama_query_screens(xcb_conn);
-		screens_reply = xcb_xinerama_query_screens_reply(xcb_conn,
-							screens_cookie, NULL);
-		iter = xcb_xinerama_query_screens_screen_info_iterator(
-								screens_reply);
-
-		for(; iter.rem; xcb_xinerama_screen_info_next(&iter)) {
-			monitors.emplace_back(iter.data->x_org,
-					      iter.data->y_org,
-					      iter.data->width,
-					      iter.data->height);
-		}
-		free(screens_reply);
-	} else {
-		// no xinerama so fall back to basic x11 calls
-		xcb_screen_iterator_t iter;
-
-		iter = xcb_setup_roots_iterator(xcb_get_setup(xcb_conn));
-		for(; iter.rem; xcb_screen_next(&iter)) {
-			monitors.emplace_back(0,0,iter.data->width_in_pixels,
-					          iter.data->height_in_pixels);
-		}
-	}
-
-	xcb_disconnect(xcb_conn);
-}
-
 bool InitApplicationBundle()
 {
 	return true;
diff --git a/UI/platform.hpp b/UI/platform.hpp
index ad579d6..1b1344b 100644
--- a/UI/platform.hpp
+++ b/UI/platform.hpp
@@ -24,19 +24,8 @@
 
 class QWidget;
 
-struct MonitorInfo {
-	int32_t  x, y;
-	uint32_t cx, cy;
-
-	inline MonitorInfo() {}
-	inline MonitorInfo(int32_t x, int32_t y, uint32_t cx, uint32_t cy)
-		: x(x), y(y), cx(cx), cy(cy)
-	{}
-};
-
 /* Gets the path of obs-studio specific data files (such as locale) */
 bool GetDataFilePath(const char *data, std::string &path);
-void GetMonitors(std::vector<MonitorInfo> &monitors);
 
 /* Updates the working directory for OSX application bundles */
 bool InitApplicationBundle();
diff --git a/UI/remote-text.cpp b/UI/remote-text.cpp
index b77a802..e4b5c39 100644
--- a/UI/remote-text.cpp
+++ b/UI/remote-text.cpp
@@ -22,6 +22,9 @@
 
 using namespace std;
 
+static auto curl_deleter = [] (CURL *curl) {curl_easy_cleanup(curl);};
+using Curl = unique_ptr<CURL, decltype(curl_deleter)>;
+
 static size_t string_write(char *ptr, size_t size, size_t nmemb, string &str)
 {
 	size_t total = size * nmemb;
@@ -45,9 +48,6 @@ void RemoteTextThread::run()
 		contentTypeString += contentType;
 	}
 
-	auto curl_deleter = [] (CURL *curl) {curl_easy_cleanup(curl);};
-	using Curl = unique_ptr<CURL, decltype(curl_deleter)>;
-
 	Curl curl{curl_easy_init(), curl_deleter};
 	if (curl) {
 		struct curl_slist *header = nullptr;
@@ -91,3 +91,110 @@ void RemoteTextThread::run()
 		curl_slist_free_all(header);
 	}
 }
+
+static size_t header_write(char *ptr, size_t size, size_t nmemb,
+		vector<string> &list)
+{
+	string str;
+
+	size_t total = size * nmemb;
+	if (total)
+		str.append(ptr, total);
+
+	if (str.back() == '\n')
+		str.resize(str.size() - 1);
+	if (str.back() == '\r')
+		str.resize(str.size() - 1);
+
+	list.push_back(std::move(str));
+	return total;
+}
+
+bool GetRemoteFile(
+	const char *url,
+	std::string &str,
+	std::string &error,
+	long *responseCode,
+	const char *contentType,
+	const char *postData,
+	std::vector<std::string> extraHeaders,
+	std::string *signature)
+{
+	vector<string> header_in_list;
+	char error_in[CURL_ERROR_SIZE];
+	CURLcode code = CURLE_FAILED_INIT;
+
+	error_in[0] = 0;
+
+	string versionString("User-Agent: obs-basic ");
+	versionString += App()->GetVersionString();
+
+	string contentTypeString;
+	if (contentType) {
+		contentTypeString += "Content-Type: ";
+		contentTypeString += contentType;
+	}
+
+	Curl curl{curl_easy_init(), curl_deleter};
+	if (curl) {
+		struct curl_slist *header = nullptr;
+
+		header = curl_slist_append(header,
+				versionString.c_str());
+
+		if (!contentTypeString.empty()) {
+			header = curl_slist_append(header,
+					contentTypeString.c_str());
+		}
+
+		for (std::string &h : extraHeaders)
+			header = curl_slist_append(header, h.c_str());
+
+		curl_easy_setopt(curl.get(), CURLOPT_URL, url);
+		curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER,
+				header);
+		curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER,
+				error_in);
+		curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION,
+				string_write);
+		curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA,
+				&str);
+		if (signature) {
+			curl_easy_setopt(curl.get(), CURLOPT_HEADERFUNCTION,
+					header_write);
+			curl_easy_setopt(curl.get(), CURLOPT_HEADERDATA,
+					&header_in_list);
+		}
+
+#if LIBCURL_VERSION_NUM >= 0x072400
+		// A lot of servers don't yet support ALPN
+		curl_easy_setopt(curl.get(), CURLOPT_SSL_ENABLE_ALPN, 0);
+#endif
+
+		if (postData) {
+			curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS,
+					postData);
+		}
+
+		code = curl_easy_perform(curl.get());
+		if (responseCode)
+			curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE,
+					responseCode);
+
+		if (code != CURLE_OK) {
+			error = error_in;
+		} else if (signature) {
+			for (string &h : header_in_list) {
+				string name = h.substr(0, 13);
+				if (name == "X-Signature: ") {
+					*signature = h.substr(13);
+					break;
+				}
+			}
+		}
+
+		curl_slist_free_all(header);
+	}
+
+	return code == CURLE_OK;
+}
diff --git a/UI/remote-text.hpp b/UI/remote-text.hpp
index e0e2268..7758843 100644
--- a/UI/remote-text.hpp
+++ b/UI/remote-text.hpp
@@ -18,6 +18,7 @@
 #pragma once
 
 #include <QThread>
+#include <vector>
 #include <string>
 
 class RemoteTextThread : public QThread {
@@ -40,3 +41,13 @@ public:
 		: url(url_), contentType(contentType_), postData(postData_)
 	{}
 };
+
+bool GetRemoteFile(
+	const char *url,
+	std::string &str,
+	std::string &error,
+	long *responseCode = nullptr,
+	const char *contentType = nullptr,
+	const char *postData = nullptr,
+	std::vector<std::string> extraHeaders = std::vector<std::string>(),
+	std::string *signature = nullptr);
diff --git a/UI/volume-control.cpp b/UI/volume-control.cpp
index 02456a4..ba66209 100644
--- a/UI/volume-control.cpp
+++ b/UI/volume-control.cpp
@@ -1,8 +1,10 @@
 #include "volume-control.hpp"
 #include "qt-wrappers.hpp"
+#include "obs-app.hpp"
 #include "mute-checkbox.hpp"
 #include "slider-absoluteset-style.hpp"
 #include <util/platform.h>
+#include <util/threading.h>
 #include <QHBoxLayout>
 #include <QVBoxLayout>
 #include <QPushButton>
@@ -16,6 +18,8 @@
 
 using namespace std;
 
+QWeakPointer<VolumeMeterTimer> VolumeMeter::updateTimer;
+
 void VolControl::OBSVolumeChanged(void *data, float db)
 {
 	Q_UNUSED(db);
@@ -29,11 +33,10 @@ void VolControl::OBSVolumeLevel(void *data, float level, float mag,
 {
 	VolControl *volControl = static_cast<VolControl*>(data);
 
-	QMetaObject::invokeMethod(volControl, "VolumeLevel",
-		Q_ARG(float, mag),
-		Q_ARG(float, level),
-		Q_ARG(float, peak),
-		Q_ARG(bool,  muted));
+	if (muted)
+		level = mag = peak = 0.0f;
+
+	volControl->volMeter->setLevels(mag, level, peak);
 }
 
 void VolControl::OBSVolumeMuted(void *data, calldata_t *calldata)
@@ -84,8 +87,19 @@ void VolControl::SliderChanged(int vol)
 
 void VolControl::updateText()
 {
-	volLabel->setText(QString::number(obs_fader_get_db(obs_fader), 'f', 1)
-			.append(" dB"));
+	QString db = QString::number(obs_fader_get_db(obs_fader), 'f', 1)
+			.append(" dB");
+	volLabel->setText(db);
+
+	bool muted = obs_source_muted(source);
+	const char *accTextLookup = muted
+		? "VolControl.SliderMuted"
+		: "VolControl.SliderUnmuted";
+
+	QString sourceName = obs_source_get_name(source);
+	QString accText = QTStr(accTextLookup).arg(sourceName, db);
+
+	slider->setAccessibleName(accText);
 }
 
 QString VolControl::GetName() const
@@ -124,7 +138,9 @@ VolControl::VolControl(OBSSource source_, bool showConfig)
 	QFont font = nameLabel->font();
 	font.setPointSize(font.pointSize()-1);
 
-	nameLabel->setText(obs_source_get_name(source));
+	QString sourceName = obs_source_get_name(source);
+
+	nameLabel->setText(sourceName);
 	nameLabel->setFont(font);
 	volLabel->setFont(font);
 	slider->setMinimum(0);
@@ -138,7 +154,10 @@ VolControl::VolControl(OBSSource source_, bool showConfig)
 	textLayout->setAlignment(nameLabel, Qt::AlignLeft);
 	textLayout->setAlignment(volLabel,  Qt::AlignRight);
 
-	mute->setChecked(obs_source_muted(source));
+	bool muted = obs_source_muted(source);
+	mute->setChecked(muted);
+	mute->setAccessibleName(
+			QTStr("VolControl.Mute").arg(sourceName));
 
 	volLayout->addWidget(slider);
 	volLayout->addWidget(mute);
@@ -157,6 +176,9 @@ VolControl::VolControl(OBSSource source_, bool showConfig)
 		config->setMaximumSize(22, 22);
 		config->setAutoDefault(false);
 
+		config->setAccessibleName(QTStr("VolControl.Properties")
+				.arg(sourceName));
+
 		connect(config, &QAbstractButton::clicked,
 				this, &VolControl::EmitConfigClicked);
 
@@ -255,30 +277,51 @@ VolumeMeter::VolumeMeter(QWidget *parent)
 	peakColor.setRgb(0x3E, 0xF1, 0x2B);
 	peakHoldColor.setRgb(0x00, 0x00, 0x00);
 	
-	resetTimer = new QTimer(this);
-	connect(resetTimer, SIGNAL(timeout()), this, SLOT(resetState()));
+	updateTimerRef = updateTimer.toStrongRef();
+	if (!updateTimerRef) {
+		updateTimerRef = QSharedPointer<VolumeMeterTimer>::create();
+		updateTimerRef->start(34);
+		updateTimer = updateTimerRef;
+	}
 
-	resetState();
+	updateTimerRef->AddVolControl(this);
 }
 
-void VolumeMeter::resetState(void)
+VolumeMeter::~VolumeMeter()
 {
-	setLevels(0.0f, 0.0f, 0.0f);
-	if (resetTimer->isActive())
-		resetTimer->stop();
+	updateTimerRef->RemoveVolControl(this);
 }
 
 void VolumeMeter::setLevels(float nmag, float npeak, float npeakHold)
 {
-	mag      = nmag;
-	peak     = npeak;
-	peakHold = npeakHold;
+	uint64_t ts = os_gettime_ns();
+	QMutexLocker locker(&dataMutex);
+
+	mag += nmag;
+	peak += npeak;
+	peakHold += npeakHold;
+	multiple += 1.0f;
+	lastUpdateTime = ts;
+}
+
+inline void VolumeMeter::calcLevels()
+{
+	uint64_t ts = os_gettime_ns();
+	QMutexLocker locker(&dataMutex);
+
+	if (lastUpdateTime && ts - lastUpdateTime > 1000000000) {
+		mag = peak = peakHold = 0.0f;
+		multiple = 1.0f;
+		lastUpdateTime = 0;
+	}
 
-	update();
+	if (multiple > 0.0f) {
+		curMag = mag / multiple;
+		curPeak = peak / multiple;
+		curPeakHold = peakHold / multiple;
 
-	if (resetTimer->isActive())
-		resetTimer->stop();
-	resetTimer->start(1000);
+		mag = peak = peakHold = multiple = 0.0f;
+	}
 }
 
 void VolumeMeter::paintEvent(QPaintEvent *event)
@@ -291,9 +334,11 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
 	int width  = size().width();
 	int height = size().height();
 
-	int scaledMag      = int((float)width * mag);
-	int scaledPeak     = int((float)width * peak);
-	int scaledPeakHold = int((float)width * peakHold);
+	calcLevels();
+
+	int scaledMag      = int((float)width * curMag);
+	int scaledPeak     = int((float)width * curPeak);
+	int scaledPeakHold = int((float)width * curPeakHold);
 
 	gradient.setStart(qreal(scaledMag), 0);
 	gradient.setFinalStop(qreal(scaledPeak), 0);
@@ -324,3 +369,19 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
 		scaledPeakHold, height);
 
 }
+
+void VolumeMeterTimer::AddVolControl(VolumeMeter *meter)
+{
+	volumeMeters.push_back(meter);
+}
+
+void VolumeMeterTimer::RemoveVolControl(VolumeMeter *meter)
+{
+	volumeMeters.removeOne(meter);
+}
+
+void VolumeMeterTimer::timerEvent(QTimerEvent*)
+{
+	for (VolumeMeter *meter : volumeMeters)
+		meter->update();
+}
diff --git a/UI/volume-control.hpp b/UI/volume-control.hpp
index 27b52b2..9330af7 100644
--- a/UI/volume-control.hpp
+++ b/UI/volume-control.hpp
@@ -2,8 +2,13 @@
 
 #include <obs.hpp>
 #include <QWidget>
+#include <QSharedPointer>
+#include <QTimer>
+#include <QMutex>
+#include <QList>
 
 class QPushButton;
+class VolumeMeterTimer;
 
 class VolumeMeter : public QWidget
 {
@@ -14,12 +19,23 @@ class VolumeMeter : public QWidget
 	Q_PROPERTY(QColor peakHoldColor READ getPeakHoldColor WRITE setPeakHoldColor DESIGNABLE true)
 
 private:
-	float mag, peak, peakHold;
+	static QWeakPointer<VolumeMeterTimer> updateTimer;
+	QSharedPointer<VolumeMeterTimer> updateTimerRef;
+	float curMag = 0.0f, curPeak = 0.0f, curPeakHold = 0.0f;
+
+	inline void calcLevels();
+
+	QMutex dataMutex;
+	float mag = 0.0f, peak = 0.0f, peakHold = 0.0f;
+	float multiple = 0.0f;
+	uint64_t lastUpdateTime = 0;
+
 	QColor bkColor, magColor, peakColor, peakHoldColor;
-	QTimer *resetTimer;
 
 public:
 	explicit VolumeMeter(QWidget *parent = 0);
+	~VolumeMeter();
+
 	void setLevels(float nmag, float npeak, float npeakHold);
 	QColor getBkColor() const;
 	void setBkColor(QColor c);
@@ -32,8 +48,20 @@ public:
 
 protected:
 	void paintEvent(QPaintEvent *event);
-private slots:
-	void resetState();
+};
+
+class VolumeMeterTimer : public QTimer {
+	Q_OBJECT
+
+public:
+	inline VolumeMeterTimer() : QTimer() {}
+
+	void AddVolControl(VolumeMeter *meter);
+	void RemoveVolControl(VolumeMeter *meter);
+
+protected:
+	virtual void timerEvent(QTimerEvent *event) override;
+	QList<VolumeMeter*> volumeMeters;
 };
 
 class QLabel;
diff --git a/UI/win-update/update-window.cpp b/UI/win-update/update-window.cpp
new file mode 100644
index 0000000..9c2dcf7
--- /dev/null
+++ b/UI/win-update/update-window.cpp
@@ -0,0 +1,44 @@
+#include "update-window.hpp"
+#include "obs-app.hpp"
+
+OBSUpdate::OBSUpdate(QWidget *parent, bool manualUpdate, const QString &text)
+	: QDialog (parent, Qt::WindowSystemMenuHint |
+	                   Qt::WindowTitleHint |
+	                   Qt::WindowCloseButtonHint),
+	  ui      (new Ui_OBSUpdate)
+{
+	ui->setupUi(this);
+	ui->text->setHtml(text);
+
+	if (manualUpdate) {
+		delete ui->skip;
+		ui->skip = nullptr;
+
+		ui->no->setText(QTStr("Cancel"));
+	}
+}
+
+void OBSUpdate::on_yes_clicked()
+{
+	done(OBSUpdate::Yes);
+}
+
+void OBSUpdate::on_no_clicked()
+{
+	done(OBSUpdate::No);
+}
+
+void OBSUpdate::on_skip_clicked()
+{
+	done(OBSUpdate::Skip);
+}
+
+void OBSUpdate::accept()
+{
+	done(OBSUpdate::Yes);
+}
+
+void OBSUpdate::reject()
+{
+	done(OBSUpdate::No);
+}
diff --git a/UI/win-update/update-window.hpp b/UI/win-update/update-window.hpp
new file mode 100644
index 0000000..361e730
--- /dev/null
+++ b/UI/win-update/update-window.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <QDialog>
+#include <memory>
+
+#include "ui_OBSUpdate.h"
+
+class OBSUpdate : public QDialog {
+	Q_OBJECT
+
+public:
+	enum ReturnVal {
+		No,
+		Yes,
+		Skip
+	};
+
+	OBSUpdate(QWidget *parent, bool manualUpdate, const QString &text);
+
+public slots:
+	void on_yes_clicked();
+	void on_no_clicked();
+	void on_skip_clicked();
+	virtual void accept() override;
+	virtual void reject() override;
+
+private:
+	std::unique_ptr<Ui_OBSUpdate> ui;
+};
diff --git a/UI/win-update/updater/CMakeLists.txt b/UI/win-update/updater/CMakeLists.txt
new file mode 100644
index 0000000..e158475
--- /dev/null
+++ b/UI/win-update/updater/CMakeLists.txt
@@ -0,0 +1,51 @@
+if(NOT ENABLE_WIN_UPDATER)
+	return()
+endif()
+
+if(NOT DEFINED STATIC_ZLIB_PATH OR "${STATIC_ZLIB_PATH}" STREQUAL "")
+	message(STATUS "STATIC_ZLIB_PATH not set, windows updater disabled")
+	return()
+endif()
+
+project(updater)
+
+include_directories(${OBS_JANSSON_INCLUDE_DIRS})
+include_directories(${LIBLZMA_INCLUDE_DIRS})
+include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs")
+include_directories(${BLAKE2_INCLUDE_DIR})
+
+find_package(ZLIB REQUIRED)
+
+set(updater_HEADERS
+	../win-update-helpers.hpp
+	resource.h
+	updater.hpp
+	)
+set(updater_SOURCES
+	../win-update-helpers.cpp
+	updater.cpp
+	patch.cpp
+	http.cpp
+	hash.cpp
+	updater.rc
+	)
+
+add_definitions(-DNOMINMAX -DUNICODE -D_UNICODE)
+if(MSVC)
+	add_compile_options("$<$<CONFIG:RelWithDebInfo>:/MT>")
+endif()
+
+add_executable(updater WIN32
+	${updater_HEADERS}
+	${updater_SOURCES}
+	)
+target_link_libraries(updater
+	${OBS_JANSSON_IMPORT}
+	${STATIC_ZLIB_PATH}
+	lzma
+	blake2
+	psapi
+	comctl32
+	shell32
+	winhttp
+	)
diff --git a/UI/win-update/updater/hash.cpp b/UI/win-update/updater/hash.cpp
new file mode 100644
index 0000000..69033b0
--- /dev/null
+++ b/UI/win-update/updater/hash.cpp
@@ -0,0 +1,61 @@
+#include "updater.hpp"
+
+#include <util/windows/WinHandle.hpp>
+#include <vector>
+
+using namespace std;
+
+void HashToString(const uint8_t *in, wchar_t *out)
+{
+	const wchar_t alphabet[] = L"0123456789abcdef";
+
+	for (int i = 0; i != BLAKE2_HASH_LENGTH; ++i) {
+		out[2 * i]     = alphabet[in[i] / 16];
+		out[2 * i + 1] = alphabet[in[i] % 16];
+	}
+
+	out[BLAKE2_HASH_LENGTH * 2] = 0;
+}
+
+void StringToHash(const wchar_t *in, BYTE *out)
+{
+	int temp;
+
+	for (int i = 0; i < BLAKE2_HASH_LENGTH; i++) {
+		swscanf_s(in + i * 2, L"%02x", &temp);
+		out[i] = (BYTE)temp;
+	}
+}
+
+bool CalculateFileHash(const wchar_t *path, BYTE *hash)
+{
+	blake2b_state blake2;
+	if (blake2b_init(&blake2, BLAKE2_HASH_LENGTH) != 0)
+		return false;
+
+	WinHandle handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ,
+			nullptr, OPEN_EXISTING, 0, nullptr);
+	if (handle == INVALID_HANDLE_VALUE)
+		return false;
+
+	vector<BYTE> buf;
+	buf.resize(65536);
+
+	for (;;) {
+		DWORD read = 0;
+		if (!ReadFile(handle, buf.data(), (DWORD)buf.size(), &read,
+					nullptr))
+			return false;
+
+		if (!read)
+			break;
+
+		if (blake2b_update(&blake2, buf.data(), read) != 0)
+			return false;
+	}
+
+	if (blake2b_final(&blake2, hash, BLAKE2_HASH_LENGTH) != 0)
+		return false;
+
+	return true;
+}
diff --git a/UI/win-update/updater/http.cpp b/UI/win-update/updater/http.cpp
new file mode 100644
index 0000000..cbea2b3
--- /dev/null
+++ b/UI/win-update/updater/http.cpp
@@ -0,0 +1,537 @@
+#include "Updater.hpp"
+
+#include <algorithm>
+
+using namespace std;
+
+#define MAX_BUF_SIZE  262144
+#define READ_BUF_SIZE 32768
+
+/* ------------------------------------------------------------------------ */
+
+class ZipStream {
+	z_stream strm = {};
+	bool initialized = false;
+
+public:
+	inline ~ZipStream()
+	{
+		if (initialized)
+			inflateEnd(&strm);
+	}
+
+	inline operator z_stream*() {return &strm;}
+	inline z_stream *operator->() {return &strm;}
+
+	inline bool inflate()
+	{
+		int ret = inflateInit2(&strm, 16 + MAX_WBITS);
+		initialized = (ret == Z_OK);
+		return initialized;
+	}
+};
+
+/* ------------------------------------------------------------------------ */
+
+static bool ReadZippedHTTPData(string &responseBuf, z_stream *strm,
+		string &zipBuf, const uint8_t *buffer, DWORD outSize)
+{
+	do {
+		strm->avail_in = outSize;
+		strm->next_in  = buffer;
+
+		strm->avail_out = (uInt)zipBuf.size();
+		strm->next_out  = (Bytef *)zipBuf.data();
+
+		int zret = inflate(strm, Z_NO_FLUSH);
+		if (zret != Z_STREAM_END && zret != Z_OK)
+			return false;
+
+		try {
+			responseBuf.append(zipBuf.data(),
+					zipBuf.size() - strm->avail_out);
+		} catch (...) {
+			return false;
+		}
+	} while (strm->avail_out == 0);
+
+	return true;
+}
+
+static bool ReadHTTPData(string &responseBuf, const uint8_t *buffer,
+		DWORD outSize)
+{
+	try {
+		responseBuf.append((const char *)buffer, outSize);
+	} catch (...) {
+		return false;
+	}
+	return true;
+}
+
+bool HTTPPostData(const wchar_t *url,
+                  const BYTE *   data,
+                  int            dataLen,
+                  const wchar_t *extraHeaders,
+                  int *          responseCode,
+                  string &       responseBuf)
+{
+	HttpHandle     hSession;
+	HttpHandle     hConnect;
+	HttpHandle     hRequest;
+	string         zipBuf;
+	URL_COMPONENTS urlComponents = {};
+	bool           secure        = false;
+
+	wchar_t hostName[256];
+	wchar_t path[1024];
+
+	const wchar_t *acceptTypes[] = {L"*/*", nullptr};
+
+	responseBuf.clear();
+
+	/* -------------------------------------- *
+	 * get URL components                     */
+
+	urlComponents.dwStructSize = sizeof(urlComponents);
+
+	urlComponents.lpszHostName     = hostName;
+	urlComponents.dwHostNameLength = _countof(hostName);
+
+	urlComponents.lpszUrlPath     = path;
+	urlComponents.dwUrlPathLength = _countof(path);
+
+	WinHttpCrackUrl(url, 0, 0, &urlComponents);
+
+	if (urlComponents.nPort == 443)
+		secure = true;
+
+	/* -------------------------------------- *
+	 * connect to server                      */
+
+	hSession = WinHttpOpen(L"OBS Updater/2.1",
+	                       WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+	                       WINHTTP_NO_PROXY_NAME,
+	                       WINHTTP_NO_PROXY_BYPASS,
+	                       0);
+	if (!hSession) {
+		*responseCode = -1;
+		return false;
+	}
+
+	hConnect = WinHttpConnect(hSession, hostName,
+			secure
+			? INTERNET_DEFAULT_HTTPS_PORT
+			: INTERNET_DEFAULT_HTTP_PORT, 0);
+	if (!hConnect) {
+		*responseCode = -2;
+		return false;
+	}
+
+	/* -------------------------------------- *
+	 * request data                           */
+
+	hRequest = WinHttpOpenRequest(hConnect,
+	                              L"POST",
+	                              path,
+	                              nullptr,
+	                              WINHTTP_NO_REFERER,
+	                              acceptTypes,
+	                              secure
+	                              ? WINHTTP_FLAG_SECURE |
+	                                WINHTTP_FLAG_REFRESH
+	                              : WINHTTP_FLAG_REFRESH);
+	if (!hRequest) {
+		*responseCode = -3;
+		return false;
+	}
+
+	bool bResults = !!WinHttpSendRequest(hRequest, extraHeaders,
+			extraHeaders ? -1 : 0,
+			(void *)data, dataLen, dataLen, 0);
+
+	/* -------------------------------------- *
+	 * end request                            */
+
+	if (bResults) {
+		bResults = !!WinHttpReceiveResponse(hRequest, nullptr);
+	} else {
+		*responseCode = GetLastError();
+		return false;
+	}
+
+	/* -------------------------------------- *
+	 * get headers                            */
+
+	wchar_t encoding[64];
+	DWORD   encodingLen;
+
+	wchar_t statusCode[8];
+	DWORD   statusCodeLen;
+
+	statusCodeLen = sizeof(statusCode);
+	if (!WinHttpQueryHeaders(hRequest,
+	                         WINHTTP_QUERY_STATUS_CODE,
+	                         WINHTTP_HEADER_NAME_BY_INDEX,
+	                         &statusCode,
+	                         &statusCodeLen,
+	                         WINHTTP_NO_HEADER_INDEX)) {
+		*responseCode = -4;
+		return false;
+	} else {
+		statusCode[_countof(statusCode) - 1] = 0;
+	}
+
+	encodingLen = sizeof(encoding);
+	if (!WinHttpQueryHeaders(hRequest,
+	                         WINHTTP_QUERY_CONTENT_ENCODING,
+	                         WINHTTP_HEADER_NAME_BY_INDEX,
+	                         encoding,
+	                         &encodingLen,
+	                         WINHTTP_NO_HEADER_INDEX)) {
+		encoding[0] = 0;
+		if (GetLastError() != ERROR_WINHTTP_HEADER_NOT_FOUND) {
+			*responseCode = -5;
+			return false;
+		}
+	} else {
+		encoding[_countof(encoding) - 1] = 0;
+	}
+
+	/* -------------------------------------- *
+	 * allocate response data                 */
+
+	DWORD responseBufSize = MAX_BUF_SIZE;
+
+	try {
+		responseBuf.reserve(responseBufSize);
+	} catch (...) {
+		*responseCode = -6;
+		return false;
+	}
+
+	/* -------------------------------------- *
+	 * if zipped, initialize zip data         */
+
+	ZipStream strm;
+	bool gzip = wcscmp(encoding, L"gzip") == 0;
+
+	if (gzip) {
+		strm->zalloc   = Z_NULL;
+		strm->zfree    = Z_NULL;
+		strm->opaque   = Z_NULL;
+		strm->avail_in = 0;
+		strm->next_in  = Z_NULL;
+
+		if (!strm.inflate())
+			return false;
+
+		try {
+			zipBuf.resize(MAX_BUF_SIZE);
+		} catch (...) {
+			*responseCode = -6;
+			return false;
+		}
+	}
+
+	/* -------------------------------------- *
+	 * read data                              */
+
+	*responseCode = wcstoul(statusCode, nullptr, 10);
+
+	/* are we supposed to return true here? */
+	if (!bResults || *responseCode != 200)
+		return true;
+
+	BYTE buffer[READ_BUF_SIZE];
+	DWORD dwSize, outSize;
+
+	do {
+		/* Check for available data. */
+		dwSize = 0;
+		if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
+			*responseCode = -8;
+			return false;
+		}
+
+		dwSize = std::min(dwSize, (DWORD)sizeof(buffer));
+
+		if (!WinHttpReadData(hRequest, (void *)buffer, dwSize,
+					&outSize)) {
+			*responseCode = -9;
+			return false;
+		}
+
+		if (!outSize)
+			break;
+
+		if (gzip) {
+			if (!ReadZippedHTTPData(responseBuf, strm, zipBuf,
+						buffer, outSize)) {
+				*responseCode = -6;
+				return false;
+			}
+		} else {
+			if (!ReadHTTPData(responseBuf, buffer, outSize)) {
+				*responseCode = -6;
+				return false;
+			}
+		}
+
+		if (WaitForSingleObject(cancelRequested, 0) == WAIT_OBJECT_0) {
+			*responseCode = -14;
+			return false;
+		}
+	} while (dwSize > 0);
+
+	return true;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static bool ReadHTTPZippedFile(z_stream *strm, HANDLE updateFile,
+		string &zipBuf, const uint8_t *buffer, DWORD outSize,
+		int *responseCode)
+{
+	do {
+		strm->avail_in = outSize;
+		strm->next_in  = buffer;
+
+		strm->avail_out = (uInt)zipBuf.size();
+		strm->next_out  = (Bytef *)zipBuf.data();
+
+		int zret = inflate(strm, Z_NO_FLUSH);
+		if (zret != Z_STREAM_END && zret != Z_OK)
+			return false;
+
+		DWORD written;
+		if (!WriteFile(updateFile,
+			       zipBuf.data(),
+			       MAX_BUF_SIZE - strm->avail_out,
+			       &written,
+			       nullptr)) {
+			*responseCode = -10;
+			return false;
+		}
+		if (written != MAX_BUF_SIZE - strm->avail_out) {
+			*responseCode = -11;
+			return false;
+		}
+
+		completedFileSize += written;
+	} while (strm->avail_out == 0);
+
+	return true;
+}
+
+static bool ReadHTTPFile(HANDLE updateFile, const uint8_t *buffer,
+		DWORD outSize, int *responseCode)
+{
+	DWORD written;
+	if (!WriteFile(updateFile, buffer, outSize, &written, nullptr)) {
+		*responseCode = -12;
+		return false;
+	}
+
+	if (written != outSize) {
+		*responseCode = -13;
+		return false;
+	}
+
+	completedFileSize += outSize;
+	return true;
+}
+
+bool HTTPGetFile(HINTERNET      hConnect,
+                 const wchar_t *url,
+                 const wchar_t *outputPath,
+                 const wchar_t *extraHeaders,
+                 int *          responseCode)
+{
+	HttpHandle hRequest;
+
+	const wchar_t *acceptTypes[] = {L"*/*", nullptr};
+
+	URL_COMPONENTS urlComponents = {};
+	bool           secure        = false;
+
+	string  zipBuf;
+	wchar_t hostName[256];
+	wchar_t path[1024];
+
+	/* -------------------------------------- *
+	 * get URL components                     */
+
+	urlComponents.dwStructSize = sizeof(urlComponents);
+
+	urlComponents.lpszHostName     = hostName;
+	urlComponents.dwHostNameLength = _countof(hostName);
+
+	urlComponents.lpszUrlPath     = path;
+	urlComponents.dwUrlPathLength = _countof(path);
+
+	WinHttpCrackUrl(url, 0, 0, &urlComponents);
+
+	if (urlComponents.nPort == 443)
+		secure = true;
+
+	/* -------------------------------------- *
+	 * request data                           */
+
+	hRequest = WinHttpOpenRequest(hConnect,
+	                              L"GET",
+	                              path,
+	                              nullptr,
+	                              WINHTTP_NO_REFERER,
+	                              acceptTypes,
+	                              secure
+	                              ? WINHTTP_FLAG_SECURE |
+	                                WINHTTP_FLAG_REFRESH
+	                              : WINHTTP_FLAG_REFRESH);
+	if (!hRequest) {
+		*responseCode = -3;
+		return false;
+	}
+
+	bool bResults = !!WinHttpSendRequest(hRequest, extraHeaders,
+			extraHeaders ? -1 : 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
+
+	/* -------------------------------------- *
+	 * end request                            */
+
+	if (bResults) {
+		bResults = !!WinHttpReceiveResponse(hRequest, nullptr);
+	} else {
+		*responseCode = GetLastError();
+		return false;
+	}
+
+	/* -------------------------------------- *
+	 * get headers                            */
+
+	wchar_t encoding[64];
+	DWORD   encodingLen;
+
+	wchar_t statusCode[8];
+	DWORD   statusCodeLen;
+
+	statusCodeLen = sizeof(statusCode);
+	if (!WinHttpQueryHeaders(hRequest,
+	                         WINHTTP_QUERY_STATUS_CODE,
+	                         WINHTTP_HEADER_NAME_BY_INDEX,
+	                         &statusCode,
+	                         &statusCodeLen,
+	                         WINHTTP_NO_HEADER_INDEX)) {
+		*responseCode = -4;
+		return false;
+	} else {
+		statusCode[_countof(statusCode) - 1] = 0;
+	}
+
+	encodingLen = sizeof(encoding);
+	if (!WinHttpQueryHeaders(hRequest,
+	                         WINHTTP_QUERY_CONTENT_ENCODING,
+	                         WINHTTP_HEADER_NAME_BY_INDEX,
+	                         encoding,
+	                         &encodingLen,
+	                         WINHTTP_NO_HEADER_INDEX)) {
+		encoding[0] = 0;
+		if (GetLastError() != ERROR_WINHTTP_HEADER_NOT_FOUND) {
+			*responseCode = -5;
+			return false;
+		}
+	} else {
+		encoding[_countof(encoding) - 1] = 0;
+	}
+
+	/* -------------------------------------- *
+	 * allocate response data                 */
+
+	ZipStream strm;
+	bool gzip = wcscmp(encoding, L"gzip") == 0;
+
+	if (gzip) {
+		strm->zalloc   = Z_NULL;
+		strm->zfree    = Z_NULL;
+		strm->opaque   = Z_NULL;
+		strm->avail_in = 0;
+		strm->next_in  = Z_NULL;
+
+		if (!strm.inflate())
+			return false;
+
+		try {
+			zipBuf.resize(MAX_BUF_SIZE);
+		} catch (...) {
+			*responseCode = -6;
+			return false;
+		}
+	}
+
+	/* -------------------------------------- *
+	 * read data                              */
+
+	*responseCode = wcstoul(statusCode, nullptr, 10);
+
+	/* are we supposed to return true here? */
+	if (!bResults || *responseCode != 200)
+		return true;
+
+	BYTE  buffer[READ_BUF_SIZE];
+	DWORD dwSize, outSize;
+	int   lastPosition = 0;
+
+	WinHandle updateFile = CreateFile(outputPath, GENERIC_WRITE, 0,
+			nullptr, CREATE_ALWAYS, 0, nullptr);
+	if (!updateFile.Valid()) {
+		*responseCode = -7;
+		return false;
+	}
+
+	do {
+		/* Check for available data. */
+		dwSize = 0;
+		if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
+			*responseCode = -8;
+			return false;
+		}
+
+		dwSize = std::min(dwSize, (DWORD)sizeof(buffer));
+
+		if (!WinHttpReadData(hRequest, (void *)buffer, dwSize,
+					&outSize)) {
+			*responseCode = -9;
+			return false;
+		} else {
+			if (!outSize)
+				break;
+
+			if (gzip) {
+				if (!ReadHTTPZippedFile(strm, updateFile,
+							zipBuf, buffer,
+							outSize, responseCode))
+					return false;
+			} else {
+				if (!ReadHTTPFile(updateFile, buffer,
+							outSize, responseCode))
+					return false;
+			}
+
+			int position = (int)(((float)completedFileSize /
+						(float)totalFileSize) * 100.0f);
+			if (position > lastPosition) {
+				lastPosition = position;
+				SendDlgItemMessage(hwndMain, IDC_PROGRESS,
+						PBM_SETPOS, position, 0);
+			}
+		}
+
+		if (WaitForSingleObject(cancelRequested, 0) == WAIT_OBJECT_0) {
+			*responseCode = -14;
+			return false;
+		}
+
+	} while (dwSize > 0);
+
+	return true;
+}
diff --git a/UI/win-update/updater/patch.cpp b/UI/win-update/updater/patch.cpp
new file mode 100644
index 0000000..a801168
--- /dev/null
+++ b/UI/win-update/updater/patch.cpp
@@ -0,0 +1,301 @@
+#include "updater.hpp"
+
+#include <stdint.h>
+#include <vector>
+
+#include <lzma.h>
+
+using namespace std;
+
+#define MAX_BUF_SIZE  262144
+#define READ_BUF_SIZE 32768
+
+/* ------------------------------------------------------------------------ */
+
+class LZMAStream {
+	lzma_stream strm = {};
+	bool initialized = false;
+
+public:
+	inline ~LZMAStream()
+	{
+		if (initialized) {
+			lzma_end(&strm);
+		}
+	}
+
+	inline bool init_decoder()
+	{
+		lzma_ret ret = lzma_stream_decoder(
+				&strm,
+				200 * 1024 * 1024,
+				0);
+		initialized = (ret == LZMA_OK);
+		return initialized;
+	}
+
+	inline operator lzma_stream *() { return &strm; }
+	inline bool operator!() const { return !initialized; }
+
+	inline lzma_stream *get() { return &strm; }
+};
+
+class File {
+	FILE *f = nullptr;
+
+public:
+	inline ~File()
+	{
+		if (f)
+			fclose(f);
+	}
+
+	inline FILE **operator&() { return &f; }
+	inline operator FILE *() const { return f; }
+	inline bool operator!() const { return !f; }
+};
+
+/* ------------------------------------------------------------------------ */
+
+struct bspatch_stream {
+	void *opaque;
+	int (*read)(const struct bspatch_stream *stream, void *buffer,
+			int length);
+};
+
+/* ------------------------------------------------------------------------ */
+
+static int64_t offtin(const uint8_t *buf)
+{
+	int64_t y;
+
+	y = buf[7] & 0x7F;
+	y = y * 256;
+	y += buf[6];
+	y = y * 256;
+	y += buf[5];
+	y = y * 256;
+	y += buf[4];
+	y = y * 256;
+	y += buf[3];
+	y = y * 256;
+	y += buf[2];
+	y = y * 256;
+	y += buf[1];
+	y = y * 256;
+	y += buf[0];
+
+	if (buf[7] & 0x80)
+		y = -y;
+
+	return y;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int bspatch(const uint8_t *old, int64_t oldsize, uint8_t *newp,
+		int64_t newsize, struct bspatch_stream *stream)
+{
+	uint8_t buf[8];
+	int64_t oldpos, newpos;
+	int64_t ctrl[3];
+	int64_t i;
+
+	oldpos = 0;
+	newpos = 0;
+	while (newpos < newsize) {
+		/* Read control data */
+		for (i = 0; i <= 2; i++) {
+			if (stream->read(stream, buf, 8))
+				return -1;
+			ctrl[i] = offtin(buf);
+		};
+
+		/* Sanity-check */
+		if (newpos + ctrl[0] > newsize)
+			return -1;
+
+		/* Read diff string */
+		if (stream->read(stream, newp + newpos, (int)ctrl[0]))
+			return -1;
+
+		/* Add old data to diff string */
+		for (i = 0; i < ctrl[0]; i++)
+			if ((oldpos + i >= 0) && (oldpos + i < oldsize))
+				newp[newpos + i] += old[oldpos + i];
+
+		/* Adjust pointers */
+		newpos += ctrl[0];
+		oldpos += ctrl[0];
+
+		/* Sanity-check */
+		if (newpos + ctrl[1] > newsize)
+			return -1;
+
+		/* Read extra string */
+		if (stream->read(stream, newp + newpos, (int)ctrl[1]))
+			return -1;
+
+		/* Adjust pointers */
+		newpos += ctrl[1];
+		oldpos += ctrl[2];
+	};
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+struct patch_data {
+	HANDLE        h;
+	lzma_stream   *strm;
+	uint8_t       buf[READ_BUF_SIZE];
+};
+
+static int read_lzma(const struct bspatch_stream *stream, void *buffer, int len)
+{
+	if (!len)
+		return 0;
+
+	patch_data  *data    = (patch_data*)stream->opaque;
+	HANDLE      h        = data->h;
+	lzma_stream *strm    = data->strm;
+
+	strm->avail_out = (size_t)len;
+	strm->next_out  = (uint8_t *)buffer;
+
+	for (;;) {
+		if (strm->avail_in == 0) {
+			DWORD read_size;
+			if (!ReadFile(h, data->buf, READ_BUF_SIZE, &read_size,
+						nullptr))
+				return -1;
+			if (read_size == 0)
+				return -1;
+
+			strm->avail_in = (size_t)read_size;
+			strm->next_in  = data->buf;
+		}
+
+		lzma_ret ret = lzma_code(strm, LZMA_RUN);
+		if (ret == LZMA_STREAM_END)
+			return 0;
+		if (ret != LZMA_OK)
+			return -1;
+		if (strm->avail_out == 0)
+			break;
+	}
+
+	return 0;
+}
+
+int ApplyPatch(const wchar_t *patchFile, const wchar_t *targetFile)
+try {
+	uint8_t               header[24];
+	int64_t               newsize;
+	struct bspatch_stream stream;
+	bool                  success;
+
+	WinHandle  hPatch;
+	WinHandle  hTarget;
+	LZMAStream strm;
+
+	/* --------------------------------- *
+	 * open patch and file to patch      */
+
+	hPatch = CreateFile(patchFile, GENERIC_READ, 0, nullptr,
+			OPEN_EXISTING, 0, nullptr);
+	if (!hPatch.Valid())
+		throw int(GetLastError());
+
+	hTarget = CreateFile(targetFile, GENERIC_READ, 0, nullptr,
+			OPEN_EXISTING, 0, nullptr);
+	if (!hTarget.Valid())
+		throw int(GetLastError());
+
+	/* --------------------------------- *
+	 * read patch header                 */
+
+	DWORD read;
+	success = !!ReadFile(hPatch, header, sizeof(header), &read, nullptr);
+	if (success && read == sizeof(header)) {
+		if (memcmp(header, "JIMSLEY/BSDIFF43", 16))
+			throw int(-4);
+	} else {
+		throw int(GetLastError());
+	}
+
+	/* --------------------------------- *
+	 * allocate new file size data       */
+
+	newsize = offtin(header + 16);
+	if (newsize < 0 || newsize >= 0x7ffffffff)
+		throw int(-5);
+
+	vector<uint8_t> newData;
+	try {
+		newData.resize(newsize);
+	} catch (...) {
+		throw int(-1);
+	}
+
+	/* --------------------------------- *
+	 * read old file                     */
+
+	DWORD targetFileSize;
+
+	targetFileSize = GetFileSize(hTarget, nullptr);
+	if (targetFileSize == INVALID_FILE_SIZE)
+		throw int(GetLastError());
+
+	vector<uint8_t> oldData;
+	try {
+		oldData.resize(targetFileSize);
+	} catch (...) {
+		throw int(-1);
+	}
+
+	if (!ReadFile(hTarget, &oldData[0], targetFileSize, &read, nullptr))
+		throw int(GetLastError());
+	if (read != targetFileSize)
+		throw int(-1);
+
+	/* --------------------------------- *
+	 * patch to new file data            */
+
+	if (!strm.init_decoder())
+		throw int(-10);
+
+	patch_data data;
+	data.h    = hPatch;
+	data.strm = strm.get();
+
+	stream.read   = read_lzma;
+	stream.opaque = &data;
+
+	int ret = bspatch(oldData.data(), oldData.size(), newData.data(),
+			newData.size(), &stream);
+	if (ret != 0)
+		throw int(-9);
+
+	/* --------------------------------- *
+	 * write new file                    */
+
+	hTarget = nullptr;
+	hTarget = CreateFile(targetFile, GENERIC_WRITE, 0, nullptr,
+			CREATE_ALWAYS, 0, nullptr);
+	if (!hTarget.Valid())
+		throw int(GetLastError());
+
+	DWORD written;
+
+	success = !!WriteFile(hTarget, newData.data(), (DWORD)newsize,
+			&written, nullptr);
+	if (!success || written != newsize)
+		throw int(GetLastError());
+
+	return 0;
+
+} catch (int code) {
+	return code;
+}
diff --git a/UI/win-update/updater/resource.h b/UI/win-update/updater/resource.h
new file mode 100644
index 0000000..9b34eb0
--- /dev/null
+++ b/UI/win-update/updater/resource.h
@@ -0,0 +1,21 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by updater.rc
+//
+#define IDD_UPDATEDIALOG                101
+#define IDI_ICON1                       103
+#define IDC_PROGRESS                    1001
+#define IDC_STATUS                      1002
+#define IDCBUTTON                       1004
+#define IDC_BUTTON                      1004
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        104
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1005
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/UI/win-update/updater/updater.cpp b/UI/win-update/updater/updater.cpp
new file mode 100644
index 0000000..5ada461
--- /dev/null
+++ b/UI/win-update/updater/updater.cpp
@@ -0,0 +1,1438 @@
+/******************************************************************************
+ Copyright (C) 2017 Hugh Bailey <obs.jim at gmail.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+******************************************************************************/
+
+#include "updater.hpp"
+
+#include <psapi.h>
+
+#include <util/windows/CoTaskMemPtr.hpp>
+
+#include <future>
+#include <vector>
+#include <string>
+#include <mutex>
+
+using namespace std;
+
+/* ----------------------------------------------------------------------- */
+
+HANDLE     cancelRequested = nullptr;
+HANDLE     updateThread    = nullptr;
+HINSTANCE  hinstMain       = nullptr;
+HWND       hwndMain        = nullptr;
+HCRYPTPROV hProvider       = 0;
+
+static bool bExiting     = false;
+static bool updateFailed = false;
+static bool is32bit      = false;
+
+static bool downloadThreadFailure = false;
+
+int totalFileSize     = 0;
+int completedFileSize = 0;
+static int completedUpdates  = 0;
+
+struct LastError {
+	DWORD code;
+	inline LastError() { code = GetLastError(); }
+};
+
+void FreeWinHttpHandle(HINTERNET handle)
+{
+	WinHttpCloseHandle(handle);
+}
+
+/* ----------------------------------------------------------------------- */
+
+// http://www.codeproject.com/Articles/320748/Haephrati-Elevating-during-runtime
+static bool IsAppRunningAsAdminMode()
+{
+	BOOL  fIsRunAsAdmin        = FALSE;
+	DWORD dwError              = ERROR_SUCCESS;
+	PSID  pAdministratorsGroup = nullptr;
+
+	/* Allocate and initialize a SID of the administrators group. */
+	SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
+	if (!AllocateAndInitializeSid(&NtAuthority,
+	                              2,
+	                              SECURITY_BUILTIN_DOMAIN_RID,
+	                              DOMAIN_ALIAS_RID_ADMINS,
+	                              0,
+	                              0,
+	                              0,
+	                              0,
+	                              0,
+	                              0,
+	                              &pAdministratorsGroup)) {
+		dwError = GetLastError();
+		goto Cleanup;
+	}
+
+	/* Determine whether the SID of administrators group is enabled in the
+	 * primary access token of the process. */
+	if (!CheckTokenMembership(nullptr, pAdministratorsGroup,
+				&fIsRunAsAdmin)) {
+		dwError = GetLastError();
+		goto Cleanup;
+	}
+
+Cleanup:
+	/* Centralized cleanup for all allocated resources. */
+	if (pAdministratorsGroup) {
+		FreeSid(pAdministratorsGroup);
+		pAdministratorsGroup = nullptr;
+	}
+
+	/* Throw the error if something failed in the function. */
+	if (ERROR_SUCCESS != dwError)
+		return false;
+
+	return !!fIsRunAsAdmin;
+}
+
+static void Status(const wchar_t *fmt, ...)
+{
+	wchar_t str[512];
+
+	va_list argptr;
+	va_start(argptr, fmt);
+
+	StringCbVPrintf(str, sizeof(str), fmt, argptr);
+
+	SetDlgItemText(hwndMain, IDC_STATUS, str);
+
+	va_end(argptr);
+}
+
+static void CreateFoldersForPath(const wchar_t *path)
+{
+	wchar_t *p = (wchar_t *)path;
+
+	while (*p) {
+		if (*p == '\\' || *p == '/') {
+			*p = 0;
+			CreateDirectory(path, nullptr);
+			*p = '\\';
+		}
+		p++;
+	}
+}
+
+static bool MyCopyFile(const wchar_t *src, const wchar_t *dest)
+try {
+	WinHandle hSrc;
+	WinHandle hDest;
+
+	hSrc = CreateFile(src, GENERIC_READ, 0, nullptr, OPEN_EXISTING,
+			FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
+	if (!hSrc.Valid())
+		throw LastError();
+
+	hDest = CreateFile(dest, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,
+			0, nullptr);
+	if (!hDest.Valid())
+		throw LastError();
+
+	BYTE  buf[65536];
+	DWORD read, wrote;
+
+	for (;;) {
+		if (!ReadFile(hSrc, buf, sizeof(buf), &read, nullptr))
+			throw LastError();
+
+		if (read == 0)
+			break;
+
+		if (!WriteFile(hDest, buf, read, &wrote, nullptr))
+			throw LastError();
+
+		if (wrote != read)
+			return false;
+	}
+
+	return true;
+
+} catch (LastError error) {
+	SetLastError(error.code);
+	return false;
+}
+
+static bool IsSafeFilename(const wchar_t *path)
+{
+	const wchar_t *p = path;
+
+	if (!*p)
+		return false;
+
+	if (wcsstr(path, L".."))
+		return false;
+
+	if (*p == '/')
+		return false;
+
+	while (*p) {
+		if (!isalnum(*p) &&
+		    *p != '.' &&
+		    *p != '/' &&
+		    *p != '_' &&
+		    *p != '-')
+			return false;
+		p++;
+	}
+
+	return true;
+}
+
+static string QuickReadFile(const wchar_t *path)
+{
+	string data;
+
+	WinHandle handle = CreateFileW(path, GENERIC_READ, 0, nullptr,
+			OPEN_EXISTING, 0, nullptr);
+	if (!handle.Valid()) {
+		return string();
+	}
+
+	LARGE_INTEGER size;
+
+	if (!GetFileSizeEx(handle, &size)) {
+		return string();
+	}
+
+	data.resize((size_t)size.QuadPart);
+
+	DWORD read;
+	if (!ReadFile(handle,
+	              &data[0],
+	              (DWORD)data.size(),
+	              &read,
+	              nullptr)) {
+		return string();
+	}
+	if (read != size.QuadPart) {
+		return string();
+	}
+
+	return data;
+}
+
+/* ----------------------------------------------------------------------- */
+
+enum state_t {
+	STATE_INVALID,
+	STATE_PENDING_DOWNLOAD,
+	STATE_DOWNLOADING,
+	STATE_DOWNLOADED,
+	STATE_INSTALLED,
+};
+
+struct update_t {
+	wstring sourceURL;
+	wstring outputPath;
+	wstring tempPath;
+	wstring previousFile;
+	wstring basename;
+	string  packageName;
+
+	DWORD   fileSize = 0;
+	BYTE    hash[BLAKE2_HASH_LENGTH];
+	BYTE    downloadhash[BLAKE2_HASH_LENGTH];
+	BYTE    my_hash[BLAKE2_HASH_LENGTH];
+	state_t state     = STATE_INVALID;
+	bool    has_hash  = false;
+	bool    patchable = false;
+
+	inline update_t() {}
+	inline update_t(const update_t &from)
+	        : sourceURL(from.sourceURL),
+	          outputPath(from.outputPath),
+	          tempPath(from.tempPath),
+	          previousFile(from.previousFile),
+	          basename(from.basename),
+	          packageName(from.packageName),
+	          fileSize(from.fileSize),
+	          state(from.state),
+	          has_hash(from.has_hash),
+	          patchable(from.patchable)
+	{
+		memcpy(hash, from.hash, sizeof(hash));
+		memcpy(downloadhash, from.downloadhash, sizeof(downloadhash));
+		memcpy(my_hash, from.my_hash, sizeof(my_hash));
+	}
+
+	inline update_t(update_t &&from)
+	        : sourceURL(std::move(from.sourceURL)),
+	          outputPath(std::move(from.outputPath)),
+	          tempPath(std::move(from.tempPath)),
+	          previousFile(std::move(from.previousFile)),
+	          basename(std::move(from.basename)),
+	          packageName(std::move(from.packageName)),
+	          fileSize(from.fileSize),
+	          state(from.state),
+	          has_hash(from.has_hash),
+	          patchable(from.patchable)
+	{
+		from.state = STATE_INVALID;
+
+		memcpy(hash, from.hash, sizeof(hash));
+		memcpy(downloadhash, from.downloadhash, sizeof(downloadhash));
+		memcpy(my_hash, from.my_hash, sizeof(my_hash));
+	}
+
+	void CleanPartialUpdate()
+	{
+		if (state == STATE_INSTALLED) {
+			if (!previousFile.empty()) {
+				DeleteFile(outputPath.c_str());
+				MyCopyFile(previousFile.c_str(),
+						outputPath.c_str());
+				DeleteFile(previousFile.c_str());
+			} else {
+				DeleteFile(outputPath.c_str());
+			}
+		} else if (state == STATE_DOWNLOADED) {
+			DeleteFile(tempPath.c_str());
+		}
+	}
+
+	inline update_t &operator=(const update_t &from)
+	{
+	        sourceURL = from.sourceURL;
+	        outputPath = from.outputPath;
+	        tempPath = from.tempPath;
+	        previousFile = from.previousFile;
+	        basename = from.basename;
+	        packageName = from.packageName;
+	        fileSize = from.fileSize;
+	        state = from.state;
+	        has_hash = from.has_hash;
+	        patchable = from.patchable;
+
+		memcpy(hash, from.hash, sizeof(hash));
+		memcpy(downloadhash, from.downloadhash, sizeof(downloadhash));
+		memcpy(my_hash, from.my_hash, sizeof(my_hash));
+	}
+};
+
+static vector<update_t> updates;
+static mutex updateMutex;
+
+static inline void CleanupPartialUpdates()
+{
+	for (update_t &update : updates)
+		update.CleanPartialUpdate();
+}
+
+/* ----------------------------------------------------------------------- */
+
+bool DownloadWorkerThread()
+{
+	HttpHandle hSession = WinHttpOpen(L"OBS Studio Updater/2.1",
+	                                  WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+	                                  WINHTTP_NO_PROXY_NAME,
+	                                  WINHTTP_NO_PROXY_BYPASS,
+	                                  0);
+	if (!hSession) {
+		downloadThreadFailure = true;
+		Status(L"Update failed: Couldn't open obsproject.com");
+		return false;
+	}
+
+	HttpHandle hConnect = WinHttpConnect(hSession, L"obsproject.com",
+			INTERNET_DEFAULT_HTTPS_PORT, 0);
+	if (!hConnect) {
+		downloadThreadFailure = true;
+		Status(L"Update failed: Couldn't connect to obsproject.com");
+		return false;
+	}
+
+	for (;;) {
+		bool foundWork = false;
+
+		unique_lock<mutex> ulock(updateMutex);
+
+		for (update_t &update : updates) {
+			int responseCode;
+
+			DWORD waitResult =
+				WaitForSingleObject(cancelRequested, 0);
+			if (waitResult == WAIT_OBJECT_0) {
+				return false;
+			}
+
+			if (update.state != STATE_PENDING_DOWNLOAD)
+				continue;
+
+			update.state = STATE_DOWNLOADING;
+
+			ulock.unlock();
+
+			foundWork = true;
+
+			if (downloadThreadFailure) {
+				return false;
+			}
+
+			Status(L"Downloading %s", update.outputPath.c_str());
+
+			if (!HTTPGetFile(hConnect,
+			                 update.sourceURL.c_str(),
+			                 update.tempPath.c_str(),
+			                 L"Accept-Encoding: gzip",
+			                 &responseCode)) {
+
+				downloadThreadFailure = true;
+				DeleteFile(update.tempPath.c_str());
+				Status(L"Update failed: Could not download "
+				       L"%s (error code %d)",
+				       update.outputPath.c_str(),
+				       responseCode);
+				return 1;
+			}
+
+			if (responseCode != 200) {
+				downloadThreadFailure = true;
+				DeleteFile(update.tempPath.c_str());
+				Status(L"Update failed: Could not download "
+				       L"%s (error code %d)",
+				       update.outputPath.c_str(),
+				       responseCode);
+				return 1;
+			}
+
+			BYTE downloadHash[BLAKE2_HASH_LENGTH];
+			if (!CalculateFileHash(update.tempPath.c_str(),
+						downloadHash)) {
+				downloadThreadFailure = true;
+				DeleteFile(update.tempPath.c_str());
+				Status(L"Update failed: Couldn't verify "
+						L"integrity of %s",
+						update.outputPath.c_str());
+				return 1;
+			}
+
+			if (memcmp(update.downloadhash, downloadHash, 20)) {
+				downloadThreadFailure = true;
+				DeleteFile(update.tempPath.c_str());
+				Status(L"Update failed: Integrity check "
+						L"failed on %s",
+						update.outputPath.c_str());
+				return 1;
+			}
+
+			ulock.lock();
+
+			update.state = STATE_DOWNLOADED;
+			completedUpdates++;
+		}
+
+		if (!foundWork) {
+			break;
+		}
+		if (downloadThreadFailure) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static bool RunDownloadWorkers(int num)
+try {
+	vector<future<bool>> thread_success_results;
+	thread_success_results.resize(num);
+
+	for (future<bool> &result : thread_success_results) {
+		result = async(DownloadWorkerThread);
+	}
+	for (future<bool> &result : thread_success_results) {
+		if (!result.get()) {
+			return false;
+		}
+	}
+
+	return true;
+
+} catch (...) {
+	return false;
+}
+
+/* ----------------------------------------------------------------------- */
+
+#define WAITIFOBS_SUCCESS       0
+#define WAITIFOBS_WRONG_PROCESS 1
+#define WAITIFOBS_CANCELLED     2
+
+static inline DWORD WaitIfOBS(DWORD id, const wchar_t *expected)
+{
+	wchar_t path[MAX_PATH];
+	wchar_t *name;
+	*path = 0;
+
+	WinHandle proc = OpenProcess(
+			PROCESS_QUERY_INFORMATION |
+			PROCESS_VM_READ |
+			SYNCHRONIZE,
+			false, id);
+	if (!proc.Valid())
+		return WAITIFOBS_WRONG_PROCESS;
+
+	if (!GetProcessImageFileName(proc, path, _countof(path)))
+		return WAITIFOBS_WRONG_PROCESS;
+
+	name = wcsrchr(path, L'\\');
+	if (name)
+		name += 1;
+	else
+		name = path;
+
+	if (_wcsnicmp(name, expected, 5) == 0) {
+		HANDLE hWait[2];
+		hWait[0] = proc;
+		hWait[1] = cancelRequested;
+
+		int i = WaitForMultipleObjects(2, hWait, false, INFINITE);
+		if (i == WAIT_OBJECT_0 + 1)
+			return WAITIFOBS_CANCELLED;
+
+		return WAITIFOBS_SUCCESS;
+	}
+
+	return WAITIFOBS_WRONG_PROCESS;
+}
+
+static bool WaitForOBS()
+{
+	DWORD proc_ids[1024], needed, count;
+	const wchar_t *name = is32bit ? L"obs32" : L"obs64";
+
+	if (!EnumProcesses(proc_ids, sizeof(proc_ids), &needed)) {
+		return true;
+	}
+
+	count = needed / sizeof(DWORD);
+
+	for (DWORD i = 0; i < count; i++) {
+		DWORD id = proc_ids[i];
+		if (id != 0) {
+			switch (WaitIfOBS(id, name)) {
+			case WAITIFOBS_SUCCESS:
+				return true;
+			case WAITIFOBS_WRONG_PROCESS:
+				break;
+			case WAITIFOBS_CANCELLED:
+				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static inline bool UTF8ToWide(wchar_t *wide, int wideSize, const char *utf8)
+{
+	return !!MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wide, wideSize);
+}
+
+static inline bool WideToUTF8(char *utf8, int utf8Size, const wchar_t *wide)
+{
+	return !!WideCharToMultiByte(CP_UTF8, 0, wide, -1, utf8, utf8Size,
+			nullptr, nullptr);
+}
+
+static inline bool FileExists(const wchar_t *path)
+{
+	WIN32_FIND_DATAW wfd;
+	HANDLE           hFind;
+
+	hFind = FindFirstFileW(path, &wfd);
+	if (hFind != INVALID_HANDLE_VALUE)
+		FindClose(hFind);
+
+	return hFind != INVALID_HANDLE_VALUE;
+}
+
+static bool NonCorePackageInstalled(const char *name)
+{
+	if (strcmp(name, "obs-browser") == 0) {
+		return FileExists(L"obs-plugins\\32bit\\obs-browser.dll");
+	} else if (strcmp(name, "realsense") == 0) {
+		return FileExists(L"obs-plugins\\32bit\\win-ivcam.dll");
+	}
+
+	return false;
+}
+
+#define UTF8ToWideBuf(wide, utf8) UTF8ToWide(wide, _countof(wide), utf8)
+#define WideToUTF8Buf(utf8, wide) WideToUTF8(utf8, _countof(utf8), wide)
+
+#define UPDATE_URL L"https://obsproject.com/update_studio"
+
+static bool AddPackageUpdateFiles(json_t *root, size_t idx,
+		const wchar_t *tempPath)
+{
+	json_t *package = json_array_get(root, idx);
+	json_t *name    = json_object_get(package, "name");
+	json_t *files   = json_object_get(package, "files");
+
+	if (!json_is_array(files))
+		return true;
+	if (!json_is_string(name))
+		return true;
+
+	wchar_t wPackageName[512];
+	const char *packageName = json_string_value(name);
+	size_t fileCount = json_array_size(files);
+
+	if (!UTF8ToWideBuf(wPackageName, packageName))
+		return false;
+
+	if (strcmp(packageName, "core") != 0 &&
+	    !NonCorePackageInstalled(packageName))
+		return true;
+
+	for (size_t j = 0; j < fileCount; j++) {
+		json_t *file     = json_array_get(files, j);
+		json_t *fileName = json_object_get(file, "name");
+		json_t *hash     = json_object_get(file, "hash");
+		json_t *size     = json_object_get(file, "size");
+
+		if (!json_is_string(fileName))
+			continue;
+		if (!json_is_string(hash))
+			continue;
+		if (!json_is_integer(size))
+			continue;
+
+		const char *fileUTF8 = json_string_value(fileName);
+		const char *hashUTF8 = json_string_value(hash);
+		int fileSize         = (int)json_integer_value(size);
+
+		if (strlen(hashUTF8) != BLAKE2_HASH_LENGTH * 2)
+			continue;
+
+		/* convert strings to wide */
+
+		wchar_t sourceURL[1024];
+		wchar_t updateFileName[MAX_PATH];
+		wchar_t updateHashStr[BLAKE2_HASH_STR_LENGTH];
+		wchar_t tempFilePath[MAX_PATH];
+
+		if (!UTF8ToWideBuf(updateFileName, fileUTF8))
+			continue;
+		if (!UTF8ToWideBuf(updateHashStr, hashUTF8))
+			continue;
+
+		/* make sure paths are safe */
+
+		if (!IsSafeFilename(updateFileName)) {
+			Status(L"Update failed: Unsafe path '%s' found in "
+					L"manifest", updateFileName);
+			return false;
+		}
+
+		StringCbPrintf(sourceURL, sizeof(sourceURL), L"%s/%s/%s",
+				UPDATE_URL, wPackageName, updateFileName);
+		StringCbPrintf(tempFilePath, sizeof(tempFilePath),
+				L"%s\\%s", tempPath, updateHashStr);
+
+		/* Check file hash */
+
+		BYTE    existingHash[BLAKE2_HASH_LENGTH];
+		wchar_t fileHashStr[BLAKE2_HASH_STR_LENGTH];
+		bool    has_hash;
+
+		/* We don't really care if this fails, it's just to avoid
+		 * wasting bandwidth by downloading unmodified files */
+		if (CalculateFileHash(updateFileName, existingHash)) {
+
+			HashToString(existingHash, fileHashStr);
+			if (wcscmp(fileHashStr, updateHashStr) == 0)
+				continue;
+
+			has_hash = true;
+		} else {
+			has_hash = false;
+		}
+
+		/* Add update file */
+
+		update_t update;
+		update.fileSize     = fileSize;
+		update.basename     = updateFileName;
+		update.outputPath   = updateFileName;
+		update.tempPath     = tempFilePath;
+		update.sourceURL    = sourceURL;
+		update.packageName  = packageName;
+		update.state        = STATE_PENDING_DOWNLOAD;
+		update.patchable    = false;
+
+		StringToHash(updateHashStr, update.downloadhash);
+		memcpy(update.hash, update.downloadhash, sizeof(update.hash));
+
+		update.has_hash = has_hash;
+		if (has_hash)
+			StringToHash(fileHashStr, update.my_hash);
+
+		updates.push_back(move(update));
+
+		totalFileSize += fileSize;
+	}
+
+	return true;
+}
+
+static void UpdateWithPatchIfAvailable(const char *name, const char *hash,
+		const char *source,
+		int size)
+{
+	wchar_t widePatchableFilename[MAX_PATH];
+	wchar_t widePatchHash[MAX_PATH];
+	wchar_t sourceURL[1024];
+	wchar_t patchHashStr[BLAKE2_HASH_STR_LENGTH];
+
+	if (strncmp(source, "https://obsproject.com/", 23) != 0)
+		return;
+
+	string patchPackageName = name;
+
+	const char *slash = strchr(name, '/');
+	if (!slash)
+		return;
+
+	patchPackageName.resize(slash - name);
+	name = slash + 1;
+
+	if (!UTF8ToWideBuf(widePatchableFilename, name))
+		return;
+	if (!UTF8ToWideBuf(widePatchHash, hash))
+		return;
+	if (!UTF8ToWideBuf(sourceURL, source))
+		return;
+	if (!UTF8ToWideBuf(patchHashStr, hash))
+		return;
+
+	for (update_t &update : updates) {
+		if (update.packageName != patchPackageName)
+			continue;
+		if (update.basename != widePatchableFilename)
+			continue;
+
+		StringToHash(patchHashStr, update.downloadhash);
+
+		/* Replace the source URL with the patch file, mark it as
+		 * patchable, and re-calculate download size */
+		totalFileSize -= (update.fileSize - size);
+		update.sourceURL = sourceURL;
+		update.fileSize  = size;
+		update.patchable = true;
+		break;
+	}
+}
+
+static bool UpdateFile(update_t &file)
+{
+	wchar_t oldFileRenamedPath[MAX_PATH];
+
+	if (file.patchable)
+		Status(L"Updating %s...", file.outputPath.c_str());
+	else
+		Status(L"Installing %s...", file.outputPath.c_str());
+
+	/* Check if we're replacing an existing file or just installing a new
+	 * one */
+	DWORD attribs = GetFileAttributes(file.outputPath.c_str());
+
+	if (attribs != INVALID_FILE_ATTRIBUTES) {
+		wchar_t *curFileName = nullptr;
+		wchar_t  baseName[MAX_PATH];
+
+		StringCbCopy(baseName, sizeof(baseName),
+				file.outputPath.c_str());
+
+		curFileName = wcsrchr(baseName, '/');
+		if (curFileName) {
+			curFileName[0] = '\0';
+			curFileName++;
+		} else
+			curFileName = baseName;
+
+		/* Backup the existing file in case a rollback is needed */
+		StringCbCopy(oldFileRenamedPath,
+				sizeof(oldFileRenamedPath),
+				file.outputPath.c_str());
+		StringCbCat(oldFileRenamedPath,
+				sizeof(oldFileRenamedPath),
+				L".old");
+
+		if (!MyCopyFile(file.outputPath.c_str(), oldFileRenamedPath)) {
+			int is_sharing_violation =
+				(GetLastError() == ERROR_SHARING_VIOLATION);
+
+			if (is_sharing_violation)
+				Status(L"Update failed: %s is still in use.  "
+				       L"Close all programs and try again.",
+				       curFileName);
+			else
+				Status(L"Update failed: Couldn't backup %s "
+				       L"(error %d)",
+				       curFileName, GetLastError());
+			return false;
+		}
+
+		int  error_code;
+		bool installed_ok;
+
+		if (file.patchable) {
+			error_code = ApplyPatch(
+					file.tempPath.c_str(),
+					file.outputPath.c_str());
+			installed_ok = (error_code == 0);
+
+			if (installed_ok) {
+				BYTE patchedFileHash[BLAKE2_HASH_LENGTH];
+				if (!CalculateFileHash(file.outputPath.c_str(),
+						patchedFileHash)) {
+					Status(L"Update failed: Couldn't "
+					       L"verify integrity of patched %s",
+					       curFileName);
+					return false;
+				}
+
+				if (memcmp(file.hash, patchedFileHash,
+						BLAKE2_HASH_LENGTH) != 0) {
+					Status(L"Update failed: Integrity "
+					       L"check of patched "
+					       L"%s failed",
+					       curFileName);
+					return false;
+				}
+			}
+		} else {
+			installed_ok = MyCopyFile(
+					file.tempPath.c_str(),
+					file.outputPath.c_str());
+			error_code = GetLastError();
+		}
+
+		if (!installed_ok) {
+			int is_sharing_violation =
+				(error_code == ERROR_SHARING_VIOLATION);
+
+			if (is_sharing_violation)
+				Status(L"Update failed: %s is still in use.  "
+				       L"Close all "
+				       L"programs and try again.",
+				       curFileName);
+			else
+				Status(L"Update failed: Couldn't update %s "
+				       L"(error %d)",
+				       curFileName,
+				       GetLastError());
+			return false;
+		}
+
+		file.previousFile = oldFileRenamedPath;
+		file.state        = STATE_INSTALLED;
+	} else {
+		if (file.patchable) {
+			/* Uh oh, we thought we could patch something but it's
+			 * no longer there! */
+			Status(L"Update failed: Source file %s not found",
+					file.outputPath.c_str());
+			return false;
+		}
+
+		/* We may be installing into new folders,
+		 * make sure they exist */
+		CreateFoldersForPath(file.outputPath.c_str());
+
+		bool success = !!MyCopyFile(
+				file.tempPath.c_str(),
+				file.outputPath.c_str());
+		if (!success) {
+			Status(L"Update failed: Couldn't install %s (error %d)",
+					file.outputPath.c_str(),
+					GetLastError());
+			return false;
+		}
+
+		file.previousFile = L"";
+		file.state        = STATE_INSTALLED;
+	}
+
+	return true;
+}
+
+static wchar_t tempPath[MAX_PATH] = {};
+
+#define PATCH_MANIFEST_URL \
+	L"https://obsproject.com/update_studio/getpatchmanifest"
+#define HASH_NULL \
+	L"0000000000000000000000000000000000000000"
+
+static bool Update(wchar_t *cmdLine)
+{
+	/* ------------------------------------- *
+	 * Check to make sure OBS isn't running  */
+
+	HANDLE hObsUpdateMutex = OpenMutexW(SYNCHRONIZE, false,
+			L"OBSStudioUpdateMutex");
+	if (hObsUpdateMutex) {
+		HANDLE hWait[2];
+		hWait[0] = hObsUpdateMutex;
+		hWait[1] = cancelRequested;
+
+		int i = WaitForMultipleObjects(2, hWait, false, INFINITE);
+
+		if (i == WAIT_OBJECT_0)
+			ReleaseMutex(hObsUpdateMutex);
+
+		CloseHandle(hObsUpdateMutex);
+
+		if (i == WAIT_OBJECT_0 + 1)
+			return false;
+	}
+
+	if (!WaitForOBS())
+		return false;
+
+	/* ------------------------------------- *
+	 * Init crypt stuff                      */
+
+	CryptProvider hProvider;
+	if (!CryptAcquireContext(&hProvider, nullptr, MS_ENH_RSA_AES_PROV,
+				PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
+		SetDlgItemTextW(hwndMain, IDC_STATUS,
+				L"Update failed: CryptAcquireContext failure");
+		return false;
+	}
+
+	::hProvider = hProvider;
+
+	/* ------------------------------------- */
+
+	SetDlgItemTextW(hwndMain, IDC_STATUS,
+			L"Searching for available updates...");
+
+	/* ------------------------------------- *
+	 * Check if updating portable build      */
+
+	bool bIsPortable = false;
+
+	if (cmdLine[0]) {
+		int argc;
+		LPWSTR *argv = CommandLineToArgvW(cmdLine, &argc);
+
+		if (argv) {
+			for (int i = 0; i < argc; i++) {
+				if (wcscmp(argv[i], L"Portable") == 0) {
+					bIsPortable = true;
+				}
+			}
+
+			LocalFree((HLOCAL)argv);
+		}
+	}
+
+	/* ------------------------------------- *
+	 * Get config path                       */
+
+	wchar_t lpAppDataPath[MAX_PATH];
+	lpAppDataPath[0] = 0;
+
+	if (bIsPortable) {
+		GetCurrentDirectory(_countof(lpAppDataPath), lpAppDataPath);
+		StringCbCat(lpAppDataPath, sizeof(lpAppDataPath), L"\\config");
+	} else {
+		CoTaskMemPtr<wchar_t> pOut;
+		HRESULT hr = SHGetKnownFolderPath(FOLDERID_RoamingAppData,
+				KF_FLAG_DEFAULT, nullptr, &pOut);
+		if (hr != S_OK) {
+			Status(L"Update failed: Could not determine AppData "
+					L"location");
+			return false;
+		}
+
+		StringCbCopy(lpAppDataPath, sizeof(lpAppDataPath), pOut);
+		StringCbCat(lpAppDataPath, sizeof(lpAppDataPath),
+				L"\\obs-studio");
+	}
+
+	/* ------------------------------------- *
+	 * Get download path                     */
+
+	wchar_t manifestPath[MAX_PATH];
+	wchar_t tempDirName[MAX_PATH];
+
+	manifestPath[0] = 0;
+	tempDirName[0]  = 0;
+
+	StringCbPrintf(manifestPath, sizeof(manifestPath),
+			L"%s\\updates\\manifest.json", lpAppDataPath);
+	if (!GetTempPathW(_countof(tempPath), tempPath)) {
+		Status(L"Update failed: Failed to get temp path: %ld",
+				GetLastError());
+		return false;
+	}
+	if (!GetTempFileNameW(tempDirName, L"obs-studio", 0, tempDirName)) {
+		Status(L"Update failed: Failed to create temp dir name: %ld",
+				GetLastError());
+		return false;
+	}
+
+	StringCbCat(tempPath, sizeof(tempPath), tempDirName);
+	CreateDirectory(tempPath, nullptr);
+
+	/* ------------------------------------- *
+	 * Load manifest file                    */
+
+	Json root;
+	{
+		string manifestFile = QuickReadFile(manifestPath);
+		if (manifestFile.empty()) {
+			Status(L"Update failed: Couldn't load manifest file");
+			return false;
+		}
+
+		json_error_t error;
+		root = json_loads(manifestFile.c_str(), 0, &error);
+
+		if (!root) {
+			Status(L"Update failed: Couldn't parse update "
+					L"manifest: %S", error.text);
+			return false;
+		}
+	}
+
+	if (!json_is_object(root.get())) {
+		Status(L"Update failed: Invalid update manifest");
+		return false;
+	}
+
+	/* ------------------------------------- *
+	 * Parse current manifest update files   */
+
+	json_t *packages = json_object_get(root, "packages");
+	size_t packageCount = json_array_size(packages);
+
+	for (size_t i = 0; i < packageCount; i++) {
+		if (!AddPackageUpdateFiles(packages, i, tempPath)) {
+			Status(L"Failed to process update packages");
+			return false;
+		}
+	}
+
+	/* ------------------------------------- *
+	 * Exit if updates already installed     */
+
+	if (!updates.size()) {
+		Status(L"All available updates are already installed.");
+		return true;
+	}
+
+	/* ------------------------------------- *
+	 * Generate file hash json               */
+
+	Json files(json_array());
+
+	for (update_t &update : updates) {
+		wchar_t whash_string[BLAKE2_HASH_STR_LENGTH];
+		char    hash_string[BLAKE2_HASH_STR_LENGTH];
+		char    outputPath[MAX_PATH];
+
+		if (!update.has_hash)
+			continue;
+
+		/* check hash */
+		HashToString(update.my_hash, whash_string);
+		if (wcscmp(whash_string, HASH_NULL) == 0)
+			continue;
+
+		if (!WideToUTF8Buf(hash_string, whash_string))
+			continue;
+		if (!WideToUTF8Buf(outputPath, update.basename.c_str()))
+			continue;
+
+		string package_path;
+		package_path = update.packageName;
+		package_path += "/";
+		package_path += outputPath;
+
+		json_t *obj = json_object();
+		json_object_set(obj, "name", json_string(package_path.c_str()));
+		json_object_set(obj, "hash", json_string(hash_string));
+		json_array_append_new(files, obj);
+	}
+
+	/* ------------------------------------- *
+	 * Send file hashes                      */
+
+	string newManifest;
+	{
+		char *post_body = json_dumps(files, JSON_COMPACT);
+
+		int    responseCode;
+
+		int len = (int)strlen(post_body);
+		uLong compressSize = compressBound(len);
+		string compressedJson;
+
+		compressedJson.resize(compressSize);
+		compress2((Bytef*)&compressedJson[0], &compressSize,
+				(const Bytef*)post_body, len,
+				Z_BEST_COMPRESSION);
+		compressedJson.resize(compressSize);
+
+		bool success = !!HTTPPostData(PATCH_MANIFEST_URL,
+				(BYTE *)&compressedJson[0],
+				(int)compressedJson.size(),
+				L"Accept-Encoding: gzip", &responseCode,
+				newManifest);
+		free(post_body);
+
+		if (!success)
+			return false;
+
+		if (responseCode != 200) {
+			Status(L"Update failed: HTTP/%d while trying to "
+					L"download patch manifest",
+					responseCode);
+			return false;
+		}
+	}
+
+	/* ------------------------------------- *
+	 * Parse new manifest                    */
+
+	json_error_t error;
+	root = json_loads(newManifest.c_str(), 0, &error);
+	if (!root) {
+		Status(L"Update failed: Couldn't parse patch manifest: %S",
+				error.text);
+		return false;
+	}
+
+	if (!json_is_array(root.get())) {
+		Status(L"Update failed: Invalid patch manifest");
+		return false;
+	}
+
+	packageCount = json_array_size(root);
+
+	for (size_t i = 0; i < packageCount; i++) {
+		json_t *patch = json_array_get(root, i);
+
+		if (!json_is_object(patch)) {
+			Status(L"Update failed: Invalid patch manifest");
+			return false;
+		}
+
+		json_t *name_json   = json_object_get(patch, "name");
+		json_t *hash_json   = json_object_get(patch, "hash");
+		json_t *source_json = json_object_get(patch, "source");
+		json_t *size_json   = json_object_get(patch, "size");
+
+		if (!json_is_string(name_json))
+			continue;
+		if (!json_is_string(hash_json))
+			continue;
+		if (!json_is_string(source_json))
+			continue;
+		if (!json_is_integer(size_json))
+			continue;
+
+		const char *name   = json_string_value(name_json);
+		const char *hash   = json_string_value(hash_json);
+		const char *source = json_string_value(source_json);
+		int         size   = (int)json_integer_value(size_json);
+
+		UpdateWithPatchIfAvailable(name, hash, source, size);
+	}
+
+	/* ------------------------------------- *
+	 * Download Updates                      */
+
+	if (!RunDownloadWorkers(2))
+		return false;
+
+	if (completedUpdates != updates.size()) {
+		Status(L"Update failed to download all files.");
+		return false;
+	}
+
+	/* ------------------------------------- *
+	 * Install updates                       */
+
+	for (update_t &update : updates) {
+		if (!UpdateFile(update))
+			return false;
+	}
+
+	/* If we get here, all updates installed successfully so we can purge
+	 * the old versions */
+	for (update_t &update : updates) {
+		if (!update.previousFile.empty())
+			DeleteFile(update.previousFile.c_str());
+
+		/* We delete here not above in case of duplicate hashes */
+		if (!update.tempPath.empty())
+			DeleteFile(update.tempPath.c_str());
+	}
+
+	Status(L"Update complete.");
+	SetDlgItemText(hwndMain, IDC_BUTTON, L"Launch OBS");
+	return true;
+}
+
+static DWORD WINAPI UpdateThread(void *arg)
+{
+	wchar_t *cmdLine = (wchar_t *)arg;
+
+	bool success = Update(cmdLine);
+
+	if (!success) {
+		/* This handles deleting temp files and rolling back and
+		 * partially installed updates */
+		CleanupPartialUpdates();
+
+		if (tempPath[0])
+			RemoveDirectory(tempPath);
+
+		if (WaitForSingleObject(cancelRequested, 0) == WAIT_OBJECT_0)
+			Status(L"Update aborted.");
+
+		SendDlgItemMessage(hwndMain, IDC_PROGRESS, PBM_SETSTATE,
+				PBST_ERROR, 0);
+
+		SetDlgItemText(hwndMain, IDC_BUTTON, L"Exit");
+		EnableWindow(GetDlgItem(hwndMain, IDC_BUTTON), true);
+
+		updateFailed = true;
+	} else {
+		if (tempPath[0])
+			RemoveDirectory(tempPath);
+	}
+
+	if (bExiting)
+		ExitProcess(success);
+	return 0;
+}
+
+static void CancelUpdate(bool quit)
+{
+	if (WaitForSingleObject(updateThread, 0) != WAIT_OBJECT_0) {
+		bExiting = quit;
+		SetEvent(cancelRequested);
+	} else {
+		PostQuitMessage(0);
+	}
+}
+
+static void LaunchOBS()
+{
+	wchar_t cwd[MAX_PATH];
+	wchar_t newCwd[MAX_PATH];
+	wchar_t obsPath[MAX_PATH];
+
+	GetCurrentDirectory(_countof(cwd) - 1, cwd);
+
+	StringCbCopy(obsPath, sizeof(obsPath), cwd);
+	StringCbCat(obsPath, sizeof(obsPath), is32bit
+			? L"\\bin\\32bit"
+			: L"\\bin\\64bit");
+	SetCurrentDirectory(obsPath);
+	StringCbCopy(newCwd, sizeof(newCwd), obsPath);
+
+	StringCbCat(obsPath, sizeof(obsPath), is32bit
+			? L"\\obs32.exe"
+			: L"\\obs64.exe");
+
+	if (!FileExists(obsPath)) {
+		StringCbCopy(obsPath, sizeof(obsPath), cwd);
+		StringCbCat(obsPath, sizeof(obsPath), L"\\bin\\32bit");
+		SetCurrentDirectory(obsPath);
+		StringCbCopy(newCwd, sizeof(newCwd), obsPath);
+
+		StringCbCat(obsPath, sizeof(obsPath), L"\\obs32.exe");
+
+		if (!FileExists(obsPath)) {
+			/* TODO: give user a message maybe? */
+			return;
+		}
+	}
+
+	SHELLEXECUTEINFO execInfo;
+
+	ZeroMemory(&execInfo, sizeof(execInfo));
+
+	execInfo.cbSize      = sizeof(execInfo);
+	execInfo.lpFile      = obsPath;
+	execInfo.lpDirectory = newCwd;
+	execInfo.nShow       = SW_SHOWNORMAL;
+
+	ShellExecuteEx(&execInfo);
+}
+
+static INT_PTR CALLBACK UpdateDialogProc(HWND hwnd, UINT message,
+		WPARAM wParam, LPARAM lParam)
+{
+	switch (message) {
+	case WM_INITDIALOG: {
+		static HICON hMainIcon = LoadIcon(hinstMain,
+				MAKEINTRESOURCE(IDI_ICON1));
+		SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hMainIcon);
+		SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hMainIcon);
+		return true;
+	}
+
+	case WM_COMMAND:
+		if (LOWORD(wParam) == IDC_BUTTON) {
+			if (HIWORD(wParam) == BN_CLICKED) {
+				DWORD result = WaitForSingleObject(
+						updateThread, 0);
+				if (result == WAIT_OBJECT_0) {
+					if (updateFailed)
+						PostQuitMessage(0);
+					else
+						PostQuitMessage(1);
+				} else {
+					EnableWindow((HWND)lParam, false);
+					CancelUpdate(false);
+				}
+			}
+		}
+		return true;
+
+	case WM_CLOSE:
+		CancelUpdate(true);
+		return true;
+	}
+
+	return false;
+}
+
+static void RestartAsAdmin(LPWSTR lpCmdLine)
+{
+	wchar_t myPath[MAX_PATH];
+	if (!GetModuleFileNameW(nullptr, myPath, _countof(myPath) - 1)) {
+		return;
+	}
+
+	wchar_t cwd[MAX_PATH];
+	GetCurrentDirectoryW(_countof(cwd) - 1, cwd);
+
+	SHELLEXECUTEINFO shExInfo = {0};
+	shExInfo.cbSize           = sizeof(shExInfo);
+	shExInfo.fMask            = SEE_MASK_NOCLOSEPROCESS;
+	shExInfo.hwnd             = 0;
+	shExInfo.lpVerb           = L"runas";  /* Operation to perform */
+	shExInfo.lpFile           = myPath;    /* Application to start */
+	shExInfo.lpParameters     = lpCmdLine; /* Additional parameters */
+	shExInfo.lpDirectory      = cwd;
+	shExInfo.nShow            = SW_NORMAL;
+	shExInfo.hInstApp         = 0;
+
+	/* annoyingly the actual elevated updater will disappear behind other
+	 * windows :( */
+	AllowSetForegroundWindow(ASFW_ANY);
+
+	if (ShellExecuteEx(&shExInfo)) {
+		DWORD exitCode;
+
+		if (GetExitCodeProcess(shExInfo.hProcess, &exitCode)) {
+			if (exitCode == 1) {
+				LaunchOBS();
+			}
+		}
+		CloseHandle(shExInfo.hProcess);
+	}
+}
+
+int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
+{
+	INITCOMMONCONTROLSEX icce;
+
+	if (!IsAppRunningAsAdminMode()) {
+		HANDLE hLowMutex = CreateMutexW(nullptr, true,
+				L"OBSUpdaterRunningAsNonAdminUser");
+
+		RestartAsAdmin(lpCmdLine);
+
+		if (hLowMutex) {
+			ReleaseMutex(hLowMutex);
+			CloseHandle(hLowMutex);
+		}
+
+		return 0;
+	} else {
+		{
+			wchar_t cwd[MAX_PATH];
+			wchar_t newPath[MAX_PATH];
+			GetCurrentDirectoryW(_countof(cwd) - 1, cwd);
+
+			is32bit = wcsstr(cwd, L"bin\\32bit") != nullptr;
+			StringCbCat(cwd, sizeof(cwd), L"\\..\\..");
+
+			GetFullPathName(cwd, _countof(newPath), newPath,
+					nullptr);
+			SetCurrentDirectory(newPath);
+		}
+
+		hinstMain = hInstance;
+
+		icce.dwSize = sizeof(icce);
+		icce.dwICC  = ICC_PROGRESS_CLASS;
+
+		InitCommonControlsEx(&icce);
+
+		hwndMain = CreateDialog(hInstance,
+				MAKEINTRESOURCE(IDD_UPDATEDIALOG), nullptr,
+				UpdateDialogProc);
+		if (!hwndMain) {
+			return -1;
+		}
+
+		ShowWindow(hwndMain, SW_SHOWNORMAL);
+		SetForegroundWindow(hwndMain);
+
+		cancelRequested = CreateEvent(nullptr, true, false, nullptr);
+		updateThread = CreateThread(nullptr, 0, UpdateThread,
+				lpCmdLine, 0, nullptr);
+
+		MSG msg;
+		while (GetMessage(&msg, nullptr, 0, 0)) {
+			if (!IsDialogMessage(hwndMain, &msg)) {
+				TranslateMessage(&msg);
+				DispatchMessage(&msg);
+			}
+		}
+
+		/* there is no non-elevated process waiting for us if UAC is
+		 * disabled */
+		WinHandle hMutex = OpenMutex(SYNCHRONIZE, false,
+				L"OBSUpdaterRunningAsNonAdminUser");
+		if (msg.wParam == 1 && !hMutex) {
+			LaunchOBS();
+		}
+
+		return (int)msg.wParam;
+	}
+}
diff --git a/UI/win-update/updater/updater.hpp b/UI/win-update/updater/updater.hpp
new file mode 100644
index 0000000..5f1abd7
--- /dev/null
+++ b/UI/win-update/updater/updater.hpp
@@ -0,0 +1,103 @@
+#pragma once
+
+#define WINVER 0x0600
+#define _WIN32_WINDOWS 0x0600
+#define _WIN32_WINNT 0x0600
+#define WIN32_LEAN_AND_MEAN
+
+#define ZLIB_CONST
+
+#include <windows.h>
+#include <winhttp.h>
+#include <commctrl.h>
+#include <Wincrypt.h>
+#include <shlobj.h>
+#include <shellapi.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <tchar.h>
+#include <strsafe.h>
+#include <zlib.h>
+#include <ctype.h>
+#include <blake2.h>
+
+#include <string>
+
+#include "../win-update-helpers.hpp"
+
+#define BLAKE2_HASH_LENGTH 20
+#define BLAKE2_HASH_STR_LENGTH ((BLAKE2_HASH_LENGTH * 2) + 1)
+
+#if defined _M_IX86
+#pragma comment(linker, \
+                "/manifestdependency:\"type='win32' " \
+                "name='Microsoft.Windows.Common-Controls' " \
+                "version='6.0.0.0' " \
+                "processorArchitecture='x86' " \
+                "publicKeyToken='6595b64144ccf1df' " \
+                "language='*'\"")
+#elif defined _M_IA64
+#pragma comment(linker, \
+                "/manifestdependency:\"type='win32' " \
+                "name='Microsoft.Windows.Common-Controls' " \
+                "version='6.0.0.0' " \
+                "processorArchitecture='ia64' " \
+                "publicKeyToken='6595b64144ccf1df' " \
+                "language='*'\"")
+#elif defined _M_X64
+#pragma comment(linker, \
+                "/manifestdependency:\"type='win32' " \
+                "name='Microsoft.Windows.Common-Controls' " \
+                "version='6.0.0.0' " \
+                "processorArchitecture='amd64' " \
+                "publicKeyToken='6595b64144ccf1df' " \
+                "language='*'\"")
+#else
+#pragma comment(linker, \
+                "/manifestdependency:\"type='win32' " \
+                "name='Microsoft.Windows.Common-Controls' " \
+                "version='6.0.0.0' processorArchitecture='*' " \
+                "publicKeyToken='6595b64144ccf1df' " \
+                "language='*'\"")
+#endif
+
+#include <util/windows/WinHandle.hpp>
+#include <jansson.h>
+#include "resource.h"
+
+bool HTTPGetFile(HINTERNET      hConnect,
+                 const wchar_t *url,
+                 const wchar_t *outputPath,
+                 const wchar_t *extraHeaders,
+                 int *          responseCode);
+bool HTTPPostData(const wchar_t *url,
+                  const BYTE *   data,
+                  int            dataLen,
+                  const wchar_t *extraHeaders,
+                  int *          responseCode,
+                  std::string &  response);
+
+void HashToString(const BYTE *in, wchar_t *out);
+void StringToHash(const wchar_t *in, BYTE *out);
+
+bool CalculateFileHash(const wchar_t *path, BYTE *hash);
+
+int ApplyPatch(LPCTSTR patchFile, LPCTSTR targetFile);
+
+extern HWND       hwndMain;
+extern HCRYPTPROV hProvider;
+extern int        totalFileSize;
+extern int        completedFileSize;
+extern HANDLE     cancelRequested;
+
+#pragma pack(push, r1, 1)
+
+typedef struct {
+	BLOBHEADER blobheader;
+	RSAPUBKEY  rsapubkey;
+} PUBLICKEYHEADER;
+
+#pragma pack(pop, r1)
+
+void FreeWinHttpHandle(HINTERNET handle);
+using HttpHandle = CustomHandle<HINTERNET, FreeWinHttpHandle>;
diff --git a/UI/win-update/updater/updater.rc b/UI/win-update/updater/updater.rc
new file mode 100644
index 0000000..c099f5c
--- /dev/null
+++ b/UI/win-update/updater/updater.rc
@@ -0,0 +1,145 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_UPDATEDIALOG DIALOGEX 0, 0, 316, 56
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "OBS Studio Update"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    PUSHBUTTON      "Cancel",IDC_BUTTON,259,34,50,14
+    CONTROL         "",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH,7,17,302,14
+    LTEXT           "Waiting for OBS to exit...",IDC_STATUS,7,7,302,8,SS_WORDELLIPSIS
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+    IDD_UPDATEDIALOG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 309
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 48
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", "obsproject.com"
+            VALUE "FileDescription", "OBS Updater"
+            VALUE "FileVersion", "1.0.0.1"
+            VALUE "InternalName", "updater.exe"
+            VALUE "LegalCopyright", "Copyright (C) 2013 Richard Stanway"
+            VALUE "OriginalFilename", "updater.exe"
+            VALUE "ProductName", "OBS Updater"
+            VALUE "ProductVersion", "1.0.0.1"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1               ICON                    "../../../cmake/winrc/obs-studio.ico"
+#endif    // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/UI/win-update/win-update-helpers.cpp b/UI/win-update/win-update-helpers.cpp
new file mode 100644
index 0000000..b969e32
--- /dev/null
+++ b/UI/win-update/win-update-helpers.cpp
@@ -0,0 +1,40 @@
+#include "win-update-helpers.hpp"
+
+void FreeProvider(HCRYPTPROV prov)
+{
+	CryptReleaseContext(prov, 0);
+}
+
+void FreeHash(HCRYPTHASH hash)
+{
+	CryptDestroyHash(hash);
+}
+
+void FreeKey(HCRYPTKEY key)
+{
+	CryptDestroyKey(key);
+}
+
+std::string vstrprintf(const char *format, va_list args)
+{
+	if (!format)
+		return std::string();
+
+	std::string str;
+	int size = (int)vsnprintf(nullptr, 0, format, args);
+	str.resize(size);
+	vsnprintf(&str[0], size, format, args);
+	return str;
+}
+
+std::string strprintf(const char *format, ...)
+{
+	std::string str;
+	va_list args;
+
+	va_start(args, format);
+	str = vstrprintf(format, args);
+	va_end(args);
+
+	return str;
+}
diff --git a/UI/win-update/win-update-helpers.hpp b/UI/win-update/win-update-helpers.hpp
new file mode 100644
index 0000000..51ea16a
--- /dev/null
+++ b/UI/win-update/win-update-helpers.hpp
@@ -0,0 +1,139 @@
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <Wincrypt.h>
+
+#include <jansson.h>
+
+#include <cstdint>
+#include <string>
+
+/* ------------------------------------------------------------------------ */
+
+template<typename T, void freefunc(T)> class CustomHandle {
+	T handle;
+
+public:
+	inline CustomHandle() : handle(0) {}
+	inline CustomHandle(T in) : handle(in) {}
+	inline ~CustomHandle()
+	{
+		if (handle)
+			freefunc(handle);
+	}
+
+	inline T *operator&() {return &handle;}
+	inline operator T() const {return handle;}
+	inline T get() const {return handle;}
+
+	inline CustomHandle<T, freefunc> &operator=(T in)
+	{
+		if (handle)
+			freefunc(handle);
+		handle = in;
+		return *this;
+	}
+
+	inline bool operator!() const {return !handle;}
+};
+
+void FreeProvider(HCRYPTPROV prov);
+void FreeHash(HCRYPTHASH hash);
+void FreeKey(HCRYPTKEY key);
+
+using CryptProvider = CustomHandle<HCRYPTPROV, FreeProvider>;
+using CryptHash     = CustomHandle<HCRYPTHASH, FreeHash>;
+using CryptKey      = CustomHandle<HCRYPTKEY,  FreeKey>;
+
+/* ------------------------------------------------------------------------ */
+
+template<typename T> class LocalPtr {
+	T *ptr = nullptr;
+
+public:
+	inline ~LocalPtr()
+	{
+		if (ptr)
+			LocalFree(ptr);
+	}
+
+	inline T **operator&() {return &ptr;}
+	inline operator T() const {return ptr;}
+	inline T *get() const {return ptr;}
+
+	inline bool operator!() const {return !ptr;}
+
+	inline T *operator->() {return ptr;}
+};
+
+/* ------------------------------------------------------------------------ */
+
+class Json {
+	json_t *json;
+
+public:
+	inline Json() : json(nullptr) {}
+	explicit inline Json(json_t *json_) : json(json_) {}
+	inline Json(const Json &from) : json(json_incref(from.json)) {}
+	inline Json(Json &&from) : json(from.json) {from.json = nullptr;}
+
+	inline ~Json() {
+		if (json)
+			json_decref(json);
+	}
+
+	inline Json &operator=(json_t *json_)
+	{
+		if (json)
+			json_decref(json);
+		json = json_;
+		return *this;
+	}
+	inline Json &operator=(const Json &from)
+	{
+		if (json)
+			json_decref(json);
+		json = json_incref(from.json);
+		return *this;
+	}
+	inline Json &operator=(Json &&from)
+	{
+		if (json)
+			json_decref(json);
+		json = from.json;
+		from.json = nullptr;
+		return *this;
+	}
+
+	inline operator json_t *() const {return json;}
+
+	inline bool operator!() const {return !json;}
+
+	inline const char *GetString(const char *name,
+			const char *def = nullptr) const
+	{
+		json_t *obj(json_object_get(json, name));
+		if (!obj)
+			return def;
+		return json_string_value(obj);
+	}
+	inline int64_t GetInt(const char *name, int def = 0) const
+	{
+		json_t *obj(json_object_get(json, name));
+		if (!obj)
+			return def;
+		return json_integer_value(obj);
+	}
+	inline json_t *GetObject(const char *name) const
+	{
+		return json_object_get(json, name);
+	}
+
+	inline json_t *get() const {return json;}
+};
+
+/* ------------------------------------------------------------------------ */
+
+std::string vstrprintf(const char *format, va_list args);
+std::string strprintf(const char *format, ...);
diff --git a/UI/win-update/win-update.cpp b/UI/win-update/win-update.cpp
new file mode 100644
index 0000000..6cfec73
--- /dev/null
+++ b/UI/win-update/win-update.cpp
@@ -0,0 +1,781 @@
+#include "win-update-helpers.hpp"
+#include "update-window.hpp"
+#include "remote-text.hpp"
+#include "win-update.hpp"
+#include "obs-app.hpp"
+
+#include <QMessageBox>
+
+#include <string>
+
+#include <util/windows/WinHandle.hpp>
+#include <util/util.hpp>
+#include <jansson.h>
+#include <blake2.h>
+
+#include <time.h>
+#include <strsafe.h>
+#include <winhttp.h>
+#include <shellapi.h>
+
+using namespace std;
+
+/* ------------------------------------------------------------------------ */
+
+#ifndef WIN_MANIFEST_URL
+#define WIN_MANIFEST_URL "https://obsproject.com/update_studio/manifest.json"
+#endif
+
+#ifndef WIN_UPDATER_URL
+#define WIN_UPDATER_URL "https://obsproject.com/update_studio/updater.exe"
+#endif
+
+static HCRYPTPROV provider = 0;
+
+#pragma pack(push, r1, 1)
+
+typedef struct {
+	BLOBHEADER blobheader;
+	RSAPUBKEY  rsapubkey;
+} PUBLICKEYHEADER;
+
+#pragma pack(pop, r1)
+
+#define BLAKE2_HASH_LENGTH 20
+#define BLAKE2_HASH_STR_LENGTH ((BLAKE2_HASH_LENGTH * 2) + 1)
+
+#define TEST_BUILD
+
+// Hard coded 4096 bit RSA public key for obsproject.com in PEM format
+static const unsigned char obs_pub[] = {
+	0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50,
+	0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d,
+	0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x49, 0x6a, 0x41, 0x4e, 0x42,
+	0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+	0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x67, 0x38, 0x41, 0x4d,
+	0x49, 0x49, 0x43, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x67, 0x45, 0x41, 0x6c,
+	0x33, 0x73, 0x76, 0x65, 0x72, 0x77, 0x39, 0x48, 0x51, 0x2b, 0x72, 0x59,
+	0x51, 0x4e, 0x6e, 0x39, 0x43, 0x61, 0x37, 0x0a, 0x39, 0x4c, 0x55, 0x36,
+	0x32, 0x6e, 0x47, 0x36, 0x4e, 0x6f, 0x7a, 0x45, 0x2f, 0x46, 0x73, 0x49,
+	0x56, 0x4e, 0x65, 0x72, 0x2b, 0x57, 0x2f, 0x68, 0x75, 0x65, 0x45, 0x38,
+	0x57, 0x51, 0x31, 0x6d, 0x72, 0x46, 0x50, 0x2b, 0x32, 0x79, 0x41, 0x2b,
+	0x69, 0x59, 0x52, 0x75, 0x74, 0x59, 0x50, 0x65, 0x45, 0x67, 0x70, 0x78,
+	0x74, 0x6f, 0x64, 0x48, 0x68, 0x67, 0x6b, 0x52, 0x34, 0x70, 0x45, 0x4b,
+	0x0a, 0x56, 0x6e, 0x72, 0x72, 0x31, 0x38, 0x71, 0x34, 0x73, 0x7a, 0x6c,
+	0x76, 0x38, 0x39, 0x51, 0x49, 0x37, 0x74, 0x38, 0x6c, 0x4d, 0x6f, 0x4c,
+	0x54, 0x6c, 0x46, 0x2b, 0x74, 0x31, 0x49, 0x52, 0x30, 0x56, 0x34, 0x77,
+	0x4a, 0x56, 0x33, 0x34, 0x49, 0x33, 0x43, 0x2b, 0x33, 0x35, 0x39, 0x4b,
+	0x69, 0x78, 0x6e, 0x7a, 0x4c, 0x30, 0x42, 0x6c, 0x39, 0x61, 0x6a, 0x2f,
+	0x7a, 0x44, 0x63, 0x72, 0x58, 0x0a, 0x57, 0x6c, 0x35, 0x70, 0x48, 0x54,
+	0x69, 0x6f, 0x4a, 0x77, 0x59, 0x4f, 0x67, 0x4d, 0x69, 0x42, 0x47, 0x4c,
+	0x79, 0x50, 0x65, 0x69, 0x74, 0x4d, 0x46, 0x64, 0x6a, 0x6a, 0x54, 0x49,
+	0x70, 0x43, 0x4d, 0x2b, 0x6d, 0x78, 0x54, 0x57, 0x58, 0x43, 0x72, 0x5a,
+	0x39, 0x64, 0x50, 0x55, 0x4b, 0x76, 0x5a, 0x74, 0x67, 0x7a, 0x6a, 0x64,
+	0x2b, 0x49, 0x7a, 0x6c, 0x48, 0x69, 0x64, 0x48, 0x74, 0x4f, 0x0a, 0x4f,
+	0x52, 0x42, 0x4e, 0x35, 0x6d, 0x52, 0x73, 0x38, 0x4c, 0x4e, 0x4f, 0x35,
+	0x38, 0x6b, 0x37, 0x39, 0x72, 0x37, 0x37, 0x44, 0x63, 0x67, 0x51, 0x59,
+	0x50, 0x4e, 0x69, 0x69, 0x43, 0x74, 0x57, 0x67, 0x43, 0x2b, 0x59, 0x34,
+	0x4b, 0x37, 0x75, 0x53, 0x5a, 0x58, 0x33, 0x48, 0x76, 0x65, 0x6f, 0x6d,
+	0x32, 0x74, 0x48, 0x62, 0x56, 0x58, 0x79, 0x30, 0x4c, 0x2f, 0x43, 0x6c,
+	0x37, 0x66, 0x4d, 0x0a, 0x48, 0x4b, 0x71, 0x66, 0x63, 0x51, 0x47, 0x75,
+	0x79, 0x72, 0x76, 0x75, 0x64, 0x34, 0x32, 0x4f, 0x72, 0x57, 0x61, 0x72,
+	0x41, 0x73, 0x6e, 0x32, 0x70, 0x32, 0x45, 0x69, 0x36, 0x4b, 0x7a, 0x78,
+	0x62, 0x33, 0x47, 0x36, 0x45, 0x53, 0x43, 0x77, 0x31, 0x35, 0x6e, 0x48,
+	0x41, 0x67, 0x4c, 0x61, 0x6c, 0x38, 0x7a, 0x53, 0x71, 0x37, 0x2b, 0x72,
+	0x61, 0x45, 0x2f, 0x78, 0x6b, 0x4c, 0x70, 0x43, 0x0a, 0x62, 0x59, 0x67,
+	0x35, 0x67, 0x6d, 0x59, 0x36, 0x76, 0x62, 0x6d, 0x57, 0x6e, 0x71, 0x39,
+	0x64, 0x71, 0x57, 0x72, 0x55, 0x7a, 0x61, 0x71, 0x4f, 0x66, 0x72, 0x5a,
+	0x50, 0x67, 0x76, 0x67, 0x47, 0x30, 0x57, 0x76, 0x6b, 0x42, 0x53, 0x68,
+	0x66, 0x61, 0x45, 0x4f, 0x42, 0x61, 0x49, 0x55, 0x78, 0x41, 0x33, 0x51,
+	0x42, 0x67, 0x7a, 0x41, 0x5a, 0x68, 0x71, 0x65, 0x65, 0x64, 0x46, 0x39,
+	0x68, 0x0a, 0x61, 0x66, 0x4d, 0x47, 0x4d, 0x4d, 0x39, 0x71, 0x56, 0x62,
+	0x66, 0x77, 0x75, 0x75, 0x7a, 0x4a, 0x32, 0x75, 0x68, 0x2b, 0x49, 0x6e,
+	0x61, 0x47, 0x61, 0x65, 0x48, 0x32, 0x63, 0x30, 0x34, 0x6f, 0x56, 0x63,
+	0x44, 0x46, 0x66, 0x65, 0x4f, 0x61, 0x44, 0x75, 0x78, 0x52, 0x6a, 0x43,
+	0x43, 0x62, 0x71, 0x72, 0x35, 0x73, 0x4c, 0x53, 0x6f, 0x31, 0x43, 0x57,
+	0x6f, 0x6b, 0x79, 0x6e, 0x6a, 0x4e, 0x0a, 0x43, 0x42, 0x2b, 0x62, 0x32,
+	0x72, 0x51, 0x46, 0x37, 0x44, 0x50, 0x50, 0x62, 0x44, 0x34, 0x73, 0x2f,
+	0x6e, 0x54, 0x39, 0x4e, 0x73, 0x63, 0x6b, 0x2f, 0x4e, 0x46, 0x7a, 0x72,
+	0x42, 0x58, 0x52, 0x4f, 0x2b, 0x64, 0x71, 0x6b, 0x65, 0x42, 0x77, 0x44,
+	0x55, 0x43, 0x76, 0x37, 0x62, 0x5a, 0x67, 0x57, 0x37, 0x4f, 0x78, 0x75,
+	0x4f, 0x58, 0x30, 0x37, 0x4c, 0x54, 0x71, 0x66, 0x70, 0x35, 0x73, 0x0a,
+	0x4f, 0x65, 0x47, 0x67, 0x75, 0x62, 0x75, 0x62, 0x69, 0x77, 0x59, 0x33,
+	0x55, 0x64, 0x48, 0x59, 0x71, 0x2b, 0x4c, 0x39, 0x4a, 0x71, 0x49, 0x53,
+	0x47, 0x31, 0x74, 0x4d, 0x34, 0x48, 0x65, 0x4b, 0x6a, 0x61, 0x48, 0x6a,
+	0x75, 0x31, 0x4d, 0x44, 0x6a, 0x76, 0x48, 0x5a, 0x32, 0x44, 0x62, 0x6d,
+	0x4c, 0x77, 0x55, 0x78, 0x75, 0x59, 0x61, 0x36, 0x4a, 0x5a, 0x44, 0x4b,
+	0x57, 0x73, 0x37, 0x72, 0x0a, 0x49, 0x72, 0x64, 0x44, 0x77, 0x78, 0x33,
+	0x4a, 0x77, 0x61, 0x63, 0x46, 0x36, 0x36, 0x68, 0x33, 0x59, 0x55, 0x57,
+	0x36, 0x74, 0x7a, 0x55, 0x5a, 0x68, 0x7a, 0x74, 0x63, 0x6d, 0x51, 0x65,
+	0x70, 0x50, 0x2f, 0x75, 0x37, 0x42, 0x67, 0x47, 0x72, 0x6b, 0x4f, 0x50,
+	0x50, 0x70, 0x59, 0x41, 0x30, 0x4e, 0x45, 0x4a, 0x38, 0x30, 0x53, 0x65,
+	0x41, 0x78, 0x37, 0x68, 0x69, 0x4e, 0x34, 0x76, 0x61, 0x0a, 0x65, 0x45,
+	0x51, 0x4b, 0x6e, 0x52, 0x6e, 0x2b, 0x45, 0x70, 0x42, 0x4e, 0x36, 0x55,
+	0x42, 0x61, 0x35, 0x66, 0x37, 0x4c, 0x6f, 0x4b, 0x38, 0x43, 0x41, 0x77,
+	0x45, 0x41, 0x41, 0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+	0x45, 0x4e, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b,
+	0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a
+};
+static const unsigned int obs_pub_len = 800;
+
+/* ------------------------------------------------------------------------ */
+
+static bool QuickWriteFile(const char *file, const void *data, size_t size)
+try {
+	BPtr<wchar_t> w_file;
+	if (os_utf8_to_wcs_ptr(file, 0, &w_file) == 0)
+		return false;
+
+	WinHandle handle = CreateFileW(
+			w_file,
+			GENERIC_WRITE,
+			0,
+			nullptr,
+			CREATE_ALWAYS,
+			FILE_FLAG_WRITE_THROUGH,
+			nullptr);
+
+	if (handle == INVALID_HANDLE_VALUE)
+		throw strprintf("Failed to open file '%s': %lu",
+				file, GetLastError());
+
+	DWORD written;
+	if (!WriteFile(handle, data, (DWORD)size, &written, nullptr))
+		throw strprintf("Failed to write file '%s': %lu",
+				file, GetLastError());
+
+	return true;
+
+} catch (string text) {
+	blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str());
+	return false;
+}
+
+static bool QuickReadFile(const char *file, string &data)
+try {
+	BPtr<wchar_t> w_file;
+	if (os_utf8_to_wcs_ptr(file, 0, &w_file) == 0)
+		return false;
+
+	WinHandle handle = CreateFileW(
+			w_file,
+			GENERIC_READ,
+			FILE_SHARE_READ,
+			nullptr,
+			OPEN_EXISTING,
+			0,
+			nullptr);
+
+	if (handle == INVALID_HANDLE_VALUE)
+		throw strprintf("Failed to open file '%s': %lu",
+				file, GetLastError());
+
+	DWORD size = GetFileSize(handle, nullptr);
+	data.resize(size);
+
+	DWORD read;
+	if (!ReadFile(handle, &data[0], size, &read, nullptr))
+		throw strprintf("Failed to write file '%s': %lu",
+				file, GetLastError());
+
+	return true;
+
+} catch (string text) {
+	blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str());
+	return false;
+}
+
+static void HashToString(const uint8_t *in, char *out)
+{
+	const char alphabet[] = "0123456789abcdef";
+
+	for (int i = 0; i != BLAKE2_HASH_LENGTH; ++i) {
+		out[2 * i]     = alphabet[in[i] / 16];
+		out[2 * i + 1] = alphabet[in[i] % 16];
+	}
+
+	out[BLAKE2_HASH_LENGTH * 2] = 0;
+}
+
+static bool CalculateFileHash(const char *path, uint8_t *hash)
+try {
+	blake2b_state blake2;
+	if (blake2b_init(&blake2, BLAKE2_HASH_LENGTH) != 0)
+		return false;
+
+	BPtr<wchar_t> w_path;
+	if (os_utf8_to_wcs_ptr(path, 0, &w_path) == 0)
+		return false;
+
+	WinHandle handle = CreateFileW(w_path, GENERIC_READ, FILE_SHARE_READ,
+			nullptr, OPEN_EXISTING, 0, nullptr);
+	if (handle == INVALID_HANDLE_VALUE)
+		throw strprintf("Failed to open file '%s': %lu",
+				path, GetLastError());
+
+	vector<BYTE> buf;
+	buf.resize(65536);
+
+	for (;;) {
+		DWORD read = 0;
+		if (!ReadFile(handle, buf.data(), (DWORD)buf.size(), &read,
+					nullptr))
+			throw strprintf("Failed to read file '%s': %lu",
+					path, GetLastError());
+
+		if (!read)
+			break;
+
+		if (blake2b_update(&blake2, buf.data(), read) != 0)
+			return false;
+	}
+
+	if (blake2b_final(&blake2, hash, BLAKE2_HASH_LENGTH) != 0)
+		return false;
+
+	return true;
+
+} catch (string text) {
+	blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str());
+	return false;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig,
+		size_t sigLen)
+{
+	/* ASN of PEM public key */
+	BYTE  binaryKey[1024];
+	DWORD binaryKeyLen = sizeof(binaryKey);
+
+	/* Windows X509 public key info from ASN */
+	LocalPtr<CERT_PUBLIC_KEY_INFO> publicPBLOB;
+	DWORD                          iPBLOBSize;
+
+	/* RSA BLOB info from X509 public key */
+	LocalPtr<PUBLICKEYHEADER> rsaPublicBLOB;
+	DWORD                     rsaPublicBLOBSize;
+
+	/* Handle to public key */
+	CryptKey keyOut;
+
+	/* Handle to hash context */
+	CryptHash hash;
+
+	/* Signature in little-endian format */
+	vector<BYTE> reversedSig;
+
+	if (!CryptStringToBinaryA((LPCSTR)obs_pub,
+	                          obs_pub_len,
+	                          CRYPT_STRING_BASE64HEADER,
+	                          binaryKey,
+	                          &binaryKeyLen,
+	                          nullptr,
+	                          nullptr))
+		return false;
+
+	if (!CryptDecodeObjectEx(X509_ASN_ENCODING,
+	                         X509_PUBLIC_KEY_INFO,
+	                         binaryKey,
+	                         binaryKeyLen,
+	                         CRYPT_ENCODE_ALLOC_FLAG,
+	                         nullptr,
+	                         &publicPBLOB,
+	                         &iPBLOBSize))
+		return false;
+
+	if (!CryptDecodeObjectEx(X509_ASN_ENCODING,
+	                         RSA_CSP_PUBLICKEYBLOB,
+	                         publicPBLOB->PublicKey.pbData,
+	                         publicPBLOB->PublicKey.cbData,
+	                         CRYPT_ENCODE_ALLOC_FLAG,
+	                         nullptr,
+	                         &rsaPublicBLOB,
+	                         &rsaPublicBLOBSize))
+		return false;
+
+	if (!CryptImportKey(provider,
+	                    (const BYTE *)rsaPublicBLOB.get(),
+	                    rsaPublicBLOBSize,
+	                    0,
+	                    0,
+	                    &keyOut))
+		return false;
+
+	if (!CryptCreateHash(provider, CALG_SHA_512, 0, 0, &hash))
+		return false;
+
+	if (!CryptHashData(hash, buf, (DWORD)len, 0))
+		return false;
+
+	/* Windows requires signature in little-endian. Every other crypto
+	 * provider is big-endian of course. */
+	reversedSig.resize(sigLen);
+	for (size_t i = 0; i < sigLen; i++)
+		reversedSig[i] = sig[sigLen - i - 1];
+
+	if (!CryptVerifySignature(hash,
+	                          reversedSig.data(),
+	                          (DWORD)sigLen,
+	                          keyOut,
+	                          nullptr,
+	                          0))
+		return false;
+
+	return true;
+}
+
+static inline void HexToByteArray(const char *hexStr, size_t hexLen,
+		vector<uint8_t> &out)
+{
+	char ptr[3];
+
+	ptr[2] = 0;
+
+	for (size_t i = 0; i < hexLen; i += 2) {
+		ptr[0] = hexStr[i];
+		ptr[1] = hexStr[i + 1];
+		out.push_back((uint8_t)strtoul(ptr, nullptr, 16));
+	}
+}
+
+static bool CheckDataSignature(const string &data, const char *name,
+		const char *hexSig, size_t sigLen)
+try {
+	if (sigLen == 0 || sigLen > 0xFFFF || (sigLen & 1) != 0)
+		throw strprintf("Missing or invalid signature for %s", name);
+
+	/* Convert TCHAR signature to byte array */
+	vector<uint8_t> signature;
+	signature.reserve(sigLen);
+	HexToByteArray(hexSig, sigLen, signature);
+
+	if (!VerifyDigitalSignature((uint8_t*)data.data(),
+	                            data.size(),
+	                            signature.data(),
+	                            signature.size()))
+		throw strprintf("Signature check failed for %s", name);
+
+	return true;
+
+} catch (string text) {
+	blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str());
+	return false;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static bool FetchUpdaterModule(const char *url)
+try {
+	long     responseCode;
+	uint8_t  updateFileHash[BLAKE2_HASH_LENGTH];
+	vector<string> extraHeaders;
+
+	BPtr<char> updateFilePath = GetConfigPathPtr(
+			"obs-studio\\updates\\updater.exe");
+
+	if (CalculateFileHash(updateFilePath, updateFileHash)) {
+		char hashString[BLAKE2_HASH_STR_LENGTH];
+		HashToString(updateFileHash, hashString);
+
+		string header = "If-None-Match: ";
+		header += hashString;
+		extraHeaders.push_back(move(header));
+	}
+
+	string signature;
+	string error;
+	string data;
+
+	bool success = GetRemoteFile(url, data, error, &responseCode,
+			nullptr, nullptr, extraHeaders, &signature);
+
+	if (!success || (responseCode != 200 && responseCode != 304)) {
+		if (responseCode == 404)
+			return false;
+
+		throw strprintf("Could not fetch '%s': %s", url, error.c_str());
+	}
+
+	/* A new file must be digitally signed */
+	if (responseCode == 200) {
+		bool valid = CheckDataSignature(data, url, signature.data(),
+				signature.size());
+		if (!valid)
+			throw string("Invalid updater module signature");
+
+		if (!QuickWriteFile(updateFilePath, data.data(), data.size()))
+			return false;
+	}
+
+	return true;
+
+} catch (string text) {
+	blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str());
+	return false;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static bool ParseUpdateManifest(const char *manifest, bool *updatesAvailable,
+		string &notes_str, int &updateVer)
+try {
+
+	json_error_t error;
+	Json root(json_loads(manifest, 0, &error));
+	if (!root)
+		throw strprintf("Failed reading json string (%d): %s",
+				error.line, error.text);
+
+	if (!json_is_object(root.get()))
+		throw string("Root of manifest is not an object");
+
+	int major = root.GetInt("version_major");
+	int minor = root.GetInt("version_minor");
+	int patch = root.GetInt("version_patch");
+
+	if (major == 0)
+		throw strprintf("Invalid version number: %d.%d.%d",
+				major,
+				minor,
+				patch);
+
+	json_t *notes = json_object_get(root, "notes");
+	if (!json_is_string(notes))
+		throw string("'notes' value invalid");
+
+	notes_str = json_string_value(notes);
+
+	json_t *packages = json_object_get(root, "packages");
+	if (!json_is_array(packages))
+		throw string("'packages' value invalid");
+
+	int cur_ver = LIBOBS_API_VER;
+	int new_ver = MAKE_SEMANTIC_VERSION(major, minor, patch);
+
+	updateVer = new_ver;
+	*updatesAvailable = new_ver > cur_ver;
+
+	return true;
+
+} catch (string text) {
+	blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str());
+	return false;
+}
+
+/* ------------------------------------------------------------------------ */
+
+void GenerateGUID(string &guid)
+{
+	BYTE junk[20];
+
+	if (!CryptGenRandom(provider, sizeof(junk), junk))
+		return;
+
+	guid.resize(41);
+	HashToString(junk, &guid[0]);
+}
+
+void AutoUpdateThread::infoMsg(const QString &title, const QString &text)
+{
+	QMessageBox::information(App()->GetMainWindow(), title, text);
+}
+
+void AutoUpdateThread::info(const QString &title, const QString &text)
+{
+	QMetaObject::invokeMethod(this, "infoMsg",
+			Qt::BlockingQueuedConnection,
+			Q_ARG(QString, title),
+			Q_ARG(QString, text));
+}
+
+int AutoUpdateThread::queryUpdateSlot(bool manualUpdate, const QString &text)
+{
+	OBSUpdate updateDlg(App()->GetMainWindow(), manualUpdate, text);
+	return updateDlg.exec();
+}
+
+int AutoUpdateThread::queryUpdate(bool manualUpdate, const char *text_utf8)
+{
+	int ret = OBSUpdate::No;
+	QString text = text_utf8;
+	QMetaObject::invokeMethod(this, "queryUpdateSlot",
+			Qt::BlockingQueuedConnection,
+			Q_RETURN_ARG(int, ret),
+			Q_ARG(bool, manualUpdate),
+			Q_ARG(QString, text));
+	return ret;
+}
+
+static bool IsFileInUse(const wstring &file)
+{
+	WinHandle f = CreateFile(file.c_str(), GENERIC_WRITE, 0, nullptr,
+			OPEN_EXISTING, 0, nullptr);
+	if (!f.Valid()) {
+		int err = GetLastError();
+		if (err == ERROR_SHARING_VIOLATION ||
+		    err == ERROR_LOCK_VIOLATION)
+			return true;
+	}
+
+	return false;
+}
+
+static bool IsGameCaptureInUse()
+{
+	wstring path = L"..\\..\\data\\obs-plugins\\win-capture\\graphics-hook";
+	return IsFileInUse(path + L"32.dll") ||
+	       IsFileInUse(path + L"64.dll");
+}
+
+void AutoUpdateThread::run()
+try {
+	long           responseCode;
+	vector<string> extraHeaders;
+	string         text;
+	string         error;
+	string         signature;
+	CryptProvider  provider;
+	BYTE           manifestHash[BLAKE2_HASH_LENGTH];
+	bool           updatesAvailable = false;
+	bool           success;
+
+	struct FinishedTrigger {
+		inline ~FinishedTrigger()
+		{
+			QMetaObject::invokeMethod(App()->GetMainWindow(),
+					"updateCheckFinished");	
+		}
+	} finishedTrigger;
+
+	BPtr<char> manifestPath = GetConfigPathPtr(
+			"obs-studio\\updates\\manifest.json");
+
+	auto ActiveOrGameCaptureLocked = [this] ()
+	{
+		if (video_output_active(obs_get_video())) {
+			if (manualUpdate)
+				info(QTStr("Updater.Running.Title"),
+				     QTStr("Updater.Running.Text"));
+			return true;
+		}
+		if (IsGameCaptureInUse()) {
+			if (manualUpdate)
+				info(QTStr("Updater.GameCaptureActive.Title"),
+				     QTStr("Updater.GameCaptureActive.Text"));
+			return true;
+		}
+
+		return false;
+	};
+
+	/* ----------------------------------- *
+	 * warn if running or gc locked        */
+
+	if (ActiveOrGameCaptureLocked())
+		return;
+
+	/* ----------------------------------- *
+	 * create signature provider           */
+
+	if (!CryptAcquireContext(&provider,
+	                         nullptr,
+	                         MS_ENH_RSA_AES_PROV,
+	                         PROV_RSA_AES,
+	                         CRYPT_VERIFYCONTEXT))
+		throw strprintf("CryptAcquireContext failed: %lu",
+				GetLastError());
+
+	::provider = provider;
+
+	/* ----------------------------------- *
+	 * avoid downloading manifest again    */
+
+	if (CalculateFileHash(manifestPath, manifestHash)) {
+		char hashString[BLAKE2_HASH_STR_LENGTH];
+		HashToString(manifestHash, hashString);
+
+		string header = "If-None-Match: ";
+		header += hashString;
+		extraHeaders.push_back(move(header));
+	}
+
+	/* ----------------------------------- *
+	 * get current install GUID            */
+
+	/* NOTE: this is an arbitrary random number that we use to count the
+	 * number of unique OBS installations and is not associated with any
+	 * kind of identifiable information */
+	const char *pguid = config_get_string(GetGlobalConfig(),
+			"General", "InstallGUID");
+	string guid;
+	if (pguid)
+		guid = pguid;
+
+	if (guid.empty()) {
+		GenerateGUID(guid);
+
+		if (!guid.empty())
+			config_set_string(GetGlobalConfig(),
+					"General", "InstallGUID",
+					guid.c_str());
+	}
+
+	if (!guid.empty()) {
+		string header = "X-OBS2-GUID: ";
+		header += guid;
+		extraHeaders.push_back(move(header));
+	}
+
+	/* ----------------------------------- *
+	 * get manifest from server            */
+
+	success = GetRemoteFile(WIN_MANIFEST_URL, text, error, &responseCode,
+			nullptr, nullptr, extraHeaders, &signature);
+
+	if (!success || (responseCode != 200 && responseCode != 304)) {
+		if (responseCode == 404)
+			return;
+
+		throw strprintf("Failed to fetch manifest file: %s", error);   
+	}
+
+	/* ----------------------------------- *
+	 * verify file signature               */
+
+	/* a new file must be digitally signed */
+	if (responseCode == 200) {
+		success = CheckDataSignature(text, "manifest",
+				signature.data(), signature.size());
+		if (!success)
+			throw string("Invalid manifest signature");
+	}
+
+	/* ----------------------------------- *
+	 * write or load manifest              */
+
+	if (responseCode == 200) {
+		if (!QuickWriteFile(manifestPath, text.data(), text.size()))
+			throw strprintf("Could not write file '%s'",
+					manifestPath);
+	} else {
+		if (!QuickReadFile(manifestPath, text))
+			throw strprintf("Could not read file '%s'",
+					manifestPath);
+	}
+
+	/* ----------------------------------- *
+	 * check manifest for update           */
+
+	string notes;
+	int updateVer = 0;
+
+	success = ParseUpdateManifest(text.c_str(), &updatesAvailable, notes,
+			updateVer);
+	if (!success)
+		throw string("Failed to parse manifest");
+
+	if (!updatesAvailable) {
+		if (manualUpdate)
+			info(QTStr("Updater.NoUpdatesAvailable.Title"),
+			     QTStr("Updater.NoUpdatesAvailable.Text"));
+		return;
+	}
+
+	/* ----------------------------------- *
+	 * skip this version if set to skip    */
+
+	int skipUpdateVer = config_get_int(GetGlobalConfig(), "General",
+			"SkipUpdateVersion");
+	if (!manualUpdate && updateVer == skipUpdateVer)
+		return;
+
+	/* ----------------------------------- *
+	 * warn again if running or gc locked  */
+
+	if (ActiveOrGameCaptureLocked())
+		return;
+
+	/* ----------------------------------- *
+	 * fetch updater module                */
+
+	if (!FetchUpdaterModule(WIN_UPDATER_URL))
+		return;
+
+	/* ----------------------------------- *
+	 * query user for update               */
+
+	int queryResult = queryUpdate(manualUpdate, notes.c_str());
+
+	if (queryResult == OBSUpdate::No) {
+		if (!manualUpdate) {
+			long long t = (long long)time(nullptr);
+			config_set_int(GetGlobalConfig(), "General",
+					"LastUpdateCheck", t);
+		}
+		return;
+
+	} else if (queryResult == OBSUpdate::Skip) {
+		config_set_int(GetGlobalConfig(), "General",
+				"SkipUpdateVersion", updateVer);
+		return;
+	}
+
+	/* ----------------------------------- *
+	 * get working dir                     */
+
+	wchar_t cwd[MAX_PATH];
+	GetModuleFileNameW(nullptr, cwd, _countof(cwd) - 1);
+	wchar_t *p = wcsrchr(cwd, '\\');
+	if (p)
+		*p = 0;
+
+	/* ----------------------------------- *
+	 * execute updater                     */
+
+	BPtr<char> updateFilePath = GetConfigPathPtr(
+			"obs-studio\\updates\\updater.exe");
+	BPtr<wchar_t> wUpdateFilePath;
+
+	size_t size = os_utf8_to_wcs_ptr(updateFilePath, 0, &wUpdateFilePath);
+	if (!size)
+		throw string("Could not convert updateFilePath to wide");
+
+	/* note, can't use CreateProcess to launch as admin. */
+	SHELLEXECUTEINFO execInfo = {};
+
+	execInfo.cbSize = sizeof(execInfo);
+	execInfo.lpFile = wUpdateFilePath;
+#ifndef UPDATE_CHANNEL
+#define UPDATE_ARG_SUFFIX L""
+#else
+#define UPDATE_ARG_SUFFIX UPDATE_CHANNEL
+#endif
+	if (App()->IsPortableMode())
+		execInfo.lpParameters = UPDATE_ARG_SUFFIX L" Portable";
+	else
+		execInfo.lpParameters = UPDATE_ARG_SUFFIX;
+
+	execInfo.lpDirectory = cwd;
+	execInfo.nShow       = SW_SHOWNORMAL;
+
+	if (!ShellExecuteEx(&execInfo)) {
+		QString msg = QTStr("Updater.FailedToLaunch");
+		info(msg, msg);
+		throw strprintf("Can't launch updater '%s': %d",
+				updateFilePath, GetLastError());
+	}
+
+	/* force OBS to perform another update check immediately after updating
+	 * in case of issues with the new version */
+	config_set_int(GetGlobalConfig(), "General", "LastUpdateCheck", 0);
+	config_set_int(GetGlobalConfig(), "General", "SkipUpdateVersion", 0);
+	config_set_string(GetGlobalConfig(), "General", "InstallGUID",
+			guid.c_str());
+
+	QMetaObject::invokeMethod(App()->GetMainWindow(), "close");
+
+} catch (string text) {
+	blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str());
+}
diff --git a/UI/win-update/win-update.hpp b/UI/win-update/win-update.hpp
new file mode 100644
index 0000000..47bdd03
--- /dev/null
+++ b/UI/win-update/win-update.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <QThread>
+#include <QString>
+
+class AutoUpdateThread : public QThread {
+	Q_OBJECT
+
+	bool manualUpdate;
+	bool user_confirmed = false;
+
+	virtual void run() override;
+
+	void info(const QString &title, const QString &text);
+	int queryUpdate(bool manualUpdate, const char *text_utf8);
+
+private slots:
+	void infoMsg(const QString &title, const QString &text);
+	int queryUpdateSlot(bool manualUpdate, const QString &text);
+
+public:
+	AutoUpdateThread(bool manualUpdate_) : manualUpdate(manualUpdate_) {}
+};
diff --git a/UI/window-basic-adv-audio.cpp b/UI/window-basic-adv-audio.cpp
index e983b51..ad3977d 100644
--- a/UI/window-basic-adv-audio.cpp
+++ b/UI/window-basic-adv-audio.cpp
@@ -22,26 +22,32 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent)
 	QWidget *widget;
 	QLabel *label;
 
+	int idx = 0;
 	mainLayout = new QGridLayout;
 	mainLayout->setContentsMargins(0, 0, 0, 0);
 	label = new QLabel(QTStr("Basic.AdvAudio.Name"));
 	label->setAlignment(Qt::AlignHCenter);
-	mainLayout->addWidget(label, 0, 0);
+	mainLayout->addWidget(label, 0, idx++);
 	label = new QLabel(QTStr("Basic.AdvAudio.Volume"));
 	label->setAlignment(Qt::AlignHCenter);
-	mainLayout->addWidget(label, 0, 1);
+	mainLayout->addWidget(label, 0, idx++);
 	label = new QLabel(QTStr("Basic.AdvAudio.Mono"));
 	label->setAlignment(Qt::AlignHCenter);
-	mainLayout->addWidget(label, 0, 2);
+	mainLayout->addWidget(label, 0, idx++);
 	label = new QLabel(QTStr("Basic.AdvAudio.Panning"));
 	label->setAlignment(Qt::AlignHCenter);
-	mainLayout->addWidget(label, 0, 3);
+	mainLayout->addWidget(label, 0, idx++);
 	label = new QLabel(QTStr("Basic.AdvAudio.SyncOffset"));
 	label->setAlignment(Qt::AlignHCenter);
-	mainLayout->addWidget(label, 0, 4);
+	mainLayout->addWidget(label, 0, idx++);
+#if defined(_WIN32) || defined(__APPLE__)
+	label = new QLabel(QTStr("Basic.AdvAudio.Monitoring"));
+	label->setAlignment(Qt::AlignHCenter);
+	mainLayout->addWidget(label, 0, idx++);
+#endif
 	label = new QLabel(QTStr("Basic.AdvAudio.AudioTracks"));
 	label->setAlignment(Qt::AlignHCenter);
-	mainLayout->addWidget(label, 0, 5);
+	mainLayout->addWidget(label, 0, idx++);
 
 	controlArea = new QWidget;
 	controlArea->setLayout(mainLayout);
diff --git a/UI/window-basic-filters.cpp b/UI/window-basic-filters.cpp
index f3bb847..f3d53e8 100644
--- a/UI/window-basic-filters.cpp
+++ b/UI/window-basic-filters.cpp
@@ -147,6 +147,7 @@ inline OBSSource OBSBasicFilters::GetFilter(int row, bool async)
 void OBSBasicFilters::UpdatePropertiesView(int row, bool async)
 {
 	if (view) {
+		ui->rightLayout->removeWidget(view);
 		view->deleteLater();
 		view = nullptr;
 	}
diff --git a/UI/window-basic-main-dropfiles.cpp b/UI/window-basic-main-dropfiles.cpp
index 64ae7f6..45475a6 100644
--- a/UI/window-basic-main-dropfiles.cpp
+++ b/UI/window-basic-main-dropfiles.cpp
@@ -11,6 +11,10 @@
 
 using namespace std;
 
+static const char *textExtensions[] = {
+	"txt", "log", nullptr
+};
+
 static const char *imageExtensions[] = {
 	"bmp", "tga", "png", "jpg", "jpeg", "gif", nullptr
 };
@@ -52,19 +56,31 @@ static string GenerateSourceName(const char *base)
 	}
 }
 
-void OBSBasic::AddDropSource(const char *file, bool image)
+void OBSBasic::AddDropSource(const char *data, DropType image)
 {
 	OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
 	obs_data_t *settings = obs_data_create();
 	obs_source_t *source = nullptr;
 	const char *type = nullptr;
 
-	if (image) {
-		obs_data_set_string(settings, "file", file);
+	switch (image) {
+	case DropType_RawText:
+		obs_data_set_string(settings, "text", data);
+		type = "text_gdiplus";
+		break;
+	case DropType_Text:
+		obs_data_set_bool(settings, "read_from_file", true);
+		obs_data_set_string(settings, "file", data);
+		type = "text_gdiplus";
+		break;
+	case DropType_Image:
+		obs_data_set_string(settings, "file", data);
 		type = "image_source";
-	} else {
-		obs_data_set_string(settings, "local_file", file);
+		break;
+	case DropType_Media:
+		obs_data_set_string(settings, "local_file", data);
 		type = "ffmpeg_source";
+		break;
 	}
 
 	const char *name = obs_source_get_display_name(type);
@@ -113,10 +129,28 @@ void OBSBasic::dropEvent(QDropEvent *event)
 			const char *suffix = suffixArray.constData();
 			bool found = false;
 
-			const char **cmp = imageExtensions;
+			const char **cmp;
+
+			cmp = textExtensions;
+			while (*cmp) {
+				if (strcmp(*cmp, suffix) == 0) {
+					AddDropSource(QT_TO_UTF8(file),
+							DropType_Text);
+					found = true;
+					break;
+				}
+
+				cmp++;
+			}
+
+			if (found)
+				continue;
+
+			cmp = imageExtensions;
 			while (*cmp) {
 				if (strcmp(*cmp, suffix) == 0) {
-					AddDropSource(QT_TO_UTF8(file), true);
+					AddDropSource(QT_TO_UTF8(file),
+							DropType_Image);
 					found = true;
 					break;
 				}
@@ -130,13 +164,16 @@ void OBSBasic::dropEvent(QDropEvent *event)
 			cmp = mediaExtensions;
 			while (*cmp) {
 				if (strcmp(*cmp, suffix) == 0) {
-					AddDropSource(QT_TO_UTF8(file), false);
+					AddDropSource(QT_TO_UTF8(file),
+							DropType_Media);
 					break;
 				}
 
 				cmp++;
 			}
 		}
+	} else if (mimeData->hasText()) {
+		AddDropSource(QT_TO_UTF8(mimeData->text()), DropType_RawText);
 	}
 }
 
diff --git a/UI/window-basic-main-outputs.cpp b/UI/window-basic-main-outputs.cpp
index b703a4f..2222fe9 100644
--- a/UI/window-basic-main-outputs.cpp
+++ b/UI/window-basic-main-outputs.cpp
@@ -84,6 +84,36 @@ static void OBSRecordStopping(void *data, calldata_t *params)
 	UNUSED_PARAMETER(params);
 }
 
+static void OBSStartReplayBuffer(void *data, calldata_t *params)
+{
+	BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
+
+	output->replayBufferActive = true;
+	QMetaObject::invokeMethod(output->main, "ReplayBufferStart");
+
+	UNUSED_PARAMETER(params);
+}
+
+static void OBSStopReplayBuffer(void *data, calldata_t *params)
+{
+	BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
+	int code = (int)calldata_int(params, "code");
+
+	output->replayBufferActive = false;
+	QMetaObject::invokeMethod(output->main,
+			"ReplayBufferStop", Q_ARG(int, code));
+
+	UNUSED_PARAMETER(params);
+}
+
+static void OBSReplayBufferStopping(void *data, calldata_t *params)
+{
+	BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
+	QMetaObject::invokeMethod(output->main, "ReplayBufferStopping");
+
+	UNUSED_PARAMETER(params);
+}
+
 static void FindBestFilename(string &strPath, bool noSpace)
 {
 	int num = 2;
@@ -154,6 +184,7 @@ struct SimpleOutput : BasicOutputHandler {
 	string                 videoEncoder;
 	string                 videoQuality;
 	bool                   usingRecordingPreset = false;
+	bool                   recordingConfigured = false;
 	bool                   ffmpegOutput = false;
 	bool                   lowCPUx264 = false;
 
@@ -179,12 +210,18 @@ struct SimpleOutput : BasicOutputHandler {
 
 	void LoadStreamingPreset_h264(const char *encoder);
 
+	void UpdateRecording();
+	bool ConfigureRecording(bool useReplayBuffer);
+
 	virtual bool StartStreaming(obs_service_t *service) override;
 	virtual bool StartRecording() override;
+	virtual bool StartReplayBuffer() override;
 	virtual void StopStreaming(bool force) override;
 	virtual void StopRecording(bool force) override;
+	virtual void StopReplayBuffer(bool force) override;
 	virtual bool StreamingActive() const override;
 	virtual bool RecordingActive() const override;
+	virtual bool ReplayBufferActive() const override;
 };
 
 void SimpleOutput::LoadRecordingPreset_Lossless()
@@ -306,6 +343,32 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 	LoadRecordingPreset();
 
 	if (!ffmpegOutput) {
+		bool useReplayBuffer = config_get_bool(main->Config(),
+				"SimpleOutput", "RecRB");
+		if (useReplayBuffer) {
+			const char *str = config_get_string(main->Config(),
+					"Hotkeys", "ReplayBuffer");
+			obs_data_t *hotkey = obs_data_create_from_json(str);
+			replayBuffer = obs_output_create("replay_buffer",
+					Str("ReplayBuffer"), nullptr, hotkey);
+
+			obs_data_release(hotkey);
+			if (!replayBuffer)
+				throw "Failed to create replay buffer output "
+				      "(simple output)";
+			obs_output_release(replayBuffer);
+
+			signal_handler_t *signal =
+				obs_output_get_signal_handler(replayBuffer);
+
+			startReplayBuffer.Connect(signal, "start",
+					OBSStartReplayBuffer, this);
+			stopReplayBuffer.Connect(signal, "stop",
+					OBSStopReplayBuffer, this);
+			replayBufferStopping.Connect(signal, "stopping",
+					OBSReplayBufferStopping, this);
+		}
+
 		fileOutput = obs_output_create("ffmpeg_muxer",
 				"simple_file_output", nullptr, nullptr);
 		if (!fileOutput)
@@ -501,42 +564,49 @@ void SimpleOutput::UpdateRecordingSettings_nvenc(int cqp)
 void SimpleOutput::UpdateStreamingSettings_amd(obs_data_t *settings,
 		int bitrate)
 {
-	int bits = bitrate * 1000;
+	// Static Properties
 	obs_data_set_int(settings, "AMF.H264.Usage", 0);
-	obs_data_set_int(settings, "AMF.H264.QualityPreset", 2);
-	obs_data_set_int(settings, "AMF.H264.ProfileLevel", 51);
+	obs_data_set_int(settings, "AMF.H264.Profile", 100); // High
+	obs_data_set_string(settings, "profile", "high"); // High
+	
+	// Rate Control Properties
+	obs_data_set_int(settings, "AMF.H264.RateControlMethod", 1);
+	obs_data_set_string(settings, "rate_control", "CBR");
+	obs_data_set_int(settings, "AMF.H264.Bitrate.Target", bitrate);
+	obs_data_set_int(settings, "bitrate", bitrate);
 	obs_data_set_int(settings, "AMF.H264.FillerData", 1);
-	obs_data_set_int(settings, "AMF.H264.FrameSkipping", -1);
-	obs_data_set_int(settings, "AMF.H264.BPicture.Pattern", 2);
-	obs_data_set_int(settings, "AMF.H264.BPicture.Reference", 1);
-	obs_data_set_int(settings, "AMF.H264.Bitrate.Target", bits);
-	obs_data_set_int(settings, "AMF.H264.Bitrate.Peak", bits);
-	obs_data_set_int(settings, "AMF.H264Advanced.VBVBuffer.Size", bits);
-	obs_data_set_string(settings, "profile", "high");
+	obs_data_set_int(settings, "AMF.H264.VBVBuffer", 1);
+	obs_data_set_int(settings, "AMF.H264.VBVBuffer.Size", bitrate);
+	
+	// Picture Control Properties
+	obs_data_set_double(settings, "AMF.H264.KeyframeInterval", 2.0);
+	obs_data_set_int(settings, "keyint_sec", 2);
 }
 
 void SimpleOutput::UpdateRecordingSettings_amd_cqp(int cqp)
 {
 	obs_data_t *settings = obs_data_create();
 
+	// Static Properties
 	obs_data_set_int(settings, "AMF.H264.Usage", 0);
-	obs_data_set_int(settings, "AMF.H264.QualityPreset", 2);
-	obs_data_set_int(settings, "AMF.H264.ProfileLevel", 51);
-	obs_data_set_int(settings, "AMF.H264.FillerData", 0);
-	obs_data_set_int(settings, "AMF.H264.FrameSkipping", 0);
-	obs_data_set_int(settings, "AMF.H264.QP.Minimum", 0);
-	obs_data_set_int(settings, "AMF.H264.QP.Maximum", 51);
+	obs_data_set_int(settings, "AMF.H264.Profile", 100); // High
+	obs_data_set_string(settings, "profile", "high"); // High
+
+	// Rate Control Properties
+	obs_data_set_int(settings, "AMF.H264.RateControlMethod", 0);
+	obs_data_set_string(settings, "rate_control", "CQP");
 	obs_data_set_int(settings, "AMF.H264.QP.IFrame", cqp);
 	obs_data_set_int(settings, "AMF.H264.QP.PFrame", cqp);
 	obs_data_set_int(settings, "AMF.H264.QP.BFrame", cqp);
-	obs_data_set_int(settings, "AMF.H264.BPicture.Pattern", 3);
-	obs_data_set_int(settings, "AMF.H264.BPicture.Reference", 1);
-	obs_data_set_int(settings, "keyint_sec", 1);
-	obs_data_set_string(settings, "rate_control", "CQP");
-	obs_data_set_string(settings, "profile", "high");
+	obs_data_set_int(settings, "AMF.H264.VBVBuffer", 1);
+	obs_data_set_int(settings, "AMF.H264.VBVBuffer.Size", 50000);
 
-	obs_encoder_update(h264Recording, settings);
+	// Picture Control Properties
+	obs_data_set_double(settings, "AMF.H264.KeyframeInterval", 2.0);
+	obs_data_set_int(settings, "keyint_sec", 2);
 
+	// Update and release
+	obs_encoder_update(h264Recording, settings);
 	obs_data_release(settings);
 }
 
@@ -599,9 +669,17 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
 			"DelayPreserve");
 	const char *bindIP = config_get_string(main->Config(), "Output",
 			"BindIP");
+	bool enableNewSocketLoop = config_get_bool(main->Config(), "Output",
+			"NewSocketLoopEnable");
+	bool enableLowLatencyMode = config_get_bool(main->Config(), "Output",
+			"LowLatencyEnable");
 
 	obs_data_t *settings = obs_data_create();
 	obs_data_set_string(settings, "bind_ip", bindIP);
+	obs_data_set_bool(settings, "new_socket_loop_enabled",
+			enableNewSocketLoop);
+	obs_data_set_bool(settings, "low_latency_mode_enabled",
+			enableLowLatencyMode);
 	obs_output_update(streamOutput, settings);
 	obs_data_release(settings);
 
@@ -621,6 +699,19 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
 	return false;
 }
 
+static void remove_reserved_file_characters(string &s)
+{
+	replace(s.begin(), s.end(), '/', '_');
+	replace(s.begin(), s.end(), '\\', '_');
+	replace(s.begin(), s.end(), '*', '_');
+	replace(s.begin(), s.end(), '?', '_');
+	replace(s.begin(), s.end(), '"', '_');
+	replace(s.begin(), s.end(), '|', '_');
+	replace(s.begin(), s.end(), ':', '_');
+	replace(s.begin(), s.end(), '>', '_');
+	replace(s.begin(), s.end(), '<', '_');
+}
+
 static void ensure_directory_exists(string &path)
 {
 	replace(path.begin(), path.end(), '\\', '/');
@@ -633,8 +724,11 @@ static void ensure_directory_exists(string &path)
 	os_mkdirs(directory.c_str());
 }
 
-bool SimpleOutput::StartRecording()
+void SimpleOutput::UpdateRecording()
 {
+	if (replayBufferActive || recordingActive)
+		return;
+
 	if (usingRecordingPreset) {
 		if (!ffmpegOutput)
 			UpdateRecordingSettings();
@@ -645,6 +739,20 @@ bool SimpleOutput::StartRecording()
 	if (!Active())
 		SetupOutputs();
 
+	if (!ffmpegOutput) {
+		obs_output_set_video_encoder(fileOutput, h264Recording);
+		obs_output_set_audio_encoder(fileOutput, aacRecording, 0);
+	}
+	if (replayBuffer) {
+		obs_output_set_video_encoder(replayBuffer, h264Recording);
+		obs_output_set_audio_encoder(replayBuffer, aacRecording, 0);
+	}
+
+	recordingConfigured = true;
+}
+
+bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer)
+{
 	const char *path = config_get_string(main->Config(),
 			"SimpleOutput", "FilePath");
 	const char *format = config_get_string(main->Config(),
@@ -657,6 +765,14 @@ bool SimpleOutput::StartRecording()
 				"FilenameFormatting");
 	bool overwriteIfExists = config_get_bool(main->Config(), "Output",
 				"OverwriteIfExists");
+	const char *rbPrefix = config_get_string(main->Config(), "SimpleOutput",
+				"RecRBPrefix");
+	const char *rbSuffix = config_get_string(main->Config(), "SimpleOutput",
+				"RecRBSuffix");
+	int rbTime = config_get_int(main->Config(), "SimpleOutput",
+			"RecRBTime");
+	int rbSize = config_get_int(main->Config(), "SimpleOutput",
+			"RecRBSize");
 
 	os_dir_t *dir = path ? os_opendir(path) : nullptr;
 
@@ -686,25 +802,76 @@ bool SimpleOutput::StartRecording()
 	if (!overwriteIfExists)
 		FindBestFilename(strPath, noSpace);
 
-	if (!ffmpegOutput) {
-		obs_output_set_video_encoder(fileOutput, h264Recording);
-		obs_output_set_audio_encoder(fileOutput, aacRecording, 0);
+	obs_data_t *settings = obs_data_create();
+	if (updateReplayBuffer) {
+		string f;
+
+		if (rbPrefix && *rbPrefix) {
+			f += rbPrefix;
+			if (f.back() != ' ')
+				f += " ";
+		}
+
+		f += filenameFormat;
+
+		if (rbSuffix && *rbSuffix) {
+			if (*rbSuffix != ' ')
+				f += " ";
+			f += rbSuffix;
+		}
+
+		remove_reserved_file_characters(f);
+
+		obs_data_set_string(settings, "directory", path);
+		obs_data_set_string(settings, "format", f.c_str());
+		obs_data_set_string(settings, "extension", format);
+		obs_data_set_int(settings, "max_time_sec", rbTime);
+		obs_data_set_int(settings, "max_size_mb",
+				usingRecordingPreset ? rbSize : 0);
+	} else {
+		obs_data_set_string(settings, ffmpegOutput ? "url" : "path",
+				strPath.c_str());
 	}
 
-	obs_data_t *settings = obs_data_create();
-	obs_data_set_string(settings, ffmpegOutput ? "url" : "path",
-			strPath.c_str());
 	obs_data_set_string(settings, "muxer_settings", mux);
 
-	obs_output_update(fileOutput, settings);
+	if (updateReplayBuffer)
+		obs_output_update(replayBuffer, settings);
+	else
+		obs_output_update(fileOutput, settings);
 
 	obs_data_release(settings);
+	return true;
+}
 
-	if (obs_output_start(fileOutput)) {
-		return true;
+bool SimpleOutput::StartRecording()
+{
+	UpdateRecording();
+	if (!ConfigureRecording(false))
+		return false;
+	if (!obs_output_start(fileOutput))  {
+		QMessageBox::critical(main,
+				QTStr("Output.StartRecordingFailed"),
+				QTStr("Output.StartFailedGeneric"));
+		return false;
 	}
 
-	return false;
+	return true;
+}
+
+bool SimpleOutput::StartReplayBuffer()
+{
+	UpdateRecording();
+	if (!ConfigureRecording(true))
+		return false;
+	if (!obs_output_start(replayBuffer)) {
+		QMessageBox::critical(main,
+				QTStr("Output.StartReplayFailed"),
+				QTStr("Output.StartFailedGeneric"));
+		return false;
+	}
+
+	return true;
 }
 
 void SimpleOutput::StopStreaming(bool force)
@@ -723,6 +890,14 @@ void SimpleOutput::StopRecording(bool force)
 		obs_output_stop(fileOutput);
 }
 
+void SimpleOutput::StopReplayBuffer(bool force)
+{
+	if (force)
+		obs_output_force_stop(replayBuffer);
+	else
+		obs_output_stop(replayBuffer);
+}
+
 bool SimpleOutput::StreamingActive() const
 {
 	return obs_output_active(streamOutput);
@@ -733,10 +908,15 @@ bool SimpleOutput::RecordingActive() const
 	return obs_output_active(fileOutput);
 }
 
+bool SimpleOutput::ReplayBufferActive() const
+{
+	return obs_output_active(replayBuffer);
+}
+
 /* ------------------------------------------------------------------------ */
 
 struct AdvancedOutput : BasicOutputHandler {
-	OBSEncoder             aacTrack[4];
+	OBSEncoder             aacTrack[MAX_AUDIO_MIXES];
 	OBSEncoder             h264Streaming;
 	OBSEncoder             h264Recording;
 
@@ -744,7 +924,7 @@ struct AdvancedOutput : BasicOutputHandler {
 	bool                   ffmpegRecording;
 	bool                   useStreamEncoder;
 
-	string                 aacEncoderID[4];
+	string                 aacEncoderID[MAX_AUDIO_MIXES];
 
 	AdvancedOutput(OBSBasic *main_);
 
@@ -841,7 +1021,7 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 		      "(advanced output)";
 	obs_encoder_release(h264Streaming);
 
-	for (int i = 0; i < 4; i++) {
+	for (int i = 0; i < MAX_AUDIO_MIXES; i++) {
 		char name[9];
 		sprintf(name, "adv_aac%d", i);
 
@@ -936,7 +1116,7 @@ inline void AdvancedOutput::SetupStreaming()
 		for (; i < trackCount; i++)
 			obs_output_set_audio_encoder(streamOutput, aacTrack[i],
 					i);
-		for (; i < 4; i++)
+		for (; i < MAX_AUDIO_MIXES; i++)
 			obs_output_set_audio_encoder(streamOutput, nullptr, i);
 
 	} else {
@@ -994,6 +1174,8 @@ inline void AdvancedOutput::SetupFFmpeg()
 	const char *url = config_get_string(main->Config(), "AdvOut", "FFURL");
 	int vBitrate = config_get_int(main->Config(), "AdvOut",
 			"FFVBitrate");
+	int gopSize = config_get_int(main->Config(), "AdvOut",
+			"FFVGOPSize");
 	bool rescale = config_get_bool(main->Config(), "AdvOut",
 			"FFRescale");
 	const char *rescaleRes = config_get_string(main->Config(), "AdvOut",
@@ -1026,6 +1208,7 @@ inline void AdvancedOutput::SetupFFmpeg()
 	obs_data_set_string(settings, "format_name", formatName);
 	obs_data_set_string(settings, "format_mime_type", mimeType);
 	obs_data_set_string(settings, "muxer_settings", muxCustom);
+	obs_data_set_int(settings, "gop_size", gopSize);
 	obs_data_set_int(settings, "video_bitrate", vBitrate);
 	obs_data_set_string(settings, "video_encoder", vEncoder);
 	obs_data_set_int(settings, "video_encoder_id", vEncoderId);
@@ -1061,31 +1244,30 @@ static inline void SetEncoderName(obs_encoder_t *encoder, const char *name,
 
 inline void AdvancedOutput::UpdateAudioSettings()
 {
-	const char *name1 = config_get_string(main->Config(), "AdvOut",
-			"Track1Name");
-	const char *name2 = config_get_string(main->Config(), "AdvOut",
-			"Track2Name");
-	const char *name3 = config_get_string(main->Config(), "AdvOut",
-			"Track3Name");
-	const char *name4 = config_get_string(main->Config(), "AdvOut",
-			"Track4Name");
 	bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut",
 			"ApplyServiceSettings");
 	int streamTrackIndex = config_get_int(main->Config(), "AdvOut",
 			"TrackIndex");
-	obs_data_t *settings[4];
+	obs_data_t *settings[MAX_AUDIO_MIXES];
 
-	for (size_t i = 0; i < 4; i++) {
+	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) {
 		settings[i] = obs_data_create();
 		obs_data_set_int(settings[i], "bitrate", GetAudioBitrate(i));
 	}
 
-	SetEncoderName(aacTrack[0], name1, "Track1");
-	SetEncoderName(aacTrack[1], name2, "Track2");
-	SetEncoderName(aacTrack[2], name3, "Track3");
-	SetEncoderName(aacTrack[3], name4, "Track4");
+	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) {
+		string cfg_name = "Track";
+		cfg_name += to_string((int)i + 1);
+		cfg_name += "Name";
+		const char *name = config_get_string(main->Config(), "AdvOut",
+				cfg_name.c_str());
 
-	for (size_t i = 0; i < 4; i++) {
+		string def_name = "Track";
+		def_name += to_string((int)i + 1);
+		SetEncoderName(aacTrack[i], name, def_name.c_str());
+	}
+
+	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) {
 		if (applyServiceSettings && (int)(i + 1) == streamTrackIndex)
 			obs_service_apply_encoder_settings(main->GetService(),
 					nullptr, settings[i]);
@@ -1100,10 +1282,8 @@ void AdvancedOutput::SetupOutputs()
 	obs_encoder_set_video(h264Streaming, obs_get_video());
 	if (h264Recording)
 		obs_encoder_set_video(h264Recording, obs_get_video());
-	obs_encoder_set_audio(aacTrack[0], obs_get_audio());
-	obs_encoder_set_audio(aacTrack[1], obs_get_audio());
-	obs_encoder_set_audio(aacTrack[2], obs_get_audio());
-	obs_encoder_set_audio(aacTrack[3], obs_get_audio());
+	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++)
+		obs_encoder_set_audio(aacTrack[i], obs_get_audio());
 
 	SetupStreaming();
 
@@ -1115,9 +1295,10 @@ void AdvancedOutput::SetupOutputs()
 
 int AdvancedOutput::GetAudioBitrate(size_t i) const
 {
-	const char *names[] = {
+	static const char *names[] = {
 		"Track1Bitrate", "Track2Bitrate",
 		"Track3Bitrate", "Track4Bitrate",
+		"Track5Bitrate", "Track6Bitrate",
 	};
 	int bitrate = (int)config_get_uint(main->Config(), "AdvOut", names[i]);
 	return FindClosestAvailableAACBitrate(bitrate);
@@ -1148,9 +1329,17 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
 			"DelayPreserve");
 	const char *bindIP = config_get_string(main->Config(), "Output",
 			"BindIP");
+	bool enableNewSocketLoop = config_get_bool(main->Config(), "Output",
+			"NewSocketLoopEnable");
+	bool enableLowLatencyMode = config_get_bool(main->Config(), "Output",
+			"LowLatencyEnable");
 
 	obs_data_t *settings = obs_data_create();
 	obs_data_set_string(settings, "bind_ip", bindIP);
+	obs_data_set_bool(settings, "new_socket_loop_enabled",
+			enableNewSocketLoop);
+	obs_data_set_bool(settings, "low_latency_mode_enabled",
+			enableLowLatencyMode);
 	obs_output_update(streamOutput, settings);
 	obs_data_release(settings);
 
@@ -1243,11 +1432,14 @@ bool AdvancedOutput::StartRecording()
 		obs_data_release(settings);
 	}
 
-	if (obs_output_start(fileOutput)) {
-		return true;
+	if (!obs_output_start(fileOutput)) {
+		QMessageBox::critical(main,
+				QTStr("Output.StartRecordingFailed"),
+				QTStr("Output.StartFailedGeneric"));
+		return false;
 	}
 
-	return false;
+	return true;
 }
 
 void AdvancedOutput::StopStreaming(bool force)
diff --git a/UI/window-basic-main-outputs.hpp b/UI/window-basic-main-outputs.hpp
index 74a73a6..ec814a7 100644
--- a/UI/window-basic-main-outputs.hpp
+++ b/UI/window-basic-main-outputs.hpp
@@ -5,18 +5,23 @@ class OBSBasic;
 struct BasicOutputHandler {
 	OBSOutput              fileOutput;
 	OBSOutput              streamOutput;
+	OBSOutput              replayBuffer;
 	bool                   streamingActive = false;
 	bool                   recordingActive = false;
 	bool                   delayActive = false;
+	bool                   replayBufferActive = false;
 	OBSBasic               *main;
 
 	OBSSignal              startRecording;
 	OBSSignal              stopRecording;
+	OBSSignal              startReplayBuffer;
+	OBSSignal              stopReplayBuffer;
 	OBSSignal              startStreaming;
 	OBSSignal              stopStreaming;
 	OBSSignal              streamDelayStarting;
 	OBSSignal              streamStopping;
 	OBSSignal              recordStopping;
+	OBSSignal              replayBufferStopping;
 
 	inline BasicOutputHandler(OBSBasic *main_) : main(main_) {}
 
@@ -24,16 +29,20 @@ struct BasicOutputHandler {
 
 	virtual bool StartStreaming(obs_service_t *service) = 0;
 	virtual bool StartRecording() = 0;
+	virtual bool StartReplayBuffer() {return false;}
 	virtual void StopStreaming(bool force = false) = 0;
 	virtual void StopRecording(bool force = false) = 0;
+	virtual void StopReplayBuffer(bool force = false) {(void)force;}
 	virtual bool StreamingActive() const = 0;
 	virtual bool RecordingActive() const = 0;
+	virtual bool ReplayBufferActive() const {return false;}
 
 	virtual void Update() = 0;
 
 	inline bool Active() const
 	{
-		return streamingActive || recordingActive || delayActive;
+		return streamingActive || recordingActive || delayActive ||
+			replayBufferActive;
 	}
 };
 
diff --git a/UI/window-basic-main-profiles.cpp b/UI/window-basic-main-profiles.cpp
index 9637fca..badf5fa 100644
--- a/UI/window-basic-main-profiles.cpp
+++ b/UI/window-basic-main-profiles.cpp
@@ -20,6 +20,7 @@
 #include <util/util.hpp>
 #include <QMessageBox>
 #include <QVariant>
+#include <QFileDialog>
 #include "window-basic-main.hpp"
 #include "window-namedialog.hpp"
 #include "qt-wrappers.hpp"
@@ -448,6 +449,93 @@ void OBSBasic::on_actionRemoveProfile_triggered()
 	}
 }
 
+void OBSBasic::on_actionImportProfile_triggered()
+{
+	char path[512];
+
+	QString home = QDir::homePath();
+
+	int ret = GetConfigPath(path, 512, "obs-studio/basic/profiles/");
+	if (ret <= 0) {
+		blog(LOG_WARNING, "Failed to get profile config path");
+		return;
+	}
+
+	QString dir = QFileDialog::getExistingDirectory(
+			this,
+			QTStr("Basic.MainMenu.Profile.Import"),
+			home,
+			QFileDialog::ShowDirsOnly |
+			QFileDialog::DontResolveSymlinks);
+
+	if (!dir.isEmpty() && !dir.isNull()) {
+		QString inputPath = QString::fromUtf8(path);
+		QFileInfo finfo(dir);
+		QString directory = finfo.fileName();
+		QString profileDir = inputPath + directory;
+		QDir folder(profileDir);
+
+		if (!folder.exists()) {
+			folder.mkpath(profileDir);
+			QFile::copy(dir + "/basic.ini",
+					profileDir + "/basic.ini");
+			QFile::copy(dir + "/service.json",
+					profileDir + "/service.json");
+			QFile::copy(dir + "/streamEncoder.json",
+					profileDir + "/streamEncoder.json");
+			QFile::copy(dir + "/recordEncoder.json",
+					profileDir + "/recordEncoder.json");
+			RefreshProfiles();
+		} else {
+			QMessageBox::information(this,
+					QTStr("Basic.MainMenu.Profile.Import"),
+					QTStr("Basic.MainMenu.Profile.Exists"));
+		}
+	}
+}
+
+void OBSBasic::on_actionExportProfile_triggered()
+{
+	char path[512];
+
+	QString home = QDir::homePath();
+
+	QString currentProfile =
+		QString::fromUtf8(config_get_string(App()->GlobalConfig(),
+		"Basic", "ProfileDir"));
+
+	int ret = GetConfigPath(path, 512, "obs-studio/basic/profiles/");
+	if (ret <= 0) {
+		blog(LOG_WARNING, "Failed to get profile config path");
+		return;
+	}
+
+	QString dir = QFileDialog::getExistingDirectory(
+			this,
+			QTStr("Basic.MainMenu.Profile.Export"),
+			home,
+			QFileDialog::ShowDirsOnly |
+			QFileDialog::DontResolveSymlinks);
+
+	if (!dir.isEmpty() && !dir.isNull()) {
+		QString outputDir = dir + "/" + currentProfile;
+		QString inputPath = QString::fromUtf8(path);
+		QDir folder(outputDir);
+
+		if (!folder.exists()) {
+			folder.mkpath(outputDir);
+			QFile::copy(inputPath + currentProfile + "/basic.ini",
+					outputDir + "/basic.ini");
+			QFile::copy(inputPath + currentProfile + "/service.json",
+					outputDir + "/service.json");
+			QFile::copy(inputPath + currentProfile + "/streamEncoder.json",
+					outputDir + "/streamEncoder.json");
+			QFile::copy(inputPath + currentProfile + "/recordEncoder.json",
+					outputDir + "/recordEncoder.json");
+		}
+	}
+}
+
 void OBSBasic::ChangeProfile()
 {
 	QAction *action = reinterpret_cast<QAction*>(sender());
diff --git a/UI/window-basic-main-scene-collections.cpp b/UI/window-basic-main-scene-collections.cpp
index c35b0b1..a715441 100644
--- a/UI/window-basic-main-scene-collections.cpp
+++ b/UI/window-basic-main-scene-collections.cpp
@@ -19,6 +19,8 @@
 #include <util/util.hpp>
 #include <QMessageBox>
 #include <QVariant>
+#include <QFileDialog>
+#include <QStandardPaths>
 #include "item-widget-helpers.hpp"
 #include "window-basic-main.hpp"
 #include "window-namedialog.hpp"
@@ -191,7 +193,7 @@ void OBSBasic::RefreshSceneCollections()
 	int count = 0;
 
 	for (int i = 0; i < menuActions.count(); i++) {
-		QVariant v = menuActions[i]->property("fileName");
+		QVariant v = menuActions[i]->property("file_name");
 		if (v.typeName() != nullptr)
 			delete menuActions[i];
 	}
@@ -205,7 +207,7 @@ void OBSBasic::RefreshSceneCollections()
 		file.erase(file.size() - 5, 5);
 
 		QAction *action = new QAction(QT_UTF8(name), this);
-		action->setProperty("fileName", QT_UTF8(path));
+		action->setProperty("file_name", QT_UTF8(path));
 		connect(action, &QAction::triggered,
 				this, &OBSBasic::ChangeSceneCollection);
 		action->setCheckable(true);
@@ -220,6 +222,9 @@ void OBSBasic::RefreshSceneCollections()
 	EnumSceneCollections(addCollection);
 
 	ui->actionRemoveSceneCollection->setEnabled(count > 1);
+
+	OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
+	main->OpenSavedProjectors();
 }
 
 void OBSBasic::on_actionNewSceneCollection_triggered()
@@ -347,6 +352,67 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered()
 	}
 }
 
+void OBSBasic::on_actionImportSceneCollection_triggered()
+{
+	char path[512];
+
+	QString home = QDir::homePath();
+
+	int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
+	if (ret <= 0) {
+		blog(LOG_WARNING, "Failed to get scene collection config path");
+		return;
+	}
+
+	QString file = QFileDialog::getOpenFileName(
+			this,
+			QTStr("Basic.MainMenu.SceneCollection.Import"),
+			home,
+			"JSON Files (*.json)");
+
+	QFileInfo finfo(file);
+	QString filename = finfo.fileName();
+	QFileInfo destinfo(path + filename);
+
+	if (!file.isEmpty() && !file.isNull()) {
+		 if (!destinfo.exists()) {
+			QFile::copy(file, path + filename);
+			RefreshSceneCollections();
+		} else {
+			QMessageBox::information(this,
+				QTStr("Basic.MainMenu.SceneCollection.Import"),
+				QTStr("Basic.MainMenu.SceneCollection.Exists"));
+		}
+	}
+}
+
+void OBSBasic::on_actionExportSceneCollection_triggered()
+{
+	char path[512];
+
+	QString home = QDir::homePath();
+
+	QString currentFile = QT_UTF8(config_get_string(App()->GlobalConfig(),
+				"Basic", "SceneCollectionFile"));
+
+	int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
+	if (ret <= 0) {
+		blog(LOG_WARNING, "Failed to get scene collection config path");
+		return;
+	}
+
+	QString exportFile = QFileDialog::getSaveFileName(
+			this,
+			QTStr("Basic.MainMenu.SceneCollection.Export"),
+			home + "/" + currentFile,
+			"JSON Files (*.json)");
+
+	string file = QT_TO_UTF8(exportFile);
+
+	if (!exportFile.isEmpty() && !exportFile.isNull())
+		QFile::copy(path + currentFile + ".json", exportFile);
+}
+
 void OBSBasic::ChangeSceneCollection()
 {
 	QAction *action = reinterpret_cast<QAction*>(sender());
@@ -355,7 +421,7 @@ void OBSBasic::ChangeSceneCollection()
 	if (!action)
 		return;
 
-	fileName = QT_TO_UTF8(action->property("fileName").value<QString>());
+	fileName = QT_TO_UTF8(action->property("file_name").value<QString>());
 	if (fileName.empty())
 		return;
 
diff --git a/UI/window-basic-main-transitions.cpp b/UI/window-basic-main-transitions.cpp
index 3a69b24..64906d8 100644
--- a/UI/window-basic-main-transitions.cpp
+++ b/UI/window-basic-main-transitions.cpp
@@ -234,8 +234,10 @@ void OBSBasic::TransitionStopped()
 			SetCurrentScene(scene);
 	}
 
-	if (api)
+	if (api) {
 		api->on_event(OBS_FRONTEND_EVENT_TRANSITION_STOPPED);
+		api->on_event(OBS_FRONTEND_EVENT_SCENE_CHANGED);
+	}
 
 	swapScene = nullptr;
 }
@@ -274,19 +276,19 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force)
 
 	obs_source_t *transition = obs_get_output_source(0);
 
-	if (force)
+	if (force) {
 		obs_transition_set(transition, source);
-	else
+		if (api)
+			api->on_event(OBS_FRONTEND_EVENT_SCENE_CHANGED);
+	} else {
 		obs_transition_start(transition, OBS_TRANSITION_MODE_AUTO,
 				ui->transitionDuration->value(), source);
+	}
 
 	if (usingPreviewProgram && sceneDuplicationMode)
 		obs_scene_release(scene);
 
 	obs_source_release(transition);
-
-	if (api)
-		api->on_event(OBS_FRONTEND_EVENT_SCENE_CHANGED);
 }
 
 static inline void SetComboTransition(QComboBox *combo, obs_source_t *tr)
diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp
index e775461..8590dd7 100644
--- a/UI/window-basic-main.cpp
+++ b/UI/window-basic-main.cpp
@@ -19,11 +19,14 @@
 
 #include <time.h>
 #include <obs.hpp>
+#include <QGuiApplication>
 #include <QMessageBox>
 #include <QShowEvent>
 #include <QDesktopServices>
 #include <QFileDialog>
 #include <QDesktopWidget>
+#include <QRect>
+#include <QScreen>
 
 #include <util/dstr.h>
 #include <util/util.hpp>
@@ -49,6 +52,10 @@
 #include "volume-control.hpp"
 #include "remote-text.hpp"
 
+#if defined(_WIN32) && defined(ENABLE_WIN_UPDATER)
+#include "win-update/win-update.hpp"
+#endif
+
 #include "ui_OBSBasic.h"
 
 #include <fstream>
@@ -120,6 +127,11 @@ OBSBasic::OBSBasic(QWidget *parent)
 	: OBSMainWindow  (parent),
 	  ui             (new Ui::OBSBasic)
 {
+	setAttribute(Qt::WA_NativeWindow);
+
+	projectorArray.resize(10, "");
+	previewProjectorArray.resize(10, 0);
+
 	setAcceptDrops(true);
 
 	ui->setupUi(this);
@@ -138,7 +150,7 @@ OBSBasic::OBSBasic(QWidget *parent)
 
 		QRect windowGeometry = normalGeometry();
 		if (!WindowPositionValid(windowGeometry)) {
-			QRect rect = App()->desktop()->availableGeometry();
+			QRect rect = App()->desktop()->geometry();
 			setGeometry(QStyle::alignedRect(
 						Qt::LeftToRight,
 						Qt::AlignCenter,
@@ -259,7 +271,9 @@ static void SaveAudioDevice(const char *name, int channel, obs_data_t *parent,
 static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder,
 		obs_data_array_t *quickTransitionData, int transitionDuration,
 		obs_data_array_t *transitions,
-		OBSScene &scene, OBSSource &curProgramScene)
+		OBSScene &scene, OBSSource &curProgramScene,
+		obs_data_array_t *savedProjectorList,
+		obs_data_array_t *savedPreviewProjectorList)
 {
 	obs_data_t *saveData = obs_data_create();
 
@@ -300,6 +314,9 @@ static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder,
 	obs_data_set_array(saveData, "sources", sourcesArray);
 	obs_data_set_array(saveData, "quick_transitions", quickTransitionData);
 	obs_data_set_array(saveData, "transitions", transitions);
+	obs_data_set_array(saveData, "saved_projectors", savedProjectorList);
+	obs_data_set_array(saveData, "saved_preview_projectors",
+			savedPreviewProjectorList);
 	obs_data_array_release(sourcesArray);
 
 	obs_data_set_string(saveData, "current_transition",
@@ -357,6 +374,36 @@ obs_data_array_t *OBSBasic::SaveSceneListOrder()
 	return sceneOrder;
 }
 
+obs_data_array_t *OBSBasic::SaveProjectors()
+{
+	obs_data_array_t *saveProjector = obs_data_array_create();
+
+	for (size_t i = 0; i < projectorArray.size(); i++) {
+		obs_data_t *data = obs_data_create();
+		obs_data_set_string(data, "saved_projectors",
+			projectorArray.at(i).c_str());
+		obs_data_array_push_back(saveProjector, data);
+		obs_data_release(data);
+	}
+
+	return saveProjector;
+}
+
+obs_data_array_t *OBSBasic::SavePreviewProjectors()
+{
+	obs_data_array_t *saveProjector = obs_data_array_create();
+
+	for (size_t i = 0; i < previewProjectorArray.size(); i++) {
+		obs_data_t *data = obs_data_create();
+		obs_data_set_int(data, "saved_preview_projectors",
+			previewProjectorArray.at(i));
+		obs_data_array_push_back(saveProjector, data);
+		obs_data_release(data);
+	}
+
+	return saveProjector;
+}
+
 void OBSBasic::Save(const char *file)
 {
 	OBSScene scene = GetCurrentScene();
@@ -367,11 +414,16 @@ void OBSBasic::Save(const char *file)
 	obs_data_array_t *sceneOrder = SaveSceneListOrder();
 	obs_data_array_t *transitions = SaveTransitions();
 	obs_data_array_t *quickTrData = SaveQuickTransitions();
+	obs_data_array_t *savedProjectorList = SaveProjectors();
+	obs_data_array_t *savedPreviewProjectorList = SavePreviewProjectors();
 	obs_data_t *saveData  = GenerateSaveData(sceneOrder, quickTrData,
 			ui->transitionDuration->value(), transitions,
-			scene, curProgramScene);
+			scene, curProgramScene, savedProjectorList,
+			savedPreviewProjectorList);
 
 	obs_data_set_bool(saveData, "preview_locked", ui->preview->Locked());
+	obs_data_set_int(saveData, "scaling_mode",
+			static_cast<uint32_t>(ui->preview->GetScalingMode()));
 
 	if (api) {
 		obs_data_t *moduleObj = obs_data_create();
@@ -387,6 +439,8 @@ void OBSBasic::Save(const char *file)
 	obs_data_array_release(sceneOrder);
 	obs_data_array_release(quickTrData);
 	obs_data_array_release(transitions);
+	obs_data_array_release(savedProjectorList);
+	obs_data_array_release(savedPreviewProjectorList);
 }
 
 static void LoadAudioDevice(const char *name, int channel, obs_data_t *parent)
@@ -486,6 +540,32 @@ void OBSBasic::LoadSceneListOrder(obs_data_array_t *array)
 	}
 }
 
+void OBSBasic::LoadSavedProjectors(obs_data_array_t *array)
+{
+	size_t num = obs_data_array_count(array);
+
+	for (size_t i = 0; i < num; i++) {
+		obs_data_t *data = obs_data_array_item(array, i);
+		projectorArray.at(i) = obs_data_get_string(data,
+				"saved_projectors");
+
+		obs_data_release(data);
+	}
+}
+
+void OBSBasic::LoadSavedPreviewProjectors(obs_data_array_t *array)
+{
+	size_t num = obs_data_array_count(array);
+
+	for (size_t i = 0; i < num; i++) {
+		obs_data_t *data = obs_data_array_item(array, i);
+		previewProjectorArray.at(i) = obs_data_get_int(data,
+				"saved_preview_projectors");
+
+		obs_data_release(data);
+	}
+}
+
 static void LogFilter(obs_source_t*, obs_source_t *filter, void *v_val)
 {
 	const char *name = obs_source_get_name(filter);
@@ -507,6 +587,18 @@ static bool LogSceneItem(obs_scene_t*, obs_sceneitem_t *item, void*)
 
 	blog(LOG_INFO, "    - source: '%s' (%s)", name, id);
 
+	obs_monitoring_type monitoring_type =
+		obs_source_get_monitoring_type(source);
+
+	if (monitoring_type != OBS_MONITORING_TYPE_NONE) {
+		const char *type =
+			(monitoring_type == OBS_MONITORING_TYPE_MONITOR_ONLY)
+			? "monitor only"
+			: "monitor and output";
+
+		blog(LOG_INFO, "        - monitoring: %s", type);
+	}
+
 	obs_source_enum_filters(source, LogFilter, (void*)(intptr_t)2);
 	return true;
 }
@@ -613,6 +705,23 @@ void OBSBasic::Load(const char *file)
 	ui->transitionDuration->setValue(newDuration);
 	SetTransition(curTransition);
 
+	obs_data_array_t *savedProjectors = obs_data_get_array(data,
+			"saved_projectors");
+
+	if (savedProjectors)
+		LoadSavedProjectors(savedProjectors);
+
+	obs_data_array_release(savedProjectors);
+
+	obs_data_array_t *savedPreviewProjectors = obs_data_get_array(data,
+			"saved_preview_projectors");
+
+	if (savedPreviewProjectors)
+		LoadSavedPreviewProjectors(savedPreviewProjectors);
+
+	obs_data_array_release(savedPreviewProjectors);
+
+
 retryScene:
 	curScene = obs_get_source_by_name(sceneName);
 	curProgramScene = obs_get_source_by_name(programSceneName);
@@ -662,6 +771,19 @@ retryScene:
 	ui->preview->SetLocked(previewLocked);
 	ui->actionLockPreview->setChecked(previewLocked);
 
+	ScalingMode previewScaling = static_cast<ScalingMode>(
+			obs_data_get_int(data, "scaling_mode"));
+	switch (previewScaling) {
+	case ScalingMode::Window:
+	case ScalingMode::Canvas:
+	case ScalingMode::Output:
+		break;
+	default:
+		previewScaling = ScalingMode::Window;
+	}
+
+	ui->preview->SetScaling(previewScaling);
+
 	if (api) {
 		obs_data_t *modulesObj = obs_data_get_obj(data, "modules");
 		api->on_load(modulesObj);
@@ -685,6 +807,12 @@ retryScene:
 		opt_start_recording = false;
 	}
 
+	if (opt_start_replaybuffer) {
+		QMetaObject::invokeMethod(this, "StartReplayBuffer",
+				Qt::QueuedConnection);
+		opt_start_replaybuffer = false;
+	}
+
 	LogScenes();
 
 	disableSaving--;
@@ -780,17 +908,18 @@ static const double scaled_vals[] =
 
 bool OBSBasic::InitBasicConfigDefaults()
 {
-	vector<MonitorInfo> monitors;
-	GetMonitors(monitors);
+	QList<QScreen*> screens = QGuiApplication::screens();
 
-	if (!monitors.size()) {
+	if (!screens.size()) {
 		OBSErrorBox(NULL, "There appears to be no monitors.  Er, this "
 		                  "technically shouldn't be possible.");
 		return false;
 	}
 
-	uint32_t cx = monitors[0].cx;
-	uint32_t cy = monitors[0].cy;
+	QScreen *primaryScreen = QGuiApplication::primaryScreen();
+
+	uint32_t cx = primaryScreen->size().width();
+	uint32_t cy = primaryScreen->size().height();
 
 	/* ----------------------------------------------------- */
 	/* move over mixer values in advanced if older config */
@@ -828,6 +957,11 @@ bool OBSBasic::InitBasicConfigDefaults()
 			"Stream");
 	config_set_default_string(basicConfig, "SimpleOutput", "RecEncoder",
 			SIMPLE_ENCODER_X264);
+	config_set_default_bool(basicConfig, "SimpleOutput", "RecRB", false);
+	config_set_default_int(basicConfig, "SimpleOutput", "RecRBTime", 20);
+	config_set_default_int(basicConfig, "SimpleOutput", "RecRBSize", 512);
+	config_set_default_string(basicConfig, "SimpleOutput", "RecRBPrefix",
+			"Replay");
 
 	config_set_default_bool  (basicConfig, "AdvOut", "ApplyServiceSettings",
 			true);
@@ -852,8 +986,11 @@ bool OBSBasic::InitBasicConfigDefaults()
 			GetDefaultVideoSavePath().c_str());
 	config_set_default_string(basicConfig, "AdvOut", "FFExtension", "mp4");
 	config_set_default_uint  (basicConfig, "AdvOut", "FFVBitrate", 2500);
+	config_set_default_uint  (basicConfig, "AdvOut", "FFVGOPSize", 250);
 	config_set_default_bool  (basicConfig, "AdvOut", "FFUseRescale",
 			false);
+	config_set_default_bool  (basicConfig, "AdvOut", "FFIgnoreCompat",
+			false);
 	config_set_default_uint  (basicConfig, "AdvOut", "FFABitrate", 160);
 	config_set_default_uint  (basicConfig, "AdvOut", "FFAudioTrack", 1);
 
@@ -861,6 +998,8 @@ bool OBSBasic::InitBasicConfigDefaults()
 	config_set_default_uint  (basicConfig, "AdvOut", "Track2Bitrate", 160);
 	config_set_default_uint  (basicConfig, "AdvOut", "Track3Bitrate", 160);
 	config_set_default_uint  (basicConfig, "AdvOut", "Track4Bitrate", 160);
+	config_set_default_uint  (basicConfig, "AdvOut", "Track5Bitrate", 160);
+	config_set_default_uint  (basicConfig, "AdvOut", "Track6Bitrate", 160);
 
 	config_set_default_uint  (basicConfig, "Video", "BaseCX",   cx);
 	config_set_default_uint  (basicConfig, "Video", "BaseCY",   cy);
@@ -877,6 +1016,10 @@ bool OBSBasic::InitBasicConfigDefaults()
 	config_set_default_uint  (basicConfig, "Output", "MaxRetries", 20);
 
 	config_set_default_string(basicConfig, "Output", "BindIP", "default");
+	config_set_default_bool  (basicConfig, "Output", "NewSocketLoopEnable",
+			false);
+	config_set_default_bool  (basicConfig, "Output", "LowLatencyEnable",
+			false);
 
 	int i = 0;
 	uint32_t scale_cx = cx;
@@ -904,6 +1047,11 @@ bool OBSBasic::InitBasicConfigDefaults()
 	config_set_default_string(basicConfig, "Video", "ColorRange",
 			"Partial");
 
+	config_set_default_string(basicConfig, "Audio", "MonitoringDeviceId",
+			"default");
+	config_set_default_string(basicConfig, "Audio", "MonitoringDeviceName",
+			Str("Basic.Settings.Advanced.Audio.MonitoringDevice"
+				".Default"));
 	config_set_default_uint  (basicConfig, "Audio", "SampleRate", 44100);
 	config_set_default_string(basicConfig, "Audio", "ChannelSetup",
 			"Stereo");
@@ -1010,6 +1158,14 @@ void OBSBasic::InitPrimitives()
 	obs_leave_graphics();
 }
 
+void OBSBasic::ReplayBufferClicked()
+{
+	if (outputHandler->ReplayBufferActive())
+		StopReplayBuffer();
+	else
+		StartReplayBuffer();
+};
+
 void OBSBasic::ResetOutputs()
 {
 	ProfileScope("OBSBasic::ResetOutputs");
@@ -1022,6 +1178,24 @@ void OBSBasic::ResetOutputs()
 		outputHandler.reset(advOut ?
 			CreateAdvancedOutputHandler(this) :
 			CreateSimpleOutputHandler(this));
+
+		delete replayBufferButton;
+
+		if (outputHandler->replayBuffer) {
+			replayBufferButton = new QPushButton(
+					QTStr("Basic.Main.StartReplayBuffer"),
+					this);
+			connect(replayBufferButton.data(),
+					&QPushButton::clicked,
+					this,
+					&OBSBasic::ReplayBufferClicked);
+
+			ui->buttonsVLayout->insertWidget(2, replayBufferButton);
+		}
+
+		if (sysTrayReplayBuffer)
+			sysTrayReplayBuffer->setEnabled(
+					!!outputHandler->replayBuffer);
 	} else {
 		outputHandler->Update();
 	}
@@ -1034,6 +1208,14 @@ void OBSBasic::ResetOutputs()
 
 extern obs_frontend_callbacks *InitializeAPIInterface(OBSBasic *main);
 
+#define UNSUPPORTED_ERROR \
+	"Failed to initialize video:\n\nRequired graphics API functionality " \
+	"not found.  Your GPU may not be supported."
+
+#define UNKNOWN_ERROR \
+	"Failed to initialize video.  Your GPU may not be supported, " \
+	"or your graphics drivers may need to be updated."
+
 void OBSBasic::OBSInit()
 {
 	ProfileScope("OBSBasic::OBSInit");
@@ -1067,16 +1249,27 @@ void OBSBasic::OBSInit()
 	case OBS_VIDEO_MODULE_NOT_FOUND:
 		throw "Failed to initialize video:  Graphics module not found";
 	case OBS_VIDEO_NOT_SUPPORTED:
-		throw "Failed to initialize video:  Required graphics API "
-		      "functionality not found on these drivers or "
-		      "unavailable on this equipment";
+		throw UNSUPPORTED_ERROR;
 	case OBS_VIDEO_INVALID_PARAM:
 		throw "Failed to initialize video:  Invalid parameters";
 	default:
 		if (ret != OBS_VIDEO_SUCCESS)
-			throw "Failed to initialize video:  Unspecified error";
+			throw UNKNOWN_ERROR;
 	}
 
+	/* load audio monitoring */
+#if defined(_WIN32) || defined(__APPLE__)
+	const char *device_name = config_get_string(basicConfig, "Audio",
+			"MonitoringDeviceName");
+	const char *device_id = config_get_string(basicConfig, "Audio",
+			"MonitoringDeviceId");
+
+	obs_set_audio_monitoring_device(device_name, device_id);
+
+	blog(LOG_INFO, "Audio monitoring device:\n\tname: %s\n\tid: %s",
+			device_name, device_id);
+#endif
+
 	InitOBSCallbacks();
 	InitHotkeys();
 
@@ -1104,8 +1297,14 @@ void OBSBasic::OBSInit()
 				"BasicWindow", "SwapScenesMode");
 	editPropertiesMode = config_get_bool(App()->GlobalConfig(),
 				"BasicWindow", "EditPropertiesMode");
-	SetPreviewProgramMode(config_get_bool(App()->GlobalConfig(),
-				"BasicWindow", "PreviewProgramMode"));
+
+	if (!opt_studio_mode) {
+		SetPreviewProgramMode(config_get_bool(App()->GlobalConfig(),
+					"BasicWindow", "PreviewProgramMode"));
+	} else {
+		SetPreviewProgramMode(true);
+		opt_studio_mode = false;
+	}
 
 #define SET_VISIBILITY(name, control) \
 	do { \
@@ -1201,6 +1400,8 @@ void OBSBasic::OBSInit()
 	ui->mainSplitter->setSizes(defSizes);
 
 	SystemTray(true);
+
+	OpenSavedProjectors();
 }
 
 void OBSBasic::InitHotkeys()
@@ -1325,9 +1526,9 @@ void OBSBasic::CreateHotkeys()
 
 	streamingHotkeys = obs_hotkey_pair_register_frontend(
 			"OBSBasic.StartStreaming",
-			Str("Basic.Hotkeys.StartStreaming"),
+			Str("Basic.Main.StartStreaming"),
 			"OBSBasic.StopStreaming",
-			Str("Basic.Hotkeys.StopStreaming"),
+			Str("Basic.Main.StopStreaming"),
 			MAKE_CALLBACK(!basic.outputHandler->StreamingActive(),
 				basic.StartStreaming),
 			MAKE_CALLBACK(basic.outputHandler->StreamingActive(),
@@ -1353,9 +1554,9 @@ void OBSBasic::CreateHotkeys()
 
 	recordingHotkeys = obs_hotkey_pair_register_frontend(
 			"OBSBasic.StartRecording",
-			Str("Basic.Hotkeys.StartRecording"),
+			Str("Basic.Main.StartRecording"),
 			"OBSBasic.StopRecording",
-			Str("Basic.Hotkeys.StopRecording"),
+			Str("Basic.Main.StopRecording"),
 			MAKE_CALLBACK(!basic.outputHandler->RecordingActive(),
 				basic.StartRecording),
 			MAKE_CALLBACK(basic.outputHandler->RecordingActive(),
@@ -1363,6 +1564,19 @@ void OBSBasic::CreateHotkeys()
 			this, this);
 	LoadHotkeyPair(recordingHotkeys,
 			"OBSBasic.StartRecording", "OBSBasic.StopRecording");
+
+	replayBufHotkeys = obs_hotkey_pair_register_frontend(
+			"OBSBasic.StartReplayBuffer",
+			Str("Basic.Main.StartReplayBuffer"),
+			"OBSBasic.StopReplayBuffer",
+			Str("Basic.Main.StopReplayBuffer"),
+			MAKE_CALLBACK(!basic.outputHandler->ReplayBufferActive(),
+				basic.StartReplayBuffer),
+			MAKE_CALLBACK(basic.outputHandler->ReplayBufferActive(),
+				basic.StopReplayBuffer),
+			this, this);
+	LoadHotkeyPair(replayBufHotkeys,
+			"OBSBasic.StartReplayBuffer", "OBSBasic.StopReplayBuffer");
 #undef MAKE_CALLBACK
 
 	auto togglePreviewProgram = [] (void *data, obs_hotkey_id,
@@ -1399,6 +1613,7 @@ void OBSBasic::ClearHotkeys()
 {
 	obs_hotkey_pair_unregister(streamingHotkeys);
 	obs_hotkey_pair_unregister(recordingHotkeys);
+	obs_hotkey_pair_unregister(replayBufHotkeys);
 	obs_hotkey_unregister(forceStreamingStopHotkey);
 	obs_hotkey_unregister(togglePreviewProgramHotkey);
 	obs_hotkey_unregister(transitionHotkey);
@@ -1406,6 +1621,9 @@ void OBSBasic::ClearHotkeys()
 
 OBSBasic::~OBSBasic()
 {
+	if (updateCheckThread && updateCheckThread->isRunning())
+		updateCheckThread->wait();
+
 	delete programOptions;
 	delete program;
 
@@ -1463,7 +1681,6 @@ OBSBasic::~OBSBasic()
 	config_set_int(App()->GlobalConfig(), "General", "LastVersion",
 			LIBOBS_API_VER);
 
-	QRect lastGeom = normalGeometry();
 	QList<int> splitterSizes = ui->mainSplitter->sizes();
 	bool alwaysOnTop = IsAlwaysOnTop(this);
 
@@ -1563,6 +1780,17 @@ OBSSceneItem OBSBasic::GetCurrentSceneItem()
 	return GetSceneItem(GetTopSelectedSourceItem());
 }
 
+void OBSBasic::UpdatePreviewScalingMenu()
+{
+	ScalingMode scalingMode = ui->preview->GetScalingMode();
+	ui->actionScaleWindow->setChecked(
+			scalingMode == ScalingMode::Window);
+	ui->actionScaleCanvas->setChecked(
+			scalingMode == ScalingMode::Canvas);
+	ui->actionScaleOutput->setChecked(
+			scalingMode == ScalingMode::Output);
+}
+
 void OBSBasic::UpdateSources(OBSScene scene)
 {
 	ClearListItems(ui->sources);
@@ -1689,6 +1917,9 @@ void OBSBasic::AddScene(OBSSource source)
 		blog(LOG_INFO, "User added scene '%s'",
 				obs_source_get_name(source));
 	}
+
+	if (api)
+		api->on_event(OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED);
 }
 
 void OBSBasic::RemoveScene(OBSSource source)
@@ -1719,6 +1950,9 @@ void OBSBasic::RemoveScene(OBSSource source)
 		blog(LOG_INFO, "User Removed scene '%s'",
 				obs_source_get_name(source));
 	}
+
+	if (api)
+		api->on_event(OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED);
 }
 
 void OBSBasic::AddSceneItem(OBSSceneItem item)
@@ -1805,6 +2039,14 @@ void OBSBasic::RenameSources(QString newName, QString prevName)
 			volumes[i]->SetName(newName);
 	}
 
+	std::string newText = newName.toUtf8().constData();
+	std::string prevText = prevName.toUtf8().constData();
+
+	for (size_t j = 0; j < projectorArray.size(); j++) {
+		if (projectorArray.at(j) == prevText)
+			projectorArray.at(j) = newText;
+	}
+
 	SaveProject();
 }
 
@@ -1923,10 +2165,14 @@ void trigger_sparkle_update();
 
 void OBSBasic::TimedCheckForUpdates()
 {
+	if (!config_get_bool(App()->GlobalConfig(), "General",
+				"EnableAutoUpdates"))
+		return;
+
 #ifdef UPDATE_SPARKLE
 	init_sparkle_updater(config_get_bool(App()->GlobalConfig(), "General",
 				"UpdateToUndeployed"));
-#else
+#elif ENABLE_WIN_UPDATER
 	long long lastUpdate = config_get_int(App()->GlobalConfig(), "General",
 			"LastUpdateCheck");
 	uint32_t lastVersion = config_get_int(App()->GlobalConfig(), "General",
@@ -1942,27 +2188,21 @@ void OBSBasic::TimedCheckForUpdates()
 	long long secs = t - lastUpdate;
 
 	if (secs > UPDATE_CHECK_INTERVAL)
-		CheckForUpdates();
+		CheckForUpdates(false);
 #endif
 }
 
-void OBSBasic::CheckForUpdates()
+void OBSBasic::CheckForUpdates(bool manualUpdate)
 {
 #ifdef UPDATE_SPARKLE
 	trigger_sparkle_update();
-#else
+#elif ENABLE_WIN_UPDATER
 	ui->actionCheckForUpdates->setEnabled(false);
 
-	if (updateCheckThread) {
-		updateCheckThread->wait();
-		delete updateCheckThread;
-	}
+	if (updateCheckThread && updateCheckThread->isRunning())
+		return;
 
-	RemoteTextThread *thread = new RemoteTextThread(
-			"https://obsproject.com/obs2_update/basic.json");
-	updateCheckThread = thread;
-	connect(thread, &RemoteTextThread::Result,
-			this, &OBSBasic::updateFileFinished);
+	updateCheckThread = new AutoUpdateThread(manualUpdate);
 	updateCheckThread->start();
 #endif
 }
@@ -1975,57 +2215,9 @@ void OBSBasic::CheckForUpdates()
 #define VERSION_ENTRY "other"
 #endif
 
-void OBSBasic::updateFileFinished(const QString &text, const QString &error)
+void OBSBasic::updateCheckFinished()
 {
 	ui->actionCheckForUpdates->setEnabled(true);
-
-	if (text.isEmpty()) {
-		blog(LOG_WARNING, "Update check failed: %s", QT_TO_UTF8(error));
-		return;
-	}
-
-	obs_data_t *returnData  = obs_data_create_from_json(QT_TO_UTF8(text));
-	obs_data_t *versionData = obs_data_get_obj(returnData, VERSION_ENTRY);
-	const char *description = obs_data_get_string(returnData,
-			"description");
-	const char *download    = obs_data_get_string(versionData, "download");
-
-	if (returnData && versionData && description && download) {
-		long major   = obs_data_get_int(versionData, "major");
-		long minor   = obs_data_get_int(versionData, "minor");
-		long patch   = obs_data_get_int(versionData, "patch");
-		long version = MAKE_SEMANTIC_VERSION(major, minor, patch);
-
-		blog(LOG_INFO, "Update check: last known remote version "
-				"is %ld.%ld.%ld",
-				major, minor, patch);
-
-		if (version > LIBOBS_API_VER) {
-			QString     str = QTStr("UpdateAvailable.Text");
-			QMessageBox messageBox(this);
-
-			str = str.arg(QString::number(major),
-			              QString::number(minor),
-			              QString::number(patch),
-			              download);
-
-			messageBox.setWindowTitle(QTStr("UpdateAvailable"));
-			messageBox.setTextFormat(Qt::RichText);
-			messageBox.setText(str);
-			messageBox.setInformativeText(QT_UTF8(description));
-			messageBox.exec();
-
-			long long t = (long long)time(nullptr);
-			config_set_int(App()->GlobalConfig(), "General",
-					"LastUpdateCheck", t);
-			config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
-		}
-	} else {
-		blog(LOG_WARNING, "Bad JSON file received from server");
-	}
-
-	obs_data_release(versionData);
-	obs_data_release(returnData);
 }
 
 void OBSBasic::DuplicateSelectedScene()
@@ -2081,8 +2273,6 @@ void OBSBasic::DuplicateSelectedScene()
 		SetCurrentScene(source, true);
 		obs_scene_release(scene);
 
-		if (api)
-			api->on_event(OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED);
 		break;
 	}
 }
@@ -2566,13 +2756,39 @@ void OBSBasic::ResetAudioDevice(const char *sourceId, const char *deviceId,
 void OBSBasic::ResizePreview(uint32_t cx, uint32_t cy)
 {
 	QSize  targetSize;
+	ScalingMode scalingMode;
+	obs_video_info ovi;
 
 	/* resize preview panel to fix to the top section of the window */
 	targetSize = GetPixelSize(ui->preview);
-	GetScaleAndCenterPos(int(cx), int(cy),
-			targetSize.width()  - PREVIEW_EDGE_SIZE * 2,
-			targetSize.height() - PREVIEW_EDGE_SIZE * 2,
-			previewX, previewY, previewScale);
+
+	scalingMode = ui->preview->GetScalingMode();
+	obs_get_video_info(&ovi);
+
+	if (scalingMode == ScalingMode::Canvas) {
+		previewScale = 1.0f;
+		GetCenterPosFromFixedScale(int(cx), int(cy),
+				targetSize.width() - PREVIEW_EDGE_SIZE * 2,
+				targetSize.height() - PREVIEW_EDGE_SIZE * 2,
+				previewX, previewY, previewScale);
+		previewX += ui->preview->ScrollX();
+		previewY += ui->preview->ScrollY();
+
+	} else if (scalingMode == ScalingMode::Output) {
+		previewScale = float(ovi.output_width) / float(ovi.base_width);
+		GetCenterPosFromFixedScale(int(cx), int(cy),
+				targetSize.width() - PREVIEW_EDGE_SIZE * 2,
+				targetSize.height() - PREVIEW_EDGE_SIZE * 2,
+				previewX, previewY, previewScale);
+		previewX += ui->preview->ScrollX();
+		previewY += ui->preview->ScrollY();
+
+	} else {
+		GetScaleAndCenterPos(int(cx), int(cy),
+				targetSize.width() - PREVIEW_EDGE_SIZE * 2,
+				targetSize.height() - PREVIEW_EDGE_SIZE * 2,
+				previewX, previewY, previewScale);
+	}
 
 	previewX += float(PREVIEW_EDGE_SIZE);
 	previewY += float(PREVIEW_EDGE_SIZE);
@@ -2593,6 +2809,29 @@ void OBSBasic::CloseDialogs()
 	}
 }
 
+void OBSBasic::EnumDialogs()
+{
+	visDialogs.clear();
+	modalDialogs.clear();
+	visMsgBoxes.clear();
+
+	/* fill list of Visible dialogs and Modal dialogs */
+	QList<QDialog*> dialogs = findChildren<QDialog*>();
+	for (QDialog *dialog : dialogs) {
+		if (dialog->isVisible())
+			visDialogs.append(dialog);
+		if (dialog->isModal())
+			modalDialogs.append(dialog);
+	}
+
+	/* fill list of Visible message boxes */
+	QList<QMessageBox*> msgBoxes = findChildren<QMessageBox*>();
+	for (QMessageBox *msgbox : msgBoxes) {
+		if (msgbox->isVisible())
+			visMsgBoxes.append(msgbox);
+	}
+}
+
 void OBSBasic::ClearSceneData()
 {
 	disableSaving++;
@@ -2677,8 +2916,13 @@ void OBSBasic::closeEvent(QCloseEvent *event)
 
 void OBSBasic::changeEvent(QEvent *event)
 {
-	/* TODO */
-	UNUSED_PARAMETER(event);
+	if (event->type() == QEvent::WindowStateChange &&
+	    isMinimized() &&
+	    trayIcon->isVisible() &&
+	    sysTrayMinimizeToTray()) {
+
+		ToggleShowHide();
+	}
 }
 
 void OBSBasic::on_actionShow_Recordings_triggered()
@@ -2702,11 +2946,9 @@ void OBSBasic::on_actionRemux_triggered()
 
 void OBSBasic::on_action_Settings_triggered()
 {
-	disableHiding = true;
 	OBSBasicSettings settings(this);
 	settings.exec();
 	SystemTray(false);
-	disableHiding = false;
 }
 
 void OBSBasic::on_actionAdvAudioProperties_triggered()
@@ -2768,19 +3010,16 @@ static void AddProjectorMenuMonitors(QMenu *parent, QObject *target,
 		const char *slot)
 {
 	QAction *action;
-	std::vector<MonitorInfo> monitors;
-	GetMonitors(monitors);
-
-	for (int i = 0; (size_t)i < monitors.size(); i++) {
-		const MonitorInfo &monitor = monitors[i];
-
+	QList<QScreen*> screens = QGuiApplication::screens();
+	for (int i = 0; i < screens.size(); i++) {
+		QRect screenGeometry = screens[i]->geometry();
 		QString str = QString("%1 %2: %3x%4 @ %5,%6").
 			arg(QTStr("Display"),
 			    QString::number(i),
-			    QString::number((int)monitor.cx),
-			    QString::number((int)monitor.cy),
-			    QString::number((int)monitor.x),
-			    QString::number((int)monitor.y));
+			    QString::number((int)screenGeometry.width()),
+			    QString::number((int)screenGeometry.height()),
+			    QString::number((int)screenGeometry.x()),
+			    QString::number((int)screenGeometry.y()));
 
 		action = parent->addAction(str, target, slot);
 		action->setProperty("monitor", i);
@@ -2837,7 +3076,7 @@ void OBSBasic::on_actionAddScene_triggered()
 	string name;
 	QString format{QTStr("Basic.Main.DefaultSceneName.Text")};
 
-	int i = 1;
+	int i = 2;
 	QString placeHolderText = format.arg(i);
 	obs_source_t *source = nullptr;
 	while ((source = obs_get_source_by_name(QT_TO_UTF8(placeHolderText)))) {
@@ -3082,11 +3321,8 @@ void OBSBasic::CreateSourcePopupMenu(QListWidgetItem *item, bool preview)
 		if (IsPreviewProgramMode())
 			action->setEnabled(false);
 
-		action = popup.addAction(
-				QTStr("Basic.MainMenu.Edit.LockPreview"),
-				this, SLOT(on_actionLockPreview_triggered()));
-		action->setCheckable(true);
-		action->setChecked(ui->preview->Locked());
+		popup.addAction(ui->actionLockPreview);
+		popup.addMenu(ui->scalingMenu);
 
 		previewProjector = new QMenu(QTStr("PreviewProjector"));
 		AddProjectorMenuMonitors(previewProjector, this,
@@ -3184,9 +3420,11 @@ QMenu *OBSBasic::CreateAddSourcePopupMenu()
 {
 	const char *type;
 	bool foundValues = false;
+	bool foundDeprecated = false;
 	size_t idx = 0;
 
 	QMenu *popup = new QMenu(QTStr("Add"), this);
+	QMenu *deprecated = new QMenu(QTStr("Deprecated"), popup);
 
 	auto getActionAfter = [] (QMenu *menu, const QString &name)
 	{
@@ -3219,15 +3457,26 @@ QMenu *OBSBasic::CreateAddSourcePopupMenu()
 
 		if ((caps & OBS_SOURCE_DEPRECATED) == 0) {
 			addSource(popup, type, name);
-			foundValues = true;
+		} else {
+			addSource(deprecated, type, name);
+			foundDeprecated = true;
 		}
+		foundValues = true;
 	}
 
 	addSource(popup, "scene", Str("Basic.Scene"));
 
+	if (!foundDeprecated) {
+		delete deprecated;
+		deprecated = nullptr;
+	}
+
 	if (!foundValues) {
 		delete popup;
 		popup = nullptr;
+
+	} else if (foundDeprecated) {
+		popup->addMenu(deprecated);
 	}
 
 	return popup;
@@ -3473,7 +3722,7 @@ void OBSBasic::on_actionViewCurrentLog_triggered()
 
 void OBSBasic::on_actionCheckForUpdates_triggered()
 {
-	CheckForUpdates();
+	CheckForUpdates(true);
 }
 
 void OBSBasic::logUploadFinished(const QString &text, const QString &error)
@@ -3584,6 +3833,10 @@ void OBSBasic::OpenSceneFilters()
 	"==== Recording Start ==============================================="
 #define RECORDING_STOP \
 	"==== Recording Stop ================================================"
+#define REPLAY_BUFFER_START \
+	"==== Replay Buffer Start ==========================================="
+#define REPLAY_BUFFER_STOP \
+	"==== Replay Buffer Stop ============================================"
 #define STREAMING_START \
 	"==== Streaming Start ==============================================="
 #define STREAMING_STOP \
@@ -3601,20 +3854,36 @@ void OBSBasic::StartStreaming()
 
 	ui->streamButton->setEnabled(false);
 	ui->streamButton->setText(QTStr("Basic.Main.Connecting"));
-	sysTrayStream->setEnabled(false);
-	sysTrayStream->setText(ui->streamButton->text());
+
+	if (sysTrayStream) {
+		sysTrayStream->setEnabled(false);
+		sysTrayStream->setText(ui->streamButton->text());
+	}
 
 	if (!outputHandler->StartStreaming(service)) {
 		ui->streamButton->setText(QTStr("Basic.Main.StartStreaming"));
 		ui->streamButton->setEnabled(true);
-		sysTrayStream->setText(ui->streamButton->text());
-		sysTrayStream->setEnabled(true);
+
+		if (sysTrayStream) {
+			sysTrayStream->setText(ui->streamButton->text());
+			sysTrayStream->setEnabled(true);
+		}
+
+		QMessageBox::critical(this,
+				QTStr("Output.StartStreamFailed"),
+				QTStr("Output.StartFailedGeneric"));
+		return;
 	}
 
 	bool recordWhenStreaming = config_get_bool(GetGlobalConfig(),
 			"BasicWindow", "RecordWhenStreaming");
 	if (recordWhenStreaming)
 		StartRecording();
+
+	bool replayBufferWhileStreaming = config_get_bool(GetGlobalConfig(),
+		"BasicWindow", "ReplayBufferWhileStreaming");
+	if (replayBufferWhileStreaming)
+		StartReplayBuffer();
 }
 
 #ifdef _WIN32
@@ -3645,7 +3914,8 @@ inline void OBSBasic::OnActivate()
 		App()->IncrementSleepInhibition();
 		UpdateProcessPriority();
 
-		trayIcon->setIcon(QIcon(":/res/images/tray_active.png"));
+		if (trayIcon)
+			trayIcon->setIcon(QIcon(":/res/images/tray_active.png"));
 	}
 }
 
@@ -3656,7 +3926,8 @@ inline void OBSBasic::OnDeactivate()
 		App()->DecrementSleepInhibition();
 		ClearProcessPriority();
 
-		trayIcon->setIcon(QIcon(":/res/images/obs.png"));
+		if (trayIcon)
+			trayIcon->setIcon(QIcon(":/res/images/obs.png"));
 	}
 }
 
@@ -3675,6 +3946,13 @@ void OBSBasic::StopStreaming()
 			"BasicWindow", "KeepRecordingWhenStreamStops");
 	if (recordWhenStreaming && !keepRecordingWhenStreamStops)
 		StopRecording();
+
+	bool replayBufferWhileStreaming = config_get_bool(GetGlobalConfig(),
+		"BasicWindow", "ReplayBufferWhileStreaming");
+	bool keepReplayBufferStreamStops = config_get_bool(GetGlobalConfig(),
+		"BasicWindow", "KeepReplayBufferStreamStops");
+	if (replayBufferWhileStreaming && !keepReplayBufferStreamStops)
+		StopReplayBuffer();
 }
 
 void OBSBasic::ForceStopStreaming()
@@ -3692,14 +3970,24 @@ void OBSBasic::ForceStopStreaming()
 			"BasicWindow", "KeepRecordingWhenStreamStops");
 	if (recordWhenStreaming && !keepRecordingWhenStreamStops)
 		StopRecording();
+
+	bool replayBufferWhileStreaming = config_get_bool(GetGlobalConfig(),
+		"BasicWindow", "ReplayBufferWhileStreaming");
+	bool keepReplayBufferStreamStops = config_get_bool(GetGlobalConfig(),
+		"BasicWindow", "KeepReplayBufferStreamStops");
+	if (replayBufferWhileStreaming && !keepReplayBufferStreamStops)
+		StopReplayBuffer();
 }
 
 void OBSBasic::StreamDelayStarting(int sec)
 {
 	ui->streamButton->setText(QTStr("Basic.Main.StopStreaming"));
 	ui->streamButton->setEnabled(true);
-	sysTrayStream->setText(ui->streamButton->text());
-	sysTrayStream->setEnabled(true);
+
+	if (sysTrayStream) {
+		sysTrayStream->setText(ui->streamButton->text());
+		sysTrayStream->setEnabled(true);
+	}
 
 	if (!startStreamMenu.isNull())
 		startStreamMenu->deleteLater();
@@ -3720,8 +4008,11 @@ void OBSBasic::StreamDelayStopping(int sec)
 {
 	ui->streamButton->setText(QTStr("Basic.Main.StartStreaming"));
 	ui->streamButton->setEnabled(true);
-	sysTrayStream->setText(ui->streamButton->text());
-	sysTrayStream->setEnabled(true);
+
+	if (sysTrayStream) {
+		sysTrayStream->setText(ui->streamButton->text());
+		sysTrayStream->setEnabled(true);
+	}
 
 	if (!startStreamMenu.isNull())
 		startStreamMenu->deleteLater();
@@ -3741,8 +4032,11 @@ void OBSBasic::StreamingStart()
 	ui->streamButton->setText(QTStr("Basic.Main.StopStreaming"));
 	ui->streamButton->setEnabled(true);
 	ui->statusbar->StreamStarted(outputHandler->streamOutput);
-	sysTrayStream->setText(ui->streamButton->text());
-	sysTrayStream->setEnabled(true);
+
+	if (sysTrayStream) {
+		sysTrayStream->setText(ui->streamButton->text());
+		sysTrayStream->setEnabled(true);
+	}
 
 	if (api)
 		api->on_event(OBS_FRONTEND_EVENT_STREAMING_STARTED);
@@ -3755,7 +4049,9 @@ void OBSBasic::StreamingStart()
 void OBSBasic::StreamStopping()
 {
 	ui->streamButton->setText(QTStr("Basic.Main.StoppingStreaming"));
-	sysTrayStream->setText(ui->streamButton->text());
+
+	if (sysTrayStream)
+		sysTrayStream->setText(ui->streamButton->text());
 
 	streamingStopping = true;
 	if (api)
@@ -3794,8 +4090,11 @@ void OBSBasic::StreamingStop(int code)
 
 	ui->streamButton->setText(QTStr("Basic.Main.StartStreaming"));
 	ui->streamButton->setEnabled(true);
-	sysTrayStream->setText(ui->streamButton->text());
-	sysTrayStream->setEnabled(true);
+
+	if (sysTrayStream) {
+		sysTrayStream->setText(ui->streamButton->text());
+		sysTrayStream->setEnabled(true);
+	}
 
 	streamingStopping = false;
 	if (api)
@@ -3835,7 +4134,9 @@ void OBSBasic::StartRecording()
 void OBSBasic::RecordStopping()
 {
 	ui->recordButton->setText(QTStr("Basic.Main.StoppingRecording"));
-	sysTrayRecord->setText(ui->recordButton->text());
+
+	if (sysTrayRecord)
+		sysTrayRecord->setText(ui->recordButton->text());
 
 	recordingStopping = true;
 	if (api)
@@ -3856,7 +4157,9 @@ void OBSBasic::RecordingStart()
 {
 	ui->statusbar->RecordingStarted(outputHandler->fileOutput);
 	ui->recordButton->setText(QTStr("Basic.Main.StopRecording"));
-	sysTrayRecord->setText(ui->recordButton->text());
+
+	if (sysTrayRecord)
+		sysTrayRecord->setText(ui->recordButton->text());
 
 	recordingStopping = false;
 	if (api)
@@ -3871,7 +4174,10 @@ void OBSBasic::RecordingStop(int code)
 {
 	ui->statusbar->RecordingStopped();
 	ui->recordButton->setText(QTStr("Basic.Main.StartRecording"));
-	sysTrayRecord->setText(ui->recordButton->text());
+
+	if (sysTrayRecord)
+		sysTrayRecord->setText(ui->recordButton->text());
+
 	blog(LOG_INFO, RECORDING_STOP);
 
 	if (code == OBS_OUTPUT_UNSUPPORTED && isVisible()) {
@@ -3908,6 +4214,131 @@ void OBSBasic::RecordingStop(int code)
 	OnDeactivate();
 }
 
+#define RP_NO_HOTKEY_TITLE QTStr("Output.ReplayBuffer.NoHotkey.Title")
+#define RP_NO_HOTKEY_TEXT  QTStr("Output.ReplayBuffer.NoHotkey.Msg")
+
+void OBSBasic::StartReplayBuffer()
+{
+	if (!outputHandler || !outputHandler->replayBuffer)
+		return;
+	if (outputHandler->ReplayBufferActive())
+		return;
+
+	obs_output_t *output = outputHandler->replayBuffer;
+	obs_data_t *hotkeys = obs_hotkeys_save_output(output);
+	obs_data_array_t *bindings = obs_data_get_array(hotkeys,
+			"ReplayBuffer.Save");
+	size_t count = obs_data_array_count(bindings);
+	obs_data_array_release(bindings);
+	obs_data_release(hotkeys);
+
+	if (!count) {
+		QMessageBox::information(this,
+				RP_NO_HOTKEY_TITLE,
+				RP_NO_HOTKEY_TEXT);
+		return;
+	}
+
+	if (api)
+		api->on_event(OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTING);
+
+	SaveProject();
+	outputHandler->StartReplayBuffer();
+}
+
+void OBSBasic::ReplayBufferStopping()
+{
+	if (!outputHandler || !outputHandler->replayBuffer)
+		return;
+
+	replayBufferButton->setText(QTStr("Basic.Main.StoppingReplayBuffer"));
+
+	if (sysTrayReplayBuffer)
+		sysTrayReplayBuffer->setText(replayBufferButton->text());
+
+	replayBufferStopping = true;
+	if (api)
+		api->on_event(OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPING);
+}
+
+void OBSBasic::StopReplayBuffer()
+{
+	if (!outputHandler || !outputHandler->replayBuffer)
+		return;
+
+	SaveProject();
+
+	if (outputHandler->ReplayBufferActive())
+		outputHandler->StopReplayBuffer(replayBufferStopping);
+
+	OnDeactivate();
+}
+
+void OBSBasic::ReplayBufferStart()
+{
+	if (!outputHandler || !outputHandler->replayBuffer)
+		return;
+
+	replayBufferButton->setText(QTStr("Basic.Main.StopReplayBuffer"));
+
+	if (sysTrayReplayBuffer)
+		sysTrayReplayBuffer->setText(replayBufferButton->text());
+
+	replayBufferStopping = false;
+	if (api)
+		api->on_event(OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTED);
+
+	OnActivate();
+
+	blog(LOG_INFO, REPLAY_BUFFER_START);
+}
+
+void OBSBasic::ReplayBufferStop(int code)
+{
+	if (!outputHandler || !outputHandler->replayBuffer)
+		return;
+
+	replayBufferButton->setText(QTStr("Basic.Main.StartReplayBuffer"));
+
+	if (sysTrayReplayBuffer)
+		sysTrayReplayBuffer->setText(replayBufferButton->text());
+
+	blog(LOG_INFO, REPLAY_BUFFER_STOP);
+
+	if (code == OBS_OUTPUT_UNSUPPORTED && isVisible()) {
+		QMessageBox::information(this,
+				QTStr("Output.RecordFail.Title"),
+				QTStr("Output.RecordFail.Unsupported"));
+
+	} else if (code == OBS_OUTPUT_NO_SPACE && isVisible()) {
+		QMessageBox::information(this,
+				QTStr("Output.RecordNoSpace.Title"),
+				QTStr("Output.RecordNoSpace.Msg"));
+
+	} else if (code != OBS_OUTPUT_SUCCESS && isVisible()) {
+		QMessageBox::information(this,
+				QTStr("Output.RecordError.Title"),
+				QTStr("Output.RecordError.Msg"));
+
+	} else if (code == OBS_OUTPUT_UNSUPPORTED && !isVisible()) {
+		SysTrayNotify(QTStr("Output.RecordFail.Unsupported"),
+			QSystemTrayIcon::Warning);
+
+	} else if (code == OBS_OUTPUT_NO_SPACE && !isVisible()) {
+		SysTrayNotify(QTStr("Output.RecordNoSpace.Msg"),
+			QSystemTrayIcon::Warning);
+
+	} else if (code != OBS_OUTPUT_SUCCESS && !isVisible()) {
+		SysTrayNotify(QTStr("Output.RecordError.Msg"),
+			QSystemTrayIcon::Warning);
+	}
+
+	if (api)
+		api->on_event(OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPED);
+
+	OnDeactivate();
+}
+
 void OBSBasic::on_streamButton_clicked()
 {
 	if (outputHandler->StreamingActive()) {
@@ -4052,6 +4483,9 @@ void OBSBasic::GetFPSCommon(uint32_t &num, uint32_t &den) const
 	} else if (strcmp(val, "20") == 0) {
 		num = 20;
 		den = 1;
+	} else if (strcmp(val, "24 NTSC") == 0) {
+		num = 24000;
+		den = 1001;
 	} else if (strcmp(val, "25") == 0) {
 		num = 25;
 		den = 1;
@@ -4120,6 +4554,50 @@ void OBSBasic::on_actionEditTransform_triggered()
 	transformWindow->setAttribute(Qt::WA_DeleteOnClose, true);
 }
 
+static obs_transform_info copiedTransformInfo;
+static obs_sceneitem_crop copiedCropInfo;
+
+void OBSBasic::on_actionCopyTransform_triggered()
+{
+	auto func = [](obs_scene_t *scene, obs_sceneitem_t *item, void *param)
+	{
+		if (!obs_sceneitem_selected(item))
+			return true;
+
+		obs_sceneitem_defer_update_begin(item);
+		obs_sceneitem_get_info(item, &copiedTransformInfo);
+		obs_sceneitem_get_crop(item, &copiedCropInfo);
+		obs_sceneitem_defer_update_end(item);
+
+		UNUSED_PARAMETER(scene);
+		UNUSED_PARAMETER(param);
+		return true;
+	};
+
+	obs_scene_enum_items(GetCurrentScene(), func, nullptr);
+	ui->actionPasteTransform->setEnabled(true);
+}
+
+void OBSBasic::on_actionPasteTransform_triggered()
+{
+	auto func = [](obs_scene_t *scene, obs_sceneitem_t *item, void *param)
+	{
+		if (!obs_sceneitem_selected(item))
+			return true;
+
+		obs_sceneitem_defer_update_begin(item);
+		obs_sceneitem_set_info(item, &copiedTransformInfo);
+		obs_sceneitem_set_crop(item, &copiedCropInfo);
+		obs_sceneitem_defer_update_end(item);
+
+		UNUSED_PARAMETER(scene);
+		UNUSED_PARAMETER(param);
+		return true;
+	};
+
+	obs_scene_enum_items(GetCurrentScene(), func, nullptr);
+}
+
 void OBSBasic::on_actionResetTransform_triggered()
 {
 	auto func = [] (obs_scene_t *scene, obs_sceneitem_t *item, void *param)
@@ -4406,15 +4884,30 @@ void OBSBasic::NudgeRight()    {Nudge(1,  MoveDir::Right);}
 void OBSBasic::OpenProjector(obs_source_t *source, int monitor)
 {
 	/* seriously?  10 monitors? */
-	if (monitor > 9)
+	if (monitor > 9 || monitor > QGuiApplication::screens().size() - 1)
 		return;
 
+	bool isPreview = false;
+
+	if (source == nullptr)
+		isPreview = true;
+
 	delete projectors[monitor];
 	projectors[monitor].clear();
 
+	RemoveSavedProjectors(monitor);
+
 	OBSProjector *projector = new OBSProjector(nullptr, source);
-	projector->Init(monitor);
 
+	const char *name = obs_source_get_name(source);
+
+	if (isPreview) {
+		previewProjectorArray.at((size_t)monitor) = 1;
+	} else {
+		projectorArray.at((size_t)monitor) = name;
+	}
+
+	projector->Init(monitor);
 	projectors[monitor] = projector;
 }
 
@@ -4444,6 +4937,42 @@ void OBSBasic::OpenSceneProjector()
 	OpenProjector(obs_scene_get_source(scene), monitor);
 }
 
+void OBSBasic::OpenSavedProjectors()
+{
+	bool projectorSave = config_get_bool(GetGlobalConfig(),
+			"BasicWindow", "SaveProjectors");
+
+	if (projectorSave) {
+		for (size_t i = 0; i < projectorArray.size(); i++) {
+			if (projectorArray.at(i).empty() == false) {
+				OBSSource source = obs_get_source_by_name(
+					projectorArray.at(i).c_str());
+
+				if (!source) {
+					RemoveSavedProjectors((int)i);
+					obs_source_release(source);
+					continue;
+				}
+
+				OpenProjector(source, (int)i);
+				obs_source_release(source);
+			}
+		}
+
+		for (size_t i = 0; i < previewProjectorArray.size(); i++) {
+			if (previewProjectorArray.at(i) == 1) {
+				OpenProjector(nullptr, (int)i);
+			}
+		}
+	}
+}
+
+void OBSBasic::RemoveSavedProjectors(int monitor)
+{
+	previewProjectorArray.at((size_t)monitor) = 0;
+	projectorArray.at((size_t)monitor) = "";
+}
+
 void OBSBasic::UpdateTitleBar()
 {
 	stringstream name;
@@ -4458,6 +4987,9 @@ void OBSBasic::UpdateTitleBar()
 		name << "Studio ";
 
 	name << App()->GetVersionString();
+	if (App()->IsPortableMode())
+		name << " - Portable Mode";
+
 	name << " - " << Str("TitleBar.Profile") << ": " << profile;
 	name << " - " << Str("TitleBar.Scenes") << ": " << sceneCollection;
 
@@ -4520,6 +5052,45 @@ void OBSBasic::on_actionLockPreview_triggered()
 	ui->actionLockPreview->setChecked(ui->preview->Locked());
 }
 
+void OBSBasic::on_scalingMenu_aboutToShow()
+{
+	obs_video_info ovi;
+	obs_get_video_info(&ovi);
+
+	QAction *action = ui->actionScaleCanvas;
+	QString text = QTStr("Basic.MainMenu.Edit.Scale.Canvas");
+	text = text.arg(QString::number(ovi.base_width),
+			QString::number(ovi.base_height));
+	action->setText(text);
+
+	action = ui->actionScaleOutput;
+	text = QTStr("Basic.MainMenu.Edit.Scale.Output");
+	text = text.arg(QString::number(ovi.output_width),
+			QString::number(ovi.output_height));
+	action->setText(text);
+
+	UpdatePreviewScalingMenu();
+}
+
+void OBSBasic::on_actionScaleWindow_triggered()
+{
+	ui->preview->SetScaling(ScalingMode::Window);
+	ui->preview->ResetScrollingOffset();
+	emit ui->preview->DisplayResized();
+}
+
+void OBSBasic::on_actionScaleCanvas_triggered()
+{
+	ui->preview->SetScaling(ScalingMode::Canvas);
+	emit ui->preview->DisplayResized();
+}
+
+void OBSBasic::on_actionScaleOutput_triggered()
+{
+	ui->preview->SetScaling(ScalingMode::Output);
+	emit ui->preview->DisplayResized();
+}
+
 void OBSBasic::SetShowing(bool showing)
 {
 	if (!showing && isVisible()) {
@@ -4527,7 +5098,17 @@ void OBSBasic::SetShowing(bool showing)
 			"BasicWindow", "geometry",
 			saveGeometry().toBase64().constData());
 
-		showHide->setText(QTStr("Basic.SystemTray.Show"));
+		/* hide all visible child dialogs */
+		visDlgPositions.clear();
+		if (!visDialogs.isEmpty()) {
+			for (QDialog *dlg : visDialogs) {
+				visDlgPositions.append(dlg->pos());
+				dlg->hide();
+			}
+		}
+
+		if (showHide)
+			showHide->setText(QTStr("Basic.SystemTray.Show"));
 		QTimer::singleShot(250, this, SLOT(hide()));
 
 		if (previewEnabled)
@@ -4536,17 +5117,49 @@ void OBSBasic::SetShowing(bool showing)
 		setVisible(false);
 
 	} else if (showing && !isVisible()) {
-		showHide->setText(QTStr("Basic.SystemTray.Hide"));
+		if (showHide)
+			showHide->setText(QTStr("Basic.SystemTray.Hide"));
 		QTimer::singleShot(250, this, SLOT(show()));
 
 		if (previewEnabled)
 			EnablePreviewDisplay(true);
 
 		setVisible(true);
+
+		/* show all child dialogs that was visible earlier */
+		if (!visDialogs.isEmpty()) {
+			for (int i = 0; i < visDialogs.size(); ++i) {
+				QDialog *dlg = visDialogs[i];
+				dlg->move(visDlgPositions[i]);
+				dlg->show();
+			}
+		}
+
+		/* Unminimize window if it was hidden to tray instead of task
+		 * bar. */
+		if (sysTrayMinimizeToTray()) {
+			Qt::WindowStates state;
+			state  = windowState() & ~Qt::WindowMinimized;
+			state |= Qt::WindowActive;
+			setWindowState(state);
+		}
 	}
 }
 
-void OBSBasic::SystemTrayInit() {
+void OBSBasic::ToggleShowHide()
+{
+	bool showing = isVisible();
+	if (showing) {
+		/* check for modal dialogs */
+		EnumDialogs();
+		if (!modalDialogs.isEmpty() || !visMsgBoxes.isEmpty())
+			return;
+	}
+	SetShowing(!showing);
+}
+
+void OBSBasic::SystemTrayInit()
+{
 	trayIcon = new QSystemTrayIcon(QIcon(":/res/images/obs.png"),
 			this);
 	trayIcon->setToolTip("OBS Studio");
@@ -4557,9 +5170,14 @@ void OBSBasic::SystemTrayInit() {
 			trayIcon);
 	sysTrayRecord = new QAction(QTStr("Basic.Main.StartRecording"),
 			trayIcon);
+	sysTrayReplayBuffer = new QAction(QTStr("Basic.Main.StartReplayBuffer"),
+			trayIcon);
 	exit = new QAction(QTStr("Exit"),
 			trayIcon);
 
+	if (outputHandler && !outputHandler->replayBuffer)
+		sysTrayReplayBuffer->setEnabled(false);
+
 	connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
 			this,
 			SLOT(IconActivated(QSystemTrayIcon::ActivationReason)));
@@ -4569,6 +5187,8 @@ void OBSBasic::SystemTrayInit() {
 			this, SLOT(on_streamButton_clicked()));
 	connect(sysTrayRecord, SIGNAL(triggered()),
 			this, SLOT(on_recordButton_clicked()));
+	connect(sysTrayReplayBuffer.data(), &QAction::triggered,
+			this, &OBSBasic::ReplayBufferClicked);
 	connect(exit, SIGNAL(triggered()),
 			this, SLOT(close()));
 
@@ -4576,6 +5196,7 @@ void OBSBasic::SystemTrayInit() {
 	trayMenu->addAction(showHide);
 	trayMenu->addAction(sysTrayStream);
 	trayMenu->addAction(sysTrayRecord);
+	trayMenu->addAction(sysTrayReplayBuffer);
 	trayMenu->addAction(exit);
 	trayIcon->setContextMenu(trayMenu);
 }
@@ -4611,12 +5232,14 @@ void OBSBasic::SystemTray(bool firstStarted)
 
 	if (!sysTrayWhenStarted && !sysTrayEnabled) {
 		trayIcon->hide();
-	} else if (sysTrayWhenStarted && sysTrayEnabled) {
+	} else if ((sysTrayWhenStarted && sysTrayEnabled)
+			|| opt_minimize_tray) {
 		trayIcon->show();
 		if (firstStarted) {
 			QTimer::singleShot(50, this, SLOT(hide()));
 			EnablePreviewDisplay(false);
 			setVisible(false);
+			opt_minimize_tray = false;
 		}
 	} else if (sysTrayEnabled) {
 		trayIcon->show();
@@ -4631,3 +5254,9 @@ void OBSBasic::SystemTray(bool firstStarted)
 	else
 		showHide->setText(QTStr("Basic.SystemTray.Show"));
 }
+
+bool OBSBasic::sysTrayMinimizeToTray()
+{
+	return config_get_bool(GetGlobalConfig(),
+			"BasicWindow", "SysTrayMinimizeToTray");
+}
diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp
index 1aaa735..d89be13 100644
--- a/UI/window-basic-main.hpp
+++ b/UI/window-basic-main.hpp
@@ -38,6 +38,7 @@
 
 #include <QPointer>
 
+class QMessageBox;
 class QListWidgetItem;
 class VolControl;
 class QNetworkReply;
@@ -86,6 +87,7 @@ class OBSBasic : public OBSMainWindow {
 	friend class OBSBasicPreview;
 	friend class OBSBasicStatusBar;
 	friend class OBSBasicSourceSelect;
+	friend class OBSBasicSettings;
 	friend struct OBSStudioAPI;
 
 	enum class MoveDir {
@@ -95,6 +97,13 @@ class OBSBasic : public OBSMainWindow {
 		Right
 	};
 
+	enum DropType {
+		DropType_RawText,
+		DropType_Text,
+		DropType_Image,
+		DropType_Media
+	};
+
 private:
 	obs_frontend_callbacks *api = nullptr;
 
@@ -102,6 +111,9 @@ private:
 
 	std::vector<OBSSignal> signalHandlers;
 
+	std::vector<std::string> projectorArray;
+	std::vector<int> previewProjectorArray;
+
 	bool loaded = false;
 	long disableSaving = 1;
 	bool projectChanged = false;
@@ -123,6 +135,7 @@ private:
 	std::unique_ptr<BasicOutputHandler> outputHandler;
 	bool streamingStopping = false;
 	bool recordingStopping = false;
+	bool replayBufferStopping = false;
 
 	gs_vertbuffer_t *box = nullptr;
 	gs_vertbuffer_t *boxLeft = nullptr;
@@ -144,14 +157,15 @@ private:
 
 	QPointer<QMenu> startStreamMenu;
 
-	QSystemTrayIcon *trayIcon;
-	QMenu         *trayMenu;
-	QAction       *sysTrayStream;
-	QAction       *sysTrayRecord;
-	QAction       *showHide;
-	QAction       *showPreview;
-	QAction       *exit;
-	bool          disableHiding = false;
+	QPointer<QPushButton> replayBufferButton;
+
+	QPointer<QSystemTrayIcon> trayIcon;
+	QPointer<QAction>         sysTrayStream;
+	QPointer<QAction>         sysTrayRecord;
+	QPointer<QAction>         sysTrayReplayBuffer;
+	QPointer<QAction>         showHide;
+	QPointer<QAction>         exit;
+	QPointer<QMenu>           trayMenu;
 
 	void          DrawBackdrop(float cx, float cy);
 
@@ -186,7 +200,7 @@ private:
 	bool          QueryRemoveSource(obs_source_t *source);
 
 	void          TimedCheckForUpdates();
-	void          CheckForUpdates();
+	void          CheckForUpdates(bool manualUpdate);
 
 	void GetFPSCommon(uint32_t &num, uint32_t &den) const;
 	void GetFPSInteger(uint32_t &num, uint32_t &den) const;
@@ -194,6 +208,8 @@ private:
 	void GetFPSNanoseconds(uint32_t &num, uint32_t &den) const;
 	void GetConfigFPS(uint32_t &num, uint32_t &den) const;
 
+	void UpdatePreviewScalingMenu();
+
 	void UpdateSources(OBSScene scene);
 	void InsertSceneItem(obs_sceneitem_t *item);
 
@@ -236,7 +252,8 @@ private:
 
 	QListWidgetItem *GetTopSelectedSourceItem();
 
-	obs_hotkey_pair_id streamingHotkeys, recordingHotkeys;
+	obs_hotkey_pair_id streamingHotkeys, recordingHotkeys,
+	                   replayBufHotkeys;
 	obs_hotkey_id forceStreamingStopHotkey;
 
 	void InitDefaultTransitions();
@@ -299,12 +316,31 @@ private:
 	inline void OnActivate();
 	inline void OnDeactivate();
 
-	void AddDropSource(const char *file, bool image);
+	void AddDropSource(const char *file, DropType image);
 	void dragEnterEvent(QDragEnterEvent *event) override;
 	void dragLeaveEvent(QDragLeaveEvent *event) override;
 	void dragMoveEvent(QDragMoveEvent *event) override;
 	void dropEvent(QDropEvent *event) override;
 
+	void ReplayBufferClicked();
+
+	bool sysTrayMinimizeToTray();
+
+	void EnumDialogs();
+
+	QList<QDialog*> visDialogs;
+	QList<QDialog*> modalDialogs;
+	QList<QMessageBox*> visMsgBoxes;
+
+	QList<QPoint> visDlgPositions;
+
+	obs_data_array_t *SaveProjectors();
+	void LoadSavedProjectors(obs_data_array_t *savedProjectors);
+
+	obs_data_array_t *SavePreviewProjectors();
+	void LoadSavedPreviewProjectors(
+		obs_data_array_t *savedPreviewProjectors);
+
 public slots:
 	void StartStreaming();
 	void StopStreaming();
@@ -324,6 +360,13 @@ public slots:
 	void RecordStopping();
 	void RecordingStop(int code);
 
+	void StartReplayBuffer();
+	void StopReplayBuffer();
+
+	void ReplayBufferStart();
+	void ReplayBufferStopping();
+	void ReplayBufferStop(int code);
+
 	void SaveProjectDeferred();
 	void SaveProject();
 
@@ -368,15 +411,7 @@ private slots:
 	void IconActivated(QSystemTrayIcon::ActivationReason reason);
 	void SetShowing(bool showing);
 
-	inline void ToggleShowHide()
-	{
-		bool showing = isVisible();
-		if (disableHiding && showing)
-			return;
-		if (showing)
-			CloseDialogs();
-		SetShowing(!showing);
-	}
+	void ToggleShowHide();
 
 private:
 	/* OBS Callbacks */
@@ -457,6 +492,9 @@ public:
 	void SystemTrayInit();
 	void SystemTray(bool firstStarted);
 
+	void OpenSavedProjectors();
+	void RemoveSavedProjectors(int monitor);
+
 protected:
 	virtual void closeEvent(QCloseEvent *event) override;
 	virtual void changeEvent(QEvent *event) override;
@@ -475,6 +513,8 @@ private slots:
 	void on_actionCheckForUpdates_triggered();
 
 	void on_actionEditTransform_triggered();
+	void on_actionCopyTransform_triggered();
+	void on_actionPasteTransform_triggered();
 	void on_actionRotate90CW_triggered();
 	void on_actionRotate90CCW_triggered();
 	void on_actionRotate180_triggered();
@@ -508,6 +548,11 @@ private slots:
 
 	void on_actionLockPreview_triggered();
 
+	void on_scalingMenu_aboutToShow();
+	void on_actionScaleWindow_triggered();
+	void on_actionScaleCanvas_triggered();
+	void on_actionScaleOutput_triggered();
+
 	void on_streamButton_clicked();
 	void on_recordButton_clicked();
 	void on_settingsButton_clicked();
@@ -522,11 +567,15 @@ private slots:
 	void on_actionDupSceneCollection_triggered();
 	void on_actionRenameSceneCollection_triggered();
 	void on_actionRemoveSceneCollection_triggered();
+	void on_actionImportSceneCollection_triggered();
+	void on_actionExportSceneCollection_triggered();
 
 	void on_actionNewProfile_triggered();
 	void on_actionDupProfile_triggered();
 	void on_actionRenameProfile_triggered();
 	void on_actionRemoveProfile_triggered();
+	void on_actionImportProfile_triggered();
+	void on_actionExportProfile_triggered();
 
 	void on_actionShowSettingsFolder_triggered();
 	void on_actionShowProfileFolder_triggered();
@@ -546,7 +595,7 @@ private slots:
 
 	void logUploadFinished(const QString &text, const QString &error);
 
-	void updateFileFinished(const QString &text, const QString &error);
+	void updateCheckFinished();
 
 	void AddSourceFromAction();
 
diff --git a/UI/window-basic-preview.cpp b/UI/window-basic-preview.cpp
index dc2c4f3..6cba59b 100644
--- a/UI/window-basic-preview.cpp
+++ b/UI/window-basic-preview.cpp
@@ -17,6 +17,7 @@
 OBSBasicPreview::OBSBasicPreview(QWidget *parent, Qt::WindowFlags flags)
 	: OBSQTDisplay(parent, flags)
 {
+	ResetScrollingOffset();
 	setMouseTracking(true);
 }
 
@@ -377,8 +378,56 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos)
 	}
 }
 
+void OBSBasicPreview::keyPressEvent(QKeyEvent *event)
+{
+	if (GetScalingMode() == ScalingMode::Window ||
+	    event->isAutoRepeat()) {
+		OBSQTDisplay::keyPressEvent(event);
+		return;
+	}
+
+	switch (event->key()) {
+	case Qt::Key_Space:
+		setCursor(Qt::OpenHandCursor);
+		scrollMode = true;
+		break;
+	}
+
+	OBSQTDisplay::keyPressEvent(event);
+}
+
+void OBSBasicPreview::keyReleaseEvent(QKeyEvent *event)
+{
+	if (event->isAutoRepeat()) {
+		OBSQTDisplay::keyReleaseEvent(event);
+		return;
+	}
+
+	switch (event->key()) {
+	case Qt::Key_Space:
+		scrollMode = false;
+		setCursor(Qt::ArrowCursor);
+		break;
+	}
+
+	OBSQTDisplay::keyReleaseEvent(event);
+}
+
 void OBSBasicPreview::mousePressEvent(QMouseEvent *event)
 {
+	if (scrollMode && GetScalingMode() != ScalingMode::Window &&
+	    event->button() == Qt::LeftButton) {
+		setCursor(Qt::ClosedHandCursor);
+		scrollingFrom.x = event->x();
+		scrollingFrom.y = event->y();
+		return;
+	}
+
+	if (event->button() == Qt::RightButton) {
+		scrollMode = false;
+		setCursor(Qt::ArrowCursor);
+	}
+
 	if (locked) {
 		OBSQTDisplay::mousePressEvent(event);
 		return;
@@ -456,6 +505,9 @@ void OBSBasicPreview::ProcessClick(const vec2 &pos)
 
 void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event)
 {
+	if (scrollMode)
+		setCursor(Qt::OpenHandCursor);
+
 	if (locked) {
 		OBSQTDisplay::mouseReleaseEvent(event);
 		return;
@@ -688,18 +740,35 @@ void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size,
 	    stretchHandle == ItemHandle::TopRight   ||
 	    stretchHandle == ItemHandle::BottomLeft ||
 	    stretchHandle == ItemHandle::BottomRight) {
-		if (aspect < baseAspect)
-			size.x = size.y * baseAspect;
-		else
-			size.y = size.x / baseAspect;
+		if (aspect < baseAspect) {
+			if ((size.y >= 0.0f && size.x >= 0.0f) ||
+			    (size.y <= 0.0f && size.x <= 0.0f))
+				size.x = size.y * baseAspect;
+			else
+				size.x = size.y * baseAspect * -1.0f;
+		} else {
+			if ((size.y >= 0.0f && size.x >= 0.0f) ||
+			    (size.y <= 0.0f && size.x <= 0.0f))
+				size.y = size.x / baseAspect;
+			else
+				size.y = size.x / baseAspect * -1.0f;
+		}
 
 	} else if (stretchHandle == ItemHandle::TopCenter ||
 	           stretchHandle == ItemHandle::BottomCenter) {
-		size.x = size.y * baseAspect;
+		if ((size.y >= 0.0f && size.x >= 0.0f) ||
+		    (size.y <= 0.0f && size.x <= 0.0f))
+			size.x = size.y * baseAspect;
+		else
+			size.x = size.y * baseAspect * -1.0f;
 
 	} else if (stretchHandle == ItemHandle::CenterLeft ||
 	           stretchHandle == ItemHandle::CenterRight) {
-		size.y = size.x / baseAspect;
+		if ((size.y >= 0.0f && size.x >= 0.0f) ||
+		    (size.y <= 0.0f && size.x <= 0.0f))
+			size.y = size.x / baseAspect;
+		else
+			size.y = size.x / baseAspect * -1.0f;
 	}
 
 	size.x = std::round(size.x);
@@ -951,6 +1020,15 @@ void OBSBasicPreview::StretchItem(const vec2 &pos)
 
 void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event)
 {
+	if (scrollMode && event->buttons() == Qt::LeftButton) {
+		scrollingOffset.x += event->x() - scrollingFrom.x;
+		scrollingOffset.y += event->y() - scrollingFrom.y;
+		scrollingFrom.x = event->x();
+		scrollingFrom.y = event->y();
+		emit DisplayResized();
+		return;
+	}
+
 	if (locked)
 		return;
 
@@ -1113,3 +1191,8 @@ void OBSBasicPreview::DrawSceneEditing()
 	gs_technique_end_pass(tech);
 	gs_technique_end(tech);
 }
+
+void OBSBasicPreview::ResetScrollingOffset()
+{
+	vec2_zero(&scrollingOffset);
+}
diff --git a/UI/window-basic-preview.hpp b/UI/window-basic-preview.hpp
index c11581b..fed3c18 100644
--- a/UI/window-basic-preview.hpp
+++ b/UI/window-basic-preview.hpp
@@ -26,6 +26,12 @@ enum class ItemHandle : uint32_t {
 	BottomRight  = ITEM_BOTTOM | ITEM_RIGHT
 };
 
+enum class ScalingMode : uint32_t {
+	Window = 0,
+	Canvas = 1,
+	Output = 2
+};
+
 class OBSBasicPreview : public OBSQTDisplay {
 	Q_OBJECT
 
@@ -35,17 +41,21 @@ private:
 	vec2         cropSize;
 	OBSSceneItem stretchItem;
 	ItemHandle   stretchHandle = ItemHandle::None;
+	ScalingMode  scale = ScalingMode::Window;
 	vec2         stretchItemSize;
 	matrix4      screenToItem;
 	matrix4      itemToScreen;
 
 	vec2         startPos;
 	vec2         lastMoveOffset;
+	vec2         scrollingFrom;
+	vec2         scrollingOffset;
 	bool         mouseDown      = false;
 	bool         mouseMoved     = false;
 	bool         mouseOverItems = false;
 	bool         cropping       = false;
 	bool         locked         = false;
+	bool         scrollMode     = false;
 
 	static vec2 GetMouseEventPos(QMouseEvent *event);
 	static bool DrawSelectedItem(obs_scene_t *scene, obs_sceneitem_t *item,
@@ -75,16 +85,26 @@ private:
 public:
 	OBSBasicPreview(QWidget *parent, Qt::WindowFlags flags = 0);
 
+	virtual void keyPressEvent(QKeyEvent *event) override;
+	virtual void keyReleaseEvent(QKeyEvent *event) override;
+
 	virtual void mousePressEvent(QMouseEvent *event) override;
 	virtual void mouseReleaseEvent(QMouseEvent *event) override;
 	virtual void mouseMoveEvent(QMouseEvent *event) override;
 
 	void DrawSceneEditing();
+	void ResetScrollingOffset();
 
 	inline void SetLocked(bool newLockedVal) {locked = newLockedVal;}
 	inline void ToggleLocked() {locked = !locked;}
 	inline bool Locked() const {return locked;}
 
+	inline void SetScaling(ScalingMode newScaledVal) {scale = newScaledVal;}
+	inline ScalingMode GetScalingMode() const {return scale;}
+
+	inline float ScrollX() const {return scrollingOffset.x;}
+	inline float ScrollY() const {return scrollingOffset.y;}
+
 	/* use libobs allocator for alignment because the matrices itemToScreen
 	 * and screenToItem may contain SSE data, which will cause SSE
 	 * instructions to crash if the data is not aligned to at least a 16
diff --git a/UI/window-basic-properties.cpp b/UI/window-basic-properties.cpp
index 2fad427..b305f1d 100644
--- a/UI/window-basic-properties.cpp
+++ b/UI/window-basic-properties.cpp
@@ -70,21 +70,27 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
 	view = new OBSPropertiesView(settings, source,
 			(PropertiesReloadCallback)obs_source_properties,
 			(PropertiesUpdateCallback)obs_source_update);
+	view->setMinimumHeight(150);
 
-	preview->setMinimumSize(20, 20);
+	preview->setMinimumSize(20, 150);
 	preview->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,
 				QSizePolicy::Expanding));
 
+	// Create a QSplitter to keep a unified workflow here.
+	windowSplitter = new QSplitter(Qt::Orientation::Vertical, this);
+	windowSplitter->addWidget(preview);
+	windowSplitter->addWidget(view);
+	windowSplitter->setChildrenCollapsible(false);
+	//windowSplitter->setSizes(QList<int>({ 16777216, 150 }));
+	windowSplitter->setStretchFactor(0, 3);
+	windowSplitter->setStretchFactor(1, 1);
+
 	setLayout(new QVBoxLayout(this));
-	layout()->addWidget(preview);
-	layout()->addWidget(view);
+	layout()->addWidget(windowSplitter);
 	layout()->addWidget(buttonBox);
 	layout()->setAlignment(buttonBox, Qt::AlignRight | Qt::AlignBottom);
-	layout()->setAlignment(view, Qt::AlignBottom);
-	view->setMaximumHeight(250);
-	view->setMinimumHeight(150);
-	view->show();
 
+	view->show();
 	installEventFilter(CreateShortcutFilter());
 
 	const char *name = obs_source_get_name(source);
diff --git a/UI/window-basic-properties.hpp b/UI/window-basic-properties.hpp
index a5cbfa9..b21a2cf 100644
--- a/UI/window-basic-properties.hpp
+++ b/UI/window-basic-properties.hpp
@@ -20,6 +20,7 @@
 #include <QDialog>
 #include <QDialogButtonBox>
 #include <QPointer>
+#include <QSplitter>
 #include "qt-display.hpp"
 #include <obs.hpp>
 
@@ -42,6 +43,7 @@ private:
 	OBSData    oldSettings;
 	OBSPropertiesView *view;
 	QDialogButtonBox *buttonBox;
+	QSplitter *windowSplitter;
 
 	static void SourceRemoved(void *data, calldata_t *params);
 	static void SourceRenamed(void *data, calldata_t *params);
diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp
index aab5c16..9493b31 100644
--- a/UI/window-basic-settings.cpp
+++ b/UI/window-basic-settings.cpp
@@ -23,6 +23,7 @@
 #include <initializer_list>
 #include <sstream>
 #include <QCompleter>
+#include <QGuiApplication>
 #include <QLineEdit>
 #include <QMessageBox>
 #include <QCloseEvent>
@@ -30,6 +31,7 @@
 #include <QDirIterator>
 #include <QVariant>
 #include <QTreeView>
+#include <QScreen>
 #include <QStandardItemModel>
 #include <QSpacerItem>
 
@@ -42,6 +44,7 @@
 #include "qt-wrappers.hpp"
 #include "window-basic-main.hpp"
 #include "window-basic-settings.hpp"
+#include "window-basic-main-outputs.hpp"
 
 #include <util/platform.h>
 
@@ -259,7 +262,8 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 
 	PopulateAACBitrates({ui->simpleOutputABitrate,
 			ui->advOutTrack1Bitrate, ui->advOutTrack2Bitrate,
-			ui->advOutTrack3Bitrate, ui->advOutTrack4Bitrate});
+			ui->advOutTrack3Bitrate, ui->advOutTrack4Bitrate,
+			ui->advOutTrack5Bitrate, ui->advOutTrack6Bitrate});
 
 	ui->listWidget->setAttribute(Qt::WA_MacShowFocusRect, false);
 
@@ -269,14 +273,19 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 
 	HookWidget(ui->language,             COMBO_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->theme, 		     COMBO_CHANGED,  GENERAL_CHANGED);
+	HookWidget(ui->enableAutoUpdates,    CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->warnBeforeStreamStart,CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->warnBeforeStreamStop, CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->hideProjectorCursor,  CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->projectorAlwaysOnTop, CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->recordWhenStreaming,  CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->keepRecordStreamStops,CHECK_CHANGED,  GENERAL_CHANGED);
+	HookWidget(ui->replayWhileStreaming, CHECK_CHANGED,  GENERAL_CHANGED);
+	HookWidget(ui->keepReplayStreamStops,CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->systemTrayEnabled,    CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->systemTrayWhenStarted,CHECK_CHANGED,  GENERAL_CHANGED);
+	HookWidget(ui->systemTrayAlways,     CHECK_CHANGED,  GENERAL_CHANGED);
+	HookWidget(ui->saveProjectors,       CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->snappingEnabled,      CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->screenSnapping,       CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->centerSnapping,       CHECK_CHANGED,  GENERAL_CHANGED);
@@ -297,6 +306,9 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	HookWidget(ui->simpleOutRecQuality,  COMBO_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->simpleOutRecEncoder,  COMBO_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->simpleOutMuxCustom,   EDIT_CHANGED,   OUTPUTS_CHANGED);
+	HookWidget(ui->simpleReplayBuf,      CHECK_CHANGED,  OUTPUTS_CHANGED);
+	HookWidget(ui->simpleRBSecMax,       SCROLL_CHANGED, OUTPUTS_CHANGED);
+	HookWidget(ui->simpleRBMegsMax,      SCROLL_CHANGED, OUTPUTS_CHANGED);
 	HookWidget(ui->advOutEncoder,        COMBO_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutUseRescale,     CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutRescale,        CBEDIT_CHANGED, OUTPUTS_CHANGED);
@@ -304,6 +316,8 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	HookWidget(ui->advOutTrack2,         CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutTrack3,         CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutTrack4,         CHECK_CHANGED,  OUTPUTS_CHANGED);
+	HookWidget(ui->advOutTrack5,         CHECK_CHANGED,  OUTPUTS_CHANGED);
+	HookWidget(ui->advOutTrack6,         CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutApplyService,   CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutRecType,        COMBO_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutRecPath,        EDIT_CHANGED,   OUTPUTS_CHANGED);
@@ -317,6 +331,8 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	HookWidget(ui->advOutRecTrack2,      CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutRecTrack3,      CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutRecTrack4,      CHECK_CHANGED,  OUTPUTS_CHANGED);
+	HookWidget(ui->advOutRecTrack5,      CHECK_CHANGED,  OUTPUTS_CHANGED);
+	HookWidget(ui->advOutRecTrack6,      CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFType,         COMBO_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFRecPath,      EDIT_CHANGED,   OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFNoSpace,      CHECK_CHANGED,  OUTPUTS_CHANGED);
@@ -324,7 +340,9 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	HookWidget(ui->advOutFFFormat,       COMBO_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFMCfg,         EDIT_CHANGED,   OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFVBitrate,     SCROLL_CHANGED, OUTPUTS_CHANGED);
+	HookWidget(ui->advOutFFVGOPSize,     SCROLL_CHANGED, OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFUseRescale,   CHECK_CHANGED,  OUTPUTS_CHANGED);
+	HookWidget(ui->advOutFFIgnoreCompat, CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFRescale,      CBEDIT_CHANGED, OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFVEncoder,     COMBO_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFVCfg,         EDIT_CHANGED,   OUTPUTS_CHANGED);
@@ -333,7 +351,9 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	HookWidget(ui->advOutFFTrack2,       CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFTrack3,       CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFTrack4,       CHECK_CHANGED,  OUTPUTS_CHANGED);
-	HookWidget(ui->advOutFFAEncoder,     COMBO_CHANGED,   OUTPUTS_CHANGED);
+	HookWidget(ui->advOutFFTrack5,       CHECK_CHANGED,  OUTPUTS_CHANGED);
+	HookWidget(ui->advOutFFTrack6,       CHECK_CHANGED,  OUTPUTS_CHANGED);
+	HookWidget(ui->advOutFFAEncoder,     COMBO_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutFFACfg,         EDIT_CHANGED,   OUTPUTS_CHANGED);
 	HookWidget(ui->advOutTrack1Bitrate,  COMBO_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutTrack1Name,     EDIT_CHANGED,   OUTPUTS_CHANGED);
@@ -343,6 +363,10 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	HookWidget(ui->advOutTrack3Name,     EDIT_CHANGED,   OUTPUTS_CHANGED);
 	HookWidget(ui->advOutTrack4Bitrate,  COMBO_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->advOutTrack4Name,     EDIT_CHANGED,   OUTPUTS_CHANGED);
+	HookWidget(ui->advOutTrack5Bitrate,  COMBO_CHANGED,  OUTPUTS_CHANGED);
+	HookWidget(ui->advOutTrack5Name,     EDIT_CHANGED,   OUTPUTS_CHANGED);
+	HookWidget(ui->advOutTrack6Bitrate,  COMBO_CHANGED,  OUTPUTS_CHANGED);
+	HookWidget(ui->advOutTrack6Name,     EDIT_CHANGED,   OUTPUTS_CHANGED);
 	HookWidget(ui->channelSetup,         COMBO_CHANGED,  AUDIO_RESTART);
 	HookWidget(ui->sampleRate,           COMBO_CHANGED,  AUDIO_RESTART);
 	HookWidget(ui->desktopAudioDevice1,  COMBO_CHANGED,  AUDIO_CHANGED);
@@ -366,8 +390,13 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	HookWidget(ui->colorRange,           COMBO_CHANGED,  ADV_CHANGED);
 	HookWidget(ui->disableOSXVSync,      CHECK_CHANGED,  ADV_CHANGED);
 	HookWidget(ui->resetOSXVSync,        CHECK_CHANGED,  ADV_CHANGED);
+#if defined(_WIN32) || defined(__APPLE__)
+	HookWidget(ui->monitoringDevice,     COMBO_CHANGED,  ADV_CHANGED);
+#endif
 	HookWidget(ui->filenameFormatting,   EDIT_CHANGED,   ADV_CHANGED);
 	HookWidget(ui->overwriteIfExists,    CHECK_CHANGED,  ADV_CHANGED);
+	HookWidget(ui->simpleRBPrefix,       EDIT_CHANGED,   ADV_CHANGED);
+	HookWidget(ui->simpleRBSuffix,       EDIT_CHANGED,   ADV_CHANGED);
 	HookWidget(ui->streamDelayEnable,    CHECK_CHANGED,  ADV_CHANGED);
 	HookWidget(ui->streamDelaySec,       SCROLL_CHANGED, ADV_CHANGED);
 	HookWidget(ui->streamDelayPreserve,  CHECK_CHANGED,  ADV_CHANGED);
@@ -376,6 +405,19 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	HookWidget(ui->reconnectMaxRetries,  SCROLL_CHANGED, ADV_CHANGED);
 	HookWidget(ui->processPriority,      COMBO_CHANGED,  ADV_CHANGED);
 	HookWidget(ui->bindToIP,             COMBO_CHANGED,  ADV_CHANGED);
+	HookWidget(ui->enableNewSocketLoop,  CHECK_CHANGED,  ADV_CHANGED);
+	HookWidget(ui->enableLowLatencyMode, CHECK_CHANGED,  ADV_CHANGED);
+
+#if !defined(_WIN32) && !defined(__APPLE__)
+	delete ui->monitoringDevice;
+	delete ui->monitoringDeviceLabel;
+	delete ui->advAudioGroupBox;
+	delete ui->enableAutoUpdates;
+	ui->monitoringDevice = nullptr;
+	ui->monitoringDeviceLabel = nullptr;
+	ui->advAudioGroupBox = nullptr;
+	ui->enableAutoUpdates = nullptr;
+#endif
 
 #ifdef _WIN32
 	uint32_t winVer = GetWindowsVersion();
@@ -417,6 +459,8 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	delete ui->processPriorityLabel;
 	delete ui->processPriority;
 	delete ui->advancedGeneralGroupBox;
+	delete ui->enableNewSocketLoop;
+	delete ui->enableLowLatencyMode;
 	ui->rendererLabel = nullptr;
 	ui->renderer = nullptr;
 	ui->adapterLabel = nullptr;
@@ -424,6 +468,8 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	ui->processPriorityLabel = nullptr;
 	ui->processPriority = nullptr;
 	ui->advancedGeneralGroupBox = nullptr;
+	ui->enableNewSocketLoop = nullptr;
+	ui->enableLowLatencyMode = nullptr;
 #endif
 
 #ifndef __APPLE__
@@ -449,6 +495,10 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 			this, SLOT(UpdateStreamDelayEstimate()));
 	connect(ui->advOutTrack4Bitrate, SIGNAL(currentIndexChanged(int)),
 			this, SLOT(UpdateStreamDelayEstimate()));
+	connect(ui->advOutTrack5Bitrate, SIGNAL(currentIndexChanged(int)),
+			this, SLOT(UpdateStreamDelayEstimate()));
+	connect(ui->advOutTrack6Bitrate, SIGNAL(currentIndexChanged(int)),
+			this, SLOT(UpdateStreamDelayEstimate()));
 
 	//Apply button disabled until change.
 	EnableApplyButton(false);
@@ -504,11 +554,16 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 
 	FillSimpleRecordingValues();
 	FillSimpleStreamingValues();
+#if defined(_WIN32) || defined(__APPLE__)
+	FillAudioMonitoringDevices();
+#endif
 
 	connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)),
 			this, SLOT(SimpleRecordingQualityChanged()));
 	connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)),
 			this, SLOT(SimpleRecordingQualityLosslessWarning(int)));
+	connect(ui->simpleOutRecFormat, SIGNAL(currentIndexChanged(int)),
+			this, SLOT(SimpleRecordingEncoderChanged()));
 	connect(ui->simpleOutStrEncoder, SIGNAL(currentIndexChanged(int)),
 			this, SLOT(SimpleStreamingEncoderChanged()));
 	connect(ui->simpleOutStrEncoder, SIGNAL(currentIndexChanged(int)),
@@ -523,6 +578,14 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 			this, SLOT(SimpleRecordingEncoderChanged()));
 	connect(ui->simpleOutEnforce, SIGNAL(toggled(bool)),
 			this, SLOT(SimpleRecordingEncoderChanged()));
+	connect(ui->simpleReplayBuf, SIGNAL(toggled(bool)),
+			this, SLOT(SimpleReplayBufferChanged()));
+	connect(ui->simpleOutputVBitrate, SIGNAL(valueChanged(int)),
+			this, SLOT(SimpleReplayBufferChanged()));
+	connect(ui->simpleOutputABitrate, SIGNAL(currentIndexChanged(int)),
+			this, SLOT(SimpleReplayBufferChanged()));
+	connect(ui->simpleRBSecMax, SIGNAL(valueChanged(int)),
+			this, SLOT(SimpleReplayBufferChanged()));
 	connect(ui->listWidget, SIGNAL(currentRowChanged(int)),
 			this, SLOT(SimpleRecordingEncoderChanged()));
 
@@ -551,9 +614,17 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 			this, SLOT(AdvOutRecCheckWarnings()));
 	connect(ui->advOutRecTrack4, SIGNAL(clicked()),
 			this, SLOT(AdvOutRecCheckWarnings()));
+	connect(ui->advOutRecTrack5, SIGNAL(clicked()),
+			this, SLOT(AdvOutRecCheckWarnings()));
+	connect(ui->advOutRecTrack6, SIGNAL(clicked()),
+			this, SLOT(AdvOutRecCheckWarnings()));
+	connect(ui->advOutRecFormat, SIGNAL(currentIndexChanged(int)),
+			this, SLOT(AdvOutRecCheckWarnings()));
 	AdvOutRecCheckWarnings();
 
 	SimpleRecordingQualityChanged();
+
+	UpdateAutomaticReplayBufferCheckboxes();
 }
 
 void OBSBasicSettings::SaveCombo(QComboBox *widget, const char *section,
@@ -632,15 +703,28 @@ void OBSBasicSettings::LoadEncoderTypes()
 		const char *codec = obs_get_encoder_codec(type);
 		uint32_t caps = obs_get_encoder_caps(type);
 
-		if (strcmp(codec, "h264") != 0)
+		if (obs_get_encoder_type(type) != OBS_ENCODER_VIDEO)
 			continue;
+
+		const char* streaming_codecs[] = {
+			"h264",
+			//"hevc",
+		};
+		bool is_streaming_codec = false;
+		for (const char* test_codec : streaming_codecs) {
+			if (strcmp(codec, test_codec) == 0) {
+				is_streaming_codec = true;
+				break;
+			}
+		}
 		if ((caps & OBS_ENCODER_CAP_DEPRECATED) != 0)
 			continue;
 
 		QString qName = QT_UTF8(name);
 		QString qType = QT_UTF8(type);
 
-		ui->advOutEncoder->addItem(qName, qType);
+		if (is_streaming_codec)
+			ui->advOutEncoder->addItem(qName, qType);
 		ui->advOutRecEncoder->addItem(qName, qType);
 	}
 }
@@ -736,7 +820,9 @@ void OBSBasicSettings::ReloadCodecs(const ff_format_desc *formatDesc)
 	if (formatDesc == nullptr)
 		return;
 
-	OBSFFCodecDesc codecDescs(ff_codec_supported(formatDesc));
+	bool ignore_compatability = ui->advOutFFIgnoreCompat->isChecked();
+	OBSFFCodecDesc codecDescs(ff_codec_supported(formatDesc,
+				ignore_compatability));
 
 	const ff_codec_desc *codec = codecDescs.get();
 
@@ -840,6 +926,12 @@ void OBSBasicSettings::LoadGeneralSettings()
 	LoadLanguageList();
 	LoadThemeList();
 
+#if defined(_WIN32) || defined(__APPLE__)
+	bool enableAutoUpdates = config_get_bool(GetGlobalConfig(),
+			"General", "EnableAutoUpdates");
+	ui->enableAutoUpdates->setChecked(enableAutoUpdates);
+#endif
+
 	bool recordWhenStreaming = config_get_bool(GetGlobalConfig(),
 			"BasicWindow", "RecordWhenStreaming");
 	ui->recordWhenStreaming->setChecked(recordWhenStreaming);
@@ -848,6 +940,14 @@ void OBSBasicSettings::LoadGeneralSettings()
 			"BasicWindow", "KeepRecordingWhenStreamStops");
 	ui->keepRecordStreamStops->setChecked(keepRecordStreamStops);
 
+	bool replayWhileStreaming = config_get_bool(GetGlobalConfig(),
+		"BasicWindow", "ReplayBufferWhileStreaming");
+	ui->replayWhileStreaming->setChecked(replayWhileStreaming);
+
+	bool keepReplayStreamStops = config_get_bool(GetGlobalConfig(),
+		"BasicWindow", "KeepReplayBufferStreamStops");
+	ui->keepReplayStreamStops->setChecked(keepReplayStreamStops);
+
 	bool systemTrayEnabled = config_get_bool(GetGlobalConfig(),
 			"BasicWindow", "SysTrayEnabled");
 	ui->systemTrayEnabled->setChecked(systemTrayEnabled);
@@ -856,6 +956,14 @@ void OBSBasicSettings::LoadGeneralSettings()
 			"BasicWindow", "SysTrayWhenStarted");
 	ui->systemTrayWhenStarted->setChecked(systemTrayWhenStarted);
 
+	bool systemTrayAlways = config_get_bool(GetGlobalConfig(),
+			"BasicWindow", "SysTrayMinimizeToTray");
+	ui->systemTrayAlways->setChecked(systemTrayAlways);
+
+	bool saveProjectors = config_get_bool(GetGlobalConfig(),
+			"BasicWindow", "SaveProjectors");
+	ui->saveProjectors->setChecked(saveProjectors);
+
 	bool snappingEnabled = config_get_bool(GetGlobalConfig(),
 			"BasicWindow", "SnappingEnabled");
 	ui->snappingEnabled->setChecked(snappingEnabled);
@@ -950,8 +1058,6 @@ void OBSBasicSettings::LoadRendererList()
 #endif
 }
 
-Q_DECLARE_METATYPE(MonitorInfo);
-
 static string ResString(uint32_t cx, uint32_t cy)
 {
 	stringstream res;
@@ -1097,14 +1203,12 @@ void OBSBasicSettings::LoadResolutionLists()
 	uint32_t cy = config_get_uint(main->Config(), "Video", "BaseCY");
 	uint32_t out_cx = config_get_uint(main->Config(), "Video", "OutputCX");
 	uint32_t out_cy = config_get_uint(main->Config(), "Video", "OutputCY");
-	vector<MonitorInfo> monitors;
 
 	ui->baseResolution->clear();
 
-	GetMonitors(monitors);
-
-	for (MonitorInfo &monitor : monitors) {
-		string res = ResString(monitor.cx, monitor.cy);
+	for (QScreen* screen: QGuiApplication::screens()) {
+		QSize as = screen->size();
+		string res = ResString(as.width(), as.height());
 		ui->baseResolution->addItem(res.c_str());
 	}
 
@@ -1124,7 +1228,7 @@ static inline void LoadFPSCommon(OBSBasic *main, Ui::OBSBasicSettings *ui)
 			"FPSCommon");
 
 	int idx = ui->fpsCommon->findText(val);
-	if (idx == -1) idx = 3;
+	if (idx == -1) idx = 4;
 	ui->fpsCommon->setCurrentIndex(idx);
 }
 
@@ -1208,6 +1312,8 @@ void OBSBasicSettings::LoadSimpleOutputSettings()
 			"QSVPreset");
 	const char *nvPreset = config_get_string(main->Config(), "SimpleOutput",
 			"NVENCPreset");
+	const char* amdPreset = config_get_string(main->Config(), "SimpleOutput",
+			"AMDPreset");
 	const char *custom = config_get_string(main->Config(), "SimpleOutput",
 			"x264Settings");
 	const char *recQual = config_get_string(main->Config(), "SimpleOutput",
@@ -1216,10 +1322,17 @@ void OBSBasicSettings::LoadSimpleOutputSettings()
 			"RecEncoder");
 	const char *muxCustom = config_get_string(main->Config(),
 			"SimpleOutput", "MuxerCustom");
+	bool replayBuf = config_get_bool(main->Config(), "SimpleOutput",
+			"RecRB");
+	int rbTime = config_get_int(main->Config(), "SimpleOutput",
+			"RecRBTime");
+	int rbSize = config_get_int(main->Config(), "SimpleOutput",
+			"RecRBSize");
 
 	curPreset = preset;
 	curQSVPreset = qsvPreset;
 	curNVENCPreset = nvPreset;
+	curAMDPreset = amdPreset;
 
 	audioBitrate = FindClosestAvailableAACBitrate(audioBitrate);
 
@@ -1251,6 +1364,10 @@ void OBSBasicSettings::LoadSimpleOutputSettings()
 
 	ui->simpleOutMuxCustom->setText(muxCustom);
 
+	ui->simpleReplayBuf->setChecked(replayBuf);
+	ui->simpleRBSecMax->setValue(rbTime);
+	ui->simpleRBMegsMax->setValue(rbSize);
+
 	SimpleStreamingEncoderChanged();
 }
 
@@ -1283,6 +1400,8 @@ void OBSBasicSettings::LoadAdvOutputStreamingSettings()
 	case 2: ui->advOutTrack2->setChecked(true); break;
 	case 3: ui->advOutTrack3->setChecked(true); break;
 	case 4: ui->advOutTrack4->setChecked(true); break;
+	case 5: ui->advOutTrack5->setChecked(true); break;
+	case 6: ui->advOutTrack6->setChecked(true); break;
 	}
 }
 
@@ -1292,14 +1411,16 @@ OBSPropertiesView *OBSBasicSettings::CreateEncoderPropertyView(
 	obs_data_t *settings = obs_encoder_defaults(encoder);
 	OBSPropertiesView *view;
 
-	char encoderJsonPath[512];
-	int ret = GetProfilePath(encoderJsonPath, sizeof(encoderJsonPath),
-			path);
-	if (ret > 0) {
-		obs_data_t *data = obs_data_create_from_json_file_safe(
-				encoderJsonPath, "bak");
-		obs_data_apply(settings, data);
-		obs_data_release(data);
+	if (path) {
+		char encoderJsonPath[512];
+		int ret = GetProfilePath(encoderJsonPath,
+				sizeof(encoderJsonPath), path);
+		if (ret > 0) {
+			obs_data_t *data = obs_data_create_from_json_file_safe(
+					encoderJsonPath, "bak");
+			obs_data_apply(settings, data);
+			obs_data_release(data);
+		}
 	}
 
 	view = new OBSPropertiesView(settings, encoder,
@@ -1375,6 +1496,8 @@ void OBSBasicSettings::LoadAdvOutputRecordingSettings()
 	ui->advOutRecTrack2->setChecked(tracks & (1<<1));
 	ui->advOutRecTrack3->setChecked(tracks & (1<<2));
 	ui->advOutRecTrack4->setChecked(tracks & (1<<3));
+	ui->advOutRecTrack5->setChecked(tracks & (1<<4));
+	ui->advOutRecTrack6->setChecked(tracks & (1<<5));
 }
 
 void OBSBasicSettings::LoadAdvOutputRecordingEncoderProperties()
@@ -1447,8 +1570,12 @@ void OBSBasicSettings::LoadAdvOutputFFmpegSettings()
 			"FFMCustom");
 	int videoBitrate = config_get_int(main->Config(), "AdvOut",
 			"FFVBitrate");
+	int gopSize = config_get_int(main->Config(), "AdvOut",
+			"FFVGOPSize");
 	bool rescale = config_get_bool(main->Config(), "AdvOut",
 			"FFRescale");
+	bool codecCompat = config_get_bool(main->Config(), "AdvOut",
+			"FFIgnoreCompat");
 	const char *rescaleRes = config_get_string(main->Config(), "AdvOut",
 			"FFRescaleRes");
 	const char *vEncoder = config_get_string(main->Config(), "AdvOut",
@@ -1475,7 +1602,9 @@ void OBSBasicSettings::LoadAdvOutputFFmpegSettings()
 	SelectFormat(ui->advOutFFFormat, format, mimeType);
 	ui->advOutFFMCfg->setText(muxCustom);
 	ui->advOutFFVBitrate->setValue(videoBitrate);
+	ui->advOutFFVGOPSize->setValue(gopSize);
 	ui->advOutFFUseRescale->setChecked(rescale);
+	ui->advOutFFIgnoreCompat->setChecked(codecCompat);
 	ui->advOutFFRescale->setEnabled(rescale);
 	ui->advOutFFRescale->setCurrentText(rescaleRes);
 	SelectEncoder(ui->advOutFFVEncoder, vEncoder, vEncoderId);
@@ -1489,6 +1618,8 @@ void OBSBasicSettings::LoadAdvOutputFFmpegSettings()
 	case 2: ui->advOutFFTrack2->setChecked(true); break;
 	case 3: ui->advOutFFTrack3->setChecked(true); break;
 	case 4: ui->advOutFFTrack4->setChecked(true); break;
+	case 5: ui->advOutFFTrack5->setChecked(true); break;
+	case 6: ui->advOutFFTrack6->setChecked(true); break;
 	}
 }
 
@@ -1502,6 +1633,10 @@ void OBSBasicSettings::LoadAdvOutputAudioSettings()
 			"Track3Bitrate");
 	int track4Bitrate = config_get_uint(main->Config(), "AdvOut",
 			"Track4Bitrate");
+	int track5Bitrate = config_get_uint(main->Config(), "AdvOut",
+			"Track5Bitrate");
+	int track6Bitrate = config_get_uint(main->Config(), "AdvOut",
+			"Track6Bitrate");
 	const char *name1 = config_get_string(main->Config(), "AdvOut",
 			"Track1Name");
 	const char *name2 = config_get_string(main->Config(), "AdvOut",
@@ -1510,11 +1645,17 @@ void OBSBasicSettings::LoadAdvOutputAudioSettings()
 			"Track3Name");
 	const char *name4 = config_get_string(main->Config(), "AdvOut",
 			"Track4Name");
+	const char *name5 = config_get_string(main->Config(), "AdvOut",
+			"Track5Name");
+	const char *name6 = config_get_string(main->Config(), "AdvOut",
+			"Track6Name");
 
 	track1Bitrate = FindClosestAvailableAACBitrate(track1Bitrate);
 	track2Bitrate = FindClosestAvailableAACBitrate(track2Bitrate);
 	track3Bitrate = FindClosestAvailableAACBitrate(track3Bitrate);
 	track4Bitrate = FindClosestAvailableAACBitrate(track4Bitrate);
+	track5Bitrate = FindClosestAvailableAACBitrate(track5Bitrate);
+	track6Bitrate = FindClosestAvailableAACBitrate(track6Bitrate);
 
 	SetComboByName(ui->advOutTrack1Bitrate,
 			std::to_string(track1Bitrate).c_str());
@@ -1524,11 +1665,17 @@ void OBSBasicSettings::LoadAdvOutputAudioSettings()
 			std::to_string(track3Bitrate).c_str());
 	SetComboByName(ui->advOutTrack4Bitrate,
 			std::to_string(track4Bitrate).c_str());
+	SetComboByName(ui->advOutTrack5Bitrate,
+			std::to_string(track5Bitrate).c_str());
+	SetComboByName(ui->advOutTrack6Bitrate,
+			std::to_string(track6Bitrate).c_str());
 
 	ui->advOutTrack1Name->setText(name1);
 	ui->advOutTrack2Name->setText(name2);
 	ui->advOutTrack3Name->setText(name3);
 	ui->advOutTrack4Name->setText(name4);
+	ui->advOutTrack5Name->setText(name5);
+	ui->advOutTrack6Name->setText(name6);
 }
 
 void OBSBasicSettings::LoadOutputSettings()
@@ -1551,10 +1698,13 @@ void OBSBasicSettings::LoadOutputSettings()
 	if (video_output_active(obs_get_video())) {
 		ui->outputMode->setEnabled(false);
 		ui->outputModeLabel->setEnabled(false);
+		ui->simpleRecordingGroupBox->setEnabled(false);
+		ui->replayBufferGroupBox->setEnabled(false);
 		ui->advOutTopContainer->setEnabled(false);
 		ui->advOutRecTopContainer->setEnabled(false);
 		ui->advOutRecTypeContainer->setEnabled(false);
 		ui->advOutputAudioTracksTab->setEnabled(false);
+		ui->advNetworkGroupBox->setEnabled(false);
 	}
 
 	loading = false;
@@ -1570,6 +1720,7 @@ void OBSBasicSettings::SetAdvOutputFFmpegEnablement(
 	switch (encoderType) {
 	case FF_CODEC_VIDEO:
 		ui->advOutFFVBitrate->setEnabled(enabled);
+		ui->advOutFFVGOPSize->setEnabled(enabled);
 		ui->advOutFFUseRescale->setEnabled(enabled);
 		ui->advOutFFRescale->setEnabled(enabled && rescale);
 		ui->advOutFFVEncoder->setEnabled(enabled || enableEncoder);
@@ -1583,6 +1734,8 @@ void OBSBasicSettings::SetAdvOutputFFmpegEnablement(
 		ui->advOutFFTrack2->setEnabled(enabled);
 		ui->advOutFFTrack3->setEnabled(enabled);
 		ui->advOutFFTrack4->setEnabled(enabled);
+		ui->advOutFFTrack5->setEnabled(enabled);
+		ui->advOutFFTrack6->setEnabled(enabled);
 	default:
 		break;
 	}
@@ -1824,6 +1977,12 @@ void OBSBasicSettings::LoadAdvancedSettings()
 			"Video", "ColorSpace");
 	const char *videoColorRange = config_get_string(main->Config(),
 			"Video", "ColorRange");
+#if defined(_WIN32) || defined(__APPLE__)
+	const char *monDevName = config_get_string(main->Config(), "Audio",
+			"MonitoringDeviceName");
+	const char *monDevId = config_get_string(main->Config(), "Audio",
+			"MonitoringDeviceId");
+#endif
 	bool enableDelay = config_get_bool(main->Config(), "Output",
 			"DelayEnable");
 	int delaySec = config_get_int(main->Config(), "Output",
@@ -1842,13 +2001,39 @@ void OBSBasicSettings::LoadAdvancedSettings()
 			"OverwriteIfExists");
 	const char *bindIP = config_get_string(main->Config(), "Output",
 			"BindIP");
+	const char *rbPrefix = config_get_string(main->Config(), "SimpleOutput",
+			"RecRBPrefix");
+	const char *rbSuffix = config_get_string(main->Config(), "SimpleOutput",
+			"RecRBSuffix");
+	int idx;
 
 	loading = true;
 
 	LoadRendererList();
 
+#if defined(_WIN32) || defined(__APPLE__)
+	QComboBox *cb = ui->monitoringDevice;
+	idx = cb->findData(monDevId);
+	if (idx == -1) {
+		cb->insertItem(0, monDevName, monDevId);
+
+		QStandardItemModel *model =
+			dynamic_cast<QStandardItemModel*>(cb->model());
+		if (!model)
+			return;
+
+		QStandardItem *item = model->item(0);
+		item->setFlags(Qt::NoItemFlags);
+
+		idx = 0;
+	}
+	cb->setCurrentIndex(idx);
+#endif
+
 	ui->filenameFormatting->setText(filename);
 	ui->overwriteIfExists->setChecked(overwriteIfExists);
+	ui->simpleRBPrefix->setText(rbPrefix);
+	ui->simpleRBSuffix->setText(rbSuffix);
 
 	ui->reconnectEnable->setChecked(reconnect);
 	ui->reconnectRetryDelay->setValue(retryDelay);
@@ -1858,6 +2043,7 @@ void OBSBasicSettings::LoadAdvancedSettings()
 	ui->streamDelayPreserve->setChecked(preserveDelay);
 	ui->streamDelayEnable->setChecked(enableDelay);
 
+
 	SetComboByName(ui->colorFormat, videoColorFormat);
 	SetComboByName(ui->colorSpace, videoColorSpace);
 	SetComboByValue(ui->colorRange, videoColorRange);
@@ -1879,10 +2065,18 @@ void OBSBasicSettings::LoadAdvancedSettings()
 #elif _WIN32
 	const char *processPriority = config_get_string(App()->GlobalConfig(),
 			"General", "ProcessPriority");
-	int idx = ui->processPriority->findData(processPriority);
+	bool enableNewSocketLoop = config_get_bool(main->Config(), "Output",
+			"NewSocketLoopEnable");
+	bool enableLowLatencyMode = config_get_bool(main->Config(), "Output",
+			"LowLatencyEnable");
+
+	idx = ui->processPriority->findData(processPriority);
 	if (idx == -1)
 		idx = ui->processPriority->findData("Normal");
 	ui->processPriority->setCurrentIndex(idx);
+
+	ui->enableNewSocketLoop->setChecked(enableNewSocketLoop);
+	ui->enableLowLatencyMode->setChecked(enableLowLatencyMode);
 #endif
 
 	loading = false;
@@ -2210,6 +2404,12 @@ void OBSBasicSettings::SaveGeneralSettings()
 		App()->SetTheme(theme);
 	}
 
+#if defined(_WIN32) || defined(__APPLE__)
+	if (WidgetChanged(ui->enableAutoUpdates))
+		config_set_bool(GetGlobalConfig(), "General",
+				"EnableAutoUpdates",
+				ui->enableAutoUpdates->isChecked());
+#endif
 	if (WidgetChanged(ui->snappingEnabled))
 		config_set_bool(GetGlobalConfig(), "BasicWindow",
 				"SnappingEnabled",
@@ -2254,6 +2454,15 @@ void OBSBasicSettings::SaveGeneralSettings()
 				"KeepRecordingWhenStreamStops",
 				ui->keepRecordStreamStops->isChecked());
 
+	if (WidgetChanged(ui->replayWhileStreaming))
+		config_set_bool(GetGlobalConfig(), "BasicWindow",
+			"ReplayBufferWhileStreaming",
+			ui->replayWhileStreaming->isChecked());
+	if (WidgetChanged(ui->keepReplayStreamStops))
+		config_set_bool(GetGlobalConfig(), "BasicWindow",
+			"KeepReplayBufferStreamStops",
+			ui->keepReplayStreamStops->isChecked());
+
 	if (WidgetChanged(ui->systemTrayEnabled))
 		config_set_bool(GetGlobalConfig(), "BasicWindow",
 				"SysTrayEnabled",
@@ -2263,6 +2472,16 @@ void OBSBasicSettings::SaveGeneralSettings()
 		config_set_bool(GetGlobalConfig(), "BasicWindow",
 				"SysTrayWhenStarted",
 				ui->systemTrayWhenStarted->isChecked());
+
+	if (WidgetChanged(ui->systemTrayAlways))
+		config_set_bool(GetGlobalConfig(),
+				"BasicWindow", "SysTrayMinimizeToTray",
+				ui->systemTrayAlways->isChecked());
+
+	if (WidgetChanged(ui->saveProjectors))
+		config_set_bool(GetGlobalConfig(), "BasicWindow",
+				"SaveProjectors",
+				ui->saveProjectors->isChecked());
 }
 
 void OBSBasicSettings::SaveStream1Settings()
@@ -2325,6 +2544,9 @@ void OBSBasicSettings::SaveVideoSettings()
 
 void OBSBasicSettings::SaveAdvancedSettings()
 {
+	QString lastMonitoringDevice = config_get_string(main->Config(),
+			"Audio", "MonitoringDeviceId");
+
 #ifdef _WIN32
 	if (WidgetChanged(ui->renderer))
 		config_set_string(App()->GlobalConfig(), "Video", "Renderer",
@@ -2336,6 +2558,9 @@ void OBSBasicSettings::SaveAdvancedSettings()
 			priority.c_str());
 	if (main->Active())
 		SetProcessPriority(priority.c_str());
+
+	SaveCheckBox(ui->enableNewSocketLoop, "Output", "NewSocketLoopEnable");
+	SaveCheckBox(ui->enableLowLatencyMode, "Output", "LowLatencyEnable");
 #endif
 
 #ifdef __APPLE__
@@ -2354,7 +2579,13 @@ void OBSBasicSettings::SaveAdvancedSettings()
 	SaveCombo(ui->colorFormat, "Video", "ColorFormat");
 	SaveCombo(ui->colorSpace, "Video", "ColorSpace");
 	SaveComboData(ui->colorRange, "Video", "ColorRange");
+#if defined(_WIN32) || defined(__APPLE__)
+	SaveCombo(ui->monitoringDevice, "Audio", "MonitoringDeviceName");
+	SaveComboData(ui->monitoringDevice, "Audio", "MonitoringDeviceId");
+#endif
 	SaveEdit(ui->filenameFormatting, "Output", "FilenameFormatting");
+	SaveEdit(ui->simpleRBPrefix, "SimpleOutput", "RecRBPrefix");
+	SaveEdit(ui->simpleRBSuffix, "SimpleOutput", "RecRBSuffix");
 	SaveCheckBox(ui->overwriteIfExists, "Output", "OverwriteIfExists");
 	SaveCheckBox(ui->streamDelayEnable, "Output", "DelayEnable");
 	SaveSpinBox(ui->streamDelaySec, "Output", "DelaySec");
@@ -2363,6 +2594,20 @@ void OBSBasicSettings::SaveAdvancedSettings()
 	SaveSpinBox(ui->reconnectRetryDelay, "Output", "RetryDelay");
 	SaveSpinBox(ui->reconnectMaxRetries, "Output", "MaxRetries");
 	SaveComboData(ui->bindToIP, "Output", "BindIP");
+
+#if defined(_WIN32) || defined(__APPLE__)
+	QString newDevice = ui->monitoringDevice->currentData().toString();
+
+	if (lastMonitoringDevice != newDevice) {
+		obs_set_audio_monitoring_device(
+				QT_TO_UTF8(ui->monitoringDevice->currentText()),
+				QT_TO_UTF8(newDevice));
+
+		blog(LOG_INFO, "Audio monitoring device:\n\tname: %s\n\tid: %s",
+				QT_TO_UTF8(ui->monitoringDevice->currentText()),
+				QT_TO_UTF8(newDevice));
+	}
+#endif
 }
 
 static inline const char *OutputModeFromIdx(int idx)
@@ -2403,12 +2648,16 @@ static void SaveTrackIndex(config_t *config, const char *section,
 		QAbstractButton *check1,
 		QAbstractButton *check2,
 		QAbstractButton *check3,
-		QAbstractButton *check4)
+		QAbstractButton *check4,
+		QAbstractButton *check5,
+		QAbstractButton *check6)
 {
 	if (check1->isChecked()) config_set_int(config, section, name, 1);
 	else if (check2->isChecked()) config_set_int(config, section, name, 2);
 	else if (check3->isChecked()) config_set_int(config, section, name, 3);
 	else if (check4->isChecked()) config_set_int(config, section, name, 4);
+	else if (check5->isChecked()) config_set_int(config, section, name, 5);
+	else if (check6->isChecked()) config_set_int(config, section, name, 6);
 }
 
 void OBSBasicSettings::SaveFormat(QComboBox *combo)
@@ -2426,7 +2675,7 @@ void OBSBasicSettings::SaveFormat(QComboBox *combo)
 
 		char *comma = strchr(&extStr[0], ',');
 		if (comma)
-			comma = 0;
+			*comma = 0;
 
 		config_set_string(main->Config(), "AdvOut", "FFExtension",
 				extStr.c_str());
@@ -2485,6 +2734,9 @@ void OBSBasicSettings::SaveOutputSettings()
 	SaveComboData(ui->simpleOutRecQuality, "SimpleOutput", "RecQuality");
 	SaveComboData(ui->simpleOutRecEncoder, "SimpleOutput", "RecEncoder");
 	SaveEdit(ui->simpleOutMuxCustom, "SimpleOutput", "MuxerCustom");
+	SaveCheckBox(ui->simpleReplayBuf, "SimpleOutput", "RecRB");
+	SaveSpinBox(ui->simpleRBSecMax, "SimpleOutput", "RecRBTime");
+	SaveSpinBox(ui->simpleRBMegsMax, "SimpleOutput", "RecRBSize");
 
 	curAdvStreamEncoder = GetComboData(ui->advOutEncoder);
 
@@ -2494,7 +2746,8 @@ void OBSBasicSettings::SaveOutputSettings()
 	SaveCombo(ui->advOutRescale, "AdvOut", "RescaleRes");
 	SaveTrackIndex(main->Config(), "AdvOut", "TrackIndex",
 			ui->advOutTrack1, ui->advOutTrack2,
-			ui->advOutTrack3, ui->advOutTrack4);
+			ui->advOutTrack3, ui->advOutTrack4,
+			ui->advOutTrack5, ui->advOutTrack6);
 
 	config_set_string(main->Config(), "AdvOut", "RecType",
 			RecTypeFromIdx(ui->advOutRecType->currentIndex()));
@@ -2513,7 +2766,9 @@ void OBSBasicSettings::SaveOutputSettings()
 			(ui->advOutRecTrack1->isChecked() ? (1<<0) : 0) |
 			(ui->advOutRecTrack2->isChecked() ? (1<<1) : 0) |
 			(ui->advOutRecTrack3->isChecked() ? (1<<2) : 0) |
-			(ui->advOutRecTrack4->isChecked() ? (1<<3) : 0));
+			(ui->advOutRecTrack4->isChecked() ? (1<<3) : 0) |
+			(ui->advOutRecTrack5->isChecked() ? (1<<4) : 0) |
+			(ui->advOutRecTrack6->isChecked() ? (1<<5) : 0));
 
 	config_set_bool(main->Config(), "AdvOut", "FFOutputToFile",
 			ui->advOutFFType->currentIndex() == 0 ? true : false);
@@ -2523,7 +2778,9 @@ void OBSBasicSettings::SaveOutputSettings()
 	SaveFormat(ui->advOutFFFormat);
 	SaveEdit(ui->advOutFFMCfg, "AdvOut", "FFMCustom");
 	SaveSpinBox(ui->advOutFFVBitrate, "AdvOut", "FFVBitrate");
+	SaveSpinBox(ui->advOutFFVGOPSize, "AdvOut", "FFVGOPSize");
 	SaveCheckBox(ui->advOutFFUseRescale, "AdvOut", "FFRescale");
+	SaveCheckBox(ui->advOutFFIgnoreCompat, "AdvOut", "FFIgnoreCompat");
 	SaveCombo(ui->advOutFFRescale, "AdvOut", "FFRescaleRes");
 	SaveEncoder(ui->advOutFFVEncoder, "AdvOut", "FFVEncoder");
 	SaveEdit(ui->advOutFFVCfg, "AdvOut", "FFVCustom");
@@ -2532,16 +2789,21 @@ void OBSBasicSettings::SaveOutputSettings()
 	SaveEdit(ui->advOutFFACfg, "AdvOut", "FFACustom");
 	SaveTrackIndex(main->Config(), "AdvOut", "FFAudioTrack",
 			ui->advOutFFTrack1, ui->advOutFFTrack2,
-			ui->advOutFFTrack3, ui->advOutFFTrack4);
+			ui->advOutFFTrack3, ui->advOutFFTrack4,
+			ui->advOutFFTrack5, ui->advOutFFTrack6);
 
 	SaveCombo(ui->advOutTrack1Bitrate, "AdvOut", "Track1Bitrate");
 	SaveCombo(ui->advOutTrack2Bitrate, "AdvOut", "Track2Bitrate");
 	SaveCombo(ui->advOutTrack3Bitrate, "AdvOut", "Track3Bitrate");
 	SaveCombo(ui->advOutTrack4Bitrate, "AdvOut", "Track4Bitrate");
+	SaveCombo(ui->advOutTrack5Bitrate, "AdvOut", "Track5Bitrate");
+	SaveCombo(ui->advOutTrack6Bitrate, "AdvOut", "Track6Bitrate");
 	SaveEdit(ui->advOutTrack1Name, "AdvOut", "Track1Name");
 	SaveEdit(ui->advOutTrack2Name, "AdvOut", "Track2Name");
 	SaveEdit(ui->advOutTrack3Name, "AdvOut", "Track3Name");
 	SaveEdit(ui->advOutTrack4Name, "AdvOut", "Track4Name");
+	SaveEdit(ui->advOutTrack5Name, "AdvOut", "Track5Name");
+	SaveEdit(ui->advOutTrack6Name, "AdvOut", "Track6Name");
 
 	WriteJsonData(streamEncoderProps, "streamEncoder.json");
 	WriteJsonData(recordEncoderProps, "recordEncoder.json");
@@ -2632,6 +2894,18 @@ void OBSBasicSettings::SaveHotkeySettings()
 		obs_data_release(data);
 		obs_data_array_release(array);
 	}
+
+	if (!main->outputHandler || !main->outputHandler->replayBuffer)
+		return;
+
+	const char *id = obs_obj_get_id(main->outputHandler->replayBuffer);
+	if (strcmp(id, "replay_buffer") == 0) {
+		obs_data_t *hotkeys = obs_hotkeys_save_output(
+				main->outputHandler->replayBuffer);
+		config_set_string(config, "Hotkeys", "ReplayBuffer",
+				obs_data_get_json(hotkeys));
+		obs_data_release(hotkeys);
+	}
 }
 
 #define MINOR_SEPARATOR \
@@ -2864,6 +3138,13 @@ void OBSBasicSettings::on_advOutRecEncoder_currentIndexChanged(int idx)
 	}
 }
 
+void OBSBasicSettings::on_advOutFFIgnoreCompat_stateChanged(int)
+{
+	/* Little hack to reload codecs when checked */
+	on_advOutFFFormat_currentIndexChanged(
+			ui->advOutFFFormat->currentIndex());
+}
+
 #define DEFAULT_CONTAINER_STR \
 	QTStr("Basic.Settings.Output.Adv.FFmpeg.FormatDescDef")
 
@@ -2975,6 +3256,7 @@ void OBSBasicSettings::on_filenameFormatting_textEdited(const QString &text)
 		text.toStdString().find_first_of("<>:\"|?*");
 #else
 	size_t invalidLocation = string::npos;
+	UNUSED_PARAMETER(text);
 #endif
 
 	if (invalidLocation != string::npos)
@@ -3126,28 +3408,39 @@ void OBSBasicSettings::AdvOutRecCheckWarnings()
 		return box->isChecked() ? 1 : 0;
 	};
 
-	QString msg;
+	QString errorMsg;
+	QString warningMsg;
 	uint32_t tracks =
 		Checked(ui->advOutRecTrack1) +
 		Checked(ui->advOutRecTrack2) +
 		Checked(ui->advOutRecTrack3) +
-		Checked(ui->advOutRecTrack4);
-	const char *objectName = nullptr;
+		Checked(ui->advOutRecTrack4) +
+		Checked(ui->advOutRecTrack5) +
+		Checked(ui->advOutRecTrack6);
 
 	if (tracks == 0) {
-		msg = QTStr("OutputWarnings.NoTracksSelected");
-		objectName = "errorLabel";
+		errorMsg = QTStr("OutputWarnings.NoTracksSelected");
 
 	} else if (tracks > 1) {
-		msg = QTStr("OutputWarnings.MultiTrackRecording");
-		objectName = "warningLabel";
+		warningMsg = QTStr("OutputWarnings.MultiTrackRecording");
+	}
+
+	if (ui->advOutRecFormat->currentText().compare("mp4") == 0) {
+		if (!warningMsg.isEmpty())
+			warningMsg += "\n\n";
+		warningMsg += QTStr("OutputWarnings.MP4Recording");
 	}
 
 	delete advOutRecWarning;
 
-	if (!msg.isEmpty()) {
-		advOutRecWarning = new QLabel(msg, this);
-		advOutRecWarning->setObjectName(objectName);
+	if (!errorMsg.isEmpty() || !warningMsg.isEmpty()) {
+		advOutRecWarning = new QLabel(
+				errorMsg.isEmpty() ? warningMsg : errorMsg,
+				this);
+		advOutRecWarning->setObjectName(
+				errorMsg.isEmpty() ? "warningLabel" :
+					"errorLabel");
+		advOutRecWarning->setWordWrap(true);
 
 		QFormLayout *formLayout = reinterpret_cast<QFormLayout*>(
 				ui->advOutRecTopContainer->layout());
@@ -3189,6 +3482,8 @@ void OBSBasicSettings::UpdateAdvOutStreamDelayEstimate()
 	case 2: aBitrateText = ui->advOutTrack2Bitrate->currentText(); break;
 	case 3: aBitrateText = ui->advOutTrack3Bitrate->currentText(); break;
 	case 4: aBitrateText = ui->advOutTrack4Bitrate->currentText(); break;
+	case 5: aBitrateText = ui->advOutTrack5Bitrate->currentText(); break;
+	case 6: aBitrateText = ui->advOutTrack6Bitrate->currentText(); break;
 	}
 
 	int seconds = ui->streamDelaySec->value();
@@ -3206,6 +3501,8 @@ void OBSBasicSettings::UpdateStreamDelayEstimate()
 		UpdateSimpleOutStreamDelayEstimate();
 	else
 		UpdateAdvOutStreamDelayEstimate();
+
+	UpdateAutomaticReplayBufferCheckboxes();
 }
 
 static bool EncoderAvailable(const char *encoder)
@@ -3275,6 +3572,23 @@ void OBSBasicSettings::FillSimpleStreamingValues()
 #undef ENCODER_STR
 }
 
+void OBSBasicSettings::FillAudioMonitoringDevices()
+{
+	QComboBox *cb = ui->monitoringDevice;
+
+	auto enum_devices = [] (void *param, const char *name, const char *id)
+	{
+		QComboBox *cb = (QComboBox*)param;
+		cb->addItem(name, id);
+		return true;
+	};
+
+	cb->addItem(QTStr("Basic.Settings.Advanced.Audio.MonitoringDevice"
+				".Default"), "default");
+
+	obs_enum_audio_monitoring_devices(enum_devices, cb);
+}
+
 void OBSBasicSettings::SimpleRecordingQualityChanged()
 {
 	QString qual = ui->simpleOutRecQuality->currentData().toString();
@@ -3288,6 +3602,7 @@ void OBSBasicSettings::SimpleRecordingQualityChanged()
 	ui->simpleOutRecFormatLabel->setVisible(!losslessQuality);
 
 	SimpleRecordingEncoderChanged();
+	SimpleReplayBufferChanged();
 }
 
 void OBSBasicSettings::SimpleStreamingEncoderChanged()
@@ -3333,9 +3648,12 @@ void OBSBasicSettings::SimpleStreamingEncoderChanged()
 		preset = curNVENCPreset;
 
 	} else if (encoder == SIMPLE_ENCODER_AMD) {
-		/* none */
-		defaultPreset = "";
+		ui->simpleOutPreset->addItem("Speed", "speed");
+		ui->simpleOutPreset->addItem("Balanced", "balanced");
+		ui->simpleOutPreset->addItem("Quality", "quality");
 
+		defaultPreset = "balanced";
+		preset = curAMDPreset;
 	} else {
 		ui->simpleOutPreset->addItem("ultrafast", "ultrafast");
 		ui->simpleOutPreset->addItem("superfast", "superfast");
@@ -3357,6 +3675,51 @@ void OBSBasicSettings::SimpleStreamingEncoderChanged()
 	ui->simpleOutPreset->setCurrentIndex(idx);
 }
 
+#define ESTIMATE_STR "Basic.Settings.Output.ReplayBuffer.Estimate"
+#define ESTIMATE_UNKNOWN_STR \
+	"Basic.Settings.Output.ReplayBuffer.EstimateUnknown"
+
+void OBSBasicSettings::UpdateAutomaticReplayBufferCheckboxes()
+{
+	bool state = ui->simpleReplayBuf->isChecked() &&
+		ui->outputMode->currentIndex() == 0;
+	ui->replayWhileStreaming->setEnabled(state);
+	ui->keepReplayStreamStops->setEnabled(state &&
+			ui->replayWhileStreaming->isChecked());
+}
+
+void OBSBasicSettings::SimpleReplayBufferChanged()
+{
+	QString qual = ui->simpleOutRecQuality->currentData().toString();
+	bool replayBufferEnabled = ui->simpleReplayBuf->isChecked();
+	bool lossless = qual == "Lossless";
+	bool streamQuality = qual == "Stream";
+
+	ui->simpleRBMegsMax->setVisible(!streamQuality);
+	ui->simpleRBMegsMaxLabel->setVisible(!streamQuality);
+
+	int vbitrate = ui->simpleOutputVBitrate->value();
+	int abitrate = ui->simpleOutputABitrate->currentText().toInt();
+	int seconds = ui->simpleRBSecMax->value();
+
+	int64_t memMB = int64_t(seconds) * int64_t(vbitrate + abitrate) *
+		1000 / 8 / 1024 / 1024;
+	if (memMB < 1) memMB = 1;
+
+	if (streamQuality)
+		ui->simpleRBEstimate->setText(
+				QTStr(ESTIMATE_STR).arg(
+					QString::number(int(memMB))));
+	else
+		ui->simpleRBEstimate->setText(QTStr(ESTIMATE_UNKNOWN_STR));
+
+	ui->replayBufferGroupBox->setVisible(!lossless && replayBufferEnabled);
+	ui->simpleReplayBuf->setVisible(!lossless);
+
+	UpdateAutomaticReplayBufferCheckboxes();
+
+}
+
 #define SIMPLE_OUTPUT_WARNING(str) \
 	QTStr("Basic.Settings.Output.Simple.Warn." str)
 
@@ -3435,6 +3798,12 @@ void OBSBasicSettings::SimpleRecordingEncoderChanged()
 		}
 	}
 
+	if (ui->simpleOutRecFormat->currentText().compare("mp4") == 0) {
+		if (!warning.isEmpty())
+			warning += "\n\n";
+		warning += QTStr("OutputWarnings.MP4Recording");
+	}
+
 	if (warning.isEmpty())
 		return;
 
diff --git a/UI/window-basic-settings.hpp b/UI/window-basic-settings.hpp
index e3bdcfa..6440322 100644
--- a/UI/window-basic-settings.hpp
+++ b/UI/window-basic-settings.hpp
@@ -111,6 +111,7 @@ private:
 	QString curPreset;
 	QString curQSVPreset;
 	QString curNVENCPreset;
+	QString curAMDPreset;
 
 	QString curAdvStreamEncoder;
 	QString curAdvRecordEncoder;
@@ -239,6 +240,7 @@ private:
 
 	void FillSimpleRecordingValues();
 	void FillSimpleStreamingValues();
+	void FillAudioMonitoringDevices();
 
 	void RecalcOutputResPixels(const char *resText);
 
@@ -254,6 +256,7 @@ private slots:
 	void on_advOutFFPathBrowse_clicked();
 	void on_advOutEncoder_currentIndexChanged(int idx);
 	void on_advOutRecEncoder_currentIndexChanged(int idx);
+	void on_advOutFFIgnoreCompat_stateChanged(int state);
 	void on_advOutFFFormat_currentIndexChanged(int idx);
 	void on_advOutFFAEncoder_currentIndexChanged(int idx);
 	void on_advOutFFVEncoder_currentIndexChanged(int idx);
@@ -283,12 +286,16 @@ private slots:
 
 	void UpdateStreamDelayEstimate();
 
+	void UpdateAutomaticReplayBufferCheckboxes();
+
 	void AdvOutRecCheckWarnings();
 
 	void SimpleRecordingQualityChanged();
 	void SimpleRecordingEncoderChanged();
 	void SimpleRecordingQualityLosslessWarning(int idx);
 
+	void SimpleReplayBufferChanged();
+
 	void SimpleStreamingEncoderChanged();
 
 protected:
diff --git a/UI/window-basic-source-select.cpp b/UI/window-basic-source-select.cpp
index 826fb8b..b66ba08 100644
--- a/UI/window-basic-source-select.cpp
+++ b/UI/window-basic-source-select.cpp
@@ -204,7 +204,7 @@ OBSBasicSourceSelect::OBSBasicSourceSelect(OBSBasic *parent, const char *id_)
 	QString placeHolderText{QT_UTF8(GetSourceDisplayName(id))};
 
 	QString text{placeHolderText};
-	int i = 1;
+	int i = 2;
 	obs_source_t *source = nullptr;
 	while ((source = obs_get_source_by_name(QT_TO_UTF8(text)))) {
 		obs_source_release(source);
diff --git a/UI/window-basic-status-bar.cpp b/UI/window-basic-status-bar.cpp
index 1dd42b9..e10e0d8 100644
--- a/UI/window-basic-status-bar.cpp
+++ b/UI/window-basic-status-bar.cpp
@@ -1,4 +1,7 @@
 #include <QLabel>
+#include <QHBoxLayout>
+#include <QPainter>
+#include <QPixmap>
 #include "obs-app.hpp"
 #include "window-basic-main.hpp"
 #include "window-basic-status-bar.hpp"
@@ -8,30 +11,63 @@ OBSBasicStatusBar::OBSBasicStatusBar(QWidget *parent)
 	: QStatusBar    (parent),
 	  delayInfo     (new QLabel),
 	  droppedFrames (new QLabel),
-	  sessionTime   (new QLabel),
+	  streamTime    (new QLabel),
+	  recordTime    (new QLabel),
 	  cpuUsage      (new QLabel),
-	  kbps          (new QLabel)
+	  transparentPixmap (20, 20),
+	  greenPixmap       (20, 20),
+	  grayPixmap        (20, 20),
+	  redPixmap         (20, 20)
 {
-	sessionTime->setText(QString("00:00:00"));
-	cpuUsage->setText(QString("CPU: 0.0%"));
+	streamTime->setText(QString("LIVE: 00:00:00"));
+	recordTime->setText(QString("REC: 00:00:00"));
+	cpuUsage->setText(QString("CPU: 0.0%, 0.00 fps"));
+
+	QWidget *brWidget = new QWidget(this);
+	QHBoxLayout *brLayout = new QHBoxLayout(brWidget);
+	brLayout->setContentsMargins(0, 0, 0, 0);
+
+	statusSquare = new QLabel(brWidget);
+	brLayout->addWidget(statusSquare);
+
+	kbps = new QLabel(brWidget);
+	brLayout->addWidget(kbps);
+
+	brWidget->setLayout(brLayout);
 
 	delayInfo->setAlignment(Qt::AlignRight);
+	delayInfo->setAlignment(Qt::AlignVCenter);
 	droppedFrames->setAlignment(Qt::AlignRight);
-	sessionTime->setAlignment(Qt::AlignRight);
+	droppedFrames->setAlignment(Qt::AlignVCenter);
+	streamTime->setAlignment(Qt::AlignRight);
+	streamTime->setAlignment(Qt::AlignVCenter);
+	recordTime->setAlignment(Qt::AlignRight);
+	recordTime->setAlignment(Qt::AlignVCenter);
 	cpuUsage->setAlignment(Qt::AlignRight);
+	cpuUsage->setAlignment(Qt::AlignVCenter);
 	kbps->setAlignment(Qt::AlignRight);
+	kbps->setAlignment(Qt::AlignVCenter);
 
 	delayInfo->setIndent(20);
 	droppedFrames->setIndent(20);
-	sessionTime->setIndent(20);
+	streamTime->setIndent(20);
+	recordTime->setIndent(20);
 	cpuUsage->setIndent(20);
 	kbps->setIndent(10);
 
 	addPermanentWidget(droppedFrames);
-	addPermanentWidget(sessionTime);
+	addPermanentWidget(streamTime);
+	addPermanentWidget(recordTime);
 	addPermanentWidget(cpuUsage);
 	addPermanentWidget(delayInfo);
-	addPermanentWidget(kbps);
+	addPermanentWidget(brWidget);
+
+	transparentPixmap.fill(QColor(0, 0, 0, 0));
+	greenPixmap.fill(QColor(0, 255, 0));
+	grayPixmap.fill(QColor(72, 72, 72));
+	redPixmap.fill(QColor(255, 0, 0));
+
+	statusSquare->setPixmap(transparentPixmap);
 }
 
 void OBSBasicStatusBar::Activate()
@@ -44,13 +80,18 @@ void OBSBasicStatusBar::Activate()
 		int skipped = video_output_get_skipped_frames(obs_get_video());
 		int total   = video_output_get_total_frames(obs_get_video());
 
-		totalSeconds = 0;
+		totalStreamSeconds = 0;
+		totalRecordSeconds = 0;
 		lastSkippedFrameCount = 0;
 		startSkippedFrameCount = skipped;
 		startTotalFrameCount = total;
 
 		refreshTimer->start(1000);
 		active = true;
+
+		if (streamOutput) {
+			statusSquare->setPixmap(grayPixmap);
+		}
 	}
 }
 
@@ -60,9 +101,19 @@ void OBSBasicStatusBar::Deactivate()
 	if (!main)
 		return;
 
+	if (!streamOutput) {
+		streamTime->setText(QString("LIVE: 00:00:00"));
+		totalStreamSeconds = 0;
+	}
+
+	if (!recordOutput) {
+		recordTime->setText(QString("REC: 00:00:00"));
+		totalRecordSeconds = 0;
+	}
+
 	if (!main->outputHandler->Active()) {
 		delete refreshTimer;
-		sessionTime->setText(QString("00:00:00"));
+
 		delayInfo->setText("");
 		droppedFrames->setText("");
 		kbps->setText("");
@@ -73,6 +124,8 @@ void OBSBasicStatusBar::Deactivate()
 		reconnectTimeout = 0;
 		active = false;
 		overloadedNotify = true;
+
+		statusSquare->setPixmap(transparentPixmap);
 	}
 }
 
@@ -130,6 +183,7 @@ void OBSBasicStatusBar::UpdateBandwidth()
 	QString text;
 	text += QString("kb/s: ") +
 		QString::number(kbitsPerSec, 'f', 0);
+
 	kbps->setText(text);
 	kbps->setMinimumWidth(kbps->width());
 
@@ -153,19 +207,19 @@ void OBSBasicStatusBar::UpdateCPUUsage()
 	cpuUsage->setMinimumWidth(cpuUsage->width());
 }
 
-void OBSBasicStatusBar::UpdateSessionTime()
+void OBSBasicStatusBar::UpdateStreamTime()
 {
-	totalSeconds++;
+	totalStreamSeconds++;
 
-	int seconds      = totalSeconds % 60;
-	int totalMinutes = totalSeconds / 60;
+	int seconds      = totalStreamSeconds % 60;
+	int totalMinutes = totalStreamSeconds / 60;
 	int minutes      = totalMinutes % 60;
 	int hours        = totalMinutes / 60;
 
 	QString text;
-	text.sprintf("%02d:%02d:%02d", hours, minutes, seconds);
-	sessionTime->setText(text);
-	sessionTime->setMinimumWidth(sessionTime->width());
+	text.sprintf("LIVE: %02d:%02d:%02d", hours, minutes, seconds);
+	streamTime->setText(text);
+	streamTime->setMinimumWidth(streamTime->width());
 
 	if (reconnectTimeout > 0) {
 		QString msg = QTStr("Basic.StatusBar.Reconnecting")
@@ -188,6 +242,21 @@ void OBSBasicStatusBar::UpdateSessionTime()
 	}
 }
 
+void OBSBasicStatusBar::UpdateRecordTime()
+{
+	totalRecordSeconds++;
+
+	int seconds      = totalRecordSeconds % 60;
+	int totalMinutes = totalRecordSeconds / 60;
+	int minutes      = totalMinutes % 60;
+	int hours        = totalMinutes / 60;
+
+	QString text;
+	text.sprintf("REC: %02d:%02d:%02d", hours, minutes, seconds);
+	recordTime->setText(text);
+	recordTime->setMinimumWidth(recordTime->width());
+}
+
 void OBSBasicStatusBar::UpdateDroppedFrames()
 {
 	if (!streamOutput)
@@ -205,6 +274,37 @@ void OBSBasicStatusBar::UpdateDroppedFrames()
 			QString::number(percent, 'f', 1));
 	droppedFrames->setText(text);
 	droppedFrames->setMinimumWidth(droppedFrames->width());
+
+	/* ----------------------------------- *
+	 * calculate congestion color          */
+
+	float congestion = obs_output_get_congestion(streamOutput);
+	float avgCongestion = (congestion + lastCongestion) * 0.5f;
+	if (avgCongestion < congestion)
+		avgCongestion = congestion;
+	if (avgCongestion > 1.0f)
+		avgCongestion = 1.0f;
+
+	if (avgCongestion < EPSILON) {
+		statusSquare->setPixmap(greenPixmap);
+	} else if (fabsf(avgCongestion - 1.0f) < EPSILON) {
+		statusSquare->setPixmap(redPixmap);
+	} else {
+		QPixmap pixmap(20, 20);
+
+		float red = avgCongestion * 2.0f;
+		if (red > 1.0f) red = 1.0f;
+		red *= 255.0;
+
+		float green = (1.0f - avgCongestion) * 2.0f;
+		if (green > 1.0f) green = 1.0f;
+		green *= 255.0;
+
+		pixmap.fill(QColor(int(red), int(green), 0));
+		statusSquare->setPixmap(pixmap);
+	}
+
+	lastCongestion = congestion;
 }
 
 void OBSBasicStatusBar::OBSOutputReconnect(void *data, calldata_t *params)
@@ -276,7 +376,13 @@ void OBSBasicStatusBar::UpdateStatusBar()
 	OBSBasic *main = qobject_cast<OBSBasic*>(parent());
 
 	UpdateBandwidth();
-	UpdateSessionTime();
+
+	if (streamOutput)
+		UpdateStreamTime();
+
+	if (recordOutput)
+		UpdateRecordTime();
+
 	UpdateDroppedFrames();
 
 	int skipped = video_output_get_skipped_frames(obs_get_video());
diff --git a/UI/window-basic-status-bar.hpp b/UI/window-basic-status-bar.hpp
index e0c7a0d..2da33c3 100644
--- a/UI/window-basic-status-bar.hpp
+++ b/UI/window-basic-status-bar.hpp
@@ -14,9 +14,11 @@ class OBSBasicStatusBar : public QStatusBar {
 private:
 	QLabel *delayInfo;
 	QLabel *droppedFrames;
-	QLabel *sessionTime;
+	QLabel *streamTime;
+	QLabel *recordTime;
 	QLabel *cpuUsage;
 	QLabel *kbps;
+	QLabel *statusSquare;
 
 	obs_output_t *streamOutput = nullptr;
 	obs_output_t *recordOutput = nullptr;
@@ -24,7 +26,8 @@ private:
 	bool overloadedNotify = true;
 
 	int retries = 0;
-	int totalSeconds = 0;
+	int totalStreamSeconds = 0;
+	int totalRecordSeconds = 0;
 
 	int reconnectTimeout = 0;
 
@@ -40,6 +43,13 @@ private:
 	uint64_t lastBytesSent = 0;
 	uint64_t lastBytesSentTime = 0;
 
+	QPixmap transparentPixmap;
+	QPixmap greenPixmap;
+	QPixmap grayPixmap;
+	QPixmap redPixmap;
+
+	float lastCongestion = 0.0f;
+
 	QPointer<QTimer> refreshTimer;
 
 	obs_output_t *GetOutput();
@@ -49,7 +59,8 @@ private:
 
 	void UpdateDelayMsg();
 	void UpdateBandwidth();
-	void UpdateSessionTime();
+	void UpdateStreamTime();
+	void UpdateRecordTime();
 	void UpdateDroppedFrames();
 
 	static void OBSOutputReconnect(void *data, calldata_t *params);
diff --git a/UI/window-basic-transform.cpp b/UI/window-basic-transform.cpp
index f1143e7..7b0b4b0 100644
--- a/UI/window-basic-transform.cpp
+++ b/UI/window-basic-transform.cpp
@@ -56,10 +56,10 @@ OBSBasicTransform::OBSBasicTransform(OBSBasic *parent)
 	HookWidget(ui->cropTop,      ISCROLL_CHANGED, SLOT(OnCropChanged()));
 	HookWidget(ui->cropBottom,   ISCROLL_CHANGED, SLOT(OnCropChanged()));
 
+	ui->buttonBox->button(QDialogButtonBox::Close)->setDefault(true);
+
 	connect(ui->buttonBox->button(QDialogButtonBox::Reset),
 		SIGNAL(clicked()), this, SLOT(on_resetButton_clicked()));
-	connect(ui->buttonBox,
-		SIGNAL(rejected()), this, SLOT(close()));
 
 	installEventFilter(CreateShortcutFilter());
 
diff --git a/UI/window-projector.cpp b/UI/window-projector.cpp
index 5e3ecf9..e894897 100644
--- a/UI/window-projector.cpp
+++ b/UI/window-projector.cpp
@@ -1,6 +1,8 @@
 #include <QAction>
+#include <QGuiApplication>
 #include <QMouseEvent>
 #include <QMenu>
+#include <QScreen>
 #include "window-projector.hpp"
 #include "display-helpers.hpp"
 #include "qt-wrappers.hpp"
@@ -17,6 +19,9 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_)
 {
 	setAttribute(Qt::WA_DeleteOnClose, true);
 
+	//disable application quit when last window closed
+	setAttribute(Qt::WA_QuitOnClose, false);
+
 	installEventFilter(CreateShortcutFilter());
 
 	auto addDrawCallback = [this] ()
@@ -47,11 +52,9 @@ OBSProjector::~OBSProjector()
 
 void OBSProjector::Init(int monitor)
 {
-	std::vector<MonitorInfo> monitors;
-	GetMonitors(monitors);
-	MonitorInfo &mi = monitors[monitor];
+	QScreen *screen = QGuiApplication::screens()[monitor];
 
-	setGeometry(mi.x, mi.y, mi.cx, mi.cy);
+	setGeometry(screen->geometry());
 
 	bool alwaysOnTop = config_get_bool(GetGlobalConfig(),
 			"BasicWindow", "ProjectorAlwaysOnTop");
@@ -68,6 +71,8 @@ void OBSProjector::Init(int monitor)
 	addAction(action);
 
 	connect(action, SIGNAL(triggered()), this, SLOT(EscapeTriggered()));
+
+	savedMonitor = monitor;
 }
 
 void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
@@ -112,6 +117,7 @@ void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
 void OBSProjector::OBSSourceRemoved(void *data, calldata_t *params)
 {
 	OBSProjector *window = reinterpret_cast<OBSProjector*>(data);
+
 	window->deleteLater();
 
 	UNUSED_PARAMETER(params);
@@ -130,5 +136,8 @@ void OBSProjector::mousePressEvent(QMouseEvent *event)
 
 void OBSProjector::EscapeTriggered()
 {
+	OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
+	main->RemoveSavedProjectors(savedMonitor);
+
 	deleteLater();
 }
diff --git a/UI/window-projector.hpp b/UI/window-projector.hpp
index f623f9e..394d270 100644
--- a/UI/window-projector.hpp
+++ b/UI/window-projector.hpp
@@ -2,6 +2,7 @@
 
 #include <obs.hpp>
 #include "qt-display.hpp"
+#include "window-basic-main.hpp"
 
 class QMouseEvent;
 
@@ -17,6 +18,8 @@ private:
 
 	void mousePressEvent(QMouseEvent *event) override;
 
+	int savedMonitor = 0;
+
 private slots:
 	void EscapeTriggered();
 
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..a7a8447
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,41 @@
+environment:
+  CURL_VERSION: 7.39.0
+
+install:
+  - git submodule update --init --recursive
+  - if not exist dependencies2015.zip curl -kLO https://obsproject.com/downloads/dependencies2015.zip -f --retry 5 -C -
+  - if not exist vlc.zip curl -kLO https://obsproject.com/downloads/vlc.zip -f --retry 5 -C -
+  - 7z x dependencies2015.zip -odependencies2015
+  - 7z x vlc.zip -ovlc
+  - set DepsPath32=%CD%\dependencies2015\win32
+  - set DepsPath64=%CD%\dependencies2015\win64
+  - set VLCPath=%CD%\vlc
+  - set QTDIR32=C:\Qt\5.7\msvc2015
+  - set QTDIR64=C:\Qt\5.7\msvc2015_64
+  - set build_config=RelWithDebInfo
+  - move "C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\um\d3d11on12*" "C:\Program Files (x86)\Windows Kits\8.1\Include\um"
+  - move "C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\um\d3d12*" "C:\Program Files (x86)\Windows Kits\8.1\Include\um"
+  - move "C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\shared\dxgi*" "C:\Program Files (x86)\Windows Kits\8.1\Include\shared"
+  - mkdir build
+  - mkdir build32
+  - mkdir build64
+  - cd ./build32
+  - cmake -G "Visual Studio 14 2015" -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DBUILD_CAPTIONS=true -DCOMPILE_D3D12_HOOK=true ..
+  - cd ../build64
+  - cmake -G "Visual Studio 14 2015 Win64" -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DBUILD_CAPTIONS=true -DCOMPILE_D3D12_HOOK=true ..
+
+build_script:
+  - call msbuild /m /p:Configuration=%build_config% C:\projects\obs-studio\build32\obs-studio.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
+  - call msbuild /m /p:Configuration=%build_config% C:\projects\obs-studio\build64\obs-studio.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
+
+before_deploy:
+  - C:\projects\obs-studio\CI\before-deploy-win.cmd
+
+deploy_script:
+  - ps: Push-AppveyorArtifact "build.zip" -FileName "$(git describe).zip"
+
+test: off
+
+cache:
+  - dependencies2015.zip
+  - vlc.zip
diff --git a/cmake/Modules/CopyMSVCBins.cmake b/cmake/Modules/CopyMSVCBins.cmake
index 1dd0723..13ce4ea 100644
--- a/cmake/Modules/CopyMSVCBins.cmake
+++ b/cmake/Modules/CopyMSVCBins.cmake
@@ -8,7 +8,7 @@ if(COPIED_DEPENDENCIES)
 	return()
 endif()
 
-option(COPY_DEPENDENCIES "Automaticaly try copying all dependencies" OFF)
+option(COPY_DEPENDENCIES "Automaticaly try copying all dependencies" ON)
 if(NOT COPY_DEPENDENCIES)
 	return()
 endif()
@@ -19,12 +19,6 @@ else()
 	set(_bin_suffix 32)
 endif()
 
-find_package(Libavcodec QUIET)
-find_package(Libx264 QUIET)
-find_package(Libfdk QUIET)
-find_package(ssl QUIET)
-find_package(Qt5Core QUIET)
-
 file(GLOB FFMPEG_BIN_FILES
 	"${FFMPEG_avcodec_INCLUDE_DIR}/../bin/avcodec-*.dll"
 	"${FFMPEG_avcodec_INCLUDE_DIR}/../bin${_bin_suffix}/avcodec-*.dll"
diff --git a/cmake/Modules/FindFFmpeg.cmake b/cmake/Modules/FindFFmpeg.cmake
index aca205e..5206695 100644
--- a/cmake/Modules/FindFFmpeg.cmake
+++ b/cmake/Modules/FindFFmpeg.cmake
@@ -49,6 +49,8 @@ function(find_ffmpeg_library component header)
 			${DepsPath${_lib_suffix}}
 			${DepsPath}
 			${PC_FFMPEG_${component}_INCLUDE_DIRS}
+		PATHS
+			/usr/include /usr/local/include /opt/local/include /sw/include
 		PATH_SUFFIXES ffmpeg libav include)
 
 	find_library(FFMPEG_${component}_LIBRARY
@@ -64,6 +66,8 @@ function(find_ffmpeg_library component header)
 			${DepsPath${_lib_suffix}}
 			${DepsPath}
 			${PC_FFMPEG_${component}_LIBRARY_DIRS}
+		PATHS
+			/usr/lib /usr/local/lib /opt/local/lib /sw/lib
 		PATH_SUFFIXES
 			lib${_lib_suffix} lib
 			libs${_lib_suffix} libs
diff --git a/cmake/Modules/FindRSSDK.cmake b/cmake/Modules/FindRSSDK.cmake
new file mode 100644
index 0000000..bd008db
--- /dev/null
+++ b/cmake/Modules/FindRSSDK.cmake
@@ -0,0 +1,40 @@
+# Once done these will be defined:
+#
+#  RSSDK_FOUND
+#  RSSDK_INCLUDE_DIRS
+#  RSSDK_LIBRARIES
+#
+# For use in OBS:
+#
+#  RSSDK_INCLUDE_DIR
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+	set(_RSSDK_lib_dir "x64")
+else()
+	set(_RSSDK_lib_dir "Win32")
+endif()
+
+find_path(RSSDK_INCLUDE_DIR
+	NAMES pxcsession.h
+	HINTS
+		ENV RSSDK_DIR
+	PATH_SUFFIXES
+		include)
+
+find_library(RSSDK_LIB
+	NAMES libpxc
+	HINTS
+		ENV RSSDK_DIR
+	PATH_SUFFIXES
+		lib/${_RSSDK_lib_dir}
+	)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(RSSDK DEFAULT_MSG RSSDK_LIB RSSDK_INCLUDE_DIR)
+mark_as_advanced(RSSDK_INCLUDE_DIR RSSDK_LIB)
+
+if(RSSDK_FOUND)
+	set(RSSDK_INCLUDE_DIRS ${RSSDK_INCLUDE_DIR})
+	set(RSSDK_LIBRARIES ${RSSDK_LIB})
+endif()
+
diff --git a/cmake/Modules/IDLFileHelper.cmake b/cmake/Modules/IDLFileHelper.cmake
index a486d6a..059a08c 100644
--- a/cmake/Modules/IDLFileHelper.cmake
+++ b/cmake/Modules/IDLFileHelper.cmake
@@ -1,4 +1,4 @@
-macro(add_idl_files generated_files)
+macro(add_idl_files_base generated_files with_tlb)
 	foreach(filename ${ARGN})
 		get_filename_component(file_we ${filename} NAME_WE)
 		get_filename_component(file_path ${filename} PATH)
@@ -9,10 +9,18 @@ macro(add_idl_files generated_files)
 		set(bin_file_c ${CMAKE_CURRENT_BINARY_DIR}/${file_c})
 
 		if(MSVC)
+			if(${with_tlb})
+				set(file_tlb ${file_we}.tlb)
+				set(bin_file_tlb ${CMAKE_CURRENT_BINARY_DIR}/${file_tlb})
+				set(tlb_opt "")
+			else()
+				set(tlb_opt "/notlb")
+			endif()
+
 			add_custom_command(
 				OUTPUT ${bin_file_h} ${bin_file_c}
 				DEPENDS ${filename}
-				COMMAND midl /h ${file_h} /iid ${file_c} /notlb ${CMAKE_CURRENT_SOURCE_DIR}/${filename}
+				COMMAND midl /h ${file_h} /iid ${file_c} ${tlb_opt} ${CMAKE_CURRENT_SOURCE_DIR}/${filename}
 				WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
 		else()
 			execute_process(COMMAND echo
@@ -62,4 +70,12 @@ macro(add_idl_files generated_files)
 			PROPERTIES
 			HEADER_FILE_ONLY TRUE)
 	endforeach(filename ${ARGN})
+endmacro(add_idl_files_base)
+
+macro(add_idl_files generated_files)
+	add_idl_files_base(${generated_files} FALSE ${ARGN})
 endmacro(add_idl_files)
+
+macro(add_idl_files_with_tlb generated_files)
+	add_idl_files_base(${generated_files} TRUE ${ARGN})
+endmacro(add_idl_files_with_tlb)
diff --git a/cmake/Modules/ObsCpack.cmake b/cmake/Modules/ObsCpack.cmake
index 0e9d2c0..d9564b9 100644
--- a/cmake/Modules/ObsCpack.cmake
+++ b/cmake/Modules/ObsCpack.cmake
@@ -8,6 +8,7 @@ endif()
 set(CPACK_PACKAGE_NAME "OBS")
 set(CPACK_PACKAGE_VENDOR "obsproject.com")
 set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OBS - Live video and audio streaming and recording software")
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/UI/data/license/gplv2.txt")
 
 set(CPACK_PACKAGE_VERSION_MAJOR "0")
 set(CPACK_PACKAGE_VERSION_MINOR "0")
diff --git a/cmake/osxbundle/fixup_bundle.sh b/cmake/osxbundle/fixup_bundle.sh
index 456d339..7eb501d 100755
--- a/cmake/osxbundle/fixup_bundle.sh
+++ b/cmake/osxbundle/fixup_bundle.sh
@@ -9,7 +9,9 @@ cd "$1"
 
 function buildlist() {
 	otool -L "$@" | 
-		grep -E "(opt|Users)" |
+		grep -E '^\s+/' |
+		grep -vE '^\s+/System/' |
+		grep -vE '^\s+/usr/lib/' |
 		perl -pe 's|^\s+(/.*)\s\(.*$|$1|' |
 		grep -vE ":$" |
 		sort -u
@@ -34,6 +36,7 @@ for lib in $FOUNDLIBS; do
 
 	INTOOL_CALL+=(-change "$lib" "$LDEST/$libname")
 	cp "$lib" "$DEST/$libname"
+	chmod 644 "$DEST/$libname"
 
 	echo "Fixing up dependency: $libname"
 done
diff --git a/cmake/winrc/obs-studio.ico b/cmake/winrc/obs-studio.ico
index 32f1466..7127372 100644
Binary files a/cmake/winrc/obs-studio.ico and b/cmake/winrc/obs-studio.ico differ
diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt
index 0f234c6..5859065 100644
--- a/deps/CMakeLists.txt
+++ b/deps/CMakeLists.txt
@@ -8,6 +8,15 @@ add_subdirectory(ipc-util)
 add_subdirectory(libff)
 add_subdirectory(file-updater)
 
+if(WIN32)
+	add_subdirectory(blake2)
+	add_subdirectory(lzma)
+endif()
+
+if(BUILD_CAPTIONS)
+	add_subdirectory(libcaption)
+endif()
+
 find_package(Jansson 2.5 QUIET)
 
 if(NOT JANSSON_FOUND)
diff --git a/deps/ipc-util/CMakeLists.txt b/deps/ipc-util/CMakeLists.txt
index 917311d..8b2e672 100644
--- a/deps/ipc-util/CMakeLists.txt
+++ b/deps/ipc-util/CMakeLists.txt
@@ -22,6 +22,10 @@ else()
 		ipc-util/pipe-posix.c)
 endif()
 
+if(MSVC)
+	add_compile_options("$<$<CONFIG:RelWithDebInfo>:/MT>")
+endif()
+
 add_library(ipc-util STATIC
 	${ipc-util_SOURCES}
 	${ipc-util_HEADERS})
diff --git a/deps/jansson/.gitignore b/deps/jansson/.gitignore
deleted file mode 100644
index 9189a93..0000000
--- a/deps/jansson/.gitignore
+++ /dev/null
@@ -1,28 +0,0 @@
-*~
-*.o
-*.a
-.libs
-.deps
-Makefile
-Makefile.in
-aclocal.m4
-autom4te.cache
-config.guess
-config.h
-config.h.in
-config.log
-config.status
-config.sub
-configure
-depcomp
-install-sh
-libtool
-ltmain.sh
-missing
-*.lo
-*.la
-stamp-h1
-*.pyc
-*.pc
-/src/jansson_config.h
-*.exe
diff --git a/deps/jansson/.travis.yml b/deps/jansson/.travis.yml
deleted file mode 100644
index 1cca274..0000000
--- a/deps/jansson/.travis.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-language: c
-compiler:
-  - gcc
-  - clang
-script: autoreconf -f -i && CFLAGS=-Werror ./configure && make check
diff --git a/deps/jansson/Android.mk b/deps/jansson/Android.mk
deleted file mode 100644
index eb4fed7..0000000
--- a/deps/jansson/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_ARM_MODE := arm
-
-LOCAL_SRC_FILES := \
-    src/dump.c \
-    src/error.c \
-    src/hashtable.c \
-    src/load.c \
-    src/memory.c \
-    src/pack_unpack.c \
-    src/strbuffer.c \
-    src/strconv.c \
-    src/utf.c \
-    src/value.c
-
-LOCAL_C_INCLUDES += \
-        $(LOCAL_PATH) \
-        $(LOCAL_PATH)/android \
-        $(LOCAL_PATH)/src
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := libc
-LOCAL_CFLAGS += -O3
-
-LOCAL_MODULE:= libjansson
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/deps/jansson/CHANGES b/deps/jansson/CHANGES
deleted file mode 100644
index 7807904..0000000
--- a/deps/jansson/CHANGES
+++ /dev/null
@@ -1,586 +0,0 @@
-Version 2.6 (in development)
-============================
-
-Released XXXX-XX-XX
-
-* New features:
-
-  - `json_pack()` and friends: Add format specifiers ``s%`` and ``+%``
-    for a size_t string length.
-
-  - `json_unpack()` and friends: Add format specifier ``s%`` for
-    unpacking the string length along with the string itself.
-
-  - Add length-aware string constructors `json_stringn()` and
-    `json_stringn_nocheck()`, length-aware string mutators
-    `json_string_setn()` and `json_string_setn_nocheck()`, and a
-    function for getting string's length `json_string_length()`.
-
-  - Support ``\u0000`` escapes in the decoder. The support can be
-    enabled by using the ``JSON_ALLOW_NUL`` decoding flag.
-
-* Bug fixes:
-
-  - Some malformed ``\uNNNN`` escapes could crash the decoder with an
-    assertion failure.
-
-* Other changes:
-
-  - ``\uNNNN`` escapes are now encoded in upper case for better
-    readability.
-
-
-Version 2.5
-===========
-
-Released 2013-09-19
-
-* New features:
-
-  - `json_pack()` and friends: Add format specifiers ``s#``, ``+`` and
-    ``+#``.
-
-  - Add ``JSON_DECODE_INT_AS_REAL`` decoding flag to treat all numbers
-    as real in the decoder (#123).
-
-  - Add `json_array_foreach()`, paralleling `json_object_foreach()`
-    (#118).
-
-* Bug fixes:
-
-  - `json_dumps()` and friends: Don't crash if json is *NULL* and
-    ``JSON_ENCODE_ANY`` is set.
-
-  - Fix a theoretical integer overflow in `jsonp_strdup()`.
-
-  - Fix `l_isxdigit()` macro (#97).
-
-  - Fix an off-by-one error in `json_array_remove()`.
-
-* Build:
-
-  - Support CMake in addition to GNU Autotools (#106, #107, #112,
-    #115, #120, #127).
-
-  - Support building for Android (#109).
-
-  - Don't use ``-Werror`` by default.
-
-  - Support building and testing with VPATH (#93).
-
-  - Fix compilation when ``NDEBUG`` is defined (#128)
-
-* Tests:
-
-  - Fix a refleak in ``test/bin/json_process.c``.
-
-* Documentation:
-
-  - Clarify the return value of `json_load_callback_t`.
-
-  - Document how to circumvent problems with separate heaps on Windows.
-
-  - Fix memory leaks and warnings in ``github_commits.c``.
-
-  - Use `json_decref()` properly in tutorial.
-
-* Other:
-
-  - Make it possible to forward declare ``struct json_t``.
-
-
-Version 2.4
-===========
-
-Released 2012-09-23
-
-* New features:
-
-  - Add `json_boolean()` macro that returns the JSON true or false
-    value based on its argument (#86).
-
-  - Add `json_load_callback()` that calls a callback function
-    repeatedly to read the JSON input (#57).
-
-  - Add JSON_ESCAPE_SLASH encoding flag to escape all occurences of
-    ``/`` with ``\/``.
-
-* Bug fixes:
-
-  - Check for and reject NaN and Inf values for reals. Encoding these
-    values resulted in invalid JSON.
-
-  - Fix `json_real_set()` to return -1 on error.
-
-* Build:
-
-  - Jansson now builds on Windows with Visual Studio 2010, and
-    includes solution and project files in ``win32/vs2010/``
-    directory.
-
-  - Fix build warnings (#77, #78).
-
-  - Add ``-no-undefined`` to LDFLAGS (#90).
-
-* Tests:
-
-  - Fix the symbol exports test on Linux/PPC64 (#88).
-
-* Documentation:
-
-  - Fix typos (#73, #84).
-
-
-Version 2.3.1
-=============
-
-Released 2012-04-20
-
-* Build issues:
-
-  - Only use ``long long`` if ``strtoll()`` is also available.
-
-* Documentation:
-
-  - Fix the names of library version constants in documentation. (#52)
-
-  - Change the tutorial to use GitHub API v3. (#65)
-
-* Tests:
-
-  - Make some tests locale independent. (#51)
-
-  - Distribute the library exports test in the tarball.
-
-  - Make test run on shells that don't support the ``export FOO=bar``
-    syntax.
-
-
-Version 2.3
-===========
-
-Released 2012-01-27
-
-* New features:
-
-  - `json_unpack()` and friends: Add support for optional object keys
-    with the ``{s?o}`` syntax.
-
-  - Add `json_object_update_existing()` and
-    `json_object_update_missing()`, for updating only existing keys or
-    only adding missing keys to an object. (#37)
-
-  - Add `json_object_foreach()` for more convenient iteration over
-    objects. (#45, #46)
-
-  - When decoding JSON, write the number of bytes that were read from
-    input to ``error.position`` also on success. This is handy with
-    ``JSON_DISABLE_EOF_CHECK``.
-
-  - Add support for decoding any JSON value, not just arrays or
-    objects. The support is enabled with the new ``JSON_DECODE_ANY``
-    flag. Patch by Andrea Marchesini. (#4)
-
-* Bug fixes
-
-  - Avoid problems with object's serial number growing too big. (#40,
-    #41)
-
-  - Decoding functions now return NULL if the first argument is NULL.
-    Patch by Andrea Marchesini.
-
-  - Include ``jansson_config.h.win32`` in the distribution tarball.
-
-  - Remove ``+`` and leading zeros from exponents in the encoder.
-    (#39)
-
-  - Make Jansson build and work on MinGW. (#39, #38)
-
-* Documentation
-
-  - Note that the same JSON values must not be encoded in parallel by
-    separate threads. (#42)
-
-  - Document MinGW support.
-
-
-Version 2.2.1
-=============
-
-Released 2011-10-06
-
-* Bug fixes:
-
-  - Fix real number encoding and decoding under non-C locales. (#32)
-
-  - Fix identifier decoding under non-UTF-8 locales. (#35)
-
-  - `json_load_file()`: Open the input file in binary mode for maximum
-    compatiblity.
-
-* Documentation:
-
-  - Clarify the lifecycle of the result of the ``s`` fromat of
-    `json_unpack()`. (#31)
-
-  - Add some portability info. (#36)
-
-  - Little clarifications here and there.
-
-* Other:
-
-  - Some style fixes, issues detected by static analyzers.
-
-
-Version 2.2
-===========
-
-Released 2011-09-03
-
-* New features:
-
-  - `json_dump_callback()`: Pass the encoder output to a callback
-    function in chunks.
-
-* Bug fixes:
-
-  - `json_string_set()`: Check that target is a string and value is
-    not NULL.
-
-* Other:
-
-  - Documentation typo fixes and clarifications.
-
-
-Version 2.1
-===========
-
-Released 2011-06-10
-
-* New features:
-
-  - `json_loadb()`: Decode a string with a given size, useful if the
-    string is not null terminated.
-
-  - Add ``JSON_ENCODE_ANY`` encoding flag to allow encoding any JSON
-    value. By default, only arrays and objects can be encoded. (#19)
-
-  - Add ``JSON_REJECT_DUPLICATES`` decoding flag to issue a decoding
-    error if any JSON object in the input contins duplicate keys. (#3)
-
-  - Add ``JSON_DISABLE_EOF_CHECK`` decoding flag to stop decoding after a
-    valid JSON input. This allows other data after the JSON data.
-
-* Bug fixes:
-
-  - Fix an additional memory leak when memory allocation fails in
-    `json_object_set()` and friends.
-
-  - Clear errno before calling `strtod()` for better portability. (#27)
-
-* Building:
-
-  - Avoid set-but-not-used warning/error in a test. (#20)
-
-* Other:
-
-  - Minor clarifications to documentation.
-
-
-Version 2.0.1
-=============
-
-Released 2011-03-31
-
-* Bug fixes:
-
-  - Replace a few `malloc()` and `free()` calls with their
-    counterparts that support custom memory management.
-
-  - Fix object key hashing in json_unpack() strict checking mode.
-
-  - Fix the parentheses in ``JANSSON_VERSION_HEX`` macro.
-
-  - Fix `json_object_size()` return value.
-
-  - Fix a few compilation issues.
-
-* Portability:
-
-  - Enhance portability of `va_copy()`.
-
-  - Test framework portability enhancements.
-
-* Documentation:
-
-  - Distribute ``doc/upgrading.rst`` with the source tarball.
-
-  - Build documentation in strict mode in ``make distcheck``.
-
-
-Version 2.0
-===========
-
-Released 2011-02-28
-
-This release is backwards incompatible with the 1.x release series.
-See the chapter "Upgrading from older versions" in documentation for
-details.
-
-* Backwards incompatible changes:
-
-  - Unify unsigned integer usage in the API: All occurences of
-    unsigned int and unsigned long have been replaced with size_t.
-
-  - Change JSON integer's underlying type to the widest signed integer
-    type available, i.e. long long if it's supported, otherwise long.
-    Add a typedef json_int_t that defines the type.
-
-  - Change the maximum indentation depth to 31 spaces in encoder. This
-    frees up bits from the flags parameter of encoding functions
-    `json_dumpf()`, `json_dumps()` and `json_dump_file()`.
-
-  - For future needs, add a flags parameter to all decoding functions
-    `json_loadf()`, `json_loads()` and `json_load_file()`.
-
-* New features
-
-  - `json_pack()`, `json_pack_ex()`, `json_vpack_ex()`: Create JSON
-    values based on a format string.
-
-  - `json_unpack()`, `json_unpack_ex()`, `json_vunpack_ex()`: Simple
-    value extraction and validation functionality based on a format
-    string.
-
-  - Add column, position and source fields to the ``json_error_t``
-    struct.
-
-  - Enhance error reporting in the decoder.
-
-  - ``JANSSON_VERSION`` et al.: Preprocessor constants that define the
-    library version.
-
-  - `json_set_alloc_funcs()`: Set custom memory allocation functions.
-
-* Fix many portability issues, especially on Windows.
-
-* Configuration
-
-  - Add file ``jansson_config.h`` that contains site specific
-    configuration. It's created automatically by the configure script,
-    or can be created by hand if the configure script cannot be used.
-    The file ``jansson_config.h.win32`` can be used without
-    modifications on Windows systems.
-
-  - Add a section to documentation describing how to build Jansson on
-    Windows.
-
-  - Documentation now requires Sphinx 1.0 or newer.
-
-
-Version 1.3
-===========
-
-Released 2010-06-13
-
-* New functions:
-
-  - `json_object_iter_set()`, `json_object_iter_set_new()`: Change
-    object contents while iterating over it.
-
-  - `json_object_iter_at()`: Return an iterator that points to a
-    specific object item.
-
-* New encoding flags:
-
-  - ``JSON_PRESERVE_ORDER``: Preserve the insertion order of object
-    keys.
-
-* Bug fixes:
-
-  - Fix an error that occured when an array or object was first
-    encoded as empty, then populated with some data, and then
-    re-encoded
-
-  - Fix the situation like above, but when the first encoding resulted
-    in an error
-
-* Documentation:
-
-  - Clarify the documentation on reference stealing, providing an
-    example usage pattern
-
-
-Version 1.2.1
-=============
-
-Released 2010-04-03
-
-* Bug fixes:
-
-  - Fix reference counting on ``true``, ``false`` and ``null``
-  - Estimate real number underflows in decoder with 0.0 instead of
-    issuing an error
-
-* Portability:
-
-  - Make ``int32_t`` available on all systems
-  - Support compilers that don't have the ``inline`` keyword
-  - Require Autoconf 2.60 (for ``int32_t``)
-
-* Tests:
-
-  - Print test names correctly when ``VERBOSE=1``
-  - ``test/suites/api``: Fail when a test fails
-  - Enhance tests for iterators
-  - Enhance tests for decoding texts that contain null bytes
-
-* Documentation:
-
-  - Don't remove ``changes.rst`` in ``make clean``
-  - Add a chapter on RFC conformance
-
-
-Version 1.2
-===========
-
-Released 2010-01-21
-
-* New functions:
-
-  - `json_equal()`: Test whether two JSON values are equal
-  - `json_copy()` and `json_deep_copy()`: Make shallow and deep copies
-    of JSON values
-  - Add a version of all functions taking a string argument that
-    doesn't check for valid UTF-8: `json_string_nocheck()`,
-    `json_string_set_nocheck()`, `json_object_set_nocheck()`,
-    `json_object_set_new_nocheck()`
-
-* New encoding flags:
-
-  - ``JSON_SORT_KEYS``: Sort objects by key
-  - ``JSON_ENSURE_ASCII``: Escape all non-ASCII Unicode characters
-  - ``JSON_COMPACT``: Use a compact representation with all unneeded
-    whitespace stripped
-
-* Bug fixes:
-
-  - Revise and unify whitespace usage in encoder: Add spaces between
-    array and object items, never append newline to output.
-  - Remove const qualifier from the ``json_t`` parameter in
-    `json_string_set()`, `json_integer_set()` and `json_real_set`.
-  - Use ``int32_t`` internally for representing Unicode code points
-    (int is not enough on all platforms)
-
-* Other changes:
-
-  - Convert ``CHANGES`` (this file) to reStructured text and add it to
-    HTML documentation
-  - The test system has been refactored. Python is no longer required
-    to run the tests.
-  - Documentation can now be built by invoking ``make html``
-  - Support for pkg-config
-
-
-Version 1.1.3
-=============
-
-Released 2009-12-18
-
-* Encode reals correctly, so that first encoding and then decoding a
-  real always produces the same value
-* Don't export private symbols in ``libjansson.so``
-
-
-Version 1.1.2
-=============
-
-Released 2009-11-08
-
-* Fix a bug where an error message was not produced if the input file
-  could not be opened in `json_load_file()`
-* Fix an assertion failure in decoder caused by a minus sign without a
-  digit after it
-* Remove an unneeded include of ``stdint.h`` in ``jansson.h``
-
-
-Version 1.1.1
-=============
-
-Released 2009-10-26
-
-* All documentation files were not distributed with v1.1; build
-  documentation in make distcheck to prevent this in the future
-* Fix v1.1 release date in ``CHANGES``
-
-
-Version 1.1
-===========
-
-Released 2009-10-20
-
-* API additions and improvements:
-
-  - Extend array and object APIs
-  - Add functions to modify integer, real and string values
-  - Improve argument validation
-  - Use unsigned int instead of ``uint32_t`` for encoding flags
-
-* Enhance documentation
-
-  - Add getting started guide and tutorial
-  - Fix some typos
-  - General clarifications and cleanup
-
-* Check for integer and real overflows and underflows in decoder
-* Make singleton values thread-safe (``true``, ``false`` and ``null``)
-* Enhance circular reference handling
-* Don't define ``-std=c99`` in ``AM_CFLAGS``
-* Add C++ guards to ``jansson.h``
-* Minor performance and portability improvements
-* Expand test coverage
-
-
-Version 1.0.4
-=============
-
-Released 2009-10-11
-
-* Relax Autoconf version requirement to 2.59
-* Make Jansson compile on platforms where plain ``char`` is unsigned
-* Fix API tests for object
-
-
-Version 1.0.3
-=============
-
-Released 2009-09-14
-
-* Check for integer and real overflows and underflows in decoder
-* Use the Python json module for tests, or simplejson if the json
-  module is not found
-* Distribute changelog (this file)
-
-
-Version 1.0.2
-=============
-
-Released 2009-09-08
-
-* Handle EOF correctly in decoder
-
-
-Version 1.0.1
-=============
-
-Released 2009-09-04
-
-* Fixed broken `json_is_boolean()`
-
-
-Version 1.0
-===========
-
-Released 2009-08-25
-
-* Initial release
diff --git a/deps/jansson/CMakeLists.txt b/deps/jansson/CMakeLists.txt
deleted file mode 100644
index fc26dc8..0000000
--- a/deps/jansson/CMakeLists.txt
+++ /dev/null
@@ -1,476 +0,0 @@
-# Notes:
-#
-# Author: Paul Harris, June 2012
-# Additions: Joakim Soderberg, Febuary 2013
-#
-# Supports: building static/shared, release/debug/etc, can also build html docs
-# and some of the tests.
-# Note that its designed for out-of-tree builds, so it will not pollute your
-# source tree.
-#
-# TODO 1: Finish implementing tests. api tests are working, but the valgrind
-# variants are not flagging problems.
-#
-# TODO 2: There is a check_exports script that would try and incorporate.
-#
-# TODO 3: Consolidate version numbers, currently the version number is written
-# into: * cmake (here) * autotools (the configure) * source code header files.
-# Should not be written directly into header files, autotools/cmake can do
-# that job.
-#
-# Brief intro on how to use cmake:
-# > mkdir build (somewhere - we do out-of-tree builds)
-# > use cmake, ccmake, or cmake-gui to configure the project. for linux, you
-# can only choose one variant: release,debug,etc... and static or shared.
-# >> example:
-# >> cd build
-# >> ccmake -i ../path_to_jansson_dir
-# >>  inside, configure your options. press C until there are no lines
-#     with * next to them.
-# >>  note, I like to configure the 'install' path to ../install, so I get
-#     self-contained clean installs I can point other projects to.
-# >>  press G to 'generate' the project files.
-# >> make (to build the project)
-# >> make install
-# >> make test (to run the tests, if you enabled them)
-#
-# Brief description on how it works:
-# There is a small heirachy of CMakeLists.txt files which define how the
-# project is built.
-# Header file detection etc is done, and the results are written into config.h
-# and jansson_config.h, which are generated from the corresponding
-# config.h.cmake and jansson_config.h.cmake template files.
-# The generated header files end up in the build directory - not in
-# the source directory.
-# The rest is down to the usual make process.
-
-
-
-cmake_minimum_required (VERSION 2.8)
-# required for exports? cmake_minimum_required (VERSION 2.8.6)
-project (jansson C)
-
-# Set some nicer output dirs.
-SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
-SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
-SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
-
-# Give the debug version a different postfix for windows,
-# so both the debug and release version can be built in the
-# same build-tree on Windows (MSVC).
-if (WIN32)
-   SET (CMAKE_DEBUG_POSTFIX "_d")
-else (WIN32)
-endif (WIN32)
-
-# This is how I thought it should go
-# set (JANSSON_VERSION "2.3.1")
-# set (JANSSON_SOVERSION 2)
-
-set(JANSSON_DISPLAY_VERSION "2.5")
-
-# This is what is required to match the same numbers as automake's
-set (JANSSON_VERSION "4.5.0")
-set (JANSSON_SOVERSION 4)
-
-# for CheckFunctionKeywords
-set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
-
-include (CheckFunctionExists)
-include (CheckFunctionKeywords)
-include (CheckIncludeFiles)
-include (CheckTypeSize)
-include (CheckSymbolExists)
-
-
-if (MSVC)
-   # Turn off Microsofts "security" warnings.
-   add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo" )
-   
-   # Disabled by OBS, options already set by top level CMakeLists
-   if (FALSE)
-      set(CMAKE_C_FLAGS_RELEASE "/MT")
-      set(CMAKE_C_FLAGS_DEBUG "/MTd")
-   endif()
-   
-endif()
-
-if (NOT WIN32 AND NOT APPLE)
-   set(CMAKE_C_FLAGS "-fPIC")
-endif()
-
-   
-
-# Check for the int-type includes
-check_include_files (sys/types.h HAVE_SYS_TYPES_H)
-check_include_files (inttypes.h HAVE_INTTYPES_H)
-check_include_files (stdint.h HAVE_STDINT_H)
-
-
-# Check our 64 bit integer sizes
-check_type_size (__int64 __INT64)
-check_type_size (int64_t INT64_T)
-check_type_size ("long long" LONG_LONG_INT)
-
-# Check our 32 bit integer sizes
-check_type_size (int32_t INT32_T)
-check_type_size (__int32 __INT32)
-check_type_size ("long" LONG_INT)
-check_type_size ("int" INT)
-
-if (HAVE_INT32_T)
-   set (JSON_INT32 int32_t)
-elseif (HAVE___INT32)
-   set (JSON_INT32 __int32)
-elseif (HAVE_LONG AND (${LONG_INT} EQUAL 4))
-   set (JSON_INT32 long)
-elseif (HAVE_INT AND (${INT} EQUAL 4))
-   set (JSON_INT32 int)
-else ()
-   message (FATAL_ERROR "Could not detect a valid 32 bit integer type")
-endif ()
-
-# Check for ssize_t and SSIZE_T existance.
-check_type_size(ssize_t SSIZE_T)
-check_type_size(SSIZE_T UPPERCASE_SSIZE_T)
-if(NOT HAVE_SSIZE_T)
-   if(HAVE_UPPERCASE_SSIZE_T)
-      set(JSON_SSIZE SSIZE_T)
-   else()
-      set(JSON_SSIZE int)
-   endif()
-endif()
-set(CMAKE_EXTRA_INCLUDE_FILES "")
-
-# Check for all the variants of strtoll
-check_function_exists (strtoll HAVE_STRTOLL)
-check_function_exists (strtoq HAVE_STRTOQ)
-check_function_exists (_strtoi64 HAVE__STRTOI64)
-
-# Figure out what variant we should use
-if (HAVE_STRTOLL)
-   set (JSON_STRTOINT strtoll)
-elseif (HAVE_STRTOQ)
-   set (JSON_STRTOINT strtoq)
-elseif (HAVE__STRTOI64)
-   set (JSON_STRTOINT _strtoi64)
-else ()
-   # fallback to strtol (32 bit)
-   # this will set all the required variables
-   set (JSON_STRTOINT strtol)
-   set (JSON_INT_T long)
-   set (JSON_INTEGER_FORMAT "\"ld\"")
-endif ()
-
-# if we haven't defined JSON_INT_T, then we have a 64 bit conversion function.
-# detect what to use for the 64 bit type.
-# Note: I will prefer long long if I can get it, as that is what the automake system aimed for.
-if (NOT DEFINED JSON_INT_T)
-   if (HAVE_LONG_LONG_INT AND (${LONG_LONG_INT} EQUAL 8))
-      set (JSON_INT_T "long long")
-   elseif (HAVE_INT64_T)
-      set (JSON_INT_T int64_t)
-   elseif (HAVE___INT64)
-      set (JSON_INT_T __int64)
-   else ()
-      message (FATAL_ERROR "Could not detect 64 bit type, although I detected the strtoll equivalent")
-   endif ()
-
-   # Apparently, Borland BCC and MSVC wants I64d,
-   # Borland BCC could also accept LD
-   # and gcc wants ldd,
-   # I am not sure what cygwin will want, so I will assume I64d
-
-   if (WIN32) # matches both msvc and cygwin
-      set (JSON_INTEGER_FORMAT "\"I64d\"")
-   else ()
-      set (JSON_INTEGER_FORMAT "\"lld\"")
-   endif ()
-endif ()
-
-
-# If locale.h and localeconv() are available, define to 1, otherwise to 0.
-check_include_files (locale.h HAVE_LOCALE_H)
-check_function_exists (localeconv HAVE_LOCALECONV)
-
-if (HAVE_LOCALECONV AND HAVE_LOCALE_H)
-   set (JSON_HAVE_LOCALECONV 1)
-else ()
-   set (JSON_HAVE_LOCALECONV 0)
-endif ()
-
-
-# check if we have setlocale
-check_function_exists (setlocale HAVE_SETLOCALE)
-
-
-# Check what the inline keyword is.
-# Note that the original JSON_INLINE was always set to just 'inline', so this goes further.
-check_function_keywords("inline")
-check_function_keywords("__inline")
-check_function_keywords("__inline__")
-
-if (HAVE_INLINE)
-   set (JSON_INLINE inline)
-elseif (HAVE___INLINE)
-   set (JSON_INLINE __inline)
-elseif (HAVE___INLINE__)
-   set (JSON_INLINE __inline__)
-else (HAVE_INLINE)
-   # no inline on this platform
-   set (JSON_INLINE)
-endif (HAVE_INLINE)
-
-# Find our snprintf
-check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
-check_symbol_exists(_snprintf "stdio.h" HAVE__SNPRINTF)
-
-if (HAVE_SNPRINTF)
-   set (JSON_SNPRINTF snprintf)
-elseif (HAVE__SNPRINTF)
-   set (JSON_SNPRINTF _snprintf)
-endif ()
-
-# Create pkg-conf file.
-# (We use the same files as ./configure does, so we
-#  have to defined the same variables used there).
-if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
-  set(CMAKE_INSTALL_LIBDIR lib)
-endif(NOT DEFINED CMAKE_INSTALL_LIBDIR)
-set(prefix      ${CMAKE_INSTALL_PREFIX})
-set(exec_prefix ${CMAKE_INSTALL_PREFIX})
-set(libdir      ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
-set(VERSION     ${JANSSON_DISPLAY_VERSION})
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/jansson.pc.in
-               ${CMAKE_CURRENT_BINARY_DIR}/jansson.pc @ONLY)
-
-# configure the public config file
-configure_file (${CMAKE_CURRENT_SOURCE_DIR}/cmake/jansson_config.h.cmake
-                ${CMAKE_CURRENT_BINARY_DIR}/include/jansson_config.h)
-
-# Copy the jansson.h file to the public include folder
-file (COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/jansson.h
-           DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/)
-
-
-# configure the private config file
-configure_file (${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.h.cmake
-                ${CMAKE_CURRENT_BINARY_DIR}/private_include/config.h)
-
-# and tell the source code to include it
-add_definitions (-DHAVE_CONFIG_H)
-
-include_directories (${CMAKE_CURRENT_BINARY_DIR}/include)
-include_directories (${CMAKE_CURRENT_BINARY_DIR}/private_include)
-
-# Add the lib sources.
-file (GLOB C_FILES src/*.c)
-
-# Disabled by OBS, we use it as a static library
-if (FALSE)
-
-   add_library (jansson SHARED ${C_FILES} src/jansson.def)
-
-   set_target_properties (jansson PROPERTIES
-      VERSION ${JANSSON_VERSION}
-      SOVERSION ${JANSSON_SOVERSION})
-
-else ()
-
-   add_library (jansson ${C_FILES})
-
-endif ()
-
-# LIBRARY for linux
-# RUNTIME for windows (when building shared)
-#install (TARGETS jansson
-#   ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-#   LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-#   RUNTIME DESTINATION bin
-#)
-
-#install (FILES
-#         ${CMAKE_CURRENT_BINARY_DIR}/include/jansson_config.h
-#         ${CMAKE_CURRENT_SOURCE_DIR}/src/jansson.h
-#         DESTINATION include)
-
-#install (FILES 
-#         ${CMAKE_CURRENT_BINARY_DIR}/jansson.pc
-#         DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
-
-# For building Documentation (uses Sphinx)
-# OPTION (BUILD_DOCS "Build documentation (uses python-sphinx)." ON)
-# Disabled by OBS
-if (FALSE)
-   find_package(Sphinx)
-
-   if (NOT SPHINX_FOUND)
-      message(WARNING "Sphinx not found. Cannot generate documentation! 
-      Set -DBUILD_DOCS=0 to get rid of this message.")
-   else()
-      if (Sphinx_VERSION_STRING VERSION_LESS 1.0)
-         message(WARNING "Your Sphinx version is too old! 
-               This project requires Sphinx v1.0 or above to produce 
-               proper documentation (you have v${Sphinx_VERSION_STRING}).
-               You will get output but it will have errors.")
-      endif()
-
-      # configured documentation tools and intermediate build results
-      set(BINARY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/_build")
-
-      # Sphinx cache with pickled ReST documents
-      set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees")
-
-      # CMake could be used to build the conf.py file too,
-      # eg it could automatically write the version of the program or change the theme.
-      # if(NOT DEFINED SPHINX_THEME)
-      #    set(SPHINX_THEME default)
-      # endif()
-      #
-      # if(NOT DEFINED SPHINX_THEME_DIR)
-      #    set(SPHINX_THEME_DIR)
-      # endif()
-      #
-      # configure_file(
-      #    "${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in"
-      #    "${BINARY_BUILD_DIR}/conf.py"
-      #    @ONLY)
-
-      # TODO: Add support for all sphinx builders: http://sphinx-doc.org/builders.html
-
-      # Add documentation targets.
-      set(DOC_TARGETS html)
-
-      OPTION(BUILD_MAN "Create a target for building man pages." ON)
-
-      if (BUILD_MAN)
-         if (Sphinx_VERSION_STRING VERSION_LESS 1.0)
-            message(WARNING "Sphinx version 1.0 > is required to build man pages. You have v${Sphinx_VERSION_STRING}.")
-         else()
-            list(APPEND DOC_TARGETS man)
-         endif()
-      endif()
-
-      OPTION(BUILD_LATEX "Create a target for building latex docs (to create PDF)." OFF)
-
-      if (BUILD_LATEX)
-         find_package(LATEX)
-
-         if (NOT LATEX_COMPILER)
-            message("Couldn't find Latex, can't build latex docs using Sphinx")
-         else()
-            message("Latex found! If you have problems building, see Sphinx documentation for required Latex packages.")
-            list(APPEND DOC_TARGETS latex)
-         endif()
-      endif()
-      
-      # The doc target will build all documentation targets.
-      add_custom_target(doc)
-
-      foreach (DOC_TARGET ${DOC_TARGETS})
-         add_custom_target(${DOC_TARGET}
-            ${SPHINX_EXECUTABLE}
-            # -q   # Enable for quiet mode
-            -b ${DOC_TARGET}
-            -d "${SPHINX_CACHE_DIR}"
-            # -c "${BINARY_BUILD_DIR}" # enable if using cmake-generated conf.py
-            "${CMAKE_CURRENT_SOURCE_DIR}/doc"
-            "${CMAKE_CURRENT_BINARY_DIR}/doc/${DOC_TARGET}"
-            COMMENT "Building ${DOC_TARGET} documentation with Sphinx")
-
-         add_dependencies(doc ${DOC_TARGET})
-      endforeach()
-
-      message("Building documentation enabled for: ${DOC_TARGETS}")
-   endif()
-endif ()
-
-# Disabled by OBS, we don't test this.
-if (FALSE)
-   OPTION (TEST_WITH_VALGRIND "Enable valgrind tests." OFF)
-
-   ENABLE_TESTING()
-
-   if (TEST_WITH_VALGRIND)
-      # TODO: Add FindValgrind.cmake instead of having a hardcoded path.
-
-      # enable valgrind
-      set(CMAKE_MEMORYCHECK_COMMAND valgrind)
-      set(CMAKE_MEMORYCHECK_COMMAND_OPTIONS
-         "--leak-check=full --show-reachable=yes --track-origins=yes -q")
-
-      set(MEMCHECK_COMMAND
-         "${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS}")
-      separate_arguments(MEMCHECK_COMMAND)
-   endif ()
-
-   #
-   # Test suites.
-   #
-   if (CMAKE_COMPILER_IS_GNUCC)
-      add_definitions(-Wall -Wextra -Wdeclaration-after-statement)
-   endif ()
-
-   set(api_tests
-         test_array
-         test_copy
-         test_dump
-         test_dump_callback
-         test_equal
-         test_load
-         test_loadb
-         test_number
-         test_object
-         test_pack
-         test_simple
-         test_unpack)
-
-   # Doing arithmetic on void pointers is not allowed by Microsofts compiler
-   # such as secure_malloc and secure_free is doing, so exclude it for now.
-   if (NOT MSVC)
-      list(APPEND api_tests test_memory_funcs)
-   endif()
-
-   # Helper macro for building and linking a test program.
-   macro(build_testprog name dir)
-       add_executable(${name} ${dir}/${name}.c)
-       add_dependencies(${name} jansson)
-       target_link_libraries(${name} jansson)
-   endmacro(build_testprog)
-
-   # Create executables and tests/valgrind tests for API tests.
-   foreach (test ${api_tests})
-      build_testprog(${test} ${PROJECT_SOURCE_DIR}/test/suites/api)
-      add_test(${test} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test})
-
-      if (TEST_WITH_VALGRIND)
-         add_test(memcheck_${test} ${MEMCHECK_COMMAND}
-                  ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test})
-      endif ()
-   endforeach ()
-
-   # Test harness for the suites tests.
-   build_testprog(json_process ${PROJECT_SOURCE_DIR}/test/bin)
-
-   set(SUITES encoding-flags valid invalid invalid-unicode)
-   foreach (SUITE ${SUITES})
-       file(GLOB TESTDIRS ${jansson_SOURCE_DIR}/test/suites/${SUITE}/*)
-       foreach (TESTDIR ${TESTDIRS})
-         if (IS_DIRECTORY ${TESTDIR})
-            get_filename_component(TNAME ${TESTDIR} NAME)
-            add_test(${SUITE}__${TNAME}
-                     ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/json_process ${TESTDIR})
-            if ((${SUITE} STREQUAL "valid" OR ${SUITE} STREQUAL "invalid") AND NOT EXISTS ${TESTDIR}/nostrip)
-               add_test(${SUITE}__${TNAME}__strip
-                        ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/json_process --strip ${TESTDIR})
-            endif ()
-         endif ()
-       endforeach ()
-   endforeach ()
-
-   add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} 
-                     DEPENDS json_process ${api_tests})
-endif ()
-
-target_include_directories(jansson
-	PUBLIC src "${CMAKE_CURRENT_BINARY_DIR}/include")
diff --git a/deps/jansson/CleanSpec.mk b/deps/jansson/CleanSpec.mk
deleted file mode 100644
index b84e1b6..0000000
--- a/deps/jansson/CleanSpec.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# If you don't need to do a full clean build but would like to touch
-# a file or delete some intermediate files, add a clean step to the end
-# of the list.  These steps will only be run once, if they haven't been
-# run before.
-#
-# E.g.:
-#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
-#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
-#
-# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
-# files that are missing or have been moved.
-#
-# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
-# Use $(OUT_DIR) to refer to the "out" directory.
-#
-# If you need to re-do something that's already mentioned, just copy
-# the command and add it to the bottom of the list.  E.g., if a change
-# that you made last week required touching a file and a change you
-# made today requires touching the same file, just copy the old
-# touch step and add it to the end of the list.
-#
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
-
-# For example:
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
-#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
-#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
-
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
diff --git a/deps/jansson/LICENSE b/deps/jansson/LICENSE
deleted file mode 100644
index a8fb5b8..0000000
--- a/deps/jansson/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/deps/jansson/Makefile.am b/deps/jansson/Makefile.am
deleted file mode 100644
index 788f9ac..0000000
--- a/deps/jansson/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-EXTRA_DIST = CHANGES LICENSE README.rst win32 CMakeLists.txt cmake
-SUBDIRS = doc src test
-
-# "make distcheck" builds the dvi target, so use it to check that the
-# documentation is built correctly.
-dvi:
-	$(MAKE) SPHINXOPTS_EXTRA=-W html
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = jansson.pc
-
-if GCC
-# These flags are gcc specific
-export AM_CFLAGS = -Wall -Wextra -Wdeclaration-after-statement
-endif
diff --git a/deps/jansson/README.rst b/deps/jansson/README.rst
deleted file mode 100644
index a01cbc0..0000000
--- a/deps/jansson/README.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-Jansson README
-==============
-
-.. image:: https://travis-ci.org/akheron/jansson.png
-  :alt: Build status
-  :target: https://travis-ci.org/akheron/jansson
-
-Jansson_ is a C library for encoding, decoding and manipulating JSON
-data. Its main features and design principles are:
-
-- Simple and intuitive API and data model
-
-- Comprehensive documentation
-
-- No dependencies on other libraries
-
-- Full Unicode support (UTF-8)
-
-- Extensive test suite
-
-Jansson is licensed under the `MIT license`_; see LICENSE in the
-source distribution for details.
-
-
-Compilation and Installation
-----------------------------
-
-If you obtained a source tarball, just use the standard autotools
-commands::
-
-   $ ./configure
-   $ make
-   $ make install
-
-To run the test suite, invoke::
-
-   $ make check
-
-If the source has been checked out from a Git repository, the
-./configure script has to be generated first. The easiest way is to
-use autoreconf::
-
-   $ autoreconf -i
-
-
-Documentation
--------------
-
-Prebuilt HTML documentation is available at
-http://www.digip.org/jansson/doc/.
-
-The documentation source is in the ``doc/`` subdirectory. To generate
-HTML documentation, invoke::
-
-   $ make html
-
-Then, point your browser to ``doc/_build/html/index.html``. Sphinx_
-1.0 or newer is required to generate the documentation.
-
-
-.. _Jansson: http://www.digip.org/jansson/
-.. _`MIT license`: http://www.opensource.org/licenses/mit-license.php
-.. _Sphinx: http://sphinx.pocoo.org/
diff --git a/deps/jansson/android/jansson_config.h b/deps/jansson/android/jansson_config.h
deleted file mode 100644
index c76940b..0000000
--- a/deps/jansson/android/jansson_config.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2010-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- *
- *
- * This file specifies a part of the site-specific configuration for
- * Jansson, namely those things that affect the public API in
- * jansson.h.
- *
- * The configure script copies this file to jansson_config.h and
- * replaces @var@ substitutions by values that fit your system. If you
- * cannot run the configure script, you can do the value substitution
- * by hand.
- */
-
-#ifndef JANSSON_CONFIG_H
-#define JANSSON_CONFIG_H
-
-/* If your compiler supports the inline keyword in C, JSON_INLINE is
-   defined to `inline', otherwise empty. In C++, the inline is always
-   supported. */
-#ifdef __cplusplus
-#define JSON_INLINE inline
-#else
-#define JSON_INLINE inline
-#endif
-
-/* If your compiler supports the `long long` type and the strtoll()
-   library function, JSON_INTEGER_IS_LONG_LONG is defined to 1,
-   otherwise to 0. */
-#define JSON_INTEGER_IS_LONG_LONG 1
-
-/* If locale.h and localeconv() are available, define to 1,
-   otherwise to 0. */
-#define JSON_HAVE_LOCALECONV 0
-
-#endif
diff --git a/deps/jansson/cmake/CheckFunctionKeywords.cmake b/deps/jansson/cmake/CheckFunctionKeywords.cmake
deleted file mode 100644
index 44601fd..0000000
--- a/deps/jansson/cmake/CheckFunctionKeywords.cmake
+++ /dev/null
@@ -1,15 +0,0 @@
-include(CheckCSourceCompiles)
-
-macro(check_function_keywords _wordlist)
-  set(${_result} "")
-  foreach(flag ${_wordlist})
-    string(REGEX REPLACE "[-+/ ()]" "_" flagname "${flag}")
-    string(TOUPPER "${flagname}" flagname)
-    set(have_flag "HAVE_${flagname}")
-    check_c_source_compiles("${flag} void func(); void func() { } int main() { func(); return 0; }" ${have_flag})
-    if(${have_flag} AND NOT ${_result})
-      set(${_result} "${flag}")
-#      break()
-    endif(${have_flag} AND NOT ${_result})
-  endforeach(flag)
-endmacro(check_function_keywords)
diff --git a/deps/jansson/cmake/FindSphinx.cmake b/deps/jansson/cmake/FindSphinx.cmake
deleted file mode 100644
index 55539d4..0000000
--- a/deps/jansson/cmake/FindSphinx.cmake
+++ /dev/null
@@ -1,301 +0,0 @@
-#
-# PART B. DOWNLOADING AGREEMENT - LICENSE FROM SBIA WITH RIGHT TO SUBLICENSE ("SOFTWARE LICENSE").
-#  ------------------------------------------------------------------------------------------------
-#
-#  1. As used in this Software License, "you" means the individual downloading and/or
-#     using, reproducing, modifying, displaying and/or distributing the Software and
-#     the institution or entity which employs or is otherwise affiliated with such
-#     individual in connection therewith. The Section of Biomedical Image Analysis,
-#     Department of Radiology at the Universiy of Pennsylvania ("SBIA") hereby grants
-#     you, with right to sublicense, with respect to SBIA's rights in the software,
-#     and data, if any, which is the subject of this Software License (collectively,
-#     the "Software"), a royalty-free, non-exclusive license to use, reproduce, make
-#     derivative works of, display and distribute the Software, provided that:
-#     (a) you accept and adhere to all of the terms and conditions of this Software
-#     License; (b) in connection with any copy of or sublicense of all or any portion
-#     of the Software, all of the terms and conditions in this Software License shall
-#     appear in and shall apply to such copy and such sublicense, including without
-#     limitation all source and executable forms and on any user documentation,
-#     prefaced with the following words: "All or portions of this licensed product
-#     (such portions are the "Software") have been obtained under license from the
-#     Section of Biomedical Image Analysis, Department of Radiology at the University
-#     of Pennsylvania and are subject to the following terms and conditions:"
-#     (c) you preserve and maintain all applicable attributions, copyright notices
-#     and licenses included in or applicable to the Software; (d) modified versions
-#     of the Software must be clearly identified and marked as such, and must not
-#     be misrepresented as being the original Software; and (e) you consider making,
-#     but are under no obligation to make, the source code of any of your modifications
-#     to the Software freely available to others on an open source basis.
-#
-#  2. The license granted in this Software License includes without limitation the
-#     right to (i) incorporate the Software into proprietary programs (subject to
-#     any restrictions applicable to such programs), (ii) add your own copyright
-#     statement to your modifications of the Software, and (iii) provide additional
-#     or different license terms and conditions in your sublicenses of modifications
-#     of the Software; provided that in each case your use, reproduction or
-#     distribution of such modifications otherwise complies with the conditions
-#     stated in this Software License.
-#
-#  3. This Software License does not grant any rights with respect to third party
-#     software, except those rights that SBIA has been authorized by a third
-#     party to grant to you, and accordingly you are solely responsible for
-#     (i) obtaining any permissions from third parties that you need to use,
-#     reproduce, make derivative works of, display and distribute the Software,
-#     and (ii) informing your sublicensees, including without limitation your
-#     end-users, of their obligations to secure any such required permissions.
-#
-#  4. The Software has been designed for research purposes only and has not been
-#     reviewed or approved by the Food and Drug Administration or by any other
-#     agency. YOU ACKNOWLEDGE AND AGREE THAT CLINICAL APPLICATIONS ARE NEITHER
-#     RECOMMENDED NOR ADVISED. Any commercialization of the Software is at the
-#     sole risk of the party or parties engaged in such commercialization.
-#     You further agree to use, reproduce, make derivative works of, display
-#     and distribute the Software in compliance with all applicable governmental
-#     laws, regulations and orders, including without limitation those relating
-#     to export and import control.
-#
-#  5. The Software is provided "AS IS" and neither SBIA nor any contributor to
-#     the software (each a "Contributor") shall have any obligation to provide
-#     maintenance, support, updates, enhancements or modifications thereto.
-#     SBIA AND ALL CONTRIBUTORS SPECIFICALLY DISCLAIM ALL EXPRESS AND IMPLIED
-#     WARRANTIES OF ANY KIND INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF
-#     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-#     IN NO EVENT SHALL SBIA OR ANY CONTRIBUTOR BE LIABLE TO ANY PARTY FOR
-#     DIRECT, INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES
-#     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY ARISING IN ANY WAY RELATED
-#     TO THE SOFTWARE, EVEN IF SBIA OR ANY CONTRIBUTOR HAS BEEN ADVISED OF THE
-#     POSSIBILITY OF SUCH DAMAGES. TO THE MAXIMUM EXTENT NOT PROHIBITED BY LAW OR
-#     REGULATION, YOU FURTHER ASSUME ALL LIABILITY FOR YOUR USE, REPRODUCTION,
-#     MAKING OF DERIVATIVE WORKS, DISPLAY, LICENSE OR DISTRIBUTION OF THE SOFTWARE
-#     AND AGREE TO INDEMNIFY AND HOLD HARMLESS SBIA AND ALL CONTRIBUTORS FROM
-#     AND AGAINST ANY AND ALL CLAIMS, SUITS, ACTIONS, DEMANDS AND JUDGMENTS ARISING
-#     THEREFROM.
-#
-#  6. None of the names, logos or trademarks of SBIA or any of SBIA's affiliates
-#     or any of the Contributors, or any funding agency, may be used to endorse
-#     or promote products produced in whole or in part by operation of the Software
-#     or derived from or based on the Software without specific prior written
-#     permission from the applicable party.
-#
-#  7. Any use, reproduction or distribution of the Software which is not in accordance
-#     with this Software License shall automatically revoke all rights granted to you
-#     under this Software License and render Paragraphs 1 and 2 of this Software
-#     License null and void.
-#
-#  8. This Software License does not grant any rights in or to any intellectual
-#     property owned by SBIA or any Contributor except those rights expressly
-#     granted hereunder.
-#
-#
-#  PART C. MISCELLANEOUS
-#  ---------------------
-#
-#  This Agreement shall be governed by and construed in accordance with the laws
-#  of The Commonwealth of Pennsylvania without regard to principles of conflicts
-#  of law. This Agreement shall supercede and replace any license terms that you
-#  may have agreed to previously with respect to Software from SBIA.
-#
-##############################################################################
-# @file  FindSphinx.cmake
-# @brief Find Sphinx documentation build tools.
-#
-# @par Input variables:
-# <table border="0">
-#   <tr>
-#     @tp @b Sphinx_DIR @endtp
-#     <td>Installation directory of Sphinx tools. Can also be set as environment variable.</td>
-#   </tr>
-#   <tr>
-#     @tp @b SPHINX_DIR @endtp
-#     <td>Alternative environment variable for @c Sphinx_DIR.</td>
-#   </tr>
-#   <tr>
-#     @tp @b Sphinx_FIND_COMPONENTS @endtp
-#     <td>Sphinx build tools to look for, i.e., 'apidoc' and/or 'build'.</td>
-#   </tr>
-# </table>
-#
-# @par Output variables:
-# <table border="0">
-#   <tr>
-#     @tp @b Sphinx_FOUND @endtp
-#     <td>Whether all or only the requested Sphinx build tools were found.</td>
-#   </tr>
-#   <tr>
-#     @tp @b SPHINX_FOUND @endtp
-#     <td>Alias for @c Sphinx_FOUND.<td>
-#   </tr>
-#   <tr>
-#     @tp @b SPHINX_EXECUTABLE @endtp
-#     <td>Non-cached alias for @c Sphinx-build_EXECUTABLE.</td>
-#   </tr>
-#   <tr>
-#     @tp @b Sphinx_PYTHON_EXECUTABLE @endtp
-#     <td>Python executable used to run sphinx-build. This is either the
-#         by default found Python interpreter or a specific version as
-#         specified by the shebang (#!) of the sphinx-build script.</td>
-#   </tr>
-#   <tr>
-#     @tp @b Sphinx_PYTHON_OPTIONS @endtp
-#     <td>A list of Python options extracted from the shebang (#!) of the
-#         sphinx-build script. The -E option is added by this module
-#         if the Python executable is not the system default to avoid
-#         problems with a differing setting of the @c PYTHONHOME.</td>
-#   </tr>
-#   <tr>
-#     @tp @b Sphinx-build_EXECUTABLE @endtp
-#     <td>Absolute path of the found sphinx-build tool.</td>
-#   </tr>
-#   <tr>
-#     @tp @b Sphinx-apidoc_EXECUTABLE @endtp
-#     <td>Absolute path of the found sphinx-apidoc tool.</td>
-#   </tr>
-#   <tr>
-#     @tp @b Sphinx_VERSION_STRING @endtp
-#     <td>Sphinx version found e.g. 1.1.2.</td>
-#   </tr>
-#   <tr>
-#     @tp @b Sphinx_VERSION_MAJOR @endtp
-#     <td>Sphinx major version found e.g. 1.</td>
-#   </tr>
-#   <tr>
-#     @tp @b Sphinx_VERSION_MINOR @endtp
-#     <td>Sphinx minor version found e.g. 1.</td>
-#   </tr>
-#   <tr>
-#     @tp @b Sphinx_VERSION_PATCH @endtp
-#     <td>Sphinx patch version found e.g. 2.</td>
-#   </tr>
-# </table>
-#
-# @ingroup CMakeFindModules
-##############################################################################
-
-set (_Sphinx_REQUIRED_VARS)
-
-# ----------------------------------------------------------------------------
-# initialize search
-if (NOT Sphinx_DIR)
-  if (NOT $ENV{Sphinx_DIR} STREQUAL "")
-    set (Sphinx_DIR "$ENV{Sphinx_DIR}" CACHE PATH "Installation prefix of Sphinx (docutils)." FORCE)
-  else ()
-    set (Sphinx_DIR "$ENV{SPHINX_DIR}" CACHE PATH "Installation prefix of Sphinx (docutils)." FORCE)
-  endif ()
-endif ()
-
-# ----------------------------------------------------------------------------
-# default components to look for
-if (NOT Sphinx_FIND_COMPONENTS)
-  set (Sphinx_FIND_COMPONENTS "build")
-elseif (NOT Sphinx_FIND_COMPONENTS MATCHES "^(build|apidoc)$")
-  message (FATAL_ERROR "Invalid Sphinx component in: ${Sphinx_FIND_COMPONENTS}")
-endif ()
-
-# ----------------------------------------------------------------------------
-# find components, i.e., build tools
-foreach (_Sphinx_TOOL IN LISTS Sphinx_FIND_COMPONENTS)
-  if (Sphinx_DIR)
-    find_program (
-      Sphinx-${_Sphinx_TOOL}_EXECUTABLE
-      NAMES         sphinx-${_Sphinx_TOOL} sphinx-${_Sphinx_TOOL}.py
-      HINTS         "${Sphinx_DIR}"
-      PATH_SUFFIXES bin
-      DOC           "The sphinx-${_Sphinx_TOOL} Python script."
-      NO_DEFAULT_PATH
-    )
-  else ()
-    find_program (
-      Sphinx-${_Sphinx_TOOL}_EXECUTABLE
-      NAMES sphinx-${_Sphinx_TOOL} sphinx-${_Sphinx_TOOL}.py
-      DOC   "The sphinx-${_Sphinx_TOOL} Python script."
-    )
-  endif ()
-  mark_as_advanced (Sphinx-${_Sphinx_TOOL}_EXECUTABLE)
-  list (APPEND _Sphinx_REQUIRED_VARS Sphinx-${_Sphinx_TOOL}_EXECUTABLE)
-endforeach ()
-
-# ----------------------------------------------------------------------------
-# determine Python executable used by Sphinx
-if (Sphinx-build_EXECUTABLE)
-  # extract python executable from shebang of sphinx-build
-  find_package (PythonInterp QUIET)
-  set (Sphinx_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}")
-  set (Sphinx_PYTHON_OPTIONS)
-  file (STRINGS "${Sphinx-build_EXECUTABLE}" FIRST_LINE LIMIT_COUNT 1)
-  if (FIRST_LINE MATCHES "^#!(.*/python.*)") # does not match "#!/usr/bin/env python" !
-    string (REGEX REPLACE "^ +| +$" "" Sphinx_PYTHON_EXECUTABLE "${CMAKE_MATCH_1}")
-    if (Sphinx_PYTHON_EXECUTABLE MATCHES "([^ ]+) (.*)")
-      set (Sphinx_PYTHON_EXECUTABLE "${CMAKE_MATCH_1}")
-      string (REGEX REPLACE " +" ";" Sphinx_PYTHON_OPTIONS "${CMAKE_MATCH_2}")
-    endif ()
-  endif ()
-  # this is done to avoid problems with multiple Python versions being installed
-  # remember: CMake command if(STR EQUAL STR) is bad and may cause many troubles !
-  string (REGEX REPLACE "([.+*?^$])" "\\\\\\1" _Sphinx_PYTHON_EXECUTABLE_RE "${PYTHON_EXECUTABLE}")
-  list (FIND Sphinx_PYTHON_OPTIONS -E IDX)
-  if (IDX EQUAL -1 AND NOT Sphinx_PYTHON_EXECUTABLE MATCHES "^${_Sphinx_PYTHON_EXECUTABLE_RE}$")
-    list (INSERT Sphinx_PYTHON_OPTIONS 0 -E)
-  endif ()
-  unset (_Sphinx_PYTHON_EXECUTABLE_RE)
-endif ()
-
-# ----------------------------------------------------------------------------
-# determine Sphinx version
-if (Sphinx-build_EXECUTABLE)
-  # intentionally use invalid -h option here as the help that is shown then
-  # will include the Sphinx version information
-  if (Sphinx_PYTHON_EXECUTABLE)
-    execute_process (
-      COMMAND "${Sphinx_PYTHON_EXECUTABLE}" ${Sphinx_PYTHON_OPTIONS} "${Sphinx-build_EXECUTABLE}" -h
-      OUTPUT_VARIABLE _Sphinx_VERSION
-      ERROR_VARIABLE  _Sphinx_VERSION
-    )
-  elseif (UNIX)
-    execute_process (
-      COMMAND "${Sphinx-build_EXECUTABLE}" -h
-      OUTPUT_VARIABLE _Sphinx_VERSION
-      ERROR_VARIABLE  _Sphinx_VERSION
-    )
-  endif ()
-
-  # The sphinx version can also contain a "b" instead of the last dot.
-  # For example "Sphinx v1.2b1" so we cannot just split on "."
-  if (_Sphinx_VERSION MATCHES "Sphinx v([0-9]+\\.[0-9]+(\\.|b)[0-9]+)")
-    set (Sphinx_VERSION_STRING "${CMAKE_MATCH_1}")
-    string(REGEX REPLACE "([0-9]+)\\.[0-9]+(\\.|b)[0-9]+" "\\1" Sphinx_VERSION_MAJOR ${Sphinx_VERSION_STRING})
-    string(REGEX REPLACE "[0-9]+\\.([0-9]+)(\\.|b)[0-9]+" "\\1" Sphinx_VERSION_MINOR ${Sphinx_VERSION_STRING})
-    string(REGEX REPLACE "[0-9]+\\.[0-9]+(\\.|b)([0-9]+)" "\\1" Sphinx_VERSION_PATCH ${Sphinx_VERSION_STRING})
-
-    # v1.2.0 -> v1.2
-    if (Sphinx_VERSION_PATCH EQUAL 0)
-      string (REGEX REPLACE "\\.0$" "" Sphinx_VERSION_STRING "${Sphinx_VERSION_STRING}")
-    endif ()
-  endif()
-endif ()
-
-# ----------------------------------------------------------------------------
-# compatibility with FindPythonInterp.cmake and FindPerl.cmake
-set (SPHINX_EXECUTABLE "${Sphinx-build_EXECUTABLE}")
-
-# ----------------------------------------------------------------------------
-# handle the QUIETLY and REQUIRED arguments and set SPHINX_FOUND to TRUE if
-# all listed variables are TRUE
-include (FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS (
-  Sphinx
-  REQUIRED_VARS
-    ${_Sphinx_REQUIRED_VARS}
-#  VERSION_VAR # This isn't available until CMake 2.8.8 so don't use it.
-    Sphinx_VERSION_STRING
-)
-
-# ----------------------------------------------------------------------------
-# set Sphinx_DIR
-if (NOT Sphinx_DIR AND Sphinx-build_EXECUTABLE)
-  get_filename_component (Sphinx_DIR "${Sphinx-build_EXECUTABLE}" PATH)
-  string (REGEX REPLACE "/bin/?" "" Sphinx_DIR "${Sphinx_DIR}")
-  set (Sphinx_DIR "${Sphinx_DIR}" CACHE PATH "Installation directory of Sphinx tools." FORCE)
-endif ()
-
-unset (_Sphinx_VERSION)
-unset (_Sphinx_REQUIRED_VARS)
\ No newline at end of file
diff --git a/deps/jansson/cmake/config.h.cmake b/deps/jansson/cmake/config.h.cmake
deleted file mode 100644
index bc81178..0000000
--- a/deps/jansson/cmake/config.h.cmake
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Reduced down to the defines that are actually used in the code */
-
-/* Define to 1 if you have the <inttypes.h> (and friends) header file. */
-#cmakedefine HAVE_INTTYPES_H 1
-#cmakedefine HAVE_STDINT_H 1
-#cmakedefine HAVE_SYS_TYPES_H 1
-
-/* We must include this here, as in (eg) utf.h it will want to use
-   the integer type, which in MSVC2010 will be in stdint.h
-   (there is no inttypes.h in MSVC2010) */
-#if defined(HAVE_STDINT_H)
-#  include <stdint.h>
-#elif defined(HAVE_INTTYPES_H)
-#  include <inttypes.h>
-#elif defined(HAVE_SYS_TYPES_H)
-#  include <sys/types.h>
-#endif
-
-/* Define to 1 if you have the <locale.h> header file. */
-#cmakedefine HAVE_LOCALE_H 1
-
-/* Define to 1 if you have the 'setlocale' function. */
-#cmakedefine HAVE_SETLOCALE 1
-
-/* Define to the type of a signed integer type of width exactly 32 bits if
-   such a type exists and the standard includes do not define it. */
-#cmakedefine HAVE_INT32_T 1
-
-#ifndef HAVE_INT32_T
-#  define int32_t @JSON_INT32@
-#endif
-
-#cmakedefine HAVE_SSIZE_T 1
-
-#ifndef HAVE_SSIZE_T
-#  define ssize_t @JSON_SSIZE@
-#endif
-
-#cmakedefine HAVE_SNPRINTF 1
-
-#ifndef HAVE_SNPRINTF
-#  define snprintf @JSON_SNPRINTF@
-#endif
-
-#cmakedefine HAVE_VSNPRINTF
diff --git a/deps/jansson/cmake/jansson_config.h.cmake b/deps/jansson/cmake/jansson_config.h.cmake
deleted file mode 100644
index 8c500b5..0000000
--- a/deps/jansson/cmake/jansson_config.h.cmake
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2010-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- *
- *
- * This file specifies a part of the site-specific configuration for
- * Jansson, namely those things that affect the public API in
- * jansson.h.
- *
- * The CMake system will generate the jansson_config.h file and
- * copy it to the build and install directories.
- */
-
-#ifndef JANSSON_CONFIG_H
-#define JANSSON_CONFIG_H
-
-/* Define this so that we can disable scattered automake configuration in source files */
-#define JANSSON_USING_CMAKE
-
-/* Note: when using cmake, JSON_INTEGER_IS_LONG_LONG is not defined nor used,
- * as we will also check for __int64 etc types.
- * (the definition was used in the automake system) */
-
-/* Bring in the cmake-detected defines */
-#cmakedefine HAVE_STDINT_H 1
-#cmakedefine HAVE_INTTYPES_H 1
-#cmakedefine HAVE_SYS_TYPES_H 1
-
-/* Include our standard type header for the integer typedef */
-
-#if defined(HAVE_STDINT_H)
-#  include <stdint.h>
-#elif defined(HAVE_INTTYPES_H)
-#  include <inttypes.h>
-#elif defined(HAVE_SYS_TYPES_H)
-#  include <sys/types.h>
-#endif
-
-
-/* If your compiler supports the inline keyword in C, JSON_INLINE is
-   defined to `inline', otherwise empty. In C++, the inline is always
-   supported. */
-#ifdef __cplusplus
-#define JSON_INLINE inline
-#else
-#define JSON_INLINE @JSON_INLINE@
-#endif
-
-
-#define json_int_t @JSON_INT_T@
-#define json_strtoint @JSON_STRTOINT@
-#define JSON_INTEGER_FORMAT @JSON_INTEGER_FORMAT@
-
-
-/* If locale.h and localeconv() are available, define to 1, otherwise to 0. */
-#define JSON_HAVE_LOCALECONV @JSON_HAVE_LOCALECONV@
-
-
-
-#endif
diff --git a/deps/jansson/configure.ac b/deps/jansson/configure.ac
deleted file mode 100644
index 24ba37d..0000000
--- a/deps/jansson/configure.ac
+++ /dev/null
@@ -1,57 +0,0 @@
-AC_PREREQ([2.60])
-AC_INIT([jansson], [2.5], [petri at digip.org])
-
-AM_INIT_AUTOMAKE([1.10 foreign])
-
-AC_CONFIG_SRCDIR([src/value.c])
-AC_CONFIG_HEADERS([config.h])
-
-# Checks for programs.
-AC_PROG_CC
-AC_PROG_LIBTOOL
-AM_CONDITIONAL([GCC], [test x$GCC = xyes])
-
-# Checks for libraries.
-
-# Checks for header files.
-AC_CHECK_HEADERS([locale.h])
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_TYPE_INT32_T
-AC_TYPE_LONG_LONG_INT
-
-AC_C_INLINE
-case $ac_cv_c_inline in
-    yes) json_inline=inline;;
-    no) json_inline=;;
-    *) json_inline=$ac_cv_c_inline;;
-esac
-AC_SUBST([json_inline])
-
-# Checks for library functions.
-AC_CHECK_FUNCS([strtoll localeconv])
-
-case "$ac_cv_type_long_long_int$ac_cv_func_strtoll" in
-     yesyes) json_have_long_long=1;;
-     *) json_have_long_long=0;;
-esac
-AC_SUBST([json_have_long_long])
-
-case "$ac_cv_header_locale_h$ac_cv_func_localeconv" in
-     yesyes) json_have_localeconv=1;;
-     *) json_have_localeconv=0;;
-esac
-AC_SUBST([json_have_localeconv])
-
-AC_CONFIG_FILES([
-        jansson.pc
-        Makefile
-        doc/Makefile
-        src/Makefile
-        src/jansson_config.h
-        test/Makefile
-        test/bin/Makefile
-        test/suites/Makefile
-        test/suites/api/Makefile
-])
-AC_OUTPUT
diff --git a/deps/jansson/doc/.gitignore b/deps/jansson/doc/.gitignore
deleted file mode 100644
index 69fa449..0000000
--- a/deps/jansson/doc/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-_build/
diff --git a/deps/jansson/doc/Makefile.am b/deps/jansson/doc/Makefile.am
deleted file mode 100644
index 5069623..0000000
--- a/deps/jansson/doc/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-EXTRA_DIST = conf.py apiref.rst changes.rst conformance.rst		\
-	gettingstarted.rst github_commits.c index.rst portability.rst	\
-	tutorial.rst upgrading.rst ext/refcounting.py
-
-SPHINXBUILD = sphinx-build
-SPHINXOPTS = -d _build/doctrees $(SPHINXOPTS_EXTRA)
-
-html-local:
-	$(SPHINXBUILD) -b html $(SPHINXOPTS) $(srcdir) _build/html
-
-install-html-local: html
-	mkdir -p $(DESTDIR)$(htmldir)
-	cp -r _build/html $(DESTDIR)$(htmldir)
-
-uninstall-local:
-	rm -rf $(DESTDIR)$(htmldir)
-
-clean-local:
-	rm -rf _build
-	rm -f ext/refcounting.pyc
diff --git a/deps/jansson/doc/README b/deps/jansson/doc/README
deleted file mode 100644
index 930b3bf..0000000
--- a/deps/jansson/doc/README
+++ /dev/null
@@ -1,5 +0,0 @@
-To build the documentation, invoke
-
-    make html
-
-Then point your browser to _build/html/index.html.
diff --git a/deps/jansson/doc/apiref.rst b/deps/jansson/doc/apiref.rst
deleted file mode 100644
index 717e140..0000000
--- a/deps/jansson/doc/apiref.rst
+++ /dev/null
@@ -1,1560 +0,0 @@
-.. _apiref:
-
-*************
-API Reference
-*************
-
-.. highlight:: c
-
-Preliminaries
-=============
-
-All declarations are in :file:`jansson.h`, so it's enough to
-
-::
-
-   #include <jansson.h>
-
-in each source file.
-
-All constants are prefixed with ``JSON_`` (except for those describing
-the library version, prefixed with ``JANSSON_``). Other identifiers
-are prefixed with ``json_``. Type names are suffixed with ``_t`` and
-``typedef``\ 'd so that the ``struct`` keyword need not be used.
-
-
-Library Version
-===============
-
-The Jansson version is of the form *A.B.C*, where *A* is the major
-version, *B* is the minor version and *C* is the micro version. If the
-micro version is zero, it's omitted from the version string, i.e. the
-version string is just *A.B*.
-
-When a new release only fixes bugs and doesn't add new features or
-functionality, the micro version is incremented. When new features are
-added in a backwards compatible way, the minor version is incremented
-and the micro version is set to zero. When there are backwards
-incompatible changes, the major version is incremented and others are
-set to zero.
-
-The following preprocessor constants specify the current version of
-the library:
-
-``JANSSON_MAJOR_VERSION``, ``JANSSON_MINOR_VERSION``, ``JANSSON_MICRO_VERSION``
-  Integers specifying the major, minor and micro versions,
-  respectively.
-
-``JANSSON_VERSION``
-  A string representation of the current version, e.g. ``"1.2.1"`` or
-  ``"1.3"``.
-
-``JANSSON_VERSION_HEX``
-  A 3-byte hexadecimal representation of the version, e.g.
-  ``0x010201`` for version 1.2.1 and ``0x010300`` for version 1.3.
-  This is useful in numeric comparisions, e.g.::
-
-      #if JANSSON_VERSION_HEX >= 0x010300
-      /* Code specific to version 1.3 and above */
-      #endif
-
-
-Value Representation
-====================
-
-The JSON specification (:rfc:`4627`) defines the following data types:
-*object*, *array*, *string*, *number*, *boolean*, and *null*. JSON
-types are used dynamically; arrays and objects can hold any other data
-type, including themselves. For this reason, Jansson's type system is
-also dynamic in nature. There's one C type to represent all JSON
-values, and this structure knows the type of the JSON value it holds.
-
-.. type:: json_t
-
-  This data structure is used throughout the library to represent all
-  JSON values. It always contains the type of the JSON value it holds
-  and the value's reference count. The rest depends on the type of the
-  value.
-
-Objects of :type:`json_t` are always used through a pointer. There
-are APIs for querying the type, manipulating the reference count, and
-for constructing and manipulating values of different types.
-
-Unless noted otherwise, all API functions return an error value if an
-error occurs. Depending on the function's signature, the error value
-is either *NULL* or -1. Invalid arguments or invalid input are
-apparent sources for errors. Memory allocation and I/O operations may
-also cause errors.
-
-
-Type
-----
-
-The type of a JSON value is queried and tested using the following
-functions:
-
-.. type:: enum json_type
-
-   The type of a JSON value. The following members are defined:
-
-   +--------------------+
-   | ``JSON_OBJECT``    |
-   +--------------------+
-   | ``JSON_ARRAY``     |
-   +--------------------+
-   | ``JSON_STRING``    |
-   +--------------------+
-   | ``JSON_INTEGER``   |
-   +--------------------+
-   | ``JSON_REAL``      |
-   +--------------------+
-   | ``JSON_TRUE``      |
-   +--------------------+
-   | ``JSON_FALSE``     |
-   +--------------------+
-   | ``JSON_NULL``      |
-   +--------------------+
-
-   These correspond to JSON object, array, string, number, boolean and
-   null. A number is represented by either a value of the type
-   ``JSON_INTEGER`` or of the type ``JSON_REAL``. A true boolean value
-   is represented by a value of the type ``JSON_TRUE`` and false by a
-   value of the type ``JSON_FALSE``.
-
-.. function:: int json_typeof(const json_t *json)
-
-   Return the type of the JSON value (a :type:`json_type` cast to
-   :type:`int`). *json* MUST NOT be *NULL*. This function is actually
-   implemented as a macro for speed.
-
-.. function:: json_is_object(const json_t *json)
-               json_is_array(const json_t *json)
-               json_is_string(const json_t *json)
-               json_is_integer(const json_t *json)
-               json_is_real(const json_t *json)
-               json_is_true(const json_t *json)
-               json_is_false(const json_t *json)
-               json_is_null(const json_t *json)
-
-   These functions (actually macros) return true (non-zero) for values
-   of the given type, and false (zero) for values of other types and
-   for *NULL*.
-
-.. function:: json_is_number(const json_t *json)
-
-   Returns true for values of types ``JSON_INTEGER`` and
-   ``JSON_REAL``, and false for other types and for *NULL*.
-
-.. function:: json_is_boolean(const json_t *json)
-
-   Returns true for types ``JSON_TRUE`` and ``JSON_FALSE``, and false
-   for values of other types and for *NULL*.
-
-.. function:: json_boolean_value(const json_t *json)
-
-   Alias of :func:`json_is_true()`, i.e. returns 1 for ``JSON_TRUE``
-   and 0 otherwise.
-
-
-.. _apiref-reference-count:
-
-Reference Count
----------------
-
-The reference count is used to track whether a value is still in use
-or not. When a value is created, it's reference count is set to 1. If
-a reference to a value is kept (e.g. a value is stored somewhere for
-later use), its reference count is incremented, and when the value is
-no longer needed, the reference count is decremented. When the
-reference count drops to zero, there are no references left, and the
-value can be destroyed.
-
-The following functions are used to manipulate the reference count.
-
-.. function:: json_t *json_incref(json_t *json)
-
-   Increment the reference count of *json* if it's not *NULL*.
-   Returns *json*.
-
-.. function:: void json_decref(json_t *json)
-
-   Decrement the reference count of *json*. As soon as a call to
-   :func:`json_decref()` drops the reference count to zero, the value
-   is destroyed and it can no longer be used.
-
-Functions creating new JSON values set the reference count to 1. These
-functions are said to return a **new reference**. Other functions
-returning (existing) JSON values do not normally increase the
-reference count. These functions are said to return a **borrowed
-reference**. So, if the user will hold a reference to a value returned
-as a borrowed reference, he must call :func:`json_incref`. As soon as
-the value is no longer needed, :func:`json_decref` should be called
-to release the reference.
-
-Normally, all functions accepting a JSON value as an argument will
-manage the reference, i.e. increase and decrease the reference count
-as needed. However, some functions **steal** the reference, i.e. they
-have the same result as if the user called :func:`json_decref()` on
-the argument right after calling the function. These functions are
-suffixed with ``_new`` or have ``_new_`` somewhere in their name.
-
-For example, the following code creates a new JSON array and appends
-an integer to it::
-
-  json_t *array, *integer;
-
-  array = json_array();
-  integer = json_integer(42);
-
-  json_array_append(array, integer);
-  json_decref(integer);
-
-Note how the caller has to release the reference to the integer value
-by calling :func:`json_decref()`. By using a reference stealing
-function :func:`json_array_append_new()` instead of
-:func:`json_array_append()`, the code becomes much simpler::
-
-  json_t *array = json_array();
-  json_array_append_new(array, json_integer(42));
-
-In this case, the user doesn't have to explicitly release the
-reference to the integer value, as :func:`json_array_append_new()`
-steals the reference when appending the value to the array.
-
-In the following sections it is clearly documented whether a function
-will return a new or borrowed reference or steal a reference to its
-argument.
-
-
-Circular References
--------------------
-
-A circular reference is created when an object or an array is,
-directly or indirectly, inserted inside itself. The direct case is
-simple::
-
-  json_t *obj = json_object();
-  json_object_set(obj, "foo", obj);
-
-Jansson will refuse to do this, and :func:`json_object_set()` (and
-all the other such functions for objects and arrays) will return with
-an error status. The indirect case is the dangerous one::
-
-  json_t *arr1 = json_array(), *arr2 = json_array();
-  json_array_append(arr1, arr2);
-  json_array_append(arr2, arr1);
-
-In this example, the array ``arr2`` is contained in the array
-``arr1``, and vice versa. Jansson cannot check for this kind of
-indirect circular references without a performance hit, so it's up to
-the user to avoid them.
-
-If a circular reference is created, the memory consumed by the values
-cannot be freed by :func:`json_decref()`. The reference counts never
-drops to zero because the values are keeping the references to each
-other. Moreover, trying to encode the values with any of the encoding
-functions will fail. The encoder detects circular references and
-returns an error status.
-
-
-True, False and Null
-====================
-
-These three values are implemented as singletons, so the returned
-pointers won't change between invocations of these functions.
-
-.. function:: json_t *json_true(void)
-
-   .. refcounting:: new
-
-   Returns the JSON true value.
-
-.. function:: json_t *json_false(void)
-
-   .. refcounting:: new
-
-   Returns the JSON false value.
-
-.. function:: json_t *json_boolean(val)
-
-   .. refcounting:: new
-
-   Returns JSON false if ``val`` is zero, and JSON true otherwise.
-   This is a macro, and equivalent to ``val ? json_true() :
-   json_false()``.
-
-   .. versionadded:: 2.4
-
-
-.. function:: json_t *json_null(void)
-
-   .. refcounting:: new
-
-   Returns the JSON null value.
-
-
-String
-======
-
-Jansson uses UTF-8 as the character encoding. All JSON strings must be
-valid UTF-8 (or ASCII, as it's a subset of UTF-8). Normal null
-terminated C strings are used, so JSON strings may not contain
-embedded null characters. All other Unicode codepoints U+0000 through
-U+10FFFF are allowed, but you must use length-aware functions if you
-wish to embed NUL bytes in strings.
-
-.. function:: json_t *json_string(const char *value)
-
-   .. refcounting:: new
-
-   Returns a new JSON string, or *NULL* on error. *value* must be a
-   valid UTF-8 encoded Unicode string.
-
-.. function:: json_t *json_stringn(const char *value, size_t len)
-
-   .. refcounting:: new
-
-   Like :func:`json_string`, but with explicit length, so *value* may
-   contain null characters or not be null terminated.
-
-.. function:: json_t *json_string_nocheck(const char *value)
-
-   .. refcounting:: new
-
-   Like :func:`json_string`, but doesn't check that *value* is valid
-   UTF-8. Use this function only if you are certain that this really
-   is the case (e.g. you have already checked it by other means).
-
-.. function:: json_t *json_stringn_nocheck(const char *value, size_t len)
-
-   .. refcounting:: new
-
-   Like :func:`json_string_nocheck`, but with explicit length, so
-   *value* may contain null characters or not be null terminated.
-
-.. function:: const char *json_string_value(const json_t *string)
-
-   Returns the associated value of *string* as a null terminated UTF-8
-   encoded string, or *NULL* if *string* is not a JSON string.
-
-   The retuned value is read-only and must not be modified or freed by
-   the user. It is valid as long as *string* exists, i.e. as long as
-   its reference count has not dropped to zero.
-
-.. function:: size_t json_string_length(const json_t *string)
-
-   Returns the length of *string* in its UTF-8 presentation, or zero
-   if *string* is not a JSON string.
-
-.. function:: int json_string_set(const json_t *string, const char *value)
-
-   Sets the associated value of *string* to *value*. *value* must be a
-   valid UTF-8 encoded Unicode string. Returns 0 on success and -1 on
-   error.
-
-.. function:: int json_string_setn(json_t *string, const char *value, size_t len)
-
-   Like :func:`json_string_set`, but with explicit length, so *value*
-   may contain null characters or not be null terminated.
-
-.. function:: int json_string_set_nocheck(const json_t *string, const char *value)
-
-   Like :func:`json_string_set`, but doesn't check that *value* is
-   valid UTF-8. Use this function only if you are certain that this
-   really is the case (e.g. you have already checked it by other
-   means).
-
-.. function:: int json_string_setn_nocheck(json_t *string, const char *value, size_t len)
-
-   Like :func:`json_string_set_nocheck`, but with explicit length,
-   so *value* may contain null characters or not be null terminated.
-
-
-Number
-======
-
-The JSON specification only contains one numeric type, "number". The C
-programming language has distinct types for integer and floating-point
-numbers, so for practical reasons Jansson also has distinct types for
-the two. They are called "integer" and "real", respectively. For more
-information, see :ref:`rfc-conformance`.
-
-.. type:: json_int_t
-
-   This is the C type that is used to store JSON integer values. It
-   represents the widest integer type available on your system. In
-   practice it's just a typedef of ``long long`` if your compiler
-   supports it, otherwise ``long``.
-
-   Usually, you can safely use plain ``int`` in place of
-   ``json_int_t``, and the implicit C integer conversion handles the
-   rest. Only when you know that you need the full 64-bit range, you
-   should use ``json_int_t`` explicitly.
-
-``JSON_INTEGER_IS_LONG_LONG``
-   This is a preprocessor variable that holds the value 1 if
-   :type:`json_int_t` is ``long long``, and 0 if it's ``long``. It
-   can be used as follows::
-
-       #if JSON_INTEGER_IS_LONG_LONG
-       /* Code specific for long long */
-       #else
-       /* Code specific for long */
-       #endif
-
-``JSON_INTEGER_FORMAT``
-   This is a macro that expands to a :func:`printf()` conversion
-   specifier that corresponds to :type:`json_int_t`, without the
-   leading ``%`` sign, i.e. either ``"lld"`` or ``"ld"``. This macro
-   is required because the actual type of :type:`json_int_t` can be
-   either ``long`` or ``long long``, and :func:`printf()` reuiqres
-   different length modifiers for the two.
-
-   Example::
-
-       json_int_t x = 123123123;
-       printf("x is %" JSON_INTEGER_FORMAT "\n", x);
-
-
-.. function:: json_t *json_integer(json_int_t value)
-
-   .. refcounting:: new
-
-   Returns a new JSON integer, or *NULL* on error.
-
-.. function:: json_int_t json_integer_value(const json_t *integer)
-
-   Returns the associated value of *integer*, or 0 if *json* is not a
-   JSON integer.
-
-.. function:: int json_integer_set(const json_t *integer, json_int_t value)
-
-   Sets the associated value of *integer* to *value*. Returns 0 on
-   success and -1 if *integer* is not a JSON integer.
-
-.. function:: json_t *json_real(double value)
-
-   .. refcounting:: new
-
-   Returns a new JSON real, or *NULL* on error.
-
-.. function:: double json_real_value(const json_t *real)
-
-   Returns the associated value of *real*, or 0.0 if *real* is not a
-   JSON real.
-
-.. function:: int json_real_set(const json_t *real, double value)
-
-   Sets the associated value of *real* to *value*. Returns 0 on
-   success and -1 if *real* is not a JSON real.
-
-In addition to the functions above, there's a common query function
-for integers and reals:
-
-.. function:: double json_number_value(const json_t *json)
-
-   Returns the associated value of the JSON integer or JSON real
-   *json*, cast to double regardless of the actual type. If *json* is
-   neither JSON real nor JSON integer, 0.0 is returned.
-
-
-Array
-=====
-
-A JSON array is an ordered collection of other JSON values.
-
-.. function:: json_t *json_array(void)
-
-   .. refcounting:: new
-
-   Returns a new JSON array, or *NULL* on error. Initially, the array
-   is empty.
-
-.. function:: size_t json_array_size(const json_t *array)
-
-   Returns the number of elements in *array*, or 0 if *array* is NULL
-   or not a JSON array.
-
-.. function:: json_t *json_array_get(const json_t *array, size_t index)
-
-   .. refcounting:: borrow
-
-   Returns the element in *array* at position *index*. The valid range
-   for *index* is from 0 to the return value of
-   :func:`json_array_size()` minus 1. If *array* is not a JSON array,
-   if *array* is *NULL*, or if *index* is out of range, *NULL* is
-   returned.
-
-.. function:: int json_array_set(json_t *array, size_t index, json_t *value)
-
-   Replaces the element in *array* at position *index* with *value*.
-   The valid range for *index* is from 0 to the return value of
-   :func:`json_array_size()` minus 1. Returns 0 on success and -1 on
-   error.
-
-.. function:: int json_array_set_new(json_t *array, size_t index, json_t *value)
-
-   Like :func:`json_array_set()` but steals the reference to *value*.
-   This is useful when *value* is newly created and not used after
-   the call.
-
-.. function:: int json_array_append(json_t *array, json_t *value)
-
-   Appends *value* to the end of *array*, growing the size of *array*
-   by 1. Returns 0 on success and -1 on error.
-
-.. function:: int json_array_append_new(json_t *array, json_t *value)
-
-   Like :func:`json_array_append()` but steals the reference to
-   *value*. This is useful when *value* is newly created and not used
-   after the call.
-
-.. function:: int json_array_insert(json_t *array, size_t index, json_t *value)
-
-   Inserts *value* to *array* at position *index*, shifting the
-   elements at *index* and after it one position towards the end of
-   the array. Returns 0 on success and -1 on error.
-
-.. function:: int json_array_insert_new(json_t *array, size_t index, json_t *value)
-
-   Like :func:`json_array_insert()` but steals the reference to
-   *value*. This is useful when *value* is newly created and not used
-   after the call.
-
-.. function:: int json_array_remove(json_t *array, size_t index)
-
-   Removes the element in *array* at position *index*, shifting the
-   elements after *index* one position towards the start of the array.
-   Returns 0 on success and -1 on error. The reference count of the
-   removed value is decremented.
-
-.. function:: int json_array_clear(json_t *array)
-
-   Removes all elements from *array*. Returns 0 on sucess and -1 on
-   error. The reference count of all removed values are decremented.
-
-.. function:: int json_array_extend(json_t *array, json_t *other_array)
-
-   Appends all elements in *other_array* to the end of *array*.
-   Returns 0 on success and -1 on error.
-
-The following macro can be used to iterate through all elements
-in an array.
-
-.. function:: json_array_foreach(array, index, value)
-
-   Iterate over every element of ``array``, running the block
-   of code that follows each time with the proper values set to
-   variables ``index`` and ``value``, of types :type:`size_t` and
-   :type:`json_t *` respectively. Example::
-
-       /* array is a JSON array */
-       size_t index;
-       json_t *value;
-
-       json_array_foreach(array, index, value) {
-           /* block of code that uses index and value */
-       }
-
-   The items are returned in increasing index order.
-
-   This macro expands to an ordinary ``for`` statement upon
-   preprocessing, so its performance is equivalent to that of
-   hand-written code using the array access functions.
-   The main advantage of this macro is that it abstracts
-   away the complexity, and makes for shorter, more
-   concise code.
-
-   .. versionadded:: 2.5
-
-
-Object
-======
-
-A JSON object is a dictionary of key-value pairs, where the key is a
-Unicode string and the value is any JSON value.
-
-Even though NUL bytes are allowed in string values, they are not
-allowed in object keys.
-
-.. function:: json_t *json_object(void)
-
-   .. refcounting:: new
-
-   Returns a new JSON object, or *NULL* on error. Initially, the
-   object is empty.
-
-.. function:: size_t json_object_size(const json_t *object)
-
-   Returns the number of elements in *object*, or 0 if *object* is not
-   a JSON object.
-
-.. function:: json_t *json_object_get(const json_t *object, const char *key)
-
-   .. refcounting:: borrow
-
-   Get a value corresponding to *key* from *object*. Returns *NULL* if
-   *key* is not found and on error.
-
-.. function:: int json_object_set(json_t *object, const char *key, json_t *value)
-
-   Set the value of *key* to *value* in *object*. *key* must be a
-   valid null terminated UTF-8 encoded Unicode string. If there
-   already is a value for *key*, it is replaced by the new value.
-   Returns 0 on success and -1 on error.
-
-.. function:: int json_object_set_nocheck(json_t *object, const char *key, json_t *value)
-
-   Like :func:`json_object_set`, but doesn't check that *key* is
-   valid UTF-8. Use this function only if you are certain that this
-   really is the case (e.g. you have already checked it by other
-   means).
-
-.. function:: int json_object_set_new(json_t *object, const char *key, json_t *value)
-
-   Like :func:`json_object_set()` but steals the reference to
-   *value*. This is useful when *value* is newly created and not used
-   after the call.
-
-.. function:: int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value)
-
-   Like :func:`json_object_set_new`, but doesn't check that *key* is
-   valid UTF-8. Use this function only if you are certain that this
-   really is the case (e.g. you have already checked it by other
-   means).
-
-.. function:: int json_object_del(json_t *object, const char *key)
-
-   Delete *key* from *object* if it exists. Returns 0 on success, or
-   -1 if *key* was not found. The reference count of the removed value
-   is decremented.
-
-.. function:: int json_object_clear(json_t *object)
-
-   Remove all elements from *object*. Returns 0 on success and -1 if
-   *object* is not a JSON object. The reference count of all removed
-   values are decremented.
-
-.. function:: int json_object_update(json_t *object, json_t *other)
-
-   Update *object* with the key-value pairs from *other*, overwriting
-   existing keys. Returns 0 on success or -1 on error.
-
-.. function:: int json_object_update_existing(json_t *object, json_t *other)
-
-   Like :func:`json_object_update()`, but only the values of existing
-   keys are updated. No new keys are created. Returns 0 on success or
-   -1 on error.
-
-   .. versionadded:: 2.3
-
-.. function:: int json_object_update_missing(json_t *object, json_t *other)
-
-   Like :func:`json_object_update()`, but only new keys are created.
-   The value of any existing key is not changed. Returns 0 on success
-   or -1 on error.
-
-   .. versionadded:: 2.3
-
-The following macro can be used to iterate through all key-value pairs
-in an object.
-
-.. function:: json_object_foreach(object, key, value)
-
-   Iterate over every key-value pair of ``object``, running the block
-   of code that follows each time with the proper values set to
-   variables ``key`` and ``value``, of types :type:`const char *` and
-   :type:`json_t *` respectively. Example::
-
-       /* obj is a JSON object */
-       const char *key;
-       json_t *value;
-
-       json_object_foreach(obj, key, value) {
-           /* block of code that uses key and value */
-       }
-
-   The items are not returned in any particular order.
-
-   This macro expands to an ordinary ``for`` statement upon
-   preprocessing, so its performance is equivalent to that of
-   hand-written iteration code using the object iteration protocol
-   (see below). The main advantage of this macro is that it abstracts
-   away the complexity behind iteration, and makes for shorter, more
-   concise code.
-
-   .. versionadded:: 2.3
-
-
-The following functions implement an iteration protocol for objects,
-allowing to iterate through all key-value pairs in an object. The
-items are not returned in any particular order, as this would require
-sorting due to the internal hashtable implementation.
-
-.. function:: void *json_object_iter(json_t *object)
-
-   Returns an opaque iterator which can be used to iterate over all
-   key-value pairs in *object*, or *NULL* if *object* is empty.
-
-.. function:: void *json_object_iter_at(json_t *object, const char *key)
-
-   Like :func:`json_object_iter()`, but returns an iterator to the
-   key-value pair in *object* whose key is equal to *key*, or NULL if
-   *key* is not found in *object*. Iterating forward to the end of
-   *object* only yields all key-value pairs of the object if *key*
-   happens to be the first key in the underlying hash table.
-
-.. function:: void *json_object_iter_next(json_t *object, void *iter)
-
-   Returns an iterator pointing to the next key-value pair in *object*
-   after *iter*, or *NULL* if the whole object has been iterated
-   through.
-
-.. function:: const char *json_object_iter_key(void *iter)
-
-   Extract the associated key from *iter*.
-
-.. function:: json_t *json_object_iter_value(void *iter)
-
-   .. refcounting:: borrow
-
-   Extract the associated value from *iter*.
-
-.. function:: int json_object_iter_set(json_t *object, void *iter, json_t *value)
-
-   Set the value of the key-value pair in *object*, that is pointed to
-   by *iter*, to *value*.
-
-.. function:: int json_object_iter_set_new(json_t *object, void *iter, json_t *value)
-
-   Like :func:`json_object_iter_set()`, but steals the reference to
-   *value*. This is useful when *value* is newly created and not used
-   after the call.
-
-.. function:: void *json_object_key_to_iter(const char *key)
-
-   Like :func:`json_object_iter_at()`, but much faster. Only works for
-   values returned by :func:`json_object_iter_key()`. Using other keys
-   will lead to segfaults. This function is used internally to
-   implement :func:`json_object_foreach`.
-
-   .. versionadded:: 2.3
-
-The iteration protocol can be used for example as follows::
-
-   /* obj is a JSON object */
-   const char *key;
-   json_t *value;
-
-   void *iter = json_object_iter(obj);
-   while(iter)
-   {
-       key = json_object_iter_key(iter);
-       value = json_object_iter_value(iter);
-       /* use key and value ... */
-       iter = json_object_iter_next(obj, iter);
-   }
-
-
-Error reporting
-===============
-
-Jansson uses a single struct type to pass error information to the
-user. See sections :ref:`apiref-decoding`, :ref:`apiref-pack` and
-:ref:`apiref-unpack` for functions that pass error information using
-this struct.
-
-.. type:: json_error_t
-
-   .. member:: char text[]
-
-      The error message (in UTF-8), or an empty string if a message is
-      not available.
-
-   .. member:: char source[]
-
-      Source of the error. This can be (a part of) the file name or a
-      special identifier in angle brackers (e.g. ``<string>``).
-
-   .. member:: int line
-
-      The line number on which the error occurred.
-
-   .. member:: int column
-
-      The column on which the error occurred. Note that this is the
-      *character column*, not the byte column, i.e. a multibyte UTF-8
-      character counts as one column.
-
-   .. member:: size_t position
-
-      The position in bytes from the start of the input. This is
-      useful for debugging Unicode encoding problems.
-
-The normal use of :type:`json_error_t` is to allocate it on the stack,
-and pass a pointer to a function. Example::
-
-   int main() {
-       json_t *json;
-       json_error_t error;
-
-       json = json_load_file("/path/to/file.json", 0, &error);
-       if(!json) {
-           /* the error variable contains error information */
-       }
-       ...
-   }
-
-Also note that if the call succeeded (``json != NULL`` in the above
-example), the contents of ``error`` are generally left unspecified.
-The decoding functions write to the ``position`` member also on
-success. See :ref:`apiref-decoding` for more info.
-
-All functions also accept *NULL* as the :type:`json_error_t` pointer,
-in which case no error information is returned to the caller.
-
-
-Encoding
-========
-
-This sections describes the functions that can be used to encode
-values to JSON. By default, only objects and arrays can be encoded
-directly, since they are the only valid *root* values of a JSON text.
-To encode any JSON value, use the ``JSON_ENCODE_ANY`` flag (see
-below).
-
-By default, the output has no newlines, and spaces are used between
-array and object elements for a readable output. This behavior can be
-altered by using the ``JSON_INDENT`` and ``JSON_COMPACT`` flags
-described below. A newline is never appended to the end of the encoded
-JSON data.
-
-Each function takes a *flags* parameter that controls some aspects of
-how the data is encoded. Its default value is 0. The following macros
-can be ORed together to obtain *flags*.
-
-``JSON_INDENT(n)``
-   Pretty-print the result, using newlines between array and object
-   items, and indenting with *n* spaces. The valid range for *n* is
-   between 0 and 31 (inclusive), other values result in an undefined
-   output. If ``JSON_INDENT`` is not used or *n* is 0, no newlines are
-   inserted between array and object items.
-
-``JSON_COMPACT``
-   This flag enables a compact representation, i.e. sets the separator
-   between array and object items to ``","`` and between object keys
-   and values to ``":"``. Without this flag, the corresponding
-   separators are ``", "`` and ``": "`` for more readable output.
-
-``JSON_ENSURE_ASCII``
-   If this flag is used, the output is guaranteed to consist only of
-   ASCII characters. This is achived by escaping all Unicode
-   characters outside the ASCII range.
-
-``JSON_SORT_KEYS``
-   If this flag is used, all the objects in output are sorted by key.
-   This is useful e.g. if two JSON texts are diffed or visually
-   compared.
-
-``JSON_PRESERVE_ORDER``
-   If this flag is used, object keys in the output are sorted into the
-   same order in which they were first inserted to the object. For
-   example, decoding a JSON text and then encoding with this flag
-   preserves the order of object keys.
-
-``JSON_ENCODE_ANY``
-   Specifying this flag makes it possible to encode any JSON value on
-   its own. Without it, only objects and arrays can be passed as the
-   *root* value to the encoding functions.
-
-   **Note:** Encoding any value may be useful in some scenarios, but
-   it's generally discouraged as it violates strict compatiblity with
-   :rfc:`4627`. If you use this flag, don't expect interoperatibility
-   with other JSON systems.
-
-   .. versionadded:: 2.1
-
-``JSON_ESCAPE_SLASH``
-   Escape the ``/`` characters in strings with ``\/``.
-
-   .. versionadded:: 2.4
-
-The following functions perform the actual JSON encoding. The result
-is in UTF-8.
-
-.. function:: char *json_dumps(const json_t *root, size_t flags)
-
-   Returns the JSON representation of *root* as a string, or *NULL* on
-   error. *flags* is described above. The return value must be freed
-   by the caller using :func:`free()`.
-
-.. function:: int json_dumpf(const json_t *root, FILE *output, size_t flags)
-
-   Write the JSON representation of *root* to the stream *output*.
-   *flags* is described above. Returns 0 on success and -1 on error.
-   If an error occurs, something may have already been written to
-   *output*. In this case, the output is undefined and most likely not
-   valid JSON.
-
-.. function:: int json_dump_file(const json_t *json, const char *path, size_t flags)
-
-   Write the JSON representation of *root* to the file *path*. If
-   *path* already exists, it is overwritten. *flags* is described
-   above. Returns 0 on success and -1 on error.
-
-.. type:: json_dump_callback_t
-
-   A typedef for a function that's called by
-   :func:`json_dump_callback()`::
-
-       typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data);
-
-   *buffer* points to a buffer containing a chunk of output, *size* is
-   the length of the buffer, and *data* is the corresponding
-   :func:`json_dump_callback()` argument passed through.
-
-   On error, the function should return -1 to stop the encoding
-   process. On success, it should return 0.
-
-   .. versionadded:: 2.2
-
-.. function:: int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags)
-
-   Call *callback* repeatedly, passing a chunk of the JSON
-   representation of *root* each time. *flags* is described above.
-   Returns 0 on success and -1 on error.
-
-   .. versionadded:: 2.2
-
-
-.. _apiref-decoding:
-
-Decoding
-========
-
-This sections describes the functions that can be used to decode JSON
-text to the Jansson representation of JSON data. The JSON
-specification requires that a JSON text is either a serialized array
-or object, and this requirement is also enforced with the following
-functions. In other words, the top level value in the JSON text being
-decoded must be either array or object. To decode any JSON value, use
-the ``JSON_DECODE_ANY`` flag (see below).
-
-See :ref:`rfc-conformance` for a discussion on Jansson's conformance
-to the JSON specification. It explains many design decisions that
-affect especially the behavior of the decoder.
-
-Each function takes a *flags* parameter that can be used to control
-the behavior of the decoder. Its default value is 0. The following
-macros can be ORed together to obtain *flags*.
-
-``JSON_REJECT_DUPLICATES``
-   Issue a decoding error if any JSON object in the input text
-   contains duplicate keys. Without this flag, the value of the last
-   occurence of each key ends up in the result. Key equivalence is
-   checked byte-by-byte, without special Unicode comparison
-   algorithms.
-
-   .. versionadded:: 2.1
-
-``JSON_DECODE_ANY``
-   By default, the decoder expects an array or object as the input.
-   With this flag enabled, the decoder accepts any valid JSON value.
-
-   **Note:** Decoding any value may be useful in some scenarios, but
-   it's generally discouraged as it violates strict compatiblity with
-   :rfc:`4627`. If you use this flag, don't expect interoperatibility
-   with other JSON systems.
-
-   .. versionadded:: 2.3
-
-``JSON_DISABLE_EOF_CHECK``
-   By default, the decoder expects that its whole input constitutes a
-   valid JSON text, and issues an error if there's extra data after
-   the otherwise valid JSON input. With this flag enabled, the decoder
-   stops after decoding a valid JSON array or object, and thus allows
-   extra data after the JSON text.
-
-   Normally, reading will stop when the last ``]`` or ``}`` in the
-   JSON input is encountered. If both ``JSON_DISABLE_EOF_CHECK`` and
-   ``JSON_DECODE_ANY`` flags are used, the decoder may read one extra
-   UTF-8 code unit (up to 4 bytes of input). For example, decoding
-   ``4true`` correctly decodes the integer 4, but also reads the
-   ``t``. For this reason, if reading multiple consecutive values that
-   are not arrays or objects, they should be separated by at least one
-   whitespace character.
-
-   .. versionadded:: 2.1
-
-``JSON_DECODE_INT_AS_REAL``
-   JSON defines only one number type. Jansson distinguishes between
-   ints and reals. For more information see :ref:`real-vs-integer`.
-   With this flag enabled the decoder interprets all numbers as real
-   values. Integers that do not have an exact double representation
-   will silently result in a loss of precision. Integers that cause
-   a double overflow will cause an error.
-
-   .. versionadded:: 2.5
-
-``JSON_ALLOW_NUL``
-   Allow ``\u0000`` escape inside string values. This is a safety
-   measure; If you know your input can contain NUL bytes, use this
-   flag. If you don't use this flag, you don't have to worry about NUL
-   bytes inside strings unless you explicitly create themselves by
-   using e.g. :func:`json_stringn()` or ``s#`` format specifier for
-   :func:`json_pack()`.
-
-   Object keys cannot have embedded NUL bytes even if this flag is
-   used.
-
-   .. versionadded:: 2.6
-
-Each function also takes an optional :type:`json_error_t` parameter
-that is filled with error information if decoding fails. It's also
-updated on success; the number of bytes of input read is written to
-its ``position`` field. This is especially useful when using
-``JSON_DISABLE_EOF_CHECK`` to read multiple consecutive JSON texts.
-
-.. versionadded:: 2.3
-   Number of bytes of input read is written to the ``position`` field
-   of the :type:`json_error_t` structure.
-
-If no error or position information is needed, you can pass *NULL*.
-
-The following functions perform the actual JSON decoding.
-
-.. function:: json_t *json_loads(const char *input, size_t flags, json_error_t *error)
-
-   .. refcounting:: new
-
-   Decodes the JSON string *input* and returns the array or object it
-   contains, or *NULL* on error, in which case *error* is filled with
-   information about the error. *flags* is described above.
-
-.. function:: json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error)
-
-   .. refcounting:: new
-
-   Decodes the JSON string *buffer*, whose length is *buflen*, and
-   returns the array or object it contains, or *NULL* on error, in
-   which case *error* is filled with information about the error. This
-   is similar to :func:`json_loads()` except that the string doesn't
-   need to be null-terminated. *flags* is described above.
-
-   .. versionadded:: 2.1
-
-.. function:: json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
-
-   .. refcounting:: new
-
-   Decodes the JSON text in stream *input* and returns the array or
-   object it contains, or *NULL* on error, in which case *error* is
-   filled with information about the error. *flags* is described
-   above.
-
-   This function will start reading the input from whatever position
-   the input file was, without attempting to seek first. If an error
-   occurs, the file position will be left indeterminate. On success,
-   the file position will be at EOF, unless ``JSON_DISABLE_EOF_CHECK``
-   flag was used. In this case, the file position will be at the first
-   character after the last ``]`` or ``}`` in the JSON input. This
-   allows calling :func:`json_loadf()` on the same ``FILE`` object
-   multiple times, if the input consists of consecutive JSON texts,
-   possibly separated by whitespace.
-
-.. function:: json_t *json_load_file(const char *path, size_t flags, json_error_t *error)
-
-   .. refcounting:: new
-
-   Decodes the JSON text in file *path* and returns the array or
-   object it contains, or *NULL* on error, in which case *error* is
-   filled with information about the error. *flags* is described
-   above.
-
-.. type:: json_load_callback_t
-
-   A typedef for a function that's called by
-   :func:`json_load_callback()` to read a chunk of input data::
-
-       typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data);
-
-   *buffer* points to a buffer of *buflen* bytes, and *data* is the
-   corresponding :func:`json_load_callback()` argument passed through.
-
-   On success, the function should return the number of bytes read; a
-   returned value of 0 indicates that no data was read and that the
-   end of file has been reached. On error, the function should return
-   ``(size_t)-1`` to abort the decoding process.
-
-   .. versionadded:: 2.4
-
-.. function:: json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error)
-
-   .. refcounting:: new
-
-   Decodes the JSON text produced by repeated calls to *callback*, and
-   returns the array or object it contains, or *NULL* on error, in
-   which case *error* is filled with information about the error.
-   *data* is passed through to *callback* on each call. *flags* is
-   described above.
-
-   .. versionadded:: 2.4
-
-
-.. _apiref-pack:
-
-Building Values
-===============
-
-This section describes functions that help to create, or *pack*,
-complex JSON values, especially nested objects and arrays. Value
-building is based on a *format string* that is used to tell the
-functions about the expected arguments.
-
-For example, the format string ``"i"`` specifies a single integer
-value, while the format string ``"[ssb]"`` or the equivalent ``"[s, s,
-b]"`` specifies an array value with two strings and a boolean as its
-items::
-
-    /* Create the JSON integer 42 */
-    json_pack("i", 42);
-
-    /* Create the JSON array ["foo", "bar", true] */
-    json_pack("[ssb]", "foo", "bar", 1);
-
-Here's the full list of format specifiers. The type in parentheses
-denotes the resulting JSON type, and the type in brackets (if any)
-denotes the C type that is expected as the corresponding argument or
-arguments.
-
-``s`` (string) [const char \*]
-    Convert a NULL terminated UTF-8 string to a JSON string.
-
-``s#`` (string) [const char \*, int]
-    Convert a UTF-8 buffer of a given length to a JSON string.
-
-    .. versionadded:: 2.5
-
-``s%`` (string) [const char \*, size_t]
-    Like ``s#`` but the length argument is of type :type:`size_t`.
-
-    .. versionadded:: 2.6
-
-``+`` [const char \*]
-    Like ``s``, but concatenate to the previous string. Only valid
-    after ``s``, ``s#``, ``+`` or ``+#``.
-
-    .. versionadded:: 2.5
-
-``+#`` [const char \*, int]
-    Like ``s#``, but concatenate to the previous string. Only valid
-    after ``s``, ``s#``, ``+`` or ``+#``.
-
-    .. versionadded:: 2.5
-
-``+%`` (string) [const char \*, size_t]
-    Like ``+#`` but the length argument is of type :type:`size_t`.
-
-    .. versionadded:: 2.6
-
-``n`` (null)
-    Output a JSON null value. No argument is consumed.
-
-``b`` (boolean) [int]
-    Convert a C :type:`int` to JSON boolean value. Zero is converted
-    to ``false`` and non-zero to ``true``.
-
-``i`` (integer) [int]
-    Convert a C :type:`int` to JSON integer.
-
-``I`` (integer) [json_int_t]
-    Convert a C :type:`json_int_t` to JSON integer.
-
-``f`` (real) [double]
-    Convert a C :type:`double` to JSON real.
-
-``o`` (any value) [json_t \*]
-    Output any given JSON value as-is. If the value is added to an
-    array or object, the reference to the value passed to ``o`` is
-    stolen by the container.
-
-``O`` (any value) [json_t \*]
-    Like ``o``, but the argument's reference count is incremented.
-    This is useful if you pack into an array or object and want to
-    keep the reference for the JSON value consumed by ``O`` to
-    yourself.
-
-``[fmt]`` (array)
-    Build an array with contents from the inner format string. ``fmt``
-    may contain objects and arrays, i.e. recursive value building is
-    supported.
-
-``{fmt}`` (object)
-    Build an object with contents from the inner format string
-    ``fmt``. The first, third, etc. format specifier represent a key,
-    and must be a string (see ``s``, ``s#``, ``+`` and ``+#`` above),
-    as object keys are always strings. The second, fourth, etc. format
-    specifier represent a value. Any value may be an object or array,
-    i.e. recursive value building is supported.
-
-Whitespace, ``:`` and ``,`` are ignored.
-
-The following functions compose the value building API:
-
-.. function:: json_t *json_pack(const char *fmt, ...)
-
-   .. refcounting:: new
-
-   Build a new JSON value according to the format string *fmt*. For
-   each format specifier (except for ``{}[]n``), one or more arguments
-   are consumed and used to build the corresponding value. Returns
-   *NULL* on error.
-
-.. function:: json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...)
-              json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap)
-
-   .. refcounting:: new
-
-   Like :func:`json_pack()`, but an in the case of an error, an error
-   message is written to *error*, if it's not *NULL*. The *flags*
-   parameter is currently unused and should be set to 0.
-
-   As only the errors in format string (and out-of-memory errors) can
-   be caught by the packer, these two functions are most likely only
-   useful for debugging format strings.
-
-More examples::
-
-  /* Build an empty JSON object */
-  json_pack("{}");
-
-  /* Build the JSON object {"foo": 42, "bar": 7} */
-  json_pack("{sisi}", "foo", 42, "bar", 7);
-
-  /* Like above, ':', ',' and whitespace are ignored */
-  json_pack("{s:i, s:i}", "foo", 42, "bar", 7);
-
-  /* Build the JSON array [[1, 2], {"cool": true}] */
-  json_pack("[[i,i],{s:b}]", 1, 2, "cool", 1);
-
-  /* Build a string from a non-NUL terminated buffer */
-  char buffer[4] = {'t', 'e', 's', 't'};
-  json_pack("s#", buffer, 4);
-
-  /* Concatentate strings together to build the JSON string "foobarbaz" */
-  json_pack("s++", "foo", "bar", "baz");
-
-
-.. _apiref-unpack:
-
-Parsing and Validating Values
-=============================
-
-This section describes functions that help to validate complex values
-and extract, or *unpack*, data from them. Like :ref:`building values
-<apiref-pack>`, this is also based on format strings.
-
-While a JSON value is unpacked, the type specified in the format
-string is checked to match that of the JSON value. This is the
-validation part of the process. In addition to this, the unpacking
-functions can also check that all items of arrays and objects are
-unpacked. This check be enabled with the format specifier ``!`` or by
-using the flag ``JSON_STRICT``. See below for details.
-
-Here's the full list of format specifiers. The type in parentheses
-denotes the JSON type, and the type in brackets (if any) denotes the C
-type whose address should be passed.
-
-``s`` (string) [const char \*]
-    Convert a JSON string to a pointer to a NULL terminated UTF-8
-    string. The resulting string is extracted by using
-    :func:`json_string_value()` internally, so it exists as long as
-    there are still references to the corresponding JSON string.
-
-``s%`` (string) [const char \*, size_t *]
-    Convert a JSON string to a pointer to a NULL terminated UTF-8
-    string and its length.
-
-    .. versionadded:: 2.6
-
-``n`` (null)
-    Expect a JSON null value. Nothing is extracted.
-
-``b`` (boolean) [int]
-    Convert a JSON boolean value to a C :type:`int`, so that ``true``
-    is converted to 1 and ``false`` to 0.
-
-``i`` (integer) [int]
-    Convert a JSON integer to C :type:`int`.
-
-``I`` (integer) [json_int_t]
-    Convert a JSON integer to C :type:`json_int_t`.
-
-``f`` (real) [double]
-    Convert a JSON real to C :type:`double`.
-
-``F`` (integer or real) [double]
-    Convert a JSON number (integer or real) to C :type:`double`.
-
-``o`` (any value) [json_t \*]
-    Store a JSON value with no conversion to a :type:`json_t` pointer.
-
-``O`` (any value) [json_t \*]
-    Like ``O``, but the JSON value's reference count is incremented.
-
-``[fmt]`` (array)
-    Convert each item in the JSON array according to the inner format
-    string. ``fmt`` may contain objects and arrays, i.e. recursive
-    value extraction is supporetd.
-
-``{fmt}`` (object)
-    Convert each item in the JSON object according to the inner format
-    string ``fmt``. The first, third, etc. format specifier represent
-    a key, and must be ``s``. The corresponding argument to unpack
-    functions is read as the object key. The second fourth, etc.
-    format specifier represent a value and is written to the address
-    given as the corresponding argument. **Note** that every other
-    argument is read from and every other is written to.
-
-    ``fmt`` may contain objects and arrays as values, i.e. recursive
-    value extraction is supporetd.
-
-    .. versionadded:: 2.3
-       Any ``s`` representing a key may be suffixed with a ``?`` to
-       make the key optional. If the key is not found, nothing is
-       extracted. See below for an example.
-
-``!``
-    This special format specifier is used to enable the check that
-    all object and array items are accessed, on a per-value basis. It
-    must appear inside an array or object as the last format specifier
-    before the closing bracket or brace. To enable the check globally,
-    use the ``JSON_STRICT`` unpacking flag.
-
-``*``
-    This special format specifier is the opposite of ``!``. If the
-    ``JSON_STRICT`` flag is used, ``*`` can be used to disable the
-    strict check on a per-value basis. It must appear inside an array
-    or object as the last format specifier before the closing bracket
-    or brace.
-
-Whitespace, ``:`` and ``,`` are ignored.
-
-The following functions compose the parsing and validation API:
-
-.. function:: int json_unpack(json_t *root, const char *fmt, ...)
-
-   Validate and unpack the JSON value *root* according to the format
-   string *fmt*. Returns 0 on success and -1 on failure.
-
-.. function:: int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...)
-              int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, va_list ap)
-
-   Validate and unpack the JSON value *root* according to the format
-   string *fmt*. If an error occurs and *error* is not *NULL*, write
-   error information to *error*. *flags* can be used to control the
-   behaviour of the unpacker, see below for the flags. Returns 0 on
-   success and -1 on failure.
-
-.. note::
-
-   The first argument of all unpack functions is ``json_t *root``
-   instead of ``const json_t *root``, because the use of ``O`` format
-   specifier causes the reference count of ``root``, or some value
-   reachable from ``root``, to be increased. Furthermore, the ``o``
-   format specifier may be used to extract a value as-is, which allows
-   modifying the structure or contents of a value reachable from
-   ``root``.
-
-   If the ``O`` and ``o`` format specifiers are not used, it's
-   perfectly safe to cast a ``const json_t *`` variable to plain
-   ``json_t *`` when used with these functions.
-
-The following unpacking flags are available:
-
-``JSON_STRICT``
-    Enable the extra validation step checking that all object and
-    array items are unpacked. This is equivalent to appending the
-    format specifier ``!`` to the end of every array and object in the
-    format string.
-
-``JSON_VALIDATE_ONLY``
-    Don't extract any data, just validate the JSON value against the
-    given format string. Note that object keys must still be specified
-    after the format string.
-
-Examples::
-
-    /* root is the JSON integer 42 */
-    int myint;
-    json_unpack(root, "i", &myint);
-    assert(myint == 42);
-
-    /* root is the JSON object {"foo": "bar", "quux": true} */
-    const char *str;
-    int boolean;
-    json_unpack(root, "{s:s, s:b}", "foo", &str, "quux", &boolean);
-    assert(strcmp(str, "bar") == 0 && boolean == 1);
-
-    /* root is the JSON array [[1, 2], {"baz": null} */
-    json_error_t error;
-    json_unpack_ex(root, &error, JSON_VALIDATE_ONLY, "[[i,i], {s:n}]", "baz");
-    /* returns 0 for validation success, nothing is extracted */
-
-    /* root is the JSON array [1, 2, 3, 4, 5] */
-    int myint1, myint2;
-    json_unpack(root, "[ii!]", &myint1, &myint2);
-    /* returns -1 for failed validation */
-
-    /* root is an empty JSON object */
-    int myint = 0, myint2 = 0;
-    json_unpack(root, "{s?i, s?[ii]}",
-                "foo", &myint1,
-                "bar", &myint2, &myint3);
-    /* myint1, myint2 or myint3 is no touched as "foo" and "bar" don't exist */
-
-
-Equality
-========
-
-Testing for equality of two JSON values cannot, in general, be
-achieved using the ``==`` operator. Equality in the terms of the
-``==`` operator states that the two :type:`json_t` pointers point to
-exactly the same JSON value. However, two JSON values can be equal not
-only if they are exactly the same value, but also if they have equal
-"contents":
-
-* Two integer or real values are equal if their contained numeric
-  values are equal. An integer value is never equal to a real value,
-  though.
-
-* Two strings are equal if their contained UTF-8 strings are equal,
-  byte by byte. Unicode comparison algorithms are not implemented.
-
-* Two arrays are equal if they have the same number of elements and
-  each element in the first array is equal to the corresponding
-  element in the second array.
-
-* Two objects are equal if they have exactly the same keys and the
-  value for each key in the first object is equal to the value of the
-  corresponding key in the second object.
-
-* Two true, false or null values have no "contents", so they are equal
-  if their types are equal. (Because these values are singletons,
-  their equality can actually be tested with ``==``.)
-
-The following function can be used to test whether two JSON values are
-equal.
-
-.. function:: int json_equal(json_t *value1, json_t *value2)
-
-   Returns 1 if *value1* and *value2* are equal, as defined above.
-   Returns 0 if they are inequal or one or both of the pointers are
-   *NULL*.
-
-
-Copying
-=======
-
-Because of reference counting, passing JSON values around doesn't
-require copying them. But sometimes a fresh copy of a JSON value is
-needed. For example, if you need to modify an array, but still want to
-use the original afterwards, you should take a copy of it first.
-
-Jansson supports two kinds of copying: shallow and deep. There is a
-difference between these methods only for arrays and objects. Shallow
-copying only copies the first level value (array or object) and uses
-the same child values in the copied value. Deep copying makes a fresh
-copy of the child values, too. Moreover, all the child values are deep
-copied in a recursive fashion.
-
-.. function:: json_t *json_copy(json_t *value)
-
-   .. refcounting:: new
-
-   Returns a shallow copy of *value*, or *NULL* on error.
-
-.. function:: json_t *json_deep_copy(const json_t *value)
-
-   .. refcounting:: new
-
-   Returns a deep copy of *value*, or *NULL* on error.
-
-
-.. _apiref-custom-memory-allocation:
-
-Custom Memory Allocation
-========================
-
-By default, Jansson uses :func:`malloc()` and :func:`free()` for
-memory allocation. These functions can be overridden if custom
-behavior is needed.
-
-.. type:: json_malloc_t
-
-   A typedef for a function pointer with :func:`malloc()`'s
-   signature::
-
-       typedef void *(*json_malloc_t)(size_t);
-
-.. type:: json_free_t
-
-   A typedef for a function pointer with :func:`free()`'s
-   signature::
-
-       typedef void (*json_free_t)(void *);
-
-.. function:: void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn)
-
-   Use *malloc_fn* instead of :func:`malloc()` and *free_fn* instead
-   of :func:`free()`. This function has to be called before any other
-   Jansson's API functions to ensure that all memory operations use
-   the same functions.
-
-**Examples:**
-
-Circumvent problems with different CRT heaps on Windows by using
-application's :func:`malloc()` and :func:`free()`::
-
-    json_set_alloc_funcs(malloc, free);
-
-Use the `Boehm's conservative garbage collector`_ for memory
-operations::
-
-    json_set_alloc_funcs(GC_malloc, GC_free);
-
-.. _Boehm's conservative garbage collector: http://www.hpl.hp.com/personal/Hans_Boehm/gc/
-
-Allow storing sensitive data (e.g. passwords or encryption keys) in
-JSON structures by zeroing all memory when freed::
-
-    static void *secure_malloc(size_t size)
-    {
-        /* Store the memory area size in the beginning of the block */
-        void *ptr = malloc(size + 8);
-        *((size_t *)ptr) = size;
-        return ptr + 8;
-    }
-
-    static void secure_free(void *ptr)
-    {
-        size_t size;
-
-        ptr -= 8;
-        size = *((size_t *)ptr);
-
-        guaranteed_memset(ptr, 0, size + 8);
-        free(ptr);
-    }
-
-    int main()
-    {
-        json_set_alloc_funcs(secure_malloc, secure_free);
-        /* ... */
-    }
-
-For more information about the issues of storing sensitive data in
-memory, see
-http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/protect-secrets.html.
-The page also explains the :func:`guaranteed_memset()` function used
-in the example and gives a sample implementation for it.
diff --git a/deps/jansson/doc/changes.rst b/deps/jansson/doc/changes.rst
deleted file mode 100644
index ea56843..0000000
--- a/deps/jansson/doc/changes.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-******************
-Changes in Jansson
-******************
-
-.. include:: ../CHANGES
diff --git a/deps/jansson/doc/conf.py b/deps/jansson/doc/conf.py
deleted file mode 100644
index ddf5833..0000000
--- a/deps/jansson/doc/conf.py
+++ /dev/null
@@ -1,217 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Jansson documentation build configuration file, created by
-# sphinx-quickstart on Sun Sep  5 21:47:20 2010.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys, os
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-sys.path.insert(0, os.path.abspath('ext'))
-
-# -- General configuration -----------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['refcounting']
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'Jansson'
-copyright = u'2009-2013, Petri Lehtinen'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = '2.5'
-# The full version, including alpha/beta/rc tags.
-release = version
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-default_role = 'c:func'
-primary_domain = 'c'
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages.  See the documentation for
-# a list of builtin themes.
-#html_theme = 'default'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-#html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'Janssondoc'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-# The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-#latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
-  ('index', 'Jansson.tex', u'Jansson Documentation',
-   u'Petri Lehtinen', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Additional stuff for the LaTeX preamble.
-#latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output --------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
-    ('index', 'jansson', u'Jansson Documentation',
-     [u'Petri Lehtinen'], 1)
-]
diff --git a/deps/jansson/doc/conformance.rst b/deps/jansson/doc/conformance.rst
deleted file mode 100644
index de3947d..0000000
--- a/deps/jansson/doc/conformance.rst
+++ /dev/null
@@ -1,110 +0,0 @@
-.. _rfc-conformance:
-
-***************
-RFC Conformance
-***************
-
-JSON is specified in :rfc:`4627`, *"The application/json Media Type
-for JavaScript Object Notation (JSON)"*.
-
-Character Encoding
-==================
-
-Jansson only supports UTF-8 encoded JSON texts. It does not support or
-auto-detect any of the other encodings mentioned in the RFC, namely
-UTF-16LE, UTF-16BE, UTF-32LE or UTF-32BE. Pure ASCII is supported, as
-it's a subset of UTF-8.
-
-Strings
-=======
-
-JSON strings are mapped to C-style null-terminated character arrays,
-and UTF-8 encoding is used internally.
-
-All Unicode codepoints U+0000 through U+10FFFF are allowed in string
-values. However, U+0000 is not allowed in object keys because of API
-restrictions.
-
-Unicode normalization or any other transformation is never performed
-on any strings (string values or object keys). When checking for
-equivalence of strings or object keys, the comparison is performed
-byte by byte between the original UTF-8 representations of the
-strings.
-
-Numbers
-=======
-
-.. _real-vs-integer:
-
-Real vs. Integer
-----------------
-
-JSON makes no distinction between real and integer numbers; Jansson
-does. Real numbers are mapped to the ``double`` type and integers to
-the ``json_int_t`` type, which is a typedef of ``long long`` or
-``long``, depending on whether ``long long`` is supported by your
-compiler or not.
-
-A JSON number is considered to be a real number if its lexical
-representation includes one of ``e``, ``E``, or ``.``; regardless if
-its actual numeric value is a true integer (e.g., all of ``1E6``,
-``3.0``, ``400E-2``, and ``3.14E3`` are mathematical integers, but
-will be treated as real values). With the ``JSON_DECODE_INT_AS_REAL``
-decoder flag set all numbers are interpreted as real.
-
-All other JSON numbers are considered integers.
-
-When encoding to JSON, real values are always represented
-with a fractional part; e.g., the ``double`` value 3.0 will be
-represented in JSON as ``3.0``, not ``3``.
-
-Overflow, Underflow & Precision
--------------------------------
-
-Real numbers whose absolute values are too small to be represented in
-a C ``double`` will be silently estimated with 0.0. Thus, depending on
-platform, JSON numbers very close to zero such as 1E-999 may result in
-0.0.
-
-Real numbers whose absolute values are too large to be represented in
-a C ``double`` will result in an overflow error (a JSON decoding
-error). Thus, depending on platform, JSON numbers like 1E+999 or
--1E+999 may result in a parsing error.
-
-Likewise, integer numbers whose absolute values are too large to be
-represented in the ``json_int_t`` type (see above) will result in an
-overflow error (a JSON decoding error). Thus, depending on platform,
-JSON numbers like 1000000000000000 may result in parsing error.
-
-Parsing JSON real numbers may result in a loss of precision. As long
-as overflow does not occur (i.e. a total loss of precision), the
-rounded approximate value is silently used. Thus the JSON number
-1.000000000000000005 may, depending on platform, result in the
-``double`` value 1.0.
-
-Signed zeros
-------------
-
-JSON makes no statement about what a number means; however Javascript
-(ECMAscript) does state that +0.0 and -0.0 must be treated as being
-distinct values, i.e. -0.0 |not-equal| 0.0. Jansson relies on the
-underlying floating point library in the C environment in which it is
-compiled. Therefore it is platform-dependent whether 0.0 and -0.0 will
-be distinct values. Most platforms that use the IEEE 754
-floating-point standard will support signed zeros.
-
-Note that this only applies to floating-point; neither JSON, C, or
-IEEE support the concept of signed integer zeros.
-
-.. |not-equal| unicode:: U+2260
-
-Types
------
-
-No support is provided in Jansson for any C numeric types other than
-``json_int_t`` and ``double``. This excludes things such as unsigned
-types, ``long double``, etc. Obviously, shorter types like ``short``,
-``int``, ``long`` (if ``json_int_t`` is ``long long``) and ``float``
-are implicitly handled via the ordinary C type coercion rules (subject
-to overflow semantics). Also, no support or hooks are provided for any
-supplemental "bignum" type add-on packages.
diff --git a/deps/jansson/doc/ext/refcounting.py b/deps/jansson/doc/ext/refcounting.py
deleted file mode 100644
index 4af3084..0000000
--- a/deps/jansson/doc/ext/refcounting.py
+++ /dev/null
@@ -1,59 +0,0 @@
-"""
-    refcounting
-    ~~~~~~~~~~~
-
-    Reference count annotations for C API functions. Has the same
-    result as the sphinx.ext.refcounting extension but works for all
-    functions regardless of the signature, and the reference counting
-    information is written inline with the documentation instead of a
-    separate file.
-
-    Adds a new directive "refcounting". The directive has no content
-    and one required positional parameter:: "new" or "borrow".
-
-    Example:
-
-    .. cfunction:: json_t *json_object(void)
-
-       .. refcounting:: new
-
-       <description of the json_object function>
-
-    :copyright: Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
-    :license: MIT, see LICENSE for details.
-"""
-
-from docutils import nodes
-
-class refcounting(nodes.emphasis): pass
-
-def visit(self, node):
-    self.visit_emphasis(node)
-
-def depart(self, node):
-    self.depart_emphasis(node)
-
-def html_visit(self, node):
-    self.body.append(self.starttag(node, 'em', '', CLASS='refcount'))
-
-def html_depart(self, node):
-    self.body.append('</em>')
-
-
-def refcounting_directive(name, arguments, options, content, lineno,
-                   content_offset, block_text, state, state_machine):
-    if arguments[0] == 'borrow':
-        text = 'Return value: Borrowed reference.'
-    elif arguments[0] == 'new':
-        text = 'Return value: New reference.'
-    else:
-        raise Error('Valid arguments: new, borrow')
-
-    return [refcounting(text, text)]
-
-def setup(app):
-    app.add_node(refcounting,
-                 html=(html_visit, html_depart),
-                 latex=(visit, depart),
-                 text=(visit, depart))
-    app.add_directive('refcounting', refcounting_directive, 0, (1, 0, 0))
diff --git a/deps/jansson/doc/gettingstarted.rst b/deps/jansson/doc/gettingstarted.rst
deleted file mode 100644
index 4e59e51..0000000
--- a/deps/jansson/doc/gettingstarted.rst
+++ /dev/null
@@ -1,237 +0,0 @@
-***************
-Getting Started
-***************
-
-.. highlight:: c
-
-Compiling and Installing Jansson
-================================
-
-The Jansson source is available at
-http://www.digip.org/jansson/releases/.
-
-Unix-like systems (including MinGW)
------------------------------------
-
-Unpack the source tarball and change to the source directory:
-
-.. parsed-literal::
-
-    bunzip2 -c jansson-|release|.tar.bz2 | tar xf -
-    cd jansson-|release|
-
-The source uses GNU Autotools (autoconf_, automake_, libtool_), so
-compiling and installing is extremely simple::
-
-    ./configure
-    make
-    make check
-    make install
-
-To change the destination directory (``/usr/local`` by default), use
-the ``--prefix=DIR`` argument to ``./configure``. See ``./configure
---help`` for the list of all possible installation options. (There are
-no options to customize the resulting Jansson binary.)
-
-The command ``make check`` runs the test suite distributed with
-Jansson. This step is not strictly necessary, but it may find possible
-problems that Jansson has on your platform. If any problems are found,
-please report them.
-
-If you obtained the source from a Git repository (or any other source
-control system), there's no ``./configure`` script as it's not kept in
-version control. To create the script, the build system needs to be
-bootstrapped. There are many ways to do this, but the easiest one is
-to use ``autoreconf``::
-
-    autoreconf -vi
-
-This command creates the ``./configure`` script, which can then be
-used as described above.
-
-.. _autoconf: http://www.gnu.org/software/autoconf/
-.. _automake: http://www.gnu.org/software/automake/
-.. _libtool: http://www.gnu.org/software/libtool/
-
-
-.. _build-cmake:
-
-CMake (various platforms, including Windows)
---------------------------------------------
-
-Jansson can be built using CMake_. Create a build directory for an
-out-of-tree build, change to that directory, and run ``cmake`` (or ``ccmake``,
-``cmake-gui``, or similar) to configure the project.
-
-See the examples below for more detailed information.
-
-.. note:: In the below examples ``..`` is used as an argument for ``cmake``.
-          This is simply the path to the jansson project root directory.
-          In the example it is assumed you've created a sub-directory ``build``
-          and are using that. You could use any path you want.
-
-.. _build-cmake-unix:
-
-Unix (Make files)
-^^^^^^^^^^^^^^^^^
-Generating make files on unix:
-
-.. parsed-literal::
-
-    bunzip2 -c jansson-|release|.tar.bz2 | tar xf -
-    cd jansson-|release|
-
-    mkdir build
-    cd build
-    cmake .. # or `ccmake ..` for a GUI.
-
-Then to build::
-    
-    make
-    make check
-    make install
-
-Windows (Visual Studio)
-^^^^^^^^^^^^^^^^^^^^^^^
-Creating Visual Studio project files from the command line:
-
-.. parsed-literal::
-
-    <unpack>
-    cd jansson-|release|
-
-    md build
-    cd build
-    cmake -G "Visual Studio 10" ..
-
-You will now have a *Visual Studio Solution* in your build directory.
-To run the unit tests build the ``RUN_TESTS`` project.
-
-If you prefer a GUI the ``cmake`` line in the above example can 
-be replaced with::
-
-    cmake-gui ..
-
-For command line help (including a list of available generators)
-for CMake_ simply run::
-
-    cmake
-
-To list available CMake_ settings (and what they are currently set to) 
-for the project, run::
-
-    cmake -LH ..
-
-Mac OSX (Xcode)
-^^^^^^^^^^^^^^^
-If you prefer using Xcode instead of make files on OSX,
-do the following. (Use the same steps as 
-for :ref:`Unix <build-cmake-unix>`)::
-
-    ...
-    cmake -G "Xcode" ..
-
-Additional CMake settings
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Shared library
-""""""""""""""
-By default the CMake_ project will generate build files for building the
-static library. To build the shared version use::
-
-    ...
-    cmake -DBUILD_SHARED=1 ..
-
-Changing install directory (same as autoconf --prefix)
-""""""""""""""""""""""""""""""""""""""""""""""""""""""
-Just as with the autoconf_ project you can change the destination directory
-for ``make install``. The equivalent for autoconfs ``./configure --prefix`` 
-in CMake_ is::
-
-    ...
-    cmake -DCMAKE_INSTALL_PREFIX:PATH=/some/other/path ..
-    make install
-
-.. _CMake: http://www.cmake.org
-
-Android
--------
-
-Jansson can be built for Android platforms. Android.mk is in the
-source root directory. The configuration header file is located in the
-``android`` directory in the source distribution.
-
-
-Windows
--------
-
-**This method is deprecated**. Using :ref:`CMake <build-cmake>` is now
-preferred.
-
-Jansson can be built with Visual Studio 2010 (and probably newer
-versions, too). The solution and project files are in the
-``win32/vs2010/`` directory in the source distribution.
-
-
-Other Systems
--------------
-
-On non Unix-like systems, you may be unable to run the ``./configure``
-script. In this case, follow these steps. All the files mentioned can
-be found in the ``src/`` directory.
-
-1. Create ``jansson_config.h`` (which has some platform-specific
-   parameters that are normally filled in by the ``./configure``
-   script). Edit ``jansson_config.h.in``, replacing all ``@variable@``
-   placeholders, and rename the file to ``jansson_config.h``.
-
-2. Make ``jansson.h`` and ``jansson_config.h`` available to the
-   compiler, so that they can be found when compiling programs that
-   use Jansson.
-
-3. Compile all the ``.c`` files (in the ``src/`` directory) into a
-   library file. Make the library available to the compiler, as in
-   step 2.
-
-
-Building the Documentation
---------------------------
-
-(This subsection describes how to build the HTML documentation you are
-currently reading, so it can be safely skipped.)
-
-Documentation is in the ``doc/`` subdirectory. It's written in
-reStructuredText_ with Sphinx_ annotations. To generate the HTML
-documentation, invoke::
-
-   make html
-
-and point your browser to ``doc/_build/html/index.html``. Sphinx_ 1.0
-or newer is required to generate the documentation.
-
-.. _reStructuredText: http://docutils.sourceforge.net/rst.html
-.. _Sphinx: http://sphinx.pocoo.org/
-
-
-Compiling Programs that Use Jansson
-===================================
-
-Jansson involves one C header file, :file:`jansson.h`, so it's enough
-to put the line
-
-::
-
-    #include <jansson.h>
-
-in the beginning of every source file that uses Jansson.
-
-There's also just one library to link with, ``libjansson``. Compile and
-link the program as follows::
-
-    cc -o prog prog.c -ljansson
-
-Starting from version 1.2, there's also support for pkg-config_::
-
-    cc -o prog prog.c `pkg-config --cflags --libs jansson`
-
-.. _pkg-config: http://pkg-config.freedesktop.org/
diff --git a/deps/jansson/doc/github_commits.c b/deps/jansson/doc/github_commits.c
deleted file mode 100644
index 94fb8b7..0000000
--- a/deps/jansson/doc/github_commits.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <jansson.h>
-#include <curl/curl.h>
-
-#define BUFFER_SIZE  (256 * 1024)  /* 256 KB */
-
-#define URL_FORMAT   "https://api.github.com/repos/%s/%s/commits"
-#define URL_SIZE     256
-
-/* Return the offset of the first newline in text or the length of
-   text if there's no newline */
-static int newline_offset(const char *text)
-{
-    const char *newline = strchr(text, '\n');
-    if(!newline)
-        return strlen(text);
-    else
-        return (int)(newline - text);
-}
-
-struct write_result
-{
-    char *data;
-    int pos;
-};
-
-static size_t write_response(void *ptr, size_t size, size_t nmemb, void *stream)
-{
-    struct write_result *result = (struct write_result *)stream;
-
-    if(result->pos + size * nmemb >= BUFFER_SIZE - 1)
-    {
-        fprintf(stderr, "error: too small buffer\n");
-        return 0;
-    }
-
-    memcpy(result->data + result->pos, ptr, size * nmemb);
-    result->pos += size * nmemb;
-
-    return size * nmemb;
-}
-
-static char *request(const char *url)
-{
-    CURL *curl = NULL;
-    CURLcode status;
-    struct curl_slist *headers = NULL;
-    char *data = NULL;
-    long code;
-
-    curl_global_init(CURL_GLOBAL_ALL);
-    curl = curl_easy_init();
-    if(!curl)
-        goto error;
-
-    data = malloc(BUFFER_SIZE);
-    if(!data)
-        goto error;
-
-    struct write_result write_result = {
-        .data = data,
-        .pos = 0
-    };
-
-    curl_easy_setopt(curl, CURLOPT_URL, url);
-
-    /* GitHub commits API v3 requires a User-Agent header */
-    headers = curl_slist_append(headers, "User-Agent: Jansson-Tutorial");
-    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
-
-    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response);
-    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_result);
-
-    status = curl_easy_perform(curl);
-    if(status != 0)
-    {
-        fprintf(stderr, "error: unable to request data from %s:\n", url);
-        fprintf(stderr, "%s\n", curl_easy_strerror(status));
-        goto error;
-    }
-
-    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
-    if(code != 200)
-    {
-        fprintf(stderr, "error: server responded with code %ld\n", code);
-        goto error;
-    }
-
-    curl_easy_cleanup(curl);
-    curl_slist_free_all(headers);
-    curl_global_cleanup();
-
-    /* zero-terminate the result */
-    data[write_result.pos] = '\0';
-
-    return data;
-
-error:
-    if(data)
-        free(data);
-    if(curl)
-        curl_easy_cleanup(curl);
-    if(headers)
-        curl_slist_free_all(headers);
-    curl_global_cleanup();
-    return NULL;
-}
-
-int main(int argc, char *argv[])
-{
-    size_t i;
-    char *text;
-    char url[URL_SIZE];
-
-    json_t *root;
-    json_error_t error;
-
-    if(argc != 3)
-    {
-        fprintf(stderr, "usage: %s USER REPOSITORY\n\n", argv[0]);
-        fprintf(stderr, "List commits at USER's REPOSITORY.\n\n");
-        return 2;
-    }
-
-    snprintf(url, URL_SIZE, URL_FORMAT, argv[1], argv[2]);
-
-    text = request(url);
-    if(!text)
-        return 1;
-
-    root = json_loads(text, 0, &error);
-    free(text);
-
-    if(!root)
-    {
-        fprintf(stderr, "error: on line %d: %s\n", error.line, error.text);
-        return 1;
-    }
-
-    if(!json_is_array(root))
-    {
-        fprintf(stderr, "error: root is not an array\n");
-        json_decref(root);
-        return 1;
-    }
-
-    for(i = 0; i < json_array_size(root); i++)
-    {
-        json_t *data, *sha, *commit, *message;
-        const char *message_text;
-
-        data = json_array_get(root, i);
-        if(!json_is_object(data))
-        {
-            fprintf(stderr, "error: commit data %d is not an object\n", (int)(i + 1));
-            json_decref(root);
-            return 1;
-        }
-
-        sha = json_object_get(data, "sha");
-        if(!json_is_string(sha))
-        {
-            fprintf(stderr, "error: commit %d: sha is not a string\n", (int)(i + 1));
-            return 1;
-        }
-
-        commit = json_object_get(data, "commit");
-        if(!json_is_object(commit))
-        {
-            fprintf(stderr, "error: commit %d: commit is not an object\n", (int)(i + 1));
-            json_decref(root);
-            return 1;
-        }
-
-        message = json_object_get(commit, "message");
-        if(!json_is_string(message))
-        {
-            fprintf(stderr, "error: commit %d: message is not a string\n", (int)(i + 1));
-            json_decref(root);
-            return 1;
-        }
-
-        message_text = json_string_value(message);
-        printf("%.8s %.*s\n",
-               json_string_value(sha),
-               newline_offset(message_text),
-               message_text);
-    }
-
-    json_decref(root);
-    return 0;
-}
diff --git a/deps/jansson/doc/index.rst b/deps/jansson/doc/index.rst
deleted file mode 100644
index 1f3f8ef..0000000
--- a/deps/jansson/doc/index.rst
+++ /dev/null
@@ -1,53 +0,0 @@
-Jansson Documentation
-=====================
-
-This is the documentation for Jansson_ |release|, last updated |today|.
-
-Introduction
-------------
-
-Jansson_ is a C library for encoding, decoding and manipulating JSON
-data. Its main features and design principles are:
-
-- Simple and intuitive API and data model
-
-- Comprehensive documentation
-
-- No dependencies on other libraries
-
-- Full Unicode support (UTF-8)
-
-- Extensive test suite
-
-Jansson is licensed under the `MIT license`_; see LICENSE in the
-source distribution for details.
-
-Jansson is used in production and its API is stable. It works on
-numerous platforms, including numerous Unix like systems and Windows.
-It's suitable for use on any system, including desktop, server, and
-small embedded systems.
-
-
-.. _`MIT license`: http://www.opensource.org/licenses/mit-license.php
-.. _Jansson: http://www.digip.org/jansson/
-
-Contents
---------
-
-.. toctree::
-   :maxdepth: 2
-
-   gettingstarted
-   upgrading
-   tutorial
-   conformance
-   portability
-   apiref
-   changes
-
-
-Indices and Tables
-==================
-
-* :ref:`genindex`
-* :ref:`search`
diff --git a/deps/jansson/doc/portability.rst b/deps/jansson/doc/portability.rst
deleted file mode 100644
index dc6c5eb..0000000
--- a/deps/jansson/doc/portability.rst
+++ /dev/null
@@ -1,52 +0,0 @@
-***********
-Portability
-***********
-
-Thread safety
--------------
-
-Jansson is thread safe and has no mutable global state. The only
-exception are the memory allocation functions, that should be set at
-most once, and only on program startup. See
-:ref:`apiref-custom-memory-allocation`.
-
-There's no locking performed inside Jansson's code, so a multithreaded
-program must perform its own locking if JSON values are shared by
-multiple threads. Jansson's reference counting semantics may make this
-a bit harder than it seems, as it's possible to have a reference to a
-value that's also stored inside a list or object. Modifying the
-container (adding or removing values) may trigger concurrent access to
-such values, as containers manage the reference count of their
-contained values. Bugs involving concurrent incrementing or
-decrementing of deference counts may be hard to track.
-
-The encoding functions (:func:`json_dumps()` and friends) track
-reference loops by modifying the internal state of objects and arrays.
-For this reason, encoding functions must not be run on the same JSON
-values in two separate threads at the same time. As already noted
-above, be especially careful if two arrays or objects share their
-contained values with another array or object.
-
-If you want to make sure that two JSON value hierarchies do not
-contain shared values, use :func:`json_deep_copy()` to make copies.
-
-Locale
-------
-
-Jansson works fine under any locale.
-
-However, if the host program is multithreaded and uses ``setlocale()``
-to switch the locale in one thread while Jansson is currently encoding
-or decoding JSON data in another thread, the result may be wrong or
-the program may even crash.
-
-Jansson uses locale specific functions for certain string conversions
-in the encoder and decoder, and then converts the locale specific
-values to/from the JSON representation. This fails if the locale
-changes between the string conversion and the locale-to-JSON
-conversion. This can only happen in multithreaded programs that use
-``setlocale()``, because ``setlocale()`` switches the locale for all
-running threads, not only the thread that calls ``setlocale()``.
-
-If your program uses ``setlocale()`` as described above, consider
-using the thread-safe ``uselocale()`` instead.
diff --git a/deps/jansson/doc/tutorial.rst b/deps/jansson/doc/tutorial.rst
deleted file mode 100644
index c2df081..0000000
--- a/deps/jansson/doc/tutorial.rst
+++ /dev/null
@@ -1,286 +0,0 @@
-.. _tutorial:
-
-********
-Tutorial
-********
-
-.. highlight:: c
-
-In this tutorial, we create a program that fetches the latest commits
-of a repository in GitHub_ over the web. `GitHub API`_ uses JSON, so
-the result can be parsed using Jansson.
-
-To stick to the the scope of this tutorial, we will only cover the the
-parts of the program related to handling JSON data. For the best user
-experience, the full source code is available:
-:download:`github_commits.c`. To compile it (on Unix-like systems with
-gcc), use the following command::
-
-    gcc -o github_commits github_commits.c -ljansson -lcurl
-
-libcurl_ is used to communicate over the web, so it is required to
-compile the program.
-
-The command line syntax is::
-
-    github_commits USER REPOSITORY
-
-``USER`` is a GitHub user ID and ``REPOSITORY`` is the repository
-name. Please note that the GitHub API is rate limited, so if you run
-the program too many times within a short period of time, the sever
-starts to respond with an error.
-
-.. _GitHub: https://github.com/
-.. _GitHub API: http://developer.github.com/
-.. _libcurl: http://curl.haxx.se/
-
-
-.. _tutorial-github-commits-api:
-
-The GitHub Repo Commits API
-===========================
-
-The `GitHub Repo Commits API`_ is used by sending HTTP requests to
-URLs like ``https://api.github.com/repos/USER/REPOSITORY/commits``,
-where ``USER`` and ``REPOSITORY`` are the GitHub user ID and the name
-of the repository whose commits are to be listed, respectively.
-
-GitHub responds with a JSON array of the following form:
-
-.. code-block:: none
-
-    [
-        {
-            "sha": "<the commit ID>",
-            "commit": {
-                "message": "<the commit message>",
-                <more fields, not important to this tutorial...>
-            },
-            <more fields...>
-        },
-        {
-            "sha": "<the commit ID>",
-            "commit": {
-                "message": "<the commit message>",
-                <more fields...>
-            },
-            <more fields...>
-        },
-        <more commits...>
-    ]
-
-In our program, the HTTP request is sent using the following
-function::
-
-    static char *request(const char *url);
-
-It takes the URL as a parameter, preforms a HTTP GET request, and
-returns a newly allocated string that contains the response body. If
-the request fails, an error message is printed to stderr and the
-return value is *NULL*. For full details, refer to :download:`the code
-<github_commits.c>`, as the actual implementation is not important
-here.
-
-.. _GitHub Repo Commits API: http://developer.github.com/v3/repos/commits/
-
-.. _tutorial-the-program:
-
-The Program
-===========
-
-First the includes::
-
-    #include <string.h>
-    #include <jansson.h>
-
-Like all the programs using Jansson, we need to include
-:file:`jansson.h`.
-
-The following definitions are used to build the GitHub API request
-URL::
-
-   #define URL_FORMAT   "https://api.github.com/repos/%s/%s/commits"
-   #define URL_SIZE     256
-
-The following function is used when formatting the result to find the
-first newline in the commit message::
-
-    /* Return the offset of the first newline in text or the length of
-       text if there's no newline */
-    static int newline_offset(const char *text)
-    {
-        const char *newline = strchr(text, '\n');
-        if(!newline)
-            return strlen(text);
-        else
-            return (int)(newline - text);
-    }
-
-The main function follows. In the beginning, we first declare a bunch
-of variables and check the command line parameters::
-
-    int main(int argc, char *argv[])
-    {
-        size_t i;
-        char *text;
-        char url[URL_SIZE];
-
-        json_t *root;
-        json_error_t error;
-
-        if(argc != 3)
-        {
-            fprintf(stderr, "usage: %s USER REPOSITORY\n\n", argv[0]);
-            fprintf(stderr, "List commits at USER's REPOSITORY.\n\n");
-            return 2;
-        }
-
-Then we build the request URL using the user and repository names
-given as command line parameters::
-
-    snprintf(url, URL_SIZE, URL_FORMAT, argv[1], argv[2]);
-
-This uses the ``URL_SIZE`` and ``URL_FORMAT`` constants defined above.
-Now we're ready to actually request the JSON data over the web::
-
-    text = request(url);
-    if(!text)
-        return 1;
-
-If an error occurs, our function ``request`` prints the error and
-returns *NULL*, so it's enough to just return 1 from the main
-function.
-
-Next we'll call :func:`json_loads()` to decode the JSON text we got
-as a response::
-
-    root = json_loads(text, 0, &error);
-    free(text);
-
-    if(!root)
-    {
-        fprintf(stderr, "error: on line %d: %s\n", error.line, error.text);
-        return 1;
-    }
-
-We don't need the JSON text anymore, so we can free the ``text``
-variable right after decoding it. If :func:`json_loads()` fails, it
-returns *NULL* and sets error information to the :type:`json_error_t`
-structure given as the second parameter. In this case, our program
-prints the error information out and returns 1 from the main function.
-
-Now we're ready to extract the data out of the decoded JSON response.
-The structure of the response JSON was explained in section
-:ref:`tutorial-github-commits-api`.
-
-We check that the returned value really is an array::
-
-    if(!json_is_array(root))
-    {
-        fprintf(stderr, "error: root is not an array\n");
-        json_decref(root);
-        return 1;
-    }
-
-Then we proceed to loop over all the commits in the array::
-
-    for(i = 0; i < json_array_size(root); i++)
-    {
-        json_t *data, *sha, *commit, *message;
-        const char *message_text;
-
-        data = json_array_get(root, i);
-        if(!json_is_object(data))
-        {
-            fprintf(stderr, "error: commit data %d is not an object\n", i + 1);
-            json_decref(root);
-            return 1;
-        }
-    ...
-
-The function :func:`json_array_size()` returns the size of a JSON
-array. First, we again declare some variables and then extract the
-i'th element of the ``root`` array using :func:`json_array_get()`.
-We also check that the resulting value is a JSON object.
-
-Next we'll extract the commit ID (a hexadecimal SHA-1 sum),
-intermediate commit info object, and the commit message from that
-object. We also do proper type checks::
-
-        sha = json_object_get(data, "sha");
-        if(!json_is_string(sha))
-        {
-            fprintf(stderr, "error: commit %d: sha is not a string\n", i + 1);
-            json_decref(root);
-            return 1;
-        }
-
-        commit = json_object_get(data, "commit");
-        if(!json_is_object(commit))
-        {
-            fprintf(stderr, "error: commit %d: commit is not an object\n", i + 1);
-            json_decref(root);
-            return 1;
-        }
-
-        message = json_object_get(commit, "message");
-        if(!json_is_string(message))
-        {
-            fprintf(stderr, "error: commit %d: message is not a string\n", i + 1);
-            json_decref(root);
-            return 1;
-        }
-    ...
-
-And finally, we'll print the first 8 characters of the commit ID and
-the first line of the commit message. A C-style string is extracted
-from a JSON string using :func:`json_string_value()`::
-
-        message_text = json_string_value(message);
-        printf("%.8s %.*s\n",
-               json_string_value(id),
-               newline_offset(message_text),
-               message_text);
-    }
-
-After sending the HTTP request, we decoded the JSON text using
-:func:`json_loads()`, remember? It returns a *new reference* to the
-JSON value it decodes. When we're finished with the value, we'll need
-to decrease the reference count using :func:`json_decref()`. This way
-Jansson can release the resources::
-
-    json_decref(root);
-    return 0;
-
-For a detailed explanation of reference counting in Jansson, see
-:ref:`apiref-reference-count` in :ref:`apiref`.
-
-The program's ready, let's test it and view the latest commits in
-Jansson's repository::
-
-    $ ./github_commits akheron jansson
-    1581f26a Merge branch '2.3'
-    aabfd493 load: Change buffer_pos to be a size_t
-    bd72efbd load: Avoid unexpected behaviour in macro expansion
-    e8fd3e30 Document and tweak json_load_callback()
-    873eddaf Merge pull request #60 from rogerz/contrib
-    bd2c0c73 Ignore the binary test_load_callback
-    17a51a4b Merge branch '2.3'
-    09c39adc Add json_load_callback to the list of exported symbols
-    cbb80baf Merge pull request #57 from rogerz/contrib
-    040bd7b0 Add json_load_callback()
-    2637faa4 Make test stripping locale independent
-    <...>
-
-
-Conclusion
-==========
-
-In this tutorial, we implemented a program that fetches the latest
-commits of a GitHub repository using the GitHub Repo Commits API.
-Jansson was used to decode the JSON response and to extract the commit
-data.
-
-This tutorial only covered a small part of Jansson. For example, we
-did not create or manipulate JSON values at all. Proceed to
-:ref:`apiref` to explore all features of Jansson.
diff --git a/deps/jansson/doc/upgrading.rst b/deps/jansson/doc/upgrading.rst
deleted file mode 100644
index 9b49046..0000000
--- a/deps/jansson/doc/upgrading.rst
+++ /dev/null
@@ -1,76 +0,0 @@
-.. highlight:: c
-
-******************
-Upgrading from 1.x
-******************
-
-This chapter lists the backwards incompatible changes introduced in
-Jansson 2.0, and the steps that are needed for upgrading your code.
-
-**The incompatibilities are not dramatic.** The biggest change is that
-all decoding functions now require and extra parameter. Most programs
-can be modified to work with 2.0 by adding a ``0`` as the second
-parameter to all calls of :func:`json_loads()`, :func:`json_loadf()`
-and :func:`json_load_file()`.
-
-
-Compatibility
-=============
-
-Jansson 2.0 is backwards incompatible with the Jansson 1.x releases.
-It is ABI incompatible, i.e. all programs dynamically linking to the
-Jansson library need to be recompiled. It's also API incompatible,
-i.e. the source code of programs using Jansson 1.x may need
-modifications to make them compile against Jansson 2.0.
-
-All the 2.x releases are guaranteed to be backwards compatible for
-both ABI and API, so no recompilation or source changes are needed
-when upgrading from 2.x to 2.y.
-
-
-List of Incompatible Changes
-============================
-
-**Decoding flags**
-    For future needs, a ``flags`` parameter was added as the second
-    parameter to all decoding functions, i.e. :func:`json_loads()`,
-    :func:`json_loadf()` and :func:`json_load_file()`. All calls to
-    these functions need to be changed by adding a ``0`` as the second
-    argument. For example::
-
-        /* old code */
-        json_loads(input, &error);
-
-        /* new code */
-        json_loads(input, 0, &error);
-
-
-**Underlying type of JSON integers**
-    The underlying C type of JSON integers has been changed from
-    :type:`int` to the widest available signed integer type, i.e.
-    :type:`long long` or :type:`long`, depending on whether
-    :type:`long long` is supported on your system or not. This makes
-    the whole 64-bit integer range available on most modern systems.
-
-    ``jansson.h`` has a typedef :type:`json_int_t` to the underlying
-    integer type. :type:`int` should still be used in most cases when
-    dealing with smallish JSON integers, as the compiler handles
-    implicit type coercion. Only when the full 64-bit range is needed,
-    :type:`json_int_t` should be explicitly used.
-
-
-**Maximum encoder indentation depth**
-    The maximum argument of the ``JSON_INDENT()`` macro has been
-    changed from 255 to 31, to free up bits from the ``flags``
-    parameter of :func:`json_dumps()`, :func:`json_dumpf()` and
-    :func:`json_dump_file()`. If your code uses a bigger indentation
-    than 31, it needs to be changed.
-
-
-**Unsigned integers in API functions**
-    Version 2.0 unifies unsigned integer usage in the API. All uses of
-    :type:`unsigned int` and :type:`unsigned long` have been replaced
-    with :type:`size_t`. This includes flags, container sizes, etc.
-    This should not require source code changes, as both
-    :type:`unsigned int` and :type:`unsigned long` are usually
-    compatible with :type:`size_t`.
diff --git a/deps/jansson/jansson.pc.in b/deps/jansson/jansson.pc.in
deleted file mode 100644
index d9bf4da..0000000
--- a/deps/jansson/jansson.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=${prefix}/include
-
-Name: Jansson
-Description: Library for encoding, decoding and manipulating JSON data
-Version: @VERSION@
-Libs: -L${libdir} -ljansson
-Cflags: -I${includedir}
diff --git a/deps/jansson/release.sh b/deps/jansson/release.sh
deleted file mode 100755
index c2551f8..0000000
--- a/deps/jansson/release.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-#
-# Use this script to easily make releases of Jansson. It configures
-# the source tree, and builds and signs all tarballs.
-
-die() {
-    echo $1 >&2
-    exit 1
-}
-
-confirm() {
-    local answer
-    read -p "$1 [yN]: " answer
-    [ "$answer" = "Y" -o "$answer" = "y" ] || exit 0
-}
-
-set -e
-[ -f configure.ac ] || die "Must be run at project root directory"
-
-# Determine version
-v=$(grep AC_INIT configure.ac | sed -r 's/.*, \[(.+?)\],.*/\1/')
-[ -n "$v" ] || die "Unable to determine version"
-confirm "Version is $v, proceed?"
-
-# Sanity checks
-vi=$(grep version-info src/Makefile.am | sed 's/^[ \t]*//g' | cut -d" " -f2)
-confirm "Libtool version-info is $vi, proceed?"
-
-r=$(grep 'Released ' CHANGES | head -n 1)
-confirm "Last CHANGES entry says \"$r\", proceed??"
-
-dv=$(grep ^version doc/conf.py | sed -r "s/.*'(.*)'.*/\1/")
-if [ "$dv" != "$v" ]; then
-    die "Documentation version ($dv) doesn't match library version"
-fi
-
-[ -f Makefile ] && make distclean || true
-rm -f jansson-$v.tar.*
-rm -rf jansson-$v-doc
-rm -f jansson-$v-doc.tar.*
-
-autoreconf -fi
-./configure
-
-# Run tests and make gz source tarball
-: ${VALGRIND:=1}
-export VALGRIND
-make distcheck
-
-# Make bzip2 source tarball
-make dist-bzip2
-
-# Sign source tarballs
-for s in gz bz2; do
-    gpg --detach-sign --armor jansson-$v.tar.$s
-done
-
-# Build documentation
-make html
-mv doc/_build/html jansson-$v-doc
-
-# Make and sign documentation tarballs
-for s in gz bz2; do
-    [ $s = gz ] && compress=gzip
-    [ $s = bz2 ] && compress=bzip2
-    tar cf - jansson-$v-doc | $compress -9 -c > jansson-$v-doc.tar.$s
-    gpg --detach-sign --armor jansson-$v-doc.tar.$s
-done
-
-echo "All done"
diff --git a/deps/jansson/src/Makefile.am b/deps/jansson/src/Makefile.am
deleted file mode 100644
index e1a5493..0000000
--- a/deps/jansson/src/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-EXTRA_DIST = jansson.def
-
-include_HEADERS = jansson.h jansson_config.h
-
-lib_LTLIBRARIES = libjansson.la
-libjansson_la_SOURCES = \
-	dump.c \
-	error.c \
-	hashtable.c \
-	hashtable.h \
-	jansson_private.h \
-	load.c \
-	memory.c \
-	pack_unpack.c \
-	strbuffer.c \
-	strbuffer.h \
-	strconv.c \
-	utf.c \
-	utf.h \
-	value.c
-libjansson_la_LDFLAGS = \
-	-no-undefined \
-	-export-symbols-regex '^json_' \
-	-version-info 9:0:5
diff --git a/deps/jansson/src/dump.c b/deps/jansson/src/dump.c
deleted file mode 100644
index 26a1906..0000000
--- a/deps/jansson/src/dump.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "jansson.h"
-#include "jansson_private.h"
-#include "strbuffer.h"
-#include "utf.h"
-
-#define MAX_INTEGER_STR_LENGTH  100
-#define MAX_REAL_STR_LENGTH     100
-
-struct object_key {
-    size_t serial;
-    const char *key;
-};
-
-static int dump_to_strbuffer(const char *buffer, size_t size, void *data)
-{
-    return strbuffer_append_bytes((strbuffer_t *)data, buffer, size);
-}
-
-static int dump_to_file(const char *buffer, size_t size, void *data)
-{
-    FILE *dest = (FILE *)data;
-    if(fwrite(buffer, size, 1, dest) != 1)
-        return -1;
-    return 0;
-}
-
-/* 32 spaces (the maximum indentation size) */
-static const char whitespace[] = "                                ";
-
-static int dump_indent(size_t flags, int depth, int space, json_dump_callback_t dump, void *data)
-{
-    if(JSON_INDENT(flags) > 0)
-    {
-        int i, ws_count = JSON_INDENT(flags);
-
-        if(dump("\n", 1, data))
-            return -1;
-
-        for(i = 0; i < depth; i++)
-        {
-            if(dump(whitespace, ws_count, data))
-                return -1;
-        }
-    }
-    else if(space && !(flags & JSON_COMPACT))
-    {
-        return dump(" ", 1, data);
-    }
-    return 0;
-}
-
-static int dump_string(const char *str, size_t len, json_dump_callback_t dump, void *data, size_t flags)
-{
-    const char *pos, *end, *lim;
-    int32_t codepoint;
-
-    if(dump("\"", 1, data))
-        return -1;
-
-    end = pos = str;
-    lim = str + len;
-    while(1)
-    {
-        const char *text;
-        char seq[13];
-        int length;
-
-        while(end < lim)
-        {
-            end = utf8_iterate(pos, lim - pos, &codepoint);
-            if(!end)
-                return -1;
-
-            /* mandatory escape or control char */
-            if(codepoint == '\\' || codepoint == '"' || codepoint < 0x20)
-                break;
-
-            /* slash */
-            if((flags & JSON_ESCAPE_SLASH) && codepoint == '/')
-                break;
-
-            /* non-ASCII */
-            if((flags & JSON_ENSURE_ASCII) && codepoint > 0x7F)
-                break;
-
-            pos = end;
-        }
-
-        if(pos != str) {
-            if(dump(str, pos - str, data))
-                return -1;
-        }
-
-        if(end == pos)
-            break;
-
-        /* handle \, /, ", and control codes */
-        length = 2;
-        switch(codepoint)
-        {
-            case '\\': text = "\\\\"; break;
-            case '\"': text = "\\\""; break;
-            case '\b': text = "\\b"; break;
-            case '\f': text = "\\f"; break;
-            case '\n': text = "\\n"; break;
-            case '\r': text = "\\r"; break;
-            case '\t': text = "\\t"; break;
-            case '/':  text = "\\/"; break;
-            default:
-            {
-                /* codepoint is in BMP */
-                if(codepoint < 0x10000)
-                {
-                    sprintf(seq, "\\u%04X", codepoint);
-                    length = 6;
-                }
-
-                /* not in BMP -> construct a UTF-16 surrogate pair */
-                else
-                {
-                    int32_t first, last;
-
-                    codepoint -= 0x10000;
-                    first = 0xD800 | ((codepoint & 0xffc00) >> 10);
-                    last = 0xDC00 | (codepoint & 0x003ff);
-
-                    sprintf(seq, "\\u%04X\\u%04X", first, last);
-                    length = 12;
-                }
-
-                text = seq;
-                break;
-            }
-        }
-
-        if(dump(text, length, data))
-            return -1;
-
-        str = pos = end;
-    }
-
-    return dump("\"", 1, data);
-}
-
-static int object_key_compare_keys(const void *key1, const void *key2)
-{
-    return strcmp(((const struct object_key *)key1)->key,
-                  ((const struct object_key *)key2)->key);
-}
-
-static int object_key_compare_serials(const void *key1, const void *key2)
-{
-    size_t a = ((const struct object_key *)key1)->serial;
-    size_t b = ((const struct object_key *)key2)->serial;
-
-    return a < b ? -1 : a == b ? 0 : 1;
-}
-
-static int do_dump(const json_t *json, size_t flags, int depth,
-                   json_dump_callback_t dump, void *data)
-{
-    if(!json)
-        return -1;
-
-    switch(json_typeof(json)) {
-        case JSON_NULL:
-            return dump("null", 4, data);
-
-        case JSON_TRUE:
-            return dump("true", 4, data);
-
-        case JSON_FALSE:
-            return dump("false", 5, data);
-
-        case JSON_INTEGER:
-        {
-            char buffer[MAX_INTEGER_STR_LENGTH];
-            int size;
-
-            size = snprintf(buffer, MAX_INTEGER_STR_LENGTH,
-                            "%" JSON_INTEGER_FORMAT,
-                            json_integer_value(json));
-            if(size < 0 || size >= MAX_INTEGER_STR_LENGTH)
-                return -1;
-
-            return dump(buffer, size, data);
-        }
-
-        case JSON_REAL:
-        {
-            char buffer[MAX_REAL_STR_LENGTH];
-            int size;
-            double value = json_real_value(json);
-
-            size = jsonp_dtostr(buffer, MAX_REAL_STR_LENGTH, value);
-            if(size < 0)
-                return -1;
-
-            return dump(buffer, size, data);
-        }
-
-        case JSON_STRING:
-            return dump_string(json_string_value(json), json_string_length(json), dump, data, flags);
-
-        case JSON_ARRAY:
-        {
-            int i;
-            int n;
-            json_array_t *array;
-
-            /* detect circular references */
-            array = json_to_array(json);
-            if(array->visited)
-                goto array_error;
-            array->visited = 1;
-
-            n = (int)json_array_size(json);
-
-            if(dump("[", 1, data))
-                goto array_error;
-            if(n == 0) {
-                array->visited = 0;
-                return dump("]", 1, data);
-            }
-            if(dump_indent(flags, depth + 1, 0, dump, data))
-                goto array_error;
-
-            for(i = 0; i < n; ++i) {
-                if(do_dump(json_array_get(json, i), flags, depth + 1,
-                           dump, data))
-                    goto array_error;
-
-                if(i < n - 1)
-                {
-                    if(dump(",", 1, data) ||
-                       dump_indent(flags, depth + 1, 1, dump, data))
-                        goto array_error;
-                }
-                else
-                {
-                    if(dump_indent(flags, depth, 0, dump, data))
-                        goto array_error;
-                }
-            }
-
-            array->visited = 0;
-            return dump("]", 1, data);
-
-        array_error:
-            array->visited = 0;
-            return -1;
-        }
-
-        case JSON_OBJECT:
-        {
-            json_object_t *object;
-            void *iter;
-            const char *separator;
-            int separator_length;
-
-            if(flags & JSON_COMPACT) {
-                separator = ":";
-                separator_length = 1;
-            }
-            else {
-                separator = ": ";
-                separator_length = 2;
-            }
-
-            /* detect circular references */
-            object = json_to_object(json);
-            if(object->visited)
-                goto object_error;
-            object->visited = 1;
-
-            iter = json_object_iter((json_t *)json);
-
-            if(dump("{", 1, data))
-                goto object_error;
-            if(!iter) {
-                object->visited = 0;
-                return dump("}", 1, data);
-            }
-            if(dump_indent(flags, depth + 1, 0, dump, data))
-                goto object_error;
-
-            if(flags & JSON_SORT_KEYS || flags & JSON_PRESERVE_ORDER)
-            {
-                struct object_key *keys;
-                size_t size, i;
-                int (*cmp_func)(const void *, const void *);
-
-                size = json_object_size(json);
-                keys = jsonp_malloc(size * sizeof(struct object_key));
-                if(!keys)
-                    goto object_error;
-
-                i = 0;
-                while(iter)
-                {
-                    keys[i].serial = hashtable_iter_serial(iter);
-                    keys[i].key = json_object_iter_key(iter);
-                    iter = json_object_iter_next((json_t *)json, iter);
-                    i++;
-                }
-                assert(i == size);
-
-                if(flags & JSON_SORT_KEYS)
-                    cmp_func = object_key_compare_keys;
-                else
-                    cmp_func = object_key_compare_serials;
-
-                qsort(keys, size, sizeof(struct object_key), cmp_func);
-
-                for(i = 0; i < size; i++)
-                {
-                    const char *key;
-                    json_t *value;
-
-                    key = keys[i].key;
-                    value = json_object_get(json, key);
-                    assert(value);
-
-                    dump_string(key, strlen(key), dump, data, flags);
-                    if(dump(separator, separator_length, data) ||
-                       do_dump(value, flags, depth + 1, dump, data))
-                    {
-                        jsonp_free(keys);
-                        goto object_error;
-                    }
-
-                    if(i < size - 1)
-                    {
-                        if(dump(",", 1, data) ||
-                           dump_indent(flags, depth + 1, 1, dump, data))
-                        {
-                            jsonp_free(keys);
-                            goto object_error;
-                        }
-                    }
-                    else
-                    {
-                        if(dump_indent(flags, depth, 0, dump, data))
-                        {
-                            jsonp_free(keys);
-                            goto object_error;
-                        }
-                    }
-                }
-
-                jsonp_free(keys);
-            }
-            else
-            {
-                /* Don't sort keys */
-
-                while(iter)
-                {
-                    void *next = json_object_iter_next((json_t *)json, iter);
-                    const char *key = json_object_iter_key(iter);
-
-                    dump_string(key, strlen(key), dump, data, flags);
-                    if(dump(separator, separator_length, data) ||
-                       do_dump(json_object_iter_value(iter), flags, depth + 1,
-                               dump, data))
-                        goto object_error;
-
-                    if(next)
-                    {
-                        if(dump(",", 1, data) ||
-                           dump_indent(flags, depth + 1, 1, dump, data))
-                            goto object_error;
-                    }
-                    else
-                    {
-                        if(dump_indent(flags, depth, 0, dump, data))
-                            goto object_error;
-                    }
-
-                    iter = next;
-                }
-            }
-
-            object->visited = 0;
-            return dump("}", 1, data);
-
-        object_error:
-            object->visited = 0;
-            return -1;
-        }
-
-        default:
-            /* not reached */
-            return -1;
-    }
-}
-
-char *json_dumps(const json_t *json, size_t flags)
-{
-    strbuffer_t strbuff;
-    char *result;
-
-    if(strbuffer_init(&strbuff))
-        return NULL;
-
-    if(json_dump_callback(json, dump_to_strbuffer, (void *)&strbuff, flags))
-        result = NULL;
-    else
-        result = jsonp_strdup(strbuffer_value(&strbuff));
-
-    strbuffer_close(&strbuff);
-    return result;
-}
-
-int json_dumpf(const json_t *json, FILE *output, size_t flags)
-{
-    return json_dump_callback(json, dump_to_file, (void *)output, flags);
-}
-
-int json_dump_file(const json_t *json, const char *path, size_t flags)
-{
-    int result;
-
-    FILE *output = fopen(path, "w");
-    if(!output)
-        return -1;
-
-    result = json_dumpf(json, output, flags);
-
-    fclose(output);
-    return result;
-}
-
-int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags)
-{
-    if(!(flags & JSON_ENCODE_ANY)) {
-        if(!json_is_array(json) && !json_is_object(json))
-           return -1;
-    }
-
-    return do_dump(json, flags, 0, callback, data);
-}
diff --git a/deps/jansson/src/error.c b/deps/jansson/src/error.c
deleted file mode 100644
index 2ba8d82..0000000
--- a/deps/jansson/src/error.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <string.h>
-#include "jansson_private.h"
-
-void jsonp_error_init(json_error_t *error, const char *source)
-{
-    if(error)
-    {
-        error->text[0] = '\0';
-        error->line = -1;
-        error->column = -1;
-        error->position = 0;
-        if(source)
-            jsonp_error_set_source(error, source);
-        else
-            error->source[0] = '\0';
-    }
-}
-
-void jsonp_error_set_source(json_error_t *error, const char *source)
-{
-    size_t length;
-
-    if(!error || !source)
-        return;
-
-    length = strlen(source);
-    if(length < JSON_ERROR_SOURCE_LENGTH)
-        strcpy(error->source, source);
-    else {
-        size_t extra = length - JSON_ERROR_SOURCE_LENGTH + 4;
-        strcpy(error->source, "...");
-        strcpy(error->source + 3, source + extra);
-    }
-}
-
-void jsonp_error_set(json_error_t *error, int line, int column,
-                     size_t position, const char *msg, ...)
-{
-    va_list ap;
-
-    va_start(ap, msg);
-    jsonp_error_vset(error, line, column, position, msg, ap);
-    va_end(ap);
-}
-
-void jsonp_error_vset(json_error_t *error, int line, int column,
-                      size_t position, const char *msg, va_list ap)
-{
-    if(!error)
-        return;
-
-    if(error->text[0] != '\0') {
-        /* error already set */
-        return;
-    }
-
-    error->line = line;
-    error->column = column;
-    error->position = (int)position;
-
-    vsnprintf(error->text, JSON_ERROR_TEXT_LENGTH, msg, ap);
-    error->text[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
-}
diff --git a/deps/jansson/src/hashtable.c b/deps/jansson/src/hashtable.c
deleted file mode 100644
index a254cfa..0000000
--- a/deps/jansson/src/hashtable.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <jansson_config.h>   /* for JSON_INLINE */
-#include "jansson_private.h"  /* for container_of() */
-#include "hashtable.h"
-
-typedef struct hashtable_list list_t;
-typedef struct hashtable_pair pair_t;
-typedef struct hashtable_bucket bucket_t;
-
-#define list_to_pair(list_)  container_of(list_, pair_t, list)
-
-/* From http://www.cse.yorku.ca/~oz/hash.html */
-static size_t hash_str(const void *ptr)
-{
-    const char *str = (const char *)ptr;
-
-    size_t hash = 5381;
-    size_t c;
-
-    while((c = (size_t)*str))
-    {
-        hash = ((hash << 5) + hash) + c;
-        str++;
-    }
-
-    return hash;
-}
-
-static JSON_INLINE void list_init(list_t *list)
-{
-    list->next = list;
-    list->prev = list;
-}
-
-static JSON_INLINE void list_insert(list_t *list, list_t *node)
-{
-    node->next = list;
-    node->prev = list->prev;
-    list->prev->next = node;
-    list->prev = node;
-}
-
-static JSON_INLINE void list_remove(list_t *list)
-{
-    list->prev->next = list->next;
-    list->next->prev = list->prev;
-}
-
-static JSON_INLINE int bucket_is_empty(hashtable_t *hashtable, bucket_t *bucket)
-{
-    return bucket->first == &hashtable->list && bucket->first == bucket->last;
-}
-
-static void insert_to_bucket(hashtable_t *hashtable, bucket_t *bucket,
-                             list_t *list)
-{
-    if(bucket_is_empty(hashtable, bucket))
-    {
-        list_insert(&hashtable->list, list);
-        bucket->first = bucket->last = list;
-    }
-    else
-    {
-        list_insert(bucket->first, list);
-        bucket->first = list;
-    }
-}
-
-static const size_t primes[] = {
-    5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
-    49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469,
-    12582917, 25165843, 50331653, 100663319, 201326611, 402653189,
-    805306457, 1610612741
-};
-
-static JSON_INLINE size_t num_buckets(hashtable_t *hashtable)
-{
-    return primes[hashtable->num_buckets];
-}
-
-
-static pair_t *hashtable_find_pair(hashtable_t *hashtable, bucket_t *bucket,
-                                   const char *key, size_t hash)
-{
-    list_t *list;
-    pair_t *pair;
-
-    if(bucket_is_empty(hashtable, bucket))
-        return NULL;
-
-    list = bucket->first;
-    while(1)
-    {
-        pair = list_to_pair(list);
-        if(pair->hash == hash && strcmp(pair->key, key) == 0)
-            return pair;
-
-        if(list == bucket->last)
-            break;
-
-        list = list->next;
-    }
-
-    return NULL;
-}
-
-/* returns 0 on success, -1 if key was not found */
-static int hashtable_do_del(hashtable_t *hashtable,
-                            const char *key, size_t hash)
-{
-    pair_t *pair;
-    bucket_t *bucket;
-    size_t index;
-
-    index = hash % num_buckets(hashtable);
-    bucket = &hashtable->buckets[index];
-
-    pair = hashtable_find_pair(hashtable, bucket, key, hash);
-    if(!pair)
-        return -1;
-
-    if(&pair->list == bucket->first && &pair->list == bucket->last)
-        bucket->first = bucket->last = &hashtable->list;
-
-    else if(&pair->list == bucket->first)
-        bucket->first = pair->list.next;
-
-    else if(&pair->list == bucket->last)
-        bucket->last = pair->list.prev;
-
-    list_remove(&pair->list);
-    json_decref(pair->value);
-
-    jsonp_free(pair);
-    hashtable->size--;
-
-    return 0;
-}
-
-static void hashtable_do_clear(hashtable_t *hashtable)
-{
-    list_t *list, *next;
-    pair_t *pair;
-
-    for(list = hashtable->list.next; list != &hashtable->list; list = next)
-    {
-        next = list->next;
-        pair = list_to_pair(list);
-        json_decref(pair->value);
-        jsonp_free(pair);
-    }
-}
-
-static int hashtable_do_rehash(hashtable_t *hashtable)
-{
-    list_t *list, *next;
-    pair_t *pair;
-    size_t i, index, new_size;
-
-    jsonp_free(hashtable->buckets);
-
-    hashtable->num_buckets++;
-    new_size = num_buckets(hashtable);
-
-    hashtable->buckets = jsonp_malloc(new_size * sizeof(bucket_t));
-    if(!hashtable->buckets)
-        return -1;
-
-    for(i = 0; i < num_buckets(hashtable); i++)
-    {
-        hashtable->buckets[i].first = hashtable->buckets[i].last =
-            &hashtable->list;
-    }
-
-    list = hashtable->list.next;
-    list_init(&hashtable->list);
-
-    for(; list != &hashtable->list; list = next) {
-        next = list->next;
-        pair = list_to_pair(list);
-        index = pair->hash % new_size;
-        insert_to_bucket(hashtable, &hashtable->buckets[index], &pair->list);
-    }
-
-    return 0;
-}
-
-
-int hashtable_init(hashtable_t *hashtable)
-{
-    size_t i;
-
-    hashtable->size = 0;
-    hashtable->num_buckets = 0;  /* index to primes[] */
-    hashtable->buckets = jsonp_malloc(num_buckets(hashtable) * sizeof(bucket_t));
-    if(!hashtable->buckets)
-        return -1;
-
-    list_init(&hashtable->list);
-
-    for(i = 0; i < num_buckets(hashtable); i++)
-    {
-        hashtable->buckets[i].first = hashtable->buckets[i].last =
-            &hashtable->list;
-    }
-
-    return 0;
-}
-
-void hashtable_close(hashtable_t *hashtable)
-{
-    hashtable_do_clear(hashtable);
-    jsonp_free(hashtable->buckets);
-}
-
-int hashtable_set(hashtable_t *hashtable,
-                  const char *key, size_t serial,
-                  json_t *value)
-{
-    pair_t *pair;
-    bucket_t *bucket;
-    size_t hash, index;
-
-    /* rehash if the load ratio exceeds 1 */
-    if(hashtable->size >= num_buckets(hashtable))
-        if(hashtable_do_rehash(hashtable))
-            return -1;
-
-    hash = hash_str(key);
-    index = hash % num_buckets(hashtable);
-    bucket = &hashtable->buckets[index];
-    pair = hashtable_find_pair(hashtable, bucket, key, hash);
-
-    if(pair)
-    {
-        json_decref(pair->value);
-        pair->value = value;
-    }
-    else
-    {
-        /* offsetof(...) returns the size of pair_t without the last,
-           flexible member. This way, the correct amount is
-           allocated. */
-
-        size_t len = strlen(key);
-        if(len >= (size_t)-1 - offsetof(pair_t, key)) {
-            /* Avoid an overflow if the key is very long */
-            return -1;
-        }
-
-        pair = jsonp_malloc(offsetof(pair_t, key) + len + 1);
-        if(!pair)
-            return -1;
-
-        pair->hash = hash;
-        pair->serial = serial;
-        strcpy(pair->key, key);
-        pair->value = value;
-        list_init(&pair->list);
-
-        insert_to_bucket(hashtable, bucket, &pair->list);
-
-        hashtable->size++;
-    }
-    return 0;
-}
-
-void *hashtable_get(hashtable_t *hashtable, const char *key)
-{
-    pair_t *pair;
-    size_t hash;
-    bucket_t *bucket;
-
-    hash = hash_str(key);
-    bucket = &hashtable->buckets[hash % num_buckets(hashtable)];
-
-    pair = hashtable_find_pair(hashtable, bucket, key, hash);
-    if(!pair)
-        return NULL;
-
-    return pair->value;
-}
-
-int hashtable_del(hashtable_t *hashtable, const char *key)
-{
-    size_t hash = hash_str(key);
-    return hashtable_do_del(hashtable, key, hash);
-}
-
-void hashtable_clear(hashtable_t *hashtable)
-{
-    size_t i;
-
-    hashtable_do_clear(hashtable);
-
-    for(i = 0; i < num_buckets(hashtable); i++)
-    {
-        hashtable->buckets[i].first = hashtable->buckets[i].last =
-            &hashtable->list;
-    }
-
-    list_init(&hashtable->list);
-    hashtable->size = 0;
-}
-
-void *hashtable_iter(hashtable_t *hashtable)
-{
-    return hashtable_iter_next(hashtable, &hashtable->list);
-}
-
-void *hashtable_iter_at(hashtable_t *hashtable, const char *key)
-{
-    pair_t *pair;
-    size_t hash;
-    bucket_t *bucket;
-
-    hash = hash_str(key);
-    bucket = &hashtable->buckets[hash % num_buckets(hashtable)];
-
-    pair = hashtable_find_pair(hashtable, bucket, key, hash);
-    if(!pair)
-        return NULL;
-
-    return &pair->list;
-}
-
-void *hashtable_iter_next(hashtable_t *hashtable, void *iter)
-{
-    list_t *list = (list_t *)iter;
-    if(list->next == &hashtable->list)
-        return NULL;
-    return list->next;
-}
-
-void *hashtable_iter_key(void *iter)
-{
-    pair_t *pair = list_to_pair((list_t *)iter);
-    return pair->key;
-}
-
-size_t hashtable_iter_serial(void *iter)
-{
-    pair_t *pair = list_to_pair((list_t *)iter);
-    return pair->serial;
-}
-
-void *hashtable_iter_value(void *iter)
-{
-    pair_t *pair = list_to_pair((list_t *)iter);
-    return pair->value;
-}
-
-void hashtable_iter_set(void *iter, json_t *value)
-{
-    pair_t *pair = list_to_pair((list_t *)iter);
-
-    json_decref(pair->value);
-    pair->value = value;
-}
diff --git a/deps/jansson/src/hashtable.h b/deps/jansson/src/hashtable.h
deleted file mode 100644
index 4a7ce6f..0000000
--- a/deps/jansson/src/hashtable.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef HASHTABLE_H
-#define HASHTABLE_H
-
-struct hashtable_list {
-    struct hashtable_list *prev;
-    struct hashtable_list *next;
-};
-
-/* "pair" may be a bit confusing a name, but think of it as a
-   key-value pair. In this case, it just encodes some extra data,
-   too */
-struct hashtable_pair {
-    size_t hash;
-    struct hashtable_list list;
-    json_t *value;
-    size_t serial;
-    char key[1];
-};
-
-struct hashtable_bucket {
-    struct hashtable_list *first;
-    struct hashtable_list *last;
-};
-
-typedef struct hashtable {
-    size_t size;
-    struct hashtable_bucket *buckets;
-    size_t num_buckets;  /* index to primes[] */
-    struct hashtable_list list;
-} hashtable_t;
-
-
-#define hashtable_key_to_iter(key_) \
-    (&(container_of(key_, struct hashtable_pair, key)->list))
-
-/**
- * hashtable_init - Initialize a hashtable object
- *
- * @hashtable: The (statically allocated) hashtable object
- *
- * Initializes a statically allocated hashtable object. The object
- * should be cleared with hashtable_close when it's no longer used.
- *
- * Returns 0 on success, -1 on error (out of memory).
- */
-int hashtable_init(hashtable_t *hashtable);
-
-/**
- * hashtable_close - Release all resources used by a hashtable object
- *
- * @hashtable: The hashtable
- *
- * Destroys a statically allocated hashtable object.
- */
-void hashtable_close(hashtable_t *hashtable);
-
-/**
- * hashtable_set - Add/modify value in hashtable
- *
- * @hashtable: The hashtable object
- * @key: The key
- * @serial: For addition order of keys
- * @value: The value
- *
- * If a value with the given key already exists, its value is replaced
- * with the new value. Value is "stealed" in the sense that hashtable
- * doesn't increment its refcount but decreases the refcount when the
- * value is no longer needed.
- *
- * Returns 0 on success, -1 on failure (out of memory).
- */
-int hashtable_set(hashtable_t *hashtable,
-                  const char *key, size_t serial,
-                  json_t *value);
-
-/**
- * hashtable_get - Get a value associated with a key
- *
- * @hashtable: The hashtable object
- * @key: The key
- *
- * Returns value if it is found, or NULL otherwise.
- */
-void *hashtable_get(hashtable_t *hashtable, const char *key);
-
-/**
- * hashtable_del - Remove a value from the hashtable
- *
- * @hashtable: The hashtable object
- * @key: The key
- *
- * Returns 0 on success, or -1 if the key was not found.
- */
-int hashtable_del(hashtable_t *hashtable, const char *key);
-
-/**
- * hashtable_clear - Clear hashtable
- *
- * @hashtable: The hashtable object
- *
- * Removes all items from the hashtable.
- */
-void hashtable_clear(hashtable_t *hashtable);
-
-/**
- * hashtable_iter - Iterate over hashtable
- *
- * @hashtable: The hashtable object
- *
- * Returns an opaque iterator to the first element in the hashtable.
- * The iterator should be passed to hashtable_iter_* functions.
- * The hashtable items are not iterated over in any particular order.
- *
- * There's no need to free the iterator in any way. The iterator is
- * valid as long as the item that is referenced by the iterator is not
- * deleted. Other values may be added or deleted. In particular,
- * hashtable_iter_next() may be called on an iterator, and after that
- * the key/value pair pointed by the old iterator may be deleted.
- */
-void *hashtable_iter(hashtable_t *hashtable);
-
-/**
- * hashtable_iter_at - Return an iterator at a specific key
- *
- * @hashtable: The hashtable object
- * @key: The key that the iterator should point to
- *
- * Like hashtable_iter() but returns an iterator pointing to a
- * specific key.
- */
-void *hashtable_iter_at(hashtable_t *hashtable, const char *key);
-
-/**
- * hashtable_iter_next - Advance an iterator
- *
- * @hashtable: The hashtable object
- * @iter: The iterator
- *
- * Returns a new iterator pointing to the next element in the
- * hashtable or NULL if the whole hastable has been iterated over.
- */
-void *hashtable_iter_next(hashtable_t *hashtable, void *iter);
-
-/**
- * hashtable_iter_key - Retrieve the key pointed by an iterator
- *
- * @iter: The iterator
- */
-void *hashtable_iter_key(void *iter);
-
-/**
- * hashtable_iter_serial - Retrieve the serial number pointed to by an iterator
- *
- * @iter: The iterator
- */
-size_t hashtable_iter_serial(void *iter);
-
-/**
- * hashtable_iter_value - Retrieve the value pointed by an iterator
- *
- * @iter: The iterator
- */
-void *hashtable_iter_value(void *iter);
-
-/**
- * hashtable_iter_set - Set the value pointed by an iterator
- *
- * @iter: The iterator
- * @value: The value to set
- */
-void hashtable_iter_set(void *iter, json_t *value);
-
-#endif
diff --git a/deps/jansson/src/jansson.def b/deps/jansson/src/jansson.def
deleted file mode 100644
index 3c7d6d1..0000000
--- a/deps/jansson/src/jansson.def
+++ /dev/null
@@ -1,68 +0,0 @@
-EXPORTS
-    json_delete
-    json_true
-    json_false
-    json_null
-    json_string
-    json_stringn
-    json_string_nocheck
-    json_stringn_nocheck
-    json_string_value
-    json_string_length
-    json_string_set
-    json_string_setn
-    json_string_set_nocheck
-    json_string_setn_nocheck
-    json_integer
-    json_integer_value
-    json_integer_set
-    json_real
-    json_real_value
-    json_real_set
-    json_number_value
-    json_array
-    json_array_size
-    json_array_get
-    json_array_set_new
-    json_array_append_new
-    json_array_insert_new
-    json_array_remove
-    json_array_clear
-    json_array_extend
-    json_object
-    json_object_size
-    json_object_get
-    json_object_set_new
-    json_object_set_new_nocheck
-    json_object_del
-    json_object_clear
-    json_object_update
-    json_object_update_existing
-    json_object_update_missing
-    json_object_iter
-    json_object_iter_at
-    json_object_iter_next
-    json_object_iter_key
-    json_object_iter_value
-    json_object_iter_set_new
-    json_object_key_to_iter
-    json_dumps
-    json_dumpf
-    json_dump_file
-    json_dump_callback
-    json_loads
-    json_loadb
-    json_loadf
-    json_load_file
-    json_load_callback
-    json_equal
-    json_copy
-    json_deep_copy
-    json_pack
-    json_pack_ex
-    json_vpack_ex
-    json_unpack
-    json_unpack_ex
-    json_vunpack_ex
-    json_set_alloc_funcs
-
diff --git a/deps/jansson/src/jansson.h b/deps/jansson/src/jansson.h
deleted file mode 100644
index c497598..0000000
--- a/deps/jansson/src/jansson.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef JANSSON_H
-#define JANSSON_H
-
-#include <stdio.h>
-#include <stdlib.h>  /* for size_t */
-#include <stdarg.h>
-
-#include <jansson_config.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* version */
-
-#define JANSSON_MAJOR_VERSION  2
-#define JANSSON_MINOR_VERSION  5
-#define JANSSON_MICRO_VERSION  0
-
-/* Micro version is omitted if it's 0 */
-#define JANSSON_VERSION  "2.5"
-
-/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this
-   for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */
-#define JANSSON_VERSION_HEX  ((JANSSON_MAJOR_VERSION << 16) |   \
-                              (JANSSON_MINOR_VERSION << 8)  |   \
-                              (JANSSON_MICRO_VERSION << 0))
-
-
-/* types */
-
-typedef enum {
-    JSON_OBJECT,
-    JSON_ARRAY,
-    JSON_STRING,
-    JSON_INTEGER,
-    JSON_REAL,
-    JSON_TRUE,
-    JSON_FALSE,
-    JSON_NULL
-} json_type;
-
-typedef struct json_t {
-    json_type type;
-    size_t refcount;
-} json_t;
-
-#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */
-#if JSON_INTEGER_IS_LONG_LONG
-#ifdef _WIN32
-#define JSON_INTEGER_FORMAT "I64d"
-#else
-#define JSON_INTEGER_FORMAT "lld"
-#endif
-typedef long long json_int_t;
-#else
-#define JSON_INTEGER_FORMAT "ld"
-typedef long json_int_t;
-#endif /* JSON_INTEGER_IS_LONG_LONG */
-#endif
-
-#define json_typeof(json)      ((json)->type)
-#define json_is_object(json)   ((json) && json_typeof(json) == JSON_OBJECT)
-#define json_is_array(json)    ((json) && json_typeof(json) == JSON_ARRAY)
-#define json_is_string(json)   ((json) && json_typeof(json) == JSON_STRING)
-#define json_is_integer(json)  ((json) && json_typeof(json) == JSON_INTEGER)
-#define json_is_real(json)     ((json) && json_typeof(json) == JSON_REAL)
-#define json_is_number(json)   (json_is_integer(json) || json_is_real(json))
-#define json_is_true(json)     ((json) && json_typeof(json) == JSON_TRUE)
-#define json_is_false(json)    ((json) && json_typeof(json) == JSON_FALSE)
-#define json_boolean_value     json_is_true
-#define json_is_boolean(json)  (json_is_true(json) || json_is_false(json))
-#define json_is_null(json)     ((json) && json_typeof(json) == JSON_NULL)
-
-/* construction, destruction, reference counting */
-
-json_t *json_object(void);
-json_t *json_array(void);
-json_t *json_string(const char *value);
-json_t *json_stringn(const char *value, size_t len);
-json_t *json_string_nocheck(const char *value);
-json_t *json_stringn_nocheck(const char *value, size_t len);
-json_t *json_integer(json_int_t value);
-json_t *json_real(double value);
-json_t *json_true(void);
-json_t *json_false(void);
-#define json_boolean(val)      ((val) ? json_true() : json_false())
-json_t *json_null(void);
-
-static JSON_INLINE
-json_t *json_incref(json_t *json)
-{
-    if(json && json->refcount != (size_t)-1)
-        ++json->refcount;
-    return json;
-}
-
-/* do not call json_delete directly */
-void json_delete(json_t *json);
-
-static JSON_INLINE
-void json_decref(json_t *json)
-{
-    if(json && json->refcount != (size_t)-1 && --json->refcount == 0)
-        json_delete(json);
-}
-
-
-/* error reporting */
-
-#define JSON_ERROR_TEXT_LENGTH    160
-#define JSON_ERROR_SOURCE_LENGTH   80
-
-typedef struct {
-    int line;
-    int column;
-    int position;
-    char source[JSON_ERROR_SOURCE_LENGTH];
-    char text[JSON_ERROR_TEXT_LENGTH];
-} json_error_t;
-
-
-/* getters, setters, manipulation */
-
-size_t json_object_size(const json_t *object);
-json_t *json_object_get(const json_t *object, const char *key);
-int json_object_set_new(json_t *object, const char *key, json_t *value);
-int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value);
-int json_object_del(json_t *object, const char *key);
-int json_object_clear(json_t *object);
-int json_object_update(json_t *object, json_t *other);
-int json_object_update_existing(json_t *object, json_t *other);
-int json_object_update_missing(json_t *object, json_t *other);
-void *json_object_iter(json_t *object);
-void *json_object_iter_at(json_t *object, const char *key);
-void *json_object_key_to_iter(const char *key);
-void *json_object_iter_next(json_t *object, void *iter);
-const char *json_object_iter_key(void *iter);
-json_t *json_object_iter_value(void *iter);
-int json_object_iter_set_new(json_t *object, void *iter, json_t *value);
-
-#define json_object_foreach(object, key, value) \
-    for(key = json_object_iter_key(json_object_iter(object)); \
-        key && (value = json_object_iter_value(json_object_key_to_iter(key))); \
-        key = json_object_iter_key(json_object_iter_next(object, json_object_key_to_iter(key))))
-
-#define json_array_foreach(array, index, value) \
-	for(index = 0; \
-		index < json_array_size(array) && (value = json_array_get(array, index)); \
-		index++)
-
-static JSON_INLINE
-int json_object_set(json_t *object, const char *key, json_t *value)
-{
-    return json_object_set_new(object, key, json_incref(value));
-}
-
-static JSON_INLINE
-int json_object_set_nocheck(json_t *object, const char *key, json_t *value)
-{
-    return json_object_set_new_nocheck(object, key, json_incref(value));
-}
-
-static JSON_INLINE
-int json_object_iter_set(json_t *object, void *iter, json_t *value)
-{
-    return json_object_iter_set_new(object, iter, json_incref(value));
-}
-
-size_t json_array_size(const json_t *array);
-json_t *json_array_get(const json_t *array, size_t index);
-int json_array_set_new(json_t *array, size_t index, json_t *value);
-int json_array_append_new(json_t *array, json_t *value);
-int json_array_insert_new(json_t *array, size_t index, json_t *value);
-int json_array_remove(json_t *array, size_t index);
-int json_array_clear(json_t *array);
-int json_array_extend(json_t *array, json_t *other);
-
-static JSON_INLINE
-int json_array_set(json_t *array, size_t ind, json_t *value)
-{
-    return json_array_set_new(array, ind, json_incref(value));
-}
-
-static JSON_INLINE
-int json_array_append(json_t *array, json_t *value)
-{
-    return json_array_append_new(array, json_incref(value));
-}
-
-static JSON_INLINE
-int json_array_insert(json_t *array, size_t ind, json_t *value)
-{
-    return json_array_insert_new(array, ind, json_incref(value));
-}
-
-const char *json_string_value(const json_t *string);
-size_t json_string_length(const json_t *string);
-json_int_t json_integer_value(const json_t *integer);
-double json_real_value(const json_t *real);
-double json_number_value(const json_t *json);
-
-int json_string_set(json_t *string, const char *value);
-int json_string_setn(json_t *string, const char *value, size_t len);
-int json_string_set_nocheck(json_t *string, const char *value);
-int json_string_setn_nocheck(json_t *string, const char *value, size_t len);
-int json_integer_set(json_t *integer, json_int_t value);
-int json_real_set(json_t *real, double value);
-
-/* pack, unpack */
-
-json_t *json_pack(const char *fmt, ...);
-json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...);
-json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap);
-
-#define JSON_VALIDATE_ONLY  0x1
-#define JSON_STRICT         0x2
-
-int json_unpack(json_t *root, const char *fmt, ...);
-int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...);
-int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, va_list ap);
-
-
-/* equality */
-
-int json_equal(json_t *value1, json_t *value2);
-
-
-/* copying */
-
-json_t *json_copy(json_t *value);
-json_t *json_deep_copy(const json_t *value);
-
-
-/* decoding */
-
-#define JSON_REJECT_DUPLICATES  0x1
-#define JSON_DISABLE_EOF_CHECK  0x2
-#define JSON_DECODE_ANY         0x4
-#define JSON_DECODE_INT_AS_REAL 0x8
-#define JSON_ALLOW_NUL          0x10
-
-typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data);
-
-json_t *json_loads(const char *input, size_t flags, json_error_t *error);
-json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error);
-json_t *json_loadf(FILE *input, size_t flags, json_error_t *error);
-json_t *json_load_file(const char *path, size_t flags, json_error_t *error);
-json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error);
-
-
-/* encoding */
-
-#define JSON_INDENT(n)      (n & 0x1F)
-#define JSON_COMPACT        0x20
-#define JSON_ENSURE_ASCII   0x40
-#define JSON_SORT_KEYS      0x80
-#define JSON_PRESERVE_ORDER 0x100
-#define JSON_ENCODE_ANY     0x200
-#define JSON_ESCAPE_SLASH   0x400
-
-typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data);
-
-char *json_dumps(const json_t *json, size_t flags);
-int json_dumpf(const json_t *json, FILE *output, size_t flags);
-int json_dump_file(const json_t *json, const char *path, size_t flags);
-int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags);
-
-/* custom memory allocation */
-
-typedef void *(*json_malloc_t)(size_t);
-typedef void (*json_free_t)(void *);
-
-void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/deps/jansson/src/jansson_config.h.in b/deps/jansson/src/jansson_config.h.in
deleted file mode 100644
index 785801f..0000000
--- a/deps/jansson/src/jansson_config.h.in
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2010-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- *
- *
- * This file specifies a part of the site-specific configuration for
- * Jansson, namely those things that affect the public API in
- * jansson.h.
- *
- * The configure script copies this file to jansson_config.h and
- * replaces @var@ substitutions by values that fit your system. If you
- * cannot run the configure script, you can do the value substitution
- * by hand.
- */
-
-#ifndef JANSSON_CONFIG_H
-#define JANSSON_CONFIG_H
-
-/* If your compiler supports the inline keyword in C, JSON_INLINE is
-   defined to `inline', otherwise empty. In C++, the inline is always
-   supported. */
-#ifdef __cplusplus
-#define JSON_INLINE inline
-#else
-#define JSON_INLINE @json_inline@
-#endif
-
-/* If your compiler supports the `long long` type and the strtoll()
-   library function, JSON_INTEGER_IS_LONG_LONG is defined to 1,
-   otherwise to 0. */
-#define JSON_INTEGER_IS_LONG_LONG @json_have_long_long@
-
-/* If locale.h and localeconv() are available, define to 1,
-   otherwise to 0. */
-#define JSON_HAVE_LOCALECONV @json_have_localeconv@
-
-#endif
diff --git a/deps/jansson/src/jansson_private.h b/deps/jansson/src/jansson_private.h
deleted file mode 100644
index eb51d0d..0000000
--- a/deps/jansson/src/jansson_private.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef JANSSON_PRIVATE_H
-#define JANSSON_PRIVATE_H
-
-#include <stddef.h>
-#include "jansson.h"
-#include "hashtable.h"
-#include "strbuffer.h"
-
-#define container_of(ptr_, type_, member_)  \
-    ((type_ *)((char *)ptr_ - offsetof(type_, member_)))
-
-/* On some platforms, max() may already be defined */
-#ifndef max
-#define max(a, b)  ((a) > (b) ? (a) : (b))
-#endif
-
-/* va_copy is a C99 feature. In C89 implementations, it's sometimes
-   available as __va_copy. If not, memcpy() should do the trick. */
-#ifndef va_copy
-#ifdef __va_copy
-#define va_copy __va_copy
-#else
-#define va_copy(a, b)  memcpy(&(a), &(b), sizeof(va_list))
-#endif
-#endif
-
-typedef struct {
-    json_t json;
-    hashtable_t hashtable;
-    size_t serial;
-    int visited;
-} json_object_t;
-
-typedef struct {
-    json_t json;
-    size_t size;
-    size_t entries;
-    json_t **table;
-    int visited;
-} json_array_t;
-
-typedef struct {
-    json_t json;
-    char *value;
-    size_t length;
-} json_string_t;
-
-typedef struct {
-    json_t json;
-    double value;
-} json_real_t;
-
-typedef struct {
-    json_t json;
-    json_int_t value;
-} json_integer_t;
-
-#define json_to_object(json_)  container_of(json_, json_object_t, json)
-#define json_to_array(json_)   container_of(json_, json_array_t, json)
-#define json_to_string(json_)  container_of(json_, json_string_t, json)
-#define json_to_real(json_)    container_of(json_, json_real_t, json)
-#define json_to_integer(json_) container_of(json_, json_integer_t, json)
-
-/* Create a string by taking ownership of an existing buffer */
-json_t *jsonp_stringn_nocheck_own(const char *value, size_t len);
-
-/* Error message formatting */
-void jsonp_error_init(json_error_t *error, const char *source);
-void jsonp_error_set_source(json_error_t *error, const char *source);
-void jsonp_error_set(json_error_t *error, int line, int column,
-                     size_t position, const char *msg, ...);
-void jsonp_error_vset(json_error_t *error, int line, int column,
-                      size_t position, const char *msg, va_list ap);
-
-/* Locale independent string<->double conversions */
-int jsonp_strtod(strbuffer_t *strbuffer, double *out);
-int jsonp_dtostr(char *buffer, size_t size, double value);
-
-/* Wrappers for custom memory functions */
-void* jsonp_malloc(size_t size);
-void jsonp_free(void *ptr);
-char *jsonp_strndup(const char *str, size_t length);
-char *jsonp_strdup(const char *str);
-char *jsonp_strndup(const char *str, size_t len);
-
-/* Windows compatibility */
-#ifdef _WIN32
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#endif
-
-#endif
diff --git a/deps/jansson/src/load.c b/deps/jansson/src/load.c
deleted file mode 100644
index 5d0d1ef..0000000
--- a/deps/jansson/src/load.c
+++ /dev/null
@@ -1,1105 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "jansson.h"
-#include "jansson_private.h"
-#include "strbuffer.h"
-#include "utf.h"
-
-#define STREAM_STATE_OK        0
-#define STREAM_STATE_EOF      -1
-#define STREAM_STATE_ERROR    -2
-
-#define TOKEN_INVALID         -1
-#define TOKEN_EOF              0
-#define TOKEN_STRING         256
-#define TOKEN_INTEGER        257
-#define TOKEN_REAL           258
-#define TOKEN_TRUE           259
-#define TOKEN_FALSE          260
-#define TOKEN_NULL           261
-
-/* Locale independent versions of isxxx() functions */
-#define l_isupper(c)  ('A' <= (c) && (c) <= 'Z')
-#define l_islower(c)  ('a' <= (c) && (c) <= 'z')
-#define l_isalpha(c)  (l_isupper(c) || l_islower(c))
-#define l_isdigit(c)  ('0' <= (c) && (c) <= '9')
-#define l_isxdigit(c) \
-    (l_isdigit(c) || ('A' <= (c) && (c) <= 'F') || ('a' <= (c) && (c) <= 'f'))
-
-/* Read one byte from stream, convert to unsigned char, then int, and
-   return. return EOF on end of file. This corresponds to the
-   behaviour of fgetc(). */
-typedef int (*get_func)(void *data);
-
-typedef struct {
-    get_func get;
-    void *data;
-    char buffer[5];
-    size_t buffer_pos;
-    int state;
-    int line;
-    int column, last_column;
-    size_t position;
-} stream_t;
-
-typedef struct {
-    stream_t stream;
-    strbuffer_t saved_text;
-    int token;
-    union {
-        struct {
-            char *val;
-            size_t len;
-        } string;
-        json_int_t integer;
-        double real;
-    } value;
-} lex_t;
-
-#define stream_to_lex(stream) container_of(stream, lex_t, stream)
-
-
-/*** error reporting ***/
-
-static void error_set(json_error_t *error, const lex_t *lex,
-                      const char *msg, ...)
-{
-    va_list ap;
-    char msg_text[JSON_ERROR_TEXT_LENGTH];
-    char msg_with_context[JSON_ERROR_TEXT_LENGTH];
-
-    int line = -1, col = -1;
-    size_t pos = 0;
-    const char *result = msg_text;
-
-    if(!error)
-        return;
-
-    va_start(ap, msg);
-    vsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap);
-    msg_text[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
-    va_end(ap);
-
-    if(lex)
-    {
-        const char *saved_text = strbuffer_value(&lex->saved_text);
-
-        line = lex->stream.line;
-        col = lex->stream.column;
-        pos = lex->stream.position;
-
-        if(saved_text && saved_text[0])
-        {
-            if(lex->saved_text.length <= 20) {
-                snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
-                         "%s near '%s'", msg_text, saved_text);
-                msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
-                result = msg_with_context;
-            }
-        }
-        else
-        {
-            if(lex->stream.state == STREAM_STATE_ERROR) {
-                /* No context for UTF-8 decoding errors */
-                result = msg_text;
-            }
-            else {
-                snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
-                         "%s near end of file", msg_text);
-                msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
-                result = msg_with_context;
-            }
-        }
-    }
-
-    jsonp_error_set(error, line, col, pos, "%s", result);
-}
-
-
-/*** lexical analyzer ***/
-
-static void
-stream_init(stream_t *stream, get_func get, void *data)
-{
-    stream->get = get;
-    stream->data = data;
-    stream->buffer[0] = '\0';
-    stream->buffer_pos = 0;
-
-    stream->state = STREAM_STATE_OK;
-    stream->line = 1;
-    stream->column = 0;
-    stream->position = 0;
-}
-
-static int stream_get(stream_t *stream, json_error_t *error)
-{
-    int c;
-
-    if(stream->state != STREAM_STATE_OK)
-        return stream->state;
-
-    if(!stream->buffer[stream->buffer_pos])
-    {
-        c = stream->get(stream->data);
-        if(c == EOF) {
-            stream->state = STREAM_STATE_EOF;
-            return STREAM_STATE_EOF;
-        }
-
-        stream->buffer[0] = c;
-        stream->buffer_pos = 0;
-
-        if(0x80 <= c && c <= 0xFF)
-        {
-            /* multi-byte UTF-8 sequence */
-            int i, count;
-
-            count = (int)utf8_check_first(c);
-            if(!count)
-                goto out;
-
-            assert(count >= 2);
-
-            for(i = 1; i < count; i++)
-                stream->buffer[i] = stream->get(stream->data);
-
-            if(!utf8_check_full(stream->buffer, count, NULL))
-                goto out;
-
-            stream->buffer[count] = '\0';
-        }
-        else
-            stream->buffer[1] = '\0';
-    }
-
-    c = stream->buffer[stream->buffer_pos++];
-
-    stream->position++;
-    if(c == '\n') {
-        stream->line++;
-        stream->last_column = stream->column;
-        stream->column = 0;
-    }
-    else if(utf8_check_first(c)) {
-        /* track the Unicode character column, so increment only if
-           this is the first character of a UTF-8 sequence */
-        stream->column++;
-    }
-
-    return c;
-
-out:
-    stream->state = STREAM_STATE_ERROR;
-    error_set(error, stream_to_lex(stream), "unable to decode byte 0x%x", c);
-    return STREAM_STATE_ERROR;
-}
-
-static void stream_unget(stream_t *stream, int c)
-{
-    if(c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR)
-        return;
-
-    stream->position--;
-    if(c == '\n') {
-        stream->line--;
-        stream->column = stream->last_column;
-    }
-    else if(utf8_check_first(c))
-        stream->column--;
-
-    assert(stream->buffer_pos > 0);
-    stream->buffer_pos--;
-    assert(stream->buffer[stream->buffer_pos] == c);
-}
-
-
-static int lex_get(lex_t *lex, json_error_t *error)
-{
-    return stream_get(&lex->stream, error);
-}
-
-static void lex_save(lex_t *lex, int c)
-{
-    strbuffer_append_byte(&lex->saved_text, c);
-}
-
-static int lex_get_save(lex_t *lex, json_error_t *error)
-{
-    int c = stream_get(&lex->stream, error);
-    if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR)
-        lex_save(lex, c);
-    return c;
-}
-
-static void lex_unget(lex_t *lex, int c)
-{
-    stream_unget(&lex->stream, c);
-}
-
-static void lex_unget_unsave(lex_t *lex, int c)
-{
-    if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) {
-        /* Since we treat warnings as errors, when assertions are turned
-         * off the "d" variable would be set but never used. Which is
-         * treated as an error by GCC.
-         */
-        #ifndef NDEBUG
-        char d;
-        #endif
-        stream_unget(&lex->stream, c);
-        #ifndef NDEBUG
-        d = 
-        #endif
-            strbuffer_pop(&lex->saved_text);
-        assert(c == d);
-    }
-}
-
-static void lex_save_cached(lex_t *lex)
-{
-    while(lex->stream.buffer[lex->stream.buffer_pos] != '\0')
-    {
-        lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]);
-        lex->stream.buffer_pos++;
-        lex->stream.position++;
-    }
-}
-
-static void lex_free_string(lex_t *lex)
-{
-    jsonp_free(lex->value.string.val);
-    lex->value.string.val = NULL;
-    lex->value.string.len = 0;
-}
-
-/* assumes that str points to 'u' plus at least 4 valid hex digits */
-static int32_t decode_unicode_escape(const char *str)
-{
-    int i;
-    int32_t value = 0;
-
-    assert(str[0] == 'u');
-
-    for(i = 1; i <= 4; i++) {
-        char c = str[i];
-        value <<= 4;
-        if(l_isdigit(c))
-            value += c - '0';
-        else if(l_islower(c))
-            value += c - 'a' + 10;
-        else if(l_isupper(c))
-            value += c - 'A' + 10;
-        else
-            return -1;
-    }
-
-    return value;
-}
-
-static void lex_scan_string(lex_t *lex, json_error_t *error)
-{
-    int c;
-    const char *p;
-    char *t;
-    int i;
-
-    lex->value.string.val = NULL;
-    lex->token = TOKEN_INVALID;
-
-    c = lex_get_save(lex, error);
-
-    while(c != '"') {
-        if(c == STREAM_STATE_ERROR)
-            goto out;
-
-        else if(c == STREAM_STATE_EOF) {
-            error_set(error, lex, "premature end of input");
-            goto out;
-        }
-
-        else if(0 <= c && c <= 0x1F) {
-            /* control character */
-            lex_unget_unsave(lex, c);
-            if(c == '\n')
-                error_set(error, lex, "unexpected newline", c);
-            else
-                error_set(error, lex, "control character 0x%x", c);
-            goto out;
-        }
-
-        else if(c == '\\') {
-            c = lex_get_save(lex, error);
-            if(c == 'u') {
-                c = lex_get_save(lex, error);
-                for(i = 0; i < 4; i++) {
-                    if(!l_isxdigit(c)) {
-                        error_set(error, lex, "invalid escape");
-                        goto out;
-                    }
-                    c = lex_get_save(lex, error);
-                }
-            }
-            else if(c == '"' || c == '\\' || c == '/' || c == 'b' ||
-                    c == 'f' || c == 'n' || c == 'r' || c == 't')
-                c = lex_get_save(lex, error);
-            else {
-                error_set(error, lex, "invalid escape");
-                goto out;
-            }
-        }
-        else
-            c = lex_get_save(lex, error);
-    }
-
-    /* the actual value is at most of the same length as the source
-       string, because:
-         - shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte
-         - a single \uXXXX escape (length 6) is converted to at most 3 bytes
-         - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair
-           are converted to 4 bytes
-    */
-    t = jsonp_malloc(lex->saved_text.length + 1);
-    if(!t) {
-        /* this is not very nice, since TOKEN_INVALID is returned */
-        goto out;
-    }
-    lex->value.string.val = t;
-
-    /* + 1 to skip the " */
-    p = strbuffer_value(&lex->saved_text) + 1;
-
-    while(*p != '"') {
-        if(*p == '\\') {
-            p++;
-            if(*p == 'u') {
-                size_t length;
-                int32_t value;
-
-                value = decode_unicode_escape(p);
-                if(value < 0) {
-                    error_set(error, lex, "invalid Unicode escape '%.6s'", p - 1);
-                    goto out;
-                }
-                p += 5;
-
-                if(0xD800 <= value && value <= 0xDBFF) {
-                    /* surrogate pair */
-                    if(*p == '\\' && *(p + 1) == 'u') {
-                        int32_t value2 = decode_unicode_escape(++p);
-                        if(value2 < 0) {
-                            error_set(error, lex, "invalid Unicode escape '%.6s'", p - 1);
-                            goto out;
-                        }
-                        p += 5;
-
-                        if(0xDC00 <= value2 && value2 <= 0xDFFF) {
-                            /* valid second surrogate */
-                            value =
-                                ((value - 0xD800) << 10) +
-                                (value2 - 0xDC00) +
-                                0x10000;
-                        }
-                        else {
-                            /* invalid second surrogate */
-                            error_set(error, lex,
-                                      "invalid Unicode '\\u%04X\\u%04X'",
-                                      value, value2);
-                            goto out;
-                        }
-                    }
-                    else {
-                        /* no second surrogate */
-                        error_set(error, lex, "invalid Unicode '\\u%04X'",
-                                  value);
-                        goto out;
-                    }
-                }
-                else if(0xDC00 <= value && value <= 0xDFFF) {
-                    error_set(error, lex, "invalid Unicode '\\u%04X'", value);
-                    goto out;
-                }
-
-                if(utf8_encode(value, t, &length))
-                    assert(0);
-                t += length;
-            }
-            else {
-                switch(*p) {
-                    case '"': case '\\': case '/':
-                        *t = *p; break;
-                    case 'b': *t = '\b'; break;
-                    case 'f': *t = '\f'; break;
-                    case 'n': *t = '\n'; break;
-                    case 'r': *t = '\r'; break;
-                    case 't': *t = '\t'; break;
-                    default: assert(0);
-                }
-                t++;
-                p++;
-            }
-        }
-        else
-            *(t++) = *(p++);
-    }
-    *t = '\0';
-    lex->value.string.len = t - lex->value.string.val;
-    lex->token = TOKEN_STRING;
-    return;
-
-out:
-    lex_free_string(lex);
-}
-
-#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */
-#if JSON_INTEGER_IS_LONG_LONG
-#ifdef _MSC_VER  /* Microsoft Visual Studio */
-#define json_strtoint     _strtoi64
-#else
-#define json_strtoint     strtoll
-#endif
-#else
-#define json_strtoint     strtol
-#endif
-#endif
-
-static int lex_scan_number(lex_t *lex, int c, json_error_t *error)
-{
-    const char *saved_text;
-    char *end;
-    double value;
-
-    lex->token = TOKEN_INVALID;
-
-    if(c == '-')
-        c = lex_get_save(lex, error);
-
-    if(c == '0') {
-        c = lex_get_save(lex, error);
-        if(l_isdigit(c)) {
-            lex_unget_unsave(lex, c);
-            goto out;
-        }
-    }
-    else if(l_isdigit(c)) {
-        c = lex_get_save(lex, error);
-        while(l_isdigit(c))
-            c = lex_get_save(lex, error);
-    }
-    else {
-        lex_unget_unsave(lex, c);
-        goto out;
-    }
-
-    if(c != '.' && c != 'E' && c != 'e') {
-        json_int_t value;
-
-        lex_unget_unsave(lex, c);
-
-        saved_text = strbuffer_value(&lex->saved_text);
-
-        errno = 0;
-        value = json_strtoint(saved_text, &end, 10);
-        if(errno == ERANGE) {
-            if(value < 0)
-                error_set(error, lex, "too big negative integer");
-            else
-                error_set(error, lex, "too big integer");
-            goto out;
-        }
-
-        assert(end == saved_text + lex->saved_text.length);
-
-        lex->token = TOKEN_INTEGER;
-        lex->value.integer = value;
-        return 0;
-    }
-
-    if(c == '.') {
-        c = lex_get(lex, error);
-        if(!l_isdigit(c)) {
-            lex_unget(lex, c);
-            goto out;
-        }
-        lex_save(lex, c);
-
-        c = lex_get_save(lex, error);
-        while(l_isdigit(c))
-            c = lex_get_save(lex, error);
-    }
-
-    if(c == 'E' || c == 'e') {
-        c = lex_get_save(lex, error);
-        if(c == '+' || c == '-')
-            c = lex_get_save(lex, error);
-
-        if(!l_isdigit(c)) {
-            lex_unget_unsave(lex, c);
-            goto out;
-        }
-
-        c = lex_get_save(lex, error);
-        while(l_isdigit(c))
-            c = lex_get_save(lex, error);
-    }
-
-    lex_unget_unsave(lex, c);
-
-    if(jsonp_strtod(&lex->saved_text, &value)) {
-        error_set(error, lex, "real number overflow");
-        goto out;
-    }
-
-    lex->token = TOKEN_REAL;
-    lex->value.real = value;
-    return 0;
-
-out:
-    return -1;
-}
-
-static int lex_scan(lex_t *lex, json_error_t *error)
-{
-    int c;
-
-    strbuffer_clear(&lex->saved_text);
-
-    if(lex->token == TOKEN_STRING)
-        lex_free_string(lex);
-
-    c = lex_get(lex, error);
-    while(c == ' ' || c == '\t' || c == '\n' || c == '\r')
-        c = lex_get(lex, error);
-
-    if(c == STREAM_STATE_EOF) {
-        lex->token = TOKEN_EOF;
-        goto out;
-    }
-
-    if(c == STREAM_STATE_ERROR) {
-        lex->token = TOKEN_INVALID;
-        goto out;
-    }
-
-    lex_save(lex, c);
-
-    if(c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',')
-        lex->token = c;
-
-    else if(c == '"')
-        lex_scan_string(lex, error);
-
-    else if(l_isdigit(c) || c == '-') {
-        if(lex_scan_number(lex, c, error))
-            goto out;
-    }
-
-    else if(l_isalpha(c)) {
-        /* eat up the whole identifier for clearer error messages */
-        const char *saved_text;
-
-        c = lex_get_save(lex, error);
-        while(l_isalpha(c))
-            c = lex_get_save(lex, error);
-        lex_unget_unsave(lex, c);
-
-        saved_text = strbuffer_value(&lex->saved_text);
-
-        if(strcmp(saved_text, "true") == 0)
-            lex->token = TOKEN_TRUE;
-        else if(strcmp(saved_text, "false") == 0)
-            lex->token = TOKEN_FALSE;
-        else if(strcmp(saved_text, "null") == 0)
-            lex->token = TOKEN_NULL;
-        else
-            lex->token = TOKEN_INVALID;
-    }
-
-    else {
-        /* save the rest of the input UTF-8 sequence to get an error
-           message of valid UTF-8 */
-        lex_save_cached(lex);
-        lex->token = TOKEN_INVALID;
-    }
-
-out:
-    return lex->token;
-}
-
-static char *lex_steal_string(lex_t *lex, size_t *out_len)
-{
-    char *result = NULL;
-    if(lex->token == TOKEN_STRING) {
-        result = lex->value.string.val;
-        *out_len = lex->value.string.len;
-        lex->value.string.val = NULL;
-        lex->value.string.len = 0;
-    }
-    return result;
-}
-
-static int lex_init(lex_t *lex, get_func get, void *data)
-{
-    stream_init(&lex->stream, get, data);
-    if(strbuffer_init(&lex->saved_text))
-        return -1;
-
-    lex->token = TOKEN_INVALID;
-    return 0;
-}
-
-static void lex_close(lex_t *lex)
-{
-    if(lex->token == TOKEN_STRING)
-        lex_free_string(lex);
-    strbuffer_close(&lex->saved_text);
-}
-
-
-/*** parser ***/
-
-static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error);
-
-static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error)
-{
-    json_t *object = json_object();
-    if(!object)
-        return NULL;
-
-    lex_scan(lex, error);
-    if(lex->token == '}')
-        return object;
-
-    while(1) {
-        char *key;
-        size_t len;
-        json_t *value;
-
-        if(lex->token != TOKEN_STRING) {
-            error_set(error, lex, "string or '}' expected");
-            goto error;
-        }
-
-        key = lex_steal_string(lex, &len);
-        if(!key)
-            return NULL;
-        if (memchr(key, '\0', len)) {
-            jsonp_free(key);
-            error_set(error, lex, "NUL byte in object key not supported");
-            goto error;
-        }
-
-        if(flags & JSON_REJECT_DUPLICATES) {
-            if(json_object_get(object, key)) {
-                jsonp_free(key);
-                error_set(error, lex, "duplicate object key");
-                goto error;
-            }
-        }
-
-        lex_scan(lex, error);
-        if(lex->token != ':') {
-            jsonp_free(key);
-            error_set(error, lex, "':' expected");
-            goto error;
-        }
-
-        lex_scan(lex, error);
-        value = parse_value(lex, flags, error);
-        if(!value) {
-            jsonp_free(key);
-            goto error;
-        }
-
-        if(json_object_set_nocheck(object, key, value)) {
-            jsonp_free(key);
-            json_decref(value);
-            goto error;
-        }
-
-        json_decref(value);
-        jsonp_free(key);
-
-        lex_scan(lex, error);
-        if(lex->token != ',')
-            break;
-
-        lex_scan(lex, error);
-    }
-
-    if(lex->token != '}') {
-        error_set(error, lex, "'}' expected");
-        goto error;
-    }
-
-    return object;
-
-error:
-    json_decref(object);
-    return NULL;
-}
-
-static json_t *parse_array(lex_t *lex, size_t flags, json_error_t *error)
-{
-    json_t *array = json_array();
-    if(!array)
-        return NULL;
-
-    lex_scan(lex, error);
-    if(lex->token == ']')
-        return array;
-
-    while(lex->token) {
-        json_t *elem = parse_value(lex, flags, error);
-        if(!elem)
-            goto error;
-
-        if(json_array_append(array, elem)) {
-            json_decref(elem);
-            goto error;
-        }
-        json_decref(elem);
-
-        lex_scan(lex, error);
-        if(lex->token != ',')
-            break;
-
-        lex_scan(lex, error);
-    }
-
-    if(lex->token != ']') {
-        error_set(error, lex, "']' expected");
-        goto error;
-    }
-
-    return array;
-
-error:
-    json_decref(array);
-    return NULL;
-}
-
-static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
-{
-    json_t *json;
-    double value;
-
-    switch(lex->token) {
-        case TOKEN_STRING: {
-            const char *value = lex->value.string.val;
-            size_t len = lex->value.string.len;
-
-            if(!(flags & JSON_ALLOW_NUL)) {
-                if(memchr(value, '\0', len)) {
-                    error_set(error, lex, "\\u0000 is not allowed without JSON_ALLOW_NUL");
-                    return NULL;
-                }
-            }
-
-            json = jsonp_stringn_nocheck_own(value, len);
-            if(json) {
-                lex->value.string.val = NULL;
-                lex->value.string.len = 0;
-            }
-            break;
-        }
-
-        case TOKEN_INTEGER: {
-            if (flags & JSON_DECODE_INT_AS_REAL) {
-                if(jsonp_strtod(&lex->saved_text, &value)) {
-                    error_set(error, lex, "real number overflow");
-                    return NULL;
-                }
-                json = json_real(value);
-            } else {
-                json = json_integer(lex->value.integer);
-            }
-            break;
-        }
-
-        case TOKEN_REAL: {
-            json = json_real(lex->value.real);
-            break;
-        }
-
-        case TOKEN_TRUE:
-            json = json_true();
-            break;
-
-        case TOKEN_FALSE:
-            json = json_false();
-            break;
-
-        case TOKEN_NULL:
-            json = json_null();
-            break;
-
-        case '{':
-            json = parse_object(lex, flags, error);
-            break;
-
-        case '[':
-            json = parse_array(lex, flags, error);
-            break;
-
-        case TOKEN_INVALID:
-            error_set(error, lex, "invalid token");
-            return NULL;
-
-        default:
-            error_set(error, lex, "unexpected token");
-            return NULL;
-    }
-
-    if(!json)
-        return NULL;
-
-    return json;
-}
-
-static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error)
-{
-    json_t *result;
-
-    lex_scan(lex, error);
-    if(!(flags & JSON_DECODE_ANY)) {
-        if(lex->token != '[' && lex->token != '{') {
-            error_set(error, lex, "'[' or '{' expected");
-            return NULL;
-        }
-    }
-
-    result = parse_value(lex, flags, error);
-    if(!result)
-        return NULL;
-
-    if(!(flags & JSON_DISABLE_EOF_CHECK)) {
-        lex_scan(lex, error);
-        if(lex->token != TOKEN_EOF) {
-            error_set(error, lex, "end of file expected");
-            json_decref(result);
-            return NULL;
-        }
-    }
-
-    if(error) {
-        /* Save the position even though there was no error */
-        error->position = (int)lex->stream.position;
-    }
-
-    return result;
-}
-
-typedef struct
-{
-    const char *data;
-    int pos;
-} string_data_t;
-
-static int string_get(void *data)
-{
-    char c;
-    string_data_t *stream = (string_data_t *)data;
-    c = stream->data[stream->pos];
-    if(c == '\0')
-        return EOF;
-    else
-    {
-        stream->pos++;
-        return (unsigned char)c;
-    }
-}
-
-json_t *json_loads(const char *string, size_t flags, json_error_t *error)
-{
-    lex_t lex;
-    json_t *result;
-    string_data_t stream_data;
-
-    jsonp_error_init(error, "<string>");
-
-    if (string == NULL) {
-        error_set(error, NULL, "wrong arguments");
-        return NULL;
-    }
-
-    stream_data.data = string;
-    stream_data.pos = 0;
-
-    if(lex_init(&lex, string_get, (void *)&stream_data))
-        return NULL;
-
-    result = parse_json(&lex, flags, error);
-
-    lex_close(&lex);
-    return result;
-}
-
-typedef struct
-{
-    const char *data;
-    size_t len;
-    size_t pos;
-} buffer_data_t;
-
-static int buffer_get(void *data)
-{
-    char c;
-    buffer_data_t *stream = data;
-    if(stream->pos >= stream->len)
-      return EOF;
-
-    c = stream->data[stream->pos];
-    stream->pos++;
-    return (unsigned char)c;
-}
-
-json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error)
-{
-    lex_t lex;
-    json_t *result;
-    buffer_data_t stream_data;
-
-    jsonp_error_init(error, "<buffer>");
-
-    if (buffer == NULL) {
-        error_set(error, NULL, "wrong arguments");
-        return NULL;
-    }
-
-    stream_data.data = buffer;
-    stream_data.pos = 0;
-    stream_data.len = buflen;
-
-    if(lex_init(&lex, buffer_get, (void *)&stream_data))
-        return NULL;
-
-    result = parse_json(&lex, flags, error);
-
-    lex_close(&lex);
-    return result;
-}
-
-json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
-{
-    lex_t lex;
-    const char *source;
-    json_t *result;
-
-    if(input == stdin)
-        source = "<stdin>";
-    else
-        source = "<stream>";
-
-    jsonp_error_init(error, source);
-
-    if (input == NULL) {
-        error_set(error, NULL, "wrong arguments");
-        return NULL;
-    }
-
-    if(lex_init(&lex, (get_func)fgetc, input))
-        return NULL;
-
-    result = parse_json(&lex, flags, error);
-
-    lex_close(&lex);
-    return result;
-}
-
-json_t *json_load_file(const char *path, size_t flags, json_error_t *error)
-{
-    json_t *result;
-    FILE *fp;
-
-    jsonp_error_init(error, path);
-
-    if (path == NULL) {
-        error_set(error, NULL, "wrong arguments");
-        return NULL;
-    }
-
-    fp = fopen(path, "rb");
-    if(!fp)
-    {
-        error_set(error, NULL, "unable to open %s: %s",
-                  path, strerror(errno));
-        return NULL;
-    }
-
-    result = json_loadf(fp, flags, error);
-
-    fclose(fp);
-    return result;
-}
-
-#define MAX_BUF_LEN 1024
-
-typedef struct
-{
-    char data[MAX_BUF_LEN];
-    size_t len;
-    size_t pos;
-    json_load_callback_t callback;
-    void *arg;
-} callback_data_t;
-
-static int callback_get(void *data)
-{
-    char c;
-    callback_data_t *stream = data;
-
-    if(stream->pos >= stream->len) {
-        stream->pos = 0;
-        stream->len = stream->callback(stream->data, MAX_BUF_LEN, stream->arg);
-        if(stream->len == 0 || stream->len == (size_t)-1)
-            return EOF;
-    }
-
-    c = stream->data[stream->pos];
-    stream->pos++;
-    return (unsigned char)c;
-}
-
-json_t *json_load_callback(json_load_callback_t callback, void *arg, size_t flags, json_error_t *error)
-{
-    lex_t lex;
-    json_t *result;
-
-    callback_data_t stream_data;
-
-    memset(&stream_data, 0, sizeof(stream_data));
-    stream_data.callback = callback;
-    stream_data.arg = arg;
-
-    jsonp_error_init(error, "<callback>");
-
-    if (callback == NULL) {
-        error_set(error, NULL, "wrong arguments");
-        return NULL;
-    }
-
-    if(lex_init(&lex, (get_func)callback_get, &stream_data))
-        return NULL;
-
-    result = parse_json(&lex, flags, error);
-
-    lex_close(&lex);
-    return result;
-}
diff --git a/deps/jansson/src/memory.c b/deps/jansson/src/memory.c
deleted file mode 100644
index e6da96e..0000000
--- a/deps/jansson/src/memory.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- * Copyright (c) 2011-2012 Basile Starynkevitch <basile at starynkevitch.net>
- *
- * Jansson is free software; you can redistribute it and/or modify it
- * under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "jansson.h"
-#include "jansson_private.h"
-
-/* C89 allows these to be macros */
-#undef malloc
-#undef free
-
-/* memory function pointers */
-static json_malloc_t do_malloc = malloc;
-static json_free_t do_free = free;
-
-void *jsonp_malloc(size_t size)
-{
-    if(!size)
-        return NULL;
-
-    return (*do_malloc)(size);
-}
-
-void jsonp_free(void *ptr)
-{
-    if(!ptr)
-        return;
-
-    (*do_free)(ptr);
-}
-
-char *jsonp_strdup(const char *str)
-{
-    return jsonp_strndup(str, strlen(str));
-}
-
-char *jsonp_strndup(const char *str, size_t len)
-{
-    char *new_str;
-
-    new_str = jsonp_malloc(len + 1);
-    if(!new_str)
-        return NULL;
-
-    memcpy(new_str, str, len);
-    new_str[len] = '\0';
-    return new_str;
-}
-
-void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn)
-{
-    do_malloc = malloc_fn;
-    do_free = free_fn;
-}
diff --git a/deps/jansson/src/pack_unpack.c b/deps/jansson/src/pack_unpack.c
deleted file mode 100644
index b19097d..0000000
--- a/deps/jansson/src/pack_unpack.c
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- * Copyright (c) 2011-2012 Graeme Smecher <graeme.smecher at mail.mcgill.ca>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <string.h>
-#include "jansson.h"
-#include "jansson_private.h"
-#include "utf.h"
-
-typedef struct {
-    int line;
-    int column;
-    size_t pos;
-    char token;
-} token_t;
-
-typedef struct {
-    const char *start;
-    const char *fmt;
-    token_t prev_token;
-    token_t token;
-    token_t next_token;
-    json_error_t *error;
-    size_t flags;
-    int line;
-    int column;
-    size_t pos;
-} scanner_t;
-
-#define token(scanner) ((scanner)->token.token)
-
-static const char * const type_names[] = {
-    "object",
-    "array",
-    "string",
-    "integer",
-    "real",
-    "true",
-    "false",
-    "null"
-};
-
-#define type_name(x) type_names[json_typeof(x)]
-
-static const char unpack_value_starters[] = "{[siIbfFOon";
-
-
-static void scanner_init(scanner_t *s, json_error_t *error,
-                         size_t flags, const char *fmt)
-{
-    s->error = error;
-    s->flags = flags;
-    s->fmt = s->start = fmt;
-    memset(&s->prev_token, 0, sizeof(token_t));
-    memset(&s->token, 0, sizeof(token_t));
-    memset(&s->next_token, 0, sizeof(token_t));
-    s->line = 1;
-    s->column = 0;
-    s->pos = 0;
-}
-
-static void next_token(scanner_t *s)
-{
-    const char *t;
-    s->prev_token = s->token;
-
-    if(s->next_token.line) {
-        s->token = s->next_token;
-        s->next_token.line = 0;
-        return;
-    }
-
-    t = s->fmt;
-    s->column++;
-    s->pos++;
-
-    /* skip space and ignored chars */
-    while(*t == ' ' || *t == '\t' || *t == '\n' || *t == ',' || *t == ':') {
-        if(*t == '\n') {
-            s->line++;
-            s->column = 1;
-        }
-        else
-            s->column++;
-
-        s->pos++;
-        t++;
-    }
-
-    s->token.token = *t;
-    s->token.line = s->line;
-    s->token.column = s->column;
-    s->token.pos = s->pos;
-
-    t++;
-    s->fmt = t;
-}
-
-static void prev_token(scanner_t *s)
-{
-    s->next_token = s->token;
-    s->token = s->prev_token;
-}
-
-static void set_error(scanner_t *s, const char *source, const char *fmt, ...)
-{
-    va_list ap;
-    va_start(ap, fmt);
-
-    jsonp_error_vset(s->error, s->token.line, s->token.column, s->token.pos,
-                     fmt, ap);
-
-    jsonp_error_set_source(s->error, source);
-
-    va_end(ap);
-}
-
-static json_t *pack(scanner_t *s, va_list *ap);
-
-
-/* ours will be set to 1 if jsonp_free() must be called for the result
-   afterwards */
-static char *read_string(scanner_t *s, va_list *ap,
-                         const char *purpose, size_t *out_len, int *ours)
-{
-    char t;
-    strbuffer_t strbuff;
-    const char *str;
-    size_t length;
-
-    next_token(s);
-    t = token(s);
-    prev_token(s);
-
-    if(t != '#' && t != '%' && t != '+') {
-        /* Optimize the simple case */
-        str = va_arg(*ap, const char *);
-
-        if(!str) {
-            set_error(s, "<args>", "NULL string argument");
-            return NULL;
-        }
-
-        length = strlen(str);
-
-        if(!utf8_check_string(str, length)) {
-            set_error(s, "<args>", "Invalid UTF-8 %s", purpose);
-            return NULL;
-        }
-
-        *out_len = length;
-        *ours = 0;
-        return (char *)str;
-    }
-
-    strbuffer_init(&strbuff);
-
-    while(1) {
-        str = va_arg(*ap, const char *);
-        if(!str) {
-            set_error(s, "<args>", "NULL string argument");
-            strbuffer_close(&strbuff);
-            return NULL;
-        }
-
-        next_token(s);
-
-        if(token(s) == '#') {
-            length = va_arg(*ap, int);
-        }
-        else if(token(s) == '%') {
-            length = va_arg(*ap, size_t);
-        }
-        else {
-            prev_token(s);
-            length = strlen(str);
-        }
-
-        if(strbuffer_append_bytes(&strbuff, str, length) == -1) {
-            set_error(s, "<internal>", "Out of memory");
-            strbuffer_close(&strbuff);
-            return NULL;
-        }
-
-        next_token(s);
-        if(token(s) != '+') {
-            prev_token(s);
-            break;
-        }
-    }
-
-    if(!utf8_check_string(strbuff.value, strbuff.length)) {
-        set_error(s, "<args>", "Invalid UTF-8 %s", purpose);
-        strbuffer_close(&strbuff);
-        return NULL;
-    }
-
-    *out_len = strbuff.length;
-    *ours = 1;
-    return strbuffer_steal_value(&strbuff);
-}
-
-static json_t *pack_object(scanner_t *s, va_list *ap)
-{
-    json_t *object = json_object();
-    next_token(s);
-
-    while(token(s) != '}') {
-        char *key;
-        size_t len;
-        int ours;
-        json_t *value;
-
-        if(!token(s)) {
-            set_error(s, "<format>", "Unexpected end of format string");
-            goto error;
-        }
-
-        if(token(s) != 's') {
-            set_error(s, "<format>", "Expected format 's', got '%c'", token(s));
-            goto error;
-        }
-
-        key = read_string(s, ap, "object key", &len, &ours);
-        if(!key)
-            goto error;
-
-        next_token(s);
-
-        value = pack(s, ap);
-        if(!value) {
-            if(ours)
-                jsonp_free(key);
-
-            goto error;
-        }
-
-        if(json_object_set_new_nocheck(object, key, value)) {
-            if(ours)
-                jsonp_free(key);
-
-            set_error(s, "<internal>", "Unable to add key \"%s\"", key);
-            goto error;
-        }
-
-        if(ours)
-            jsonp_free(key);
-
-        next_token(s);
-    }
-
-    return object;
-
-error:
-    json_decref(object);
-    return NULL;
-}
-
-static json_t *pack_array(scanner_t *s, va_list *ap)
-{
-    json_t *array = json_array();
-    next_token(s);
-
-    while(token(s) != ']') {
-        json_t *value;
-
-        if(!token(s)) {
-            set_error(s, "<format>", "Unexpected end of format string");
-            goto error;
-        }
-
-        value = pack(s, ap);
-        if(!value)
-            goto error;
-
-        if(json_array_append_new(array, value)) {
-            set_error(s, "<internal>", "Unable to append to array");
-            goto error;
-        }
-
-        next_token(s);
-    }
-    return array;
-
-error:
-    json_decref(array);
-    return NULL;
-}
-
-static json_t *pack(scanner_t *s, va_list *ap)
-{
-    switch(token(s)) {
-        case '{':
-            return pack_object(s, ap);
-
-        case '[':
-            return pack_array(s, ap);
-
-        case 's': /* string */
-        {
-            char *str;
-            size_t len;
-            int ours;
-
-            str = read_string(s, ap, "string", &len, &ours);
-            if(!str)
-                return NULL;
-
-            if (ours)
-                return jsonp_stringn_nocheck_own(str, len);
-            else
-                return json_stringn_nocheck(str, len);
-        }
-
-        case 'n': /* null */
-            return json_null();
-
-        case 'b': /* boolean */
-            return va_arg(*ap, int) ? json_true() : json_false();
-
-        case 'i': /* integer from int */
-            return json_integer(va_arg(*ap, int));
-
-        case 'I': /* integer from json_int_t */
-            return json_integer(va_arg(*ap, json_int_t));
-
-        case 'f': /* real */
-            return json_real(va_arg(*ap, double));
-
-        case 'O': /* a json_t object; increments refcount */
-            return json_incref(va_arg(*ap, json_t *));
-
-        case 'o': /* a json_t object; doesn't increment refcount */
-            return va_arg(*ap, json_t *);
-
-        default:
-            set_error(s, "<format>", "Unexpected format character '%c'",
-                      token(s));
-            return NULL;
-    }
-}
-
-static int unpack(scanner_t *s, json_t *root, va_list *ap);
-
-static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
-{
-    int ret = -1;
-    int strict = 0;
-
-    /* Use a set (emulated by a hashtable) to check that all object
-       keys are accessed. Checking that the correct number of keys
-       were accessed is not enough, as the same key can be unpacked
-       multiple times.
-    */
-    hashtable_t key_set;
-
-    if(hashtable_init(&key_set)) {
-        set_error(s, "<internal>", "Out of memory");
-        return -1;
-    }
-
-    if(root && !json_is_object(root)) {
-        set_error(s, "<validation>", "Expected object, got %s",
-                  type_name(root));
-        goto out;
-    }
-    next_token(s);
-
-    while(token(s) != '}') {
-        const char *key;
-        json_t *value;
-        int opt = 0;
-
-        if(strict != 0) {
-            set_error(s, "<format>", "Expected '}' after '%c', got '%c'",
-                      (strict == 1 ? '!' : '*'), token(s));
-            goto out;
-        }
-
-        if(!token(s)) {
-            set_error(s, "<format>", "Unexpected end of format string");
-            goto out;
-        }
-
-        if(token(s) == '!' || token(s) == '*') {
-            strict = (token(s) == '!' ? 1 : -1);
-            next_token(s);
-            continue;
-        }
-
-        if(token(s) != 's') {
-            set_error(s, "<format>", "Expected format 's', got '%c'", token(s));
-            goto out;
-        }
-
-        key = va_arg(*ap, const char *);
-        if(!key) {
-            set_error(s, "<args>", "NULL object key");
-            goto out;
-        }
-
-        next_token(s);
-
-        if(token(s) == '?') {
-            opt = 1;
-            next_token(s);
-        }
-
-        if(!root) {
-            /* skipping */
-            value = NULL;
-        }
-        else {
-            value = json_object_get(root, key);
-            if(!value && !opt) {
-                set_error(s, "<validation>", "Object item not found: %s", key);
-                goto out;
-            }
-        }
-
-        if(unpack(s, value, ap))
-            goto out;
-
-        hashtable_set(&key_set, key, 0, json_null());
-        next_token(s);
-    }
-
-    if(strict == 0 && (s->flags & JSON_STRICT))
-        strict = 1;
-
-    if(root && strict == 1 && key_set.size != json_object_size(root)) {
-        long diff = (long)json_object_size(root) - (long)key_set.size;
-        set_error(s, "<validation>", "%li object item(s) left unpacked", diff);
-        goto out;
-    }
-
-    ret = 0;
-
-out:
-    hashtable_close(&key_set);
-    return ret;
-}
-
-static int unpack_array(scanner_t *s, json_t *root, va_list *ap)
-{
-    size_t i = 0;
-    int strict = 0;
-
-    if(root && !json_is_array(root)) {
-        set_error(s, "<validation>", "Expected array, got %s", type_name(root));
-        return -1;
-    }
-    next_token(s);
-
-    while(token(s) != ']') {
-        json_t *value;
-
-        if(strict != 0) {
-            set_error(s, "<format>", "Expected ']' after '%c', got '%c'",
-                      (strict == 1 ? '!' : '*'),
-                      token(s));
-            return -1;
-        }
-
-        if(!token(s)) {
-            set_error(s, "<format>", "Unexpected end of format string");
-            return -1;
-        }
-
-        if(token(s) == '!' || token(s) == '*') {
-            strict = (token(s) == '!' ? 1 : -1);
-            next_token(s);
-            continue;
-        }
-
-        if(!strchr(unpack_value_starters, token(s))) {
-            set_error(s, "<format>", "Unexpected format character '%c'",
-                      token(s));
-            return -1;
-        }
-
-        if(!root) {
-            /* skipping */
-            value = NULL;
-        }
-        else {
-            value = json_array_get(root, i);
-            if(!value) {
-                set_error(s, "<validation>", "Array index %lu out of range",
-                          (unsigned long)i);
-                return -1;
-            }
-        }
-
-        if(unpack(s, value, ap))
-            return -1;
-
-        next_token(s);
-        i++;
-    }
-
-    if(strict == 0 && (s->flags & JSON_STRICT))
-        strict = 1;
-
-    if(root && strict == 1 && i != json_array_size(root)) {
-        long diff = (long)json_array_size(root) - (long)i;
-        set_error(s, "<validation>", "%li array item(s) left unpacked", diff);
-        return -1;
-    }
-
-    return 0;
-}
-
-static int unpack(scanner_t *s, json_t *root, va_list *ap)
-{
-    switch(token(s))
-    {
-        case '{':
-            return unpack_object(s, root, ap);
-
-        case '[':
-            return unpack_array(s, root, ap);
-
-        case 's':
-            if(root && !json_is_string(root)) {
-                set_error(s, "<validation>", "Expected string, got %s",
-                          type_name(root));
-                return -1;
-            }
-
-            if(!(s->flags & JSON_VALIDATE_ONLY)) {
-                const char **str_target;
-                size_t *len_target = NULL;
-
-                str_target = va_arg(*ap, const char **);
-                if(!str_target) {
-                    set_error(s, "<args>", "NULL string argument");
-                    return -1;
-                }
-
-                next_token(s);
-
-                if(token(s) == '%') {
-                    len_target = va_arg(*ap, size_t *);
-                    if(!len_target) {
-                        set_error(s, "<args>", "NULL string length argument");
-                        return -1;
-                    }
-                }
-                else
-                    prev_token(s);
-
-                if(root) {
-                    *str_target = json_string_value(root);
-                    if(len_target)
-                        *len_target = json_string_length(root);
-                }
-            }
-            return 0;
-
-        case 'i':
-            if(root && !json_is_integer(root)) {
-                set_error(s, "<validation>", "Expected integer, got %s",
-                          type_name(root));
-                return -1;
-            }
-
-            if(!(s->flags & JSON_VALIDATE_ONLY)) {
-                int *target = va_arg(*ap, int*);
-                if(root)
-                    *target = (int)json_integer_value(root);
-            }
-
-            return 0;
-
-        case 'I':
-            if(root && !json_is_integer(root)) {
-                set_error(s, "<validation>", "Expected integer, got %s",
-                          type_name(root));
-                return -1;
-            }
-
-            if(!(s->flags & JSON_VALIDATE_ONLY)) {
-                json_int_t *target = va_arg(*ap, json_int_t*);
-                if(root)
-                    *target = json_integer_value(root);
-            }
-
-            return 0;
-
-        case 'b':
-            if(root && !json_is_boolean(root)) {
-                set_error(s, "<validation>", "Expected true or false, got %s",
-                          type_name(root));
-                return -1;
-            }
-
-            if(!(s->flags & JSON_VALIDATE_ONLY)) {
-                int *target = va_arg(*ap, int*);
-                if(root)
-                    *target = json_is_true(root);
-            }
-
-            return 0;
-
-        case 'f':
-            if(root && !json_is_real(root)) {
-                set_error(s, "<validation>", "Expected real, got %s",
-                          type_name(root));
-                return -1;
-            }
-
-            if(!(s->flags & JSON_VALIDATE_ONLY)) {
-                double *target = va_arg(*ap, double*);
-                if(root)
-                    *target = json_real_value(root);
-            }
-
-            return 0;
-
-        case 'F':
-            if(root && !json_is_number(root)) {
-                set_error(s, "<validation>", "Expected real or integer, got %s",
-                          type_name(root));
-                return -1;
-            }
-
-            if(!(s->flags & JSON_VALIDATE_ONLY)) {
-                double *target = va_arg(*ap, double*);
-                if(root)
-                    *target = json_number_value(root);
-            }
-
-            return 0;
-
-        case 'O':
-            if(root && !(s->flags & JSON_VALIDATE_ONLY))
-                json_incref(root);
-            /* Fall through */
-
-        case 'o':
-            if(!(s->flags & JSON_VALIDATE_ONLY)) {
-                json_t **target = va_arg(*ap, json_t**);
-                if(root)
-                    *target = root;
-            }
-
-            return 0;
-
-        case 'n':
-            /* Never assign, just validate */
-            if(root && !json_is_null(root)) {
-                set_error(s, "<validation>", "Expected null, got %s",
-                          type_name(root));
-                return -1;
-            }
-            return 0;
-
-        default:
-            set_error(s, "<format>", "Unexpected format character '%c'",
-                      token(s));
-            return -1;
-    }
-}
-
-json_t *json_vpack_ex(json_error_t *error, size_t flags,
-                      const char *fmt, va_list ap)
-{
-    scanner_t s;
-    va_list ap_copy;
-    json_t *value;
-
-    if(!fmt || !*fmt) {
-        jsonp_error_init(error, "<format>");
-        jsonp_error_set(error, -1, -1, 0, "NULL or empty format string");
-        return NULL;
-    }
-    jsonp_error_init(error, NULL);
-
-    scanner_init(&s, error, flags, fmt);
-    next_token(&s);
-
-    va_copy(ap_copy, ap);
-    value = pack(&s, &ap_copy);
-    va_end(ap_copy);
-
-    if(!value)
-        return NULL;
-
-    next_token(&s);
-    if(token(&s)) {
-        json_decref(value);
-        set_error(&s, "<format>", "Garbage after format string");
-        return NULL;
-    }
-
-    return value;
-}
-
-json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...)
-{
-    json_t *value;
-    va_list ap;
-
-    va_start(ap, fmt);
-    value = json_vpack_ex(error, flags, fmt, ap);
-    va_end(ap);
-
-    return value;
-}
-
-json_t *json_pack(const char *fmt, ...)
-{
-    json_t *value;
-    va_list ap;
-
-    va_start(ap, fmt);
-    value = json_vpack_ex(NULL, 0, fmt, ap);
-    va_end(ap);
-
-    return value;
-}
-
-int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags,
-                    const char *fmt, va_list ap)
-{
-    scanner_t s;
-    va_list ap_copy;
-
-    if(!root) {
-        jsonp_error_init(error, "<root>");
-        jsonp_error_set(error, -1, -1, 0, "NULL root value");
-        return -1;
-    }
-
-    if(!fmt || !*fmt) {
-        jsonp_error_init(error, "<format>");
-        jsonp_error_set(error, -1, -1, 0, "NULL or empty format string");
-        return -1;
-    }
-    jsonp_error_init(error, NULL);
-
-    scanner_init(&s, error, flags, fmt);
-    next_token(&s);
-
-    va_copy(ap_copy, ap);
-    if(unpack(&s, root, &ap_copy)) {
-        va_end(ap_copy);
-        return -1;
-    }
-    va_end(ap_copy);
-
-    next_token(&s);
-    if(token(&s)) {
-        set_error(&s, "<format>", "Garbage after format string");
-        return -1;
-    }
-
-    return 0;
-}
-
-int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...)
-{
-    int ret;
-    va_list ap;
-
-    va_start(ap, fmt);
-    ret = json_vunpack_ex(root, error, flags, fmt, ap);
-    va_end(ap);
-
-    return ret;
-}
-
-int json_unpack(json_t *root, const char *fmt, ...)
-{
-    int ret;
-    va_list ap;
-
-    va_start(ap, fmt);
-    ret = json_vunpack_ex(root, NULL, 0, fmt, ap);
-    va_end(ap);
-
-    return ret;
-}
diff --git a/deps/jansson/src/strbuffer.c b/deps/jansson/src/strbuffer.c
deleted file mode 100644
index 2d6ff31..0000000
--- a/deps/jansson/src/strbuffer.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include "jansson_private.h"
-#include "strbuffer.h"
-
-#define STRBUFFER_MIN_SIZE  16
-#define STRBUFFER_FACTOR    2
-#define STRBUFFER_SIZE_MAX  ((size_t)-1)
-
-int strbuffer_init(strbuffer_t *strbuff)
-{
-    strbuff->size = STRBUFFER_MIN_SIZE;
-    strbuff->length = 0;
-
-    strbuff->value = jsonp_malloc(strbuff->size);
-    if(!strbuff->value)
-        return -1;
-
-    /* initialize to empty */
-    strbuff->value[0] = '\0';
-    return 0;
-}
-
-void strbuffer_close(strbuffer_t *strbuff)
-{
-    if(strbuff->value)
-        jsonp_free(strbuff->value);
-
-    strbuff->size = 0;
-    strbuff->length = 0;
-    strbuff->value = NULL;
-}
-
-void strbuffer_clear(strbuffer_t *strbuff)
-{
-    strbuff->length = 0;
-    strbuff->value[0] = '\0';
-}
-
-const char *strbuffer_value(const strbuffer_t *strbuff)
-{
-    return strbuff->value;
-}
-
-char *strbuffer_steal_value(strbuffer_t *strbuff)
-{
-    char *result = strbuff->value;
-    strbuff->value = NULL;
-    return result;
-}
-
-int strbuffer_append(strbuffer_t *strbuff, const char *string)
-{
-    return strbuffer_append_bytes(strbuff, string, strlen(string));
-}
-
-int strbuffer_append_byte(strbuffer_t *strbuff, char byte)
-{
-    return strbuffer_append_bytes(strbuff, &byte, 1);
-}
-
-int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, size_t size)
-{
-    if(size >= strbuff->size - strbuff->length)
-    {
-        size_t new_size;
-        char *new_value;
-
-        /* avoid integer overflow */
-        if (strbuff->size > STRBUFFER_SIZE_MAX / STRBUFFER_FACTOR
-            || size > STRBUFFER_SIZE_MAX - 1
-            || strbuff->length > STRBUFFER_SIZE_MAX - 1 - size)
-            return -1;
-
-        new_size = max(strbuff->size * STRBUFFER_FACTOR,
-                       strbuff->length + size + 1);
-
-        new_value = jsonp_malloc(new_size);
-        if(!new_value)
-            return -1;
-
-        memcpy(new_value, strbuff->value, strbuff->length);
-
-        jsonp_free(strbuff->value);
-        strbuff->value = new_value;
-        strbuff->size = new_size;
-    }
-
-    memcpy(strbuff->value + strbuff->length, data, size);
-    strbuff->length += size;
-    strbuff->value[strbuff->length] = '\0';
-
-    return 0;
-}
-
-char strbuffer_pop(strbuffer_t *strbuff)
-{
-    if(strbuff->length > 0) {
-        char c = strbuff->value[--strbuff->length];
-        strbuff->value[strbuff->length] = '\0';
-        return c;
-    }
-    else
-        return '\0';
-}
diff --git a/deps/jansson/src/strbuffer.h b/deps/jansson/src/strbuffer.h
deleted file mode 100644
index 06fd065..0000000
--- a/deps/jansson/src/strbuffer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef STRBUFFER_H
-#define STRBUFFER_H
-
-typedef struct {
-    char *value;
-    size_t length;   /* bytes used */
-    size_t size;     /* bytes allocated */
-} strbuffer_t;
-
-int strbuffer_init(strbuffer_t *strbuff);
-void strbuffer_close(strbuffer_t *strbuff);
-
-void strbuffer_clear(strbuffer_t *strbuff);
-
-const char *strbuffer_value(const strbuffer_t *strbuff);
-
-/* Steal the value and close the strbuffer */
-char *strbuffer_steal_value(strbuffer_t *strbuff);
-
-int strbuffer_append(strbuffer_t *strbuff, const char *string);
-int strbuffer_append_byte(strbuffer_t *strbuff, char byte);
-int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, size_t size);
-
-char strbuffer_pop(strbuffer_t *strbuff);
-
-#endif
diff --git a/deps/jansson/src/strconv.c b/deps/jansson/src/strconv.c
deleted file mode 100644
index 3e2cb7c..0000000
--- a/deps/jansson/src/strconv.c
+++ /dev/null
@@ -1,134 +0,0 @@
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include "jansson_private.h"
-#include "strbuffer.h"
-
-/* need config.h to get the correct snprintf */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if JSON_HAVE_LOCALECONV
-#include <locale.h>
-
-/*
-  - This code assumes that the decimal separator is exactly one
-    character.
-
-  - If setlocale() is called by another thread between the call to
-    localeconv() and the call to sprintf() or strtod(), the result may
-    be wrong. setlocale() is not thread-safe and should not be used
-    this way. Multi-threaded programs should use uselocale() instead.
-*/
-
-static void to_locale(strbuffer_t *strbuffer)
-{
-    const char *point;
-    char *pos;
-
-    point = localeconv()->decimal_point;
-    if(*point == '.') {
-        /* No conversion needed */
-        return;
-    }
-
-    pos = strchr(strbuffer->value, '.');
-    if(pos)
-        *pos = *point;
-}
-
-static void from_locale(char *buffer)
-{
-    const char *point;
-    char *pos;
-
-    point = localeconv()->decimal_point;
-    if(*point == '.') {
-        /* No conversion needed */
-        return;
-    }
-
-    pos = strchr(buffer, *point);
-    if(pos)
-        *pos = '.';
-}
-#endif
-
-int jsonp_strtod(strbuffer_t *strbuffer, double *out)
-{
-    double value;
-    char *end;
-
-#if JSON_HAVE_LOCALECONV
-    to_locale(strbuffer);
-#endif
-
-    errno = 0;
-    value = strtod(strbuffer->value, &end);
-    assert(end == strbuffer->value + strbuffer->length);
-
-    if(errno == ERANGE && value != 0) {
-        /* Overflow */
-        return -1;
-    }
-
-    *out = value;
-    return 0;
-}
-
-int jsonp_dtostr(char *buffer, size_t size, double value)
-{
-    int ret;
-    char *start, *end;
-    size_t length;
-
-    ret = snprintf(buffer, size, "%.17g", value);
-    if(ret < 0)
-        return -1;
-
-    length = (size_t)ret;
-    if(length >= size)
-        return -1;
-
-#if JSON_HAVE_LOCALECONV
-    from_locale(buffer);
-#endif
-
-    /* Make sure there's a dot or 'e' in the output. Otherwise
-       a real is converted to an integer when decoding */
-    if(strchr(buffer, '.') == NULL &&
-       strchr(buffer, 'e') == NULL)
-    {
-        if(length + 3 >= size) {
-            /* No space to append ".0" */
-            return -1;
-        }
-        buffer[length] = '.';
-        buffer[length + 1] = '0';
-        buffer[length + 2] = '\0';
-        length += 2;
-    }
-
-    /* Remove leading '+' from positive exponent. Also remove leading
-       zeros from exponents (added by some printf() implementations) */
-    start = strchr(buffer, 'e');
-    if(start) {
-        start++;
-        end = start + 1;
-
-        if(*start == '-')
-            start++;
-
-        while(*end == '0')
-            end++;
-
-        if(end != start) {
-            memmove(start, end, length - (size_t)(end - buffer));
-            length -= (size_t)(end - start);
-        }
-    }
-
-    return (int)length;
-}
diff --git a/deps/jansson/src/utf.c b/deps/jansson/src/utf.c
deleted file mode 100644
index cbeeb54..0000000
--- a/deps/jansson/src/utf.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <string.h>
-#include "utf.h"
-
-int utf8_encode(int32_t codepoint, char *buffer, size_t *size)
-{
-    if(codepoint < 0)
-        return -1;
-    else if(codepoint < 0x80)
-    {
-        buffer[0] = (char)codepoint;
-        *size = 1;
-    }
-    else if(codepoint < 0x800)
-    {
-        buffer[0] = 0xC0 + ((codepoint & 0x7C0) >> 6);
-        buffer[1] = 0x80 + ((codepoint & 0x03F));
-        *size = 2;
-    }
-    else if(codepoint < 0x10000)
-    {
-        buffer[0] = 0xE0 + ((codepoint & 0xF000) >> 12);
-        buffer[1] = 0x80 + ((codepoint & 0x0FC0) >> 6);
-        buffer[2] = 0x80 + ((codepoint & 0x003F));
-        *size = 3;
-    }
-    else if(codepoint <= 0x10FFFF)
-    {
-        buffer[0] = 0xF0 + ((codepoint & 0x1C0000) >> 18);
-        buffer[1] = 0x80 + ((codepoint & 0x03F000) >> 12);
-        buffer[2] = 0x80 + ((codepoint & 0x000FC0) >> 6);
-        buffer[3] = 0x80 + ((codepoint & 0x00003F));
-        *size = 4;
-    }
-    else
-        return -1;
-
-    return 0;
-}
-
-size_t utf8_check_first(char byte)
-{
-    unsigned char u = (unsigned char)byte;
-
-    if(u < 0x80)
-        return 1;
-
-    if(0x80 <= u && u <= 0xBF) {
-        /* second, third or fourth byte of a multi-byte
-           sequence, i.e. a "continuation byte" */
-        return 0;
-    }
-    else if(u == 0xC0 || u == 0xC1) {
-        /* overlong encoding of an ASCII byte */
-        return 0;
-    }
-    else if(0xC2 <= u && u <= 0xDF) {
-        /* 2-byte sequence */
-        return 2;
-    }
-
-    else if(0xE0 <= u && u <= 0xEF) {
-        /* 3-byte sequence */
-        return 3;
-    }
-    else if(0xF0 <= u && u <= 0xF4) {
-        /* 4-byte sequence */
-        return 4;
-    }
-    else { /* u >= 0xF5 */
-        /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid
-           UTF-8 */
-        return 0;
-    }
-}
-
-size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint)
-{
-    size_t i;
-    int32_t value = 0;
-    unsigned char u = (unsigned char)buffer[0];
-
-    if(size == 2)
-    {
-        value = u & 0x1F;
-    }
-    else if(size == 3)
-    {
-        value = u & 0xF;
-    }
-    else if(size == 4)
-    {
-        value = u & 0x7;
-    }
-    else
-        return 0;
-
-    for(i = 1; i < size; i++)
-    {
-        u = (unsigned char)buffer[i];
-
-        if(u < 0x80 || u > 0xBF) {
-            /* not a continuation byte */
-            return 0;
-        }
-
-        value = (value << 6) + (u & 0x3F);
-    }
-
-    if(value > 0x10FFFF) {
-        /* not in Unicode range */
-        return 0;
-    }
-
-    else if(0xD800 <= value && value <= 0xDFFF) {
-        /* invalid code point (UTF-16 surrogate halves) */
-        return 0;
-    }
-
-    else if((size == 2 && value < 0x80) ||
-            (size == 3 && value < 0x800) ||
-            (size == 4 && value < 0x10000)) {
-        /* overlong encoding */
-        return 0;
-    }
-
-    if(codepoint)
-        *codepoint = value;
-
-    return 1;
-}
-
-const char *utf8_iterate(const char *buffer, size_t bufsize, int32_t *codepoint)
-{
-    size_t count;
-    int32_t value;
-
-    if(!bufsize)
-        return buffer;
-
-    count = utf8_check_first(buffer[0]);
-    if(count <= 0)
-        return NULL;
-
-    if(count == 1)
-        value = (unsigned char)buffer[0];
-    else
-    {
-        if(count > bufsize || !utf8_check_full(buffer, count, &value))
-            return NULL;
-    }
-
-    if(codepoint)
-        *codepoint = value;
-
-    return buffer + count;
-}
-
-int utf8_check_string(const char *string, size_t length)
-{
-    size_t i;
-
-    for(i = 0; i < length; i++)
-    {
-        size_t count = utf8_check_first(string[i]);
-        if(count == 0)
-            return 0;
-        else if(count > 1)
-        {
-            if(count > length - i)
-                return 0;
-
-            if(!utf8_check_full(&string[i], count, NULL))
-                return 0;
-
-            i += count - 1;
-        }
-    }
-
-    return 1;
-}
diff --git a/deps/jansson/src/utf.h b/deps/jansson/src/utf.h
deleted file mode 100644
index 81f85ab..0000000
--- a/deps/jansson/src/utf.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef UTF_H
-#define UTF_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-
-#ifdef HAVE_INTTYPES_H
-/* inttypes.h includes stdint.h in a standard environment, so there's
-no need to include stdint.h separately. If inttypes.h doesn't define
-int32_t, it's defined in config.h. */
-#include <inttypes.h>
-#endif /* HAVE_INTTYPES_H */
-
-#else /* !HAVE_CONFIG_H */
-#ifdef _WIN32
-typedef int int32_t;
-#else /* !_WIN32 */
-/* Assume a standard environment */
-#include <inttypes.h>
-#endif /* _WIN32 */
-
-#endif /* HAVE_CONFIG_H */
-
-int utf8_encode(int32_t codepoint, char *buffer, size_t *size);
-
-size_t utf8_check_first(char byte);
-size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint);
-const char *utf8_iterate(const char *buffer, size_t size, int32_t *codepoint);
-
-int utf8_check_string(const char *string, size_t length);
-
-#endif
diff --git a/deps/jansson/src/value.c b/deps/jansson/src/value.c
deleted file mode 100644
index 336873b..0000000
--- a/deps/jansson/src/value.c
+++ /dev/null
@@ -1,1023 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "jansson.h"
-#include "hashtable.h"
-#include "jansson_private.h"
-#include "utf.h"
-
-/* Work around nonstandard isnan() and isinf() implementations */
-#ifndef isnan
-static JSON_INLINE int isnan(double x) { return x != x; }
-#endif
-#ifndef isinf
-static JSON_INLINE int isinf(double x) { return !isnan(x) && isnan(x - x); }
-#endif
-
-static JSON_INLINE void json_init(json_t *json, json_type type)
-{
-    json->type = type;
-    json->refcount = 1;
-}
-
-
-/*** object ***/
-
-json_t *json_object(void)
-{
-    json_object_t *object = jsonp_malloc(sizeof(json_object_t));
-    if(!object)
-        return NULL;
-    json_init(&object->json, JSON_OBJECT);
-
-    if(hashtable_init(&object->hashtable))
-    {
-        jsonp_free(object);
-        return NULL;
-    }
-
-    object->serial = 0;
-    object->visited = 0;
-
-    return &object->json;
-}
-
-static void json_delete_object(json_object_t *object)
-{
-    hashtable_close(&object->hashtable);
-    jsonp_free(object);
-}
-
-size_t json_object_size(const json_t *json)
-{
-    json_object_t *object;
-
-    if(!json_is_object(json))
-        return 0;
-
-    object = json_to_object(json);
-    return object->hashtable.size;
-}
-
-json_t *json_object_get(const json_t *json, const char *key)
-{
-    json_object_t *object;
-
-    if(!key || !json_is_object(json))
-        return NULL;
-
-    object = json_to_object(json);
-    return hashtable_get(&object->hashtable, key);
-}
-
-int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
-{
-    json_object_t *object;
-
-    if(!value)
-        return -1;
-
-    if(!key || !json_is_object(json) || json == value)
-    {
-        json_decref(value);
-        return -1;
-    }
-    object = json_to_object(json);
-
-    if(hashtable_set(&object->hashtable, key, object->serial++, value))
-    {
-        json_decref(value);
-        return -1;
-    }
-
-    return 0;
-}
-
-int json_object_set_new(json_t *json, const char *key, json_t *value)
-{
-    if(!key || !utf8_check_string(key, strlen(key)))
-    {
-        json_decref(value);
-        return -1;
-    }
-
-    return json_object_set_new_nocheck(json, key, value);
-}
-
-int json_object_del(json_t *json, const char *key)
-{
-    json_object_t *object;
-
-    if(!key || !json_is_object(json))
-        return -1;
-
-    object = json_to_object(json);
-    return hashtable_del(&object->hashtable, key);
-}
-
-int json_object_clear(json_t *json)
-{
-    json_object_t *object;
-
-    if(!json_is_object(json))
-        return -1;
-
-    object = json_to_object(json);
-
-    hashtable_clear(&object->hashtable);
-    object->serial = 0;
-
-    return 0;
-}
-
-int json_object_update(json_t *object, json_t *other)
-{
-    const char *key;
-    json_t *value;
-
-    if(!json_is_object(object) || !json_is_object(other))
-        return -1;
-
-    json_object_foreach(other, key, value) {
-        if(json_object_set_nocheck(object, key, value))
-            return -1;
-    }
-
-    return 0;
-}
-
-int json_object_update_existing(json_t *object, json_t *other)
-{
-    const char *key;
-    json_t *value;
-
-    if(!json_is_object(object) || !json_is_object(other))
-        return -1;
-
-    json_object_foreach(other, key, value) {
-        if(json_object_get(object, key))
-            json_object_set_nocheck(object, key, value);
-    }
-
-    return 0;
-}
-
-int json_object_update_missing(json_t *object, json_t *other)
-{
-    const char *key;
-    json_t *value;
-
-    if(!json_is_object(object) || !json_is_object(other))
-        return -1;
-
-    json_object_foreach(other, key, value) {
-        if(!json_object_get(object, key))
-            json_object_set_nocheck(object, key, value);
-    }
-
-    return 0;
-}
-
-void *json_object_iter(json_t *json)
-{
-    json_object_t *object;
-
-    if(!json_is_object(json))
-        return NULL;
-
-    object = json_to_object(json);
-    return hashtable_iter(&object->hashtable);
-}
-
-void *json_object_iter_at(json_t *json, const char *key)
-{
-    json_object_t *object;
-
-    if(!key || !json_is_object(json))
-        return NULL;
-
-    object = json_to_object(json);
-    return hashtable_iter_at(&object->hashtable, key);
-}
-
-void *json_object_iter_next(json_t *json, void *iter)
-{
-    json_object_t *object;
-
-    if(!json_is_object(json) || iter == NULL)
-        return NULL;
-
-    object = json_to_object(json);
-    return hashtable_iter_next(&object->hashtable, iter);
-}
-
-const char *json_object_iter_key(void *iter)
-{
-    if(!iter)
-        return NULL;
-
-    return hashtable_iter_key(iter);
-}
-
-json_t *json_object_iter_value(void *iter)
-{
-    if(!iter)
-        return NULL;
-
-    return (json_t *)hashtable_iter_value(iter);
-}
-
-int json_object_iter_set_new(json_t *json, void *iter, json_t *value)
-{
-    if(!json_is_object(json) || !iter || !value)
-        return -1;
-
-    hashtable_iter_set(iter, value);
-    return 0;
-}
-
-void *json_object_key_to_iter(const char *key)
-{
-    if(!key)
-        return NULL;
-
-    return hashtable_key_to_iter(key);
-}
-
-static int json_object_equal(json_t *object1, json_t *object2)
-{
-    const char *key;
-    json_t *value1, *value2;
-
-    if(json_object_size(object1) != json_object_size(object2))
-        return 0;
-
-    json_object_foreach(object1, key, value1) {
-        value2 = json_object_get(object2, key);
-
-        if(!json_equal(value1, value2))
-            return 0;
-    }
-
-    return 1;
-}
-
-static json_t *json_object_copy(json_t *object)
-{
-    json_t *result;
-
-    const char *key;
-    json_t *value;
-
-    result = json_object();
-    if(!result)
-        return NULL;
-
-    json_object_foreach(object, key, value)
-        json_object_set_nocheck(result, key, value);
-
-    return result;
-}
-
-static json_t *json_object_deep_copy(const json_t *object)
-{
-    json_t *result;
-    void *iter;
-
-    result = json_object();
-    if(!result)
-        return NULL;
-
-    /* Cannot use json_object_foreach because object has to be cast
-       non-const */
-    iter = json_object_iter((json_t *)object);
-    while(iter) {
-        const char *key;
-        const json_t *value;
-        key = json_object_iter_key(iter);
-        value = json_object_iter_value(iter);
-
-        json_object_set_new_nocheck(result, key, json_deep_copy(value));
-        iter = json_object_iter_next((json_t *)object, iter);
-    }
-
-    return result;
-}
-
-
-/*** array ***/
-
-json_t *json_array(void)
-{
-    json_array_t *array = jsonp_malloc(sizeof(json_array_t));
-    if(!array)
-        return NULL;
-    json_init(&array->json, JSON_ARRAY);
-
-    array->entries = 0;
-    array->size = 8;
-
-    array->table = jsonp_malloc(array->size * sizeof(json_t *));
-    if(!array->table) {
-        jsonp_free(array);
-        return NULL;
-    }
-
-    array->visited = 0;
-
-    return &array->json;
-}
-
-static void json_delete_array(json_array_t *array)
-{
-    size_t i;
-
-    for(i = 0; i < array->entries; i++)
-        json_decref(array->table[i]);
-
-    jsonp_free(array->table);
-    jsonp_free(array);
-}
-
-size_t json_array_size(const json_t *json)
-{
-    if(!json_is_array(json))
-        return 0;
-
-    return json_to_array(json)->entries;
-}
-
-json_t *json_array_get(const json_t *json, size_t index)
-{
-    json_array_t *array;
-    if(!json_is_array(json))
-        return NULL;
-    array = json_to_array(json);
-
-    if(index >= array->entries)
-        return NULL;
-
-    return array->table[index];
-}
-
-int json_array_set_new(json_t *json, size_t index, json_t *value)
-{
-    json_array_t *array;
-
-    if(!value)
-        return -1;
-
-    if(!json_is_array(json) || json == value)
-    {
-        json_decref(value);
-        return -1;
-    }
-    array = json_to_array(json);
-
-    if(index >= array->entries)
-    {
-        json_decref(value);
-        return -1;
-    }
-
-    json_decref(array->table[index]);
-    array->table[index] = value;
-
-    return 0;
-}
-
-static void array_move(json_array_t *array, size_t dest,
-                       size_t src, size_t count)
-{
-    memmove(&array->table[dest], &array->table[src], count * sizeof(json_t *));
-}
-
-static void array_copy(json_t **dest, size_t dpos,
-                       json_t **src, size_t spos,
-                       size_t count)
-{
-    memcpy(&dest[dpos], &src[spos], count * sizeof(json_t *));
-}
-
-static json_t **json_array_grow(json_array_t *array,
-                                size_t amount,
-                                int copy)
-{
-    size_t new_size;
-    json_t **old_table, **new_table;
-
-    if(array->entries + amount <= array->size)
-        return array->table;
-
-    old_table = array->table;
-
-    new_size = max(array->size + amount, array->size * 2);
-    new_table = jsonp_malloc(new_size * sizeof(json_t *));
-    if(!new_table)
-        return NULL;
-
-    array->size = new_size;
-    array->table = new_table;
-
-    if(copy) {
-        array_copy(array->table, 0, old_table, 0, array->entries);
-        jsonp_free(old_table);
-        return array->table;
-    }
-
-    return old_table;
-}
-
-int json_array_append_new(json_t *json, json_t *value)
-{
-    json_array_t *array;
-
-    if(!value)
-        return -1;
-
-    if(!json_is_array(json) || json == value)
-    {
-        json_decref(value);
-        return -1;
-    }
-    array = json_to_array(json);
-
-    if(!json_array_grow(array, 1, 1)) {
-        json_decref(value);
-        return -1;
-    }
-
-    array->table[array->entries] = value;
-    array->entries++;
-
-    return 0;
-}
-
-int json_array_insert_new(json_t *json, size_t index, json_t *value)
-{
-    json_array_t *array;
-    json_t **old_table;
-
-    if(!value)
-        return -1;
-
-    if(!json_is_array(json) || json == value) {
-        json_decref(value);
-        return -1;
-    }
-    array = json_to_array(json);
-
-    if(index > array->entries) {
-        json_decref(value);
-        return -1;
-    }
-
-    old_table = json_array_grow(array, 1, 0);
-    if(!old_table) {
-        json_decref(value);
-        return -1;
-    }
-
-    if(old_table != array->table) {
-        array_copy(array->table, 0, old_table, 0, index);
-        array_copy(array->table, index + 1, old_table, index,
-                   array->entries - index);
-        jsonp_free(old_table);
-    }
-    else
-        array_move(array, index + 1, index, array->entries - index);
-
-    array->table[index] = value;
-    array->entries++;
-
-    return 0;
-}
-
-int json_array_remove(json_t *json, size_t index)
-{
-    json_array_t *array;
-
-    if(!json_is_array(json))
-        return -1;
-    array = json_to_array(json);
-
-    if(index >= array->entries)
-        return -1;
-
-    json_decref(array->table[index]);
-
-    /* If we're removing the last element, nothing has to be moved */
-    if(index < array->entries - 1)
-        array_move(array, index, index + 1, array->entries - index - 1);
-
-    array->entries--;
-
-    return 0;
-}
-
-int json_array_clear(json_t *json)
-{
-    json_array_t *array;
-    size_t i;
-
-    if(!json_is_array(json))
-        return -1;
-    array = json_to_array(json);
-
-    for(i = 0; i < array->entries; i++)
-        json_decref(array->table[i]);
-
-    array->entries = 0;
-    return 0;
-}
-
-int json_array_extend(json_t *json, json_t *other_json)
-{
-    json_array_t *array, *other;
-    size_t i;
-
-    if(!json_is_array(json) || !json_is_array(other_json))
-        return -1;
-    array = json_to_array(json);
-    other = json_to_array(other_json);
-
-    if(!json_array_grow(array, other->entries, 1))
-        return -1;
-
-    for(i = 0; i < other->entries; i++)
-        json_incref(other->table[i]);
-
-    array_copy(array->table, array->entries, other->table, 0, other->entries);
-
-    array->entries += other->entries;
-    return 0;
-}
-
-static int json_array_equal(json_t *array1, json_t *array2)
-{
-    size_t i, size;
-
-    size = json_array_size(array1);
-    if(size != json_array_size(array2))
-        return 0;
-
-    for(i = 0; i < size; i++)
-    {
-        json_t *value1, *value2;
-
-        value1 = json_array_get(array1, i);
-        value2 = json_array_get(array2, i);
-
-        if(!json_equal(value1, value2))
-            return 0;
-    }
-
-    return 1;
-}
-
-static json_t *json_array_copy(json_t *array)
-{
-    json_t *result;
-    size_t i;
-
-    result = json_array();
-    if(!result)
-        return NULL;
-
-    for(i = 0; i < json_array_size(array); i++)
-        json_array_append(result, json_array_get(array, i));
-
-    return result;
-}
-
-static json_t *json_array_deep_copy(const json_t *array)
-{
-    json_t *result;
-    size_t i;
-
-    result = json_array();
-    if(!result)
-        return NULL;
-
-    for(i = 0; i < json_array_size(array); i++)
-        json_array_append_new(result, json_deep_copy(json_array_get(array, i)));
-
-    return result;
-}
-
-/*** string ***/
-
-static json_t *string_create(const char *value, size_t len, int own)
-{
-    char *v;
-    json_string_t *string;
-
-    if(!value)
-        return NULL;
-
-    if(own)
-        v = (char *)value;
-    else {
-        v = jsonp_strndup(value, len);
-        if(!v)
-            return NULL;
-    }
-
-    string = jsonp_malloc(sizeof(json_string_t));
-    if(!string) {
-        if(!own)
-            jsonp_free(v);
-        return NULL;
-    }
-    json_init(&string->json, JSON_STRING);
-    string->value = v;
-    string->length = len;
-
-    return &string->json;
-}
-
-json_t *json_string_nocheck(const char *value)
-{
-    if(!value)
-        return NULL;
-
-    return string_create(value, strlen(value), 0);
-}
-
-json_t *json_stringn_nocheck(const char *value, size_t len)
-{
-    return string_create(value, len, 0);
-}
-
-/* this is private; "steal" is not a public API concept */
-json_t *jsonp_stringn_nocheck_own(const char *value, size_t len)
-{
-    return string_create(value, len, 1);
-}
-
-json_t *json_string(const char *value)
-{
-    if(!value)
-        return NULL;
-
-    return json_stringn(value, strlen(value));
-}
-
-json_t *json_stringn(const char *value, size_t len)
-{
-    if(!value || !utf8_check_string(value, len))
-        return NULL;
-
-    return json_stringn_nocheck(value, len);
-}
-
-const char *json_string_value(const json_t *json)
-{
-    if(!json_is_string(json))
-        return NULL;
-
-    return json_to_string(json)->value;
-}
-
-size_t json_string_length(const json_t *json)
-{
-    if(!json_is_string(json))
-        return 0;
-
-    return json_to_string(json)->length;
-}
-
-int json_string_set_nocheck(json_t *json, const char *value)
-{
-    if(!value)
-        return -1;
-
-    return json_string_setn_nocheck(json, value, strlen(value));
-}
-
-int json_string_setn_nocheck(json_t *json, const char *value, size_t len)
-{
-    char *dup;
-    json_string_t *string;
-
-    if(!json_is_string(json) || !value)
-        return -1;
-
-    dup = jsonp_strndup(value, len);
-    if(!dup)
-        return -1;
-
-    string = json_to_string(json);
-    jsonp_free(string->value);
-    string->value = dup;
-    string->length = len;
-
-    return 0;
-}
-
-int json_string_set(json_t *json, const char *value)
-{
-    if(!value)
-        return -1;
-
-    return json_string_setn(json, value, strlen(value));
-}
-
-int json_string_setn(json_t *json, const char *value, size_t len)
-{
-    if(!value || !utf8_check_string(value, len))
-        return -1;
-
-    return json_string_setn_nocheck(json, value, len);
-}
-
-static void json_delete_string(json_string_t *string)
-{
-    jsonp_free(string->value);
-    jsonp_free(string);
-}
-
-static int json_string_equal(json_t *string1, json_t *string2)
-{
-    json_string_t *s1, *s2;
-
-    if(!json_is_string(string1) || !json_is_string(string2))
-        return 0;
-
-    s1 = json_to_string(string1);
-    s2 = json_to_string(string2);
-    return s1->length == s2->length && !memcmp(s1->value, s2->value, s1->length);
-}
-
-static json_t *json_string_copy(const json_t *string)
-{
-    json_string_t *s;
-
-    if(!json_is_string(string))
-        return NULL;
-
-    s = json_to_string(string);
-    return json_stringn_nocheck(s->value, s->length);
-}
-
-
-/*** integer ***/
-
-json_t *json_integer(json_int_t value)
-{
-    json_integer_t *integer = jsonp_malloc(sizeof(json_integer_t));
-    if(!integer)
-        return NULL;
-    json_init(&integer->json, JSON_INTEGER);
-
-    integer->value = value;
-    return &integer->json;
-}
-
-json_int_t json_integer_value(const json_t *json)
-{
-    if(!json_is_integer(json))
-        return 0;
-
-    return json_to_integer(json)->value;
-}
-
-int json_integer_set(json_t *json, json_int_t value)
-{
-    if(!json_is_integer(json))
-        return -1;
-
-    json_to_integer(json)->value = value;
-
-    return 0;
-}
-
-static void json_delete_integer(json_integer_t *integer)
-{
-    jsonp_free(integer);
-}
-
-static int json_integer_equal(json_t *integer1, json_t *integer2)
-{
-    return json_integer_value(integer1) == json_integer_value(integer2);
-}
-
-static json_t *json_integer_copy(const json_t *integer)
-{
-    return json_integer(json_integer_value(integer));
-}
-
-
-/*** real ***/
-
-json_t *json_real(double value)
-{
-    json_real_t *real;
-
-    if(isnan(value) || isinf(value))
-        return NULL;
-
-    real = jsonp_malloc(sizeof(json_real_t));
-    if(!real)
-        return NULL;
-    json_init(&real->json, JSON_REAL);
-
-    real->value = value;
-    return &real->json;
-}
-
-double json_real_value(const json_t *json)
-{
-    if(!json_is_real(json))
-        return 0;
-
-    return json_to_real(json)->value;
-}
-
-int json_real_set(json_t *json, double value)
-{
-    if(!json_is_real(json) || isnan(value) || isinf(value))
-        return -1;
-
-    json_to_real(json)->value = value;
-
-    return 0;
-}
-
-static void json_delete_real(json_real_t *real)
-{
-    jsonp_free(real);
-}
-
-static int json_real_equal(json_t *real1, json_t *real2)
-{
-    return json_real_value(real1) == json_real_value(real2);
-}
-
-static json_t *json_real_copy(const json_t *real)
-{
-    return json_real(json_real_value(real));
-}
-
-
-/*** number ***/
-
-double json_number_value(const json_t *json)
-{
-    if(json_is_integer(json))
-        return (double)json_integer_value(json);
-    else if(json_is_real(json))
-        return json_real_value(json);
-    else
-        return 0.0;
-}
-
-
-/*** simple values ***/
-
-json_t *json_true(void)
-{
-    static json_t the_true = {JSON_TRUE, (size_t)-1};
-    return &the_true;
-}
-
-
-json_t *json_false(void)
-{
-    static json_t the_false = {JSON_FALSE, (size_t)-1};
-    return &the_false;
-}
-
-
-json_t *json_null(void)
-{
-    static json_t the_null = {JSON_NULL, (size_t)-1};
-    return &the_null;
-}
-
-
-/*** deletion ***/
-
-void json_delete(json_t *json)
-{
-    if(json_is_object(json))
-        json_delete_object(json_to_object(json));
-
-    else if(json_is_array(json))
-        json_delete_array(json_to_array(json));
-
-    else if(json_is_string(json))
-        json_delete_string(json_to_string(json));
-
-    else if(json_is_integer(json))
-        json_delete_integer(json_to_integer(json));
-
-    else if(json_is_real(json))
-        json_delete_real(json_to_real(json));
-
-    /* json_delete is not called for true, false or null */
-}
-
-
-/*** equality ***/
-
-int json_equal(json_t *json1, json_t *json2)
-{
-    if(!json1 || !json2)
-        return 0;
-
-    if(json_typeof(json1) != json_typeof(json2))
-        return 0;
-
-    /* this covers true, false and null as they are singletons */
-    if(json1 == json2)
-        return 1;
-
-    if(json_is_object(json1))
-        return json_object_equal(json1, json2);
-
-    if(json_is_array(json1))
-        return json_array_equal(json1, json2);
-
-    if(json_is_string(json1))
-        return json_string_equal(json1, json2);
-
-    if(json_is_integer(json1))
-        return json_integer_equal(json1, json2);
-
-    if(json_is_real(json1))
-        return json_real_equal(json1, json2);
-
-    return 0;
-}
-
-
-/*** copying ***/
-
-json_t *json_copy(json_t *json)
-{
-    if(!json)
-        return NULL;
-
-    if(json_is_object(json))
-        return json_object_copy(json);
-
-    if(json_is_array(json))
-        return json_array_copy(json);
-
-    if(json_is_string(json))
-        return json_string_copy(json);
-
-    if(json_is_integer(json))
-        return json_integer_copy(json);
-
-    if(json_is_real(json))
-        return json_real_copy(json);
-
-    if(json_is_true(json) || json_is_false(json) || json_is_null(json))
-        return json;
-
-    return NULL;
-}
-
-json_t *json_deep_copy(const json_t *json)
-{
-    if(!json)
-        return NULL;
-
-    if(json_is_object(json))
-        return json_object_deep_copy(json);
-
-    if(json_is_array(json))
-        return json_array_deep_copy(json);
-
-    /* for the rest of the types, deep copying doesn't differ from
-       shallow copying */
-
-    if(json_is_string(json))
-        return json_string_copy(json);
-
-    if(json_is_integer(json))
-        return json_integer_copy(json);
-
-    if(json_is_real(json))
-        return json_real_copy(json);
-
-    if(json_is_true(json) || json_is_false(json) || json_is_null(json))
-        return (json_t *)json;
-
-    return NULL;
-}
diff --git a/deps/jansson/test/.gitignore b/deps/jansson/test/.gitignore
deleted file mode 100644
index ae6c8f9..0000000
--- a/deps/jansson/test/.gitignore
+++ /dev/null
@@ -1,17 +0,0 @@
-logs
-bin/json_process
-suites/api/test_array
-suites/api/test_copy
-suites/api/test_cpp
-suites/api/test_dump
-suites/api/test_dump_callback
-suites/api/test_equal
-suites/api/test_load
-suites/api/test_loadb
-suites/api/test_memory_funcs
-suites/api/test_number
-suites/api/test_object
-suites/api/test_pack
-suites/api/test_simple
-suites/api/test_unpack
-suites/api/test_load_callback
diff --git a/deps/jansson/test/Makefile.am b/deps/jansson/test/Makefile.am
deleted file mode 100644
index 86d1614..0000000
--- a/deps/jansson/test/Makefile.am
+++ /dev/null
@@ -1,10 +0,0 @@
-SUBDIRS = bin suites
-EXTRA_DIST = scripts run-suites
-
-TESTS = run-suites
-TESTS_ENVIRONMENT = \
-	top_srcdir=$(top_srcdir) \
-	top_builddir=$(top_builddir)
-
-clean-local:
-	rm -rf logs
diff --git a/deps/jansson/test/bin/Makefile.am b/deps/jansson/test/bin/Makefile.am
deleted file mode 100644
index 63b6dce..0000000
--- a/deps/jansson/test/bin/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-check_PROGRAMS = json_process
-
-AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src
-LDFLAGS = -static  # for speed and Valgrind
-LDADD = $(top_builddir)/src/libjansson.la
diff --git a/deps/jansson/test/bin/json_process.c b/deps/jansson/test/bin/json_process.c
deleted file mode 100644
index 23afefe..0000000
--- a/deps/jansson/test/bin/json_process.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <jansson.h>
-
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
- #endif
-
-#if _WIN32
-#include <io.h>  /* for _setmode() */
-#include <fcntl.h>  /* for _O_BINARY */
-
-static const char dir_sep = '\\';
-#else
-static const char dir_sep = '/';
-#endif
-
-
-struct config {
-    int indent;
-    int compact;
-    int preserve_order;
-    int ensure_ascii;
-    int sort_keys;
-    int strip;
-    int use_env;
-} conf;
-
-#define l_isspace(c) ((c) == ' ' || (c) == '\n' || (c) == '\r' || (c) == '\t')
-
-/* Return a pointer to the first non-whitespace character of str.
-   Modifies str so that all trailing whitespace characters are
-   replaced by '\0'. */
-static const char *strip(char *str)
-{
-    size_t length;
-    char *result = str;
-    while (*result && l_isspace(*result))
-        result++;
-
-    length = strlen(result);
-    if (length == 0)
-        return result;
-
-    while (l_isspace(result[length - 1]))
-        result[--length] = '\0';
-
-    return result;
-}
-
-
-static char *loadfile(FILE *file)
-{
-    long fsize, ret;
-    char *buf;
-
-    fseek(file, 0, SEEK_END);
-    fsize = ftell(file);
-    fseek(file, 0, SEEK_SET);
-
-    buf = malloc(fsize+1);
-    ret = fread(buf, 1, fsize, file);
-    if (ret != fsize)
-        exit(1);
-    buf[fsize] = '\0';
-
-    return buf;
-}
-
-
-static void read_conf(FILE *conffile)
-{
-    char *buffer, *line, *val;
-
-    buffer = loadfile(conffile);
-    for (line = strtok(buffer, "\r\n"); line; line = strtok(NULL, "\r\n")) {
-        if (!strncmp(line, "export ", 7))
-            continue;
-        val = strchr(line, '=');
-        if (!val) {
-            printf("invalid configuration line\n");
-            break;
-        }
-        *val++ = '\0';
-
-        if (!strcmp(line, "JSON_INDENT"))
-            conf.indent = atoi(val);
-        if (!strcmp(line, "JSON_COMPACT"))
-            conf.compact = atoi(val);
-        if (!strcmp(line, "JSON_ENSURE_ASCII"))
-            conf.ensure_ascii = atoi(val);
-        if (!strcmp(line, "JSON_PRESERVE_ORDER"))
-            conf.preserve_order = atoi(val);
-        if (!strcmp(line, "JSON_SORT_KEYS"))
-            conf.sort_keys = atoi(val);
-        if (!strcmp(line, "STRIP"))
-            conf.strip = atoi(val);
-    }
-
-    free(buffer);
-}
-
-
-static int cmpfile(const char *str, const char *path, const char *fname)
-{
-    char filename[1024], *buffer;
-    int ret;
-    FILE *file;
-
-    sprintf(filename, "%s%c%s", path, dir_sep, fname);
-    file = fopen(filename, "rb");
-    if (!file) {
-        if (conf.strip)
-            strcat(filename, ".strip");
-        else
-            strcat(filename, ".normal");
-        file = fopen(filename, "rb");
-    }
-    if (!file) {
-        printf("Error: test result file could not be opened.\n");
-        exit(1);
-    }
-
-    buffer = loadfile(file);
-    if (strcmp(buffer, str) != 0)
-        ret = 1;
-    else
-        ret = 0;
-    free(buffer);
-    fclose(file);
-
-    return ret;
-}
-
-int use_conf(char *test_path)
-{
-    int ret;
-    size_t flags = 0;
-    char filename[1024], errstr[1024];
-    char *buffer;
-    FILE *infile, *conffile;
-    json_t *json;
-    json_error_t error;
-
-    sprintf(filename, "%s%cinput", test_path, dir_sep);
-    if (!(infile = fopen(filename, "rb"))) {
-        fprintf(stderr, "Could not open \"%s\"\n", filename);
-        return 2;
-    }
-
-    sprintf(filename, "%s%cenv", test_path, dir_sep);
-    conffile = fopen(filename, "rb");
-    if (conffile) {
-        read_conf(conffile);
-        fclose(conffile);
-    }
-
-    if (conf.indent < 0 || conf.indent > 255) {
-        fprintf(stderr, "invalid value for JSON_INDENT: %d\n", conf.indent);
-        return 2;
-    }
-
-    if (conf.indent)
-        flags |= JSON_INDENT(conf.indent);
-
-    if (conf.compact)
-        flags |= JSON_COMPACT;
-
-    if (conf.ensure_ascii)
-        flags |= JSON_ENSURE_ASCII;
-
-    if (conf.preserve_order)
-        flags |= JSON_PRESERVE_ORDER;
-
-    if (conf.sort_keys)
-        flags |= JSON_SORT_KEYS;
-
-    if (conf.strip) {
-        /* Load to memory, strip leading and trailing whitespace */
-        buffer = loadfile(infile);
-        json = json_loads(strip(buffer), 0, &error);
-        free(buffer);
-    }
-    else
-        json = json_loadf(infile, 0, &error);
-
-    fclose(infile);
-
-    if (!json) {
-        sprintf(errstr, "%d %d %d\n%s\n",
-                error.line, error.column, error.position,
-                error.text);
-
-        ret = cmpfile(errstr, test_path, "error");
-        return ret;
-    }
-
-    buffer = json_dumps(json, flags);
-    ret = cmpfile(buffer, test_path, "output");
-    free(buffer);
-    json_decref(json);
-
-    return ret;
-}
-
-static int getenv_int(const char *name)
-{
-    char *value, *end;
-    long result;
-
-    value = getenv(name);
-    if(!value)
-        return 0;
-
-    result = strtol(value, &end, 10);
-    if(*end != '\0')
-        return 0;
-
-    return (int)result;
-}
-
-int use_env()
-{
-    int indent;
-    size_t flags = 0;
-    json_t *json;
-    json_error_t error;
-
-    #ifdef _WIN32
-    /* On Windows, set stdout and stderr to binary mode to avoid
-       outputting DOS line terminators */
-    _setmode(_fileno(stdout), _O_BINARY);
-    _setmode(_fileno(stderr), _O_BINARY);
-    #endif
-
-    indent = getenv_int("JSON_INDENT");
-    if(indent < 0 || indent > 255) {
-        fprintf(stderr, "invalid value for JSON_INDENT: %d\n", indent);
-        return 2;
-    }
-
-    if(indent > 0)
-        flags |= JSON_INDENT(indent);
-
-    if(getenv_int("JSON_COMPACT") > 0)
-        flags |= JSON_COMPACT;
-
-    if(getenv_int("JSON_ENSURE_ASCII"))
-        flags |= JSON_ENSURE_ASCII;
-
-    if(getenv_int("JSON_PRESERVE_ORDER"))
-        flags |= JSON_PRESERVE_ORDER;
-
-    if(getenv_int("JSON_SORT_KEYS"))
-         flags |= JSON_SORT_KEYS;
-
-    if(getenv_int("STRIP")) {
-        /* Load to memory, strip leading and trailing whitespace */
-        size_t size = 0, used = 0;
-        char *buffer = NULL;
-
-        while(1) {
-            size_t count;
-
-            size = (size == 0 ? 128 : size * 2);
-            buffer = realloc(buffer, size);
-            if(!buffer) {
-                fprintf(stderr, "Unable to allocate %d bytes\n", (int)size);
-                return 1;
-            }
-
-            count = fread(buffer + used, 1, size - used, stdin);
-            if(count < size - used) {
-                buffer[used + count] = '\0';
-                break;
-            }
-            used += count;
-        }
-
-        json = json_loads(strip(buffer), 0, &error);
-        free(buffer);
-    }
-    else
-        json = json_loadf(stdin, 0, &error);
-
-    if(!json) {
-        fprintf(stderr, "%d %d %d\n%s\n",
-            error.line, error.column,
-            error.position, error.text);
-        return 1;
-    }
-
-    json_dumpf(json, stdout, flags);
-    json_decref(json);
-
-    return 0;
-}
-
-int main(int argc, char *argv[])
-{
-    int i;
-    char *test_path = NULL;
-
-    #ifdef HAVE_SETLOCALE
-    setlocale(LC_ALL, "");
-    #endif
-
-    if (argc < 2) {
-        goto usage;
-    }
-
-    for (i = 1; i < argc; i++) {
-        if (!strcmp(argv[i], "--strip"))
-            conf.strip = 1;
-        else if (!strcmp(argv[i], "--env"))
-            conf.use_env = 1;
-        else
-            test_path = argv[i];
-    }
-
-    if (conf.use_env)
-        return use_env();
-    else
-    {
-        if (!test_path)
-            goto usage;
-
-        return use_conf(test_path);
-    }
-
-usage:
-    fprintf(stderr, "argc =%d\n", argc);
-    fprintf(stderr, "usage: %s [--strip] [--env] test_dir\n", argv[0]);
-    return 2;
-}
diff --git a/deps/jansson/test/run-suites b/deps/jansson/test/run-suites
deleted file mode 100755
index 4cbaa8b..0000000
--- a/deps/jansson/test/run-suites
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/bin/sh
-
-while [ -n "$1" ]; do
-    suite=$1
-    if [ -x $top_srcdir/test/suites/$suite/run ]; then
-        SUITES="$SUITES $suite"
-    else
-        echo "No such suite: $suite"
-        exit 1
-    fi
-    shift
-done
-
-if [ -z "$SUITES" ]; then
-    suitedirs=$top_srcdir/test/suites/*
-    for suitedir in $suitedirs; do
-        if [ -d $suitedir ]; then
-            SUITES="$SUITES `basename $suitedir`"
-        fi
-    done
-fi
-
-[ -z "$STOP" ] && STOP=0
-
-suites_srcdir=$top_srcdir/test/suites
-suites_builddir=suites
-scriptdir=$top_srcdir/test/scripts
-logdir=logs
-bindir=bin
-export suites_srcdir suites_builddir scriptdir logdir bindir
-
-passed=0
-failed=0
-for suite in $SUITES; do
-    echo "Suite: $suite"
-    if $suites_srcdir/$suite/run $suite; then
-        passed=$(($passed+1))
-    else
-        failed=$(($failed+1))
-        [ $STOP -eq 1 ] && break
-    fi
-done
-
-if [ $failed -gt 0 ]; then
-    echo "$failed of $((passed+failed)) test suites failed"
-    exit 1
-else
-    echo "$passed test suites passed"
-    rm -rf $logdir
-fi
diff --git a/deps/jansson/test/scripts/run-tests.sh b/deps/jansson/test/scripts/run-tests.sh
deleted file mode 100644
index 5ed3b9f..0000000
--- a/deps/jansson/test/scripts/run-tests.sh
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
-#
-# Jansson is free software; you can redistribute it and/or modify
-# it under the terms of the MIT license. See LICENSE for details.
-
-die() {
-    echo "$1" >&2
-    exit 1
-}
-
-[ -n "$1" ] || die "Usage: $0 suite-name"
-[ -n "$bindir" ] || die "Set bindir"
-[ -n "$logdir" ] || die "Set logdir"
-[ -n "$scriptdir" ] || die "Set scriptdir"
-[ -n "$suites_srcdir" ] || die "Set suites_srcdir"
-[ -n "$suites_builddir" ] || die "Set suites_builddir"
-
-json_process=$bindir/json_process
-
-suite_name=$1
-suite_srcdir=$suites_srcdir/$suite_name
-suite_builddir=$suites_builddir/$suite_name
-suite_log=$logdir/$suite_name
-
-[ -z "$VERBOSE" ] && VERBOSE=0
-[ -z "$STOP" ] && STOP=0
-
-. $scriptdir/valgrind.sh
-
-rm -rf $suite_log
-mkdir -p $suite_log
-
-for test_path in $suite_srcdir/*; do
-    test_name=$(basename $test_path)
-    test_builddir=$suite_builddir/$test_name
-    test_log=$suite_log/$test_name
-
-    [ "$test_name" = "run" ] && continue
-    is_test || continue
-
-    rm -rf $test_log
-    mkdir -p $test_log
-    if [ $VERBOSE -eq 1 ]; then
-        printf '%s... ' "$test_name"
-    fi
-
-    run_test
-    case $? in
-        0)
-            # Success
-            if [ $VERBOSE -eq 1 ]; then
-                printf 'ok\n'
-            else
-                printf '.'
-            fi
-            rm -rf $test_log
-            ;;
-
-        77)
-            # Skip
-            if [ $VERBOSE -eq 1 ]; then
-                printf 'skipped\n'
-            else
-                printf 'S'
-            fi
-            rm -rf $test_log
-            ;;
-
-        *)
-            # Failure
-            if [ $VERBOSE -eq 1 ]; then
-                printf 'FAILED\n'
-            else
-                printf 'F'
-            fi
-
-            [ $STOP -eq 1 ] && break
-            ;;
-    esac
-done
-
-if [ $VERBOSE -eq 0 ]; then
-    printf '\n'
-fi
-
-if [ -n "$(ls -A $suite_log)" ]; then
-    for test_log in $suite_log/*; do
-        test_name=$(basename $test_log)
-        test_path=$suite_srcdir/$test_name
-        echo "================================================================="
-        echo "$suite_name/$test_name"
-        echo "================================================================="
-        show_error
-        echo
-    done
-    echo "================================================================="
-    exit 1
-else
-    rm -rf $suite_log
-fi
diff --git a/deps/jansson/test/scripts/valgrind.sh b/deps/jansson/test/scripts/valgrind.sh
deleted file mode 100644
index 9b00438..0000000
--- a/deps/jansson/test/scripts/valgrind.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
-#
-# Jansson is free software; you can redistribute it and/or modify
-# it under the terms of the MIT license. See LICENSE for details.
-
-[ -z "$VALGRIND" ] && VALGRIND=0
-
-VALGRIND_CMDLINE="valgrind --leak-check=full --show-reachable=yes --track-origins=yes -q"
-
-if [ $VALGRIND -eq 1 ]; then
-    test_runner="$VALGRIND_CMDLINE"
-    json_process="$VALGRIND_CMDLINE $json_process"
-else
-    test_runner=""
-fi
-
-valgrind_check() {
-    if [ $VALGRIND -eq 1 ]; then
-        # Check for Valgrind error output. The valgrind option
-        # --error-exitcode is not enough because Valgrind doesn't
-        # think unfreed allocs are errors.
-        if grep -E -q '^==[0-9]+== ' $1; then
-            touch $test_log/valgrind_error
-            return 1
-        fi
-    fi
-}
-
-valgrind_show_error() {
-    if [ $VALGRIND -eq 1 -a -f $test_log/valgrind_error ]; then
-        echo "valgrind detected an error"
-        return 0
-    fi
-    return 1
-}
diff --git a/deps/jansson/test/suites/.gitattributes b/deps/jansson/test/suites/.gitattributes
deleted file mode 100644
index 68d8861..0000000
--- a/deps/jansson/test/suites/.gitattributes
+++ /dev/null
@@ -1,2 +0,0 @@
-api/ text=auto
-* text eol=lf
\ No newline at end of file
diff --git a/deps/jansson/test/suites/Makefile.am b/deps/jansson/test/suites/Makefile.am
deleted file mode 100644
index a53eb07..0000000
--- a/deps/jansson/test/suites/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-SUBDIRS = api
-EXTRA_DIST = invalid invalid-unicode valid
diff --git a/deps/jansson/test/suites/api/Makefile.am b/deps/jansson/test/suites/api/Makefile.am
deleted file mode 100644
index 1dbdd2b..0000000
--- a/deps/jansson/test/suites/api/Makefile.am
+++ /dev/null
@@ -1,34 +0,0 @@
-EXTRA_DIST = run check-exports
-
-check_PROGRAMS = \
-	test_array \
-	test_copy \
-	test_dump \
-	test_dump_callback \
-	test_equal \
-	test_load \
-	test_loadb \
-	test_load_callback \
-	test_memory_funcs \
-	test_number \
-	test_object \
-	test_pack \
-	test_simple \
-	test_unpack
-
-test_array_SOURCES = test_array.c util.h
-test_copy_SOURCES = test_copy.c util.h
-test_dump_SOURCES = test_dump.c util.h
-test_dump_callback_SOURCES = test_dump_callback.c util.h
-test_load_SOURCES = test_load.c util.h
-test_loadb_SOURCES = test_loadb.c util.h
-test_memory_funcs_SOURCES = test_memory_funcs.c util.h
-test_number_SOURCES = test_number.c util.h
-test_object_SOURCES = test_object.c util.h
-test_pack_SOURCES = test_pack.c util.h
-test_simple_SOURCES = test_simple.c util.h
-test_unpack_SOURCES = test_unpack.c util.h
-
-AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src
-LDFLAGS = -static  # for speed and Valgrind
-LDADD = $(top_builddir)/src/libjansson.la
diff --git a/deps/jansson/test/suites/api/check-exports b/deps/jansson/test/suites/api/check-exports
deleted file mode 100755
index 9adca7d..0000000
--- a/deps/jansson/test/suites/api/check-exports
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-#
-# This test checks that libjansson.so exports the correct symbols.
-#
-
-SOFILE="../src/.libs/libjansson.so"
-
-# The list of symbols, which the shared object should export, is read
-# from the def file, which is used in Windows builds
-grep 'json_' $top_srcdir/src/jansson.def \
-    | sed -e 's/ //g' \
-    | sort \
-    >$test_log/exports
-
-nm -D $SOFILE >/dev/null >$test_log/symbols 2>/dev/null \
-    || exit 77  # Skip if "nm -D" doesn't seem to work
-
-grep ' [DT] ' $test_log/symbols | cut -d' ' -f3 | grep -v '^_' | sort >$test_log/output
-
-if ! cmp -s $test_log/exports $test_log/output; then
-    diff -u $test_log/exports $test_log/output >&2
-    exit 1
-fi
diff --git a/deps/jansson/test/suites/api/run b/deps/jansson/test/suites/api/run
deleted file mode 100755
index 5f8e959..0000000
--- a/deps/jansson/test/suites/api/run
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
-#
-# Jansson is free software; you can redistribute it and/or modify
-# it under the terms of the MIT license. See LICENSE for details.
-
-is_test() {
-    case "$test_name" in
-        *.c|check-exports)
-            return 0
-            ;;
-        *)
-            return 1
-            ;;
-    esac
-}
-
-run_test() {
-    if [ "$test_name" = "check-exports" ]; then
-        test_log=$test_log $test_path >$test_log/stdout 2>$test_log/stderr
-    else
-        $test_runner $suite_builddir/${test_name%.c} \
-            >$test_log/stdout \
-            2>$test_log/stderr \
-            || return 1
-        valgrind_check $test_log/stderr || return 1
-    fi
-}
-
-show_error() {
-    valgrind_show_error && return
-    cat $test_log/stderr
-}
-
-. $top_srcdir/test/scripts/run-tests.sh
diff --git a/deps/jansson/test/suites/api/test_array.c b/deps/jansson/test/suites/api/test_array.c
deleted file mode 100644
index 0a9447f..0000000
--- a/deps/jansson/test/suites/api/test_array.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <jansson.h>
-#include "util.h"
-
-static void test_misc(void)
-{
-    json_t *array, *five, *seven, *value;
-    size_t i;
-
-    array = json_array();
-    five = json_integer(5);
-    seven = json_integer(7);
-
-    if(!array)
-        fail("unable to create array");
-    if(!five || !seven)
-        fail("unable to create integer");
-
-    if(json_array_size(array) != 0)
-        fail("empty array has nonzero size");
-
-    if(!json_array_append(array, NULL))
-        fail("able to append NULL");
-
-    if(json_array_append(array, five))
-        fail("unable to append");
-
-    if(json_array_size(array) != 1)
-        fail("wrong array size");
-
-    value = json_array_get(array, 0);
-    if(!value)
-        fail("unable to get item");
-    if(value != five)
-        fail("got wrong value");
-
-    if(json_array_append(array, seven))
-        fail("unable to append value");
-
-    if(json_array_size(array) != 2)
-        fail("wrong array size");
-
-    value = json_array_get(array, 1);
-    if(!value)
-        fail("unable to get item");
-    if(value != seven)
-        fail("got wrong value");
-
-    if(json_array_set(array, 0, seven))
-        fail("unable to set value");
-
-    if(!json_array_set(array, 0, NULL))
-        fail("able to set NULL");
-
-    if(json_array_size(array) != 2)
-        fail("wrong array size");
-
-    value = json_array_get(array, 0);
-    if(!value)
-        fail("unable to get item");
-    if(value != seven)
-        fail("got wrong value");
-
-    if(json_array_get(array, 2) != NULL)
-        fail("able to get value out of bounds");
-
-    if(!json_array_set(array, 2, seven))
-        fail("able to set value out of bounds");
-
-    for(i = 2; i < 30; i++) {
-        if(json_array_append(array, seven))
-            fail("unable to append value");
-
-        if(json_array_size(array) != i + 1)
-            fail("wrong array size");
-    }
-
-    for(i = 0; i < 30; i++) {
-        value = json_array_get(array, i);
-        if(!value)
-            fail("unable to get item");
-        if(value != seven)
-            fail("got wrong value");
-    }
-
-    if(json_array_set_new(array, 15, json_integer(123)))
-        fail("unable to set new value");
-
-    value = json_array_get(array, 15);
-    if(!json_is_integer(value) || json_integer_value(value) != 123)
-        fail("json_array_set_new works incorrectly");
-
-    if(!json_array_set_new(array, 15, NULL))
-        fail("able to set_new NULL value");
-
-    if(json_array_append_new(array, json_integer(321)))
-        fail("unable to append new value");
-
-    value = json_array_get(array, json_array_size(array) - 1);
-    if(!json_is_integer(value) || json_integer_value(value) != 321)
-        fail("json_array_append_new works incorrectly");
-
-    if(!json_array_append_new(array, NULL))
-        fail("able to append_new NULL value");
-
-    json_decref(five);
-    json_decref(seven);
-    json_decref(array);
-}
-
-static void test_insert(void)
-{
-    json_t *array, *five, *seven, *eleven, *value;
-    int i;
-
-    array = json_array();
-    five = json_integer(5);
-    seven = json_integer(7);
-    eleven = json_integer(11);
-
-    if(!array)
-        fail("unable to create array");
-    if(!five || !seven || !eleven)
-        fail("unable to create integer");
-
-
-    if(!json_array_insert(array, 1, five))
-        fail("able to insert value out of bounds");
-
-
-    if(json_array_insert(array, 0, five))
-        fail("unable to insert value in an empty array");
-
-    if(json_array_get(array, 0) != five)
-        fail("json_array_insert works incorrectly");
-
-    if(json_array_size(array) != 1)
-        fail("array size is invalid after insertion");
-
-
-    if(json_array_insert(array, 1, seven))
-        fail("unable to insert value at the end of an array");
-
-    if(json_array_get(array, 0) != five)
-        fail("json_array_insert works incorrectly");
-
-    if(json_array_get(array, 1) != seven)
-        fail("json_array_insert works incorrectly");
-
-    if(json_array_size(array) != 2)
-        fail("array size is invalid after insertion");
-
-
-    if(json_array_insert(array, 1, eleven))
-        fail("unable to insert value in the middle of an array");
-
-    if(json_array_get(array, 0) != five)
-        fail("json_array_insert works incorrectly");
-
-    if(json_array_get(array, 1) != eleven)
-        fail("json_array_insert works incorrectly");
-
-    if(json_array_get(array, 2) != seven)
-        fail("json_array_insert works incorrectly");
-
-    if(json_array_size(array) != 3)
-        fail("array size is invalid after insertion");
-
-
-    if(json_array_insert_new(array, 2, json_integer(123)))
-        fail("unable to insert value in the middle of an array");
-
-    value = json_array_get(array, 2);
-    if(!json_is_integer(value) || json_integer_value(value) != 123)
-        fail("json_array_insert_new works incorrectly");
-
-    if(json_array_size(array) != 4)
-        fail("array size is invalid after insertion");
-
-
-    for(i = 0; i < 20; i++) {
-        if(json_array_insert(array, 0, seven))
-            fail("unable to insert value at the begining of an array");
-    }
-
-    for(i = 0; i < 20; i++) {
-        if(json_array_get(array, i) != seven)
-            fail("json_aray_insert works incorrectly");
-    }
-
-    if(json_array_size(array) != 24)
-        fail("array size is invalid after loop insertion");
-
-    json_decref(five);
-    json_decref(seven);
-    json_decref(eleven);
-    json_decref(array);
-}
-
-static void test_remove(void)
-{
-    json_t *array, *five, *seven;
-    int i;
-
-    array = json_array();
-    five = json_integer(5);
-    seven = json_integer(7);
-
-    if(!array)
-        fail("unable to create array");
-    if(!five)
-        fail("unable to create integer");
-    if(!seven)
-        fail("unable to create integer");
-
-
-    if(!json_array_remove(array, 0))
-        fail("able to remove an unexisting index");
-
-
-    if(json_array_append(array, five))
-        fail("unable to append");
-
-    if(!json_array_remove(array, 1))
-        fail("able to remove an unexisting index");
-
-    if(json_array_remove(array, 0))
-        fail("unable to remove");
-
-    if(json_array_size(array) != 0)
-        fail("array size is invalid after removing");
-
-
-    if(json_array_append(array, five) ||
-       json_array_append(array, seven) ||
-       json_array_append(array, five) ||
-       json_array_append(array, seven))
-        fail("unable to append");
-
-    if(json_array_remove(array, 2))
-        fail("unable to remove");
-
-    if(json_array_size(array) != 3)
-        fail("array size is invalid after removing");
-
-    if(json_array_get(array, 0) != five ||
-       json_array_get(array, 1) != seven ||
-       json_array_get(array, 2) != seven)
-        fail("remove works incorrectly");
-
-    json_decref(array);
-
-    array = json_array();
-    for(i = 0; i < 4; i++) {
-        json_array_append(array, five);
-        json_array_append(array, seven);
-    }
-    if(json_array_size(array) != 8)
-        fail("unable to append 8 items to array");
-
-    /* Remove an element from a "full" array. */
-    json_array_remove(array, 5);
-
-    json_decref(five);
-    json_decref(seven);
-    json_decref(array);
-}
-
-static void test_clear(void)
-{
-    json_t *array, *five, *seven;
-    int i;
-
-    array = json_array();
-    five = json_integer(5);
-    seven = json_integer(7);
-
-    if(!array)
-        fail("unable to create array");
-    if(!five || !seven)
-        fail("unable to create integer");
-
-    for(i = 0; i < 10; i++) {
-        if(json_array_append(array, five))
-            fail("unable to append");
-    }
-    for(i = 0; i < 10; i++) {
-        if(json_array_append(array, seven))
-            fail("unable to append");
-    }
-
-    if(json_array_size(array) != 20)
-        fail("array size is invalid after appending");
-
-    if(json_array_clear(array))
-        fail("unable to clear");
-
-    if(json_array_size(array) != 0)
-        fail("array size is invalid after clearing");
-
-    json_decref(five);
-    json_decref(seven);
-    json_decref(array);
-}
-
-static void test_extend(void)
-{
-    json_t *array1, *array2, *five, *seven;
-    int i;
-
-    array1 = json_array();
-    array2 = json_array();
-    five = json_integer(5);
-    seven = json_integer(7);
-
-    if(!array1 || !array2)
-        fail("unable to create array");
-    if(!five || !seven)
-        fail("unable to create integer");
-
-    for(i = 0; i < 10; i++) {
-        if(json_array_append(array1, five))
-            fail("unable to append");
-    }
-    for(i = 0; i < 10; i++) {
-        if(json_array_append(array2, seven))
-            fail("unable to append");
-    }
-
-    if(json_array_size(array1) != 10 || json_array_size(array2) != 10)
-        fail("array size is invalid after appending");
-
-    if(json_array_extend(array1, array2))
-        fail("unable to extend");
-
-    for(i = 0; i < 10; i++) {
-        if(json_array_get(array1, i) != five)
-            fail("invalid array contents after extending");
-    }
-    for(i = 10; i < 20; i++) {
-        if(json_array_get(array1, i) != seven)
-            fail("invalid array contents after extending");
-    }
-
-    json_decref(five);
-    json_decref(seven);
-    json_decref(array1);
-    json_decref(array2);
-}
-
-static void test_circular()
-{
-    json_t *array1, *array2;
-
-    /* the simple cases are checked */
-
-    array1 = json_array();
-    if(!array1)
-        fail("unable to create array");
-
-    if(json_array_append(array1, array1) == 0)
-        fail("able to append self");
-
-    if(json_array_insert(array1, 0, array1) == 0)
-        fail("able to insert self");
-
-    if(json_array_append_new(array1, json_true()))
-        fail("failed to append true");
-
-    if(json_array_set(array1, 0, array1) == 0)
-        fail("able to set self");
-
-    json_decref(array1);
-
-
-    /* create circular references */
-
-    array1 = json_array();
-    array2 = json_array();
-    if(!array1 || !array2)
-        fail("unable to create array");
-
-    if(json_array_append(array1, array2) ||
-       json_array_append(array2, array1))
-        fail("unable to append");
-
-    /* circularity is detected when dumping */
-    if(json_dumps(array1, 0) != NULL)
-        fail("able to dump circulars");
-
-    /* decref twice to deal with the circular references */
-    json_decref(array1);
-    json_decref(array2);
-    json_decref(array1);
-}
-
-static void test_array_foreach()
-{
-    size_t index;
-    json_t *array1, *array2, *value;
-
-    array1 = json_pack("[sisisi]", "foo", 1, "bar", 2, "baz", 3);
-    array2 = json_array();
-
-    json_array_foreach(array1, index, value) {
-        json_array_append(array2, value);
-    }
-    
-    if(!json_equal(array1, array2))
-        fail("json_array_foreach failed to iterate all elements");
-
-    json_decref(array1);
-    json_decref(array2);
-}
-
-
-static void run_tests()
-{
-    test_misc();
-    test_insert();
-    test_remove();
-    test_clear();
-    test_extend();
-    test_circular();
-    test_array_foreach();
-}
diff --git a/deps/jansson/test/suites/api/test_copy.c b/deps/jansson/test/suites/api/test_copy.c
deleted file mode 100644
index 580488d..0000000
--- a/deps/jansson/test/suites/api/test_copy.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <string.h>
-#include <jansson.h>
-#include "util.h"
-
-static void test_copy_simple(void)
-{
-    json_t *value, *copy;
-
-    if(json_copy(NULL))
-        fail("copying NULL doesn't return NULL");
-
-    /* true */
-    value = json_true();
-    copy = json_copy(value);
-    if(value != copy)
-        fail("copying true failed");
-    json_decref(value);
-    json_decref(copy);
-
-    /* false */
-    value = json_false();
-    copy = json_copy(value);
-    if(value != copy)
-        fail("copying false failed");
-    json_decref(value);
-    json_decref(copy);
-
-    /* null */
-    value = json_null();
-    copy = json_copy(value);
-    if(value != copy)
-        fail("copying null failed");
-    json_decref(value);
-    json_decref(copy);
-
-    /* string */
-    value = json_string("foo");
-    if(!value)
-        fail("unable to create a string");
-    copy = json_copy(value);
-    if(!copy)
-        fail("unable to copy a string");
-    if(copy == value)
-        fail("copying a string doesn't copy");
-    if(!json_equal(copy, value))
-        fail("copying a string produces an inequal copy");
-    if(value->refcount != 1 || copy->refcount != 1)
-        fail("invalid refcounts");
-    json_decref(value);
-    json_decref(copy);
-
-    /* integer */
-    value = json_integer(543);
-    if(!value)
-        fail("unable to create an integer");
-    copy = json_copy(value);
-    if(!copy)
-        fail("unable to copy an integer");
-    if(copy == value)
-        fail("copying an integer doesn't copy");
-    if(!json_equal(copy, value))
-        fail("copying an integer produces an inequal copy");
-    if(value->refcount != 1 || copy->refcount != 1)
-        fail("invalid refcounts");
-    json_decref(value);
-    json_decref(copy);
-
-    /* real */
-    value = json_real(123e9);
-    if(!value)
-        fail("unable to create a real");
-    copy = json_copy(value);
-    if(!copy)
-        fail("unable to copy a real");
-    if(copy == value)
-        fail("copying a real doesn't copy");
-    if(!json_equal(copy, value))
-        fail("copying a real produces an inequal copy");
-    if(value->refcount != 1 || copy->refcount != 1)
-        fail("invalid refcounts");
-    json_decref(value);
-    json_decref(copy);
-}
-
-static void test_deep_copy_simple(void)
-{
-    json_t *value, *copy;
-
-    if(json_deep_copy(NULL))
-        fail("deep copying NULL doesn't return NULL");
-
-    /* true */
-    value = json_true();
-    copy = json_deep_copy(value);
-    if(value != copy)
-        fail("deep copying true failed");
-    json_decref(value);
-    json_decref(copy);
-
-    /* false */
-    value = json_false();
-    copy = json_deep_copy(value);
-    if(value != copy)
-        fail("deep copying false failed");
-    json_decref(value);
-    json_decref(copy);
-
-    /* null */
-    value = json_null();
-    copy = json_deep_copy(value);
-    if(value != copy)
-        fail("deep copying null failed");
-    json_decref(value);
-    json_decref(copy);
-
-    /* string */
-    value = json_string("foo");
-    if(!value)
-        fail("unable to create a string");
-    copy = json_deep_copy(value);
-    if(!copy)
-        fail("unable to deep copy a string");
-    if(copy == value)
-        fail("deep copying a string doesn't copy");
-    if(!json_equal(copy, value))
-        fail("deep copying a string produces an inequal copy");
-    if(value->refcount != 1 || copy->refcount != 1)
-        fail("invalid refcounts");
-    json_decref(value);
-    json_decref(copy);
-
-    /* integer */
-    value = json_integer(543);
-    if(!value)
-        fail("unable to create an integer");
-    copy = json_deep_copy(value);
-    if(!copy)
-        fail("unable to deep copy an integer");
-    if(copy == value)
-        fail("deep copying an integer doesn't copy");
-    if(!json_equal(copy, value))
-        fail("deep copying an integer produces an inequal copy");
-    if(value->refcount != 1 || copy->refcount != 1)
-        fail("invalid refcounts");
-    json_decref(value);
-    json_decref(copy);
-
-    /* real */
-    value = json_real(123e9);
-    if(!value)
-        fail("unable to create a real");
-    copy = json_deep_copy(value);
-    if(!copy)
-        fail("unable to deep copy a real");
-    if(copy == value)
-        fail("deep copying a real doesn't copy");
-    if(!json_equal(copy, value))
-        fail("deep copying a real produces an inequal copy");
-    if(value->refcount != 1 || copy->refcount != 1)
-        fail("invalid refcounts");
-    json_decref(value);
-    json_decref(copy);
-}
-
-static void test_copy_array(void)
-{
-    const char *json_array_text = "[1, \"foo\", 3.141592, {\"foo\": \"bar\"}]";
-
-    json_t *array, *copy;
-    size_t i;
-
-    array = json_loads(json_array_text, 0, NULL);
-    if(!array)
-        fail("unable to parse an array");
-
-    copy = json_copy(array);
-    if(!copy)
-        fail("unable to copy an array");
-    if(copy == array)
-        fail("copying an array doesn't copy");
-    if(!json_equal(copy, array))
-        fail("copying an array produces an inequal copy");
-
-    for(i = 0; i < json_array_size(copy); i++)
-    {
-        if(json_array_get(array, i) != json_array_get(copy, i))
-            fail("copying an array modifies its elements");
-    }
-
-    json_decref(array);
-    json_decref(copy);
-}
-
-static void test_deep_copy_array(void)
-{
-    const char *json_array_text = "[1, \"foo\", 3.141592, {\"foo\": \"bar\"}]";
-
-    json_t *array, *copy;
-    size_t i;
-
-    array = json_loads(json_array_text, 0, NULL);
-    if(!array)
-        fail("unable to parse an array");
-
-    copy = json_deep_copy(array);
-    if(!copy)
-        fail("unable to deep copy an array");
-    if(copy == array)
-        fail("deep copying an array doesn't copy");
-    if(!json_equal(copy, array))
-        fail("deep copying an array produces an inequal copy");
-
-    for(i = 0; i < json_array_size(copy); i++)
-    {
-        if(json_array_get(array, i) == json_array_get(copy, i))
-            fail("deep copying an array doesn't copy its elements");
-    }
-
-    json_decref(array);
-    json_decref(copy);
-}
-
-static void test_copy_object(void)
-{
-    const char *json_object_text =
-        "{\"foo\": \"bar\", \"a\": 1, \"b\": 3.141592, \"c\": [1,2,3,4]}";
-
-    json_t *object, *copy;
-    void *iter;
-
-    object = json_loads(json_object_text, 0, NULL);
-    if(!object)
-        fail("unable to parse an object");
-
-    copy = json_copy(object);
-    if(!copy)
-        fail("unable to copy an object");
-    if(copy == object)
-        fail("copying an object doesn't copy");
-    if(!json_equal(copy, object))
-        fail("copying an object produces an inequal copy");
-
-    iter = json_object_iter(object);
-    while(iter)
-    {
-        const char *key;
-        json_t *value1, *value2;
-
-        key = json_object_iter_key(iter);
-        value1 = json_object_iter_value(iter);
-        value2 = json_object_get(copy, key);
-
-        if(value1 != value2)
-            fail("deep copying an object modifies its items");
-
-        iter = json_object_iter_next(object, iter);
-    }
-
-    json_decref(object);
-    json_decref(copy);
-}
-
-static void test_deep_copy_object(void)
-{
-    const char *json_object_text =
-        "{\"foo\": \"bar\", \"a\": 1, \"b\": 3.141592, \"c\": [1,2,3,4]}";
-
-    json_t *object, *copy;
-    void *iter;
-
-    object = json_loads(json_object_text, 0, NULL);
-    if(!object)
-        fail("unable to parse an object");
-
-    copy = json_deep_copy(object);
-    if(!copy)
-        fail("unable to deep copy an object");
-    if(copy == object)
-        fail("deep copying an object doesn't copy");
-    if(!json_equal(copy, object))
-        fail("deep copying an object produces an inequal copy");
-
-    iter = json_object_iter(object);
-    while(iter)
-    {
-        const char *key;
-        json_t *value1, *value2;
-
-        key = json_object_iter_key(iter);
-        value1 = json_object_iter_value(iter);
-        value2 = json_object_get(copy, key);
-
-        if(value1 == value2)
-            fail("deep copying an object doesn't copy its items");
-
-        iter = json_object_iter_next(object, iter);
-    }
-
-    json_decref(object);
-    json_decref(copy);
-}
-
-static void run_tests()
-{
-    test_copy_simple();
-    test_deep_copy_simple();
-    test_copy_array();
-    test_deep_copy_array();
-    test_copy_object();
-    test_deep_copy_object();
-}
diff --git a/deps/jansson/test/suites/api/test_dump.c b/deps/jansson/test/suites/api/test_dump.c
deleted file mode 100644
index 89e73a7..0000000
--- a/deps/jansson/test/suites/api/test_dump.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <jansson.h>
-#include <string.h>
-#include "util.h"
-
-static int encode_null_callback(const char *buffer, size_t size, void *data)
-{
-    (void)buffer;
-    (void)size;
-    (void)data;
-    return 0;
-}
-
-static void encode_null()
-{
-    if(json_dumps(NULL, JSON_ENCODE_ANY) != NULL)
-        fail("json_dumps didn't fail for NULL");
-
-    if(json_dumpf(NULL, stderr, JSON_ENCODE_ANY) != -1)
-        fail("json_dumpf didn't fail for NULL");
-
-    /* Don't test json_dump_file to avoid creating a file */
-
-    if(json_dump_callback(NULL, encode_null_callback, NULL, JSON_ENCODE_ANY) != -1)
-        fail("json_dump_callback didn't fail for NULL");
-}
-
-
-static void encode_twice()
-{
-    /* Encode an empty object/array, add an item, encode again */
-
-    json_t *json;
-    char *result;
-
-    json = json_object();
-    result = json_dumps(json, 0);
-    if(!result || strcmp(result, "{}"))
-      fail("json_dumps failed");
-    free(result);
-
-    json_object_set_new(json, "foo", json_integer(5));
-    result = json_dumps(json, 0);
-    if(!result || strcmp(result, "{\"foo\": 5}"))
-      fail("json_dumps failed");
-    free(result);
-
-    json_decref(json);
-
-    json = json_array();
-    result = json_dumps(json, 0);
-    if(!result || strcmp(result, "[]"))
-      fail("json_dumps failed");
-    free(result);
-
-    json_array_append_new(json, json_integer(5));
-    result = json_dumps(json, 0);
-    if(!result || strcmp(result, "[5]"))
-      fail("json_dumps failed");
-    free(result);
-
-    json_decref(json);
-}
-
-static void circular_references()
-{
-    /* Construct a JSON object/array with a circular reference:
-
-       object: {"a": {"b": {"c": <circular reference to $.a>}}}
-       array: [[[<circular reference to the $[0] array>]]]
-
-       Encode it, remove the circular reference and encode again.
-    */
-
-    json_t *json;
-    char *result;
-
-    json = json_object();
-    json_object_set_new(json, "a", json_object());
-    json_object_set_new(json_object_get(json, "a"), "b", json_object());
-    json_object_set(json_object_get(json_object_get(json, "a"), "b"), "c",
-                    json_object_get(json, "a"));
-
-    if(json_dumps(json, 0))
-        fail("json_dumps encoded a circular reference!");
-
-    json_object_del(json_object_get(json_object_get(json, "a"), "b"), "c");
-
-    result = json_dumps(json, 0);
-    if(!result || strcmp(result, "{\"a\": {\"b\": {}}}"))
-        fail("json_dumps failed!");
-    free(result);
-
-    json_decref(json);
-
-    json = json_array();
-    json_array_append_new(json, json_array());
-    json_array_append_new(json_array_get(json, 0), json_array());
-    json_array_append(json_array_get(json_array_get(json, 0), 0),
-                      json_array_get(json, 0));
-
-    if(json_dumps(json, 0))
-        fail("json_dumps encoded a circular reference!");
-
-    json_array_remove(json_array_get(json_array_get(json, 0), 0), 0);
-
-    result = json_dumps(json, 0);
-    if(!result || strcmp(result, "[[[]]]"))
-        fail("json_dumps failed!");
-    free(result);
-
-    json_decref(json);
-}
-
-static void encode_other_than_array_or_object()
-{
-    /* Encoding anything other than array or object should only
-     * succeed if the JSON_ENCODE_ANY flag is used */
-
-    json_t *json;
-    FILE *fp = NULL;
-    char *result;
-
-    json = json_string("foo");
-    if(json_dumps(json, 0) != NULL)
-        fail("json_dumps encoded a string!");
-    if(json_dumpf(json, fp, 0) == 0)
-        fail("json_dumpf encoded a string!");
-
-    result = json_dumps(json, JSON_ENCODE_ANY);
-    if(!result || strcmp(result, "\"foo\"") != 0)
-        fail("json_dumps failed to encode a string with JSON_ENCODE_ANY");
-
-    free(result);
-    json_decref(json);
-
-    json = json_integer(42);
-    if(json_dumps(json, 0) != NULL)
-        fail("json_dumps encoded an integer!");
-    if(json_dumpf(json, fp, 0) == 0)
-        fail("json_dumpf encoded an integer!");
-
-    result = json_dumps(json, JSON_ENCODE_ANY);
-    if(!result || strcmp(result, "42") != 0)
-        fail("json_dumps failed to encode an integer with JSON_ENCODE_ANY");
-
-    free(result);
-    json_decref(json);
-
-
-}
-
-static void escape_slashes()
-{
-    /* Test dump escaping slashes */
-
-    json_t *json;
-    char *result;
-
-    json = json_object();
-    json_object_set_new(json, "url", json_string("https://github.com/akheron/jansson"));
-
-    result = json_dumps(json, 0);
-    if(!result || strcmp(result, "{\"url\": \"https://github.com/akheron/jansson\"}"))
-        fail("json_dumps failed to not escape slashes");
-
-    free(result);
-
-    result = json_dumps(json, JSON_ESCAPE_SLASH);
-    if(!result || strcmp(result, "{\"url\": \"https:\\/\\/github.com\\/akheron\\/jansson\"}"))
-        fail("json_dumps failed to escape slashes");
-
-    free(result);
-    json_decref(json);
-}
-
-static void encode_nul_byte()
-{
-    json_t *json;
-    char *result;
-
-    json = json_stringn("nul byte \0 in string", 20);
-    result = json_dumps(json, JSON_ENCODE_ANY);
-    if(!result || memcmp(result, "\"nul byte \\u0000 in string\"", 27))
-        fail("json_dumps failed to dump an embedded NUL byte");
-
-    free(result);
-    json_decref(json);
-}
-
-static void run_tests()
-{
-    encode_null();
-    encode_twice();
-    circular_references();
-    encode_other_than_array_or_object();
-    escape_slashes();
-    encode_nul_byte();
-}
diff --git a/deps/jansson/test/suites/api/test_dump_callback.c b/deps/jansson/test/suites/api/test_dump_callback.c
deleted file mode 100644
index 4536d56..0000000
--- a/deps/jansson/test/suites/api/test_dump_callback.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <jansson.h>
-#include <string.h>
-#include <stdlib.h>
-#include "util.h"
-
-struct my_sink {
-    char *buf;
-    size_t off;
-    size_t cap;
-};
-
-static int my_writer(const char *buffer, size_t len, void *data) {
-    struct my_sink *s = data;
-    if (len > s->cap - s->off) {
-        return -1;
-    }
-    memcpy(s->buf + s->off, buffer, len);
-    s->off += len;
-    return 0;
-}
-
-static void run_tests()
-{
-    struct my_sink s;
-    json_t *json;
-    const char str[] = "[\"A\", {\"B\": \"C\", \"e\": false}, 1, null, \"foo\"]";
-    char *dumped_to_string;
-
-    json = json_loads(str, 0, NULL);
-    if(!json) {
-        fail("json_loads failed");
-    }
-
-    dumped_to_string = json_dumps(json, 0);
-    if (!dumped_to_string) {
-        json_decref(json);
-        fail("json_dumps failed");
-    }
-
-    s.off = 0;
-    s.cap = strlen(dumped_to_string);
-    s.buf = malloc(s.cap);
-    if (!s.buf) {
-        json_decref(json);
-        free(dumped_to_string);
-        fail("malloc failed");
-    }
-
-    if (json_dump_callback(json, my_writer, &s, 0) == -1) {
-        json_decref(json);
-        free(dumped_to_string);
-        free(s.buf);
-        fail("json_dump_callback failed on an exact-length sink buffer");
-    }
-
-    if (strncmp(dumped_to_string, s.buf, s.off) != 0) {
-        json_decref(json);
-        free(dumped_to_string);
-        free(s.buf);
-        fail("json_dump_callback and json_dumps did not produce identical output");
-    }
-
-    s.off = 1;
-    if (json_dump_callback(json, my_writer, &s, 0) != -1) {
-        json_decref(json);
-        free(dumped_to_string);
-        free(s.buf);
-        fail("json_dump_callback succeeded on a short buffer when it should have failed");
-    }
-
-    json_decref(json);
-    free(dumped_to_string);
-    free(s.buf);
-}
diff --git a/deps/jansson/test/suites/api/test_equal.c b/deps/jansson/test/suites/api/test_equal.c
deleted file mode 100644
index 354e5c9..0000000
--- a/deps/jansson/test/suites/api/test_equal.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <jansson.h>
-#include "util.h"
-
-static void test_equal_simple()
-{
-    json_t *value1, *value2;
-
-    if(json_equal(NULL, NULL))
-        fail("json_equal fails for two NULLs");
-
-    value1 = json_true();
-    if(json_equal(value1, NULL) || json_equal(NULL, value1))
-        fail("json_equal fails for NULL");
-
-    /* this covers true, false and null as they are singletons */
-    if(!json_equal(value1, value1))
-        fail("identical objects are not equal");
-    json_decref(value1);
-
-    /* integer */
-    value1 = json_integer(1);
-    value2 = json_integer(1);
-    if(!value1 || !value2)
-        fail("unable to create integers");
-    if(!json_equal(value1, value2))
-        fail("json_equal fails for two equal integers");
-    json_decref(value2);
-
-    value2 = json_integer(2);
-    if(!value2)
-        fail("unable to create an integer");
-    if(json_equal(value1, value2))
-        fail("json_equal fails for two inequal integers");
-
-    json_decref(value1);
-    json_decref(value2);
-
-    /* real */
-    value1 = json_real(1.2);
-    value2 = json_real(1.2);
-    if(!value1 || !value2)
-        fail("unable to create reals");
-    if(!json_equal(value1, value2))
-        fail("json_equal fails for two equal reals");
-    json_decref(value2);
-
-    value2 = json_real(3.141592);
-    if(!value2)
-        fail("unable to create an real");
-    if(json_equal(value1, value2))
-        fail("json_equal fails for two inequal reals");
-
-    json_decref(value1);
-    json_decref(value2);
-
-    /* string */
-    value1 = json_string("foo");
-    value2 = json_string("foo");
-    if(!value1 || !value2)
-        fail("unable to create strings");
-    if(!json_equal(value1, value2))
-        fail("json_equal fails for two equal strings");
-    json_decref(value2);
-
-    value2 = json_string("bar");
-    if(!value2)
-        fail("unable to create an string");
-    if(json_equal(value1, value2))
-        fail("json_equal fails for two inequal strings");
-
-    json_decref(value1);
-    json_decref(value2);
-}
-
-static void test_equal_array()
-{
-    json_t *array1, *array2;
-
-    array1 = json_array();
-    array2 = json_array();
-    if(!array1 || !array2)
-        fail("unable to create arrays");
-
-    if(!json_equal(array1, array2))
-        fail("json_equal fails for two empty arrays");
-
-    json_array_append_new(array1, json_integer(1));
-    json_array_append_new(array2, json_integer(1));
-    json_array_append_new(array1, json_string("foo"));
-    json_array_append_new(array2, json_string("foo"));
-    json_array_append_new(array1, json_integer(2));
-    json_array_append_new(array2, json_integer(2));
-    if(!json_equal(array1, array2))
-        fail("json_equal fails for two equal arrays");
-
-    json_array_remove(array2, 2);
-    if(json_equal(array1, array2))
-        fail("json_equal fails for two inequal arrays");
-
-    json_array_append_new(array2, json_integer(3));
-    if(json_equal(array1, array2))
-        fail("json_equal fails for two inequal arrays");
-
-    json_decref(array1);
-    json_decref(array2);
-}
-
-static void test_equal_object()
-{
-    json_t *object1, *object2;
-
-    object1 = json_object();
-    object2 = json_object();
-    if(!object1 || !object2)
-        fail("unable to create objects");
-
-    if(!json_equal(object1, object2))
-        fail("json_equal fails for two empty objects");
-
-    json_object_set_new(object1, "a", json_integer(1));
-    json_object_set_new(object2, "a", json_integer(1));
-    json_object_set_new(object1, "b", json_string("foo"));
-    json_object_set_new(object2, "b", json_string("foo"));
-    json_object_set_new(object1, "c", json_integer(2));
-    json_object_set_new(object2, "c", json_integer(2));
-    if(!json_equal(object1, object2))
-        fail("json_equal fails for two equal objects");
-
-    json_object_del(object2, "c");
-    if(json_equal(object1, object2))
-        fail("json_equal fails for two inequal objects");
-
-    json_object_set_new(object2, "c", json_integer(3));
-    if(json_equal(object1, object2))
-        fail("json_equal fails for two inequal objects");
-
-    json_object_del(object2, "c");
-    json_object_set_new(object2, "d", json_integer(2));
-    if(json_equal(object1, object2))
-        fail("json_equal fails for two inequal objects");
-
-    json_decref(object1);
-    json_decref(object2);
-}
-
-static void test_equal_complex()
-{
-    json_t *value1, *value2;
-
-    const char *complex_json =
-"{"
-"    \"integer\": 1, "
-"    \"real\": 3.141592, "
-"    \"string\": \"foobar\", "
-"    \"true\": true, "
-"    \"object\": {"
-"        \"array-in-object\": [1,true,\"foo\",{}],"
-"        \"object-in-object\": {\"foo\": \"bar\"}"
-"    },"
-"    \"array\": [\"foo\", false, null, 1.234]"
-"}";
-
-    value1 = json_loads(complex_json, 0, NULL);
-    value2 = json_loads(complex_json, 0, NULL);
-    if(!value1 || !value2)
-        fail("unable to parse JSON");
-    if(!json_equal(value1, value2))
-        fail("json_equal fails for two inequal strings");
-
-    json_decref(value1);
-    json_decref(value2);
-
-    /* TODO: There's no negative test case here */
-}
-
-static void run_tests()
-{
-    test_equal_simple();
-    test_equal_array();
-    test_equal_object();
-    test_equal_complex();
-}
diff --git a/deps/jansson/test/suites/api/test_load.c b/deps/jansson/test/suites/api/test_load.c
deleted file mode 100644
index eb52323..0000000
--- a/deps/jansson/test/suites/api/test_load.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <jansson.h>
-#include <string.h>
-#include "util.h"
-
-static void file_not_found()
-{
-    json_t *json;
-    json_error_t error;
-    char *pos;
-
-    json = json_load_file("/path/to/nonexistent/file.json", 0, &error);
-    if(json)
-        fail("json_load_file returned non-NULL for a nonexistent file");
-    if(error.line != -1)
-        fail("json_load_file returned an invalid line number");
-
-    /* The error message is locale specific, only check the beginning
-       of the error message. */
-
-    pos = strchr(error.text, ':');
-    if(!pos)
-        fail("json_load_file returne an invalid error message");
-
-    *pos = '\0';
-
-    if(strcmp(error.text, "unable to open /path/to/nonexistent/file.json") != 0)
-        fail("json_load_file returned an invalid error message");
-}
-
-static void reject_duplicates()
-{
-    json_error_t error;
-
-    if(json_loads("{\"foo\": 1, \"foo\": 2}", JSON_REJECT_DUPLICATES, &error))
-        fail("json_loads did not detect a duplicate key");
-    check_error("duplicate object key near '\"foo\"'", "<string>", 1, 16, 16);
-}
-
-static void disable_eof_check()
-{
-    json_error_t error;
-    json_t *json;
-
-    const char *text = "{\"foo\": 1} garbage";
-
-    if(json_loads(text, 0, &error))
-        fail("json_loads did not detect garbage after JSON text");
-    check_error("end of file expected near 'garbage'", "<string>", 1, 18, 18);
-
-    json = json_loads(text, JSON_DISABLE_EOF_CHECK, &error);
-    if(!json)
-        fail("json_loads failed with JSON_DISABLE_EOF_CHECK");
-
-    json_decref(json);
-}
-
-static void decode_any()
-{
-    json_t *json;
-    json_error_t error;
-
-    json = json_loads("\"foo\"", JSON_DECODE_ANY, &error);
-    if (!json || !json_is_string(json))
-        fail("json_load decoded any failed - string");
-    json_decref(json);
-
-    json = json_loads("42", JSON_DECODE_ANY, &error);
-    if (!json || !json_is_integer(json))
-        fail("json_load decoded any failed - integer");
-    json_decref(json);
-
-    json = json_loads("true", JSON_DECODE_ANY, &error);
-    if (!json || !json_is_true(json))
-        fail("json_load decoded any failed - boolean");
-    json_decref(json);
-
-    json = json_loads("null", JSON_DECODE_ANY, &error);
-    if (!json || !json_is_null(json))
-        fail("json_load decoded any failed - null");
-    json_decref(json);
-}
-
-static void decode_int_as_real()
-{
-    json_t *json;
-    json_error_t error;
-
-#if JSON_INTEGER_IS_LONG_LONG
-    const char *imprecise;
-    json_int_t expected;
-#endif
-
-    json = json_loads("42", JSON_DECODE_INT_AS_REAL | JSON_DECODE_ANY, &error);
-    if (!json || !json_is_real(json) || json_real_value(json) != 42.0)
-        fail("json_load decode int as real failed - int");
-    json_decref(json);
-
-#if JSON_INTEGER_IS_LONG_LONG
-    /* This number cannot be represented exactly by a double */
-    imprecise = "9007199254740993";
-    expected = 9007199254740992ll;
-
-    json = json_loads(imprecise, JSON_DECODE_INT_AS_REAL | JSON_DECODE_ANY,
-                      &error);
-    if (!json || !json_is_real(json) || expected != (json_int_t)json_real_value(json))
-        fail("json_load decode int as real failed - expected imprecision");
-    json_decref(json);
-#endif
-}
-
-static void allow_nul()
-{
-    const char *text = "\"nul byte \\u0000 in string\"";
-    const char *expected = "nul byte \0 in string";
-    size_t len = 20;
-    json_t *json;
-
-    json = json_loads(text, JSON_ALLOW_NUL | JSON_DECODE_ANY, NULL);
-    if(!json || !json_is_string(json))
-        fail("unable to decode embedded NUL byte");
-
-    if(json_string_length(json) != len)
-        fail("decoder returned wrong string length");
-
-    if(memcmp(json_string_value(json), expected, len + 1))
-        fail("decoder returned wrong string content");
-
-    json_decref(json);
-}
-
-static void load_wrong_args()
-{
-    json_t *json;
-    json_error_t error;
-
-    json = json_loads(NULL, 0, &error);
-    if (json)
-        fail("json_loads should return NULL if the first argument is NULL");
-
-    json = json_loadb(NULL, 0, 0, &error);
-    if (json)
-        fail("json_loadb should return NULL if the first argument is NULL");
-
-    json = json_loadf(NULL, 0, &error);
-    if (json)
-        fail("json_loadf should return NULL if the first argument is NULL");
-
-    json = json_load_file(NULL, 0, &error);
-    if (json)
-        fail("json_loadf should return NULL if the first argument is NULL");
-}
-
-static void position()
-{
-    json_t *json;
-    size_t flags = JSON_DISABLE_EOF_CHECK;
-    json_error_t error;
-
-    json = json_loads("{\"foo\": \"bar\"}", 0, &error);
-    if(error.position != 14)
-        fail("json_loads returned a wrong position");
-    json_decref(json);
-
-    json = json_loads("{\"foo\": \"bar\"} baz quux", flags, &error);
-    if(error.position != 14)
-        fail("json_loads returned a wrong position");
-    json_decref(json);
-}
-
-static void run_tests()
-{
-    file_not_found();
-    reject_duplicates();
-    disable_eof_check();
-    decode_any();
-    decode_int_as_real();
-    allow_nul();
-    load_wrong_args();
-    position();
-}
diff --git a/deps/jansson/test/suites/api/test_load_callback.c b/deps/jansson/test/suites/api/test_load_callback.c
deleted file mode 100644
index 9449528..0000000
--- a/deps/jansson/test/suites/api/test_load_callback.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2009-2011 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <jansson.h>
-#include <string.h>
-#include <stdlib.h>
-#include "util.h"
-
-struct my_source {
-    const char *buf;
-    size_t off;
-    size_t cap;
-};
-
-static const char my_str[] = "[\"A\", {\"B\": \"C\", \"e\": false}, 1, null, \"foo\"]";
-
-static size_t greedy_reader(void *buf, size_t buflen, void *arg)
-{
-    struct my_source *s = arg;
-    if (buflen > s->cap - s->off)
-        buflen = s->cap - s->off;
-    if (buflen > 0) {
-        memcpy(buf, s->buf + s->off, buflen);
-        s->off += buflen;
-        return buflen;
-    } else {
-        return 0;
-    }
-}
-
-static void run_tests()
-{
-    struct my_source s;
-    json_t *json;
-    json_error_t error;
-
-    s.off = 0;
-    s.cap = strlen(my_str);
-    s.buf = my_str;
-
-    json = json_load_callback(greedy_reader, &s, 0, &error);
-
-    if (!json)
-        fail("json_load_callback failed on a valid callback");
-    json_decref(json);
-
-    s.off = 0;
-    s.cap = strlen(my_str) - 1;
-    s.buf = my_str;
-
-    json = json_load_callback(greedy_reader, &s, 0, &error);
-    if (json) {
-        json_decref(json);
-        fail("json_load_callback should have failed on an incomplete stream, but it didn't");
-    }
-    if (strcmp(error.source, "<callback>") != 0) {
-        fail("json_load_callback returned an invalid error source");
-    }
-    if (strcmp(error.text, "']' expected near end of file") != 0) {
-        fail("json_load_callback returned an invalid error message for an unclosed top-level array");
-    }
-
-    json = json_load_callback(NULL, NULL, 0, &error);
-    if (json) {
-        json_decref(json);
-        fail("json_load_callback should have failed on NULL load callback, but it didn't");
-    }
-    if (strcmp(error.text, "wrong arguments") != 0) {
-        fail("json_load_callback returned an invalid error message for a NULL load callback");
-    }
-}
diff --git a/deps/jansson/test/suites/api/test_loadb.c b/deps/jansson/test/suites/api/test_loadb.c
deleted file mode 100644
index fa5e967..0000000
--- a/deps/jansson/test/suites/api/test_loadb.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <jansson.h>
-#include <string.h>
-#include "util.h"
-
-static void run_tests()
-{
-    json_t *json;
-    json_error_t error;
-    const char str[] = "[\"A\", {\"B\": \"C\"}, 1, 2, 3]garbage";
-    size_t len = strlen(str) - strlen("garbage");
-
-    json = json_loadb(str, len, 0, &error);
-    if(!json) {
-        fail("json_loadb failed on a valid JSON buffer");
-    }
-    json_decref(json);
-
-    json = json_loadb(str, len - 1, 0, &error);
-    if (json) {
-        json_decref(json);
-        fail("json_loadb should have failed on an incomplete buffer, but it didn't");
-    }
-    if(error.line != 1) {
-        fail("json_loadb returned an invalid line number on fail");
-    }
-    if(strcmp(error.text, "']' expected near end of file") != 0) {
-        fail("json_loadb returned an invalid error message for an unclosed top-level array");
-    }
-}
diff --git a/deps/jansson/test/suites/api/test_memory_funcs.c b/deps/jansson/test/suites/api/test_memory_funcs.c
deleted file mode 100644
index 8737389..0000000
--- a/deps/jansson/test/suites/api/test_memory_funcs.c
+++ /dev/null
@@ -1,82 +0,0 @@
-#include <string.h>
-#include <jansson.h>
-
-#include "util.h"
-
-static int malloc_called = 0;
-static int free_called = 0;
-
-/* helper */
-static void create_and_free_complex_object()
-{
-    json_t *obj;
-
-    obj = json_pack("{s:i,s:n,s:b,s:b,s:{s:s},s:[i,i,i]",
-                    "foo", 42,
-                    "bar",
-                    "baz", 1,
-                    "qux", 0,
-                    "alice", "bar", "baz",
-                    "bob", 9, 8, 7);
-
-    json_decref(obj);
-}
-
-static void *my_malloc(size_t size)
-{
-    malloc_called += 1;
-    return malloc(size);
-}
-
-static void my_free(void *ptr)
-{
-    free_called += 1;
-    free(ptr);
-}
-
-static void test_simple()
-{
-    json_set_alloc_funcs(my_malloc, my_free);
-    create_and_free_complex_object();
-
-    if(malloc_called != 20 || free_called != 20)
-        fail("Custom allocation failed");
-}
-
-
-/*
-  Test the secure memory functions code given in the API reference
-  documentation, but by using plain memset instead of
-  guaranteed_memset().
-*/
-
-static void *secure_malloc(size_t size)
-{
-    /* Store the memory area size in the beginning of the block */
-    void *ptr = malloc(size + 8);
-    *((size_t *)ptr) = size;
-    return (char *)ptr + 8;
-}
-
-static void secure_free(void *ptr)
-{
-    size_t size;
-
-    ptr = (char *)ptr - 8;
-    size = *((size_t *)ptr);
-
-    /*guaranteed_*/memset(ptr, 0, size + 8);
-    free(ptr);
-}
-
-static void test_secure_funcs(void)
-{
-    json_set_alloc_funcs(secure_malloc, secure_free);
-    create_and_free_complex_object();
-}
-
-static void run_tests()
-{
-    test_simple();
-    test_secure_funcs();
-}
diff --git a/deps/jansson/test/suites/api/test_number.c b/deps/jansson/test/suites/api/test_number.c
deleted file mode 100644
index b506a2b..0000000
--- a/deps/jansson/test/suites/api/test_number.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <math.h>
-#include <jansson.h>
-#include "util.h"
-
-static void run_tests()
-{
-    json_t *integer, *real;
-    json_int_t i;
-    double d;
-
-    integer = json_integer(5);
-    real = json_real(100.1);
-
-    if(!integer)
-        fail("unable to create integer");
-    if(!real)
-        fail("unable to create real");
-
-    i = json_integer_value(integer);
-    if(i != 5)
-        fail("wrong integer value");
-
-    d = json_real_value(real);
-    if(d != 100.1)
-        fail("wrong real value");
-
-    d = json_number_value(integer);
-    if(d != 5.0)
-        fail("wrong number value");
-    d = json_number_value(real);
-    if(d != 100.1)
-        fail("wrong number value");
-
-    json_decref(integer);
-    json_decref(real);
-
-#ifdef NAN
-    real = json_real(NAN);
-    if(real != NULL)
-        fail("could construct a real from NaN");
-
-    real = json_real(1.0);
-    if(json_real_set(real, NAN) != -1)
-        fail("could set a real to NaN");
-
-    if(json_real_value(real) != 1.0)
-        fail("real value changed unexpectedly");
-
-    json_decref(real);
-#endif
-
-#ifdef INFINITY
-    real = json_real(INFINITY);
-    if(real != NULL)
-        fail("could construct a real from Inf");
-
-    real = json_real(1.0);
-    if(json_real_set(real, INFINITY) != -1)
-        fail("could set a real to Inf");
-
-    if(json_real_value(real) != 1.0)
-        fail("real value changed unexpectedly");
-
-    json_decref(real);
-#endif
-}
diff --git a/deps/jansson/test/suites/api/test_object.c b/deps/jansson/test/suites/api/test_object.c
deleted file mode 100644
index ba428e1..0000000
--- a/deps/jansson/test/suites/api/test_object.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <jansson.h>
-#include <string.h>
-#include "util.h"
-
-static void test_clear()
-{
-    json_t *object, *ten;
-
-    object = json_object();
-    ten = json_integer(10);
-
-    if(!object)
-        fail("unable to create object");
-    if(!ten)
-        fail("unable to create integer");
-
-    if(json_object_set(object, "a", ten) ||
-       json_object_set(object, "b", ten) ||
-       json_object_set(object, "c", ten) ||
-       json_object_set(object, "d", ten) ||
-       json_object_set(object, "e", ten))
-        fail("unable to set value");
-
-    if(json_object_size(object) != 5)
-        fail("invalid size");
-
-    json_object_clear(object);
-
-    if(json_object_size(object) != 0)
-        fail("invalid size after clear");
-
-    json_decref(ten);
-    json_decref(object);
-}
-
-static void test_update()
-{
-    json_t *object, *other, *nine, *ten;
-
-    object = json_object();
-    other = json_object();
-
-    nine = json_integer(9);
-    ten = json_integer(10);
-
-    if(!object || !other)
-        fail("unable to create object");
-    if(!nine || !ten)
-        fail("unable to create integer");
-
-
-    /* update an empty object with an empty object */
-
-    if(json_object_update(object, other))
-        fail("unable to update an emtpy object with an empty object");
-
-    if(json_object_size(object) != 0)
-        fail("invalid size after update");
-
-    if(json_object_size(other) != 0)
-        fail("invalid size for updater after update");
-
-
-    /* update an empty object with a nonempty object */
-
-    if(json_object_set(other, "a", ten) ||
-       json_object_set(other, "b", ten) ||
-       json_object_set(other, "c", ten) ||
-       json_object_set(other, "d", ten) ||
-       json_object_set(other, "e", ten))
-        fail("unable to set value");
-
-    if(json_object_update(object, other))
-        fail("unable to update an empty object");
-
-    if(json_object_size(object) != 5)
-        fail("invalid size after update");
-
-    if(json_object_get(object, "a") != ten ||
-       json_object_get(object, "b") != ten ||
-       json_object_get(object, "c") != ten ||
-       json_object_get(object, "d") != ten ||
-       json_object_get(object, "e") != ten)
-        fail("update works incorrectly");
-
-
-    /* perform the same update again */
-
-    if(json_object_update(object, other))
-        fail("unable to update a non-empty object");
-
-    if(json_object_size(object) != 5)
-        fail("invalid size after update");
-
-    if(json_object_get(object, "a") != ten ||
-       json_object_get(object, "b") != ten ||
-       json_object_get(object, "c") != ten ||
-       json_object_get(object, "d") != ten ||
-       json_object_get(object, "e") != ten)
-        fail("update works incorrectly");
-
-
-    /* update a nonempty object with a nonempty object with both old
-       and new keys */
-
-    if(json_object_clear(other))
-        fail("clear failed");
-
-    if(json_object_set(other, "a", nine) ||
-       json_object_set(other, "b", nine) ||
-       json_object_set(other, "f", nine) ||
-       json_object_set(other, "g", nine) ||
-       json_object_set(other, "h", nine))
-        fail("unable to set value");
-
-    if(json_object_update(object, other))
-        fail("unable to update a nonempty object");
-
-    if(json_object_size(object) != 8)
-        fail("invalid size after update");
-
-    if(json_object_get(object, "a") != nine ||
-       json_object_get(object, "b") != nine ||
-       json_object_get(object, "f") != nine ||
-       json_object_get(object, "g") != nine ||
-       json_object_get(object, "h") != nine)
-        fail("update works incorrectly");
-
-    json_decref(nine);
-    json_decref(ten);
-    json_decref(other);
-    json_decref(object);
-}
-
-static void test_conditional_updates()
-{
-    json_t *object, *other;
-
-    object = json_pack("{sisi}", "foo", 1, "bar", 2);
-    other = json_pack("{sisi}", "foo", 3, "baz", 4);
-
-    if(json_object_update_existing(object, other))
-        fail("json_object_update_existing failed");
-
-    if(json_object_size(object) != 2)
-        fail("json_object_update_existing added new items");
-
-    if(json_integer_value(json_object_get(object, "foo")) != 3)
-        fail("json_object_update_existing failed to update existing key");
-
-    if(json_integer_value(json_object_get(object, "bar")) != 2)
-        fail("json_object_update_existing updated wrong key");
-
-    json_decref(object);
-
-    object = json_pack("{sisi}", "foo", 1, "bar", 2);
-
-    if(json_object_update_missing(object, other))
-        fail("json_object_update_missing failed");
-
-    if(json_object_size(object) != 3)
-        fail("json_object_update_missing didn't add new items");
-
-    if(json_integer_value(json_object_get(object, "foo")) != 1)
-        fail("json_object_update_missing updated existing key");
-
-    if(json_integer_value(json_object_get(object, "bar")) != 2)
-        fail("json_object_update_missing updated wrong key");
-
-    if(json_integer_value(json_object_get(object, "baz")) != 4)
-        fail("json_object_update_missing didn't add new items");
-
-    json_decref(object);
-    json_decref(other);
-}
-
-static void test_circular()
-{
-    json_t *object1, *object2;
-
-    object1 = json_object();
-    object2 = json_object();
-    if(!object1 || !object2)
-        fail("unable to create object");
-
-    /* the simple case is checked */
-    if(json_object_set(object1, "a", object1) == 0)
-        fail("able to set self");
-
-    /* create circular references */
-    if(json_object_set(object1, "a", object2) ||
-       json_object_set(object2, "a", object1))
-        fail("unable to set value");
-
-    /* circularity is detected when dumping */
-    if(json_dumps(object1, 0) != NULL)
-        fail("able to dump circulars");
-
-    /* decref twice to deal with the circular references */
-    json_decref(object1);
-    json_decref(object2);
-    json_decref(object1);
-}
-
-static void test_set_nocheck()
-{
-    json_t *object, *string;
-
-    object = json_object();
-    string = json_string("bar");
-
-    if(!object)
-        fail("unable to create object");
-    if(!string)
-        fail("unable to create string");
-
-    if(json_object_set_nocheck(object, "foo", string))
-        fail("json_object_set_nocheck failed");
-    if(json_object_get(object, "foo") != string)
-        fail("json_object_get after json_object_set_nocheck failed");
-
-    /* invalid UTF-8 in key */
-    if(json_object_set_nocheck(object, "a\xefz", string))
-        fail("json_object_set_nocheck failed for invalid UTF-8");
-    if(json_object_get(object, "a\xefz") != string)
-        fail("json_object_get after json_object_set_nocheck failed");
-
-    if(json_object_set_new_nocheck(object, "bax", json_integer(123)))
-        fail("json_object_set_new_nocheck failed");
-    if(json_integer_value(json_object_get(object, "bax")) != 123)
-        fail("json_object_get after json_object_set_new_nocheck failed");
-
-    /* invalid UTF-8 in key */
-    if(json_object_set_new_nocheck(object, "asdf\xfe", json_integer(321)))
-        fail("json_object_set_new_nocheck failed for invalid UTF-8");
-    if(json_integer_value(json_object_get(object, "asdf\xfe")) != 321)
-        fail("json_object_get after json_object_set_new_nocheck failed");
-
-    json_decref(string);
-    json_decref(object);
-}
-
-static void test_iterators()
-{
-    json_t *object, *foo, *bar, *baz;
-    void *iter;
-
-    if(json_object_iter(NULL))
-        fail("able to iterate over NULL");
-
-    if(json_object_iter_next(NULL, NULL))
-        fail("able to increment an iterator on a NULL object");
-
-    object = json_object();
-    foo = json_string("foo");
-    bar = json_string("bar");
-    baz = json_string("baz");
-    if(!object || !foo || !bar || !bar)
-        fail("unable to create values");
-
-    if(json_object_iter_next(object, NULL))
-        fail("able to increment a NULL iterator");
-
-    if(json_object_set(object, "a", foo) ||
-       json_object_set(object, "b", bar) ||
-       json_object_set(object, "c", baz))
-        fail("unable to populate object");
-
-    iter = json_object_iter(object);
-    if(!iter)
-        fail("unable to get iterator");
-    if(strcmp(json_object_iter_key(iter), "a"))
-        fail("iterating failed: wrong key");
-    if(json_object_iter_value(iter) != foo)
-        fail("iterating failed: wrong value");
-
-    iter = json_object_iter_next(object, iter);
-    if(!iter)
-        fail("unable to increment iterator");
-    if(strcmp(json_object_iter_key(iter), "b"))
-        fail("iterating failed: wrong key");
-    if(json_object_iter_value(iter) != bar)
-        fail("iterating failed: wrong value");
-
-    iter = json_object_iter_next(object, iter);
-    if(!iter)
-        fail("unable to increment iterator");
-    if(strcmp(json_object_iter_key(iter), "c"))
-        fail("iterating failed: wrong key");
-    if(json_object_iter_value(iter) != baz)
-        fail("iterating failed: wrong value");
-
-    if(json_object_iter_next(object, iter) != NULL)
-        fail("able to iterate over the end");
-
-    if(json_object_iter_at(object, "foo"))
-        fail("json_object_iter_at() succeeds for non-existent key");
-
-    iter = json_object_iter_at(object, "b");
-    if(!iter)
-        fail("json_object_iter_at() fails for an existing key");
-
-    if(strcmp(json_object_iter_key(iter), "b"))
-        fail("iterating failed: wrong key");
-    if(json_object_iter_value(iter) != bar)
-        fail("iterating failed: wrong value");
-
-    iter = json_object_iter_next(object, iter);
-    if(!iter)
-        fail("unable to increment iterator");
-    if(strcmp(json_object_iter_key(iter), "c"))
-        fail("iterating failed: wrong key");
-    if(json_object_iter_value(iter) != baz)
-        fail("iterating failed: wrong value");
-
-    if(json_object_iter_set(object, iter, bar))
-        fail("unable to set value at iterator");
-
-    if(strcmp(json_object_iter_key(iter), "c"))
-        fail("json_object_iter_key() fails after json_object_iter_set()");
-    if(json_object_iter_value(iter) != bar)
-        fail("json_object_iter_value() fails after json_object_iter_set()");
-    if(json_object_get(object, "c") != bar)
-        fail("json_object_get() fails after json_object_iter_set()");
-
-    json_decref(object);
-    json_decref(foo);
-    json_decref(bar);
-    json_decref(baz);
-}
-
-static void test_misc()
-{
-    json_t *object, *string, *other_string, *value;
-
-    object = json_object();
-    string = json_string("test");
-    other_string = json_string("other");
-
-    if(!object)
-        fail("unable to create object");
-    if(!string || !other_string)
-        fail("unable to create string");
-
-    if(json_object_get(object, "a"))
-        fail("value for nonexisting key");
-
-    if(json_object_set(object, "a", string))
-        fail("unable to set value");
-
-    if(!json_object_set(object, NULL, string))
-        fail("able to set NULL key");
-
-    if(!json_object_set(object, "a", NULL))
-        fail("able to set NULL value");
-
-    /* invalid UTF-8 in key */
-    if(!json_object_set(object, "a\xefz", string))
-        fail("able to set invalid unicode key");
-
-    value = json_object_get(object, "a");
-    if(!value)
-        fail("no value for existing key");
-    if(value != string)
-        fail("got different value than what was added");
-
-    /* "a", "lp" and "px" collide in a five-bucket hashtable */
-    if(json_object_set(object, "b", string) ||
-       json_object_set(object, "lp", string) ||
-       json_object_set(object, "px", string))
-        fail("unable to set value");
-
-    value = json_object_get(object, "a");
-    if(!value)
-        fail("no value for existing key");
-    if(value != string)
-        fail("got different value than what was added");
-
-    if(json_object_set(object, "a", other_string))
-        fail("unable to replace an existing key");
-
-    value = json_object_get(object, "a");
-    if(!value)
-        fail("no value for existing key");
-    if(value != other_string)
-        fail("got different value than what was set");
-
-    if(!json_object_del(object, "nonexisting"))
-        fail("able to delete a nonexisting key");
-
-    if(json_object_del(object, "px"))
-        fail("unable to delete an existing key");
-
-    if(json_object_del(object, "a"))
-        fail("unable to delete an existing key");
-
-    if(json_object_del(object, "lp"))
-        fail("unable to delete an existing key");
-
-
-    /* add many keys to initiate rehashing */
-
-    if(json_object_set(object, "a", string))
-        fail("unable to set value");
-
-    if(json_object_set(object, "lp", string))
-        fail("unable to set value");
-
-    if(json_object_set(object, "px", string))
-        fail("unable to set value");
-
-    if(json_object_set(object, "c", string))
-        fail("unable to set value");
-
-    if(json_object_set(object, "d", string))
-        fail("unable to set value");
-
-    if(json_object_set(object, "e", string))
-        fail("unable to set value");
-
-
-    if(json_object_set_new(object, "foo", json_integer(123)))
-        fail("unable to set new value");
-
-    value = json_object_get(object, "foo");
-    if(!json_is_integer(value) || json_integer_value(value) != 123)
-        fail("json_object_set_new works incorrectly");
-
-    if(!json_object_set_new(object, NULL, json_integer(432)))
-        fail("able to set_new NULL key");
-
-    if(!json_object_set_new(object, "foo", NULL))
-        fail("able to set_new NULL value");
-
-    json_decref(string);
-    json_decref(other_string);
-    json_decref(object);
-}
-
-static void test_preserve_order()
-{
-    json_t *object;
-    char *result;
-
-    const char *expected = "{\"foobar\": 1, \"bazquux\": 6, \"lorem ipsum\": 3, \"sit amet\": 5, \"helicopter\": 7}";
-
-    object = json_object();
-
-    json_object_set_new(object, "foobar", json_integer(1));
-    json_object_set_new(object, "bazquux", json_integer(2));
-    json_object_set_new(object, "lorem ipsum", json_integer(3));
-    json_object_set_new(object, "dolor", json_integer(4));
-    json_object_set_new(object, "sit amet", json_integer(5));
-
-    /* changing a value should preserve the order */
-    json_object_set_new(object, "bazquux", json_integer(6));
-
-    /* deletion shouldn't change the order of others */
-    json_object_del(object, "dolor");
-
-    /* add a new item just to make sure */
-    json_object_set_new(object, "helicopter", json_integer(7));
-
-    result = json_dumps(object, JSON_PRESERVE_ORDER);
-
-    if(strcmp(expected, result) != 0) {
-        fprintf(stderr, "%s != %s", expected, result);
-        fail("JSON_PRESERVE_ORDER doesn't work");
-    }
-
-    free(result);
-    json_decref(object);
-}
-
-static void test_object_foreach()
-{
-    const char *key;
-    json_t *object1, *object2, *value;
-
-    object1 = json_pack("{sisisi}", "foo", 1, "bar", 2, "baz", 3);
-    object2 = json_object();
-
-    json_object_foreach(object1, key, value)
-        json_object_set(object2, key, value);
-
-    if(!json_equal(object1, object2))
-        fail("json_object_foreach failed to iterate all key-value pairs");
-
-    json_decref(object1);
-    json_decref(object2);
-}
-
-static void run_tests()
-{
-    test_misc();
-    test_clear();
-    test_update();
-    test_conditional_updates();
-    test_circular();
-    test_set_nocheck();
-    test_iterators();
-    test_preserve_order();
-    test_object_foreach();
-}
diff --git a/deps/jansson/test/suites/api/test_pack.c b/deps/jansson/test/suites/api/test_pack.c
deleted file mode 100644
index 348d8b2..0000000
--- a/deps/jansson/test/suites/api/test_pack.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- * Copyright (c) 2010-2012 Graeme Smecher <graeme.smecher at mail.mcgill.ca>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <jansson_config.h>
-
-#include <string.h>
-#include <jansson.h>
-#include <stdio.h>
-#include "util.h"
-
-static void run_tests()
-{
-    json_t *value;
-    int i;
-    char buffer[4] = {'t', 'e', 's', 't'};
-    json_error_t error;
-
-    /*
-     * Simple, valid json_pack cases
-     */
-    /* true */
-    value = json_pack("b", 1);
-    if(!json_is_true(value))
-        fail("json_pack boolean failed");
-    if(value->refcount != (size_t)-1)
-        fail("json_pack boolean refcount failed");
-    json_decref(value);
-
-    /* false */
-    value = json_pack("b", 0);
-    if(!json_is_false(value))
-        fail("json_pack boolean failed");
-    if(value->refcount != (size_t)-1)
-        fail("json_pack boolean refcount failed");
-    json_decref(value);
-
-    /* null */
-    value = json_pack("n");
-    if(!json_is_null(value))
-        fail("json_pack null failed");
-    if(value->refcount != (size_t)-1)
-        fail("json_pack null refcount failed");
-    json_decref(value);
-
-    /* integer */
-    value = json_pack("i", 1);
-    if(!json_is_integer(value) || json_integer_value(value) != 1)
-        fail("json_pack integer failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack integer refcount failed");
-    json_decref(value);
-
-    /* integer from json_int_t */
-    value = json_pack("I", (json_int_t)555555);
-    if(!json_is_integer(value) || json_integer_value(value) != 555555)
-        fail("json_pack json_int_t failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack integer refcount failed");
-    json_decref(value);
-
-    /* real */
-    value = json_pack("f", 1.0);
-    if(!json_is_real(value) || json_real_value(value) != 1.0)
-        fail("json_pack real failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack real refcount failed");
-    json_decref(value);
-
-    /* string */
-    value = json_pack("s", "test");
-    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
-        fail("json_pack string failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack string refcount failed");
-    json_decref(value);
-
-    /* string and length (int) */
-    value = json_pack("s#", "test asdf", 4);
-    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
-        fail("json_pack string and length failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack string and length refcount failed");
-    json_decref(value);
-
-    /* string and length (size_t) */
-    value = json_pack("s%", "test asdf", (size_t)4);
-    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
-        fail("json_pack string and length failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack string and length refcount failed");
-    json_decref(value);
-
-    /* string and length (int), non-NUL terminated string */
-    value = json_pack("s#", buffer, 4);
-    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
-        fail("json_pack string and length (int) failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack string and length (int) refcount failed");
-    json_decref(value);
-
-    /* string and length (size_t), non-NUL terminated string */
-    value = json_pack("s%", buffer, (size_t)4);
-    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
-        fail("json_pack string and length (size_t) failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack string and length (size_t) refcount failed");
-    json_decref(value);
-
-    /* string concatenation */
-    value = json_pack("s++", "te", "st", "ing");
-    if(!json_is_string(value) || strcmp("testing", json_string_value(value)))
-        fail("json_pack string concatenation failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack string concatenation refcount failed");
-    json_decref(value);
-
-    /* string concatenation and length (int) */
-    value = json_pack("s#+#+", "test", 1, "test", 2, "test");
-    if(!json_is_string(value) || strcmp("ttetest", json_string_value(value)))
-        fail("json_pack string concatenation and length (int) failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack string concatenation and length (int) refcount failed");
-    json_decref(value);
-
-    /* string concatenation and length (size_t) */
-    value = json_pack("s%+%+", "test", (size_t)1, "test", (size_t)2, "test");
-    if(!json_is_string(value) || strcmp("ttetest", json_string_value(value)))
-        fail("json_pack string concatenation and length (size_t) failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack string concatenation and length (size_t) refcount failed");
-    json_decref(value);
-
-    /* empty object */
-    value = json_pack("{}", 1.0);
-    if(!json_is_object(value) || json_object_size(value) != 0)
-        fail("json_pack empty object failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack empty object refcount failed");
-    json_decref(value);
-
-    /* empty list */
-    value = json_pack("[]", 1.0);
-    if(!json_is_array(value) || json_array_size(value) != 0)
-        fail("json_pack empty list failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack empty list failed");
-    json_decref(value);
-
-    /* non-incref'd object */
-    value = json_pack("o", json_integer(1));
-    if(!json_is_integer(value) || json_integer_value(value) != 1)
-        fail("json_pack object failed");
-    if(value->refcount != (size_t)1)
-        fail("json_pack integer refcount failed");
-    json_decref(value);
-
-    /* incref'd object */
-    value = json_pack("O", json_integer(1));
-    if(!json_is_integer(value) || json_integer_value(value) != 1)
-        fail("json_pack object failed");
-    if(value->refcount != (size_t)2)
-        fail("json_pack integer refcount failed");
-    json_decref(value);
-    json_decref(value);
-
-    /* simple object */
-    value = json_pack("{s:[]}", "foo");
-    if(!json_is_object(value) || json_object_size(value) != 1)
-        fail("json_pack array failed");
-    if(!json_is_array(json_object_get(value, "foo")))
-        fail("json_pack array failed");
-    if(json_object_get(value, "foo")->refcount != (size_t)1)
-        fail("json_pack object refcount failed");
-    json_decref(value);
-
-    /* object with complex key */
-    value = json_pack("{s+#+: []}", "foo", "barbar", 3, "baz");
-    if(!json_is_object(value) || json_object_size(value) != 1)
-        fail("json_pack array failed");
-    if(!json_is_array(json_object_get(value, "foobarbaz")))
-        fail("json_pack array failed");
-    if(json_object_get(value, "foobarbaz")->refcount != (size_t)1)
-        fail("json_pack object refcount failed");
-    json_decref(value);
-
-    /* simple array */
-    value = json_pack("[i,i,i]", 0, 1, 2);
-    if(!json_is_array(value) || json_array_size(value) != 3)
-        fail("json_pack object failed");
-    for(i=0; i<3; i++)
-    {
-        if(!json_is_integer(json_array_get(value, i)) ||
-           json_integer_value(json_array_get(value, i)) != i)
-
-            fail("json_pack integer array failed");
-    }
-    json_decref(value);
-
-    /* Whitespace; regular string */
-    value = json_pack(" s ", "test");
-    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
-        fail("json_pack string (with whitespace) failed");
-    json_decref(value);
-
-    /* Whitespace; empty array */
-    value = json_pack("[ ]");
-    if(!json_is_array(value) || json_array_size(value) != 0)
-        fail("json_pack empty array (with whitespace) failed");
-    json_decref(value);
-
-    /* Whitespace; array */
-    value = json_pack("[ i , i,  i ] ", 1, 2, 3);
-    if(!json_is_array(value) || json_array_size(value) != 3)
-        fail("json_pack array (with whitespace) failed");
-    json_decref(value);
-
-    /*
-     * Invalid cases
-     */
-
-    /* newline in format string */
-    if(json_pack_ex(&error, 0, "{\n\n1"))
-        fail("json_pack failed to catch invalid format '1'");
-    check_error("Expected format 's', got '1'", "<format>", 3, 1, 4);
-
-    /* mismatched open/close array/object */
-    if(json_pack_ex(&error, 0, "[}"))
-        fail("json_pack failed to catch mismatched '}'");
-    check_error("Unexpected format character '}'", "<format>", 1, 2, 2);
-
-    if(json_pack_ex(&error, 0, "{]"))
-        fail("json_pack failed to catch mismatched ']'");
-    check_error("Expected format 's', got ']'", "<format>", 1, 2, 2);
-
-    /* missing close array */
-    if(json_pack_ex(&error, 0, "["))
-        fail("json_pack failed to catch missing ']'");
-    check_error("Unexpected end of format string", "<format>", 1, 2, 2);
-
-    /* missing close object */
-    if(json_pack_ex(&error, 0, "{"))
-        fail("json_pack failed to catch missing '}'");
-    check_error("Unexpected end of format string", "<format>", 1, 2, 2);
-
-    /* garbage after format string */
-    if(json_pack_ex(&error, 0, "[i]a", 42))
-        fail("json_pack failed to catch garbage after format string");
-    check_error("Garbage after format string", "<format>", 1, 4, 4);
-
-    if(json_pack_ex(&error, 0, "ia", 42))
-        fail("json_pack failed to catch garbage after format string");
-    check_error("Garbage after format string", "<format>", 1, 2, 2);
-
-    /* NULL string */
-    if(json_pack_ex(&error, 0, "s", NULL))
-        fail("json_pack failed to catch null argument string");
-    check_error("NULL string argument", "<args>", 1, 1, 1);
-
-    /* + on its own */
-    if(json_pack_ex(&error, 0, "+", NULL))
-        fail("json_pack failed to a lone +");
-    check_error("Unexpected format character '+'", "<format>", 1, 1, 1);
-
-    /* NULL format */
-    if(json_pack_ex(&error, 0, NULL))
-        fail("json_pack failed to catch NULL format string");
-    check_error("NULL or empty format string", "<format>", -1, -1, 0);
-
-    /* NULL key */
-    if(json_pack_ex(&error, 0, "{s:i}", NULL, 1))
-        fail("json_pack failed to catch NULL key");
-    check_error("NULL string argument", "<args>", 1, 2, 2);
-
-    /* More complicated checks for row/columns */
-    if(json_pack_ex(&error, 0, "{ {}: s }", "foo"))
-        fail("json_pack failed to catch object as key");
-    check_error("Expected format 's', got '{'", "<format>", 1, 3, 3);
-
-    /* Complex object */
-    if(json_pack_ex(&error, 0, "{ s: {},  s:[ii{} }", "foo", "bar", 12, 13))
-        fail("json_pack failed to catch missing ]");
-    check_error("Unexpected format character '}'", "<format>", 1, 19, 19);
-
-    /* Complex array */
-    if(json_pack_ex(&error, 0, "[[[[[   [[[[[  [[[[ }]]]] ]]]] ]]]]]"))
-        fail("json_pack failed to catch extra }");
-    check_error("Unexpected format character '}'", "<format>", 1, 21, 21);
-
-    /* Invalid UTF-8 in object key */
-    if(json_pack_ex(&error, 0, "{s:i}", "\xff\xff", 42))
-        fail("json_pack failed to catch invalid UTF-8 in an object key");
-    check_error("Invalid UTF-8 object key", "<args>", 1, 2, 2);
-
-    /* Invalid UTF-8 in a string */
-    if(json_pack_ex(&error, 0, "{s:s}", "foo", "\xff\xff"))
-        fail("json_pack failed to catch invalid UTF-8 in a string");
-    check_error("Invalid UTF-8 string", "<args>", 1, 4, 4);
-}
diff --git a/deps/jansson/test/suites/api/test_simple.c b/deps/jansson/test/suites/api/test_simple.c
deleted file mode 100644
index 7eed591..0000000
--- a/deps/jansson/test/suites/api/test_simple.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <string.h>
-#include <jansson.h>
-#include "util.h"
-
-/* Call the simple functions not covered by other tests of the public API */
-static void run_tests()
-{
-    json_t *value;
-
-    value = json_boolean(1);
-    if(!json_is_true(value))
-        fail("json_boolean(1) failed");
-    json_decref(value);
-
-    value = json_boolean(-123);
-    if(!json_is_true(value))
-        fail("json_boolean(-123) failed");
-    json_decref(value);
-
-    value = json_boolean(0);
-    if(!json_is_false(value))
-        fail("json_boolean(0) failed");
-    if(json_boolean_value(value) != 0)
-        fail("json_boolean_value failed");
-    json_decref(value);
-
-
-    value = json_integer(1);
-    if(json_typeof(value) != JSON_INTEGER)
-        fail("json_typeof failed");
-
-    if(json_is_object(value))
-        fail("json_is_object failed");
-
-    if(json_is_array(value))
-        fail("json_is_array failed");
-
-    if(json_is_string(value))
-        fail("json_is_string failed");
-
-    if(!json_is_integer(value))
-        fail("json_is_integer failed");
-
-    if(json_is_real(value))
-        fail("json_is_real failed");
-
-    if(!json_is_number(value))
-        fail("json_is_number failed");
-
-    if(json_is_true(value))
-        fail("json_is_true failed");
-
-    if(json_is_false(value))
-        fail("json_is_false failed");
-
-    if(json_is_boolean(value))
-        fail("json_is_boolean failed");
-
-    if(json_is_null(value))
-        fail("json_is_null failed");
-
-    json_decref(value);
-
-
-    value = json_string("foo");
-    if(!value)
-        fail("json_string failed");
-    if(strcmp(json_string_value(value), "foo"))
-        fail("invalid string value");
-    if (json_string_length(value) != 3)
-        fail("invalid string length");
-
-    if(json_string_set(value, "barr"))
-        fail("json_string_set failed");
-    if(strcmp(json_string_value(value), "barr"))
-        fail("invalid string value");
-    if (json_string_length(value) != 4)
-        fail("invalid string length");
-
-    if(json_string_setn(value, "hi\0ho", 5))
-        fail("json_string_set failed");
-    if(memcmp(json_string_value(value), "hi\0ho\0", 6))
-        fail("invalid string value");
-    if (json_string_length(value) != 5)
-        fail("invalid string length");
-
-    json_decref(value);
-
-    value = json_string(NULL);
-    if(value)
-        fail("json_string(NULL) failed");
-
-    /* invalid UTF-8  */
-    value = json_string("a\xefz");
-    if(value)
-        fail("json_string(<invalid utf-8>) failed");
-
-    value = json_string_nocheck("foo");
-    if(!value)
-        fail("json_string_nocheck failed");
-    if(strcmp(json_string_value(value), "foo"))
-        fail("invalid string value");
-    if (json_string_length(value) != 3)
-        fail("invalid string length");
-
-    if(json_string_set_nocheck(value, "barr"))
-        fail("json_string_set_nocheck failed");
-    if(strcmp(json_string_value(value), "barr"))
-        fail("invalid string value");
-    if (json_string_length(value) != 4)
-        fail("invalid string length");
-
-    if(json_string_setn_nocheck(value, "hi\0ho", 5))
-        fail("json_string_set failed");
-    if(memcmp(json_string_value(value), "hi\0ho\0", 6))
-        fail("invalid string value");
-    if (json_string_length(value) != 5)
-        fail("invalid string length");
-
-    json_decref(value);
-
-    /* invalid UTF-8 */
-    value = json_string_nocheck("qu\xff");
-    if(!value)
-        fail("json_string_nocheck failed");
-    if(strcmp(json_string_value(value), "qu\xff"))
-        fail("invalid string value");
-    if (json_string_length(value) != 3)
-        fail("invalid string length");
-
-    if(json_string_set_nocheck(value, "\xfd\xfe\xff"))
-        fail("json_string_set_nocheck failed");
-    if(strcmp(json_string_value(value), "\xfd\xfe\xff"))
-        fail("invalid string value");
-    if (json_string_length(value) != 3)
-        fail("invalid string length");
-
-    json_decref(value);
-
-
-    value = json_integer(123);
-    if(!value)
-        fail("json_integer failed");
-    if(json_integer_value(value) != 123)
-        fail("invalid integer value");
-    if(json_number_value(value) != 123.0)
-        fail("invalid number value");
-
-    if(json_integer_set(value, 321))
-        fail("json_integer_set failed");
-    if(json_integer_value(value) != 321)
-        fail("invalid integer value");
-    if(json_number_value(value) != 321.0)
-        fail("invalid number value");
-
-    json_decref(value);
-
-    value = json_real(123.123);
-    if(!value)
-        fail("json_real failed");
-    if(json_real_value(value) != 123.123)
-        fail("invalid integer value");
-    if(json_number_value(value) != 123.123)
-        fail("invalid number value");
-
-    if(json_real_set(value, 321.321))
-        fail("json_real_set failed");
-    if(json_real_value(value) != 321.321)
-        fail("invalid real value");
-    if(json_number_value(value) != 321.321)
-        fail("invalid number value");
-
-    json_decref(value);
-
-    value = json_true();
-    if(!value)
-        fail("json_true failed");
-    json_decref(value);
-
-    value = json_false();
-    if(!value)
-        fail("json_false failed");
-    json_decref(value);
-
-    value = json_null();
-    if(!value)
-        fail("json_null failed");
-    json_decref(value);
-
-    /* Test reference counting on singletons (true, false, null) */
-    value = json_true();
-    if(value->refcount != (size_t)-1)
-      fail("refcounting true works incorrectly");
-    json_decref(value);
-    if(value->refcount != (size_t)-1)
-      fail("refcounting true works incorrectly");
-    json_incref(value);
-    if(value->refcount != (size_t)-1)
-      fail("refcounting true works incorrectly");
-
-    value = json_false();
-    if(value->refcount != (size_t)-1)
-      fail("refcounting false works incorrectly");
-    json_decref(value);
-    if(value->refcount != (size_t)-1)
-      fail("refcounting false works incorrectly");
-    json_incref(value);
-    if(value->refcount != (size_t)-1)
-      fail("refcounting false works incorrectly");
-
-    value = json_null();
-    if(value->refcount != (size_t)-1)
-      fail("refcounting null works incorrectly");
-    json_decref(value);
-    if(value->refcount != (size_t)-1)
-      fail("refcounting null works incorrectly");
-    json_incref(value);
-    if(value->refcount != (size_t)-1)
-      fail("refcounting null works incorrectly");
-}
diff --git a/deps/jansson/test/suites/api/test_unpack.c b/deps/jansson/test/suites/api/test_unpack.c
deleted file mode 100644
index 7f049dd..0000000
--- a/deps/jansson/test/suites/api/test_unpack.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- * Copyright (c) 2010-2012 Graeme Smecher <graeme.smecher at mail.mcgill.ca>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include <string.h>
-#include <jansson.h>
-#include <stdio.h>
-#include "util.h"
-
-static void run_tests()
-{
-    json_t *j, *j2;
-    int i1, i2, i3;
-    json_int_t I1;
-    int rv;
-    size_t z;
-    double f;
-    char *s;
-
-    json_error_t error;
-
-    /*
-     * Simple, valid json_pack cases
-     */
-
-    /* true */
-    rv = json_unpack(json_true(), "b", &i1);
-    if(rv || !i1)
-        fail("json_unpack boolean failed");
-
-    /* false */
-    rv = json_unpack(json_false(), "b", &i1);
-    if(rv || i1)
-        fail("json_unpack boolean failed");
-
-    /* null */
-    if(json_unpack(json_null(), "n"))
-        fail("json_unpack null failed");
-
-    /* integer */
-    j = json_integer(42);
-    rv = json_unpack(j, "i", &i1);
-    if(rv || i1 != 42)
-        fail("json_unpack integer failed");
-    json_decref(j);
-
-    /* json_int_t */
-    j = json_integer(5555555);
-    rv = json_unpack(j, "I", &I1);
-    if(rv || I1 != 5555555)
-        fail("json_unpack json_int_t failed");
-    json_decref(j);
-
-    /* real */
-    j = json_real(1.7);
-    rv = json_unpack(j, "f", &f);
-    if(rv || f != 1.7)
-        fail("json_unpack real failed");
-    json_decref(j);
-
-    /* number */
-    j = json_integer(12345);
-    rv = json_unpack(j, "F", &f);
-    if(rv || f != 12345.0)
-        fail("json_unpack (real or) integer failed");
-    json_decref(j);
-
-    j = json_real(1.7);
-    rv = json_unpack(j, "F", &f);
-    if(rv || f != 1.7)
-        fail("json_unpack real (or integer) failed");
-    json_decref(j);
-
-    /* string */
-    j = json_string("foo");
-    rv = json_unpack(j, "s", &s);
-    if(rv || strcmp(s, "foo"))
-        fail("json_unpack string failed");
-    json_decref(j);
-
-    /* string with length (size_t) */
-    j = json_string("foo");
-    rv = json_unpack(j, "s%", &s, &z);
-    if(rv || strcmp(s, "foo") || z != 3)
-        fail("json_unpack string with length (size_t) failed");
-    json_decref(j);
-
-    /* empty object */
-    j = json_object();
-    if(json_unpack(j, "{}"))
-        fail("json_unpack empty object failed");
-    json_decref(j);
-
-    /* empty list */
-    j = json_array();
-    if(json_unpack(j, "[]"))
-        fail("json_unpack empty list failed");
-    json_decref(j);
-
-    /* non-incref'd object */
-    j = json_object();
-    rv = json_unpack(j, "o", &j2);
-    if(rv || j2 != j || j->refcount != 1)
-        fail("json_unpack object failed");
-    json_decref(j);
-
-    /* incref'd object */
-    j = json_object();
-    rv = json_unpack(j, "O", &j2);
-    if(rv || j2 != j || j->refcount != 2)
-        fail("json_unpack object failed");
-    json_decref(j);
-    json_decref(j);
-
-    /* simple object */
-    j = json_pack("{s:i}", "foo", 42);
-    rv = json_unpack(j, "{s:i}", "foo", &i1);
-    if(rv || i1 != 42)
-        fail("json_unpack simple object failed");
-    json_decref(j);
-
-    /* simple array */
-    j = json_pack("[iii]", 1, 2, 3);
-    rv = json_unpack(j, "[i,i,i]", &i1, &i2, &i3);
-    if(rv || i1 != 1 || i2 != 2 || i3 != 3)
-        fail("json_unpack simple array failed");
-    json_decref(j);
-
-    /* object with many items & strict checking */
-    j = json_pack("{s:i, s:i, s:i}", "a", 1, "b", 2, "c", 3);
-    rv = json_unpack(j, "{s:i, s:i, s:i}", "a", &i1, "b", &i2, "c", &i3);
-    if(rv || i1 != 1 || i2 != 2 || i3 != 3)
-        fail("json_unpack object with many items failed");
-    json_decref(j);
-
-    /*
-     * Invalid cases
-     */
-
-    j = json_integer(42);
-    if(!json_unpack_ex(j, &error, 0, "z"))
-        fail("json_unpack succeeded with invalid format character");
-    check_error("Unexpected format character 'z'", "<format>", 1, 1, 1);
-
-    if(!json_unpack_ex(NULL, &error, 0, "[i]"))
-        fail("json_unpack succeeded with NULL root");
-    check_error("NULL root value", "<root>", -1, -1, 0);
-    json_decref(j);
-
-    /* mismatched open/close array/object */
-    j = json_pack("[]");
-    if(!json_unpack_ex(j, &error, 0, "[}"))
-        fail("json_unpack failed to catch mismatched ']'");
-    check_error("Unexpected format character '}'", "<format>", 1, 2, 2);
-    json_decref(j);
-
-    j = json_pack("{}");
-    if(!json_unpack_ex(j, &error, 0, "{]"))
-        fail("json_unpack failed to catch mismatched '}'");
-    check_error("Expected format 's', got ']'", "<format>", 1, 2, 2);
-    json_decref(j);
-
-    /* missing close array */
-    j = json_pack("[]");
-    if(!json_unpack_ex(j, &error, 0, "["))
-        fail("json_unpack failed to catch missing ']'");
-    check_error("Unexpected end of format string", "<format>", 1, 2, 2);
-    json_decref(j);
-
-    /* missing close object */
-    j = json_pack("{}");
-    if(!json_unpack_ex(j, &error, 0, "{"))
-        fail("json_unpack failed to catch missing '}'");
-    check_error("Unexpected end of format string", "<format>", 1, 2, 2);
-    json_decref(j);
-
-    /* garbage after format string */
-    j = json_pack("[i]", 42);
-    if(!json_unpack_ex(j, &error, 0, "[i]a", &i1))
-        fail("json_unpack failed to catch garbage after format string");
-    check_error("Garbage after format string", "<format>", 1, 4, 4);
-    json_decref(j);
-
-    j = json_integer(12345);
-    if(!json_unpack_ex(j, &error, 0, "ia", &i1))
-        fail("json_unpack failed to catch garbage after format string");
-    check_error("Garbage after format string", "<format>", 1, 2, 2);
-    json_decref(j);
-
-    /* NULL format string */
-    j = json_pack("[]");
-    if(!json_unpack_ex(j, &error, 0, NULL))
-        fail("json_unpack failed to catch null format string");
-    check_error("NULL or empty format string", "<format>", -1, -1, 0);
-    json_decref(j);
-
-    /* NULL string pointer */
-    j = json_string("foobie");
-    if(!json_unpack_ex(j, &error, 0, "s", NULL))
-        fail("json_unpack failed to catch null string pointer");
-    check_error("NULL string argument", "<args>", 1, 1, 1);
-    json_decref(j);
-
-    /* invalid types */
-    j = json_integer(42);
-    j2 = json_string("foo");
-    if(!json_unpack_ex(j, &error, 0, "s"))
-        fail("json_unpack failed to catch invalid type");
-    check_error("Expected string, got integer", "<validation>", 1, 1, 1);
-
-    if(!json_unpack_ex(j, &error, 0, "n"))
-        fail("json_unpack failed to catch invalid type");
-    check_error("Expected null, got integer", "<validation>", 1, 1, 1);
-
-    if(!json_unpack_ex(j, &error, 0, "b"))
-        fail("json_unpack failed to catch invalid type");
-    check_error("Expected true or false, got integer", "<validation>", 1, 1, 1);
-
-    if(!json_unpack_ex(j2, &error, 0, "i"))
-        fail("json_unpack failed to catch invalid type");
-    check_error("Expected integer, got string", "<validation>", 1, 1, 1);
-
-    if(!json_unpack_ex(j2, &error, 0, "I"))
-        fail("json_unpack failed to catch invalid type");
-    check_error("Expected integer, got string", "<validation>", 1, 1, 1);
-
-    if(!json_unpack_ex(j, &error, 0, "f"))
-        fail("json_unpack failed to catch invalid type");
-    check_error("Expected real, got integer", "<validation>", 1, 1, 1);
-
-    if(!json_unpack_ex(j2, &error, 0, "F"))
-        fail("json_unpack failed to catch invalid type");
-    check_error("Expected real or integer, got string", "<validation>", 1, 1, 1);
-
-    if(!json_unpack_ex(j, &error, 0, "[i]"))
-        fail("json_unpack failed to catch invalid type");
-    check_error("Expected array, got integer", "<validation>", 1, 1, 1);
-
-    if(!json_unpack_ex(j, &error, 0, "{si}", "foo"))
-        fail("json_unpack failed to catch invalid type");
-    check_error("Expected object, got integer", "<validation>", 1, 1, 1);
-
-    json_decref(j);
-    json_decref(j2);
-
-    /* Array index out of range */
-    j = json_pack("[i]", 1);
-    if(!json_unpack_ex(j, &error, 0, "[ii]", &i1, &i2))
-        fail("json_unpack failed to catch index out of array bounds");
-    check_error("Array index 1 out of range", "<validation>", 1, 3, 3);
-    json_decref(j);
-
-    /* NULL object key */
-    j = json_pack("{si}", "foo", 42);
-    if(!json_unpack_ex(j, &error, 0, "{si}", NULL, &i1))
-        fail("json_unpack failed to catch null string pointer");
-    check_error("NULL object key", "<args>", 1, 2, 2);
-    json_decref(j);
-
-    /* Object key not found */
-    j = json_pack("{si}", "foo", 42);
-    if(!json_unpack_ex(j, &error, 0, "{si}", "baz", &i1))
-        fail("json_unpack failed to catch null string pointer");
-    check_error("Object item not found: baz", "<validation>", 1, 3, 3);
-    json_decref(j);
-
-    /*
-     * Strict validation
-     */
-
-    j = json_pack("[iii]", 1, 2, 3);
-    rv = json_unpack(j, "[iii!]", &i1, &i2, &i3);
-    if(rv || i1 != 1 || i2 != 2 || i3 != 3)
-        fail("json_unpack array with strict validation failed");
-    json_decref(j);
-
-    j = json_pack("[iii]", 1, 2, 3);
-    if(!json_unpack_ex(j, &error, 0, "[ii!]", &i1, &i2))
-        fail("json_unpack array with strict validation failed");
-    check_error("1 array item(s) left unpacked", "<validation>", 1, 5, 5);
-    json_decref(j);
-
-    /* Like above, but with JSON_STRICT instead of '!' format */
-    j = json_pack("[iii]", 1, 2, 3);
-    if(!json_unpack_ex(j, &error, JSON_STRICT, "[ii]", &i1, &i2))
-        fail("json_unpack array with strict validation failed");
-    check_error("1 array item(s) left unpacked", "<validation>", 1, 4, 4);
-    json_decref(j);
-
-    j = json_pack("{s:s, s:i}", "foo", "bar", "baz", 42);
-    rv = json_unpack(j, "{sssi!}", "foo", &s, "baz", &i1);
-    if(rv || strcmp(s, "bar") != 0 || i1 != 42)
-        fail("json_unpack object with strict validation failed");
-    json_decref(j);
-
-    /* Unpack the same item twice */
-    j = json_pack("{s:s, s:i}", "foo", "bar", "baz", 42);
-    if(!json_unpack_ex(j, &error, 0, "{s:s,s:s!}", "foo", &s, "foo", &s))
-        fail("json_unpack object with strict validation failed");
-    check_error("1 object item(s) left unpacked", "<validation>", 1, 10, 10);
-    json_decref(j);
-
-    j = json_pack("[i,{s:i,s:n},[i,i]]", 1, "foo", 2, "bar", 3, 4);
-    if(json_unpack_ex(j, NULL, JSON_STRICT | JSON_VALIDATE_ONLY,
-                      "[i{sisn}[ii]]", "foo", "bar"))
-        fail("json_unpack complex value with strict validation failed");
-    json_decref(j);
-
-    /* ! and * must be last */
-    j = json_pack("[ii]", 1, 2);
-    if(!json_unpack_ex(j, &error, 0, "[i!i]", &i1, &i2))
-        fail("json_unpack failed to catch ! in the middle of an array");
-    check_error("Expected ']' after '!', got 'i'", "<format>", 1, 4, 4);
-
-    if(!json_unpack_ex(j, &error, 0, "[i*i]", &i1, &i2))
-        fail("json_unpack failed to catch * in the middle of an array");
-    check_error("Expected ']' after '*', got 'i'", "<format>", 1, 4, 4);
-    json_decref(j);
-
-    j = json_pack("{sssi}", "foo", "bar", "baz", 42);
-    if(!json_unpack_ex(j, &error, 0, "{ss!si}", "foo", &s, "baz", &i1))
-        fail("json_unpack failed to catch ! in the middle of an object");
-    check_error("Expected '}' after '!', got 's'", "<format>", 1, 5, 5);
-
-    if(!json_unpack_ex(j, &error, 0, "{ss*si}", "foo", &s, "baz", &i1))
-        fail("json_unpack failed to catch ! in the middle of an object");
-    check_error("Expected '}' after '*', got 's'", "<format>", 1, 5, 5);
-    json_decref(j);
-
-    /* Error in nested object */
-    j = json_pack("{s{snsn}}", "foo", "bar", "baz");
-    if(!json_unpack_ex(j, &error, 0, "{s{sn!}}", "foo", "bar"))
-        fail("json_unpack nested object with strict validation failed");
-    check_error("1 object item(s) left unpacked", "<validation>", 1, 7, 7);
-    json_decref(j);
-
-    /* Error in nested array */
-    j = json_pack("[[ii]]", 1, 2);
-    if(!json_unpack_ex(j, &error, 0, "[[i!]]", &i1))
-        fail("json_unpack nested array with strict validation failed");
-    check_error("1 array item(s) left unpacked", "<validation>", 1, 5, 5);
-    json_decref(j);
-
-    /* Optional values */
-    j = json_object();
-    i1 = 0;
-    if(json_unpack(j, "{s?i}", "foo", &i1))
-        fail("json_unpack failed for optional key");
-    if(i1 != 0)
-        fail("json_unpack unpacked an optional key");
-    json_decref(j);
-
-    i1 = 0;
-    j = json_pack("{si}", "foo", 42);
-    if(json_unpack(j, "{s?i}", "foo", &i1))
-        fail("json_unpack failed for an optional value");
-    if(i1 != 42)
-        fail("json_unpack failed to unpack an optional value");
-    json_decref(j);
-
-    j = json_object();
-    i1 = i2 = i3 = 0;
-    if(json_unpack(j, "{s?[ii]s?{s{si}}}",
-                   "foo", &i1, &i2,
-                   "bar", "baz", "quux", &i3))
-        fail("json_unpack failed for complex optional values");
-    if(i1 != 0 || i2 != 0 || i3 != 0)
-        fail("json_unpack unexpectedly unpacked something");
-    json_decref(j);
-
-    j = json_pack("{s{si}}", "foo", "bar", 42);
-    if(json_unpack(j, "{s?{s?i}}", "foo", "bar", &i1))
-        fail("json_unpack failed for complex optional values");
-    if(i1 != 42)
-        fail("json_unpack failed to unpack");
-    json_decref(j);
-}
diff --git a/deps/jansson/test/suites/api/util.h b/deps/jansson/test/suites/api/util.h
deleted file mode 100644
index b86a546..0000000
--- a/deps/jansson/test/suites/api/util.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef UTIL_H
-#define UTIL_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#if HAVE_LOCALE_H
-#include <locale.h>
-#endif
-
-#include <jansson.h>
-
-#define failhdr fprintf(stderr, "%s:%s:%d: ", __FILE__, __FUNCTION__, __LINE__)
-
-#define fail(msg)                                                \
-    do {                                                         \
-        failhdr;                                                 \
-        fprintf(stderr, "%s\n", msg);                            \
-        exit(1);                                                 \
-    } while(0)
-
-/* Assumes json_error_t error */
-#define check_error(text_, source_, line_, column_, position_)          \
-    do {                                                                \
-        if(strcmp(error.text, text_) != 0) {                            \
-            failhdr;                                                    \
-            fprintf(stderr, "text: \"%s\" != \"%s\"\n", error.text, text_); \
-            exit(1);                                                    \
-        }                                                               \
-        if(strcmp(error.source, source_) != 0) {                        \
-            failhdr;                                                    \
-                                                                        \
-            fprintf(stderr, "source: \"%s\" != \"%s\"\n", error.source, source_); \
-            exit(1);                                                    \
-        }                                                               \
-        if(error.line != line_) {                                       \
-            failhdr;                                                    \
-            fprintf(stderr, "line: %d != %d\n", error.line, line_);     \
-            exit(1);                                                    \
-        }                                                               \
-        if(error.column != column_) {                                   \
-            failhdr;                                                    \
-            fprintf(stderr, "column: %d != %d\n", error.column, column_); \
-            exit(1);                                                    \
-        }                                                               \
-        if(error.position != position_) {                               \
-            failhdr;                                                    \
-            fprintf(stderr, "position: %d != %d\n", error.position, position_); \
-            exit(1);                                                    \
-        }                                                               \
-    } while(0)
-
-
-static void run_tests();
-
-int main() {
-#ifdef HAVE_SETLOCALE
-    setlocale(LC_ALL, "");
-#endif
-    run_tests();
-    return 0;
-}
-
-#endif
diff --git a/deps/jansson/test/suites/encoding-flags/array/input b/deps/jansson/test/suites/encoding-flags/array/input
deleted file mode 100644
index 44e2ace..0000000
--- a/deps/jansson/test/suites/encoding-flags/array/input
+++ /dev/null
@@ -1 +0,0 @@
-[1, 2]
diff --git a/deps/jansson/test/suites/encoding-flags/array/output b/deps/jansson/test/suites/encoding-flags/array/output
deleted file mode 100644
index fd8ef09..0000000
--- a/deps/jansson/test/suites/encoding-flags/array/output
+++ /dev/null
@@ -1 +0,0 @@
-[1, 2]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/encoding-flags/compact-array/env b/deps/jansson/test/suites/encoding-flags/compact-array/env
deleted file mode 100644
index 4474aaf..0000000
--- a/deps/jansson/test/suites/encoding-flags/compact-array/env
+++ /dev/null
@@ -1,2 +0,0 @@
-JSON_COMPACT=1
-export JSON_COMPACT
diff --git a/deps/jansson/test/suites/encoding-flags/compact-array/input b/deps/jansson/test/suites/encoding-flags/compact-array/input
deleted file mode 100644
index 44e2ace..0000000
--- a/deps/jansson/test/suites/encoding-flags/compact-array/input
+++ /dev/null
@@ -1 +0,0 @@
-[1, 2]
diff --git a/deps/jansson/test/suites/encoding-flags/compact-array/output b/deps/jansson/test/suites/encoding-flags/compact-array/output
deleted file mode 100644
index 3169929..0000000
--- a/deps/jansson/test/suites/encoding-flags/compact-array/output
+++ /dev/null
@@ -1 +0,0 @@
-[1,2]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/encoding-flags/compact-object/env b/deps/jansson/test/suites/encoding-flags/compact-object/env
deleted file mode 100644
index 4474aaf..0000000
--- a/deps/jansson/test/suites/encoding-flags/compact-object/env
+++ /dev/null
@@ -1,2 +0,0 @@
-JSON_COMPACT=1
-export JSON_COMPACT
diff --git a/deps/jansson/test/suites/encoding-flags/compact-object/input b/deps/jansson/test/suites/encoding-flags/compact-object/input
deleted file mode 100644
index 062e54f..0000000
--- a/deps/jansson/test/suites/encoding-flags/compact-object/input
+++ /dev/null
@@ -1 +0,0 @@
-{"a": 1, "b": 2}
diff --git a/deps/jansson/test/suites/encoding-flags/compact-object/output b/deps/jansson/test/suites/encoding-flags/compact-object/output
deleted file mode 100644
index 73a5d70..0000000
--- a/deps/jansson/test/suites/encoding-flags/compact-object/output
+++ /dev/null
@@ -1 +0,0 @@
-{"a":1,"b":2}
\ No newline at end of file
diff --git a/deps/jansson/test/suites/encoding-flags/ensure-ascii/env b/deps/jansson/test/suites/encoding-flags/ensure-ascii/env
deleted file mode 100644
index 1b7b3e3..0000000
--- a/deps/jansson/test/suites/encoding-flags/ensure-ascii/env
+++ /dev/null
@@ -1,2 +0,0 @@
-JSON_ENSURE_ASCII=1
-export JSON_ENSURE_ASCII
diff --git a/deps/jansson/test/suites/encoding-flags/ensure-ascii/input b/deps/jansson/test/suites/encoding-flags/ensure-ascii/input
deleted file mode 100644
index 69469ce..0000000
--- a/deps/jansson/test/suites/encoding-flags/ensure-ascii/input
+++ /dev/null
@@ -1,8 +0,0 @@
-[
-    "foo",
-    "å ä ö",
-    "foo åä",
-    "åä foo",
-    "å foo ä",
-    "clef g: 𝄞"
-]
diff --git a/deps/jansson/test/suites/encoding-flags/ensure-ascii/output b/deps/jansson/test/suites/encoding-flags/ensure-ascii/output
deleted file mode 100644
index 94fa79d..0000000
--- a/deps/jansson/test/suites/encoding-flags/ensure-ascii/output
+++ /dev/null
@@ -1 +0,0 @@
-["foo", "\u00E5 \u00E4 \u00F6", "foo \u00E5\u00E4", "\u00E5\u00E4 foo", "\u00E5 foo \u00E4", "clef g: \uD834\uDD1E"]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/encoding-flags/indent-array/env b/deps/jansson/test/suites/encoding-flags/indent-array/env
deleted file mode 100644
index d220f83..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-array/env
+++ /dev/null
@@ -1,2 +0,0 @@
-JSON_INDENT=4
-export JSON_INDENT
diff --git a/deps/jansson/test/suites/encoding-flags/indent-array/input b/deps/jansson/test/suites/encoding-flags/indent-array/input
deleted file mode 100644
index 44e2ace..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-array/input
+++ /dev/null
@@ -1 +0,0 @@
-[1, 2]
diff --git a/deps/jansson/test/suites/encoding-flags/indent-array/output b/deps/jansson/test/suites/encoding-flags/indent-array/output
deleted file mode 100644
index c57d705..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-array/output
+++ /dev/null
@@ -1,4 +0,0 @@
-[
-    1,
-    2
-]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/encoding-flags/indent-compact-array/env b/deps/jansson/test/suites/encoding-flags/indent-compact-array/env
deleted file mode 100644
index 78fbfcc..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-compact-array/env
+++ /dev/null
@@ -1,3 +0,0 @@
-JSON_INDENT=4
-JSON_COMPACT=1
-export JSON_INDENT JSON_COMPACT
diff --git a/deps/jansson/test/suites/encoding-flags/indent-compact-array/input b/deps/jansson/test/suites/encoding-flags/indent-compact-array/input
deleted file mode 100644
index 44e2ace..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-compact-array/input
+++ /dev/null
@@ -1 +0,0 @@
-[1, 2]
diff --git a/deps/jansson/test/suites/encoding-flags/indent-compact-array/output b/deps/jansson/test/suites/encoding-flags/indent-compact-array/output
deleted file mode 100644
index c57d705..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-compact-array/output
+++ /dev/null
@@ -1,4 +0,0 @@
-[
-    1,
-    2
-]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/encoding-flags/indent-compact-object/env b/deps/jansson/test/suites/encoding-flags/indent-compact-object/env
deleted file mode 100644
index 78fbfcc..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-compact-object/env
+++ /dev/null
@@ -1,3 +0,0 @@
-JSON_INDENT=4
-JSON_COMPACT=1
-export JSON_INDENT JSON_COMPACT
diff --git a/deps/jansson/test/suites/encoding-flags/indent-compact-object/input b/deps/jansson/test/suites/encoding-flags/indent-compact-object/input
deleted file mode 100644
index 062e54f..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-compact-object/input
+++ /dev/null
@@ -1 +0,0 @@
-{"a": 1, "b": 2}
diff --git a/deps/jansson/test/suites/encoding-flags/indent-compact-object/output b/deps/jansson/test/suites/encoding-flags/indent-compact-object/output
deleted file mode 100644
index 9cc4294..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-compact-object/output
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-    "a":1,
-    "b":2
-}
\ No newline at end of file
diff --git a/deps/jansson/test/suites/encoding-flags/indent-object/env b/deps/jansson/test/suites/encoding-flags/indent-object/env
deleted file mode 100644
index d220f83..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-object/env
+++ /dev/null
@@ -1,2 +0,0 @@
-JSON_INDENT=4
-export JSON_INDENT
diff --git a/deps/jansson/test/suites/encoding-flags/indent-object/input b/deps/jansson/test/suites/encoding-flags/indent-object/input
deleted file mode 100644
index 062e54f..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-object/input
+++ /dev/null
@@ -1 +0,0 @@
-{"a": 1, "b": 2}
diff --git a/deps/jansson/test/suites/encoding-flags/indent-object/output b/deps/jansson/test/suites/encoding-flags/indent-object/output
deleted file mode 100644
index 0fbddba..0000000
--- a/deps/jansson/test/suites/encoding-flags/indent-object/output
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-    "a": 1,
-    "b": 2
-}
\ No newline at end of file
diff --git a/deps/jansson/test/suites/encoding-flags/object/input b/deps/jansson/test/suites/encoding-flags/object/input
deleted file mode 100644
index 062e54f..0000000
--- a/deps/jansson/test/suites/encoding-flags/object/input
+++ /dev/null
@@ -1 +0,0 @@
-{"a": 1, "b": 2}
diff --git a/deps/jansson/test/suites/encoding-flags/object/output b/deps/jansson/test/suites/encoding-flags/object/output
deleted file mode 100644
index ecd219f..0000000
--- a/deps/jansson/test/suites/encoding-flags/object/output
+++ /dev/null
@@ -1 +0,0 @@
-{"a": 1, "b": 2}
\ No newline at end of file
diff --git a/deps/jansson/test/suites/encoding-flags/preserve-order/env b/deps/jansson/test/suites/encoding-flags/preserve-order/env
deleted file mode 100644
index 4d9d206..0000000
--- a/deps/jansson/test/suites/encoding-flags/preserve-order/env
+++ /dev/null
@@ -1,2 +0,0 @@
-JSON_PRESERVE_ORDER=1
-export JSON_PRESERVE_ORDER
diff --git a/deps/jansson/test/suites/encoding-flags/preserve-order/input b/deps/jansson/test/suites/encoding-flags/preserve-order/input
deleted file mode 100644
index 27bcf18..0000000
--- a/deps/jansson/test/suites/encoding-flags/preserve-order/input
+++ /dev/null
@@ -1 +0,0 @@
-{"foo": 1, "bar": 2, "asdf": 3, "deadbeef": 4, "badc0ffee": 5, "qwerty": 6}
diff --git a/deps/jansson/test/suites/encoding-flags/preserve-order/output b/deps/jansson/test/suites/encoding-flags/preserve-order/output
deleted file mode 100644
index 7a443f6..0000000
--- a/deps/jansson/test/suites/encoding-flags/preserve-order/output
+++ /dev/null
@@ -1 +0,0 @@
-{"foo": 1, "bar": 2, "asdf": 3, "deadbeef": 4, "badc0ffee": 5, "qwerty": 6}
\ No newline at end of file
diff --git a/deps/jansson/test/suites/encoding-flags/run b/deps/jansson/test/suites/encoding-flags/run
deleted file mode 100755
index 1920f7f..0000000
--- a/deps/jansson/test/suites/encoding-flags/run
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
-#
-# Jansson is free software; you can redistribute it and/or modify
-# it under the terms of the MIT license. See LICENSE for details.
-
-is_test() {
-    test -d $test_path
-}
-
-run_test() {
-    (
-        if [ -f $test_path/env ]; then
-            . $test_path/env
-        fi
-        $json_process --env <$test_path/input >$test_log/stdout 2>$test_log/stderr
-    )
-    valgrind_check $test_log/stderr || return 1
-    cmp -s $test_path/output $test_log/stdout
-}
-
-show_error() {
-    valgrind_show_error && return
-
-    echo "EXPECTED OUTPUT:"
-    nl -bn $test_path/output
-    echo "ACTUAL OUTPUT:"
-    nl -bn $test_log/stdout
-}
-
-. $top_srcdir/test/scripts/run-tests.sh
diff --git a/deps/jansson/test/suites/encoding-flags/sort-keys/env b/deps/jansson/test/suites/encoding-flags/sort-keys/env
deleted file mode 100644
index 3ef24cb..0000000
--- a/deps/jansson/test/suites/encoding-flags/sort-keys/env
+++ /dev/null
@@ -1,2 +0,0 @@
-JSON_SORT_KEYS=1
-export JSON_SORT_KEYS
diff --git a/deps/jansson/test/suites/encoding-flags/sort-keys/input b/deps/jansson/test/suites/encoding-flags/sort-keys/input
deleted file mode 100644
index 66951d6..0000000
--- a/deps/jansson/test/suites/encoding-flags/sort-keys/input
+++ /dev/null
@@ -1 +0,0 @@
-{"foo": 1, "bar": 2, "baz": 3, "quux": 4}
diff --git a/deps/jansson/test/suites/encoding-flags/sort-keys/output b/deps/jansson/test/suites/encoding-flags/sort-keys/output
deleted file mode 100644
index 132d9df..0000000
--- a/deps/jansson/test/suites/encoding-flags/sort-keys/output
+++ /dev/null
@@ -1 +0,0 @@
-{"bar": 2, "baz": 3, "foo": 1, "quux": 4}
\ No newline at end of file
diff --git a/deps/jansson/test/suites/invalid-unicode/encoded-surrogate-half/error b/deps/jansson/test/suites/invalid-unicode/encoded-surrogate-half/error
deleted file mode 100644
index 762d2c4..0000000
--- a/deps/jansson/test/suites/invalid-unicode/encoded-surrogate-half/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unable to decode byte 0xed near '"'
diff --git a/deps/jansson/test/suites/invalid-unicode/encoded-surrogate-half/input b/deps/jansson/test/suites/invalid-unicode/encoded-surrogate-half/input
deleted file mode 100644
index 515dd93..0000000
--- a/deps/jansson/test/suites/invalid-unicode/encoded-surrogate-half/input
+++ /dev/null
@@ -1 +0,0 @@
-["í¢« <-- encoded surrogate half"]
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-after-backslash/error b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-after-backslash/error
deleted file mode 100644
index b16dc17..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-after-backslash/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-unable to decode byte 0xe5 near '"\'
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-after-backslash/input b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-after-backslash/input
deleted file mode 100644
index 57c8bee..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-after-backslash/input
+++ /dev/null
@@ -1 +0,0 @@
-["\å"]
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-array/error b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-array/error
deleted file mode 100644
index be15386..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-array/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 1 1
-unable to decode byte 0xe5
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-array/input b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-array/input
deleted file mode 100644
index ebefcd6..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-array/input
+++ /dev/null
@@ -1 +0,0 @@
-[å]
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-bigger-int/error b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-bigger-int/error
deleted file mode 100644
index 01b4476..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-bigger-int/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 4 4
-unable to decode byte 0xe5 near '123'
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-bigger-int/input b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-bigger-int/input
deleted file mode 100644
index e512f9a..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-bigger-int/input
+++ /dev/null
@@ -1 +0,0 @@
-[123å]
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-escape/error b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-escape/error
deleted file mode 100644
index c13583d..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-escape/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 4 4
-unable to decode byte 0xe5 near '"\u'
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-escape/input b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-escape/input
deleted file mode 100644
index 2b271b8..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-escape/input
+++ /dev/null
@@ -1 +0,0 @@
-["\uå"]
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-exponent/error b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-exponent/error
deleted file mode 100644
index c7b20b7..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-exponent/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 4 4
-unable to decode byte 0xe5 near '1e1'
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-exponent/input b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-exponent/input
deleted file mode 100644
index d8e83c5..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-exponent/input
+++ /dev/null
@@ -1 +0,0 @@
-[1e1å]
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-identifier/error b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-identifier/error
deleted file mode 100644
index 33dfc23..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-identifier/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unable to decode byte 0xe5 near 'a'
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-identifier/input b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-identifier/input
deleted file mode 100644
index ef03851..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-identifier/input
+++ /dev/null
@@ -1 +0,0 @@
-[aå]
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-int/error b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-int/error
deleted file mode 100644
index 8f08970..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-int/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unable to decode byte 0xe5 near '0'
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-int/input b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-int/input
deleted file mode 100644
index 371226e..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-int/input
+++ /dev/null
@@ -1 +0,0 @@
-[0å]
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-real-after-e/error b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-real-after-e/error
deleted file mode 100644
index b7660e3..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-real-after-e/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-unable to decode byte 0xe5 near '1e'
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-real-after-e/input b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-real-after-e/input
deleted file mode 100644
index 17fc29c..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-real-after-e/input
+++ /dev/null
@@ -1 +0,0 @@
-[1eå]
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-string/error b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-string/error
deleted file mode 100644
index 0b7039a..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-string/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unable to decode byte 0xe5 near '"'
diff --git a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-string/input b/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-string/input
deleted file mode 100644
index 00b79c0..0000000
--- a/deps/jansson/test/suites/invalid-unicode/invalid-utf-8-in-string/input
+++ /dev/null
@@ -1 +0,0 @@
-["å <-- invalid UTF-8"]
diff --git a/deps/jansson/test/suites/invalid-unicode/lone-invalid-utf-8/error b/deps/jansson/test/suites/invalid-unicode/lone-invalid-utf-8/error
deleted file mode 100644
index 8e9a511..0000000
--- a/deps/jansson/test/suites/invalid-unicode/lone-invalid-utf-8/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 0 0
-unable to decode byte 0xe5
diff --git a/deps/jansson/test/suites/invalid-unicode/lone-invalid-utf-8/input b/deps/jansson/test/suites/invalid-unicode/lone-invalid-utf-8/input
deleted file mode 100644
index eb80796..0000000
--- a/deps/jansson/test/suites/invalid-unicode/lone-invalid-utf-8/input
+++ /dev/null
@@ -1 +0,0 @@
-å
diff --git a/deps/jansson/test/suites/invalid-unicode/lone-utf-8-continuation-byte/error b/deps/jansson/test/suites/invalid-unicode/lone-utf-8-continuation-byte/error
deleted file mode 100644
index 86bbad3..0000000
--- a/deps/jansson/test/suites/invalid-unicode/lone-utf-8-continuation-byte/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unable to decode byte 0x81 near '"'
diff --git a/deps/jansson/test/suites/invalid-unicode/lone-utf-8-continuation-byte/input b/deps/jansson/test/suites/invalid-unicode/lone-utf-8-continuation-byte/input
deleted file mode 100644
index 62a26b6..0000000
--- a/deps/jansson/test/suites/invalid-unicode/lone-utf-8-continuation-byte/input
+++ /dev/null
@@ -1 +0,0 @@
-[""]
diff --git a/deps/jansson/test/suites/invalid-unicode/not-in-unicode-range/error b/deps/jansson/test/suites/invalid-unicode/not-in-unicode-range/error
deleted file mode 100644
index d07ccb3..0000000
--- a/deps/jansson/test/suites/invalid-unicode/not-in-unicode-range/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unable to decode byte 0xf4 near '"'
diff --git a/deps/jansson/test/suites/invalid-unicode/not-in-unicode-range/input b/deps/jansson/test/suites/invalid-unicode/not-in-unicode-range/input
deleted file mode 100644
index 1216186..0000000
--- a/deps/jansson/test/suites/invalid-unicode/not-in-unicode-range/input
+++ /dev/null
@@ -1 +0,0 @@
-["ô¿¿¿"]
diff --git a/deps/jansson/test/suites/invalid-unicode/overlong-3-byte-encoding/error b/deps/jansson/test/suites/invalid-unicode/overlong-3-byte-encoding/error
deleted file mode 100644
index 8a05aba..0000000
--- a/deps/jansson/test/suites/invalid-unicode/overlong-3-byte-encoding/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unable to decode byte 0xe0 near '"'
diff --git a/deps/jansson/test/suites/invalid-unicode/overlong-3-byte-encoding/input b/deps/jansson/test/suites/invalid-unicode/overlong-3-byte-encoding/input
deleted file mode 100644
index 0bf909f..0000000
--- a/deps/jansson/test/suites/invalid-unicode/overlong-3-byte-encoding/input
+++ /dev/null
@@ -1 +0,0 @@
-["à€¢ <-- overlong encoding"]
diff --git a/deps/jansson/test/suites/invalid-unicode/overlong-4-byte-encoding/error b/deps/jansson/test/suites/invalid-unicode/overlong-4-byte-encoding/error
deleted file mode 100644
index 7e19c5f..0000000
--- a/deps/jansson/test/suites/invalid-unicode/overlong-4-byte-encoding/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unable to decode byte 0xf0 near '"'
diff --git a/deps/jansson/test/suites/invalid-unicode/overlong-4-byte-encoding/input b/deps/jansson/test/suites/invalid-unicode/overlong-4-byte-encoding/input
deleted file mode 100644
index c6b6313..0000000
--- a/deps/jansson/test/suites/invalid-unicode/overlong-4-byte-encoding/input
+++ /dev/null
@@ -1 +0,0 @@
-["ð€€¢ <-- overlong encoding"]
diff --git a/deps/jansson/test/suites/invalid-unicode/overlong-ascii-encoding/error b/deps/jansson/test/suites/invalid-unicode/overlong-ascii-encoding/error
deleted file mode 100644
index 1d382ed..0000000
--- a/deps/jansson/test/suites/invalid-unicode/overlong-ascii-encoding/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unable to decode byte 0xc1 near '"'
diff --git a/deps/jansson/test/suites/invalid-unicode/overlong-ascii-encoding/input b/deps/jansson/test/suites/invalid-unicode/overlong-ascii-encoding/input
deleted file mode 100644
index ef6e10a..0000000
--- a/deps/jansson/test/suites/invalid-unicode/overlong-ascii-encoding/input
+++ /dev/null
@@ -1 +0,0 @@
-["Á"]
diff --git a/deps/jansson/test/suites/invalid-unicode/restricted-utf-8/error b/deps/jansson/test/suites/invalid-unicode/restricted-utf-8/error
deleted file mode 100644
index d018f5f..0000000
--- a/deps/jansson/test/suites/invalid-unicode/restricted-utf-8/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unable to decode byte 0xfd near '"'
diff --git a/deps/jansson/test/suites/invalid-unicode/restricted-utf-8/input b/deps/jansson/test/suites/invalid-unicode/restricted-utf-8/input
deleted file mode 100644
index ba60170..0000000
--- a/deps/jansson/test/suites/invalid-unicode/restricted-utf-8/input
+++ /dev/null
@@ -1 +0,0 @@
-["ý"]
diff --git a/deps/jansson/test/suites/invalid-unicode/run b/deps/jansson/test/suites/invalid-unicode/run
deleted file mode 100755
index ac584f6..0000000
--- a/deps/jansson/test/suites/invalid-unicode/run
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
-#
-# Jansson is free software; you can redistribute it and/or modify
-# it under the terms of the MIT license. See LICENSE for details.
-
-is_test() {
-    test -d $test_path
-}
-
-run_test() {
-    $json_process --env <$test_path/input >$test_log/stdout 2>$test_log/stderr
-    valgrind_check $test_log/stderr || return 1
-    cmp -s $test_path/error $test_log/stderr
-}
-
-show_error() {
-    valgrind_show_error && return
-
-    echo "EXPECTED ERROR:"
-    nl -bn $test_path/error
-    echo "ACTUAL ERROR:"
-    nl -bn $test_log/stderr
-}
-
-. $top_srcdir/test/scripts/run-tests.sh
diff --git a/deps/jansson/test/suites/invalid-unicode/truncated-utf-8/error b/deps/jansson/test/suites/invalid-unicode/truncated-utf-8/error
deleted file mode 100644
index 8a05aba..0000000
--- a/deps/jansson/test/suites/invalid-unicode/truncated-utf-8/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unable to decode byte 0xe0 near '"'
diff --git a/deps/jansson/test/suites/invalid-unicode/truncated-utf-8/input b/deps/jansson/test/suites/invalid-unicode/truncated-utf-8/input
deleted file mode 100644
index bce9e18..0000000
--- a/deps/jansson/test/suites/invalid-unicode/truncated-utf-8/input
+++ /dev/null
@@ -1 +0,0 @@
-["àÿ <-- truncated UTF-8"]
diff --git a/deps/jansson/test/suites/invalid/apostrophe/error b/deps/jansson/test/suites/invalid/apostrophe/error
deleted file mode 100644
index 79bb2a0..0000000
--- a/deps/jansson/test/suites/invalid/apostrophe/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-invalid token near '''
diff --git a/deps/jansson/test/suites/invalid/apostrophe/input b/deps/jansson/test/suites/invalid/apostrophe/input
deleted file mode 100644
index f2dd4d2..0000000
--- a/deps/jansson/test/suites/invalid/apostrophe/input
+++ /dev/null
@@ -1 +0,0 @@
-['
diff --git a/deps/jansson/test/suites/invalid/ascii-unicode-identifier/error b/deps/jansson/test/suites/invalid/ascii-unicode-identifier/error
deleted file mode 100644
index a4d8142..0000000
--- a/deps/jansson/test/suites/invalid/ascii-unicode-identifier/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 1 1
-'[' or '{' expected near 'a'
diff --git a/deps/jansson/test/suites/invalid/ascii-unicode-identifier/input b/deps/jansson/test/suites/invalid/ascii-unicode-identifier/input
deleted file mode 100644
index c2c0208..0000000
--- a/deps/jansson/test/suites/invalid/ascii-unicode-identifier/input
+++ /dev/null
@@ -1 +0,0 @@
-aå
diff --git a/deps/jansson/test/suites/invalid/brace-comma/error b/deps/jansson/test/suites/invalid/brace-comma/error
deleted file mode 100644
index ce04621..0000000
--- a/deps/jansson/test/suites/invalid/brace-comma/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-string or '}' expected near ','
diff --git a/deps/jansson/test/suites/invalid/brace-comma/input b/deps/jansson/test/suites/invalid/brace-comma/input
deleted file mode 100644
index 74a6628..0000000
--- a/deps/jansson/test/suites/invalid/brace-comma/input
+++ /dev/null
@@ -1 +0,0 @@
-{,
diff --git a/deps/jansson/test/suites/invalid/bracket-comma/error b/deps/jansson/test/suites/invalid/bracket-comma/error
deleted file mode 100644
index ce0a912..0000000
--- a/deps/jansson/test/suites/invalid/bracket-comma/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unexpected token near ','
diff --git a/deps/jansson/test/suites/invalid/bracket-comma/input b/deps/jansson/test/suites/invalid/bracket-comma/input
deleted file mode 100644
index 5b911f1..0000000
--- a/deps/jansson/test/suites/invalid/bracket-comma/input
+++ /dev/null
@@ -1 +0,0 @@
-[,
diff --git a/deps/jansson/test/suites/invalid/bracket-one-comma/error.normal b/deps/jansson/test/suites/invalid/bracket-one-comma/error.normal
deleted file mode 100644
index 0248b11..0000000
--- a/deps/jansson/test/suites/invalid/bracket-one-comma/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-2 0 4
-']' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/bracket-one-comma/error.strip b/deps/jansson/test/suites/invalid/bracket-one-comma/error.strip
deleted file mode 100644
index f89b38f..0000000
--- a/deps/jansson/test/suites/invalid/bracket-one-comma/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-']' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/bracket-one-comma/input b/deps/jansson/test/suites/invalid/bracket-one-comma/input
deleted file mode 100644
index 874691b..0000000
--- a/deps/jansson/test/suites/invalid/bracket-one-comma/input
+++ /dev/null
@@ -1 +0,0 @@
-[1,
diff --git a/deps/jansson/test/suites/invalid/empty/error b/deps/jansson/test/suites/invalid/empty/error
deleted file mode 100644
index f45da6f..0000000
--- a/deps/jansson/test/suites/invalid/empty/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 0 0
-'[' or '{' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/empty/input b/deps/jansson/test/suites/invalid/empty/input
deleted file mode 100644
index e69de29..0000000
diff --git a/deps/jansson/test/suites/invalid/extra-comma-in-array/error b/deps/jansson/test/suites/invalid/extra-comma-in-array/error
deleted file mode 100644
index cae86c2..0000000
--- a/deps/jansson/test/suites/invalid/extra-comma-in-array/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 4 4
-unexpected token near ']'
diff --git a/deps/jansson/test/suites/invalid/extra-comma-in-array/input b/deps/jansson/test/suites/invalid/extra-comma-in-array/input
deleted file mode 100644
index e8b1a17..0000000
--- a/deps/jansson/test/suites/invalid/extra-comma-in-array/input
+++ /dev/null
@@ -1 +0,0 @@
-[1,]
diff --git a/deps/jansson/test/suites/invalid/extra-comma-in-multiline-array/error b/deps/jansson/test/suites/invalid/extra-comma-in-multiline-array/error
deleted file mode 100644
index 5baeea4..0000000
--- a/deps/jansson/test/suites/invalid/extra-comma-in-multiline-array/error
+++ /dev/null
@@ -1,2 +0,0 @@
-6 1 17
-unexpected token near ']'
diff --git a/deps/jansson/test/suites/invalid/extra-comma-in-multiline-array/input b/deps/jansson/test/suites/invalid/extra-comma-in-multiline-array/input
deleted file mode 100644
index bcb2a75..0000000
--- a/deps/jansson/test/suites/invalid/extra-comma-in-multiline-array/input
+++ /dev/null
@@ -1,6 +0,0 @@
-[1,
-2,
-3,
-4,
-5,
-]
diff --git a/deps/jansson/test/suites/invalid/garbage-after-newline/error b/deps/jansson/test/suites/invalid/garbage-after-newline/error
deleted file mode 100644
index 5d2dec3..0000000
--- a/deps/jansson/test/suites/invalid/garbage-after-newline/error
+++ /dev/null
@@ -1,2 +0,0 @@
-2 3 11
-end of file expected near 'foo'
diff --git a/deps/jansson/test/suites/invalid/garbage-after-newline/input b/deps/jansson/test/suites/invalid/garbage-after-newline/input
deleted file mode 100644
index 3614ac7..0000000
--- a/deps/jansson/test/suites/invalid/garbage-after-newline/input
+++ /dev/null
@@ -1,2 +0,0 @@
-[1,2,3]
-foo
diff --git a/deps/jansson/test/suites/invalid/garbage-at-the-end/error b/deps/jansson/test/suites/invalid/garbage-at-the-end/error
deleted file mode 100644
index cdd8175..0000000
--- a/deps/jansson/test/suites/invalid/garbage-at-the-end/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 10 10
-end of file expected near 'foo'
diff --git a/deps/jansson/test/suites/invalid/garbage-at-the-end/input b/deps/jansson/test/suites/invalid/garbage-at-the-end/input
deleted file mode 100644
index 55aee53..0000000
--- a/deps/jansson/test/suites/invalid/garbage-at-the-end/input
+++ /dev/null
@@ -1 +0,0 @@
-[1,2,3]foo
diff --git a/deps/jansson/test/suites/invalid/integer-starting-with-zero/error b/deps/jansson/test/suites/invalid/integer-starting-with-zero/error
deleted file mode 100644
index 64e0536..0000000
--- a/deps/jansson/test/suites/invalid/integer-starting-with-zero/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-invalid token near '0'
diff --git a/deps/jansson/test/suites/invalid/integer-starting-with-zero/input b/deps/jansson/test/suites/invalid/integer-starting-with-zero/input
deleted file mode 100644
index 12f67e2..0000000
--- a/deps/jansson/test/suites/invalid/integer-starting-with-zero/input
+++ /dev/null
@@ -1 +0,0 @@
-[012]
diff --git a/deps/jansson/test/suites/invalid/invalid-escape/error b/deps/jansson/test/suites/invalid/invalid-escape/error
deleted file mode 100644
index d9863f7..0000000
--- a/deps/jansson/test/suites/invalid/invalid-escape/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 4 4
-invalid escape near '"\a'
diff --git a/deps/jansson/test/suites/invalid/invalid-escape/input b/deps/jansson/test/suites/invalid/invalid-escape/input
deleted file mode 100644
index 64c7b70..0000000
--- a/deps/jansson/test/suites/invalid/invalid-escape/input
+++ /dev/null
@@ -1 +0,0 @@
-["\a <-- invalid escape"]
diff --git a/deps/jansson/test/suites/invalid/invalid-identifier/error b/deps/jansson/test/suites/invalid/invalid-identifier/error
deleted file mode 100644
index 496c6ab..0000000
--- a/deps/jansson/test/suites/invalid/invalid-identifier/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 5 5
-invalid token near 'troo'
diff --git a/deps/jansson/test/suites/invalid/invalid-identifier/input b/deps/jansson/test/suites/invalid/invalid-identifier/input
deleted file mode 100644
index 3d2860d..0000000
--- a/deps/jansson/test/suites/invalid/invalid-identifier/input
+++ /dev/null
@@ -1 +0,0 @@
-[troo
diff --git a/deps/jansson/test/suites/invalid/invalid-negative-integer/error b/deps/jansson/test/suites/invalid/invalid-negative-integer/error
deleted file mode 100644
index f2526c5..0000000
--- a/deps/jansson/test/suites/invalid/invalid-negative-integer/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 8 8
-']' expected near 'foo'
diff --git a/deps/jansson/test/suites/invalid/invalid-negative-integer/input b/deps/jansson/test/suites/invalid/invalid-negative-integer/input
deleted file mode 100644
index 6196980..0000000
--- a/deps/jansson/test/suites/invalid/invalid-negative-integer/input
+++ /dev/null
@@ -1 +0,0 @@
-[-123foo]
diff --git a/deps/jansson/test/suites/invalid/invalid-negative-real/error b/deps/jansson/test/suites/invalid/invalid-negative-real/error
deleted file mode 100644
index 933158a..0000000
--- a/deps/jansson/test/suites/invalid/invalid-negative-real/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 12 12
-']' expected near 'foo'
diff --git a/deps/jansson/test/suites/invalid/invalid-negative-real/input b/deps/jansson/test/suites/invalid/invalid-negative-real/input
deleted file mode 100644
index 3c763d3..0000000
--- a/deps/jansson/test/suites/invalid/invalid-negative-real/input
+++ /dev/null
@@ -1 +0,0 @@
-[-123.123foo]
diff --git a/deps/jansson/test/suites/invalid/invalid-second-surrogate/error b/deps/jansson/test/suites/invalid/invalid-second-surrogate/error
deleted file mode 100644
index e5a2359..0000000
--- a/deps/jansson/test/suites/invalid/invalid-second-surrogate/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 62 62
-invalid Unicode '\uD888\u3210'
diff --git a/deps/jansson/test/suites/invalid/invalid-second-surrogate/input b/deps/jansson/test/suites/invalid/invalid-second-surrogate/input
deleted file mode 100644
index b21453f..0000000
--- a/deps/jansson/test/suites/invalid/invalid-second-surrogate/input
+++ /dev/null
@@ -1 +0,0 @@
-["\uD888\u3210 (first surrogate and invalid second surrogate)"]
diff --git a/deps/jansson/test/suites/invalid/lone-open-brace/error.normal b/deps/jansson/test/suites/invalid/lone-open-brace/error.normal
deleted file mode 100644
index 00dc765..0000000
--- a/deps/jansson/test/suites/invalid/lone-open-brace/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-2 0 2
-string or '}' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/lone-open-brace/error.strip b/deps/jansson/test/suites/invalid/lone-open-brace/error.strip
deleted file mode 100644
index bb1c047..0000000
--- a/deps/jansson/test/suites/invalid/lone-open-brace/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 1 1
-string or '}' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/lone-open-brace/input b/deps/jansson/test/suites/invalid/lone-open-brace/input
deleted file mode 100644
index 98232c6..0000000
--- a/deps/jansson/test/suites/invalid/lone-open-brace/input
+++ /dev/null
@@ -1 +0,0 @@
-{
diff --git a/deps/jansson/test/suites/invalid/lone-open-bracket/error.normal b/deps/jansson/test/suites/invalid/lone-open-bracket/error.normal
deleted file mode 100644
index f463928..0000000
--- a/deps/jansson/test/suites/invalid/lone-open-bracket/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-2 0 2
-']' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/lone-open-bracket/error.strip b/deps/jansson/test/suites/invalid/lone-open-bracket/error.strip
deleted file mode 100644
index 2bc07ea..0000000
--- a/deps/jansson/test/suites/invalid/lone-open-bracket/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 1 1
-']' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/lone-open-bracket/input b/deps/jansson/test/suites/invalid/lone-open-bracket/input
deleted file mode 100644
index 558ed37..0000000
--- a/deps/jansson/test/suites/invalid/lone-open-bracket/input
+++ /dev/null
@@ -1 +0,0 @@
-[
diff --git a/deps/jansson/test/suites/invalid/lone-second-surrogate/error b/deps/jansson/test/suites/invalid/lone-second-surrogate/error
deleted file mode 100644
index bc5f34e..0000000
--- a/deps/jansson/test/suites/invalid/lone-second-surrogate/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 40 40
-invalid Unicode '\uDFAA'
diff --git a/deps/jansson/test/suites/invalid/lone-second-surrogate/input b/deps/jansson/test/suites/invalid/lone-second-surrogate/input
deleted file mode 100644
index 328e35c..0000000
--- a/deps/jansson/test/suites/invalid/lone-second-surrogate/input
+++ /dev/null
@@ -1 +0,0 @@
-["\uDFAA (second surrogate on it's own)"]
diff --git a/deps/jansson/test/suites/invalid/minus-sign-without-number/error b/deps/jansson/test/suites/invalid/minus-sign-without-number/error
deleted file mode 100644
index b3a78b9..0000000
--- a/deps/jansson/test/suites/invalid/minus-sign-without-number/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-invalid token near '-'
diff --git a/deps/jansson/test/suites/invalid/minus-sign-without-number/input b/deps/jansson/test/suites/invalid/minus-sign-without-number/input
deleted file mode 100644
index 0337883..0000000
--- a/deps/jansson/test/suites/invalid/minus-sign-without-number/input
+++ /dev/null
@@ -1 +0,0 @@
-[-foo]
diff --git a/deps/jansson/test/suites/invalid/negative-integer-starting-with-zero/error b/deps/jansson/test/suites/invalid/negative-integer-starting-with-zero/error
deleted file mode 100644
index 36adc34..0000000
--- a/deps/jansson/test/suites/invalid/negative-integer-starting-with-zero/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-invalid token near '-0'
diff --git a/deps/jansson/test/suites/invalid/negative-integer-starting-with-zero/input b/deps/jansson/test/suites/invalid/negative-integer-starting-with-zero/input
deleted file mode 100644
index 6fbb7a2..0000000
--- a/deps/jansson/test/suites/invalid/negative-integer-starting-with-zero/input
+++ /dev/null
@@ -1 +0,0 @@
-[-012]
diff --git a/deps/jansson/test/suites/invalid/null-byte-in-object-key/error b/deps/jansson/test/suites/invalid/null-byte-in-object-key/error
deleted file mode 100644
index 3ec685b..0000000
--- a/deps/jansson/test/suites/invalid/null-byte-in-object-key/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 15 15
-NUL byte in object key not supported near '"foo\u0000bar"'
diff --git a/deps/jansson/test/suites/invalid/null-byte-in-object-key/input b/deps/jansson/test/suites/invalid/null-byte-in-object-key/input
deleted file mode 100644
index 593f0f6..0000000
--- a/deps/jansson/test/suites/invalid/null-byte-in-object-key/input
+++ /dev/null
@@ -1 +0,0 @@
-{"foo\u0000bar": 42}
\ No newline at end of file
diff --git a/deps/jansson/test/suites/invalid/null-byte-in-string/error b/deps/jansson/test/suites/invalid/null-byte-in-string/error
deleted file mode 100644
index 45f9bd8..0000000
--- a/deps/jansson/test/suites/invalid/null-byte-in-string/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 12 12
-control character 0x0 near '"null byte '
diff --git a/deps/jansson/test/suites/invalid/null-byte-in-string/input b/deps/jansson/test/suites/invalid/null-byte-in-string/input
deleted file mode 100644
index 268d1f1..0000000
Binary files a/deps/jansson/test/suites/invalid/null-byte-in-string/input and /dev/null differ
diff --git a/deps/jansson/test/suites/invalid/null-byte-in-string/nostrip b/deps/jansson/test/suites/invalid/null-byte-in-string/nostrip
deleted file mode 100644
index 80f4bf7..0000000
--- a/deps/jansson/test/suites/invalid/null-byte-in-string/nostrip
+++ /dev/null
@@ -1,2 +0,0 @@
-The embedded NULL byte breaks json_loads(), which is used instead of
-json_loadf() in the stripped tests.
diff --git a/deps/jansson/test/suites/invalid/null-byte-outside-string/error b/deps/jansson/test/suites/invalid/null-byte-outside-string/error
deleted file mode 100644
index 44d4def..0000000
--- a/deps/jansson/test/suites/invalid/null-byte-outside-string/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-invalid token near end of file
diff --git a/deps/jansson/test/suites/invalid/null-byte-outside-string/input b/deps/jansson/test/suites/invalid/null-byte-outside-string/input
deleted file mode 100644
index aa550eb..0000000
Binary files a/deps/jansson/test/suites/invalid/null-byte-outside-string/input and /dev/null differ
diff --git a/deps/jansson/test/suites/invalid/null-byte-outside-string/nostrip b/deps/jansson/test/suites/invalid/null-byte-outside-string/nostrip
deleted file mode 100644
index 80f4bf7..0000000
--- a/deps/jansson/test/suites/invalid/null-byte-outside-string/nostrip
+++ /dev/null
@@ -1,2 +0,0 @@
-The embedded NULL byte breaks json_loads(), which is used instead of
-json_loadf() in the stripped tests.
diff --git a/deps/jansson/test/suites/invalid/null/error b/deps/jansson/test/suites/invalid/null/error
deleted file mode 100644
index 1f5d464..0000000
--- a/deps/jansson/test/suites/invalid/null/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 4 4
-'[' or '{' expected near 'null'
diff --git a/deps/jansson/test/suites/invalid/null/input b/deps/jansson/test/suites/invalid/null/input
deleted file mode 100644
index 19765bd..0000000
--- a/deps/jansson/test/suites/invalid/null/input
+++ /dev/null
@@ -1 +0,0 @@
-null
diff --git a/deps/jansson/test/suites/invalid/object-apostrophes/error b/deps/jansson/test/suites/invalid/object-apostrophes/error
deleted file mode 100644
index 23fab01..0000000
--- a/deps/jansson/test/suites/invalid/object-apostrophes/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-string or '}' expected near '''
diff --git a/deps/jansson/test/suites/invalid/object-apostrophes/input b/deps/jansson/test/suites/invalid/object-apostrophes/input
deleted file mode 100644
index 52b2905..0000000
--- a/deps/jansson/test/suites/invalid/object-apostrophes/input
+++ /dev/null
@@ -1 +0,0 @@
-{'a'
diff --git a/deps/jansson/test/suites/invalid/object-garbage-at-end/error b/deps/jansson/test/suites/invalid/object-garbage-at-end/error
deleted file mode 100644
index 06c4ec1..0000000
--- a/deps/jansson/test/suites/invalid/object-garbage-at-end/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 12 12
-'}' expected near '123'
diff --git a/deps/jansson/test/suites/invalid/object-garbage-at-end/input b/deps/jansson/test/suites/invalid/object-garbage-at-end/input
deleted file mode 100644
index 62c19d7..0000000
--- a/deps/jansson/test/suites/invalid/object-garbage-at-end/input
+++ /dev/null
@@ -1 +0,0 @@
-{"a":"a" 123}
diff --git a/deps/jansson/test/suites/invalid/object-in-unterminated-array/error.normal b/deps/jansson/test/suites/invalid/object-in-unterminated-array/error.normal
deleted file mode 100644
index 0248b11..0000000
--- a/deps/jansson/test/suites/invalid/object-in-unterminated-array/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-2 0 4
-']' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/object-in-unterminated-array/error.strip b/deps/jansson/test/suites/invalid/object-in-unterminated-array/error.strip
deleted file mode 100644
index f89b38f..0000000
--- a/deps/jansson/test/suites/invalid/object-in-unterminated-array/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-']' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/object-in-unterminated-array/input b/deps/jansson/test/suites/invalid/object-in-unterminated-array/input
deleted file mode 100644
index ca9ec37..0000000
--- a/deps/jansson/test/suites/invalid/object-in-unterminated-array/input
+++ /dev/null
@@ -1 +0,0 @@
-[{}
diff --git a/deps/jansson/test/suites/invalid/object-no-colon/error.normal b/deps/jansson/test/suites/invalid/object-no-colon/error.normal
deleted file mode 100644
index 78d84f7..0000000
--- a/deps/jansson/test/suites/invalid/object-no-colon/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-2 0 5
-':' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/object-no-colon/error.strip b/deps/jansson/test/suites/invalid/object-no-colon/error.strip
deleted file mode 100644
index 528e266..0000000
--- a/deps/jansson/test/suites/invalid/object-no-colon/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 4 4
-':' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/object-no-colon/input b/deps/jansson/test/suites/invalid/object-no-colon/input
deleted file mode 100644
index 107e626..0000000
--- a/deps/jansson/test/suites/invalid/object-no-colon/input
+++ /dev/null
@@ -1 +0,0 @@
-{"a"
diff --git a/deps/jansson/test/suites/invalid/object-no-value/error.normal b/deps/jansson/test/suites/invalid/object-no-value/error.normal
deleted file mode 100644
index 47ad902..0000000
--- a/deps/jansson/test/suites/invalid/object-no-value/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-2 0 6
-unexpected token near end of file
diff --git a/deps/jansson/test/suites/invalid/object-no-value/error.strip b/deps/jansson/test/suites/invalid/object-no-value/error.strip
deleted file mode 100644
index b36c5e2..0000000
--- a/deps/jansson/test/suites/invalid/object-no-value/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 5 5
-unexpected token near end of file
diff --git a/deps/jansson/test/suites/invalid/object-no-value/input b/deps/jansson/test/suites/invalid/object-no-value/input
deleted file mode 100644
index f68f262..0000000
--- a/deps/jansson/test/suites/invalid/object-no-value/input
+++ /dev/null
@@ -1 +0,0 @@
-{"a":
diff --git a/deps/jansson/test/suites/invalid/object-unterminated-value/error.normal b/deps/jansson/test/suites/invalid/object-unterminated-value/error.normal
deleted file mode 100644
index 2ad76d4..0000000
--- a/deps/jansson/test/suites/invalid/object-unterminated-value/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-1 7 7
-unexpected newline near '"a'
diff --git a/deps/jansson/test/suites/invalid/object-unterminated-value/error.strip b/deps/jansson/test/suites/invalid/object-unterminated-value/error.strip
deleted file mode 100644
index 385afb5..0000000
--- a/deps/jansson/test/suites/invalid/object-unterminated-value/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 7 7
-premature end of input near '"a'
diff --git a/deps/jansson/test/suites/invalid/object-unterminated-value/input b/deps/jansson/test/suites/invalid/object-unterminated-value/input
deleted file mode 100644
index b854d7e..0000000
--- a/deps/jansson/test/suites/invalid/object-unterminated-value/input
+++ /dev/null
@@ -1 +0,0 @@
-{"a":"a
diff --git a/deps/jansson/test/suites/invalid/real-garbage-after-e/error b/deps/jansson/test/suites/invalid/real-garbage-after-e/error
deleted file mode 100644
index b40ffa9..0000000
--- a/deps/jansson/test/suites/invalid/real-garbage-after-e/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-invalid token near '1e'
diff --git a/deps/jansson/test/suites/invalid/real-garbage-after-e/input b/deps/jansson/test/suites/invalid/real-garbage-after-e/input
deleted file mode 100644
index 6a945ac..0000000
--- a/deps/jansson/test/suites/invalid/real-garbage-after-e/input
+++ /dev/null
@@ -1 +0,0 @@
-[1ea]
diff --git a/deps/jansson/test/suites/invalid/real-negative-overflow/error b/deps/jansson/test/suites/invalid/real-negative-overflow/error
deleted file mode 100644
index d7f8e41..0000000
--- a/deps/jansson/test/suites/invalid/real-negative-overflow/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 15 15
-real number overflow near '-123123e100000'
diff --git a/deps/jansson/test/suites/invalid/real-negative-overflow/input b/deps/jansson/test/suites/invalid/real-negative-overflow/input
deleted file mode 100644
index b5bd21c..0000000
--- a/deps/jansson/test/suites/invalid/real-negative-overflow/input
+++ /dev/null
@@ -1 +0,0 @@
-[-123123e100000]
diff --git a/deps/jansson/test/suites/invalid/real-positive-overflow/error b/deps/jansson/test/suites/invalid/real-positive-overflow/error
deleted file mode 100644
index 55883c9..0000000
--- a/deps/jansson/test/suites/invalid/real-positive-overflow/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 14 14
-real number overflow near '123123e100000'
diff --git a/deps/jansson/test/suites/invalid/real-positive-overflow/input b/deps/jansson/test/suites/invalid/real-positive-overflow/input
deleted file mode 100644
index 524e53b..0000000
--- a/deps/jansson/test/suites/invalid/real-positive-overflow/input
+++ /dev/null
@@ -1 +0,0 @@
-[123123e100000]
diff --git a/deps/jansson/test/suites/invalid/real-truncated-at-e/error b/deps/jansson/test/suites/invalid/real-truncated-at-e/error
deleted file mode 100644
index b40ffa9..0000000
--- a/deps/jansson/test/suites/invalid/real-truncated-at-e/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-invalid token near '1e'
diff --git a/deps/jansson/test/suites/invalid/real-truncated-at-e/input b/deps/jansson/test/suites/invalid/real-truncated-at-e/input
deleted file mode 100644
index 1d67b7b..0000000
--- a/deps/jansson/test/suites/invalid/real-truncated-at-e/input
+++ /dev/null
@@ -1 +0,0 @@
-[1e]
diff --git a/deps/jansson/test/suites/invalid/real-truncated-at-point/error b/deps/jansson/test/suites/invalid/real-truncated-at-point/error
deleted file mode 100644
index db972e8..0000000
--- a/deps/jansson/test/suites/invalid/real-truncated-at-point/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-invalid token near '1.'
diff --git a/deps/jansson/test/suites/invalid/real-truncated-at-point/input b/deps/jansson/test/suites/invalid/real-truncated-at-point/input
deleted file mode 100644
index b652b3f..0000000
--- a/deps/jansson/test/suites/invalid/real-truncated-at-point/input
+++ /dev/null
@@ -1 +0,0 @@
-[1.]
diff --git a/deps/jansson/test/suites/invalid/run b/deps/jansson/test/suites/invalid/run
deleted file mode 100755
index a640ea0..0000000
--- a/deps/jansson/test/suites/invalid/run
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
-#
-# Jansson is free software; you can redistribute it and/or modify
-# it under the terms of the MIT license. See LICENSE for details.
-
-is_test() {
-    test -d $test_path
-}
-
-do_run() {
-    variant=$1
-    s=".$1"
-
-    strip=0
-    if [ "$variant" = "strip" ]; then
-        # This test should not be stripped
-        [ -f $test_path/nostrip ] && return
-        strip=1
-    fi
-
-    STRIP=$strip $json_process --env \
-        <$test_path/input >$test_log/stdout$s 2>$test_log/stderr$s
-    valgrind_check $test_log/stderr$s || return 1
-
-    ref=error
-    [ -f $test_path/error$s ] && ref=error$s
-
-    if ! cmp -s $test_path/$ref $test_log/stderr$s; then
-        echo $variant > $test_log/variant
-        return 1
-    fi
-}
-
-run_test() {
-    do_run normal && do_run strip
-}
-
-show_error() {
-    valgrind_show_error && return
-
-    read variant < $test_log/variant
-    s=".$variant"
-
-    echo "VARIANT: $variant"
-
-    echo "EXPECTED ERROR:"
-    ref=error
-    [ -f $test_path/error$s ] && ref=error$s
-    nl -bn $test_path/$ref
-
-    echo "ACTUAL ERROR:"
-    nl -bn $test_log/stderr$s
-}
-
-. $top_srcdir/test/scripts/run-tests.sh
diff --git a/deps/jansson/test/suites/invalid/tab-character-in-string/error b/deps/jansson/test/suites/invalid/tab-character-in-string/error
deleted file mode 100644
index 9e2f76e..0000000
--- a/deps/jansson/test/suites/invalid/tab-character-in-string/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-control character 0x9 near '"'
diff --git a/deps/jansson/test/suites/invalid/tab-character-in-string/input b/deps/jansson/test/suites/invalid/tab-character-in-string/input
deleted file mode 100644
index 3ebae09..0000000
--- a/deps/jansson/test/suites/invalid/tab-character-in-string/input
+++ /dev/null
@@ -1 +0,0 @@
-["	 <-- tab character"]
diff --git a/deps/jansson/test/suites/invalid/too-big-negative-integer/error b/deps/jansson/test/suites/invalid/too-big-negative-integer/error
deleted file mode 100644
index a0640b9..0000000
--- a/deps/jansson/test/suites/invalid/too-big-negative-integer/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 32 32
-too big negative integer
diff --git a/deps/jansson/test/suites/invalid/too-big-negative-integer/input b/deps/jansson/test/suites/invalid/too-big-negative-integer/input
deleted file mode 100644
index d6c26f1..0000000
--- a/deps/jansson/test/suites/invalid/too-big-negative-integer/input
+++ /dev/null
@@ -1 +0,0 @@
-[-123123123123123123123123123123]
diff --git a/deps/jansson/test/suites/invalid/too-big-positive-integer/error b/deps/jansson/test/suites/invalid/too-big-positive-integer/error
deleted file mode 100644
index 3bdbefd..0000000
--- a/deps/jansson/test/suites/invalid/too-big-positive-integer/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 31 31
-too big integer
diff --git a/deps/jansson/test/suites/invalid/too-big-positive-integer/input b/deps/jansson/test/suites/invalid/too-big-positive-integer/input
deleted file mode 100644
index 27c8553..0000000
--- a/deps/jansson/test/suites/invalid/too-big-positive-integer/input
+++ /dev/null
@@ -1 +0,0 @@
-[123123123123123123123123123123]
diff --git a/deps/jansson/test/suites/invalid/truncated-unicode-surrogate/error b/deps/jansson/test/suites/invalid/truncated-unicode-surrogate/error
deleted file mode 100644
index 1b99f06..0000000
--- a/deps/jansson/test/suites/invalid/truncated-unicode-surrogate/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 46 46
-invalid Unicode '\uDADA'
diff --git a/deps/jansson/test/suites/invalid/truncated-unicode-surrogate/input b/deps/jansson/test/suites/invalid/truncated-unicode-surrogate/input
deleted file mode 100644
index 2b340f4..0000000
--- a/deps/jansson/test/suites/invalid/truncated-unicode-surrogate/input
+++ /dev/null
@@ -1 +0,0 @@
-["\uDADA (first surrogate without the second)"]
diff --git a/deps/jansson/test/suites/invalid/unicode-identifier/error b/deps/jansson/test/suites/invalid/unicode-identifier/error
deleted file mode 100644
index 178b0dd..0000000
--- a/deps/jansson/test/suites/invalid/unicode-identifier/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 1 2
-'[' or '{' expected near 'Ã¥'
diff --git a/deps/jansson/test/suites/invalid/unicode-identifier/input b/deps/jansson/test/suites/invalid/unicode-identifier/input
deleted file mode 100644
index aad321c..0000000
--- a/deps/jansson/test/suites/invalid/unicode-identifier/input
+++ /dev/null
@@ -1 +0,0 @@
-Ã¥
diff --git a/deps/jansson/test/suites/invalid/unterminated-array-and-object/error.normal b/deps/jansson/test/suites/invalid/unterminated-array-and-object/error.normal
deleted file mode 100644
index 5b19804..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-array-and-object/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-2 0 3
-string or '}' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/unterminated-array-and-object/error.strip b/deps/jansson/test/suites/invalid/unterminated-array-and-object/error.strip
deleted file mode 100644
index da2bb22..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-array-and-object/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-string or '}' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/unterminated-array-and-object/input b/deps/jansson/test/suites/invalid/unterminated-array-and-object/input
deleted file mode 100644
index cd9dc64..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-array-and-object/input
+++ /dev/null
@@ -1 +0,0 @@
-[{
diff --git a/deps/jansson/test/suites/invalid/unterminated-array/error.normal b/deps/jansson/test/suites/invalid/unterminated-array/error.normal
deleted file mode 100644
index 8025ed1..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-array/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-2 0 5
-']' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/unterminated-array/error.strip b/deps/jansson/test/suites/invalid/unterminated-array/error.strip
deleted file mode 100644
index 495d0f7..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-array/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 4 4
-']' expected near end of file
diff --git a/deps/jansson/test/suites/invalid/unterminated-array/input b/deps/jansson/test/suites/invalid/unterminated-array/input
deleted file mode 100644
index 727ee81..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-array/input
+++ /dev/null
@@ -1 +0,0 @@
-["a"
diff --git a/deps/jansson/test/suites/invalid/unterminated-empty-key/error.normal b/deps/jansson/test/suites/invalid/unterminated-empty-key/error.normal
deleted file mode 100644
index 3d646ab..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-empty-key/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-unexpected newline near '"'
diff --git a/deps/jansson/test/suites/invalid/unterminated-empty-key/error.strip b/deps/jansson/test/suites/invalid/unterminated-empty-key/error.strip
deleted file mode 100644
index 94f1947..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-empty-key/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-premature end of input near '"'
diff --git a/deps/jansson/test/suites/invalid/unterminated-empty-key/input b/deps/jansson/test/suites/invalid/unterminated-empty-key/input
deleted file mode 100644
index 4117452..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-empty-key/input
+++ /dev/null
@@ -1 +0,0 @@
-{"
diff --git a/deps/jansson/test/suites/invalid/unterminated-key/error.normal b/deps/jansson/test/suites/invalid/unterminated-key/error.normal
deleted file mode 100644
index 5f09b77..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-key/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-unexpected newline near '"a'
diff --git a/deps/jansson/test/suites/invalid/unterminated-key/error.strip b/deps/jansson/test/suites/invalid/unterminated-key/error.strip
deleted file mode 100644
index 8b6bec4..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-key/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-premature end of input near '"a'
diff --git a/deps/jansson/test/suites/invalid/unterminated-key/input b/deps/jansson/test/suites/invalid/unterminated-key/input
deleted file mode 100644
index 705948c..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-key/input
+++ /dev/null
@@ -1 +0,0 @@
-{"a
diff --git a/deps/jansson/test/suites/invalid/unterminated-object-and-array/error b/deps/jansson/test/suites/invalid/unterminated-object-and-array/error
deleted file mode 100644
index ed97be7..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-object-and-array/error
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2 2
-string or '}' expected near '['
diff --git a/deps/jansson/test/suites/invalid/unterminated-object-and-array/input b/deps/jansson/test/suites/invalid/unterminated-object-and-array/input
deleted file mode 100644
index da35a86..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-object-and-array/input
+++ /dev/null
@@ -1 +0,0 @@
-{[
diff --git a/deps/jansson/test/suites/invalid/unterminated-string/error.normal b/deps/jansson/test/suites/invalid/unterminated-string/error.normal
deleted file mode 100644
index 5f09b77..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-string/error.normal
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-unexpected newline near '"a'
diff --git a/deps/jansson/test/suites/invalid/unterminated-string/error.strip b/deps/jansson/test/suites/invalid/unterminated-string/error.strip
deleted file mode 100644
index 8b6bec4..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-string/error.strip
+++ /dev/null
@@ -1,2 +0,0 @@
-1 3 3
-premature end of input near '"a'
diff --git a/deps/jansson/test/suites/invalid/unterminated-string/input b/deps/jansson/test/suites/invalid/unterminated-string/input
deleted file mode 100644
index 38ab6b0..0000000
--- a/deps/jansson/test/suites/invalid/unterminated-string/input
+++ /dev/null
@@ -1 +0,0 @@
-["a
diff --git a/deps/jansson/test/suites/valid/complex-array/env b/deps/jansson/test/suites/valid/complex-array/env
deleted file mode 100644
index bd89eff..0000000
--- a/deps/jansson/test/suites/valid/complex-array/env
+++ /dev/null
@@ -1 +0,0 @@
-JSON_SORT_KEYS=1
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/complex-array/input b/deps/jansson/test/suites/valid/complex-array/input
deleted file mode 100644
index 1b9bbb9..0000000
--- a/deps/jansson/test/suites/valid/complex-array/input
+++ /dev/null
@@ -1,5 +0,0 @@
-[1,2,3,4,
-"a", "b", "c",
-{"foo": "bar", "core": "dump"},
-true, false, true, true, null, false
-]
diff --git a/deps/jansson/test/suites/valid/complex-array/output b/deps/jansson/test/suites/valid/complex-array/output
deleted file mode 100644
index 7aefe56..0000000
--- a/deps/jansson/test/suites/valid/complex-array/output
+++ /dev/null
@@ -1 +0,0 @@
-[1, 2, 3, 4, "a", "b", "c", {"core": "dump", "foo": "bar"}, true, false, true, true, null, false]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/empty-array/input b/deps/jansson/test/suites/valid/empty-array/input
deleted file mode 100644
index fe51488..0000000
--- a/deps/jansson/test/suites/valid/empty-array/input
+++ /dev/null
@@ -1 +0,0 @@
-[]
diff --git a/deps/jansson/test/suites/valid/empty-array/output b/deps/jansson/test/suites/valid/empty-array/output
deleted file mode 100644
index 0637a08..0000000
--- a/deps/jansson/test/suites/valid/empty-array/output
+++ /dev/null
@@ -1 +0,0 @@
-[]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/empty-object-in-array/input b/deps/jansson/test/suites/valid/empty-object-in-array/input
deleted file mode 100644
index 93d5140..0000000
--- a/deps/jansson/test/suites/valid/empty-object-in-array/input
+++ /dev/null
@@ -1 +0,0 @@
-[{}]
diff --git a/deps/jansson/test/suites/valid/empty-object-in-array/output b/deps/jansson/test/suites/valid/empty-object-in-array/output
deleted file mode 100644
index ee1aac4..0000000
--- a/deps/jansson/test/suites/valid/empty-object-in-array/output
+++ /dev/null
@@ -1 +0,0 @@
-[{}]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/empty-object/input b/deps/jansson/test/suites/valid/empty-object/input
deleted file mode 100644
index 0967ef4..0000000
--- a/deps/jansson/test/suites/valid/empty-object/input
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/deps/jansson/test/suites/valid/empty-object/output b/deps/jansson/test/suites/valid/empty-object/output
deleted file mode 100644
index 9e26dfe..0000000
--- a/deps/jansson/test/suites/valid/empty-object/output
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/empty-string/input b/deps/jansson/test/suites/valid/empty-string/input
deleted file mode 100644
index 66a1e18..0000000
--- a/deps/jansson/test/suites/valid/empty-string/input
+++ /dev/null
@@ -1 +0,0 @@
-[""]
diff --git a/deps/jansson/test/suites/valid/empty-string/output b/deps/jansson/test/suites/valid/empty-string/output
deleted file mode 100644
index 93b6be2..0000000
--- a/deps/jansson/test/suites/valid/empty-string/output
+++ /dev/null
@@ -1 +0,0 @@
-[""]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/escaped-utf-control-char/input b/deps/jansson/test/suites/valid/escaped-utf-control-char/input
deleted file mode 100644
index 9a98545..0000000
--- a/deps/jansson/test/suites/valid/escaped-utf-control-char/input
+++ /dev/null
@@ -1 +0,0 @@
-["\u0012 escaped control character"]
diff --git a/deps/jansson/test/suites/valid/escaped-utf-control-char/output b/deps/jansson/test/suites/valid/escaped-utf-control-char/output
deleted file mode 100644
index 07221b7..0000000
--- a/deps/jansson/test/suites/valid/escaped-utf-control-char/output
+++ /dev/null
@@ -1 +0,0 @@
-["\u0012 escaped control character"]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/false/input b/deps/jansson/test/suites/valid/false/input
deleted file mode 100644
index 4343652..0000000
--- a/deps/jansson/test/suites/valid/false/input
+++ /dev/null
@@ -1 +0,0 @@
-[false]
diff --git a/deps/jansson/test/suites/valid/false/output b/deps/jansson/test/suites/valid/false/output
deleted file mode 100644
index 67b2f07..0000000
--- a/deps/jansson/test/suites/valid/false/output
+++ /dev/null
@@ -1 +0,0 @@
-[false]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/negative-int/input b/deps/jansson/test/suites/valid/negative-int/input
deleted file mode 100644
index a96d5cd..0000000
--- a/deps/jansson/test/suites/valid/negative-int/input
+++ /dev/null
@@ -1 +0,0 @@
-[-123]
diff --git a/deps/jansson/test/suites/valid/negative-int/output b/deps/jansson/test/suites/valid/negative-int/output
deleted file mode 100644
index 8e30f8b..0000000
--- a/deps/jansson/test/suites/valid/negative-int/output
+++ /dev/null
@@ -1 +0,0 @@
-[-123]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/negative-one/input b/deps/jansson/test/suites/valid/negative-one/input
deleted file mode 100644
index 2363a1a..0000000
--- a/deps/jansson/test/suites/valid/negative-one/input
+++ /dev/null
@@ -1 +0,0 @@
-[-1]
diff --git a/deps/jansson/test/suites/valid/negative-one/output b/deps/jansson/test/suites/valid/negative-one/output
deleted file mode 100644
index 99d21a2..0000000
--- a/deps/jansson/test/suites/valid/negative-one/output
+++ /dev/null
@@ -1 +0,0 @@
-[-1]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/negative-zero/input b/deps/jansson/test/suites/valid/negative-zero/input
deleted file mode 100644
index 40fc49c..0000000
--- a/deps/jansson/test/suites/valid/negative-zero/input
+++ /dev/null
@@ -1 +0,0 @@
-[-0]
diff --git a/deps/jansson/test/suites/valid/negative-zero/output b/deps/jansson/test/suites/valid/negative-zero/output
deleted file mode 100644
index 6e7ea63..0000000
--- a/deps/jansson/test/suites/valid/negative-zero/output
+++ /dev/null
@@ -1 +0,0 @@
-[0]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/null/input b/deps/jansson/test/suites/valid/null/input
deleted file mode 100644
index 62864b3..0000000
--- a/deps/jansson/test/suites/valid/null/input
+++ /dev/null
@@ -1 +0,0 @@
-[null]
diff --git a/deps/jansson/test/suites/valid/null/output b/deps/jansson/test/suites/valid/null/output
deleted file mode 100644
index 500db4a..0000000
--- a/deps/jansson/test/suites/valid/null/output
+++ /dev/null
@@ -1 +0,0 @@
-[null]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/one-byte-utf-8/input b/deps/jansson/test/suites/valid/one-byte-utf-8/input
deleted file mode 100644
index 8bda468..0000000
--- a/deps/jansson/test/suites/valid/one-byte-utf-8/input
+++ /dev/null
@@ -1 +0,0 @@
-["\u002c one-byte UTF-8"]
diff --git a/deps/jansson/test/suites/valid/one-byte-utf-8/output b/deps/jansson/test/suites/valid/one-byte-utf-8/output
deleted file mode 100644
index c33d250..0000000
--- a/deps/jansson/test/suites/valid/one-byte-utf-8/output
+++ /dev/null
@@ -1 +0,0 @@
-[", one-byte UTF-8"]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/real-capital-e-negative-exponent/input b/deps/jansson/test/suites/valid/real-capital-e-negative-exponent/input
deleted file mode 100644
index 1e9fa51..0000000
--- a/deps/jansson/test/suites/valid/real-capital-e-negative-exponent/input
+++ /dev/null
@@ -1 +0,0 @@
-[1E-2]
diff --git a/deps/jansson/test/suites/valid/real-capital-e-negative-exponent/output b/deps/jansson/test/suites/valid/real-capital-e-negative-exponent/output
deleted file mode 100644
index 75b9ef9..0000000
--- a/deps/jansson/test/suites/valid/real-capital-e-negative-exponent/output
+++ /dev/null
@@ -1 +0,0 @@
-[0.01]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/real-capital-e-positive-exponent/input b/deps/jansson/test/suites/valid/real-capital-e-positive-exponent/input
deleted file mode 100644
index 6a6ab93..0000000
--- a/deps/jansson/test/suites/valid/real-capital-e-positive-exponent/input
+++ /dev/null
@@ -1 +0,0 @@
-[1E+2]
diff --git a/deps/jansson/test/suites/valid/real-capital-e-positive-exponent/output b/deps/jansson/test/suites/valid/real-capital-e-positive-exponent/output
deleted file mode 100644
index d8ff702..0000000
--- a/deps/jansson/test/suites/valid/real-capital-e-positive-exponent/output
+++ /dev/null
@@ -1 +0,0 @@
-[100.0]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/real-capital-e/input b/deps/jansson/test/suites/valid/real-capital-e/input
deleted file mode 100644
index e703223..0000000
--- a/deps/jansson/test/suites/valid/real-capital-e/input
+++ /dev/null
@@ -1 +0,0 @@
-[1E22]
diff --git a/deps/jansson/test/suites/valid/real-capital-e/output b/deps/jansson/test/suites/valid/real-capital-e/output
deleted file mode 100644
index 9a739f2..0000000
--- a/deps/jansson/test/suites/valid/real-capital-e/output
+++ /dev/null
@@ -1 +0,0 @@
-[1e22]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/real-exponent/input b/deps/jansson/test/suites/valid/real-exponent/input
deleted file mode 100644
index b2a69b9..0000000
--- a/deps/jansson/test/suites/valid/real-exponent/input
+++ /dev/null
@@ -1 +0,0 @@
-[123e45]
diff --git a/deps/jansson/test/suites/valid/real-exponent/output b/deps/jansson/test/suites/valid/real-exponent/output
deleted file mode 100644
index 5ffc719..0000000
--- a/deps/jansson/test/suites/valid/real-exponent/output
+++ /dev/null
@@ -1 +0,0 @@
-[1.2299999999999999e47]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/real-fraction-exponent/input b/deps/jansson/test/suites/valid/real-fraction-exponent/input
deleted file mode 100644
index 0c1660d..0000000
--- a/deps/jansson/test/suites/valid/real-fraction-exponent/input
+++ /dev/null
@@ -1 +0,0 @@
-[123.456e78]
diff --git a/deps/jansson/test/suites/valid/real-fraction-exponent/output b/deps/jansson/test/suites/valid/real-fraction-exponent/output
deleted file mode 100644
index 66a3c81..0000000
--- a/deps/jansson/test/suites/valid/real-fraction-exponent/output
+++ /dev/null
@@ -1 +0,0 @@
-[1.23456e80]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/real-negative-exponent/input b/deps/jansson/test/suites/valid/real-negative-exponent/input
deleted file mode 100644
index daa4af9..0000000
--- a/deps/jansson/test/suites/valid/real-negative-exponent/input
+++ /dev/null
@@ -1 +0,0 @@
-[1e-2]
diff --git a/deps/jansson/test/suites/valid/real-negative-exponent/output b/deps/jansson/test/suites/valid/real-negative-exponent/output
deleted file mode 100644
index 75b9ef9..0000000
--- a/deps/jansson/test/suites/valid/real-negative-exponent/output
+++ /dev/null
@@ -1 +0,0 @@
-[0.01]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/real-positive-exponent/input b/deps/jansson/test/suites/valid/real-positive-exponent/input
deleted file mode 100644
index f378077..0000000
--- a/deps/jansson/test/suites/valid/real-positive-exponent/input
+++ /dev/null
@@ -1 +0,0 @@
-[1e+2]
diff --git a/deps/jansson/test/suites/valid/real-positive-exponent/output b/deps/jansson/test/suites/valid/real-positive-exponent/output
deleted file mode 100644
index d8ff702..0000000
--- a/deps/jansson/test/suites/valid/real-positive-exponent/output
+++ /dev/null
@@ -1 +0,0 @@
-[100.0]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/real-underflow/input b/deps/jansson/test/suites/valid/real-underflow/input
deleted file mode 100644
index dc70996..0000000
--- a/deps/jansson/test/suites/valid/real-underflow/input
+++ /dev/null
@@ -1 +0,0 @@
-[123e-10000000]
diff --git a/deps/jansson/test/suites/valid/real-underflow/output b/deps/jansson/test/suites/valid/real-underflow/output
deleted file mode 100644
index 92df1df..0000000
--- a/deps/jansson/test/suites/valid/real-underflow/output
+++ /dev/null
@@ -1 +0,0 @@
-[0.0]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/run b/deps/jansson/test/suites/valid/run
deleted file mode 100755
index c30d94a..0000000
--- a/deps/jansson/test/suites/valid/run
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2009-2013 Petri Lehtinen <petri at digip.org>
-#
-# Jansson is free software; you can redistribute it and/or modify
-# it under the terms of the MIT license. See LICENSE for details.
-
-JSON_SORT_KEYS=1
-export JSON_SORT_KEYS
-
-is_test() {
-    test -d $test_path
-}
-
-do_run() {
-    variant=$1
-    s=".$1"
-
-    strip=0
-    [ "$variant" = "strip" ] && strip=1
-
-    STRIP=$strip $json_process --env \
-        <$test_path/input >$test_log/stdout$s 2>$test_log/stderr$s
-    valgrind_check $test_log/stderr$s || return 1
-
-    ref=output
-    [ -f $test_path/output$s ] && ref=output$s
-
-    if ! cmp -s $test_path/$ref $test_log/stdout$s; then
-        echo $variant > $test_log/variant
-        return 1
-    fi
-}
-
-run_test() {
-    do_run normal && do_run strip
-}
-
-show_error() {
-    valgrind_show_error && return
-
-    read variant < $test_log/variant
-    s=".$variant"
-
-    echo "VARIANT: $variant"
-
-    echo "EXPECTED OUTPUT:"
-    ref=output
-    [ -f $test_path/output$s ] && ref=output$s
-    nl -bn $test_path/$ref
-
-    echo "ACTUAL OUTPUT:"
-    nl -bn $test_log/stdout$s
-}
-
-. $top_srcdir/test/scripts/run-tests.sh
diff --git a/deps/jansson/test/suites/valid/short-string/input b/deps/jansson/test/suites/valid/short-string/input
deleted file mode 100644
index 0c3426d..0000000
--- a/deps/jansson/test/suites/valid/short-string/input
+++ /dev/null
@@ -1 +0,0 @@
-["a"]
diff --git a/deps/jansson/test/suites/valid/short-string/output b/deps/jansson/test/suites/valid/short-string/output
deleted file mode 100644
index eac5f7b..0000000
--- a/deps/jansson/test/suites/valid/short-string/output
+++ /dev/null
@@ -1 +0,0 @@
-["a"]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/simple-ascii-string/input b/deps/jansson/test/suites/valid/simple-ascii-string/input
deleted file mode 100644
index 929b215..0000000
--- a/deps/jansson/test/suites/valid/simple-ascii-string/input
+++ /dev/null
@@ -1 +0,0 @@
-["abcdefghijklmnopqrstuvwxyz1234567890 "]
diff --git a/deps/jansson/test/suites/valid/simple-ascii-string/output b/deps/jansson/test/suites/valid/simple-ascii-string/output
deleted file mode 100644
index 90358ab..0000000
--- a/deps/jansson/test/suites/valid/simple-ascii-string/output
+++ /dev/null
@@ -1 +0,0 @@
-["abcdefghijklmnopqrstuvwxyz1234567890 "]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/simple-int-0/input b/deps/jansson/test/suites/valid/simple-int-0/input
deleted file mode 100644
index 111bb86..0000000
--- a/deps/jansson/test/suites/valid/simple-int-0/input
+++ /dev/null
@@ -1 +0,0 @@
-[0]
diff --git a/deps/jansson/test/suites/valid/simple-int-0/output b/deps/jansson/test/suites/valid/simple-int-0/output
deleted file mode 100644
index 6e7ea63..0000000
--- a/deps/jansson/test/suites/valid/simple-int-0/output
+++ /dev/null
@@ -1 +0,0 @@
-[0]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/simple-int-1/input b/deps/jansson/test/suites/valid/simple-int-1/input
deleted file mode 100644
index 7660873..0000000
--- a/deps/jansson/test/suites/valid/simple-int-1/input
+++ /dev/null
@@ -1 +0,0 @@
-[1]
diff --git a/deps/jansson/test/suites/valid/simple-int-1/output b/deps/jansson/test/suites/valid/simple-int-1/output
deleted file mode 100644
index bace2a0..0000000
--- a/deps/jansson/test/suites/valid/simple-int-1/output
+++ /dev/null
@@ -1 +0,0 @@
-[1]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/simple-int-123/input b/deps/jansson/test/suites/valid/simple-int-123/input
deleted file mode 100644
index 3214bfe..0000000
--- a/deps/jansson/test/suites/valid/simple-int-123/input
+++ /dev/null
@@ -1 +0,0 @@
-[123]
diff --git a/deps/jansson/test/suites/valid/simple-int-123/output b/deps/jansson/test/suites/valid/simple-int-123/output
deleted file mode 100644
index e47f69a..0000000
--- a/deps/jansson/test/suites/valid/simple-int-123/output
+++ /dev/null
@@ -1 +0,0 @@
-[123]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/simple-object/input b/deps/jansson/test/suites/valid/simple-object/input
deleted file mode 100644
index a34fb49..0000000
--- a/deps/jansson/test/suites/valid/simple-object/input
+++ /dev/null
@@ -1 +0,0 @@
-{"a":[]}
diff --git a/deps/jansson/test/suites/valid/simple-object/output b/deps/jansson/test/suites/valid/simple-object/output
deleted file mode 100644
index 982abe8..0000000
--- a/deps/jansson/test/suites/valid/simple-object/output
+++ /dev/null
@@ -1 +0,0 @@
-{"a": []}
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/simple-real/input b/deps/jansson/test/suites/valid/simple-real/input
deleted file mode 100644
index 0fed7df..0000000
--- a/deps/jansson/test/suites/valid/simple-real/input
+++ /dev/null
@@ -1 +0,0 @@
-[123.456789]
diff --git a/deps/jansson/test/suites/valid/simple-real/output b/deps/jansson/test/suites/valid/simple-real/output
deleted file mode 100644
index b02878e..0000000
--- a/deps/jansson/test/suites/valid/simple-real/output
+++ /dev/null
@@ -1 +0,0 @@
-[123.456789]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/string-escapes/input b/deps/jansson/test/suites/valid/string-escapes/input
deleted file mode 100644
index d994564..0000000
--- a/deps/jansson/test/suites/valid/string-escapes/input
+++ /dev/null
@@ -1 +0,0 @@
-["\"\\\/\b\f\n\r\t"]
diff --git a/deps/jansson/test/suites/valid/string-escapes/output b/deps/jansson/test/suites/valid/string-escapes/output
deleted file mode 100644
index ca5c1c6..0000000
--- a/deps/jansson/test/suites/valid/string-escapes/output
+++ /dev/null
@@ -1 +0,0 @@
-["\"\\/\b\f\n\r\t"]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/three-byte-utf-8/input b/deps/jansson/test/suites/valid/three-byte-utf-8/input
deleted file mode 100644
index ccc0bfa..0000000
--- a/deps/jansson/test/suites/valid/three-byte-utf-8/input
+++ /dev/null
@@ -1 +0,0 @@
-["\u0821 three-byte UTF-8"]
diff --git a/deps/jansson/test/suites/valid/three-byte-utf-8/output b/deps/jansson/test/suites/valid/three-byte-utf-8/output
deleted file mode 100644
index c44d124..0000000
--- a/deps/jansson/test/suites/valid/three-byte-utf-8/output
+++ /dev/null
@@ -1 +0,0 @@
-["à ¡ three-byte UTF-8"]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/true/input b/deps/jansson/test/suites/valid/true/input
deleted file mode 100644
index 29513c4..0000000
--- a/deps/jansson/test/suites/valid/true/input
+++ /dev/null
@@ -1 +0,0 @@
-[true]
diff --git a/deps/jansson/test/suites/valid/true/output b/deps/jansson/test/suites/valid/true/output
deleted file mode 100644
index de601e3..0000000
--- a/deps/jansson/test/suites/valid/true/output
+++ /dev/null
@@ -1 +0,0 @@
-[true]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/two-byte-utf-8/input b/deps/jansson/test/suites/valid/two-byte-utf-8/input
deleted file mode 100644
index 05ae854..0000000
--- a/deps/jansson/test/suites/valid/two-byte-utf-8/input
+++ /dev/null
@@ -1 +0,0 @@
-["\u0123 two-byte UTF-8"]
diff --git a/deps/jansson/test/suites/valid/two-byte-utf-8/output b/deps/jansson/test/suites/valid/two-byte-utf-8/output
deleted file mode 100644
index 1f0988d..0000000
--- a/deps/jansson/test/suites/valid/two-byte-utf-8/output
+++ /dev/null
@@ -1 +0,0 @@
-["Ä£ two-byte UTF-8"]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/utf-8-string/input b/deps/jansson/test/suites/valid/utf-8-string/input
deleted file mode 100644
index 20dc64a..0000000
--- a/deps/jansson/test/suites/valid/utf-8-string/input
+++ /dev/null
@@ -1 +0,0 @@
-["€þıœəßð some utf-8 ĸʒ×ŋµåäö𝄞"]
diff --git a/deps/jansson/test/suites/valid/utf-8-string/output b/deps/jansson/test/suites/valid/utf-8-string/output
deleted file mode 100644
index 5372865..0000000
--- a/deps/jansson/test/suites/valid/utf-8-string/output
+++ /dev/null
@@ -1 +0,0 @@
-["€þıœəßð some utf-8 ĸʒ×ŋµåäö𝄞"]
\ No newline at end of file
diff --git a/deps/jansson/test/suites/valid/utf-surrogate-four-byte-encoding/input b/deps/jansson/test/suites/valid/utf-surrogate-four-byte-encoding/input
deleted file mode 100644
index c598b41..0000000
--- a/deps/jansson/test/suites/valid/utf-surrogate-four-byte-encoding/input
+++ /dev/null
@@ -1 +0,0 @@
-["\uD834\uDD1E surrogate, four-byte UTF-8"]
diff --git a/deps/jansson/test/suites/valid/utf-surrogate-four-byte-encoding/output b/deps/jansson/test/suites/valid/utf-surrogate-four-byte-encoding/output
deleted file mode 100644
index fa806d2..0000000
--- a/deps/jansson/test/suites/valid/utf-surrogate-four-byte-encoding/output
+++ /dev/null
@@ -1 +0,0 @@
-["𝄞 surrogate, four-byte UTF-8"]
\ No newline at end of file
diff --git a/deps/jansson/win32/jansson_config.h b/deps/jansson/win32/jansson_config.h
deleted file mode 100644
index ab1da5d..0000000
--- a/deps/jansson/win32/jansson_config.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2010-2013 Petri Lehtinen <petri at digip.org>
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- *
- *
- * This file specifies a part of the site-specific configuration for
- * Jansson, namely those things that affect the public API in
- * jansson.h.
- *
- * The configure script copies this file to jansson_config.h and
- * replaces @var@ substitutions by values that fit your system. If you
- * cannot run the configure script, you can do the value substitution
- * by hand.
- */
-
-#ifndef JANSSON_CONFIG_H
-#define JANSSON_CONFIG_H
-
-/* If your compiler supports the inline keyword in C, JSON_INLINE is
-   defined to `inline', otherwise empty. In C++, the inline is always
-   supported. */
-#ifdef __cplusplus
-#define JSON_INLINE inline
-#else
-#define JSON_INLINE __inline
-#endif
-
-/* If your compiler supports the `long long` type and the strtoll()
-   library function, JSON_INTEGER_IS_LONG_LONG is defined to 1,
-   otherwise to 0. */
-#define JSON_INTEGER_IS_LONG_LONG 1
-
-/* If locale.h and localeconv() are available, define to 1,
-   otherwise to 0. */
-#define JSON_HAVE_LOCALECONV 1
-
-#endif
diff --git a/deps/jansson/win32/vs2010/jansson.sln b/deps/jansson/win32/vs2010/jansson.sln
deleted file mode 100644
index f5640eb..0000000
--- a/deps/jansson/win32/vs2010/jansson.sln
+++ /dev/null
@@ -1,26 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jansson", "jansson.vcxproj", "{76226D20-1972-4789-A595-EDACC7A76DC3}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
-		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{76226D20-1972-4789-A595-EDACC7A76DC3}.Debug|Win32.ActiveCfg = Debug|Win32
-		{76226D20-1972-4789-A595-EDACC7A76DC3}.Debug|Win32.Build.0 = Debug|Win32
-		{76226D20-1972-4789-A595-EDACC7A76DC3}.Debug|x64.ActiveCfg = Debug|x64
-		{76226D20-1972-4789-A595-EDACC7A76DC3}.Debug|x64.Build.0 = Debug|x64
-		{76226D20-1972-4789-A595-EDACC7A76DC3}.Release|Win32.ActiveCfg = Release|Win32
-		{76226D20-1972-4789-A595-EDACC7A76DC3}.Release|Win32.Build.0 = Release|Win32
-		{76226D20-1972-4789-A595-EDACC7A76DC3}.Release|x64.ActiveCfg = Release|x64
-		{76226D20-1972-4789-A595-EDACC7A76DC3}.Release|x64.Build.0 = Release|x64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/deps/jansson/win32/vs2010/jansson.vcxproj b/deps/jansson/win32/vs2010/jansson.vcxproj
deleted file mode 100644
index 1fe675a..0000000
--- a/deps/jansson/win32/vs2010/jansson.vcxproj
+++ /dev/null
@@ -1,181 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\src\dump.c" />
-    <ClCompile Include="..\..\src\error.c" />
-    <ClCompile Include="..\..\src\hashtable.c" />
-    <ClCompile Include="..\..\src\load.c" />
-    <ClCompile Include="..\..\src\memory.c" />
-    <ClCompile Include="..\..\src\pack_unpack.c" />
-    <ClCompile Include="..\..\src\strbuffer.c" />
-    <ClCompile Include="..\..\src\strconv.c" />
-    <ClCompile Include="..\..\src\utf.c" />
-    <ClCompile Include="..\..\src\value.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\src\hashtable.h" />
-    <ClInclude Include="..\..\src\jansson.h" />
-    <ClInclude Include="..\..\src\jansson_private.h" />
-    <ClInclude Include="..\..\src\strbuffer.h" />
-    <ClInclude Include="..\..\src\utf.h" />
-    <ClInclude Include="..\jansson_config.h" />
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{76226D20-1972-4789-A595-EDACC7A76DC3}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>jansson_dll</RootNamespace>
-    <ProjectName>jansson</ProjectName>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>Output\$(Configuration)\</OutDir>
-    <IntDir>Build\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>Output\$(Configuration)\</OutDir>
-    <IntDir>Build\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>Output\$(Configuration)\</OutDir>
-    <IntDir>Build\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>Output\$(Configuration)\</OutDir>
-    <IntDir>Build\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;JANSSON_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <ModuleDefinitionFile>../../src/jansson.def</ModuleDefinitionFile>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;JANSSON_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <ModuleDefinitionFile>../../src/jansson.def</ModuleDefinitionFile>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;JANSSON_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <ModuleDefinitionFile>../../src/jansson.def</ModuleDefinitionFile>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;JANSSON_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <ModuleDefinitionFile>../../src/jansson.def</ModuleDefinitionFile>
-    </Link>
-  </ItemDefinitionGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/deps/jansson/win32/vs2010/jansson.vcxproj.filters b/deps/jansson/win32/vs2010/jansson.vcxproj.filters
deleted file mode 100644
index f8eee30..0000000
--- a/deps/jansson/win32/vs2010/jansson.vcxproj.filters
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\src\dump.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\error.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\hashtable.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\load.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\memory.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\pack_unpack.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\strbuffer.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\strconv.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\utf.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\value.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\src\hashtable.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\jansson.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\jansson_private.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\strbuffer.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\utf.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\jansson_config.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/deps/jansson/win32/vs2010/jansson.vcxproj.user b/deps/jansson/win32/vs2010/jansson.vcxproj.user
deleted file mode 100644
index ace9a86..0000000
--- a/deps/jansson/win32/vs2010/jansson.vcxproj.user
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-</Project>
\ No newline at end of file
diff --git a/deps/libcaption/.gitignore b/deps/libcaption/.gitignore
new file mode 100644
index 0000000..d52b1ec
--- /dev/null
+++ b/deps/libcaption/.gitignore
@@ -0,0 +1,57 @@
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+
+# cmake files
+Makefile
+CMakeFiles
+CMakeCache.txt
+cmake_install.cmake
+
+# Bin
+scc2srt
+srt2vtt
+flv2srt
+ts2srt
+flv+srt
+srtdump
+party
+rtmpspit
+
+# Autogenerated files
+# src/eia608.c
+
+# Mac
+.DS_Store
+
+#Doc
+Doxyfile
diff --git a/deps/libcaption/CMakeLists.txt b/deps/libcaption/CMakeLists.txt
new file mode 100644
index 0000000..638d532
--- /dev/null
+++ b/deps/libcaption/CMakeLists.txt
@@ -0,0 +1,34 @@
+cmake_minimum_required(VERSION 2.8)
+project(libcaption)
+add_definitions(-D__STDC_CONSTANT_MACROS)
+if (WIN32)
+  add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+endif()
+
+# Don't need to prefix local includes with "caption/*"
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/caption)
+
+set(CAPTION_SOURCES
+  src/utf8.c
+  src/srt.c
+  src/scc.c
+  src/avc.c
+  src/xds.c
+  src/cea708.c
+  src/caption.c
+  src/eia608_charmap.c
+  src/eia608.c
+)
+
+set(CAPTION_HEADERS
+  caption/utf8.h
+  caption/sei.h
+  caption/scc.h
+  caption/avc.c
+  caption/cea708.h
+  caption/eia608.h
+  caption/caption.h
+  caption/eia608_charmap.h
+)
+
+add_library(caption STATIC ${CAPTION_SOURCES})
diff --git a/deps/libcaption/Doxyfile.in b/deps/libcaption/Doxyfile.in
new file mode 100644
index 0000000..6fd4ebb
--- /dev/null
+++ b/deps/libcaption/Doxyfile.in
@@ -0,0 +1,2406 @@
+# Doxyfile 1.8.11
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = "libcaption"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ./docs
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = YES
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR          = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = @CMAKE_CURRENT_SOURCE_DIR@/include @CMAKE_CURRENT_SOURCE_DIR@/examples
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
+# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.h *.c *.re2c
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/deps/libcaption/LICENSE.txt b/deps/libcaption/LICENSE.txt
new file mode 100644
index 0000000..43df7fb
--- /dev/null
+++ b/deps/libcaption/LICENSE.txt
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/deps/libcaption/README.md b/deps/libcaption/README.md
new file mode 100644
index 0000000..160a956
--- /dev/null
+++ b/deps/libcaption/README.md
@@ -0,0 +1,99 @@
+# version
+v0.6
+Matthew Szatmary m3u8 at twitch.tv / matt at szatmary.org
+
+# libcaption
+
+libcaption is a small library written in C to aid in the creating and parsing of closed caption data for use in the twitch player, open sourced to use within community developed broadcast tools. To maintain consistency across platforms libcaption aims to implement a subset of EIA608, CEA708 as supported by the Apple iOS platform.
+
+608 support is currently limited to encoding and decoding the necessary control and preamble codes as well as support for the Basic North American, Special North American and Extended Western European character sets.
+
+708 support is limited to encoding the 608 data in NTSC field 1 user data type structure.
+
+In addition, utility functions to create h.264 SEI (Supplementary enhancement information) NALUs (Network Abstraction Layer Unit) for inclusion into an h.264 elementary stream are provided.
+
+H.264 utility functions are limited to wrapping the 708 payload into a SEI NALU. This is accomplished by prepending the 708 payload with 3 bytes (nal_unit_type = 6, payloadType = 4, and PayloadSize = variable), and appending a stop bit encoded into a full byte (with a value of 127). In addition if the 708 payload contains an emulated start code, a three byte sequence equaling 0,0,1 an emulation prevention byte (3) is inserted. Functions to reverse this operation are also provided.
+
+## Characters
+| | | | | | | | | | | | | | | | | |
+|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
+|BNA| |!|"|#|$|%|&|’|(|)|á|+|,|-|.|/|
+|BNA|0|1|2|3|4|5|6|7|8|9|:|;|<|=|>|?|
+|BNA|@|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|
+|BNA|P|Q|R|S|T|U|V|W|X|Y|Z|[|é|]|í|ó|
+|BNA|ú|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|
+|BNA|p|q|r|s|t|u|v|w|x|y|z|ç|÷|Ñ|ñ|█|
+|SNA|®|°|½|¿|™|¢|£|♪|à| |è|â|ê|î|ô|û|
+|WES|Á|É|Ó|Ú|Ü|ü|‘|¡|*|'|—|©|℠|•|“|”|
+|WEF|À|Â|Ç|È|Ê|Ë|ë|Î|Ï|ï|Ô|Ù|ù|Û|«|»|
+|WEP|Ã|ã|Í|Ì|ì|Ò|ò|Õ|õ|{|}|\\|^|_|\||~|
+|WEG|Ä|ä|Ö|ö|ß|¥|¤|¦|Å|å|Ø|ø|┌|┐|└|┘|
+
+* BNA = Basic North American character set
+* SNA = Special North American character set
+* WES = Extended Western European character set : Extended Spanish/Miscellaneous
+* WEF = Extended Western European character set : Extended French
+* WEP = Extended Western European character set : Portuguese
+* WEG = Extended Western European character set : German/Danish
+
+
+------
+eia608_screen_t is the default internal representation. `screens` can be
+converted to and from SEI messages 608/708 buffers and SRT files
+
+## JSON format
+A JSON rendered format is provided for convenience of integration. The JSON
+format is as follows:
+
+```
+{
+    "format":  "eia608",
+    "mode":    "pop-on",
+    "roll-up": 0,
+    "data": [
+        { "row":0, "col":0, "char":"A", "style":"white" },
+        { "row":0, "col":1, "char":"B", "style":"white" },
+        // ...
+    ]
+}
+```
+
+### `format`
+The only current valid value is `"eia608"`. This field exists for
+future expansion.  Any values other than `"eia608"`, and the object should be
+ignored for now.
+
+### `mode`
+Defines the method by which screen contents are adjusted in response to
+new data, such as content in excess of the normal grid size.
+
+Possible modes are:
+
+`"clear"`: Generated when a screen is initialized, but not entered a "loading"
+state. `"clear"` mode  occurs frequently when the display is to be erased.
+
+`"pop-on"`: Normally used for pre recorded content where. A pop-on screen should
+completely replace all previous screen contents.
+
+`"paint-on"`: Normally used for live content. In this mode, new characters
+appear one or two at a time. The `data` array does include the complete state of
+the screen. In practice, it may not be different that `"pop-on"`.
+
+An internal "loading" mode also exists.
+
+### `roll-up`
+Normally used for live content such as news broadcasts. Text is moved up the
+screen as new rows appear. The number of rows to be displayed is also encoded in
+the JSON  key `"roll-up"` where value is an integer of `0`, `1`, `2`, `3`, or `4`.
+Like `"paint-on"`, the `data` array does include the complete state of the screen.
+
+### `data`
+Contains a object for every character to be displayed. The screen is a grid of
+15 rows and 32 columns. The position of the character is available in the `row`
+and `col` fields. The character itself is in the `char` field. The full
+character set is available in the document, but any valid UTF-8 should be
+supported for future. The style field will contain one of the following values:
+
+`"white"`, `"green"`, `"blue"`, `"cyan"`, `"red"`, `"yellow"`, `"magenta"`, `"italics"`
+
+Characters with the `"italics"` style should be displayed in white.
diff --git a/deps/libcaption/caption/avc.h b/deps/libcaption/caption/avc.h
new file mode 100644
index 0000000..d4d4ed7
--- /dev/null
+++ b/deps/libcaption/caption/avc.h
@@ -0,0 +1,198 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#ifndef LIBCAPTION_AVC_H
+#define LIBCAPTION_AVC_H
+#include "cea708.h"
+#include "caption.h"
+#include <float.h>
+////////////////////////////////////////////////////////////////////////////////
+#define MAX_NALU_SIZE (4*1024*1024)
+typedef struct {
+    size_t size;
+    uint8_t data[MAX_NALU_SIZE];
+} avcnalu_t;
+
+void avcnalu_init (avcnalu_t* nalu);
+int avcnalu_parse_annexb (avcnalu_t* nalu, const uint8_t** data, size_t* size);
+static inline uint8_t  avcnalu_type (avcnalu_t* nalu) { return nalu->data[0] & 0x1F; }
+static inline uint8_t* avcnalu_data (avcnalu_t* nalu) { return &nalu->data[0]; }
+static inline size_t   avcnalu_size (avcnalu_t* nalu) { return nalu->size; }
+////////////////////////////////////////////////////////////////////////////////
+typedef struct _sei_message_t sei_message_t;
+
+typedef enum {
+    sei_type_buffering_period = 0,
+    sei_type_pic_timing = 1,
+    sei_type_pan_scan_rect = 2,
+    sei_type_filler_payload = 3,
+    sei_type_user_data_registered_itu_t_t35 = 4,
+    sei_type_user_data_unregistered = 5,
+    sei_type_recovery_point = 6,
+    sei_type_dec_ref_pic_marking_repetition = 7,
+    sei_type_spare_pic = 8,
+    sei_type_scene_info = 9,
+    sei_type_sub_seq_info = 10,
+    sei_type_sub_seq_layer_characteristics = 11,
+    sei_type_sub_seq_characteristics = 12,
+    sei_type_full_frame_freeze = 13,
+    sei_type_full_frame_freeze_release = 14,
+    sei_type_full_frame_snapshot = 15,
+    sei_type_progressive_refinement_segment_start = 16,
+    sei_type_progressive_refinement_segment_end = 17,
+    sei_type_motion_constrained_slice_group_set = 18,
+    sei_type_film_grain_characteristics = 19,
+    sei_type_deblocking_filter_display_preference = 20,
+    sei_type_stereo_video_info = 21,
+} sei_msgtype_t;
+////////////////////////////////////////////////////////////////////////////////
+// time in seconds
+typedef struct  {
+    double dts;
+    double cts;
+    sei_message_t* head;
+    sei_message_t* tail;
+} sei_t;
+
+/*! \brief
+    \param
+*/
+void sei_init (sei_t* sei);
+/*! \brief
+    \param
+*/
+void sei_free (sei_t* sei);
+/*! \brief
+    \param
+*/
+static inline double sei_dts (sei_t* sei) { return sei->dts; }
+static inline double sei_cts (sei_t* sei) { return sei->cts; }
+static inline double sei_pts (sei_t* sei) { return sei->dts + sei->cts; }
+/*! \brief
+    \param
+*/
+int sei_parse_nalu (sei_t* sei, const uint8_t* data, size_t size, double dts, double cts);
+/*! \brief
+    \param
+*/
+// TODO add dts,cts to nalu
+static inline int sei_parse_avcnalu (sei_t* sei, avcnalu_t* nalu, double dts, double cts) { return sei_parse_nalu (sei,avcnalu_data (nalu),avcnalu_size (nalu),dts,cts); }
+/*! \brief
+    \param
+*/
+static inline int sei_finish (sei_t* sei) { return sei_parse_nalu (sei,0,0,0.0,DBL_MAX); }
+/*! \brief
+    \param
+*/
+static inline sei_message_t* sei_message_head (sei_t* sei) { return sei->head; }
+/*! \brief
+    \param
+*/
+static inline sei_message_t* sei_message_tail (sei_t* sei) { return sei->tail; }
+/*! \brief
+    \param
+*/
+sei_message_t* sei_message_next (sei_message_t* msg);
+/*! \brief
+    \param
+*/
+sei_msgtype_t sei_message_type (sei_message_t* msg);
+/*! \brief
+    \param
+*/
+size_t sei_message_size (sei_message_t* msg);
+/*! \brief
+    \param
+*/
+uint8_t* sei_message_data (sei_message_t* msg);
+/*! \brief
+    \param
+*/
+sei_message_t* sei_message_new (sei_msgtype_t type, uint8_t* data, size_t size);
+/*! \brief
+    \param
+*/
+static inline sei_message_t* sei_message_copy (sei_message_t* msg)
+{
+    return sei_message_new (sei_message_type (msg), sei_message_data (msg), sei_message_size (msg));
+}
+/**
+Free message and all accoiated data. Messaged added to sei_t by using sei_append_message MUST NOT be freed
+These messages will be freed by calling sei_free()
+*/
+/*! \brief
+    \param
+*/
+void  sei_message_free (sei_message_t* msg);
+////////////////////////////////////////////////////////////////////////////////
+/*! \brief
+    \param
+*/
+static inline int sei_decode_cea708 (sei_message_t* msg, cea708_t* cea708)
+{
+    if (sei_type_user_data_registered_itu_t_t35 == sei_message_type (msg)) {
+        return cea708_parse (sei_message_data (msg), sei_message_size (msg), cea708);
+    } else {
+        return 0;
+    }
+}
+////////////////////////////////////////////////////////////////////////////////
+/*! \brief
+    \param
+*/
+size_t sei_render_size (sei_t* sei);
+/*! \brief
+    \param
+*/
+size_t sei_render (sei_t* sei, uint8_t* data);
+/*! \brief
+    \param
+*/
+void sei_dump (sei_t* sei);
+/*! \brief
+    \param
+*/
+void sei_dump_messages (sei_message_t* head);
+////////////////////////////////////////////////////////////////////////////////
+/*! \brief
+    \param
+*/
+int sei_from_caption_frame (sei_t* sei, caption_frame_t* frame);
+/*! \brief
+    \param
+*/
+libcaption_stauts_t sei_to_caption_frame (sei_t* sei, caption_frame_t* frame);
+/*! \brief
+    \param
+*/
+static inline int nalu_to_caption_frame (caption_frame_t* frame, const uint8_t* data, size_t size, double pts, double dts)
+{
+    sei_t sei;
+    sei_init (&sei);
+    sei_parse_nalu (&sei, data, size, pts, dts);
+    sei_to_caption_frame (&sei,frame);
+    sei_free (&sei);
+    return 1;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif
diff --git a/deps/libcaption/caption/caption.h b/deps/libcaption/caption/caption.h
new file mode 100644
index 0000000..665ec28
--- /dev/null
+++ b/deps/libcaption/caption/caption.h
@@ -0,0 +1,141 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#ifndef LIBCAPTION_H
+#define LIBCAPTION_H
+#include "utf8.h"
+#include "xds.h"
+#include "eia608.h"
+
+// ssize_t is POSIX and does not exist on Windows
+#if defined(_MSC_VER)
+#if defined(_WIN64)
+typedef signed long ssize_t;
+#else
+typedef signed int ssize_t;
+#endif
+#endif
+
+typedef enum {
+    LIBCAPTION_OK = 1,
+    LIBCAPTION_ERROR = 0,
+    LIBCAPTION_READY = 2
+} libcaption_stauts_t;
+
+
+/*! \brief
+    \param
+*/
+static inline libcaption_stauts_t libcaption_status_update (libcaption_stauts_t old_stat, libcaption_stauts_t new_stat) { return (LIBCAPTION_ERROR == old_stat || LIBCAPTION_ERROR == new_stat) ? LIBCAPTION_ERROR : (LIBCAPTION_READY == old_stat) ? LIBCAPTION_READY : new_stat;  }
+
+#define SCREEN_ROWS 15
+#define SCREEN_COLS 32
+
+typedef struct {
+    unsigned int uln : 1; //< underline
+    unsigned int sty : 3; //< style
+    utf8_char_t data[5];  //< 4 byte utf8 values plus null term
+}  caption_frame_cell_t;
+
+typedef struct {
+    caption_frame_cell_t cell[SCREEN_ROWS][SCREEN_COLS];
+} caption_frame_buffer_t;
+
+
+typedef struct  {
+    unsigned int uln : 1; //< underline
+    unsigned int sty : 3; //< style
+    unsigned int mod : 3; //< current mode
+    unsigned int rup : 2; //< roll-up line count minus 1
+    uint16_t row, col, cc_data;
+} caption_frame_state_t;
+
+// timestamp and duration are in seconds
+typedef struct {
+    double timestamp;
+    double duration;
+    xds_t xds;
+    caption_frame_state_t state;
+    caption_frame_buffer_t front;
+    caption_frame_buffer_t back;
+} caption_frame_t;
+
+// typedef enum {
+//     eia608_paint_on = 0,
+//     eia608_pop_on   = 1,
+//     eia608_rollup_2 = 2,
+//     eia608_rollup_3 = 3,
+//     eia608_rollup_4 = 4,
+// } eia608_display_mode_t;
+// eia608_display_mode_t caption_frame_mode (caption_frame_t* frame);
+
+
+/*!
+    \brief Initializes an allocated caption_frame_t instance
+    \param frame Pointer to prealocated caption_frame_t object
+*/
+void caption_frame_init (caption_frame_t* frame);
+/*! \brief Writes a single charcter to a caption_frame_t object
+    \param frame A pointer to an allocted and initialized caption_frame_t object
+    \param row Row position to write charcter, must be between 0 and SCREEN_ROWS-1
+    \param col Column position to write charcter, must be between 0 and SCREEN_ROWS-1
+    \param style Style to apply to charcter
+    \param underline Set underline attribute, 0 = off any other value = on
+    \param c pointer to a single valid utf8 charcter. Bytes are automatically determined, and a NULL terminator is not required
+*/
+int caption_frame_write_char (caption_frame_t* frame, int row, int col, eia608_style_t style, int underline, const utf8_char_t* c);
+/*! \brief
+    \param
+*/
+const utf8_char_t* caption_frame_read_char (caption_frame_t* frame, int row, int col, eia608_style_t* style, int* underline);
+/*! \brief
+    \param
+*/
+
+/*! \brief
+    \param
+*/
+libcaption_stauts_t caption_frame_decode (caption_frame_t* frame, uint16_t cc_data, double timestamp);
+
+/*! \brief
+    \param
+*/
+int caption_frame_from_text (caption_frame_t* frame, const utf8_char_t* data);
+/*! \brief
+    \param
+*/
+#define CAPTION_FRAME_TEXT_BYTES (((2+SCREEN_ROWS)*SCREEN_COLS*4)+1)
+void caption_frame_to_text (caption_frame_t* frame, utf8_char_t* data);
+/*! \brief
+    \param
+*/
+#define CAPTION_FRAME_DUMP_BUF_SIZE 4096
+size_t caption_frame_dump_buffer (caption_frame_t* frame, utf8_char_t* buf);
+void caption_frame_dump (caption_frame_t* frame);
+/*! \brief
+    \param
+*/
+#define CAPTION_FRAME_JSON_BUF_SIZE 32768
+size_t caption_frame_json (caption_frame_t* frame, utf8_char_t* buf);
+
+#endif
diff --git a/deps/libcaption/caption/cea708.h b/deps/libcaption/caption/cea708.h
new file mode 100644
index 0000000..c2f5bf0
--- /dev/null
+++ b/deps/libcaption/caption/cea708.h
@@ -0,0 +1,110 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#ifndef LIBCAPTION_CEA708_H
+#define LIBCAPTION_CEA708_H
+
+#include "caption.h"
+#define CEA608_MAX_SIZE (255)
+
+////////////////////////////////////////////////////////////////////////////////
+typedef enum {
+    cc_type_ntsc_cc_field_1 = 0,
+    cc_type_ntsc_cc_field_2 = 1,
+    cc_type_dtvcc_packet_data = 2,
+    cc_type_dtvcc_packet_start = 3,
+} cea708_cc_type_t;
+
+typedef struct {
+    unsigned int marker_bits : 5;
+    unsigned int cc_valid : 1;
+    unsigned int cc_type : 2; // castable to cea708_cc_type_t
+    unsigned int cc_data : 16;
+} cc_data_t;
+
+typedef struct {
+    unsigned int process_em_data_flag : 1;
+    unsigned int process_cc_data_flag : 1;
+    unsigned int additional_data_flag : 1;
+    unsigned int cc_count : 5;
+    unsigned int em_data : 8;
+    cc_data_t cc_data[32];
+} user_data_t;
+
+/*! \brief
+    \param
+*/
+cc_data_t cea708_encode_cc_data (int cc_valid, cea708_cc_type_t type, uint16_t cc_data);
+/*! \brief
+    \param
+*/
+int cea708_cc_count (user_data_t* data);
+/*! \brief
+    \param
+*/
+uint16_t cea708_cc_data (user_data_t* data, int index, int* valid, cea708_cc_type_t* type);
+////////////////////////////////////////////////////////////////////////////////
+
+typedef enum {
+    country_united_states = 181,
+} itu_t_t35_country_code_t;
+
+typedef enum {
+    t35_provider_direct_tv = 47,
+    t35_provider_atsc = 49,
+} itu_t_t35_provider_code_t;
+
+typedef struct {
+    itu_t_t35_country_code_t country;
+    itu_t_t35_provider_code_t provider;
+    uint32_t user_identifier;
+    uint8_t atsc1_data_user_data_type_code;
+    uint8_t directv_user_data_length;
+    user_data_t user_data;
+} cea708_t;
+
+/*! \brief
+    \param
+*/
+int cea708_init (cea708_t* cea708); // will confgure using HLS compatiable defaults
+/*! \brief
+    \param
+*/
+int cea708_parse (uint8_t* data, size_t size, cea708_t* cea708);
+/*! \brief
+    \param
+*/
+libcaption_stauts_t cea708_to_caption_frame (caption_frame_t* frame, cea708_t* cea708, double pts);
+/*! \brief
+    \param
+*/
+int cea708_add_cc_data (cea708_t* cea708, int valid, cea708_cc_type_t type, uint16_t cc_data);
+/*! \brief
+    \param
+*/
+int cea708_render (cea708_t* cea708, uint8_t* data, size_t size);
+/*! \brief
+    \param
+*/
+void cea708_dump (cea708_t* cea708);
+#endif
diff --git a/deps/libcaption/caption/eia608.h b/deps/libcaption/caption/eia608.h
new file mode 100644
index 0000000..d0caf32
--- /dev/null
+++ b/deps/libcaption/caption/eia608.h
@@ -0,0 +1,206 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#ifndef LIBCAPTION_EIA608_H
+#define LIBCAPTION_EIA608_H
+
+#include "utf8.h"
+#include "eia608_charmap.h"
+////////////////////////////////////////////////////////////////////////////////
+// Parity
+#define EIA608_BX(B,X) (((B)>>X)&0x01)
+#define EIA608_BP(B) ((B)&0x7F) | ((EIA608_BX((B),0)^EIA608_BX(B,1)^EIA608_BX((B),2)^EIA608_BX((B),3)^EIA608_BX((B),4)^EIA608_BX((B),5)^EIA608_BX((B),6)^(0x01))<<7)
+#define EIA608_B2(B) EIA608_BP((B)+0), EIA608_BP((B)+1), EIA608_BP((B)+2), EIA608_BP((B)+3), EIA608_BP((B)+4), EIA608_BP((B)+5), EIA608_BP((B)+6), EIA608_BP((B)+7)
+#define EIA608_B1(B) EIA608_B2((B)+0), EIA608_B2((B)+8), EIA608_B2((B)+16), EIA608_B2((B)+24), EIA608_B2((B)+32), EIA608_B2((B)+40), EIA608_B2((B)+48), EIA608_B2((B)+56)
+
+static const uint8_t eia608_parity_table[] = { EIA608_B1 (0), EIA608_B1 (64) };
+extern const char* eia608_mode_map[];
+extern const char* eia608_style_map[];
+
+#ifdef _MSC_VER
+#ifndef inline
+#define inline __inline
+#endif
+#endif
+
+/*! \brief
+    \param
+*/
+static inline uint8_t  eia608_parity_byte (uint8_t cc_data) { return eia608_parity_table[0x7F & cc_data]; }
+/*! \brief
+    \param
+*/
+static inline uint16_t eia608_parity_word (uint16_t cc_data) { return (uint16_t) ( (eia608_parity_byte ( (uint8_t) (cc_data>>8)) <<8) | eia608_parity_byte ( (uint8_t) cc_data)); }
+/*! \brief
+    \param
+*/
+static inline uint16_t eia608_parity (uint16_t cc_data) { return eia608_parity_word (cc_data); }
+/*! \brief
+    \param
+*/
+static inline int eia608_parity_varify (uint16_t cc_data) { return eia608_parity_word (cc_data) == cc_data ? 1 : 0; }
+/*! \brief
+    \param
+*/
+static inline int eia608_parity_strip (uint16_t cc_data) { return cc_data & 0x7F7F; }
+/*! \brief
+    \param
+*/
+static inline int eia608_test_second_channel_bit (uint16_t cc_data) { return (cc_data & 0x0800); }
+
+////////////////////////////////////////////////////////////////////////////////
+// cc_data types
+/*! \brief
+    \param
+*/
+static inline int eia608_is_basicna (uint16_t cc_data) { return 0x0000 != (0x6000 & cc_data); /*&& 0x1F00 < (0x7F00 & cc_data);*/ }
+/*! \brief
+    \param
+*/
+static inline int eia608_is_preamble (uint16_t cc_data) { return 0x1040 == (0x7040 & cc_data); }
+/*! \brief
+    \param
+*/
+static inline int eia608_is_midrowchange (uint16_t cc_data) { return 0x1120 == (0x7770 & cc_data); }
+/*! \brief
+    \param
+*/
+static inline int eia608_is_specialna (uint16_t cc_data) { return 0x1130 == (0x7770 & cc_data); }
+/*! \brief
+    \param
+*/
+static inline int eia608_is_xds (uint16_t cc_data) { return 0x0000 == (0x7070 & cc_data) && 0x0000 != (0x0F0F & cc_data); }
+/*! \brief
+    \param
+*/
+static inline int eia608_is_westeu (uint16_t cc_data) { return 0x1220 == (0x7660 & cc_data); }
+/*! \brief
+    \param
+*/
+static inline int eia608_is_control (uint16_t cc_data) { return 0x1420 == (0x7670 & cc_data) || 0x1720 == (0x7770 & cc_data); }
+/*! \brief
+    \param
+*/
+static inline int eia608_is_norpak (uint16_t cc_data) { return 0x1724 == (0x777C & cc_data) || 0x1728 == (0x777C & cc_data); }
+/*! \brief
+    \param
+*/
+static inline int eia608_is_padding (uint16_t cc_data) { return 0x8080 == cc_data; }
+
+////////////////////////////////////////////////////////////////////////////////
+// preamble
+typedef enum {
+    eia608_style_white = 0,
+    eia608_style_green = 1,
+    eia608_style_blue = 2,
+    eia608_style_cyan = 3,
+    eia608_style_red = 4,
+    eia608_style_yellow = 5,
+    eia608_style_magenta = 6,
+    eia608_style_italics = 7,
+} eia608_style_t;
+
+/*! \brief
+    \param
+*/
+int eia608_parse_preamble (uint16_t cc_data, int* row, int* col, eia608_style_t* style, int* chan, int* underline);
+/*! \brief
+    \param
+*/
+int eia608_parse_midrowchange (uint16_t cc_data, int* chan, eia608_style_t* style, int* underline);
+/*! \brief
+    \param
+*/
+uint16_t eia608_row_column_pramble (int row, int col, int chan, int underline);
+/*! \brief
+    \param
+*/
+uint16_t eia608_row_style_pramble (int row, eia608_style_t style, int chan, int underline);
+
+////////////////////////////////////////////////////////////////////////////////
+// control command
+typedef enum { // yes, no?
+    eia608_tab_offset_0 = 0x1720,
+    eia608_tab_offset_1 = 0x1721,
+    eia608_tab_offset_2 = 0x1722,
+    eia608_tab_offset_3 = 0x1723,
+    eia608_control_resume_caption_loading = 0x1420,
+    eia608_control_backspace = 0x1421,
+    eia608_control_alarm_off = 0x1422,
+    eia608_control_alarm_on = 0x1423,
+    eia608_control_delete_to_end_of_row = 0x1424,
+    eia608_control_roll_up_2 = 0x1425,
+    eia608_control_roll_up_3 = 0x1426,
+    eia608_control_roll_up_4 = 0x1427,
+    eia608_control_resume_direct_captioning = 0x1429,
+    eia608_control_text_restart = 0x142A,
+    eia608_control_text_resume_text_display = 0x142B,
+    eia608_control_erase_display_memory = 0x142C,
+    eia608_control_carriage_return = 0x142D,
+    eia608_control_erase_non_displayed_memory = 0x142E,
+    eia608_control_end_of_caption = 0x142F,
+} eia608_control_t;
+
+#define eia608_control_popon eia608_control_resume_caption_loading
+#define eia608_control_painton eia608_control_resume_direct_captioning
+
+/*! \brief
+    \param
+*/
+uint16_t eia608_control_command (eia608_control_t cmd, int cc);
+/*! \brief
+    \param
+*/
+static inline uint16_t eia608_tab (int size, int cc) { return eia608_control_command ( (eia608_control_t) (eia608_tab_offset_0 | (size&0x0F)),cc); }
+/*! \brief
+    \param
+*/
+eia608_control_t eia608_parse_control (uint16_t cc_data, int* cc);
+
+////////////////////////////////////////////////////////////////////////////////
+// text
+/*! \brief
+    \param c
+*/
+uint16_t eia608_from_utf8_1 (const utf8_char_t* c, int chan);
+/*! \brief
+    \param
+*/
+uint16_t eia608_from_utf8_2 (const utf8_char_t* c1, const utf8_char_t* c2);
+/*! \brief
+    \param
+*/
+uint16_t eia608_from_basicna (uint16_t bna1, uint16_t bna2);
+/*! \brief
+    \param
+*/
+int eia608_to_utf8 (uint16_t c, int* chan, utf8_char_t* char1, utf8_char_t* char2);
+////////////////////////////////////////////////////////////////////////////////
+/*! \brief
+    \param
+*/
+void eia608_dump (uint16_t cc_data);
+////////////////////////////////////////////////////////////////////////////////
+
+
+#endif
diff --git a/deps/libcaption/caption/eia608_charmap.h b/deps/libcaption/caption/eia608_charmap.h
new file mode 100644
index 0000000..261b37a
--- /dev/null
+++ b/deps/libcaption/caption/eia608_charmap.h
@@ -0,0 +1,230 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#ifndef LIBCAPTION_EIA608_CHARMAP_H
+#define LIBCAPTION_EIA608_CHARMAP_H
+
+#define EIA608_CHAR_COUNT 176
+extern const char* eia608_char_map[EIA608_CHAR_COUNT];
+
+// Helper char
+#define EIA608_CHAR_NULL                                       ""
+// Basic North American character set
+#define EIA608_CHAR_SPACE                                      "\x20"
+#define EIA608_CHAR_EXCLAMATION_MARK                           "\x21"
+#define EIA608_CHAR_QUOTATION_MARK                             "\x22"
+#define EIA608_CHAR_NUMBER_SIGN                                "\x23"
+#define EIA608_CHAR_DOLLAR_SIGN                                "\x24"
+#define EIA608_CHAR_PERCENT_SIGN                               "\x25"
+#define EIA608_CHAR_AMPERSAND                                  "\x26"
+#define EIA608_CHAR_LEFT_SINGLE_QUOTATION_MARK                 "\xE2\x80\x98"
+#define EIA608_CHAR_LEFT_PARENTHESIS                           "\x28"
+#define EIA608_CHAR_RIGHT_PARENTHESIS                          "\x29"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_ACUTE            "\xC3\xA1"
+#define EIA608_CHAR_PLUS_SIGN                                  "\x2B"
+#define EIA608_CHAR_COMMA                                      "\x2C"
+#define EIA608_CHAR_HYPHEN_MINUS                               "\x2D"
+#define EIA608_CHAR_FULL_STOP                                  "\x2E"
+#define EIA608_CHAR_SOLIDUS                                    "\x2F"
+
+// Basic North American character set
+#define EIA608_CHAR_DIGIT_ZERO                                 "\x30"
+#define EIA608_CHAR_DIGIT_ONE                                  "\x31"
+#define EIA608_CHAR_DIGIT_TWO                                  "\x32"
+#define EIA608_CHAR_DIGIT_THREE                                "\x33"
+#define EIA608_CHAR_DIGIT_FOUR                                 "\x34"
+#define EIA608_CHAR_DIGIT_FIVE                                 "\x35"
+#define EIA608_CHAR_DIGIT_SIX                                  "\x36"
+#define EIA608_CHAR_DIGIT_SEVEN                                "\x37"
+#define EIA608_CHAR_DIGIT_EIGHT                                "\x38"
+#define EIA608_CHAR_DIGIT_NINE                                 "\x39"
+#define EIA608_CHAR_COLON                                      "\x3A"
+#define EIA608_CHAR_SEMICOLON                                  "\x3B"
+#define EIA608_CHAR_LESS_THAN_SIGN                             "\x3C"
+#define EIA608_CHAR_EQUALS_SIGN                                "\x3D"
+#define EIA608_CHAR_GREATER_THAN_SIGN                          "\x3E"
+#define EIA608_CHAR_QUESTION_MARK                              "\x3F"
+
+// Basic North American character set
+#define EIA608_CHAR_COMMERCIAL_AT                              "\x40"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A                     "\x41"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_B                     "\x42"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_C                     "\x43"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_D                     "\x44"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_E                     "\x45"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_F                     "\x46"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_G                     "\x47"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_H                     "\x48"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_I                     "\x49"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_J                     "\x4A"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_K                     "\x4B"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_L                     "\x4C"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_M                     "\x4D"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_N                     "\x4E"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O                     "\x4F"
+
+// Basic North American character set
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_P                     "\x50"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_Q                     "\x51"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_R                     "\x52"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_S                     "\x53"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_T                     "\x54"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_U                     "\x55"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_V                     "\x56"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_W                     "\x57"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_X                     "\x58"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_Y                     "\x59"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_Z                     "\x5A"
+#define EIA608_CHAR_LEFT_SQUARE_BRACKET                        "\x5B"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_ACUTE            "\xC3\xA9"
+#define EIA608_CHAR_RIGHT_SQUARE_BRACKET                       "\x5D"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_ACUTE            "\xC3\xAD"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_ACUTE            "\xC3\xB3"
+
+// Basic North American character set
+#define EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_ACUTE            "\xC3\xBA"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_A                       "\x61"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_B                       "\x62"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_C                       "\x63"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_D                       "\x64"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_E                       "\x65"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_F                       "\x66"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_G                       "\x67"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_H                       "\x68"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_I                       "\x69"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_J                       "\x6A"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_K                       "\x6B"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_L                       "\x6C"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_M                       "\x6D"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_N                       "\x6E"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_O                       "\x6F"
+
+// Basic North American character set
+#define EIA608_CHAR_LATIN_SMALL_LETTER_P                       "\x70"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_Q                       "\x71"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_R                       "\x72"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_S                       "\x73"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_T                       "\x74"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_U                       "\x75"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_V                       "\x76"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_W                       "\x77"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_X                       "\x78"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_Y                       "\x79"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_Z                       "\x7A"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_C_WITH_CEDILLA          "\xC3\xA7"
+#define EIA608_CHAR_DIVISION_SIGN                              "\xC3\xB7"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_N_WITH_TILDE          "\xC3\x91"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_N_WITH_TILDE            "\xC3\xB1"
+#define EIA608_CHAR_FULL_BLOCK                                 "\xE2\x96\x88"
+
+// Special North American character set[edit]
+#define EIA608_CHAR_REGISTERED_SIGN                            "\xC2\xAE"
+#define EIA608_CHAR_DEGREE_SIGN                                "\xC2\xB0"
+#define EIA608_CHAR_VULGAR_FRACTION_ONE_HALF                   "\xC2\xBD"
+#define EIA608_CHAR_INVERTED_QUESTION_MARK                     "\xC2\xBF"
+#define EIA608_CHAR_TRADE_MARK_SIGN                            "\xE2\x84\xA2"
+#define EIA608_CHAR_CENT_SIGN                                  "\xC2\xA2"
+#define EIA608_CHAR_POUND_SIGN                                 "\xC2\xA3"
+#define EIA608_CHAR_EIGHTH_NOTE                                "\xE2\x99\xAA"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_GRAVE            "\xC3\xA0"
+#define EIA608_CHAR_NO_BREAK_SPACE                             "\xC2\xA0"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_GRAVE            "\xC3\xA8"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX       "\xC3\xA2"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX       "\xC3\xAA"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX       "\xC3\xAE"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX       "\xC3\xB4"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX       "\xC3\xBB"
+
+// Extended Western European character set : Extended Spanish/Miscellaneous
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_ACUTE          "\xC3\x81"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_ACUTE          "\xC3\x89"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_ACUTE          "\xC3\x93"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_ACUTE          "\xC3\x9A"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS      "\xC3\x9C"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_DIAERESIS        "\xC3\xBC"
+#define EIA608_CHAR_RIGHT_SINGLE_QUOTATION_MARK                "\xE2\x80\x99"
+#define EIA608_CHAR_INVERTED_EXCLAMATION_MARK                  "\xC2\xA1"
+#define EIA608_CHAR_ASTERISK                                   "\x2A"
+#define EIA608_CHAR_APOSTROPHE                                 "\x27"
+#define EIA608_CHAR_EM_DASH                                    "\xE2\x80\x94"
+#define EIA608_CHAR_COPYRIGHT_SIGN                             "\xC2\xA9"
+#define EIA608_CHAR_SERVICE_MARK                               "\xE2\x84\xA0"
+#define EIA608_CHAR_BULLET                                     "\xE2\x80\xA2"
+#define EIA608_CHAR_LEFT_DOUBLE_QUOTATION_MARK                 "\xE2\x80\x9C"
+#define EIA608_CHAR_RIGHT_DOUBLE_QUOTATION_MARK                "\xE2\x80\x9D"
+
+// Extended Western European character set : Extended French
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_GRAVE          "\xC3\x80"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX     "\xC3\x82"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_C_WITH_CEDILLA        "\xC3\x87"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_GRAVE          "\xC3\x88"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX     "\xC3\x8A"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS      "\xC3\x8B"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_DIAERESIS        "\xC3\xAB"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX     "\xC3\x8E"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS      "\xC3\x8F"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_DIAERESIS        "\xC3\xAF"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX     "\xC3\x94"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_GRAVE          "\xC3\x99"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_GRAVE            "\xC3\xB9"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX     "\xC3\x9B"
+#define EIA608_CHAR_LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK  "\xC2\xAB"
+#define EIA608_CHAR_RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK "\xC2\xBB"
+
+// Extended Western European character set : Portuguese
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_TILDE          "\xC3\x83"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_TILDE            "\xC3\xA3"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_ACUTE          "\xC3\x8D"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_GRAVE          "\xC3\x8C"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_GRAVE            "\xC3\xAC"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_GRAVE          "\xC3\x92"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_GRAVE            "\xC3\xB2"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_TILDE          "\xC3\x95"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_TILDE            "\xC3\xB5"
+#define EIA608_CHAR_LEFT_CURLY_BRACKET                         "\x7B"
+#define EIA608_CHAR_RIGHT_CURLY_BRACKET                        "\x7D"
+#define EIA608_CHAR_REVERSE_SOLIDUS                            "\x5C"
+#define EIA608_CHAR_CIRCUMFLEX_ACCENT                          "\x5E"
+#define EIA608_CHAR_LOW_LINE                                   "\x5F"
+#define EIA608_CHAR_VERTICAL_LINE                              "\x7C"
+#define EIA608_CHAR_TILDE                                      "\x7E"
+
+// Extended Western European character set : German/Danish
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS      "\xC3\x84"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_DIAERESIS        "\xC3\xA4"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS      "\xC3\x96"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_DIAERESIS        "\xC3\xB6"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_SHARP_S                 "\xC3\x9F"
+#define EIA608_CHAR_YEN_SIGN                                   "\xC2\xA5"
+#define EIA608_CHAR_CURRENCY_SIGN                              "\xC2\xA4"
+#define EIA608_CHAR_BROKEN_BAR                                 "\xC2\xA6"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE     "\xC3\x85"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_RING_ABOVE       "\xC3\xA5"
+#define EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_STROKE         "\xC3\x98"
+#define EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_STROKE           "\xC3\xB8"
+#define EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT          "\xE2\x94\x8C" // top left
+#define EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT           "\xE2\x94\x90" // top right
+#define EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT            "\xE2\x94\x94" // lower left
+#define EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT             "\xE2\x94\x98" // bottom right
+
+#endif
diff --git a/deps/libcaption/caption/scc.h b/deps/libcaption/caption/scc.h
new file mode 100644
index 0000000..dd4d6dc
--- /dev/null
+++ b/deps/libcaption/caption/scc.h
@@ -0,0 +1,31 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#ifndef LIBCAPTION_SCC_H
+#define LIBCAPTION_SCC_H
+
+#include "eia608.h"
+
+int scc_to_608 (const char* line, double* pts, uint16_t* cc, int cc_max);
+
+#endif
diff --git a/deps/libcaption/caption/srt.h b/deps/libcaption/caption/srt.h
new file mode 100644
index 0000000..c7c1565
--- /dev/null
+++ b/deps/libcaption/caption/srt.h
@@ -0,0 +1,87 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#ifndef LIBCAPTION_SRT_H
+#define LIBCAPTION_SRT_H
+
+#include "eia608.h"
+#include "caption.h"
+
+// timestamp and duration are in seconds
+typedef struct _srt_t {
+    struct _srt_t* next;
+    double timestamp;
+    double duration;
+    size_t aloc;
+} srt_t;
+
+
+
+
+/*! \brief
+    \param
+*/
+srt_t* srt_new (const utf8_char_t* data, size_t size, double timestamp, srt_t* prev, srt_t** head);
+/*! \brief
+    \param
+*/
+srt_t* srt_free_head (srt_t* head);
+// returns the head of the link list. must bee freed when done
+/*! \brief
+    \param
+*/
+srt_t* srt_parse (const utf8_char_t* data, size_t size);
+/*! \brief
+    \param
+*/
+void srt_free (srt_t* srt);
+
+/*! \brief
+    \param
+*/
+static inline srt_t* srt_next (srt_t* srt) { return srt->next; }
+/*! \brief
+    \param
+*/
+static inline utf8_char_t* srt_data (srt_t* srt) { return (utf8_char_t*) (srt) + sizeof (srt_t); }
+// This only converts teh surrent SRT, It does not walk the list
+/*! \brief
+    \param
+*/
+int srt_to_caption_frame (srt_t* srt, caption_frame_t* frame);
+
+// returns teh new srt. Head is not tracher internally.
+/*! \brief
+    \param
+*/
+srt_t* srt_from_caption_frame (caption_frame_t* frame, srt_t* prev, srt_t** head);
+/*! \brief
+    \param
+*/
+void srt_dump (srt_t* srt);
+/*! \brief
+    \param
+*/
+void vtt_dump (srt_t* srt);
+
+#endif
diff --git a/deps/libcaption/caption/utf8.h b/deps/libcaption/caption/utf8.h
new file mode 100644
index 0000000..576f47a
--- /dev/null
+++ b/deps/libcaption/caption/utf8.h
@@ -0,0 +1,97 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#ifndef LIBCAPTION_UTF8_H
+#define LIBCAPTION_UTF8_H
+
+#include <stddef.h>
+#include <inttypes.h>
+
+// These types exist to make the code more self dcoumenting
+// utf8_char_t point is a null teminate string of utf8 encodecd chars
+//
+// utf8_size_t is the length of a string in chars
+// size_t is bytes
+typedef char utf8_char_t;
+typedef size_t utf8_size_t;
+/*! \brief
+    \param
+
+    Skiped continuation bytes
+*/
+const utf8_char_t* utf8_char_next (const char* s);
+/*! \brief
+    \param
+
+    returnes the length of the char in bytes
+*/
+size_t utf8_char_length (const utf8_char_t* c);
+
+/*! \brief
+    \param
+
+    returns length of the string in bytes
+    size is number of charcter to count (0 to count until NULL term)
+*/
+size_t utf8_string_length (const utf8_char_t* data, utf8_size_t size);
+/*! \brief
+    \param
+*/
+size_t utf8_char_copy (utf8_char_t* dst, const utf8_char_t* src);
+
+/*! \brief
+    \param
+
+    returnes the number of utf8 charcters in a string givne the numbe of bytes
+    to coutn until the a null terminator, pass 0 for size
+*/
+utf8_size_t utf8_char_count (const char* data, size_t size);
+/*! \brief
+    \param
+
+    returnes the length of the line in bytes triming not printable charcters at the end
+*/
+size_t utf8_trimmed_length (const char* data, size_t size);
+/*! \brief
+    \param
+
+    returns the length in bytes of the line including the new line charcter(s)
+    auto detects between windows(CRLF), unix(LF), mac(CR) and riscos (LFCR) line endings
+*/
+size_t utf8_line_length (const char* data);
+/*! \brief
+    \param
+
+    returns number of chars to include before split
+*/
+utf8_size_t utf8_wrap_length (const utf8_char_t* data, utf8_size_t size);
+
+/*! \brief
+    \param
+
+    returns number of new lins in teh string
+*/
+int utf8_line_count (const utf8_char_t* data);
+
+
+#endif
diff --git a/deps/libcaption/caption/xds.h b/deps/libcaption/caption/xds.h
new file mode 100644
index 0000000..7b510f5
--- /dev/null
+++ b/deps/libcaption/caption/xds.h
@@ -0,0 +1,32 @@
+/**********************************************************************************************/
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file  */
+/* except in compliance with the License. A copy of the License is located at                 */
+/*                                                                                            */
+/*     http://aws.amazon.com/apache2.0/                                                       */
+/*                                                                                            */
+/* or in the "license" file accompanying this file. This file is distributed on an "AS IS"    */
+/* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the    */
+/* License for the specific language governing permissions and limitations under the License. */
+/**********************************************************************************************/
+
+#ifndef LIBCAPTION_XDS_H
+#define LIBCAPTION_XDS_H
+
+#include <stddef.h>
+#include <inttypes.h>
+
+typedef struct {
+    int state;
+    uint8_t class;
+    uint8_t type;
+    uint32_t size;
+    uint8_t content[32];
+    uint8_t checksum;
+} xds_t;
+
+void xds_init (xds_t* xds);
+int xds_decode (xds_t* xds, uint16_t cc);
+
+#endif
diff --git a/deps/libcaption/examples/add_captions.sh b/deps/libcaption/examples/add_captions.sh
new file mode 100644
index 0000000..68e295e
--- /dev/null
+++ b/deps/libcaption/examples/add_captions.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+if [  $# -lt 2 ]
+then
+    echo "Need at least 2 arguments."
+    echo "$0 InputVideo InputSRT [OutputFilename]"
+    exit 1
+fi
+
+VIDEO=$1
+SRT=$2
+
+if [ -z "$3" ]
+then
+    OUTFILE="out.flv"
+else
+    OUTFILE="$3"
+fi
+
+echo "Video=$VIDEO"
+echo "Captions=$SRT"
+echo "Outfile=$OUTFILE"
+
+# ffmpeg -i $VIDEO -acodec copy -vcodec copy -f flv - | ./flv+srt - $SRT - | ffmpeg -i - -acodec copy -vcodec copy $OUTFILE
+ffmpeg -i $VIDEO -threads 0 -vcodec libx264 -profile:v main -preset:v medium \
+-r 30 -g 60 -keyint_min 60 -sc_threshold 0 -b:v 4000k -maxrate 4000k \
+-bufsize 4000k -filter:v scale="trunc(oh*a/2)*2:720" \
+-sws_flags lanczos+accurate_rnd -strict -2 -acodec aac -b:a 96k -ar 48000 -ac 2 \
+-f flv - | ./flv+srt - $SRT - | ffmpeg -i - -acodec copy -vcodec copy -y $OUTFILE
diff --git a/deps/libcaption/examples/captioner.c b/deps/libcaption/examples/captioner.c
new file mode 100644
index 0000000..66b29fa
--- /dev/null
+++ b/deps/libcaption/examples/captioner.c
@@ -0,0 +1,117 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <linux/input.h>
+#include <string.h>
+#include <stdio.h>
+#include "caption.h"
+#include "flv.h"
+
+char charcode[] = {
+    0,   0, '1', '2', '3', '4', '5', '6',  '7', '8', '9',  '0', '-', '=',   0,   0,
+    'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',  'O', 'P', '[',  ']','\n',   0, 'A', 'S',
+    'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '`',   0, '\\', 'Z', 'X', 'C', 'V',
+    'B', 'N', 'M', ',', '.', '/',   0, '*',    0, ' ',   0,    0,   0,   0,   0,   0,
+};
+
+int data_ready (int fd)
+{
+    fd_set set;
+    struct timeval timeout = {0,0};
+    FD_ZERO (&set);
+    FD_SET (fd,&set);
+    int cnt = select (fd+1, &set, 0, 0, &timeout);
+    FD_ZERO (&set);
+    return (0 < cnt);
+}
+
+#define MAX_CAP_LENGTH (SCREEN_ROWS*SCREEN_COLS)
+int main (int argc, char** argv)
+{
+    int fd;
+    ssize_t n;
+    flvtag_t tag;
+    struct input_event ev;
+    int has_audio, has_video;
+    const char* dev = argv[1];
+    char text[MAX_CAP_LENGTH+1];
+    memset (text,0,MAX_CAP_LENGTH+1);
+
+    FILE* flv = flv_open_read ("-");
+    FILE* out = flv_open_write ("-");
+    fd = open (dev, O_RDONLY);
+
+    if (fd == -1) {
+        fprintf (stderr, "Cannot open %s: %s.\n", dev, strerror (errno));
+        return EXIT_FAILURE;
+    }
+
+    if (!flv_read_header (flv,&has_audio,&has_video)) {
+        fprintf (stderr,"%s is not an flv file\n", argv[1]);
+        return EXIT_FAILURE;
+    }
+
+    if (!flv_write_header (out,has_audio,has_video)) {
+        return EXIT_FAILURE;
+    }
+
+    flvtag_init (&tag);
+
+    while (flv_read_tag (flv,&tag)) {
+        if (flvtag_avcpackettype_nalu == flvtag_avcpackettype (&tag)) {
+            if (data_ready (fd)) {
+                n = read (fd, &ev, sizeof ev);
+
+                if (n == (ssize_t)-1) {
+                    if (errno == EINTR) {
+                        continue;
+                    } else {
+                        break;
+                    }
+                } else if (n != sizeof ev) {
+                    errno = EIO;
+                    break;
+                }
+
+                int len = strlen (text);
+                char c = (EV_KEY == ev.type && 1 == ev.value && ev.code < 64) ? charcode[ev.code] : 0;
+
+                if (0 < len && '\n' == c) {
+                    fprintf (stderr,"='%s'\n", text);
+                    flvtag_addcaption (&tag, text);
+                    memset (text,0,MAX_CAP_LENGTH+1);
+                } else if (0 != c && len < MAX_CAP_LENGTH) {
+                    text[len] = c;
+                }
+            }
+        }
+
+        flv_write_tag (out,&tag);
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/deps/libcaption/examples/flv+scc.c b/deps/libcaption/examples/flv+scc.c
new file mode 100644
index 0000000..c368224
--- /dev/null
+++ b/deps/libcaption/examples/flv+scc.c
@@ -0,0 +1,23 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
diff --git a/deps/libcaption/examples/flv+srt.c b/deps/libcaption/examples/flv+srt.c
new file mode 100644
index 0000000..7828c79
--- /dev/null
+++ b/deps/libcaption/examples/flv+srt.c
@@ -0,0 +1,96 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "srt.h"
+#include "flv.h"
+#include "avc.h"
+// #include "sei.h"
+
+#define MAX_SRT_SIZE (10*1024*1024)
+#define MAX_READ_SIZE 4096
+
+srt_t* srt_from_file (const char* path)
+{
+    srt_t* head = 0;
+    size_t read, totl = 0;
+    FILE* file = fopen (path,"r");
+
+    if (file) {
+        char* srt_data = malloc (MAX_SRT_SIZE);
+        size_t srt_size = 0;
+        size_t size = MAX_SRT_SIZE;
+        char* data = srt_data;
+
+        while (0 < (read = fread (data,1,size,file))) {
+            totl += read; data += read; size -= read; srt_size += read;
+        }
+
+        head = srt_parse (srt_data,srt_size);
+        free (srt_data);
+    }
+
+    return head;
+}
+
+int main (int argc, char** argv)
+{
+    flvtag_t tag;
+    FILE* flv = flv_open_read (argv[1]);
+    FILE* out = flv_open_write (argv[3]);
+
+    int has_audio, has_video;
+    flvtag_init (&tag);
+
+    if (!flv_read_header (flv,&has_audio,&has_video)) {
+        fprintf (stderr,"%s is not an flv file\n", argv[1]);
+        return EXIT_FAILURE;
+    }
+
+    srt_t* head = srt_from_file (argv[2]);
+    srt_t* srt = head;
+
+    if (! head) {
+        fprintf (stderr,"%s is not an srt file\n", argv[2]);
+        return EXIT_FAILURE;
+    }
+
+    flv_write_header (out,has_audio,has_video);
+
+    while (flv_read_tag (flv,&tag)) {
+        // TODO handle B freame!
+        if (srt && flvtag_pts_seconds (&tag) >= srt->timestamp && flvtag_avcpackettype_nalu == flvtag_avcpackettype (&tag)) {
+            fprintf (stderr,"%f: %s\n", srt->timestamp, srt_data (srt));
+            flvtag_addcaption (&tag, srt_data (srt));
+            srt = srt->next;
+        }
+
+        flv_write_tag (out,&tag);
+        // Write tag out here
+    }
+
+    srt_free (head);
+    return EXIT_SUCCESS;
+}
diff --git a/deps/libcaption/examples/flv.c b/deps/libcaption/examples/flv.c
new file mode 100644
index 0000000..67ce3c5
--- /dev/null
+++ b/deps/libcaption/examples/flv.c
@@ -0,0 +1,383 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include "flv.h"
+#include <stdlib.h>
+#include <string.h>
+
+void flvtag_init (flvtag_t* tag)
+{
+    memset (tag,0,sizeof (flvtag_t));
+}
+
+void flvtag_free (flvtag_t* tag)
+{
+    if (tag->data) {
+        free (tag->data);
+    }
+
+    flvtag_init (tag);
+}
+
+int flvtag_reserve (flvtag_t* tag, uint32_t size)
+{
+    size += FLV_TAG_HEADER_SIZE + FLV_TAG_FOOTER_SIZE;
+
+    if (size > tag->aloc) {
+        tag->data = realloc (tag->data,size);
+        tag->aloc = size;
+    }
+
+    return 1;
+}
+
+FILE* flv_open_read (const char* flv)
+{
+    if (0 == flv || 0 == strcmp ("-",flv)) {
+        return stdin;
+    }
+
+    return fopen (flv,"rb");
+}
+
+FILE* flv_open_write (const char* flv)
+{
+    if (0 == flv || 0 == strcmp ("-",flv)) {
+        return stdout;
+    }
+
+    return fopen (flv,"wb");
+}
+
+FILE* flv_close (FILE* flv)
+{
+    fclose (flv);
+    return 0;
+}
+
+int flv_read_header (FILE* flv, int* has_audio, int* has_video)
+{
+    uint8_t h[FLV_HEADER_SIZE];
+
+    if (FLV_HEADER_SIZE != fread (&h[0],1,FLV_HEADER_SIZE,flv)) {
+        return 0;
+    }
+
+    if ('F' != h[0] || 'L' != h[1] || 'V' != h[2]) {
+        return 0;
+    }
+
+    (*has_audio) = h[4]&0x04;
+    (*has_video) = h[4]&0x01;
+    return 1;
+}
+
+int flv_write_header (FILE* flv, int has_audio, int has_video)
+{
+    uint8_t h[FLV_HEADER_SIZE] = {'F', 'L', 'V', 1, (has_audio?0x04:0x00) | (has_video?0x01:0x00), 0, 0, 0, 9, 0, 0, 0, 0 };
+    return FLV_HEADER_SIZE == fwrite (&h[0],1,FLV_HEADER_SIZE,flv);
+}
+
+int flv_read_tag (FILE* flv, flvtag_t* tag)
+{
+    uint32_t size;
+    uint8_t h[FLV_TAG_HEADER_SIZE];
+
+    if (FLV_TAG_HEADER_SIZE != fread (&h[0],1,FLV_TAG_HEADER_SIZE,flv)) {
+        return 0;
+    }
+
+    size = ( (h[1]<<16) | (h[2]<<8) |h[3]);
+    flvtag_reserve (tag, size);
+    // copy header to buffer
+    memcpy (tag->data,&h[0],FLV_TAG_HEADER_SIZE);
+
+    if (size+FLV_TAG_FOOTER_SIZE != fread (&tag->data[FLV_TAG_HEADER_SIZE],1,size+FLV_TAG_FOOTER_SIZE,flv)) {
+        return 0;
+    }
+
+    return 1;
+}
+
+int flv_write_tag (FILE* flv, flvtag_t* tag)
+{
+    size_t size = flvtag_raw_size (tag);
+    return size == fwrite (flvtag_raw_data (tag),1,size,flv);
+}
+////////////////////////////////////////////////////////////////////////////////
+size_t flvtag_header_size (flvtag_t* tag)
+{
+    switch (flvtag_type (tag)) {
+    case flvtag_type_audio:
+        return FLV_TAG_HEADER_SIZE + (flvtag_soundformat_aac != flvtag_soundformat (tag) ? 1 : 2);
+
+    case flvtag_type_video:
+        // CommandFrame does not have a compositionTime
+        return FLV_TAG_HEADER_SIZE + (flvtag_codecid_avc != flvtag_codecid (tag) ? 1 : (flvtag_frametype_commandframe != flvtag_frametype (tag) ? 5 : 2));
+
+    default:
+        return FLV_TAG_HEADER_SIZE;
+    }
+}
+
+size_t flvtag_payload_size (flvtag_t* tag)
+{
+    return FLV_TAG_HEADER_SIZE + flvtag_size (tag) - flvtag_header_size (tag);
+}
+
+uint8_t* flvtag_payload_data (flvtag_t* tag)
+{
+    size_t payload_offset = flvtag_header_size (tag);
+    return &tag->data[payload_offset];
+}
+////////////////////////////////////////////////////////////////////////////////
+int flvtag_updatesize (flvtag_t* tag, uint32_t size)
+{
+    tag->data[1] = size>>16; // DataSize
+    tag->data[2] = size>>8; // DataSize
+    tag->data[3] = size>>0; // DataSize
+    size += 11;
+    tag->data[size+0] = size>>24; // PrevTagSize
+    tag->data[size+1] = size>>16; // PrevTagSize
+    tag->data[size+2] = size>>8; // PrevTagSize
+    tag->data[size+3] = size>>0; // PrevTagSize
+    return 1;
+}
+
+#define FLVTAG_PREALOC 2048
+int flvtag_initavc (flvtag_t* tag, uint32_t dts, int32_t cts, flvtag_frametype_t type)
+{
+    flvtag_init (tag);
+    flvtag_reserve (tag,5+FLVTAG_PREALOC);
+    tag->data[0] = flvtag_type_video;
+    tag->data[4] = dts>>16;
+    tag->data[5] = dts>>8;
+    tag->data[6] = dts>>0;
+    tag->data[7] = dts>>24;
+    tag->data[8] = 0; // StreamID
+    tag->data[9] = 0; // StreamID
+    tag->data[10] = 0; // StreamID
+    // VideoTagHeader
+    tag->data[11] = ( (type<<4) %0xF0) |0x07; // CodecId
+    tag->data[12] = 0x01; // AVC NALU
+    tag->data[13] = cts>>16;
+    tag->data[14] = cts>>8;
+    tag->data[15] = cts>>0;
+    flvtag_updatesize (tag,5);
+    return 1;
+}
+
+int flvtag_initamf (flvtag_t* tag, uint32_t dts)
+{
+    flvtag_init (tag);
+    flvtag_reserve (tag,FLVTAG_PREALOC);
+    tag->data[0] = flvtag_type_scriptdata;
+    tag->data[4] = dts>>16;
+    tag->data[5] = dts>>8;
+    tag->data[6] = dts>>0;
+    tag->data[7] = dts>>24;
+    tag->data[8] = 0; // StreamID
+    tag->data[9] = 0; // StreamID
+    tag->data[10] = 0; // StreamID
+    flvtag_updatesize (tag,0);
+    return 1;
+}
+
+// shamelessly taken from libtomcrypt, an public domain project
+static void base64_encode (const unsigned char* in,  unsigned long inlen, unsigned char* out, unsigned long* outlen)
+{
+    static const char* codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+    unsigned long i, len2, leven;
+    unsigned char* p;
+
+    /* valid output size ? */
+    len2 = 4 * ( (inlen + 2) / 3);
+
+    if (*outlen < len2 + 1) {
+        *outlen = len2 + 1;
+        fprintf (stderr,"\n\nHERE\n\n");
+        return;
+    }
+
+    p = out;
+    leven = 3* (inlen / 3);
+
+    for (i = 0; i < leven; i += 3) {
+        *p++ = codes[ (in[0] >> 2) & 0x3F];
+        *p++ = codes[ ( ( (in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F];
+        *p++ = codes[ ( ( (in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F];
+        *p++ = codes[in[2] & 0x3F];
+        in += 3;
+    }
+
+    if (i < inlen) {
+        unsigned a = in[0];
+        unsigned b = (i+1 < inlen) ? in[1] : 0;
+
+        *p++ = codes[ (a >> 2) & 0x3F];
+        *p++ = codes[ ( ( (a & 3) << 4) + (b >> 4)) & 0x3F];
+        *p++ = (i+1 < inlen) ? codes[ ( ( (b & 0xf) << 2)) & 0x3F] : '=';
+        *p++ = '=';
+    }
+
+    /* return ok */
+    *outlen = p - out;
+}
+
+const char onCaptionInfo708[] = { 0x02,0x00,0x0D, 'o','n','C','a','p','t','i','o','n','I','n','f','o',
+                                  0x08, 0x00, 0x00, 0x00, 0x02,
+                                  0x00, 0x04, 't','y','p','e',
+                                  0x02, 0x00, 0x03, '7','0','8',
+                                  0x00, 0x04, 'd','a','t','a',
+                                  0x02, 0x00,0x00
+                                };
+
+int flvtag_amfcaption_708 (flvtag_t* tag, uint32_t timestamp, sei_message_t* msg)
+{
+    flvtag_initamf (tag,timestamp);
+    unsigned long size = 1 + (4 * ( (sei_message_size (msg) + 2) / 3));
+    flvtag_reserve (tag, sizeof (onCaptionInfo708) + size + 3);
+    memcpy (flvtag_payload_data (tag),onCaptionInfo708,sizeof (onCaptionInfo708));
+    uint8_t* data = flvtag_payload_data (tag) + sizeof (onCaptionInfo708);
+    base64_encode (sei_message_data (msg), sei_message_size (msg), data, &size);
+
+    // Update the size of the base64 string
+    data[-2] = size >> 8;
+    data[-1] = size >> 0;
+    // write the last array element
+    data[size+0] = 0x00;
+    data[size+1] = 0x00;
+    data[size+2] = 0x09;
+    flvtag_updatesize (tag, sizeof (onCaptionInfo708) + size + 3);
+
+    return 1;
+}
+
+const char onCaptionInfoUTF8[] = { 0x02,0x00,0x0D, 'o','n','C','a','p','t','i','o','n','I','n','f','o',
+                                   0x08, 0x00, 0x00, 0x00, 0x02,
+                                   0x00, 0x04, 't','y','p','e',
+                                   0x02, 0x00, 0x04, 'U','T','F','8',
+                                   0x00, 0x04, 'd','a','t','a',
+                                   0x02, 0x00,0x00
+                                 };
+
+#define MAX_AMF_STRING 65636
+int flvtag_amfcaption_utf8 (flvtag_t* tag, uint32_t timestamp, const utf8_char_t* text)
+{
+    flvtag_initamf (tag,timestamp);
+    unsigned long size = strlen (text);
+
+    if (MAX_AMF_STRING < size) {
+        size = MAX_AMF_STRING;
+    }
+
+    flvtag_reserve (tag, sizeof (onCaptionInfoUTF8) + size + 3);
+    memcpy (flvtag_payload_data (tag),onCaptionInfoUTF8,sizeof (onCaptionInfoUTF8));
+    uint8_t* data = flvtag_payload_data (tag) + sizeof (onCaptionInfo708);
+    memcpy (data,text,size);
+    // Update the size of the string
+    data[-2] = size >> 8;
+    data[-1] = size >> 0;
+    // write the last array element
+    data[size+0] = 0x00;
+    data[size+1] = 0x00;
+    data[size+2] = 0x09;
+    flvtag_updatesize (tag, sizeof (onCaptionInfoUTF8) + size + 3);
+
+    return 1;
+}
+
+#define LENGTH_SIZE 4
+
+int flvtag_avcwritenal (flvtag_t* tag, uint8_t* data, size_t size)
+{
+    uint32_t flvsize = flvtag_size (tag);
+    flvtag_reserve (tag,flvsize+LENGTH_SIZE+size);
+    uint8_t* payload = tag->data + FLV_TAG_HEADER_SIZE + flvsize;
+    payload[0] = size>>24; // nalu size
+    payload[1] = size>>16;
+    payload[2] = size>>8;
+    payload[3] = size>>0;
+    memcpy (&payload[LENGTH_SIZE],data,size);
+    flvtag_updatesize (tag,flvsize+LENGTH_SIZE+size);
+
+    return 1;
+}
+
+int flvtag_addcaption (flvtag_t* tag, const utf8_char_t* text)
+{
+    if (flvtag_avcpackettype_nalu != flvtag_avcpackettype (tag)) {
+        return 0;
+    }
+
+    sei_t sei;
+    caption_frame_t frame;
+
+    sei_init (&sei);
+    caption_frame_init (&frame);
+    caption_frame_from_text (&frame, text);
+    sei_from_caption_frame (&sei, &frame);
+
+    uint8_t* sei_data = malloc (sei_render_size (&sei));
+    size_t sei_size = sei_render (&sei, sei_data);
+
+    // rewrite tag
+    flvtag_t new_tag;
+    flvtag_initavc (&new_tag, flvtag_dts (tag), flvtag_cts (tag), flvtag_frametype (tag));
+    uint8_t* data = flvtag_payload_data (tag);
+    ssize_t  size = flvtag_payload_size (tag);
+
+    while (0<size) {
+        uint8_t*  nalu_data = &data[LENGTH_SIZE];
+        uint8_t   nalu_type = nalu_data[0]&0x1F;
+        uint32_t  nalu_size = (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | data[3];
+        data += LENGTH_SIZE + nalu_size;
+        size -= LENGTH_SIZE + nalu_size;
+
+        if (0 < sei_size && 7 != nalu_type && 8 != nalu_type && 9 != nalu_type ) {
+            // fprintf (stderr,"Wrote SEI %d '%d'\n\n", sei_size, sei_data[3]);
+            flvtag_avcwritenal (&new_tag,sei_data,sei_size);
+            sei_size = 0;
+        }
+
+        flvtag_avcwritenal (&new_tag,nalu_data,nalu_size);
+    }
+
+    // On the off chance we have an empty frame,
+    // We still wish to append the sei
+    if (0<sei_size) {
+        // fprintf (stderr,"Wrote SEI %d\n\n", sei_size);
+        flvtag_avcwritenal (&new_tag,sei_data,sei_size);
+        sei_size = 0;
+    }
+
+    if (sei_data) {
+        free (sei_data);
+    }
+
+    free (tag->data);
+    sei_free (&sei);
+    tag->data = new_tag.data;
+    tag->aloc = new_tag.aloc;
+    return 1;
+}
diff --git a/deps/libcaption/examples/flv.h b/deps/libcaption/examples/flv.h
new file mode 100644
index 0000000..9bdd93f
--- /dev/null
+++ b/deps/libcaption/examples/flv.h
@@ -0,0 +1,142 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#ifndef LIBCAPTION_FLV_H
+#define LIBCAPTION_FLV_H
+
+#include <stdio.h>
+#include <stddef.h>
+#include <inttypes.h>
+#define FLV_HEADER_SIZE     13
+#define FLV_FOOTER_SIZE      4
+#define FLV_TAG_HEADER_SIZE 11
+#define FLV_TAG_FOOTER_SIZE  4
+////////////////////////////////////////////////////////////////////////////////
+#include "avc.h"
+////////////////////////////////////////////////////////////////////////////////
+typedef struct {
+    uint8_t* data;
+    size_t   aloc;
+} flvtag_t;
+
+void flvtag_init (flvtag_t* tag);
+void flvtag_free (flvtag_t* tag);
+void flvtag_swap (flvtag_t* tag1, flvtag_t* tag2);
+////////////////////////////////////////////////////////////////////////////////
+typedef enum {
+    flvtag_type_audio      = 0x08,
+    flvtag_type_video      = 0x09,
+    flvtag_type_scriptdata = 0x12,
+} flvtag_type_t;
+
+static inline flvtag_type_t flvtag_type (flvtag_t* tag) { return (flvtag_type_t) tag->data[0]&0x1F; }
+////////////////////////////////////////////////////////////////////////////////
+typedef enum {
+    flvtag_soundformat_unknown                            = -1,
+    flvtag_soundformat_linearpcmplatformendian            =  0,
+    flvtag_soundformat_adpcm                              =  1,
+    flvtag_soundformat_mp3                                =  2,
+    flvtag_soundformat_linearpcmlittleendian              =  3,
+    flvtag_soundformat_nellymoser_16khzmono               =  4,
+    flvtag_soundformat_nellymoser_8khzmono                =  5,
+    flvtag_soundformat_nellymoser                         =  6,
+    flvtag_soundformat_g711alawlogarithmicpcm             =  7,
+    flvtag_soundformat_g711mulawlogarithmicpcm            =  8,
+    flvtag_soundformat_reserved                           =  9,
+    flvtag_soundformat_aac                                = 10,
+    flvtag_soundformat_speex                              = 11,
+    flvtag_soundformat_mp3_8khz                           = 14,
+    flvtag_soundformat_devicespecificsound                = 15
+} flvtag_soundformat_t;
+
+static inline flvtag_soundformat_t flvtag_soundformat (flvtag_t* tag) { return (flvtag_type_audio!=flvtag_type (tag)) ?flvtag_soundformat_unknown: (flvtag_soundformat_t) (tag->data[0]>>4) &0x0F; }
+////////////////////////////////////////////////////////////////////////////////
+typedef enum {
+    flvtag_codecid_unknown                = -1,
+    flvtag_codecid_sorensonh263           =  2,
+    flvtag_codecid_screenvideo            =  3,
+    flvtag_codecid_on2vp6                 =  4,
+    flvtag_codecid_on2vp6withalphachannel =  5,
+    flvtag_codecid_screenvideoversion2    =  6,
+    flvtag_codecid_avc                    =  7
+} flvtag_codecid_t;
+
+static inline flvtag_codecid_t flvtag_codecid (flvtag_t* tag) { return (flvtag_type_video!=flvtag_type (tag)) ? (flvtag_codecid_unknown) : (tag->data[11]&0x0F); }
+////////////////////////////////////////////////////////////////////////////////
+typedef enum {
+    flvtag_frametype_unknown              = -1,
+    flvtag_frametype_keyframe             =  1,
+    flvtag_frametype_interframe           =  2,
+    flvtag_frametype_disposableinterframe =  3,
+    flvtag_frametype_generatedkeyframe    =  4,
+    flvtag_frametype_commandframe         =  5
+} flvtag_frametype_t;
+
+static inline flvtag_frametype_t flvtag_frametype (flvtag_t* tag) { return (flvtag_type_video!=flvtag_type (tag)) ?flvtag_frametype_keyframe: ( (tag->data[11]>>4) &0x0F); }
+////////////////////////////////////////////////////////////////////////////////
+typedef enum {
+    flvtag_avcpackettype_unknown        = -1,
+    flvtag_avcpackettype_sequenceheader =  0,
+    flvtag_avcpackettype_nalu           =  1,
+    flvtag_avcpackettype_endofsequence  =  2
+} flvtag_avcpackettype_t;
+
+static inline flvtag_avcpackettype_t flvtag_avcpackettype (flvtag_t* tag) { return (flvtag_codecid_avc!=flvtag_codecid (tag)) ?flvtag_avcpackettype_unknown:tag->data[12]; }
+////////////////////////////////////////////////////////////////////////////////
+static inline size_t   flvtag_size (flvtag_t* tag) { return (tag->data[1]<<16) | (tag->data[2]<<8) | tag->data[3]; }
+static inline uint32_t flvtag_timestamp (flvtag_t* tag) { return (tag->data[7]<<24) | (tag->data[4]<<16) | (tag->data[5]<<8) | tag->data[6]; }
+static inline uint32_t flvtag_dts (flvtag_t* tag) { return flvtag_timestamp (tag); }
+static inline uint32_t flvtag_cts (flvtag_t* tag) { return (flvtag_avcpackettype_nalu!=flvtag_avcpackettype (tag)) ?0: (tag->data[13]<<16) | (tag->data[14]<<8) |tag->data[15]; }
+static inline uint32_t flvtag_pts (flvtag_t* tag) { return flvtag_dts (tag)+flvtag_cts (tag); }
+static inline double flvtag_dts_seconds (flvtag_t* tag) { return flvtag_dts (tag) / 1000.0; }
+static inline double flvtag_cts_seconds (flvtag_t* tag) { return flvtag_cts (tag) / 1000.0; }
+static inline double flvtag_pts_seconds (flvtag_t* tag) { return flvtag_pts (tag) / 1000.0; }
+////////////////////////////////////////////////////////////////////////////////
+size_t flvtag_header_size (flvtag_t* tag);
+size_t flvtag_payload_size (flvtag_t* tag);
+uint8_t* flvtag_payload_data (flvtag_t* tag);
+////////////////////////////////////////////////////////////////////////////////
+FILE* flv_open_read (const char* flv);
+FILE* flv_open_write (const char* flv);
+FILE* flv_close (FILE* flv);
+////////////////////////////////////////////////////////////////////////////////
+static inline const uint8_t* flvtag_raw_data (flvtag_t* tag) { return tag->data; }
+static inline const size_t flvtag_raw_size (flvtag_t* tag) { return flvtag_size (tag)+FLV_TAG_HEADER_SIZE+FLV_TAG_FOOTER_SIZE; }
+////////////////////////////////////////////////////////////////////////////////
+int flv_read_tag (FILE* flv, flvtag_t* tag);
+int flv_write_tag (FILE* flv, flvtag_t* tag);
+int flv_read_header (FILE* flv, int* has_audio, int* has_video);
+int flv_write_header (FILE* flv, int has_audio, int has_video);
+////////////////////////////////////////////////////////////////////////////////
+// If the tage has more that on sei message, they will be combined into one
+sei_t* flv_read_sei (FILE* flv, flvtag_t* tag);
+////////////////////////////////////////////////////////////////////////////////
+int flvtag_initavc (flvtag_t* tag, uint32_t dts, int32_t cts, flvtag_frametype_t type);
+int flvtag_avcwritenal (flvtag_t* tag, uint8_t* data, size_t size);
+int flvtag_addcaption (flvtag_t* tag, const utf8_char_t* text);
+////////////////////////////////////////////////////////////////////////////////
+int flvtag_amfcaption_708 (flvtag_t* tag, uint32_t timestamp, sei_message_t* msg);
+////////////////////////////////////////////////////////////////////////////////
+// This method is expermental, and not currently available on Twitch
+int flvtag_amfcaption_utf8 (flvtag_t* tag, uint32_t timestamp, const utf8_char_t* text);
+#endif
diff --git a/deps/libcaption/examples/flv2srt.c b/deps/libcaption/examples/flv2srt.c
new file mode 100644
index 0000000..5afa171
--- /dev/null
+++ b/deps/libcaption/examples/flv2srt.c
@@ -0,0 +1,92 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include "flv.h"
+#include "srt.h"
+#include "avc.h"
+
+#define LENGTH_SIZE 4
+int main (int argc, char** argv)
+{
+    const char* path = argv[1];
+
+    sei_t sei;
+    flvtag_t tag;
+    srt_t* srt = 0, *head = 0;
+    int i, has_audio, has_video;
+    caption_frame_t frame;
+
+    flvtag_init (&tag);
+    caption_frame_init (&frame);
+
+    FILE* flv = flv_open_read (path);
+
+    if (!flv_read_header (flv,&has_audio,&has_video)) {
+        fprintf (stderr,"'%s' Not an flv file\n", path);
+    } else {
+        fprintf (stderr,"Reading from '%s'\n", path);
+    }
+
+    while (flv_read_tag (flv,&tag)) {
+        if (flvtag_avcpackettype_nalu == flvtag_avcpackettype (&tag)) {
+            ssize_t  size = flvtag_payload_size (&tag);
+            uint8_t* data = flvtag_payload_data (&tag);
+
+            while (0<size) {
+                ssize_t  nalu_size = (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | data[3];
+                uint8_t* nalu_data = &data[4];
+                uint8_t  nalu_type = nalu_data[0]&0x1F;
+                data += nalu_size + LENGTH_SIZE;
+                size -= nalu_size + LENGTH_SIZE;
+
+                if (6 == nalu_type) {
+                    sei_init (&sei);
+                    sei_parse_nalu (&sei, nalu_data, nalu_size, flvtag_dts (&tag), flvtag_cts (&tag));
+
+                    cea708_t cea708;
+                    sei_message_t* msg;
+                    cea708_init (&cea708);
+
+                    // for (msg = sei_message_head (&sei) ; msg ; msg = sei_message_next (msg)) {
+                    //     if (sei_type_user_data_registered_itu_t_t35 == sei_message_type (msg)) {
+                    //         cea708_parse (sei_message_data (msg), sei_message_size (msg), &cea708);
+                    //         cea708_dump (&cea708);
+                    //     }
+                    // }
+
+                    // sei_dump(&sei);
+                    sei_to_caption_frame (&sei,&frame);
+                    sei_free (&sei);
+
+                    // caption_frame_dump (&frame);
+                    srt = srt_from_caption_frame (&frame,srt,&head);
+                }
+            }
+        }
+    }
+
+    srt_dump (head);
+    srt_free (head);
+
+    return 1;
+}
diff --git a/deps/libcaption/examples/party.c b/deps/libcaption/examples/party.c
new file mode 100644
index 0000000..e65fed4
--- /dev/null
+++ b/deps/libcaption/examples/party.c
@@ -0,0 +1,122 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "flv.h"
+#include "avc.h"
+
+#define CAPTION_METHOD_SEI_708  0 // embedded 708
+#define CAPTION_METHOD_AMF_708  1 // onCaptionInfo type = 708
+#define CAPTION_METHOD_AMF_UTF8 2 // onCaptionInfo type = utf8
+#define CAPTION_METHOD CAPTION_METHOD_SEI_708
+
+void get_dudes (char* str)
+{
+    sprintf (str, " %s%s %s(-_-)%s %s(-_-)%s.%s(-_-)%s %s%s", EIA608_CHAR_EIGHTH_NOTE, EIA608_CHAR_EIGHTH_NOTE,
+             ! (rand() % 2) ? EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT : EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT,
+             ! (rand() % 2) ? EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT : EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT,
+             ! (rand() % 2) ? EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT : EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT,
+             ! (rand() % 2) ? EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT : EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT,
+             ! (rand() % 2) ? EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT : EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT,
+             ! (rand() % 2) ? EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT : EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT,
+             EIA608_CHAR_EIGHTH_NOTE, EIA608_CHAR_EIGHTH_NOTE);
+}
+
+void write_amfcaptions_708 (FILE* out, uint32_t timestamp, const char* text)
+{
+    sei_t sei;
+    flvtag_t tag;
+    sei_message_t* msg;
+    caption_frame_t frame;
+    sei_init (&sei);
+    flvtag_init (&tag);
+    caption_frame_init (&frame);
+    caption_frame_from_text (&frame, text);
+    sei_from_caption_frame (&sei, &frame);
+    // caption_frame_dump (&frame);
+
+    for (msg = sei_message_head (&sei); msg; msg=sei_message_next (msg),++timestamp) {
+        flvtag_amfcaption_708 (&tag,timestamp,msg);
+        flv_write_tag (out,&tag);
+    }
+
+    sei_free (&sei);
+    flvtag_free (&tag);
+}
+
+
+void write_amfcaptions_utf8 (FILE* out, uint32_t timestamp, const utf8_char_t* text)
+{
+    flvtag_t tag;
+    flvtag_init (&tag);
+    flvtag_amfcaption_utf8 (&tag,timestamp,text);
+    flv_write_tag (out,&tag);
+    flvtag_free (&tag);
+}
+
+int main (int argc, char** argv)
+{
+    flvtag_t tag;
+    uint32_t nextParty = 1000;
+    int has_audio, has_video;
+    FILE* flv = flv_open_read (argv[1]);
+    FILE* out = flv_open_write (argv[2]);
+    char partyDudes[64];
+
+    flvtag_init (&tag);
+
+    if (!flv_read_header (flv,&has_audio,&has_video)) {
+        fprintf (stderr,"%s is not an flv file\n", argv[1]);
+        return EXIT_FAILURE;
+    }
+
+    flv_write_header (out,has_audio,has_video);
+
+    while (flv_read_tag (flv,&tag)) {
+
+        if (flvtag_avcpackettype_nalu == flvtag_avcpackettype (&tag) && nextParty <= flvtag_timestamp (&tag)) {
+            get_dudes (partyDudes);
+
+            if (CAPTION_METHOD == CAPTION_METHOD_SEI_708) {
+                flvtag_addcaption (&tag, partyDudes);
+            } else if (CAPTION_METHOD == CAPTION_METHOD_AMF_708) {
+                write_amfcaptions_708 (out,nextParty,partyDudes);
+            } else if (CAPTION_METHOD == CAPTION_METHOD_AMF_708) {
+                write_amfcaptions_utf8 (out, nextParty, partyDudes);
+            } else {
+                fprintf (stderr,"Unknnow method\n");
+                return EXIT_FAILURE;
+
+            }
+
+            fprintf (stderr,"%d: %s\n",nextParty, partyDudes);
+            nextParty += 500; // party all the time
+        }
+
+        flv_write_tag (out,&tag);
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/deps/libcaption/examples/rollup.c b/deps/libcaption/examples/rollup.c
new file mode 100644
index 0000000..e290af6
--- /dev/null
+++ b/deps/libcaption/examples/rollup.c
@@ -0,0 +1,95 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "flv.h"
+#include "avc.h"
+#include "srt.h"
+#include "wonderland.h"
+
+#define SECONDS_PER_LINE 3.0
+srt_t* appennd_caption (const utf8_char_t* data, srt_t* prev, srt_t** head)
+{
+
+    int r, c, chan = 0;
+    ssize_t size = (ssize_t) strlen (data);
+    size_t char_count, char_length, line_length = 0, trimmed_length = 0;
+
+    for (r = 0 ; 0 < size && SCREEN_ROWS > r ; ++r) {
+        line_length = utf8_line_length (data);
+        trimmed_length = utf8_trimmed_length (data,line_length);
+        char_count = utf8_char_count (data,trimmed_length);
+
+        // If char_count is greater than one line can display, split it.
+        if (SCREEN_COLS < char_count) {
+            char_count = utf8_wrap_length (data,SCREEN_COLS);
+            line_length = utf8_string_length (data,char_count+1);
+        }
+
+        // fprintf (stderr,"%.*s\n", line_length, data);
+        prev = srt_new (data, line_length, prev ? prev->timestamp + SECONDS_PER_LINE : 0, prev, head);
+
+        data += line_length;
+        size -= (ssize_t) line_length;
+    }
+
+    return prev;
+}
+
+int main (int argc, char** argv)
+{
+    int i = 0;
+    flvtag_t tag;
+    srt_t* head = 0, *tail = 0;
+    int has_audio, has_video;
+    FILE* flv = flv_open_read (argv[1]);
+    FILE* out = flv_open_write (argv[2]);
+    flvtag_init (&tag);
+
+    for (i = 0 ; wonderland[i][0]; ++i) {
+        tail = appennd_caption (wonderland[i], tail, &head);
+    }
+
+
+    if (!flv_read_header (flv,&has_audio,&has_video)) {
+        fprintf (stderr,"%s is not an flv file\n", argv[1]);
+        return EXIT_FAILURE;
+    }
+
+    flv_write_header (out,has_audio,has_video);
+
+    while (flv_read_tag (flv,&tag)) {
+        if (head && flvtag_avcpackettype_nalu == flvtag_avcpackettype (&tag) && head->timestamp <= flvtag_pts_seconds (&tag)) {
+            fprintf (stderr,"%f %s\n", flvtag_pts_seconds (&tag), srt_data (head));
+            flvtag_addcaption (&tag, srt_data (head));
+            head = srt_free_head (head);
+        }
+
+
+        flv_write_tag (out,&tag);
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/deps/libcaption/examples/rtmpspit.c b/deps/libcaption/examples/rtmpspit.c
new file mode 100644
index 0000000..c7ef113
--- /dev/null
+++ b/deps/libcaption/examples/rtmpspit.c
@@ -0,0 +1,165 @@
+#include "flv.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/select.h>
+#include <librtmp/log.h>
+#include <librtmp/rtmp.h>
+
+
+int MyRTMP_Write (RTMP* r, const char* buf, int size)
+{
+    RTMPPacket* pkt = &r->m_write;
+    char* enc;
+    int s2 = size, ret, num;
+
+    pkt->m_nChannel = 0x04;   /* source channel */
+    pkt->m_nInfoField2 = r->m_stream_id;
+
+    while (s2) {
+        if (!pkt->m_nBytesRead) {
+            if (size < 11) {
+                /* FLV pkt too small */
+                return 0;
+            }
+
+            if (buf[0] == 'F' && buf[1] == 'L' && buf[2] == 'V') {
+                buf += 13;
+                s2 -= 13;
+            }
+
+            pkt->m_packetType = *buf++;
+            pkt->m_nBodySize = AMF_DecodeInt24 (buf);
+            buf += 3;
+            pkt->m_nTimeStamp = AMF_DecodeInt24 (buf);
+            buf += 3;
+            pkt->m_nTimeStamp |= *buf++ << 24;
+            buf += 3;
+            s2 -= 11;
+
+            if ( ( (pkt->m_packetType == RTMP_PACKET_TYPE_AUDIO
+                    || pkt->m_packetType == RTMP_PACKET_TYPE_VIDEO) &&
+                    !pkt->m_nTimeStamp) || pkt->m_packetType == RTMP_PACKET_TYPE_INFO) {
+                pkt->m_headerType = RTMP_PACKET_SIZE_LARGE;
+            } else {
+                pkt->m_headerType = RTMP_PACKET_SIZE_MEDIUM;
+            }
+
+            if (!RTMPPacket_Alloc (pkt, pkt->m_nBodySize)) {
+                RTMP_Log (RTMP_LOGDEBUG, "%s, failed to allocate packet", __FUNCTION__);
+                return FALSE;
+            }
+
+            enc = pkt->m_body;
+        } else {
+            enc = pkt->m_body + pkt->m_nBytesRead;
+        }
+
+        num = pkt->m_nBodySize - pkt->m_nBytesRead;
+
+        if (num > s2) {
+            num = s2;
+        }
+
+        memcpy (enc, buf, num);
+        pkt->m_nBytesRead += num;
+        s2 -= num;
+        buf += num;
+
+        if (pkt->m_nBytesRead == pkt->m_nBodySize) {
+            ret = RTMP_SendPacket (r, pkt, FALSE);
+            RTMPPacket_Free (pkt);
+            pkt->m_nBytesRead = 0;
+
+            if (!ret) {
+                return -1;
+            }
+
+            buf += 4;
+            s2 -= 4;
+
+            if (s2 < 0) {
+                break;
+            }
+        }
+    }
+
+    return size+s2;
+}
+
+int main (int argc, const char** argv)
+{
+    FILE* flv;
+    RTMP* rtmp;
+    RTMPPacket rtmpPacket;
+
+    flvtag_t tag;
+    int32_t timestamp = 0;
+    int has_audio, has_video;
+    char* url = 0;
+
+    if (2 >= argc) {
+        fprintf (stderr,"Usage %s [input] [url]\n",argv[0]);
+    }
+
+    url = (char*) argv[2];
+    flv = flv_open_read (argv[1]);
+
+    if (! flv) {
+        fprintf (stderr,"Could not open %s\n",argv[1]);
+        return EXIT_FAILURE;
+    }
+
+    if (! flv_read_header (flv, &has_audio, &has_video)) {
+        fprintf (stderr,"Not an flv file %s\n",argv[1]);
+        return EXIT_FAILURE;
+    }
+
+    flvtag_init (&tag);
+    rtmp = RTMP_Alloc();
+    RTMP_Init (rtmp);
+    fprintf (stderr,"Connecting to %s\n", url);
+    RTMP_SetupURL (rtmp, url);
+    RTMP_EnableWrite (rtmp);
+
+    RTMP_Connect (rtmp, NULL);
+    RTMP_ConnectStream (rtmp, 0);
+    memset (&rtmpPacket, 0, sizeof (RTMPPacket));
+
+    if (! RTMP_IsConnected (rtmp)) {
+        fprintf (stderr,"RTMP_IsConnected() Error\n");
+        return EXIT_FAILURE;
+    }
+
+    while (flv_read_tag (flv,&tag)) {
+        if (! RTMP_IsConnected (rtmp) || RTMP_IsTimedout (rtmp)) {
+            fprintf (stderr,"RTMP_IsConnected() Error\n");
+            return EXIT_FAILURE;
+        }
+
+        if (flvtag_timestamp (&tag) > timestamp) {
+            usleep (1000 * (flvtag_timestamp (&tag) - timestamp));
+            timestamp = flvtag_timestamp (&tag);
+        }
+
+        MyRTMP_Write (rtmp, (const char*) flvtag_raw_data (&tag),flvtag_raw_size (&tag));
+
+        // Handle RTMP ping and such
+        fd_set sockset; struct timeval timeout = {0,0};
+        FD_ZERO (&sockset); FD_SET (RTMP_Socket (rtmp), &sockset);
+        register int result = select (RTMP_Socket (rtmp) + 1, &sockset, NULL, NULL, &timeout);
+
+        if (result == 1 && FD_ISSET (RTMP_Socket (rtmp), &sockset)) {
+            RTMP_ReadPacket (rtmp, &rtmpPacket);
+
+            if (! RTMPPacket_IsReady (&rtmpPacket)) {
+                fprintf (stderr,"Received RTMP packet\n");
+                RTMP_ClientPacket (rtmp,&rtmpPacket);
+                RTMPPacket_Free (&rtmpPacket);
+            }
+        }
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/deps/libcaption/examples/scc2srt.c b/deps/libcaption/examples/scc2srt.c
new file mode 100644
index 0000000..565fd23
--- /dev/null
+++ b/deps/libcaption/examples/scc2srt.c
@@ -0,0 +1,96 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "srt.h"
+#include "scc.h"
+
+#define MAX_SCC_SIZE (10*1024*1024)
+#define MAX_READ_SIZE 4096
+#define MAX_CC 128
+
+size_t read_file (FILE* file, utf8_char_t* data, size_t size)
+{
+    size_t read, totl = 0;
+
+    while (0 < (read = fread (data,1,MAX_READ_SIZE<size?MAX_READ_SIZE:size,file))) {
+        totl += read; data += read; size -= read;
+    }
+
+    return totl;
+}
+
+srt_t* scc2srt (const char* data)
+{
+    double pts;
+    size_t line_size = 0;
+    int cc_idx, count, i;
+    srt_t* srt = 0, *head = 0;
+    caption_frame_t frame;
+    uint16_t cc_data[MAX_CC];
+
+    while (0 < (line_size = utf8_line_length (data))) {
+        caption_frame_init (&frame);
+        int cc_count = scc_to_608 (data, &pts, (uint16_t*) &cc_data, MAX_CC);
+        data += line_size;
+        data += utf8_line_length (data); // skip empty line
+
+        // fprintf (stderr,"%f, %d| %.*s\n", pts, cc_count, (int) line_size,data);
+
+        for (cc_idx = 0 ; cc_idx < cc_count ; ++cc_idx) {
+            // eia608_dump (cc_data[cc_idx]);
+            caption_frame_decode (&frame,cc_data[cc_idx],pts);
+        }
+
+        // utf8_char_t buff[CAPTION_FRAME_DUMP_BUF_SIZE];
+        // size_t size = caption_frame_dump (&frame, buff);
+        // fprintf (stderr,"%s\n", buff);
+        srt = srt_from_caption_frame (&frame,srt,&head);
+    }
+
+    return head;
+}
+
+int main (int argc, char** argv)
+{
+    char frame_buf[CAPTION_FRAME_DUMP_BUF_SIZE];
+
+    if (argc < 2) {
+        return 0;
+    }
+
+    FILE* file = fopen (argv[1],"r");
+
+    if (! file) {
+        return 0;
+    }
+
+    utf8_char_t* data = malloc (MAX_SCC_SIZE);
+    read_file (file,data,MAX_SCC_SIZE);
+    srt_t* srt = scc2srt (data);
+    srt_dump (srt);
+    srt_free (srt);
+    free (data);
+}
diff --git a/deps/libcaption/examples/srt2vtt.c b/deps/libcaption/examples/srt2vtt.c
new file mode 100644
index 0000000..e6ea31c
--- /dev/null
+++ b/deps/libcaption/examples/srt2vtt.c
@@ -0,0 +1,64 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "srt.h"
+
+#define MAX_SRT_SIZE (10*1024*1024)
+#define MAX_READ_SIZE 4096
+
+size_t read_file (FILE* file, utf8_char_t* data, size_t size)
+{
+    size_t read, totl = 0;
+
+    while (0 < (read = fread (data,1,MAX_READ_SIZE<size?MAX_READ_SIZE:size,file))) {
+        totl += read; data += read; size -= read;
+    }
+
+    return totl;
+}
+
+int main (int argc, char** argv)
+{
+    srt_t* srt;
+    caption_frame_t frame;
+    char frame_buf[CAPTION_FRAME_DUMP_BUF_SIZE];
+
+    if (argc < 2) {
+        return 0;
+    }
+
+    FILE* file = fopen (argv[1],"r");
+
+    if (! file) {
+        return 0;
+    }
+
+    utf8_char_t* data = malloc (MAX_SRT_SIZE);
+    size_t size = read_file (file,data,MAX_SRT_SIZE);
+    srt_t* head = srt_parse (data,size);
+    vtt_dump (head);
+    srt_free (head);
+}
diff --git a/deps/libcaption/examples/srtdump.c b/deps/libcaption/examples/srtdump.c
new file mode 100644
index 0000000..b63c467
--- /dev/null
+++ b/deps/libcaption/examples/srtdump.c
@@ -0,0 +1,71 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "srt.h"
+#include "avc.h"
+// #include "sei.h"
+
+#define MAX_SRT_SIZE (10*1024*1024)
+#define MAX_READ_SIZE 4096
+
+size_t read_file (FILE* file, utf8_char_t* data, size_t size)
+{
+    size_t read, totl = 0;
+
+    while (0 < (read = fread (data,1,MAX_READ_SIZE<size?MAX_READ_SIZE:size,file))) {
+        totl += read; data += read; size -= read;
+    }
+
+    return totl;
+}
+
+int main (int argc, char** argv)
+{
+    srt_t* srt;
+    caption_frame_t frame;
+
+    if (argc < 2) {
+        return 0;
+    }
+
+    FILE* file = fopen (argv[1],"r");
+
+    if (! file) {
+        return 0;
+    }
+
+    utf8_char_t* data = (utf8_char_t*) malloc (MAX_SRT_SIZE);
+    size_t size = read_file (file,data,MAX_SRT_SIZE);
+    srt_t* head = srt_parse (data,size);
+
+    for (srt = head ; srt ; srt = srt->next) {
+        caption_frame_init (&frame);
+        srt_to_caption_frame (srt,&frame);
+        caption_frame_dump (&frame);
+    }
+
+    srt_free (head);
+}
diff --git a/deps/libcaption/examples/ts.c b/deps/libcaption/examples/ts.c
new file mode 100644
index 0000000..fc82c53
--- /dev/null
+++ b/deps/libcaption/examples/ts.c
@@ -0,0 +1,117 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include "ts.h"
+#include <string.h>
+
+void ts_init (ts_t* ts)
+{
+    memset (ts,0,sizeof (ts_t));
+}
+
+static int64_t ts_parse_pts (const uint8_t* data)
+{
+    // 0000 1110  1111 1111  1111 1110  1111 1111  1111 1110
+    uint64_t pts = 0;
+    pts |= (uint64_t) (data[0] & 0x0E) << 29;
+    pts |= (uint64_t) (data[1] & 0xFF) << 22;
+    pts |= (uint64_t) (data[2] & 0xFE) << 14;
+    pts |= (uint64_t) (data[3] & 0xFF) <<  7;
+    pts |= (uint64_t) (data[4] & 0xFE) >>  1;
+    return pts;
+}
+
+int ts_parse_packet (ts_t* ts, const uint8_t* data)
+{
+    size_t i = 0;
+    int pusi = !! (data[i + 1] & 0x40);  // Payload Unit Start Indicator
+    int16_t pid = ( (data[i + 1] & 0x1F) << 8) | data[i + 2];    // PID
+    int adaption_present = !! (data[i + 3] & 0x20);  // Adaptation field exist
+    int payload_present = !! (data[i + 3] & 0x10);  // Contains payload
+    i += 4;
+
+    ts->data = 0;
+    ts->size = 0;
+
+    if (adaption_present) {
+        uint8_t adaption_length = data[i + 0]; // adaption field length
+        i += 1 + adaption_length;
+    }
+
+    if (pid == 0) {
+        if (payload_present) {
+            // Skip the payload.
+            i += data[i] + 1;
+        }
+
+        ts->pmtpid = ( (data[i + 10] & 0x1F) << 8) | data[i + 11];
+    } else if (pid == ts->pmtpid) {
+        // PMT
+        if (payload_present) {
+            // Skip the payload.
+            i += data[i] + 1;
+        }
+
+        uint16_t section_length = ( (data[i + 1] & 0x0F) << 8) | data[i + 2];
+        int current = data[i + 5] & 0x01;
+        int16_t program_info_length = ( (data[i + 10] & 0x0F) << 8) | data[i + 11];
+        int16_t descriptor_loop_length = section_length - (9 + program_info_length + 4);   // 4 for the crc
+
+        i += 12 + program_info_length;
+
+        if (current) {
+            while (descriptor_loop_length >= 5) {
+                uint8_t stream_type    = data[i];
+                int16_t elementary_pid = ( (data[i + 1] & 0x1F) << 8) | data[i + 2];
+                int16_t esinfo_length  = ( (data[i + 3] & 0x0F) << 8) | data[i + 4];
+
+                if (0x1B == stream_type) {
+                    ts->avcpid = elementary_pid;
+                }
+
+                i += 5 + esinfo_length;
+                descriptor_loop_length -= 5 + esinfo_length;
+            }
+        }
+    } else if (payload_present && pid == ts->avcpid) {
+        if (pusi) {
+            // int data_alignment = !! (data[i + 6] & 0x04);
+            int has_pts = !! (data[i + 7] & 0x80);
+            int has_dts = !! (data[i + 7] & 0x40);
+            uint8_t header_length = data[i + 8];
+
+            if (has_pts) {
+                ts->pts = ts_parse_pts (&data[i + 9]);
+                ts->dts = has_dts ? ts_parse_pts (&data[i + 14]) : ts->pts;
+            }
+
+            i += 9 + header_length;
+        }
+
+        ts->data = &data[i];
+        ts->size = TS_PACKET_SIZE-i;
+        return LIBCAPTION_READY;
+    }
+
+    return LIBCAPTION_OK;
+}
diff --git a/deps/libcaption/examples/ts.h b/deps/libcaption/examples/ts.h
new file mode 100644
index 0000000..fb9e490
--- /dev/null
+++ b/deps/libcaption/examples/ts.h
@@ -0,0 +1,49 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#ifndef LIBCAPTION_TS_H
+#define LIBCAPTION_TS_H
+#include "caption.h"
+typedef struct {
+    int16_t pmtpid;
+    int16_t avcpid;
+    int64_t pts;
+    int64_t dts;
+    size_t  size;
+    const uint8_t* data;
+} ts_t;
+
+/*! \brief
+    \param
+
+    Expects 188 byte TS packet
+*/
+#define TS_PACKET_SIZE 188
+void ts_init (ts_t* ts);
+int ts_parse_packet (ts_t* ts, const uint8_t* data);
+// return timestamp in seconds
+static inline double ts_dts_seconds (ts_t* ts) { return ts->dts / 90000.0; }
+static inline double ts_pts_seconds (ts_t* ts) { return ts->pts / 90000.0; }
+static inline double ts_cts_seconds (ts_t* ts) { return (ts->dts - ts->pts) / 90000.0; }
+
+#endif
diff --git a/deps/libcaption/examples/ts2srt.c b/deps/libcaption/examples/ts2srt.c
new file mode 100644
index 0000000..18d0b1a
--- /dev/null
+++ b/deps/libcaption/examples/ts2srt.c
@@ -0,0 +1,101 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include "ts.h"
+#include "srt.h"
+#include "avc.h"
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+    const char* path = argv[1];
+
+    ts_t ts;
+    sei_t sei;
+    avcnalu_t nalu;
+    srt_t* srt = 0, *head = 0;
+    caption_frame_t frame;
+    uint8_t pkt[TS_PACKET_SIZE];
+    ts_init (&ts);
+    avcnalu_init (&nalu);
+    caption_frame_init (&frame);
+
+    FILE* file = fopen (path,"rb+");
+
+    while (TS_PACKET_SIZE == fread (&pkt[0],1,TS_PACKET_SIZE, file)) {
+        switch (ts_parse_packet (&ts,&pkt[0])) {
+        case LIBCAPTION_OK:
+            // fprintf (stderr,"read ts packet\n");
+            break;
+
+        case LIBCAPTION_READY: {
+            // fprintf (stderr,"read ts packet DATA\n");
+            while (ts.size) {
+                // fprintf (stderr,"ts.size %d (%02X%02X%02X%02X)\n",ts.size, ts.data[0], ts.data[1], ts.data[2], ts.data[3]);
+
+                switch (avcnalu_parse_annexb (&nalu, &ts.data, &ts.size)) {
+                case LIBCAPTION_OK:
+                    break;
+
+                case LIBCAPTION_ERROR:
+                    // fprintf (stderr,"LIBCAPTION_ERROR == avcnalu_parse_annexb()\n");
+                    avcnalu_init (&nalu);
+                    break;
+
+                case LIBCAPTION_READY: {
+
+                    if (6 == avcnalu_type (&nalu)) {
+                        // fprintf (stderr,"NALU %d (%d)\n", avcnalu_type (&nalu), avcnalu_size (&nalu));
+                        sei_init (&sei);
+                        sei_parse_avcnalu (&sei, &nalu, ts_dts_seconds (&ts), ts_cts_seconds (&ts));
+
+                        // sei_dump (&sei);
+
+                        if (LIBCAPTION_READY == sei_to_caption_frame (&sei,&frame)) {
+                            // caption_frame_dump (&frame);
+                            srt = srt_from_caption_frame (&frame,srt,&head);
+
+                            // srt_dump (srt);
+                        }
+
+                        sei_free (&sei);
+                    }
+
+                    avcnalu_init (&nalu);
+                } break;
+                }
+            }
+        } break;
+
+        case LIBCAPTION_ERROR:
+            // fprintf (stderr,"read ts packet ERROR\n");
+            break;
+        }
+
+    }
+
+    srt_dump (head);
+    srt_free (head);
+
+    return 1;
+}
diff --git a/deps/libcaption/examples/wonderland.h b/deps/libcaption/examples/wonderland.h
new file mode 100644
index 0000000..5c68f04
--- /dev/null
+++ b/deps/libcaption/examples/wonderland.h
@@ -0,0 +1,2794 @@
+const char* wonderland[] = {
+    "Project Gutenberg’s Alice’s Adventures in Wonderland, by Lewis Carroll",
+    "This eBook is for the use of anyone anywhere at no cost and with",
+    "almost no restrictions whatsoever.  You may copy it, give it away or",
+    "re-use it under the terms of the Project Gutenberg License included",
+    "with this eBook or online at www.gutenberg.org",
+    "Title: Alice’s Adventures in Wonderland",
+    "Author: Lewis Carroll",
+    "Posting Date: June 25, 2008 [EBook #11]",
+    "Release Date: March, 1994",
+    "Last Updated: October 6, 2016",
+    "Language: English",
+    "Character set encoding: UTF-8",
+    "*** START OF THIS PROJECT GUTENBERG EBOOK ALICE’S ADVENTURES IN WONDERLAND ***",
+    "ALICE’S ADVENTURES IN WONDERLAND",
+    "Lewis Carroll",
+    "THE MILLENNIUM FULCRUM EDITION 3.0",
+    "CHAPTER I. Down the Rabbit-Hole",
+    "Alice was beginning to get very tired of sitting by her sister on the",
+    "bank, and of having nothing to do: once or twice she had peeped into the",
+    "book her sister was reading, but it had no pictures or conversations in",
+    "it, ‘and what is the use of a book,’ thought Alice ‘without pictures or",
+    "conversations?’",
+    "So she was considering in her own mind (as well as she could, for the",
+    "hot day made her feel very sleepy and stupid), whether the pleasure",
+    "of making a daisy-chain would be worth the trouble of getting up and",
+    "picking the daisies, when suddenly a White Rabbit with pink eyes ran",
+    "close by her.",
+    "There was nothing so VERY remarkable in that; nor did Alice think it so",
+    "VERY much out of the way to hear the Rabbit say to itself, ‘Oh dear!",
+    "Oh dear! I shall be late!’ (when she thought it over afterwards, it",
+    "occurred to her that she ought to have wondered at this, but at the time",
+    "it all seemed quite natural); but when the Rabbit actually TOOK A WATCH",
+    "OUT OF ITS WAISTCOAT-POCKET, and looked at it, and then hurried on,",
+    "Alice started to her feet, for it flashed across her mind that she had",
+    "never before seen a rabbit with either a waistcoat-pocket, or a watch",
+    "to take out of it, and burning with curiosity, she ran across the field",
+    "after it, and fortunately was just in time to see it pop down a large",
+    "rabbit-hole under the hedge.",
+    "In another moment down went Alice after it, never once considering how",
+    "in the world she was to get out again.",
+    "The rabbit-hole went straight on like a tunnel for some way, and then",
+    "dipped suddenly down, so suddenly that Alice had not a moment to think",
+    "about stopping herself before she found herself falling down a very deep",
+    "well.",
+    "Either the well was very deep, or she fell very slowly, for she had",
+    "plenty of time as she went down to look about her and to wonder what was",
+    "going to happen next. First, she tried to look down and make out what",
+    "she was coming to, but it was too dark to see anything; then she",
+    "looked at the sides of the well, and noticed that they were filled with",
+    "cupboards and book-shelves; here and there she saw maps and pictures",
+    "hung upon pegs. She took down a jar from one of the shelves as",
+    "she passed; it was labelled ‘ORANGE MARMALADE’, but to her great",
+    "disappointment it was empty: she did not like to drop the jar for fear",
+    "of killing somebody, so managed to put it into one of the cupboards as",
+    "she fell past it.",
+    "‘Well!’ thought Alice to herself, ‘after such a fall as this, I shall",
+    "think nothing of tumbling down stairs! How brave they’ll all think me at",
+    "home! Why, I wouldn’t say anything about it, even if I fell off the top",
+    "of the house!’ (Which was very likely true.)",
+    "Down, down, down. Would the fall NEVER come to an end! ‘I wonder how",
+    "many miles I’ve fallen by this time?’ she said aloud. ‘I must be getting",
+    "somewhere near the centre of the earth. Let me see: that would be four",
+    "thousand miles down, I think--’ (for, you see, Alice had learnt several",
+    "things of this sort in her lessons in the schoolroom, and though this",
+    "was not a VERY good opportunity for showing off her knowledge, as there",
+    "was no one to listen to her, still it was good practice to say it over)",
+    "‘--yes, that’s about the right distance--but then I wonder what Latitude",
+    "or Longitude I’ve got to?’ (Alice had no idea what Latitude was, or",
+    "Longitude either, but thought they were nice grand words to say.)",
+    "Presently she began again. ‘I wonder if I shall fall right THROUGH the",
+    "earth! How funny it’ll seem to come out among the people that walk with",
+    "their heads downward! The Antipathies, I think--’ (she was rather glad",
+    "there WAS no one listening, this time, as it didn’t sound at all the",
+    "right word) ‘--but I shall have to ask them what the name of the country",
+    "is, you know. Please, Ma’am, is this New Zealand or Australia?’ (and",
+    "she tried to curtsey as she spoke--fancy CURTSEYING as you’re falling",
+    "through the air! Do you think you could manage it?) ‘And what an",
+    "ignorant little girl she’ll think me for asking! No, it’ll never do to",
+    "ask: perhaps I shall see it written up somewhere.’",
+    "Down, down, down. There was nothing else to do, so Alice soon began",
+    "talking again. ‘Dinah’ll miss me very much to-night, I should think!’",
+    "(Dinah was the cat.) ‘I hope they’ll remember her saucer of milk at",
+    "tea-time. Dinah my dear! I wish you were down here with me! There are no",
+    "mice in the air, I’m afraid, but you might catch a bat, and that’s very",
+    "like a mouse, you know. But do cats eat bats, I wonder?’ And here Alice",
+    "began to get rather sleepy, and went on saying to herself, in a dreamy",
+    "sort of way, ‘Do cats eat bats? Do cats eat bats?’ and sometimes, ‘Do",
+    "bats eat cats?’ for, you see, as she couldn’t answer either question,",
+    "it didn’t much matter which way she put it. She felt that she was dozing",
+    "off, and had just begun to dream that she was walking hand in hand with",
+    "Dinah, and saying to her very earnestly, ‘Now, Dinah, tell me the truth:",
+    "did you ever eat a bat?’ when suddenly, thump! thump! down she came upon",
+    "a heap of sticks and dry leaves, and the fall was over.",
+    "Alice was not a bit hurt, and she jumped up on to her feet in a moment:",
+    "she looked up, but it was all dark overhead; before her was another",
+    "long passage, and the White Rabbit was still in sight, hurrying down it.",
+    "There was not a moment to be lost: away went Alice like the wind, and",
+    "was just in time to hear it say, as it turned a corner, ‘Oh my ears",
+    "and whiskers, how late it’s getting!’ She was close behind it when she",
+    "turned the corner, but the Rabbit was no longer to be seen: she found",
+    "herself in a long, low hall, which was lit up by a row of lamps hanging",
+    "from the roof.",
+    "There were doors all round the hall, but they were all locked; and when",
+    "Alice had been all the way down one side and up the other, trying every",
+    "door, she walked sadly down the middle, wondering how she was ever to",
+    "get out again.",
+    "Suddenly she came upon a little three-legged table, all made of solid",
+    "glass; there was nothing on it except a tiny golden key, and Alice’s",
+    "first thought was that it might belong to one of the doors of the hall;",
+    "but, alas! either the locks were too large, or the key was too small,",
+    "but at any rate it would not open any of them. However, on the second",
+    "time round, she came upon a low curtain she had not noticed before, and",
+    "behind it was a little door about fifteen inches high: she tried the",
+    "little golden key in the lock, and to her great delight it fitted!",
+    "Alice opened the door and found that it led into a small passage, not",
+    "much larger than a rat-hole: she knelt down and looked along the passage",
+    "into the loveliest garden you ever saw. How she longed to get out of",
+    "that dark hall, and wander about among those beds of bright flowers and",
+    "those cool fountains, but she could not even get her head through the",
+    "doorway; ‘and even if my head would go through,’ thought poor Alice, ‘it",
+    "would be of very little use without my shoulders. Oh, how I wish I could",
+    "shut up like a telescope! I think I could, if I only knew how to begin.’",
+    "For, you see, so many out-of-the-way things had happened lately,",
+    "that Alice had begun to think that very few things indeed were really",
+    "impossible.",
+    "There seemed to be no use in waiting by the little door, so she went",
+    "back to the table, half hoping she might find another key on it, or at",
+    "any rate a book of rules for shutting people up like telescopes: this",
+    "time she found a little bottle on it, [‘which certainly was not here",
+    "before,’ said Alice,) and round the neck of the bottle was a paper",
+    "label, with the words ‘DRINK ME’ beautifully printed on it in large",
+    "letters.",
+    "It was all very well to say ‘Drink me,’ but the wise little Alice was",
+    "not going to do THAT in a hurry. ‘No, I’ll look first,’ she said, ‘and",
+    "see whether it’s marked “poison” or not’; for she had read several nice",
+    "little histories about children who had got burnt, and eaten up by wild",
+    "beasts and other unpleasant things, all because they WOULD not remember",
+    "the simple rules their friends had taught them: such as, that a red-hot",
+    "poker will burn you if you hold it too long; and that if you cut your",
+    "finger VERY deeply with a knife, it usually bleeds; and she had never",
+    "forgotten that, if you drink much from a bottle marked ‘poison,’ it is",
+    "almost certain to disagree with you, sooner or later.",
+    "However, this bottle was NOT marked ‘poison,’ so Alice ventured to taste",
+    "it, and finding it very nice, (it had, in fact, a sort of mixed flavour",
+    "of cherry-tart, custard, pine-apple, roast turkey, toffee, and hot",
+    "buttered toast,) she very soon finished it off.",
+    "  *    *    *    *    *    *    *",
+    "    *    *    *    *    *    *",
+    "  *    *    *    *    *    *    *",
+    "‘What a curious feeling!’ said Alice; ‘I must be shutting up like a",
+    "telescope.’",
+    "And so it was indeed: she was now only ten inches high, and her face",
+    "brightened up at the thought that she was now the right size for going",
+    "through the little door into that lovely garden. First, however, she",
+    "waited for a few minutes to see if she was going to shrink any further:",
+    "she felt a little nervous about this; ‘for it might end, you know,’ said",
+    "Alice to herself, ‘in my going out altogether, like a candle. I wonder",
+    "what I should be like then?’ And she tried to fancy what the flame of a",
+    "candle is like after the candle is blown out, for she could not remember",
+    "ever having seen such a thing.",
+    "After a while, finding that nothing more happened, she decided on going",
+    "into the garden at once; but, alas for poor Alice! when she got to the",
+    "door, she found she had forgotten the little golden key, and when she",
+    "went back to the table for it, she found she could not possibly reach",
+    "it: she could see it quite plainly through the glass, and she tried her",
+    "best to climb up one of the legs of the table, but it was too slippery;",
+    "and when she had tired herself out with trying, the poor little thing",
+    "sat down and cried.",
+    "‘Come, there’s no use in crying like that!’ said Alice to herself,",
+    "rather sharply; ‘I advise you to leave off this minute!’ She generally",
+    "gave herself very good advice, (though she very seldom followed it),",
+    "and sometimes she scolded herself so severely as to bring tears into",
+    "her eyes; and once she remembered trying to box her own ears for having",
+    "cheated herself in a game of croquet she was playing against herself,",
+    "for this curious child was very fond of pretending to be two people.",
+    "‘But it’s no use now,’ thought poor Alice, ‘to pretend to be two people!",
+    "Why, there’s hardly enough of me left to make ONE respectable person!’",
+    "Soon her eye fell on a little glass box that was lying under the table:",
+    "she opened it, and found in it a very small cake, on which the words",
+    "‘EAT ME’ were beautifully marked in currants. ‘Well, I’ll eat it,’ said",
+    "Alice, ‘and if it makes me grow larger, I can reach the key; and if it",
+    "makes me grow smaller, I can creep under the door; so either way I’ll",
+    "get into the garden, and I don’t care which happens!’",
+    "She ate a little bit, and said anxiously to herself, ‘Which way? Which",
+    "way?’, holding her hand on the top of her head to feel which way it was",
+    "growing, and she was quite surprised to find that she remained the same",
+    "size: to be sure, this generally happens when one eats cake, but Alice",
+    "had got so much into the way of expecting nothing but out-of-the-way",
+    "things to happen, that it seemed quite dull and stupid for life to go on",
+    "in the common way.",
+    "So she set to work, and very soon finished off the cake.",
+    "  *    *    *    *    *    *    *",
+    "    *    *    *    *    *    *",
+    "  *    *    *    *    *    *    *",
+    "CHAPTER II. The Pool of Tears",
+    "‘Curiouser and curiouser!’ cried Alice (she was so much surprised, that",
+    "for the moment she quite forgot how to speak good English); ‘now I’m",
+    "opening out like the largest telescope that ever was! Good-bye, feet!’",
+    "(for when she looked down at her feet, they seemed to be almost out of",
+    "sight, they were getting so far off). ‘Oh, my poor little feet, I wonder",
+    "who will put on your shoes and stockings for you now, dears? I’m sure",
+    "_I_ shan’t be able! I shall be a great deal too far off to trouble",
+    "myself about you: you must manage the best way you can;--but I must be",
+    "kind to them,’ thought Alice, ‘or perhaps they won’t walk the way I want",
+    "to go! Let me see: I’ll give them a new pair of boots every Christmas.’",
+    "And she went on planning to herself how she would manage it. ‘They must",
+    "go by the carrier,’ she thought; ‘and how funny it’ll seem, sending",
+    "presents to one’s own feet! And how odd the directions will look!",
+    "     ALICE’S RIGHT FOOT, ESQ.",
+    "       HEARTHRUG,",
+    "         NEAR THE FENDER,",
+    "           (WITH ALICE’S LOVE).",
+    "Oh dear, what nonsense I’m talking!’",
+    "Just then her head struck against the roof of the hall: in fact she was",
+    "now more than nine feet high, and she at once took up the little golden",
+    "key and hurried off to the garden door.",
+    "Poor Alice! It was as much as she could do, lying down on one side, to",
+    "look through into the garden with one eye; but to get through was more",
+    "hopeless than ever: she sat down and began to cry again.",
+    "‘You ought to be ashamed of yourself,’ said Alice, ‘a great girl like",
+    "you,’ (she might well say this), ‘to go on crying in this way! Stop this",
+    "moment, I tell you!’ But she went on all the same, shedding gallons of",
+    "tears, until there was a large pool all round her, about four inches",
+    "deep and reaching half down the hall.",
+    "After a time she heard a little pattering of feet in the distance, and",
+    "she hastily dried her eyes to see what was coming. It was the White",
+    "Rabbit returning, splendidly dressed, with a pair of white kid gloves in",
+    "one hand and a large fan in the other: he came trotting along in a great",
+    "hurry, muttering to himself as he came, ‘Oh! the Duchess, the Duchess!",
+    "Oh! won’t she be savage if I’ve kept her waiting!’ Alice felt so",
+    "desperate that she was ready to ask help of any one; so, when the Rabbit",
+    "came near her, she began, in a low, timid voice, ‘If you please, sir--’",
+    "The Rabbit started violently, dropped the white kid gloves and the fan,",
+    "and skurried away into the darkness as hard as he could go.",
+    "Alice took up the fan and gloves, and, as the hall was very hot, she",
+    "kept fanning herself all the time she went on talking: ‘Dear, dear! How",
+    "queer everything is to-day! And yesterday things went on just as usual.",
+    "I wonder if I’ve been changed in the night? Let me think: was I the",
+    "same when I got up this morning? I almost think I can remember feeling a",
+    "little different. But if I’m not the same, the next question is, Who",
+    "in the world am I? Ah, THAT’S the great puzzle!’ And she began thinking",
+    "over all the children she knew that were of the same age as herself, to",
+    "see if she could have been changed for any of them.",
+    "‘I’m sure I’m not Ada,’ she said, ‘for her hair goes in such long",
+    "ringlets, and mine doesn’t go in ringlets at all; and I’m sure I can’t",
+    "be Mabel, for I know all sorts of things, and she, oh! she knows such a",
+    "very little! Besides, SHE’S she, and I’m I, and--oh dear, how puzzling",
+    "it all is! I’ll try if I know all the things I used to know. Let me",
+    "see: four times five is twelve, and four times six is thirteen, and",
+    "four times seven is--oh dear! I shall never get to twenty at that rate!",
+    "However, the Multiplication Table doesn’t signify: let’s try Geography.",
+    "London is the capital of Paris, and Paris is the capital of Rome, and",
+    "Rome--no, THAT’S all wrong, I’m certain! I must have been changed for",
+    "Mabel! I’ll try and say “How doth the little--“’ and she crossed her",
+    "hands on her lap as if she were saying lessons, and began to repeat it,",
+    "but her voice sounded hoarse and strange, and the words did not come the",
+    "same as they used to do:--",
+    "     ‘How doth the little crocodile",
+    "      Improve his shining tail,",
+    "     And pour the waters of the Nile",
+    "      On every golden scale!",
+    "     ‘How cheerfully he seems to grin,",
+    "      How neatly spread his claws,",
+    "     And welcome little fishes in",
+    "      With gently smiling jaws!’",
+    "‘I’m sure those are not the right words,’ said poor Alice, and her eyes",
+    "filled with tears again as she went on, ‘I must be Mabel after all, and",
+    "I shall have to go and live in that poky little house, and have next to",
+    "no toys to play with, and oh! ever so many lessons to learn! No, I’ve",
+    "made up my mind about it; if I’m Mabel, I’ll stay down here! It’ll be no",
+    "use their putting their heads down and saying “Come up again, dear!” I",
+    "shall only look up and say “Who am I then? Tell me that first, and then,",
+    "if I like being that person, I’ll come up: if not, I’ll stay down here",
+    "till I’m somebody else”--but, oh dear!’ cried Alice, with a sudden burst",
+    "of tears, ‘I do wish they WOULD put their heads down! I am so VERY tired",
+    "of being all alone here!’",
+    "As she said this she looked down at her hands, and was surprised to see",
+    "that she had put on one of the Rabbit’s little white kid gloves while",
+    "she was talking. ‘How CAN I have done that?’ she thought. ‘I must",
+    "be growing small again.’ She got up and went to the table to measure",
+    "herself by it, and found that, as nearly as she could guess, she was now",
+    "about two feet high, and was going on shrinking rapidly: she soon found",
+    "out that the cause of this was the fan she was holding, and she dropped",
+    "it hastily, just in time to avoid shrinking away altogether.",
+    "‘That WAS a narrow escape!’ said Alice, a good deal frightened at the",
+    "sudden change, but very glad to find herself still in existence; ‘and",
+    "now for the garden!’ and she ran with all speed back to the little door:",
+    "but, alas! the little door was shut again, and the little golden key was",
+    "lying on the glass table as before, ‘and things are worse than ever,’",
+    "thought the poor child, ‘for I never was so small as this before, never!",
+    "And I declare it’s too bad, that it is!’",
+    "As she said these words her foot slipped, and in another moment, splash!",
+    "she was up to her chin in salt water. Her first idea was that she",
+    "had somehow fallen into the sea, ‘and in that case I can go back by",
+    "railway,’ she said to herself. (Alice had been to the seaside once in",
+    "her life, and had come to the general conclusion, that wherever you go",
+    "to on the English coast you find a number of bathing machines in the",
+    "sea, some children digging in the sand with wooden spades, then a row",
+    "of lodging houses, and behind them a railway station.) However, she soon",
+    "made out that she was in the pool of tears which she had wept when she",
+    "was nine feet high.",
+    "‘I wish I hadn’t cried so much!’ said Alice, as she swam about, trying",
+    "to find her way out. ‘I shall be punished for it now, I suppose, by",
+    "being drowned in my own tears! That WILL be a queer thing, to be sure!",
+    "However, everything is queer to-day.’",
+    "Just then she heard something splashing about in the pool a little way",
+    "off, and she swam nearer to make out what it was: at first she thought",
+    "it must be a walrus or hippopotamus, but then she remembered how small",
+    "she was now, and she soon made out that it was only a mouse that had",
+    "slipped in like herself.",
+    "‘Would it be of any use, now,’ thought Alice, ‘to speak to this mouse?",
+    "Everything is so out-of-the-way down here, that I should think very",
+    "likely it can talk: at any rate, there’s no harm in trying.’ So she",
+    "began: ‘O Mouse, do you know the way out of this pool? I am very tired",
+    "of swimming about here, O Mouse!’ (Alice thought this must be the right",
+    "way of speaking to a mouse: she had never done such a thing before, but",
+    "she remembered having seen in her brother’s Latin Grammar, ‘A mouse--of",
+    "a mouse--to a mouse--a mouse--O mouse!’) The Mouse looked at her rather",
+    "inquisitively, and seemed to her to wink with one of its little eyes,",
+    "but it said nothing.",
+    "‘Perhaps it doesn’t understand English,’ thought Alice; ‘I daresay it’s",
+    "a French mouse, come over with William the Conqueror.’ (For, with all",
+    "her knowledge of history, Alice had no very clear notion how long ago",
+    "anything had happened.) So she began again: ‘Ou est ma chatte?’ which",
+    "was the first sentence in her French lesson-book. The Mouse gave a",
+    "sudden leap out of the water, and seemed to quiver all over with fright.",
+    "‘Oh, I beg your pardon!’ cried Alice hastily, afraid that she had hurt",
+    "the poor animal’s feelings. ‘I quite forgot you didn’t like cats.’",
+    "‘Not like cats!’ cried the Mouse, in a shrill, passionate voice. ‘Would",
+    "YOU like cats if you were me?’",
+    "‘Well, perhaps not,’ said Alice in a soothing tone: ‘don’t be angry",
+    "about it. And yet I wish I could show you our cat Dinah: I think you’d",
+    "take a fancy to cats if you could only see her. She is such a dear quiet",
+    "thing,’ Alice went on, half to herself, as she swam lazily about in the",
+    "pool, ‘and she sits purring so nicely by the fire, licking her paws and",
+    "washing her face--and she is such a nice soft thing to nurse--and she’s",
+    "such a capital one for catching mice--oh, I beg your pardon!’ cried",
+    "Alice again, for this time the Mouse was bristling all over, and she",
+    "felt certain it must be really offended. ‘We won’t talk about her any",
+    "more if you’d rather not.’",
+    "‘We indeed!’ cried the Mouse, who was trembling down to the end of his",
+    "tail. ‘As if I would talk on such a subject! Our family always HATED",
+    "cats: nasty, low, vulgar things! Don’t let me hear the name again!’",
+    "‘I won’t indeed!’ said Alice, in a great hurry to change the subject of",
+    "conversation. ‘Are you--are you fond--of--of dogs?’ The Mouse did not",
+    "answer, so Alice went on eagerly: ‘There is such a nice little dog near",
+    "our house I should like to show you! A little bright-eyed terrier, you",
+    "know, with oh, such long curly brown hair! And it’ll fetch things when",
+    "you throw them, and it’ll sit up and beg for its dinner, and all sorts",
+    "of things--I can’t remember half of them--and it belongs to a farmer,",
+    "you know, and he says it’s so useful, it’s worth a hundred pounds! He",
+    "says it kills all the rats and--oh dear!’ cried Alice in a sorrowful",
+    "tone, ‘I’m afraid I’ve offended it again!’ For the Mouse was swimming",
+    "away from her as hard as it could go, and making quite a commotion in",
+    "the pool as it went.",
+    "So she called softly after it, ‘Mouse dear! Do come back again, and we",
+    "won’t talk about cats or dogs either, if you don’t like them!’ When the",
+    "Mouse heard this, it turned round and swam slowly back to her: its",
+    "face was quite pale (with passion, Alice thought), and it said in a low",
+    "trembling voice, ‘Let us get to the shore, and then I’ll tell you my",
+    "history, and you’ll understand why it is I hate cats and dogs.’",
+    "It was high time to go, for the pool was getting quite crowded with the",
+    "birds and animals that had fallen into it: there were a Duck and a Dodo,",
+    "a Lory and an Eaglet, and several other curious creatures. Alice led the",
+    "way, and the whole party swam to the shore.",
+    "CHAPTER III. A Caucus-Race and a Long Tale",
+    "They were indeed a queer-looking party that assembled on the bank--the",
+    "birds with draggled feathers, the animals with their fur clinging close",
+    "to them, and all dripping wet, cross, and uncomfortable.",
+    "The first question of course was, how to get dry again: they had a",
+    "consultation about this, and after a few minutes it seemed quite natural",
+    "to Alice to find herself talking familiarly with them, as if she had",
+    "known them all her life. Indeed, she had quite a long argument with the",
+    "Lory, who at last turned sulky, and would only say, ‘I am older than",
+    "you, and must know better’; and this Alice would not allow without",
+    "knowing how old it was, and, as the Lory positively refused to tell its",
+    "age, there was no more to be said.",
+    "At last the Mouse, who seemed to be a person of authority among them,",
+    "called out, ‘Sit down, all of you, and listen to me! I’LL soon make you",
+    "dry enough!’ They all sat down at once, in a large ring, with the Mouse",
+    "in the middle. Alice kept her eyes anxiously fixed on it, for she felt",
+    "sure she would catch a bad cold if she did not get dry very soon.",
+    "‘Ahem!’ said the Mouse with an important air, ‘are you all ready? This",
+    "is the driest thing I know. Silence all round, if you please! “William",
+    "the Conqueror, whose cause was favoured by the pope, was soon submitted",
+    "to by the English, who wanted leaders, and had been of late much",
+    "accustomed to usurpation and conquest. Edwin and Morcar, the earls of",
+    "Mercia and Northumbria--“’",
+    "‘Ugh!’ said the Lory, with a shiver.",
+    "‘I beg your pardon!’ said the Mouse, frowning, but very politely: ‘Did",
+    "you speak?’",
+    "‘Not I!’ said the Lory hastily.",
+    "‘I thought you did,’ said the Mouse. ‘--I proceed. “Edwin and Morcar,",
+    "the earls of Mercia and Northumbria, declared for him: and even Stigand,",
+    "the patriotic archbishop of Canterbury, found it advisable--“’",
+    "‘Found WHAT?’ said the Duck.",
+    "‘Found IT,’ the Mouse replied rather crossly: ‘of course you know what",
+    "“it” means.’",
+    "‘I know what “it” means well enough, when I find a thing,’ said the",
+    "Duck: ‘it’s generally a frog or a worm. The question is, what did the",
+    "archbishop find?’",
+    "The Mouse did not notice this question, but hurriedly went on, ‘“--found",
+    "it advisable to go with Edgar Atheling to meet William and offer him the",
+    "crown. William’s conduct at first was moderate. But the insolence of his",
+    "Normans--” How are you getting on now, my dear?’ it continued, turning",
+    "to Alice as it spoke.",
+    "‘As wet as ever,’ said Alice in a melancholy tone: ‘it doesn’t seem to",
+    "dry me at all.’",
+    "‘In that case,’ said the Dodo solemnly, rising to its feet, ‘I move",
+    "that the meeting adjourn, for the immediate adoption of more energetic",
+    "remedies--’",
+    "‘Speak English!’ said the Eaglet. ‘I don’t know the meaning of half",
+    "those long words, and, what’s more, I don’t believe you do either!’ And",
+    "the Eaglet bent down its head to hide a smile: some of the other birds",
+    "tittered audibly.",
+    "‘What I was going to say,’ said the Dodo in an offended tone, ‘was, that",
+    "the best thing to get us dry would be a Caucus-race.’",
+    "‘What IS a Caucus-race?’ said Alice; not that she wanted much to know,",
+    "but the Dodo had paused as if it thought that SOMEBODY ought to speak,",
+    "and no one else seemed inclined to say anything.",
+    "‘Why,’ said the Dodo, ‘the best way to explain it is to do it.’ (And, as",
+    "you might like to try the thing yourself, some winter day, I will tell",
+    "you how the Dodo managed it.)",
+    "First it marked out a race-course, in a sort of circle, [‘the exact",
+    "shape doesn’t matter,’ it said,) and then all the party were placed",
+    "along the course, here and there. There was no ‘One, two, three, and",
+    "away,’ but they began running when they liked, and left off when they",
+    "liked, so that it was not easy to know when the race was over. However,",
+    "when they had been running half an hour or so, and were quite dry again,",
+    "the Dodo suddenly called out ‘The race is over!’ and they all crowded",
+    "round it, panting, and asking, ‘But who has won?’",
+    "This question the Dodo could not answer without a great deal of thought,",
+    "and it sat for a long time with one finger pressed upon its forehead",
+    "(the position in which you usually see Shakespeare, in the pictures",
+    "of him), while the rest waited in silence. At last the Dodo said,",
+    "‘EVERYBODY has won, and all must have prizes.’",
+    "‘But who is to give the prizes?’ quite a chorus of voices asked.",
+    "‘Why, SHE, of course,’ said the Dodo, pointing to Alice with one finger;",
+    "and the whole party at once crowded round her, calling out in a confused",
+    "way, ‘Prizes! Prizes!’",
+    "Alice had no idea what to do, and in despair she put her hand in her",
+    "pocket, and pulled out a box of comfits, (luckily the salt water had",
+    "not got into it), and handed them round as prizes. There was exactly one",
+    "a-piece all round.",
+    "‘But she must have a prize herself, you know,’ said the Mouse.",
+    "‘Of course,’ the Dodo replied very gravely. ‘What else have you got in",
+    "your pocket?’ he went on, turning to Alice.",
+    "‘Only a thimble,’ said Alice sadly.",
+    "‘Hand it over here,’ said the Dodo.",
+    "Then they all crowded round her once more, while the Dodo solemnly",
+    "presented the thimble, saying ‘We beg your acceptance of this elegant",
+    "thimble’; and, when it had finished this short speech, they all cheered.",
+    "Alice thought the whole thing very absurd, but they all looked so grave",
+    "that she did not dare to laugh; and, as she could not think of anything",
+    "to say, she simply bowed, and took the thimble, looking as solemn as she",
+    "could.",
+    "The next thing was to eat the comfits: this caused some noise and",
+    "confusion, as the large birds complained that they could not taste",
+    "theirs, and the small ones choked and had to be patted on the back.",
+    "However, it was over at last, and they sat down again in a ring, and",
+    "begged the Mouse to tell them something more.",
+    "‘You promised to tell me your history, you know,’ said Alice, ‘and why",
+    "it is you hate--C and D,’ she added in a whisper, half afraid that it",
+    "would be offended again.",
+    "‘Mine is a long and a sad tale!’ said the Mouse, turning to Alice, and",
+    "sighing.",
+    "‘It IS a long tail, certainly,’ said Alice, looking down with wonder at",
+    "the Mouse’s tail; ‘but why do you call it sad?’ And she kept on puzzling",
+    "about it while the Mouse was speaking, so that her idea of the tale was",
+    "something like this:--",
+    "         ‘Fury said to a",
+    "         mouse, That he",
+    "        met in the",
+    "       house,",
+    "     “Let us",
+    "      both go to",
+    "       law: I will",
+    "        prosecute",
+    "         YOU.--Come,",
+    "           I’ll take no",
+    "           denial; We",
+    "          must have a",
+    "        trial: For",
+    "      really this",
+    "     morning I’ve",
+    "    nothing",
+    "    to do.”",
+    "      Said the",
+    "      mouse to the",
+    "       cur, “Such",
+    "        a trial,",
+    "         dear Sir,",
+    "            With",
+    "          no jury",
+    "        or judge,",
+    "       would be",
+    "      wasting",
+    "      our",
+    "      breath.”",
+    "        “I’ll be",
+    "        judge, I’ll",
+    "         be jury,”",
+    "             Said",
+    "         cunning",
+    "          old Fury:",
+    "          “I’ll",
+    "          try the",
+    "            whole",
+    "            cause,",
+    "              and",
+    "           condemn",
+    "           you",
+    "          to",
+    "           death.”’",
+    "‘You are not attending!’ said the Mouse to Alice severely. ‘What are you",
+    "thinking of?’",
+    "‘I beg your pardon,’ said Alice very humbly: ‘you had got to the fifth",
+    "bend, I think?’",
+    "‘I had NOT!’ cried the Mouse, sharply and very angrily.",
+    "‘A knot!’ said Alice, always ready to make herself useful, and looking",
+    "anxiously about her. ‘Oh, do let me help to undo it!’",
+    "‘I shall do nothing of the sort,’ said the Mouse, getting up and walking",
+    "away. ‘You insult me by talking such nonsense!’",
+    "‘I didn’t mean it!’ pleaded poor Alice. ‘But you’re so easily offended,",
+    "you know!’",
+    "The Mouse only growled in reply.",
+    "‘Please come back and finish your story!’ Alice called after it; and the",
+    "others all joined in chorus, ‘Yes, please do!’ but the Mouse only shook",
+    "its head impatiently, and walked a little quicker.",
+    "‘What a pity it wouldn’t stay!’ sighed the Lory, as soon as it was quite",
+    "out of sight; and an old Crab took the opportunity of saying to her",
+    "daughter ‘Ah, my dear! Let this be a lesson to you never to lose",
+    "YOUR temper!’ ‘Hold your tongue, Ma!’ said the young Crab, a little",
+    "snappishly. ‘You’re enough to try the patience of an oyster!’",
+    "‘I wish I had our Dinah here, I know I do!’ said Alice aloud, addressing",
+    "nobody in particular. ‘She’d soon fetch it back!’",
+    "‘And who is Dinah, if I might venture to ask the question?’ said the",
+    "Lory.",
+    "Alice replied eagerly, for she was always ready to talk about her pet:",
+    "‘Dinah’s our cat. And she’s such a capital one for catching mice you",
+    "can’t think! And oh, I wish you could see her after the birds! Why,",
+    "she’ll eat a little bird as soon as look at it!’",
+    "This speech caused a remarkable sensation among the party. Some of the",
+    "birds hurried off at once: one old Magpie began wrapping itself up very",
+    "carefully, remarking, ‘I really must be getting home; the night-air",
+    "doesn’t suit my throat!’ and a Canary called out in a trembling voice to",
+    "its children, ‘Come away, my dears! It’s high time you were all in bed!’",
+    "On various pretexts they all moved off, and Alice was soon left alone.",
+    "‘I wish I hadn’t mentioned Dinah!’ she said to herself in a melancholy",
+    "tone. ‘Nobody seems to like her, down here, and I’m sure she’s the best",
+    "cat in the world! Oh, my dear Dinah! I wonder if I shall ever see you",
+    "any more!’ And here poor Alice began to cry again, for she felt very",
+    "lonely and low-spirited. In a little while, however, she again heard",
+    "a little pattering of footsteps in the distance, and she looked up",
+    "eagerly, half hoping that the Mouse had changed his mind, and was coming",
+    "back to finish his story.",
+    "CHAPTER IV. The Rabbit Sends in a Little Bill",
+    "It was the White Rabbit, trotting slowly back again, and looking",
+    "anxiously about as it went, as if it had lost something; and she heard",
+    "it muttering to itself ‘The Duchess! The Duchess! Oh my dear paws! Oh",
+    "my fur and whiskers! She’ll get me executed, as sure as ferrets are",
+    "ferrets! Where CAN I have dropped them, I wonder?’ Alice guessed in a",
+    "moment that it was looking for the fan and the pair of white kid gloves,",
+    "and she very good-naturedly began hunting about for them, but they were",
+    "nowhere to be seen--everything seemed to have changed since her swim in",
+    "the pool, and the great hall, with the glass table and the little door,",
+    "had vanished completely.",
+    "Very soon the Rabbit noticed Alice, as she went hunting about, and",
+    "called out to her in an angry tone, ‘Why, Mary Ann, what ARE you doing",
+    "out here? Run home this moment, and fetch me a pair of gloves and a fan!",
+    "Quick, now!’ And Alice was so much frightened that she ran off at once",
+    "in the direction it pointed to, without trying to explain the mistake it",
+    "had made.",
+    "‘He took me for his housemaid,’ she said to herself as she ran. ‘How",
+    "surprised he’ll be when he finds out who I am! But I’d better take him",
+    "his fan and gloves--that is, if I can find them.’ As she said this, she",
+    "came upon a neat little house, on the door of which was a bright brass",
+    "plate with the name ‘W. RABBIT’ engraved upon it. She went in without",
+    "knocking, and hurried upstairs, in great fear lest she should meet the",
+    "real Mary Ann, and be turned out of the house before she had found the",
+    "fan and gloves.",
+    "‘How queer it seems,’ Alice said to herself, ‘to be going messages for",
+    "a rabbit! I suppose Dinah’ll be sending me on messages next!’ And she",
+    "began fancying the sort of thing that would happen: ‘“Miss Alice! Come",
+    "here directly, and get ready for your walk!” “Coming in a minute,",
+    "nurse! But I’ve got to see that the mouse doesn’t get out.” Only I don’t",
+    "think,’ Alice went on, ‘that they’d let Dinah stop in the house if it",
+    "began ordering people about like that!’",
+    "By this time she had found her way into a tidy little room with a table",
+    "in the window, and on it (as she had hoped) a fan and two or three pairs",
+    "of tiny white kid gloves: she took up the fan and a pair of the gloves,",
+    "and was just going to leave the room, when her eye fell upon a little",
+    "bottle that stood near the looking-glass. There was no label this time",
+    "with the words ‘DRINK ME,’ but nevertheless she uncorked it and put it",
+    "to her lips. ‘I know SOMETHING interesting is sure to happen,’ she said",
+    "to herself, ‘whenever I eat or drink anything; so I’ll just see what",
+    "this bottle does. I do hope it’ll make me grow large again, for really",
+    "I’m quite tired of being such a tiny little thing!’",
+    "It did so indeed, and much sooner than she had expected: before she had",
+    "drunk half the bottle, she found her head pressing against the ceiling,",
+    "and had to stoop to save her neck from being broken. She hastily put",
+    "down the bottle, saying to herself ‘That’s quite enough--I hope I shan’t",
+    "grow any more--As it is, I can’t get out at the door--I do wish I hadn’t",
+    "drunk quite so much!’",
+    "Alas! it was too late to wish that! She went on growing, and growing,",
+    "and very soon had to kneel down on the floor: in another minute there",
+    "was not even room for this, and she tried the effect of lying down with",
+    "one elbow against the door, and the other arm curled round her head.",
+    "Still she went on growing, and, as a last resource, she put one arm out",
+    "of the window, and one foot up the chimney, and said to herself ‘Now I",
+    "can do no more, whatever happens. What WILL become of me?’",
+    "Luckily for Alice, the little magic bottle had now had its full effect,",
+    "and she grew no larger: still it was very uncomfortable, and, as there",
+    "seemed to be no sort of chance of her ever getting out of the room",
+    "again, no wonder she felt unhappy.",
+    "‘It was much pleasanter at home,’ thought poor Alice, ‘when one wasn’t",
+    "always growing larger and smaller, and being ordered about by mice and",
+    "rabbits. I almost wish I hadn’t gone down that rabbit-hole--and yet--and",
+    "yet--it’s rather curious, you know, this sort of life! I do wonder what",
+    "CAN have happened to me! When I used to read fairy-tales, I fancied that",
+    "kind of thing never happened, and now here I am in the middle of one!",
+    "There ought to be a book written about me, that there ought! And when I",
+    "grow up, I’ll write one--but I’m grown up now,’ she added in a sorrowful",
+    "tone; ‘at least there’s no room to grow up any more HERE.’",
+    "‘But then,’ thought Alice, ‘shall I NEVER get any older than I am",
+    "now? That’ll be a comfort, one way--never to be an old woman--but",
+    "then--always to have lessons to learn! Oh, I shouldn’t like THAT!’",
+    "‘Oh, you foolish Alice!’ she answered herself. ‘How can you learn",
+    "lessons in here? Why, there’s hardly room for YOU, and no room at all",
+    "for any lesson-books!’",
+    "And so she went on, taking first one side and then the other, and making",
+    "quite a conversation of it altogether; but after a few minutes she heard",
+    "a voice outside, and stopped to listen.",
+    "‘Mary Ann! Mary Ann!’ said the voice. ‘Fetch me my gloves this moment!’",
+    "Then came a little pattering of feet on the stairs. Alice knew it was",
+    "the Rabbit coming to look for her, and she trembled till she shook the",
+    "house, quite forgetting that she was now about a thousand times as large",
+    "as the Rabbit, and had no reason to be afraid of it.",
+    "Presently the Rabbit came up to the door, and tried to open it; but, as",
+    "the door opened inwards, and Alice’s elbow was pressed hard against it,",
+    "that attempt proved a failure. Alice heard it say to itself ‘Then I’ll",
+    "go round and get in at the window.’",
+    "‘THAT you won’t’ thought Alice, and, after waiting till she fancied",
+    "she heard the Rabbit just under the window, she suddenly spread out her",
+    "hand, and made a snatch in the air. She did not get hold of anything,",
+    "but she heard a little shriek and a fall, and a crash of broken glass,",
+    "from which she concluded that it was just possible it had fallen into a",
+    "cucumber-frame, or something of the sort.",
+    "Next came an angry voice--the Rabbit’s--‘Pat! Pat! Where are you?’ And",
+    "then a voice she had never heard before, ‘Sure then I’m here! Digging",
+    "for apples, yer honour!’",
+    "‘Digging for apples, indeed!’ said the Rabbit angrily. ‘Here! Come and",
+    "help me out of THIS!’ (Sounds of more broken glass.)",
+    "‘Now tell me, Pat, what’s that in the window?’",
+    "‘Sure, it’s an arm, yer honour!’ (He pronounced it ‘arrum.’)",
+    "‘An arm, you goose! Who ever saw one that size? Why, it fills the whole",
+    "window!’",
+    "‘Sure, it does, yer honour: but it’s an arm for all that.’",
+    "‘Well, it’s got no business there, at any rate: go and take it away!’",
+    "There was a long silence after this, and Alice could only hear whispers",
+    "now and then; such as, ‘Sure, I don’t like it, yer honour, at all, at",
+    "all!’ ‘Do as I tell you, you coward!’ and at last she spread out her",
+    "hand again, and made another snatch in the air. This time there were",
+    "TWO little shrieks, and more sounds of broken glass. ‘What a number of",
+    "cucumber-frames there must be!’ thought Alice. ‘I wonder what they’ll do",
+    "next! As for pulling me out of the window, I only wish they COULD! I’m",
+    "sure I don’t want to stay in here any longer!’",
+    "She waited for some time without hearing anything more: at last came a",
+    "rumbling of little cartwheels, and the sound of a good many voices",
+    "all talking together: she made out the words: ‘Where’s the other",
+    "ladder?--Why, I hadn’t to bring but one; Bill’s got the other--Bill!",
+    "fetch it here, lad!--Here, put ‘em up at this corner--No, tie ‘em",
+    "together first--they don’t reach half high enough yet--Oh! they’ll",
+    "do well enough; don’t be particular--Here, Bill! catch hold of this",
+    "rope--Will the roof bear?--Mind that loose slate--Oh, it’s coming",
+    "down! Heads below!’ (a loud crash)--‘Now, who did that?--It was Bill, I",
+    "fancy--Who’s to go down the chimney?--Nay, I shan’t! YOU do it!--That I",
+    "won’t, then!--Bill’s to go down--Here, Bill! the master says you’re to",
+    "go down the chimney!’",
+    "‘Oh! So Bill’s got to come down the chimney, has he?’ said Alice to",
+    "herself. ‘Shy, they seem to put everything upon Bill! I wouldn’t be in",
+    "Bill’s place for a good deal: this fireplace is narrow, to be sure; but",
+    "I THINK I can kick a little!’",
+    "She drew her foot as far down the chimney as she could, and waited",
+    "till she heard a little animal (she couldn’t guess of what sort it was)",
+    "scratching and scrambling about in the chimney close above her: then,",
+    "saying to herself ‘This is Bill,’ she gave one sharp kick, and waited to",
+    "see what would happen next.",
+    "The first thing she heard was a general chorus of ‘There goes Bill!’",
+    "then the Rabbit’s voice along--‘Catch him, you by the hedge!’ then",
+    "silence, and then another confusion of voices--‘Hold up his head--Brandy",
+    "now--Don’t choke him--How was it, old fellow? What happened to you? Tell",
+    "us all about it!’",
+    "Last came a little feeble, squeaking voice, [‘That’s Bill,’ thought",
+    "Alice,) ‘Well, I hardly know--No more, thank ye; I’m better now--but I’m",
+    "a deal too flustered to tell you--all I know is, something comes at me",
+    "like a Jack-in-the-box, and up I goes like a sky-rocket!’",
+    "‘So you did, old fellow!’ said the others.",
+    "‘We must burn the house down!’ said the Rabbit’s voice; and Alice called",
+    "out as loud as she could, ‘If you do. I’ll set Dinah at you!’",
+    "There was a dead silence instantly, and Alice thought to herself, ‘I",
+    "wonder what they WILL do next! If they had any sense, they’d take the",
+    "roof off.’ After a minute or two, they began moving about again, and",
+    "Alice heard the Rabbit say, ‘A barrowful will do, to begin with.’",
+    "‘A barrowful of WHAT?’ thought Alice; but she had not long to doubt,",
+    "for the next moment a shower of little pebbles came rattling in at the",
+    "window, and some of them hit her in the face. ‘I’ll put a stop to this,’",
+    "she said to herself, and shouted out, ‘You’d better not do that again!’",
+    "which produced another dead silence.",
+    "Alice noticed with some surprise that the pebbles were all turning into",
+    "little cakes as they lay on the floor, and a bright idea came into her",
+    "head. ‘If I eat one of these cakes,’ she thought, ‘it’s sure to make",
+    "SOME change in my size; and as it can’t possibly make me larger, it must",
+    "make me smaller, I suppose.’",
+    "So she swallowed one of the cakes, and was delighted to find that she",
+    "began shrinking directly. As soon as she was small enough to get through",
+    "the door, she ran out of the house, and found quite a crowd of little",
+    "animals and birds waiting outside. The poor little Lizard, Bill, was",
+    "in the middle, being held up by two guinea-pigs, who were giving it",
+    "something out of a bottle. They all made a rush at Alice the moment she",
+    "appeared; but she ran off as hard as she could, and soon found herself",
+    "safe in a thick wood.",
+    "‘The first thing I’ve got to do,’ said Alice to herself, as she wandered",
+    "about in the wood, ‘is to grow to my right size again; and the second",
+    "thing is to find my way into that lovely garden. I think that will be",
+    "the best plan.’",
+    "It sounded an excellent plan, no doubt, and very neatly and simply",
+    "arranged; the only difficulty was, that she had not the smallest idea",
+    "how to set about it; and while she was peering about anxiously among",
+    "the trees, a little sharp bark just over her head made her look up in a",
+    "great hurry.",
+    "An enormous puppy was looking down at her with large round eyes, and",
+    "feebly stretching out one paw, trying to touch her. ‘Poor little thing!’",
+    "said Alice, in a coaxing tone, and she tried hard to whistle to it; but",
+    "she was terribly frightened all the time at the thought that it might be",
+    "hungry, in which case it would be very likely to eat her up in spite of",
+    "all her coaxing.",
+    "Hardly knowing what she did, she picked up a little bit of stick, and",
+    "held it out to the puppy; whereupon the puppy jumped into the air off",
+    "all its feet at once, with a yelp of delight, and rushed at the stick,",
+    "and made believe to worry it; then Alice dodged behind a great thistle,",
+    "to keep herself from being run over; and the moment she appeared on the",
+    "other side, the puppy made another rush at the stick, and tumbled head",
+    "over heels in its hurry to get hold of it; then Alice, thinking it was",
+    "very like having a game of play with a cart-horse, and expecting every",
+    "moment to be trampled under its feet, ran round the thistle again; then",
+    "the puppy began a series of short charges at the stick, running a very",
+    "little way forwards each time and a long way back, and barking hoarsely",
+    "all the while, till at last it sat down a good way off, panting, with",
+    "its tongue hanging out of its mouth, and its great eyes half shut.",
+    "This seemed to Alice a good opportunity for making her escape; so she",
+    "set off at once, and ran till she was quite tired and out of breath, and",
+    "till the puppy’s bark sounded quite faint in the distance.",
+    "‘And yet what a dear little puppy it was!’ said Alice, as she leant",
+    "against a buttercup to rest herself, and fanned herself with one of the",
+    "leaves: ‘I should have liked teaching it tricks very much, if--if I’d",
+    "only been the right size to do it! Oh dear! I’d nearly forgotten that",
+    "I’ve got to grow up again! Let me see--how IS it to be managed? I",
+    "suppose I ought to eat or drink something or other; but the great",
+    "question is, what?’",
+    "The great question certainly was, what? Alice looked all round her at",
+    "the flowers and the blades of grass, but she did not see anything that",
+    "looked like the right thing to eat or drink under the circumstances.",
+    "There was a large mushroom growing near her, about the same height as",
+    "herself; and when she had looked under it, and on both sides of it, and",
+    "behind it, it occurred to her that she might as well look and see what",
+    "was on the top of it.",
+    "She stretched herself up on tiptoe, and peeped over the edge of the",
+    "mushroom, and her eyes immediately met those of a large caterpillar,",
+    "that was sitting on the top with its arms folded, quietly smoking a long",
+    "hookah, and taking not the smallest notice of her or of anything else.",
+    "CHAPTER V. Advice from a Caterpillar",
+    "The Caterpillar and Alice looked at each other for some time in silence:",
+    "at last the Caterpillar took the hookah out of its mouth, and addressed",
+    "her in a languid, sleepy voice.",
+    "‘Who are YOU?’ said the Caterpillar.",
+    "This was not an encouraging opening for a conversation. Alice replied,",
+    "rather shyly, ‘I--I hardly know, sir, just at present--at least I know",
+    "who I WAS when I got up this morning, but I think I must have been",
+    "changed several times since then.’",
+    "‘What do you mean by that?’ said the Caterpillar sternly. ‘Explain",
+    "yourself!’",
+    "‘I can’t explain MYSELF, I’m afraid, sir’ said Alice, ‘because I’m not",
+    "myself, you see.’",
+    "‘I don’t see,’ said the Caterpillar.",
+    "‘I’m afraid I can’t put it more clearly,’ Alice replied very politely,",
+    "‘for I can’t understand it myself to begin with; and being so many",
+    "different sizes in a day is very confusing.’",
+    "‘It isn’t,’ said the Caterpillar.",
+    "‘Well, perhaps you haven’t found it so yet,’ said Alice; ‘but when you",
+    "have to turn into a chrysalis--you will some day, you know--and then",
+    "after that into a butterfly, I should think you’ll feel it a little",
+    "queer, won’t you?’",
+    "‘Not a bit,’ said the Caterpillar.",
+    "‘Well, perhaps your feelings may be different,’ said Alice; ‘all I know",
+    "is, it would feel very queer to ME.’",
+    "‘You!’ said the Caterpillar contemptuously. ‘Who are YOU?’",
+    "Which brought them back again to the beginning of the conversation.",
+    "Alice felt a little irritated at the Caterpillar’s making such VERY",
+    "short remarks, and she drew herself up and said, very gravely, ‘I think,",
+    "you ought to tell me who YOU are, first.’",
+    "‘Why?’ said the Caterpillar.",
+    "Here was another puzzling question; and as Alice could not think of any",
+    "good reason, and as the Caterpillar seemed to be in a VERY unpleasant",
+    "state of mind, she turned away.",
+    "‘Come back!’ the Caterpillar called after her. ‘I’ve something important",
+    "to say!’",
+    "This sounded promising, certainly: Alice turned and came back again.",
+    "‘Keep your temper,’ said the Caterpillar.",
+    "‘Is that all?’ said Alice, swallowing down her anger as well as she",
+    "could.",
+    "‘No,’ said the Caterpillar.",
+    "Alice thought she might as well wait, as she had nothing else to do, and",
+    "perhaps after all it might tell her something worth hearing. For some",
+    "minutes it puffed away without speaking, but at last it unfolded its",
+    "arms, took the hookah out of its mouth again, and said, ‘So you think",
+    "you’re changed, do you?’",
+    "‘I’m afraid I am, sir,’ said Alice; ‘I can’t remember things as I",
+    "used--and I don’t keep the same size for ten minutes together!’",
+    "‘Can’t remember WHAT things?’ said the Caterpillar.",
+    "‘Well, I’ve tried to say “HOW DOTH THE LITTLE BUSY BEE,” but it all came",
+    "different!’ Alice replied in a very melancholy voice.",
+    "‘Repeat, “YOU ARE OLD, FATHER WILLIAM,”’ said the Caterpillar.",
+    "Alice folded her hands, and began:--",
+    "   ‘You are old, Father William,’ the young man said,",
+    "    ‘And your hair has become very white;",
+    "   And yet you incessantly stand on your head--",
+    "    Do you think, at your age, it is right?’",
+    "   ‘In my youth,’ Father William replied to his son,",
+    "    ‘I feared it might injure the brain;",
+    "   But, now that I’m perfectly sure I have none,",
+    "    Why, I do it again and again.’",
+    "   ‘You are old,’ said the youth, ‘as I mentioned before,",
+    "    And have grown most uncommonly fat;",
+    "   Yet you turned a back-somersault in at the door--",
+    "    Pray, what is the reason of that?’",
+    "   ‘In my youth,’ said the sage, as he shook his grey locks,",
+    "    ‘I kept all my limbs very supple",
+    "   By the use of this ointment--one shilling the box--",
+    "    Allow me to sell you a couple?’",
+    "   ‘You are old,’ said the youth, ‘and your jaws are too weak",
+    "    For anything tougher than suet;",
+    "   Yet you finished the goose, with the bones and the beak--",
+    "    Pray how did you manage to do it?’",
+    "   ‘In my youth,’ said his father, ‘I took to the law,",
+    "    And argued each case with my wife;",
+    "   And the muscular strength, which it gave to my jaw,",
+    "    Has lasted the rest of my life.’",
+    "   ‘You are old,’ said the youth, ‘one would hardly suppose",
+    "    That your eye was as steady as ever;",
+    "   Yet you balanced an eel on the end of your nose--",
+    "    What made you so awfully clever?’",
+    "   ‘I have answered three questions, and that is enough,’",
+    "    Said his father; ‘don’t give yourself airs!",
+    "   Do you think I can listen all day to such stuff?",
+    "    Be off, or I’ll kick you down stairs!’",
+    "‘That is not said right,’ said the Caterpillar.",
+    "‘Not QUITE right, I’m afraid,’ said Alice, timidly; ‘some of the words",
+    "have got altered.’",
+    "‘It is wrong from beginning to end,’ said the Caterpillar decidedly, and",
+    "there was silence for some minutes.",
+    "The Caterpillar was the first to speak.",
+    "‘What size do you want to be?’ it asked.",
+    "‘Oh, I’m not particular as to size,’ Alice hastily replied; ‘only one",
+    "doesn’t like changing so often, you know.’",
+    "‘I DON’T know,’ said the Caterpillar.",
+    "Alice said nothing: she had never been so much contradicted in her life",
+    "before, and she felt that she was losing her temper.",
+    "‘Are you content now?’ said the Caterpillar.",
+    "‘Well, I should like to be a LITTLE larger, sir, if you wouldn’t mind,’",
+    "said Alice: ‘three inches is such a wretched height to be.’",
+    "‘It is a very good height indeed!’ said the Caterpillar angrily, rearing",
+    "itself upright as it spoke (it was exactly three inches high).",
+    "‘But I’m not used to it!’ pleaded poor Alice in a piteous tone. And",
+    "she thought of herself, ‘I wish the creatures wouldn’t be so easily",
+    "offended!’",
+    "‘You’ll get used to it in time,’ said the Caterpillar; and it put the",
+    "hookah into its mouth and began smoking again.",
+    "This time Alice waited patiently until it chose to speak again. In",
+    "a minute or two the Caterpillar took the hookah out of its mouth",
+    "and yawned once or twice, and shook itself. Then it got down off the",
+    "mushroom, and crawled away in the grass, merely remarking as it went,",
+    "‘One side will make you grow taller, and the other side will make you",
+    "grow shorter.’",
+    "‘One side of WHAT? The other side of WHAT?’ thought Alice to herself.",
+    "‘Of the mushroom,’ said the Caterpillar, just as if she had asked it",
+    "aloud; and in another moment it was out of sight.",
+    "Alice remained looking thoughtfully at the mushroom for a minute, trying",
+    "to make out which were the two sides of it; and as it was perfectly",
+    "round, she found this a very difficult question. However, at last she",
+    "stretched her arms round it as far as they would go, and broke off a bit",
+    "of the edge with each hand.",
+    "‘And now which is which?’ she said to herself, and nibbled a little of",
+    "the right-hand bit to try the effect: the next moment she felt a violent",
+    "blow underneath her chin: it had struck her foot!",
+    "She was a good deal frightened by this very sudden change, but she felt",
+    "that there was no time to be lost, as she was shrinking rapidly; so she",
+    "set to work at once to eat some of the other bit. Her chin was pressed",
+    "so closely against her foot, that there was hardly room to open her",
+    "mouth; but she did it at last, and managed to swallow a morsel of the",
+    "lefthand bit.",
+    "  *    *    *    *    *    *    *",
+    "    *    *    *    *    *    *",
+    "  *    *    *    *    *    *    *",
+    "‘Come, my head’s free at last!’ said Alice in a tone of delight, which",
+    "changed into alarm in another moment, when she found that her shoulders",
+    "were nowhere to be found: all she could see, when she looked down, was",
+    "an immense length of neck, which seemed to rise like a stalk out of a",
+    "sea of green leaves that lay far below her.",
+    "‘What CAN all that green stuff be?’ said Alice. ‘And where HAVE my",
+    "shoulders got to? And oh, my poor hands, how is it I can’t see you?’",
+    "She was moving them about as she spoke, but no result seemed to follow,",
+    "except a little shaking among the distant green leaves.",
+    "As there seemed to be no chance of getting her hands up to her head, she",
+    "tried to get her head down to them, and was delighted to find that her",
+    "neck would bend about easily in any direction, like a serpent. She had",
+    "just succeeded in curving it down into a graceful zigzag, and was going",
+    "to dive in among the leaves, which she found to be nothing but the tops",
+    "of the trees under which she had been wandering, when a sharp hiss made",
+    "her draw back in a hurry: a large pigeon had flown into her face, and",
+    "was beating her violently with its wings.",
+    "‘Serpent!’ screamed the Pigeon.",
+    "‘I’m NOT a serpent!’ said Alice indignantly. ‘Let me alone!’",
+    "‘Serpent, I say again!’ repeated the Pigeon, but in a more subdued tone,",
+    "and added with a kind of sob, ‘I’ve tried every way, and nothing seems",
+    "to suit them!’",
+    "‘I haven’t the least idea what you’re talking about,’ said Alice.",
+    "‘I’ve tried the roots of trees, and I’ve tried banks, and I’ve tried",
+    "hedges,’ the Pigeon went on, without attending to her; ‘but those",
+    "serpents! There’s no pleasing them!’",
+    "Alice was more and more puzzled, but she thought there was no use in",
+    "saying anything more till the Pigeon had finished.",
+    "‘As if it wasn’t trouble enough hatching the eggs,’ said the Pigeon;",
+    "‘but I must be on the look-out for serpents night and day! Why, I",
+    "haven’t had a wink of sleep these three weeks!’",
+    "‘I’m very sorry you’ve been annoyed,’ said Alice, who was beginning to",
+    "see its meaning.",
+    "‘And just as I’d taken the highest tree in the wood,’ continued the",
+    "Pigeon, raising its voice to a shriek, ‘and just as I was thinking I",
+    "should be free of them at last, they must needs come wriggling down from",
+    "the sky! Ugh, Serpent!’",
+    "‘But I’m NOT a serpent, I tell you!’ said Alice. ‘I’m a--I’m a--’",
+    "‘Well! WHAT are you?’ said the Pigeon. ‘I can see you’re trying to",
+    "invent something!’",
+    "‘I--I’m a little girl,’ said Alice, rather doubtfully, as she remembered",
+    "the number of changes she had gone through that day.",
+    "‘A likely story indeed!’ said the Pigeon in a tone of the deepest",
+    "contempt. ‘I’ve seen a good many little girls in my time, but never ONE",
+    "with such a neck as that! No, no! You’re a serpent; and there’s no use",
+    "denying it. I suppose you’ll be telling me next that you never tasted an",
+    "egg!’",
+    "‘I HAVE tasted eggs, certainly,’ said Alice, who was a very truthful",
+    "child; ‘but little girls eat eggs quite as much as serpents do, you",
+    "know.’",
+    "‘I don’t believe it,’ said the Pigeon; ‘but if they do, why then they’re",
+    "a kind of serpent, that’s all I can say.’",
+    "This was such a new idea to Alice, that she was quite silent for a",
+    "minute or two, which gave the Pigeon the opportunity of adding, ‘You’re",
+    "looking for eggs, I know THAT well enough; and what does it matter to me",
+    "whether you’re a little girl or a serpent?’",
+    "‘It matters a good deal to ME,’ said Alice hastily; ‘but I’m not looking",
+    "for eggs, as it happens; and if I was, I shouldn’t want YOURS: I don’t",
+    "like them raw.’",
+    "‘Well, be off, then!’ said the Pigeon in a sulky tone, as it settled",
+    "down again into its nest. Alice crouched down among the trees as well as",
+    "she could, for her neck kept getting entangled among the branches, and",
+    "every now and then she had to stop and untwist it. After a while she",
+    "remembered that she still held the pieces of mushroom in her hands, and",
+    "she set to work very carefully, nibbling first at one and then at the",
+    "other, and growing sometimes taller and sometimes shorter, until she had",
+    "succeeded in bringing herself down to her usual height.",
+    "It was so long since she had been anything near the right size, that it",
+    "felt quite strange at first; but she got used to it in a few minutes,",
+    "and began talking to herself, as usual. ‘Come, there’s half my plan done",
+    "now! How puzzling all these changes are! I’m never sure what I’m going",
+    "to be, from one minute to another! However, I’ve got back to my right",
+    "size: the next thing is, to get into that beautiful garden--how IS that",
+    "to be done, I wonder?’ As she said this, she came suddenly upon an open",
+    "place, with a little house in it about four feet high. ‘Whoever lives",
+    "there,’ thought Alice, ‘it’ll never do to come upon them THIS size: why,",
+    "I should frighten them out of their wits!’ So she began nibbling at the",
+    "righthand bit again, and did not venture to go near the house till she",
+    "had brought herself down to nine inches high.",
+    "CHAPTER VI. Pig and Pepper",
+    "For a minute or two she stood looking at the house, and wondering what",
+    "to do next, when suddenly a footman in livery came running out of the",
+    "wood--(she considered him to be a footman because he was in livery:",
+    "otherwise, judging by his face only, she would have called him a",
+    "fish)--and rapped loudly at the door with his knuckles. It was opened",
+    "by another footman in livery, with a round face, and large eyes like a",
+    "frog; and both footmen, Alice noticed, had powdered hair that curled all",
+    "over their heads. She felt very curious to know what it was all about,",
+    "and crept a little way out of the wood to listen.",
+    "The Fish-Footman began by producing from under his arm a great letter,",
+    "nearly as large as himself, and this he handed over to the other,",
+    "saying, in a solemn tone, ‘For the Duchess. An invitation from the Queen",
+    "to play croquet.’ The Frog-Footman repeated, in the same solemn tone,",
+    "only changing the order of the words a little, ‘From the Queen. An",
+    "invitation for the Duchess to play croquet.’",
+    "Then they both bowed low, and their curls got entangled together.",
+    "Alice laughed so much at this, that she had to run back into the",
+    "wood for fear of their hearing her; and when she next peeped out the",
+    "Fish-Footman was gone, and the other was sitting on the ground near the",
+    "door, staring stupidly up into the sky.",
+    "Alice went timidly up to the door, and knocked.",
+    "‘There’s no sort of use in knocking,’ said the Footman, ‘and that for",
+    "two reasons. First, because I’m on the same side of the door as you",
+    "are; secondly, because they’re making such a noise inside, no one could",
+    "possibly hear you.’ And certainly there was a most extraordinary noise",
+    "going on within--a constant howling and sneezing, and every now and then",
+    "a great crash, as if a dish or kettle had been broken to pieces.",
+    "‘Please, then,’ said Alice, ‘how am I to get in?’",
+    "‘There might be some sense in your knocking,’ the Footman went on",
+    "without attending to her, ‘if we had the door between us. For instance,",
+    "if you were INSIDE, you might knock, and I could let you out, you know.’",
+    "He was looking up into the sky all the time he was speaking, and this",
+    "Alice thought decidedly uncivil. ‘But perhaps he can’t help it,’ she",
+    "said to herself; ‘his eyes are so VERY nearly at the top of his head.",
+    "But at any rate he might answer questions.--How am I to get in?’ she",
+    "repeated, aloud.",
+    "‘I shall sit here,’ the Footman remarked, ‘till tomorrow--’",
+    "At this moment the door of the house opened, and a large plate came",
+    "skimming out, straight at the Footman’s head: it just grazed his nose,",
+    "and broke to pieces against one of the trees behind him.",
+    "‘--or next day, maybe,’ the Footman continued in the same tone, exactly",
+    "as if nothing had happened.",
+    "‘How am I to get in?’ asked Alice again, in a louder tone.",
+    "‘ARE you to get in at all?’ said the Footman. ‘That’s the first",
+    "question, you know.’",
+    "It was, no doubt: only Alice did not like to be told so. ‘It’s really",
+    "dreadful,’ she muttered to herself, ‘the way all the creatures argue.",
+    "It’s enough to drive one crazy!’",
+    "The Footman seemed to think this a good opportunity for repeating his",
+    "remark, with variations. ‘I shall sit here,’ he said, ‘on and off, for",
+    "days and days.’",
+    "‘But what am I to do?’ said Alice.",
+    "‘Anything you like,’ said the Footman, and began whistling.",
+    "‘Oh, there’s no use in talking to him,’ said Alice desperately: ‘he’s",
+    "perfectly idiotic!’ And she opened the door and went in.",
+    "The door led right into a large kitchen, which was full of smoke from",
+    "one end to the other: the Duchess was sitting on a three-legged stool in",
+    "the middle, nursing a baby; the cook was leaning over the fire, stirring",
+    "a large cauldron which seemed to be full of soup.",
+    "‘There’s certainly too much pepper in that soup!’ Alice said to herself,",
+    "as well as she could for sneezing.",
+    "There was certainly too much of it in the air. Even the Duchess",
+    "sneezed occasionally; and as for the baby, it was sneezing and howling",
+    "alternately without a moment’s pause. The only things in the kitchen",
+    "that did not sneeze, were the cook, and a large cat which was sitting on",
+    "the hearth and grinning from ear to ear.",
+    "‘Please would you tell me,’ said Alice, a little timidly, for she was",
+    "not quite sure whether it was good manners for her to speak first, ‘why",
+    "your cat grins like that?’",
+    "‘It’s a Cheshire cat,’ said the Duchess, ‘and that’s why. Pig!’",
+    "She said the last word with such sudden violence that Alice quite",
+    "jumped; but she saw in another moment that it was addressed to the baby,",
+    "and not to her, so she took courage, and went on again:--",
+    "‘I didn’t know that Cheshire cats always grinned; in fact, I didn’t know",
+    "that cats COULD grin.’",
+    "‘They all can,’ said the Duchess; ‘and most of ‘em do.’",
+    "‘I don’t know of any that do,’ Alice said very politely, feeling quite",
+    "pleased to have got into a conversation.",
+    "‘You don’t know much,’ said the Duchess; ‘and that’s a fact.’",
+    "Alice did not at all like the tone of this remark, and thought it would",
+    "be as well to introduce some other subject of conversation. While she",
+    "was trying to fix on one, the cook took the cauldron of soup off the",
+    "fire, and at once set to work throwing everything within her reach at",
+    "the Duchess and the baby--the fire-irons came first; then followed a",
+    "shower of saucepans, plates, and dishes. The Duchess took no notice of",
+    "them even when they hit her; and the baby was howling so much already,",
+    "that it was quite impossible to say whether the blows hurt it or not.",
+    "‘Oh, PLEASE mind what you’re doing!’ cried Alice, jumping up and down in",
+    "an agony of terror. ‘Oh, there goes his PRECIOUS nose’; as an unusually",
+    "large saucepan flew close by it, and very nearly carried it off.",
+    "‘If everybody minded their own business,’ the Duchess said in a hoarse",
+    "growl, ‘the world would go round a deal faster than it does.’",
+    "‘Which would NOT be an advantage,’ said Alice, who felt very glad to get",
+    "an opportunity of showing off a little of her knowledge. ‘Just think of",
+    "what work it would make with the day and night! You see the earth takes",
+    "twenty-four hours to turn round on its axis--’",
+    "‘Talking of axes,’ said the Duchess, ‘chop off her head!’",
+    "Alice glanced rather anxiously at the cook, to see if she meant to take",
+    "the hint; but the cook was busily stirring the soup, and seemed not to",
+    "be listening, so she went on again: ‘Twenty-four hours, I THINK; or is",
+    "it twelve? I--’",
+    "‘Oh, don’t bother ME,’ said the Duchess; ‘I never could abide figures!’",
+    "And with that she began nursing her child again, singing a sort of",
+    "lullaby to it as she did so, and giving it a violent shake at the end of",
+    "every line:",
+    "   ‘Speak roughly to your little boy,",
+    "    And beat him when he sneezes:",
+    "   He only does it to annoy,",
+    "    Because he knows it teases.’",
+    "         CHORUS.",
+    " (In which the cook and the baby joined):--",
+    "       ‘Wow! wow! wow!’",
+    "While the Duchess sang the second verse of the song, she kept tossing",
+    "the baby violently up and down, and the poor little thing howled so,",
+    "that Alice could hardly hear the words:--",
+    "   ‘I speak severely to my boy,",
+    "    I beat him when he sneezes;",
+    "   For he can thoroughly enjoy",
+    "    The pepper when he pleases!’",
+    "         CHORUS.",
+    "       ‘Wow! wow! wow!’",
+    "‘Here! you may nurse it a bit, if you like!’ the Duchess said to Alice,",
+    "flinging the baby at her as she spoke. ‘I must go and get ready to play",
+    "croquet with the Queen,’ and she hurried out of the room. The cook threw",
+    "a frying-pan after her as she went out, but it just missed her.",
+    "Alice caught the baby with some difficulty, as it was a queer-shaped",
+    "little creature, and held out its arms and legs in all directions, ‘just",
+    "like a star-fish,’ thought Alice. The poor little thing was snorting",
+    "like a steam-engine when she caught it, and kept doubling itself up and",
+    "straightening itself out again, so that altogether, for the first minute",
+    "or two, it was as much as she could do to hold it.",
+    "As soon as she had made out the proper way of nursing it, (which was to",
+    "twist it up into a sort of knot, and then keep tight hold of its right",
+    "ear and left foot, so as to prevent its undoing itself,) she carried",
+    "it out into the open air. ‘IF I don’t take this child away with me,’",
+    "thought Alice, ‘they’re sure to kill it in a day or two: wouldn’t it be",
+    "murder to leave it behind?’ She said the last words out loud, and the",
+    "little thing grunted in reply (it had left off sneezing by this time).",
+    "‘Don’t grunt,’ said Alice; ‘that’s not at all a proper way of expressing",
+    "yourself.’",
+    "The baby grunted again, and Alice looked very anxiously into its face to",
+    "see what was the matter with it. There could be no doubt that it had",
+    "a VERY turn-up nose, much more like a snout than a real nose; also its",
+    "eyes were getting extremely small for a baby: altogether Alice did not",
+    "like the look of the thing at all. ‘But perhaps it was only sobbing,’",
+    "she thought, and looked into its eyes again, to see if there were any",
+    "tears.",
+    "No, there were no tears. ‘If you’re going to turn into a pig, my dear,’",
+    "said Alice, seriously, ‘I’ll have nothing more to do with you. Mind",
+    "now!’ The poor little thing sobbed again (or grunted, it was impossible",
+    "to say which), and they went on for some while in silence.",
+    "Alice was just beginning to think to herself, ‘Now, what am I to do with",
+    "this creature when I get it home?’ when it grunted again, so violently,",
+    "that she looked down into its face in some alarm. This time there could",
+    "be NO mistake about it: it was neither more nor less than a pig, and she",
+    "felt that it would be quite absurd for her to carry it further.",
+    "So she set the little creature down, and felt quite relieved to see",
+    "it trot away quietly into the wood. ‘If it had grown up,’ she said",
+    "to herself, ‘it would have made a dreadfully ugly child: but it makes",
+    "rather a handsome pig, I think.’ And she began thinking over other",
+    "children she knew, who might do very well as pigs, and was just saying",
+    "to herself, ‘if one only knew the right way to change them--’ when she",
+    "was a little startled by seeing the Cheshire Cat sitting on a bough of a",
+    "tree a few yards off.",
+    "The Cat only grinned when it saw Alice. It looked good-natured, she",
+    "thought: still it had VERY long claws and a great many teeth, so she",
+    "felt that it ought to be treated with respect.",
+    "‘Cheshire Puss,’ she began, rather timidly, as she did not at all know",
+    "whether it would like the name: however, it only grinned a little wider.",
+    "‘Come, it’s pleased so far,’ thought Alice, and she went on. ‘Would you",
+    "tell me, please, which way I ought to go from here?’",
+    "‘That depends a good deal on where you want to get to,’ said the Cat.",
+    "‘I don’t much care where--’ said Alice.",
+    "‘Then it doesn’t matter which way you go,’ said the Cat.",
+    "‘--so long as I get SOMEWHERE,’ Alice added as an explanation.",
+    "‘Oh, you’re sure to do that,’ said the Cat, ‘if you only walk long",
+    "enough.’",
+    "Alice felt that this could not be denied, so she tried another question.",
+    "‘What sort of people live about here?’",
+    "‘In THAT direction,’ the Cat said, waving its right paw round, ‘lives",
+    "a Hatter: and in THAT direction,’ waving the other paw, ‘lives a March",
+    "Hare. Visit either you like: they’re both mad.’",
+    "‘But I don’t want to go among mad people,’ Alice remarked.",
+    "‘Oh, you can’t help that,’ said the Cat: ‘we’re all mad here. I’m mad.",
+    "You’re mad.’",
+    "‘How do you know I’m mad?’ said Alice.",
+    "‘You must be,’ said the Cat, ‘or you wouldn’t have come here.’",
+    "Alice didn’t think that proved it at all; however, she went on ‘And how",
+    "do you know that you’re mad?’",
+    "‘To begin with,’ said the Cat, ‘a dog’s not mad. You grant that?’",
+    "‘I suppose so,’ said Alice.",
+    "‘Well, then,’ the Cat went on, ‘you see, a dog growls when it’s angry,",
+    "and wags its tail when it’s pleased. Now I growl when I’m pleased, and",
+    "wag my tail when I’m angry. Therefore I’m mad.’",
+    "‘I call it purring, not growling,’ said Alice.",
+    "‘Call it what you like,’ said the Cat. ‘Do you play croquet with the",
+    "Queen to-day?’",
+    "‘I should like it very much,’ said Alice, ‘but I haven’t been invited",
+    "yet.’",
+    "‘You’ll see me there,’ said the Cat, and vanished.",
+    "Alice was not much surprised at this, she was getting so used to queer",
+    "things happening. While she was looking at the place where it had been,",
+    "it suddenly appeared again.",
+    "‘By-the-bye, what became of the baby?’ said the Cat. ‘I’d nearly",
+    "forgotten to ask.’",
+    "‘It turned into a pig,’ Alice quietly said, just as if it had come back",
+    "in a natural way.",
+    "‘I thought it would,’ said the Cat, and vanished again.",
+    "Alice waited a little, half expecting to see it again, but it did not",
+    "appear, and after a minute or two she walked on in the direction in",
+    "which the March Hare was said to live. ‘I’ve seen hatters before,’ she",
+    "said to herself; ‘the March Hare will be much the most interesting, and",
+    "perhaps as this is May it won’t be raving mad--at least not so mad as",
+    "it was in March.’ As she said this, she looked up, and there was the Cat",
+    "again, sitting on a branch of a tree.",
+    "‘Did you say pig, or fig?’ said the Cat.",
+    "‘I said pig,’ replied Alice; ‘and I wish you wouldn’t keep appearing and",
+    "vanishing so suddenly: you make one quite giddy.’",
+    "‘All right,’ said the Cat; and this time it vanished quite slowly,",
+    "beginning with the end of the tail, and ending with the grin, which",
+    "remained some time after the rest of it had gone.",
+    "‘Well! I’ve often seen a cat without a grin,’ thought Alice; ‘but a grin",
+    "without a cat! It’s the most curious thing I ever saw in my life!’",
+    "She had not gone much farther before she came in sight of the house",
+    "of the March Hare: she thought it must be the right house, because the",
+    "chimneys were shaped like ears and the roof was thatched with fur. It",
+    "was so large a house, that she did not like to go nearer till she had",
+    "nibbled some more of the lefthand bit of mushroom, and raised herself to",
+    "about two feet high: even then she walked up towards it rather timidly,",
+    "saying to herself ‘Suppose it should be raving mad after all! I almost",
+    "wish I’d gone to see the Hatter instead!’",
+    "CHAPTER VII. A Mad Tea-Party",
+    "There was a table set out under a tree in front of the house, and the",
+    "March Hare and the Hatter were having tea at it: a Dormouse was sitting",
+    "between them, fast asleep, and the other two were using it as a",
+    "cushion, resting their elbows on it, and talking over its head. ‘Very",
+    "uncomfortable for the Dormouse,’ thought Alice; ‘only, as it’s asleep, I",
+    "suppose it doesn’t mind.’",
+    "The table was a large one, but the three were all crowded together at",
+    "one corner of it: ‘No room! No room!’ they cried out when they saw Alice",
+    "coming. ‘There’s PLENTY of room!’ said Alice indignantly, and she sat",
+    "down in a large arm-chair at one end of the table.",
+    "‘Have some wine,’ the March Hare said in an encouraging tone.",
+    "Alice looked all round the table, but there was nothing on it but tea.",
+    "‘I don’t see any wine,’ she remarked.",
+    "‘There isn’t any,’ said the March Hare.",
+    "‘Then it wasn’t very civil of you to offer it,’ said Alice angrily.",
+    "‘It wasn’t very civil of you to sit down without being invited,’ said",
+    "the March Hare.",
+    "‘I didn’t know it was YOUR table,’ said Alice; ‘it’s laid for a great",
+    "many more than three.’",
+    "‘Your hair wants cutting,’ said the Hatter. He had been looking at Alice",
+    "for some time with great curiosity, and this was his first speech.",
+    "‘You should learn not to make personal remarks,’ Alice said with some",
+    "severity; ‘it’s very rude.’",
+    "The Hatter opened his eyes very wide on hearing this; but all he SAID",
+    "was, ‘Why is a raven like a writing-desk?’",
+    "‘Come, we shall have some fun now!’ thought Alice. ‘I’m glad they’ve",
+    "begun asking riddles.--I believe I can guess that,’ she added aloud.",
+    "‘Do you mean that you think you can find out the answer to it?’ said the",
+    "March Hare.",
+    "‘Exactly so,’ said Alice.",
+    "‘Then you should say what you mean,’ the March Hare went on.",
+    "‘I do,’ Alice hastily replied; ‘at least--at least I mean what I",
+    "say--that’s the same thing, you know.’",
+    "‘Not the same thing a bit!’ said the Hatter. ‘You might just as well say",
+    "that “I see what I eat” is the same thing as “I eat what I see”!’",
+    "‘You might just as well say,’ added the March Hare, ‘that “I like what I",
+    "get” is the same thing as “I get what I like”!’",
+    "‘You might just as well say,’ added the Dormouse, who seemed to be",
+    "talking in his sleep, ‘that “I breathe when I sleep” is the same thing",
+    "as “I sleep when I breathe”!’",
+    "‘It IS the same thing with you,’ said the Hatter, and here the",
+    "conversation dropped, and the party sat silent for a minute, while Alice",
+    "thought over all she could remember about ravens and writing-desks,",
+    "which wasn’t much.",
+    "The Hatter was the first to break the silence. ‘What day of the month",
+    "is it?’ he said, turning to Alice: he had taken his watch out of his",
+    "pocket, and was looking at it uneasily, shaking it every now and then,",
+    "and holding it to his ear.",
+    "Alice considered a little, and then said ‘The fourth.’",
+    "‘Two days wrong!’ sighed the Hatter. ‘I told you butter wouldn’t suit",
+    "the works!’ he added looking angrily at the March Hare.",
+    "‘It was the BEST butter,’ the March Hare meekly replied.",
+    "‘Yes, but some crumbs must have got in as well,’ the Hatter grumbled:",
+    "‘you shouldn’t have put it in with the bread-knife.’",
+    "The March Hare took the watch and looked at it gloomily: then he dipped",
+    "it into his cup of tea, and looked at it again: but he could think of",
+    "nothing better to say than his first remark, ‘It was the BEST butter,",
+    "you know.’",
+    "Alice had been looking over his shoulder with some curiosity. ‘What a",
+    "funny watch!’ she remarked. ‘It tells the day of the month, and doesn’t",
+    "tell what o’clock it is!’",
+    "‘Why should it?’ muttered the Hatter. ‘Does YOUR watch tell you what",
+    "year it is?’",
+    "‘Of course not,’ Alice replied very readily: ‘but that’s because it",
+    "stays the same year for such a long time together.’",
+    "‘Which is just the case with MINE,’ said the Hatter.",
+    "Alice felt dreadfully puzzled. The Hatter’s remark seemed to have no",
+    "sort of meaning in it, and yet it was certainly English. ‘I don’t quite",
+    "understand you,’ she said, as politely as she could.",
+    "‘The Dormouse is asleep again,’ said the Hatter, and he poured a little",
+    "hot tea upon its nose.",
+    "The Dormouse shook its head impatiently, and said, without opening its",
+    "eyes, ‘Of course, of course; just what I was going to remark myself.’",
+    "‘Have you guessed the riddle yet?’ the Hatter said, turning to Alice",
+    "again.",
+    "‘No, I give it up,’ Alice replied: ‘what’s the answer?’",
+    "‘I haven’t the slightest idea,’ said the Hatter.",
+    "‘Nor I,’ said the March Hare.",
+    "Alice sighed wearily. ‘I think you might do something better with the",
+    "time,’ she said, ‘than waste it in asking riddles that have no answers.’",
+    "‘If you knew Time as well as I do,’ said the Hatter, ‘you wouldn’t talk",
+    "about wasting IT. It’s HIM.’",
+    "‘I don’t know what you mean,’ said Alice.",
+    "‘Of course you don’t!’ the Hatter said, tossing his head contemptuously.",
+    "‘I dare say you never even spoke to Time!’",
+    "‘Perhaps not,’ Alice cautiously replied: ‘but I know I have to beat time",
+    "when I learn music.’",
+    "‘Ah! that accounts for it,’ said the Hatter. ‘He won’t stand beating.",
+    "Now, if you only kept on good terms with him, he’d do almost anything",
+    "you liked with the clock. For instance, suppose it were nine o’clock in",
+    "the morning, just time to begin lessons: you’d only have to whisper a",
+    "hint to Time, and round goes the clock in a twinkling! Half-past one,",
+    "time for dinner!’",
+    "[‘I only wish it was,’ the March Hare said to itself in a whisper.)",
+    "‘That would be grand, certainly,’ said Alice thoughtfully: ‘but then--I",
+    "shouldn’t be hungry for it, you know.’",
+    "‘Not at first, perhaps,’ said the Hatter: ‘but you could keep it to",
+    "half-past one as long as you liked.’",
+    "‘Is that the way YOU manage?’ Alice asked.",
+    "The Hatter shook his head mournfully. ‘Not I!’ he replied. ‘We",
+    "quarrelled last March--just before HE went mad, you know--’ (pointing",
+    "with his tea spoon at the March Hare,) ‘--it was at the great concert",
+    "given by the Queen of Hearts, and I had to sing",
+    "     “Twinkle, twinkle, little bat!",
+    "     How I wonder what you’re at!”",
+    "You know the song, perhaps?’",
+    "‘I’ve heard something like it,’ said Alice.",
+    "‘It goes on, you know,’ the Hatter continued, ‘in this way:--",
+    "     “Up above the world you fly,",
+    "     Like a tea-tray in the sky.",
+    "         Twinkle, twinkle--“’",
+    "Here the Dormouse shook itself, and began singing in its sleep ‘Twinkle,",
+    "twinkle, twinkle, twinkle--’ and went on so long that they had to pinch",
+    "it to make it stop.",
+    "‘Well, I’d hardly finished the first verse,’ said the Hatter, ‘when the",
+    "Queen jumped up and bawled out, “He’s murdering the time! Off with his",
+    "head!”’",
+    "‘How dreadfully savage!’ exclaimed Alice.",
+    "‘And ever since that,’ the Hatter went on in a mournful tone, ‘he won’t",
+    "do a thing I ask! It’s always six o’clock now.’",
+    "A bright idea came into Alice’s head. ‘Is that the reason so many",
+    "tea-things are put out here?’ she asked.",
+    "‘Yes, that’s it,’ said the Hatter with a sigh: ‘it’s always tea-time,",
+    "and we’ve no time to wash the things between whiles.’",
+    "‘Then you keep moving round, I suppose?’ said Alice.",
+    "‘Exactly so,’ said the Hatter: ‘as the things get used up.’",
+    "‘But what happens when you come to the beginning again?’ Alice ventured",
+    "to ask.",
+    "‘Suppose we change the subject,’ the March Hare interrupted, yawning.",
+    "‘I’m getting tired of this. I vote the young lady tells us a story.’",
+    "‘I’m afraid I don’t know one,’ said Alice, rather alarmed at the",
+    "proposal.",
+    "‘Then the Dormouse shall!’ they both cried. ‘Wake up, Dormouse!’ And",
+    "they pinched it on both sides at once.",
+    "The Dormouse slowly opened his eyes. ‘I wasn’t asleep,’ he said in a",
+    "hoarse, feeble voice: ‘I heard every word you fellows were saying.’",
+    "‘Tell us a story!’ said the March Hare.",
+    "‘Yes, please do!’ pleaded Alice.",
+    "‘And be quick about it,’ added the Hatter, ‘or you’ll be asleep again",
+    "before it’s done.’",
+    "‘Once upon a time there were three little sisters,’ the Dormouse began",
+    "in a great hurry; ‘and their names were Elsie, Lacie, and Tillie; and",
+    "they lived at the bottom of a well--’",
+    "‘What did they live on?’ said Alice, who always took a great interest in",
+    "questions of eating and drinking.",
+    "‘They lived on treacle,’ said the Dormouse, after thinking a minute or",
+    "two.",
+    "‘They couldn’t have done that, you know,’ Alice gently remarked; ‘they’d",
+    "have been ill.’",
+    "‘So they were,’ said the Dormouse; ‘VERY ill.’",
+    "Alice tried to fancy to herself what such an extraordinary ways of",
+    "living would be like, but it puzzled her too much, so she went on: ‘But",
+    "why did they live at the bottom of a well?’",
+    "‘Take some more tea,’ the March Hare said to Alice, very earnestly.",
+    "‘I’ve had nothing yet,’ Alice replied in an offended tone, ‘so I can’t",
+    "take more.’",
+    "‘You mean you can’t take LESS,’ said the Hatter: ‘it’s very easy to take",
+    "MORE than nothing.’",
+    "‘Nobody asked YOUR opinion,’ said Alice.",
+    "‘Who’s making personal remarks now?’ the Hatter asked triumphantly.",
+    "Alice did not quite know what to say to this: so she helped herself",
+    "to some tea and bread-and-butter, and then turned to the Dormouse, and",
+    "repeated her question. ‘Why did they live at the bottom of a well?’",
+    "The Dormouse again took a minute or two to think about it, and then",
+    "said, ‘It was a treacle-well.’",
+    "‘There’s no such thing!’ Alice was beginning very angrily, but the",
+    "Hatter and the March Hare went ‘Sh! sh!’ and the Dormouse sulkily",
+    "remarked, ‘If you can’t be civil, you’d better finish the story for",
+    "yourself.’",
+    "‘No, please go on!’ Alice said very humbly; ‘I won’t interrupt again. I",
+    "dare say there may be ONE.’",
+    "‘One, indeed!’ said the Dormouse indignantly. However, he consented to",
+    "go on. ‘And so these three little sisters--they were learning to draw,",
+    "you know--’",
+    "‘What did they draw?’ said Alice, quite forgetting her promise.",
+    "‘Treacle,’ said the Dormouse, without considering at all this time.",
+    "‘I want a clean cup,’ interrupted the Hatter: ‘let’s all move one place",
+    "on.’",
+    "He moved on as he spoke, and the Dormouse followed him: the March Hare",
+    "moved into the Dormouse’s place, and Alice rather unwillingly took",
+    "the place of the March Hare. The Hatter was the only one who got any",
+    "advantage from the change: and Alice was a good deal worse off than",
+    "before, as the March Hare had just upset the milk-jug into his plate.",
+    "Alice did not wish to offend the Dormouse again, so she began very",
+    "cautiously: ‘But I don’t understand. Where did they draw the treacle",
+    "from?’",
+    "‘You can draw water out of a water-well,’ said the Hatter; ‘so I should",
+    "think you could draw treacle out of a treacle-well--eh, stupid?’",
+    "‘But they were IN the well,’ Alice said to the Dormouse, not choosing to",
+    "notice this last remark.",
+    "‘Of course they were’, said the Dormouse; ‘--well in.’",
+    "This answer so confused poor Alice, that she let the Dormouse go on for",
+    "some time without interrupting it.",
+    "‘They were learning to draw,’ the Dormouse went on, yawning and rubbing",
+    "its eyes, for it was getting very sleepy; ‘and they drew all manner of",
+    "things--everything that begins with an M--’",
+    "‘Why with an M?’ said Alice.",
+    "‘Why not?’ said the March Hare.",
+    "Alice was silent.",
+    "The Dormouse had closed its eyes by this time, and was going off into",
+    "a doze; but, on being pinched by the Hatter, it woke up again with",
+    "a little shriek, and went on: ‘--that begins with an M, such as",
+    "mouse-traps, and the moon, and memory, and muchness--you know you say",
+    "things are “much of a muchness”--did you ever see such a thing as a",
+    "drawing of a muchness?’",
+    "‘Really, now you ask me,’ said Alice, very much confused, ‘I don’t",
+    "think--’",
+    "‘Then you shouldn’t talk,’ said the Hatter.",
+    "This piece of rudeness was more than Alice could bear: she got up in",
+    "great disgust, and walked off; the Dormouse fell asleep instantly, and",
+    "neither of the others took the least notice of her going, though she",
+    "looked back once or twice, half hoping that they would call after her:",
+    "the last time she saw them, they were trying to put the Dormouse into",
+    "the teapot.",
+    "‘At any rate I’ll never go THERE again!’ said Alice as she picked her",
+    "way through the wood. ‘It’s the stupidest tea-party I ever was at in all",
+    "my life!’",
+    "Just as she said this, she noticed that one of the trees had a door",
+    "leading right into it. ‘That’s very curious!’ she thought. ‘But",
+    "everything’s curious today. I think I may as well go in at once.’ And in",
+    "she went.",
+    "Once more she found herself in the long hall, and close to the little",
+    "glass table. ‘Now, I’ll manage better this time,’ she said to herself,",
+    "and began by taking the little golden key, and unlocking the door that",
+    "led into the garden. Then she went to work nibbling at the mushroom (she",
+    "had kept a piece of it in her pocket) till she was about a foot high:",
+    "then she walked down the little passage: and THEN--she found herself at",
+    "last in the beautiful garden, among the bright flower-beds and the cool",
+    "fountains.",
+    "CHAPTER VIII. The Queen’s Croquet-Ground",
+    "A large rose-tree stood near the entrance of the garden: the roses",
+    "growing on it were white, but there were three gardeners at it, busily",
+    "painting them red. Alice thought this a very curious thing, and she went",
+    "nearer to watch them, and just as she came up to them she heard one of",
+    "them say, ‘Look out now, Five! Don’t go splashing paint over me like",
+    "that!’",
+    "‘I couldn’t help it,’ said Five, in a sulky tone; ‘Seven jogged my",
+    "elbow.’",
+    "On which Seven looked up and said, ‘That’s right, Five! Always lay the",
+    "blame on others!’",
+    "‘YOU’D better not talk!’ said Five. ‘I heard the Queen say only",
+    "yesterday you deserved to be beheaded!’",
+    "‘What for?’ said the one who had spoken first.",
+    "‘That’s none of YOUR business, Two!’ said Seven.",
+    "‘Yes, it IS his business!’ said Five, ‘and I’ll tell him--it was for",
+    "bringing the cook tulip-roots instead of onions.’",
+    "Seven flung down his brush, and had just begun ‘Well, of all the unjust",
+    "things--’ when his eye chanced to fall upon Alice, as she stood watching",
+    "them, and he checked himself suddenly: the others looked round also, and",
+    "all of them bowed low.",
+    "‘Would you tell me,’ said Alice, a little timidly, ‘why you are painting",
+    "those roses?’",
+    "Five and Seven said nothing, but looked at Two. Two began in a low",
+    "voice, ‘Why the fact is, you see, Miss, this here ought to have been a",
+    "RED rose-tree, and we put a white one in by mistake; and if the Queen",
+    "was to find it out, we should all have our heads cut off, you know.",
+    "So you see, Miss, we’re doing our best, afore she comes, to--’ At this",
+    "moment Five, who had been anxiously looking across the garden, called",
+    "out ‘The Queen! The Queen!’ and the three gardeners instantly threw",
+    "themselves flat upon their faces. There was a sound of many footsteps,",
+    "and Alice looked round, eager to see the Queen.",
+    "First came ten soldiers carrying clubs; these were all shaped like",
+    "the three gardeners, oblong and flat, with their hands and feet at the",
+    "corners: next the ten courtiers; these were ornamented all over with",
+    "diamonds, and walked two and two, as the soldiers did. After these came",
+    "the royal children; there were ten of them, and the little dears came",
+    "jumping merrily along hand in hand, in couples: they were all ornamented",
+    "with hearts. Next came the guests, mostly Kings and Queens, and among",
+    "them Alice recognised the White Rabbit: it was talking in a hurried",
+    "nervous manner, smiling at everything that was said, and went by without",
+    "noticing her. Then followed the Knave of Hearts, carrying the King’s",
+    "crown on a crimson velvet cushion; and, last of all this grand",
+    "procession, came THE KING AND QUEEN OF HEARTS.",
+    "Alice was rather doubtful whether she ought not to lie down on her face",
+    "like the three gardeners, but she could not remember ever having heard",
+    "of such a rule at processions; ‘and besides, what would be the use of",
+    "a procession,’ thought she, ‘if people had all to lie down upon their",
+    "faces, so that they couldn’t see it?’ So she stood still where she was,",
+    "and waited.",
+    "When the procession came opposite to Alice, they all stopped and looked",
+    "at her, and the Queen said severely ‘Who is this?’ She said it to the",
+    "Knave of Hearts, who only bowed and smiled in reply.",
+    "‘Idiot!’ said the Queen, tossing her head impatiently; and, turning to",
+    "Alice, she went on, ‘What’s your name, child?’",
+    "‘My name is Alice, so please your Majesty,’ said Alice very politely;",
+    "but she added, to herself, ‘Why, they’re only a pack of cards, after",
+    "all. I needn’t be afraid of them!’",
+    "‘And who are THESE?’ said the Queen, pointing to the three gardeners who",
+    "were lying round the rosetree; for, you see, as they were lying on their",
+    "faces, and the pattern on their backs was the same as the rest of the",
+    "pack, she could not tell whether they were gardeners, or soldiers, or",
+    "courtiers, or three of her own children.",
+    "‘How should I know?’ said Alice, surprised at her own courage. ‘It’s no",
+    "business of MINE.’",
+    "The Queen turned crimson with fury, and, after glaring at her for a",
+    "moment like a wild beast, screamed ‘Off with her head! Off--’",
+    "‘Nonsense!’ said Alice, very loudly and decidedly, and the Queen was",
+    "silent.",
+    "The King laid his hand upon her arm, and timidly said ‘Consider, my",
+    "dear: she is only a child!’",
+    "The Queen turned angrily away from him, and said to the Knave ‘Turn them",
+    "over!’",
+    "The Knave did so, very carefully, with one foot.",
+    "‘Get up!’ said the Queen, in a shrill, loud voice, and the three",
+    "gardeners instantly jumped up, and began bowing to the King, the Queen,",
+    "the royal children, and everybody else.",
+    "‘Leave off that!’ screamed the Queen. ‘You make me giddy.’ And then,",
+    "turning to the rose-tree, she went on, ‘What HAVE you been doing here?’",
+    "‘May it please your Majesty,’ said Two, in a very humble tone, going",
+    "down on one knee as he spoke, ‘we were trying--’",
+    "‘I see!’ said the Queen, who had meanwhile been examining the roses.",
+    "‘Off with their heads!’ and the procession moved on, three of the",
+    "soldiers remaining behind to execute the unfortunate gardeners, who ran",
+    "to Alice for protection.",
+    "‘You shan’t be beheaded!’ said Alice, and she put them into a large",
+    "flower-pot that stood near. The three soldiers wandered about for a",
+    "minute or two, looking for them, and then quietly marched off after the",
+    "others.",
+    "‘Are their heads off?’ shouted the Queen.",
+    "‘Their heads are gone, if it please your Majesty!’ the soldiers shouted",
+    "in reply.",
+    "‘That’s right!’ shouted the Queen. ‘Can you play croquet?’",
+    "The soldiers were silent, and looked at Alice, as the question was",
+    "evidently meant for her.",
+    "‘Yes!’ shouted Alice.",
+    "‘Come on, then!’ roared the Queen, and Alice joined the procession,",
+    "wondering very much what would happen next.",
+    "‘It’s--it’s a very fine day!’ said a timid voice at her side. She was",
+    "walking by the White Rabbit, who was peeping anxiously into her face.",
+    "‘Very,’ said Alice: ‘--where’s the Duchess?’",
+    "‘Hush! Hush!’ said the Rabbit in a low, hurried tone. He looked",
+    "anxiously over his shoulder as he spoke, and then raised himself upon",
+    "tiptoe, put his mouth close to her ear, and whispered ‘She’s under",
+    "sentence of execution.’",
+    "‘What for?’ said Alice.",
+    "‘Did you say “What a pity!”?’ the Rabbit asked.",
+    "‘No, I didn’t,’ said Alice: ‘I don’t think it’s at all a pity. I said",
+    "“What for?”’",
+    "‘She boxed the Queen’s ears--’ the Rabbit began. Alice gave a little",
+    "scream of laughter. ‘Oh, hush!’ the Rabbit whispered in a frightened",
+    "tone. ‘The Queen will hear you! You see, she came rather late, and the",
+    "Queen said--’",
+    "‘Get to your places!’ shouted the Queen in a voice of thunder, and",
+    "people began running about in all directions, tumbling up against each",
+    "other; however, they got settled down in a minute or two, and the game",
+    "began. Alice thought she had never seen such a curious croquet-ground in",
+    "her life; it was all ridges and furrows; the balls were live hedgehogs,",
+    "the mallets live flamingoes, and the soldiers had to double themselves",
+    "up and to stand on their hands and feet, to make the arches.",
+    "The chief difficulty Alice found at first was in managing her flamingo:",
+    "she succeeded in getting its body tucked away, comfortably enough, under",
+    "her arm, with its legs hanging down, but generally, just as she had got",
+    "its neck nicely straightened out, and was going to give the hedgehog a",
+    "blow with its head, it WOULD twist itself round and look up in her face,",
+    "with such a puzzled expression that she could not help bursting out",
+    "laughing: and when she had got its head down, and was going to begin",
+    "again, it was very provoking to find that the hedgehog had unrolled",
+    "itself, and was in the act of crawling away: besides all this, there was",
+    "generally a ridge or furrow in the way wherever she wanted to send the",
+    "hedgehog to, and, as the doubled-up soldiers were always getting up",
+    "and walking off to other parts of the ground, Alice soon came to the",
+    "conclusion that it was a very difficult game indeed.",
+    "The players all played at once without waiting for turns, quarrelling",
+    "all the while, and fighting for the hedgehogs; and in a very short",
+    "time the Queen was in a furious passion, and went stamping about, and",
+    "shouting ‘Off with his head!’ or ‘Off with her head!’ about once in a",
+    "minute.",
+    "Alice began to feel very uneasy: to be sure, she had not as yet had any",
+    "dispute with the Queen, but she knew that it might happen any minute,",
+    "‘and then,’ thought she, ‘what would become of me? They’re dreadfully",
+    "fond of beheading people here; the great wonder is, that there’s any one",
+    "left alive!’",
+    "She was looking about for some way of escape, and wondering whether she",
+    "could get away without being seen, when she noticed a curious appearance",
+    "in the air: it puzzled her very much at first, but, after watching it",
+    "a minute or two, she made it out to be a grin, and she said to herself",
+    "‘It’s the Cheshire Cat: now I shall have somebody to talk to.’",
+    "‘How are you getting on?’ said the Cat, as soon as there was mouth",
+    "enough for it to speak with.",
+    "Alice waited till the eyes appeared, and then nodded. ‘It’s no use",
+    "speaking to it,’ she thought, ‘till its ears have come, or at least one",
+    "of them.’ In another minute the whole head appeared, and then Alice put",
+    "down her flamingo, and began an account of the game, feeling very glad",
+    "she had someone to listen to her. The Cat seemed to think that there was",
+    "enough of it now in sight, and no more of it appeared.",
+    "‘I don’t think they play at all fairly,’ Alice began, in rather a",
+    "complaining tone, ‘and they all quarrel so dreadfully one can’t hear",
+    "oneself speak--and they don’t seem to have any rules in particular;",
+    "at least, if there are, nobody attends to them--and you’ve no idea how",
+    "confusing it is all the things being alive; for instance, there’s the",
+    "arch I’ve got to go through next walking about at the other end of the",
+    "ground--and I should have croqueted the Queen’s hedgehog just now, only",
+    "it ran away when it saw mine coming!’",
+    "‘How do you like the Queen?’ said the Cat in a low voice.",
+    "‘Not at all,’ said Alice: ‘she’s so extremely--’ Just then she noticed",
+    "that the Queen was close behind her, listening: so she went on,",
+    "‘--likely to win, that it’s hardly worth while finishing the game.’",
+    "The Queen smiled and passed on.",
+    "‘Who ARE you talking to?’ said the King, going up to Alice, and looking",
+    "at the Cat’s head with great curiosity.",
+    "‘It’s a friend of mine--a Cheshire Cat,’ said Alice: ‘allow me to",
+    "introduce it.’",
+    "‘I don’t like the look of it at all,’ said the King: ‘however, it may",
+    "kiss my hand if it likes.’",
+    "‘I’d rather not,’ the Cat remarked.",
+    "‘Don’t be impertinent,’ said the King, ‘and don’t look at me like that!’",
+    "He got behind Alice as he spoke.",
+    "‘A cat may look at a king,’ said Alice. ‘I’ve read that in some book,",
+    "but I don’t remember where.’",
+    "‘Well, it must be removed,’ said the King very decidedly, and he called",
+    "the Queen, who was passing at the moment, ‘My dear! I wish you would",
+    "have this cat removed!’",
+    "The Queen had only one way of settling all difficulties, great or small.",
+    "‘Off with his head!’ she said, without even looking round.",
+    "‘I’ll fetch the executioner myself,’ said the King eagerly, and he",
+    "hurried off.",
+    "Alice thought she might as well go back, and see how the game was going",
+    "on, as she heard the Queen’s voice in the distance, screaming with",
+    "passion. She had already heard her sentence three of the players to be",
+    "executed for having missed their turns, and she did not like the look",
+    "of things at all, as the game was in such confusion that she never knew",
+    "whether it was her turn or not. So she went in search of her hedgehog.",
+    "The hedgehog was engaged in a fight with another hedgehog, which seemed",
+    "to Alice an excellent opportunity for croqueting one of them with the",
+    "other: the only difficulty was, that her flamingo was gone across to the",
+    "other side of the garden, where Alice could see it trying in a helpless",
+    "sort of way to fly up into a tree.",
+    "By the time she had caught the flamingo and brought it back, the fight",
+    "was over, and both the hedgehogs were out of sight: ‘but it doesn’t",
+    "matter much,’ thought Alice, ‘as all the arches are gone from this side",
+    "of the ground.’ So she tucked it away under her arm, that it might not",
+    "escape again, and went back for a little more conversation with her",
+    "friend.",
+    "When she got back to the Cheshire Cat, she was surprised to find quite a",
+    "large crowd collected round it: there was a dispute going on between",
+    "the executioner, the King, and the Queen, who were all talking at once,",
+    "while all the rest were quite silent, and looked very uncomfortable.",
+    "The moment Alice appeared, she was appealed to by all three to settle",
+    "the question, and they repeated their arguments to her, though, as they",
+    "all spoke at once, she found it very hard indeed to make out exactly",
+    "what they said.",
+    "The executioner’s argument was, that you couldn’t cut off a head unless",
+    "there was a body to cut it off from: that he had never had to do such a",
+    "thing before, and he wasn’t going to begin at HIS time of life.",
+    "The King’s argument was, that anything that had a head could be",
+    "beheaded, and that you weren’t to talk nonsense.",
+    "The Queen’s argument was, that if something wasn’t done about it in less",
+    "than no time she’d have everybody executed, all round. (It was this last",
+    "remark that had made the whole party look so grave and anxious.)",
+    "Alice could think of nothing else to say but ‘It belongs to the Duchess:",
+    "you’d better ask HER about it.’",
+    "‘She’s in prison,’ the Queen said to the executioner: ‘fetch her here.’",
+    "And the executioner went off like an arrow.",
+    " The Cat’s head began fading away the moment he was gone, and,",
+    "by the time he had come back with the Duchess, it had entirely",
+    "disappeared; so the King and the executioner ran wildly up and down",
+    "looking for it, while the rest of the party went back to the game.",
+    "CHAPTER IX. The Mock Turtle’s Story",
+    "‘You can’t think how glad I am to see you again, you dear old thing!’",
+    "said the Duchess, as she tucked her arm affectionately into Alice’s, and",
+    "they walked off together.",
+    "Alice was very glad to find her in such a pleasant temper, and thought",
+    "to herself that perhaps it was only the pepper that had made her so",
+    "savage when they met in the kitchen.",
+    "‘When I’M a Duchess,’ she said to herself, (not in a very hopeful tone",
+    "though), ‘I won’t have any pepper in my kitchen AT ALL. Soup does very",
+    "well without--Maybe it’s always pepper that makes people hot-tempered,’",
+    "she went on, very much pleased at having found out a new kind of",
+    "rule, ‘and vinegar that makes them sour--and camomile that makes",
+    "them bitter--and--and barley-sugar and such things that make children",
+    "sweet-tempered. I only wish people knew that: then they wouldn’t be so",
+    "stingy about it, you know--’",
+    "She had quite forgotten the Duchess by this time, and was a little",
+    "startled when she heard her voice close to her ear. ‘You’re thinking",
+    "about something, my dear, and that makes you forget to talk. I can’t",
+    "tell you just now what the moral of that is, but I shall remember it in",
+    "a bit.’",
+    "‘Perhaps it hasn’t one,’ Alice ventured to remark.",
+    "‘Tut, tut, child!’ said the Duchess. ‘Everything’s got a moral, if only",
+    "you can find it.’ And she squeezed herself up closer to Alice’s side as",
+    "she spoke.",
+    "Alice did not much like keeping so close to her: first, because the",
+    "Duchess was VERY ugly; and secondly, because she was exactly the",
+    "right height to rest her chin upon Alice’s shoulder, and it was an",
+    "uncomfortably sharp chin. However, she did not like to be rude, so she",
+    "bore it as well as she could.",
+    "‘The game’s going on rather better now,’ she said, by way of keeping up",
+    "the conversation a little.",
+    "‘’Tis so,’ said the Duchess: ‘and the moral of that is--“Oh, ‘tis love,",
+    "‘tis love, that makes the world go round!”’",
+    "‘Somebody said,’ Alice whispered, ‘that it’s done by everybody minding",
+    "their own business!’",
+    "‘Ah, well! It means much the same thing,’ said the Duchess, digging her",
+    "sharp little chin into Alice’s shoulder as she added, ‘and the moral",
+    "of THAT is--“Take care of the sense, and the sounds will take care of",
+    "themselves.”’",
+    "‘How fond she is of finding morals in things!’ Alice thought to herself.",
+    "‘I dare say you’re wondering why I don’t put my arm round your waist,’",
+    "the Duchess said after a pause: ‘the reason is, that I’m doubtful about",
+    "the temper of your flamingo. Shall I try the experiment?’",
+    "‘HE might bite,’ Alice cautiously replied, not feeling at all anxious to",
+    "have the experiment tried.",
+    "‘Very true,’ said the Duchess: ‘flamingoes and mustard both bite. And",
+    "the moral of that is--“Birds of a feather flock together.”’",
+    "‘Only mustard isn’t a bird,’ Alice remarked.",
+    "‘Right, as usual,’ said the Duchess: ‘what a clear way you have of",
+    "putting things!’",
+    "‘It’s a mineral, I THINK,’ said Alice.",
+    "‘Of course it is,’ said the Duchess, who seemed ready to agree to",
+    "everything that Alice said; ‘there’s a large mustard-mine near here. And",
+    "the moral of that is--“The more there is of mine, the less there is of",
+    "yours.”’",
+    "‘Oh, I know!’ exclaimed Alice, who had not attended to this last remark,",
+    "‘it’s a vegetable. It doesn’t look like one, but it is.’",
+    "‘I quite agree with you,’ said the Duchess; ‘and the moral of that",
+    "is--“Be what you would seem to be”--or if you’d like it put more",
+    "simply--“Never imagine yourself not to be otherwise than what it might",
+    "appear to others that what you were or might have been was not otherwise",
+    "than what you had been would have appeared to them to be otherwise.”’",
+    "‘I think I should understand that better,’ Alice said very politely, ‘if",
+    "I had it written down: but I can’t quite follow it as you say it.’",
+    "‘That’s nothing to what I could say if I chose,’ the Duchess replied, in",
+    "a pleased tone.",
+    "‘Pray don’t trouble yourself to say it any longer than that,’ said",
+    "Alice.",
+    "‘Oh, don’t talk about trouble!’ said the Duchess. ‘I make you a present",
+    "of everything I’ve said as yet.’",
+    "‘A cheap sort of present!’ thought Alice. ‘I’m glad they don’t give",
+    "birthday presents like that!’ But she did not venture to say it out",
+    "loud.",
+    "‘Thinking again?’ the Duchess asked, with another dig of her sharp",
+    "little chin.",
+    "‘I’ve a right to think,’ said Alice sharply, for she was beginning to",
+    "feel a little worried.",
+    "‘Just about as much right,’ said the Duchess, ‘as pigs have to fly; and",
+    "the m--’",
+    "But here, to Alice’s great surprise, the Duchess’s voice died away, even",
+    "in the middle of her favourite word ‘moral,’ and the arm that was linked",
+    "into hers began to tremble. Alice looked up, and there stood the Queen",
+    "in front of them, with her arms folded, frowning like a thunderstorm.",
+    "‘A fine day, your Majesty!’ the Duchess began in a low, weak voice.",
+    "‘Now, I give you fair warning,’ shouted the Queen, stamping on the",
+    "ground as she spoke; ‘either you or your head must be off, and that in",
+    "about half no time! Take your choice!’",
+    "The Duchess took her choice, and was gone in a moment.",
+    "‘Let’s go on with the game,’ the Queen said to Alice; and Alice was",
+    "too much frightened to say a word, but slowly followed her back to the",
+    "croquet-ground.",
+    "The other guests had taken advantage of the Queen’s absence, and were",
+    "resting in the shade: however, the moment they saw her, they hurried",
+    "back to the game, the Queen merely remarking that a moment’s delay would",
+    "cost them their lives.",
+    "All the time they were playing the Queen never left off quarrelling with",
+    "the other players, and shouting ‘Off with his head!’ or ‘Off with her",
+    "head!’ Those whom she sentenced were taken into custody by the soldiers,",
+    "who of course had to leave off being arches to do this, so that by",
+    "the end of half an hour or so there were no arches left, and all the",
+    "players, except the King, the Queen, and Alice, were in custody and",
+    "under sentence of execution.",
+    "Then the Queen left off, quite out of breath, and said to Alice, ‘Have",
+    "you seen the Mock Turtle yet?’",
+    "‘No,’ said Alice. ‘I don’t even know what a Mock Turtle is.’",
+    "‘It’s the thing Mock Turtle Soup is made from,’ said the Queen.",
+    "‘I never saw one, or heard of one,’ said Alice.",
+    "‘Come on, then,’ said the Queen, ‘and he shall tell you his history,’",
+    "As they walked off together, Alice heard the King say in a low voice,",
+    "to the company generally, ‘You are all pardoned.’ ‘Come, THAT’S a good",
+    "thing!’ she said to herself, for she had felt quite unhappy at the",
+    "number of executions the Queen had ordered.",
+    "They very soon came upon a Gryphon, lying fast asleep in the sun.",
+    "(IF you don’t know what a Gryphon is, look at the picture.) ‘Up, lazy",
+    "thing!’ said the Queen, ‘and take this young lady to see the Mock",
+    "Turtle, and to hear his history. I must go back and see after some",
+    "executions I have ordered’; and she walked off, leaving Alice alone with",
+    "the Gryphon. Alice did not quite like the look of the creature, but on",
+    "the whole she thought it would be quite as safe to stay with it as to go",
+    "after that savage Queen: so she waited.",
+    "The Gryphon sat up and rubbed its eyes: then it watched the Queen till",
+    "she was out of sight: then it chuckled. ‘What fun!’ said the Gryphon,",
+    "half to itself, half to Alice.",
+    "‘What IS the fun?’ said Alice.",
+    "‘Why, SHE,’ said the Gryphon. ‘It’s all her fancy, that: they never",
+    "executes nobody, you know. Come on!’",
+    "‘Everybody says “come on!” here,’ thought Alice, as she went slowly",
+    "after it: ‘I never was so ordered about in all my life, never!’",
+    "They had not gone far before they saw the Mock Turtle in the distance,",
+    "sitting sad and lonely on a little ledge of rock, and, as they came",
+    "nearer, Alice could hear him sighing as if his heart would break. She",
+    "pitied him deeply. ‘What is his sorrow?’ she asked the Gryphon, and the",
+    "Gryphon answered, very nearly in the same words as before, ‘It’s all his",
+    "fancy, that: he hasn’t got no sorrow, you know. Come on!’",
+    "So they went up to the Mock Turtle, who looked at them with large eyes",
+    "full of tears, but said nothing.",
+    "‘This here young lady,’ said the Gryphon, ‘she wants for to know your",
+    "history, she do.’",
+    "‘I’ll tell it her,’ said the Mock Turtle in a deep, hollow tone: ‘sit",
+    "down, both of you, and don’t speak a word till I’ve finished.’",
+    "So they sat down, and nobody spoke for some minutes. Alice thought to",
+    "herself, ‘I don’t see how he can EVEN finish, if he doesn’t begin.’ But",
+    "she waited patiently.",
+    "‘Once,’ said the Mock Turtle at last, with a deep sigh, ‘I was a real",
+    "Turtle.’",
+    "These words were followed by a very long silence, broken only by an",
+    "occasional exclamation of ‘Hjckrrh!’ from the Gryphon, and the constant",
+    "heavy sobbing of the Mock Turtle. Alice was very nearly getting up and",
+    "saying, ‘Thank you, sir, for your interesting story,’ but she could",
+    "not help thinking there MUST be more to come, so she sat still and said",
+    "nothing.",
+    "‘When we were little,’ the Mock Turtle went on at last, more calmly,",
+    "though still sobbing a little now and then, ‘we went to school in the",
+    "sea. The master was an old Turtle--we used to call him Tortoise--’",
+    "‘Why did you call him Tortoise, if he wasn’t one?’ Alice asked.",
+    "‘We called him Tortoise because he taught us,’ said the Mock Turtle",
+    "angrily: ‘really you are very dull!’",
+    "‘You ought to be ashamed of yourself for asking such a simple question,’",
+    "added the Gryphon; and then they both sat silent and looked at poor",
+    "Alice, who felt ready to sink into the earth. At last the Gryphon said",
+    "to the Mock Turtle, ‘Drive on, old fellow! Don’t be all day about it!’",
+    "and he went on in these words:",
+    "‘Yes, we went to school in the sea, though you mayn’t believe it--’",
+    "‘I never said I didn’t!’ interrupted Alice.",
+    "‘You did,’ said the Mock Turtle.",
+    "‘Hold your tongue!’ added the Gryphon, before Alice could speak again.",
+    "The Mock Turtle went on.",
+    "‘We had the best of educations--in fact, we went to school every day--’",
+    "‘I’VE been to a day-school, too,’ said Alice; ‘you needn’t be so proud",
+    "as all that.’",
+    "‘With extras?’ asked the Mock Turtle a little anxiously.",
+    "‘Yes,’ said Alice, ‘we learned French and music.’",
+    "‘And washing?’ said the Mock Turtle.",
+    "‘Certainly not!’ said Alice indignantly.",
+    "‘Ah! then yours wasn’t a really good school,’ said the Mock Turtle in",
+    "a tone of great relief. ‘Now at OURS they had at the end of the bill,",
+    "“French, music, AND WASHING--extra.”’",
+    "‘You couldn’t have wanted it much,’ said Alice; ‘living at the bottom of",
+    "the sea.’",
+    "‘I couldn’t afford to learn it.’ said the Mock Turtle with a sigh. ‘I",
+    "only took the regular course.’",
+    "‘What was that?’ inquired Alice.",
+    "‘Reeling and Writhing, of course, to begin with,’ the Mock Turtle",
+    "replied; ‘and then the different branches of Arithmetic--Ambition,",
+    "Distraction, Uglification, and Derision.’",
+    "‘I never heard of “Uglification,”’ Alice ventured to say. ‘What is it?’",
+    "The Gryphon lifted up both its paws in surprise. ‘What! Never heard of",
+    "uglifying!’ it exclaimed. ‘You know what to beautify is, I suppose?’",
+    "‘Yes,’ said Alice doubtfully: ‘it means--to--make--anything--prettier.’",
+    "‘Well, then,’ the Gryphon went on, ‘if you don’t know what to uglify is,",
+    "you ARE a simpleton.’",
+    "Alice did not feel encouraged to ask any more questions about it, so she",
+    "turned to the Mock Turtle, and said ‘What else had you to learn?’",
+    "‘Well, there was Mystery,’ the Mock Turtle replied, counting off",
+    "the subjects on his flappers, ‘--Mystery, ancient and modern, with",
+    "Seaography: then Drawling--the Drawling-master was an old conger-eel,",
+    "that used to come once a week: HE taught us Drawling, Stretching, and",
+    "Fainting in Coils.’",
+    "‘What was THAT like?’ said Alice.",
+    "‘Well, I can’t show it you myself,’ the Mock Turtle said: ‘I’m too",
+    "stiff. And the Gryphon never learnt it.’",
+    "‘Hadn’t time,’ said the Gryphon: ‘I went to the Classics master, though.",
+    "He was an old crab, HE was.’",
+    "‘I never went to him,’ the Mock Turtle said with a sigh: ‘he taught",
+    "Laughing and Grief, they used to say.’",
+    "‘So he did, so he did,’ said the Gryphon, sighing in his turn; and both",
+    "creatures hid their faces in their paws.",
+    "‘And how many hours a day did you do lessons?’ said Alice, in a hurry to",
+    "change the subject.",
+    "‘Ten hours the first day,’ said the Mock Turtle: ‘nine the next, and so",
+    "on.’",
+    "‘What a curious plan!’ exclaimed Alice.",
+    "‘That’s the reason they’re called lessons,’ the Gryphon remarked:",
+    "‘because they lessen from day to day.’",
+    "This was quite a new idea to Alice, and she thought it over a little",
+    "before she made her next remark. ‘Then the eleventh day must have been a",
+    "holiday?’",
+    "‘Of course it was,’ said the Mock Turtle.",
+    "‘And how did you manage on the twelfth?’ Alice went on eagerly.",
+    "‘That’s enough about lessons,’ the Gryphon interrupted in a very decided",
+    "tone: ‘tell her something about the games now.’",
+    "CHAPTER X. The Lobster Quadrille",
+    "The Mock Turtle sighed deeply, and drew the back of one flapper across",
+    "his eyes. He looked at Alice, and tried to speak, but for a minute or",
+    "two sobs choked his voice. ‘Same as if he had a bone in his throat,’",
+    "said the Gryphon: and it set to work shaking him and punching him in",
+    "the back. At last the Mock Turtle recovered his voice, and, with tears",
+    "running down his cheeks, he went on again:--",
+    "‘You may not have lived much under the sea--’ [‘I haven’t,’ said",
+    "Alice)--‘and perhaps you were never even introduced to a lobster--’",
+    "(Alice began to say ‘I once tasted--’ but checked herself hastily, and",
+    "said ‘No, never’) ‘--so you can have no idea what a delightful thing a",
+    "Lobster Quadrille is!’",
+    "‘No, indeed,’ said Alice. ‘What sort of a dance is it?’",
+    "‘Why,’ said the Gryphon, ‘you first form into a line along the",
+    "sea-shore--’",
+    "‘Two lines!’ cried the Mock Turtle. ‘Seals, turtles, salmon, and so on;",
+    "then, when you’ve cleared all the jelly-fish out of the way--’",
+    "‘THAT generally takes some time,’ interrupted the Gryphon.",
+    "‘--you advance twice--’",
+    "‘Each with a lobster as a partner!’ cried the Gryphon.",
+    "‘Of course,’ the Mock Turtle said: ‘advance twice, set to partners--’",
+    "‘--change lobsters, and retire in same order,’ continued the Gryphon.",
+    "‘Then, you know,’ the Mock Turtle went on, ‘you throw the--’",
+    "‘The lobsters!’ shouted the Gryphon, with a bound into the air.",
+    "‘--as far out to sea as you can--’",
+    "‘Swim after them!’ screamed the Gryphon.",
+    "‘Turn a somersault in the sea!’ cried the Mock Turtle, capering wildly",
+    "about.",
+    "‘Change lobsters again!’ yelled the Gryphon at the top of its voice.",
+    "‘Back to land again, and that’s all the first figure,’ said the Mock",
+    "Turtle, suddenly dropping his voice; and the two creatures, who had been",
+    "jumping about like mad things all this time, sat down again very sadly",
+    "and quietly, and looked at Alice.",
+    "‘It must be a very pretty dance,’ said Alice timidly.",
+    "‘Would you like to see a little of it?’ said the Mock Turtle.",
+    "‘Very much indeed,’ said Alice.",
+    "‘Come, let’s try the first figure!’ said the Mock Turtle to the Gryphon.",
+    "‘We can do without lobsters, you know. Which shall sing?’",
+    "‘Oh, YOU sing,’ said the Gryphon. ‘I’ve forgotten the words.’",
+    "So they began solemnly dancing round and round Alice, every now and",
+    "then treading on her toes when they passed too close, and waving their",
+    "forepaws to mark the time, while the Mock Turtle sang this, very slowly",
+    "and sadly:--",
+    " ‘“Will you walk a little faster?” said a whiting to a snail.",
+    " “There’s a porpoise close behind us, and he’s treading on my tail.",
+    " See how eagerly the lobsters and the turtles all advance!",
+    " They are waiting on the shingle--will you come and join the dance?",
+    " Will you, won’t you, will you, won’t you, will you join the dance?",
+    " Will you, won’t you, will you, won’t you, won’t you join the dance?",
+    " “You can really have no notion how delightful it will be",
+    " When they take us up and throw us, with the lobsters, out to sea!”",
+    "  But the snail replied “Too far, too far!” and gave a look askance--",
+    " Said he thanked the whiting kindly, but he would not join the dance.",
+    " Would not, could not, would not, could not, would not join the dance.",
+    " Would not, could not, would not, could not, could not join the dance.",
+    " ‘“What matters it how far we go?” his scaly friend replied.",
+    " “There is another shore, you know, upon the other side.",
+    " The further off from England the nearer is to France--",
+    " Then turn not pale, beloved snail, but come and join the dance.",
+    " Will you, won’t you, will you, won’t you, will you join the dance?",
+    " Will you, won’t you, will you, won’t you, won’t you join the dance?”’",
+    "‘Thank you, it’s a very interesting dance to watch,’ said Alice, feeling",
+    "very glad that it was over at last: ‘and I do so like that curious song",
+    "about the whiting!’",
+    "‘Oh, as to the whiting,’ said the Mock Turtle, ‘they--you’ve seen them,",
+    "of course?’",
+    "‘Yes,’ said Alice, ‘I’ve often seen them at dinn--’ she checked herself",
+    "hastily.",
+    "‘I don’t know where Dinn may be,’ said the Mock Turtle, ‘but if you’ve",
+    "seen them so often, of course you know what they’re like.’",
+    "‘I believe so,’ Alice replied thoughtfully. ‘They have their tails in",
+    "their mouths--and they’re all over crumbs.’",
+    "‘You’re wrong about the crumbs,’ said the Mock Turtle: ‘crumbs would all",
+    "wash off in the sea. But they HAVE their tails in their mouths; and the",
+    "reason is--’ here the Mock Turtle yawned and shut his eyes.--‘Tell her",
+    "about the reason and all that,’ he said to the Gryphon.",
+    "‘The reason is,’ said the Gryphon, ‘that they WOULD go with the lobsters",
+    "to the dance. So they got thrown out to sea. So they had to fall a long",
+    "way. So they got their tails fast in their mouths. So they couldn’t get",
+    "them out again. That’s all.’",
+    "‘Thank you,’ said Alice, ‘it’s very interesting. I never knew so much",
+    "about a whiting before.’",
+    "‘I can tell you more than that, if you like,’ said the Gryphon. ‘Do you",
+    "know why it’s called a whiting?’",
+    "‘I never thought about it,’ said Alice. ‘Why?’",
+    "‘IT DOES THE BOOTS AND SHOES.’ the Gryphon replied very solemnly.",
+    "Alice was thoroughly puzzled. ‘Does the boots and shoes!’ she repeated",
+    "in a wondering tone.",
+    "‘Why, what are YOUR shoes done with?’ said the Gryphon. ‘I mean, what",
+    "makes them so shiny?’",
+    "Alice looked down at them, and considered a little before she gave her",
+    "answer. ‘They’re done with blacking, I believe.’",
+    "‘Boots and shoes under the sea,’ the Gryphon went on in a deep voice,",
+    "‘are done with a whiting. Now you know.’",
+    "‘And what are they made of?’ Alice asked in a tone of great curiosity.",
+    "‘Soles and eels, of course,’ the Gryphon replied rather impatiently:",
+    "‘any shrimp could have told you that.’",
+    "‘If I’d been the whiting,’ said Alice, whose thoughts were still running",
+    "on the song, ‘I’d have said to the porpoise, “Keep back, please: we",
+    "don’t want YOU with us!”’",
+    "‘They were obliged to have him with them,’ the Mock Turtle said: ‘no",
+    "wise fish would go anywhere without a porpoise.’",
+    "‘Wouldn’t it really?’ said Alice in a tone of great surprise.",
+    "‘Of course not,’ said the Mock Turtle: ‘why, if a fish came to ME, and",
+    "told me he was going a journey, I should say “With what porpoise?”’",
+    "‘Don’t you mean “purpose”?’ said Alice.",
+    "‘I mean what I say,’ the Mock Turtle replied in an offended tone. And",
+    "the Gryphon added ‘Come, let’s hear some of YOUR adventures.’",
+    "‘I could tell you my adventures--beginning from this morning,’ said",
+    "Alice a little timidly: ‘but it’s no use going back to yesterday,",
+    "because I was a different person then.’",
+    "‘Explain all that,’ said the Mock Turtle.",
+    "‘No, no! The adventures first,’ said the Gryphon in an impatient tone:",
+    "‘explanations take such a dreadful time.’",
+    "So Alice began telling them her adventures from the time when she first",
+    "saw the White Rabbit. She was a little nervous about it just at first,",
+    "the two creatures got so close to her, one on each side, and opened",
+    "their eyes and mouths so VERY wide, but she gained courage as she went",
+    "on. Her listeners were perfectly quiet till she got to the part about",
+    "her repeating ‘YOU ARE OLD, FATHER WILLIAM,’ to the Caterpillar, and the",
+    "words all coming different, and then the Mock Turtle drew a long breath,",
+    "and said ‘That’s very curious.’",
+    "‘It’s all about as curious as it can be,’ said the Gryphon.",
+    "‘It all came different!’ the Mock Turtle repeated thoughtfully. ‘I",
+    "should like to hear her try and repeat something now. Tell her to",
+    "begin.’ He looked at the Gryphon as if he thought it had some kind of",
+    "authority over Alice.",
+    "‘Stand up and repeat “‘TIS THE VOICE OF THE SLUGGARD,”’ said the",
+    "Gryphon.",
+    "‘How the creatures order one about, and make one repeat lessons!’",
+    "thought Alice; ‘I might as well be at school at once.’ However, she",
+    "got up, and began to repeat it, but her head was so full of the Lobster",
+    "Quadrille, that she hardly knew what she was saying, and the words came",
+    "very queer indeed:--",
+    "  ‘’Tis the voice of the Lobster; I heard him declare,",
+    "  “You have baked me too brown, I must sugar my hair.”",
+    "   As a duck with its eyelids, so he with his nose",
+    "  Trims his belt and his buttons, and turns out his toes.’",
+    "       [later editions continued as follows",
+    "  When the sands are all dry, he is gay as a lark,",
+    "  And will talk in contemptuous tones of the Shark,",
+    "  But, when the tide rises and sharks are around,",
+    "  His voice has a timid and tremulous sound.]",
+    "‘That’s different from what I used to say when I was a child,’ said the",
+    "Gryphon.",
+    "‘Well, I never heard it before,’ said the Mock Turtle; ‘but it sounds",
+    "uncommon nonsense.’",
+    "Alice said nothing; she had sat down with her face in her hands,",
+    "wondering if anything would EVER happen in a natural way again.",
+    "‘I should like to have it explained,’ said the Mock Turtle.",
+    "‘She can’t explain it,’ said the Gryphon hastily. ‘Go on with the next",
+    "verse.’",
+    "‘But about his toes?’ the Mock Turtle persisted. ‘How COULD he turn them",
+    "out with his nose, you know?’",
+    "‘It’s the first position in dancing.’ Alice said; but was dreadfully",
+    "puzzled by the whole thing, and longed to change the subject.",
+    "‘Go on with the next verse,’ the Gryphon repeated impatiently: ‘it",
+    "begins “I passed by his garden.”’",
+    "Alice did not dare to disobey, though she felt sure it would all come",
+    "wrong, and she went on in a trembling voice:--",
+    "  ‘I passed by his garden, and marked, with one eye,",
+    "  How the Owl and the Panther were sharing a pie--’",
+    "    [later editions continued as follows",
+    "  The Panther took pie-crust, and gravy, and meat,",
+    "  While the Owl had the dish as its share of the treat.",
+    "  When the pie was all finished, the Owl, as a boon,",
+    "  Was kindly permitted to pocket the spoon:",
+    "  While the Panther received knife and fork with a growl,",
+    "  And concluded the banquet--]",
+    "‘What IS the use of repeating all that stuff,’ the Mock Turtle",
+    "interrupted, ‘if you don’t explain it as you go on? It’s by far the most",
+    "confusing thing I ever heard!’",
+    "‘Yes, I think you’d better leave off,’ said the Gryphon: and Alice was",
+    "only too glad to do so.",
+    "‘Shall we try another figure of the Lobster Quadrille?’ the Gryphon went",
+    "on. ‘Or would you like the Mock Turtle to sing you a song?’",
+    "‘Oh, a song, please, if the Mock Turtle would be so kind,’ Alice",
+    "replied, so eagerly that the Gryphon said, in a rather offended tone,",
+    "‘Hm! No accounting for tastes! Sing her “Turtle Soup,” will you, old",
+    "fellow?’",
+    "The Mock Turtle sighed deeply, and began, in a voice sometimes choked",
+    "with sobs, to sing this:--",
+    "   ‘Beautiful Soup, so rich and green,",
+    "   Waiting in a hot tureen!",
+    "   Who for such dainties would not stoop?",
+    "   Soup of the evening, beautiful Soup!",
+    "   Soup of the evening, beautiful Soup!",
+    "     Beau--ootiful Soo--oop!",
+    "     Beau--ootiful Soo--oop!",
+    "   Soo--oop of the e--e--evening,",
+    "     Beautiful, beautiful Soup!",
+    "   ‘Beautiful Soup! Who cares for fish,",
+    "   Game, or any other dish?",
+    "   Who would not give all else for two",
+    "   Pennyworth only of beautiful Soup?",
+    "   Pennyworth only of beautiful Soup?",
+    "     Beau--ootiful Soo--oop!",
+    "     Beau--ootiful Soo--oop!",
+    "   Soo--oop of the e--e--evening,",
+    "     Beautiful, beauti--FUL SOUP!’",
+    "‘Chorus again!’ cried the Gryphon, and the Mock Turtle had just begun",
+    "to repeat it, when a cry of ‘The trial’s beginning!’ was heard in the",
+    "distance.",
+    "‘Come on!’ cried the Gryphon, and, taking Alice by the hand, it hurried",
+    "off, without waiting for the end of the song.",
+    "‘What trial is it?’ Alice panted as she ran; but the Gryphon only",
+    "answered ‘Come on!’ and ran the faster, while more and more faintly",
+    "came, carried on the breeze that followed them, the melancholy words:--",
+    "   ‘Soo--oop of the e--e--evening,",
+    "     Beautiful, beautiful Soup!’",
+    "CHAPTER XI. Who Stole the Tarts?",
+    "The King and Queen of Hearts were seated on their throne when they",
+    "arrived, with a great crowd assembled about them--all sorts of little",
+    "birds and beasts, as well as the whole pack of cards: the Knave was",
+    "standing before them, in chains, with a soldier on each side to guard",
+    "him; and near the King was the White Rabbit, with a trumpet in one hand,",
+    "and a scroll of parchment in the other. In the very middle of the court",
+    "was a table, with a large dish of tarts upon it: they looked so good,",
+    "that it made Alice quite hungry to look at them--‘I wish they’d get the",
+    "trial done,’ she thought, ‘and hand round the refreshments!’ But there",
+    "seemed to be no chance of this, so she began looking at everything about",
+    "her, to pass away the time.",
+    "Alice had never been in a court of justice before, but she had read",
+    "about them in books, and she was quite pleased to find that she knew",
+    "the name of nearly everything there. ‘That’s the judge,’ she said to",
+    "herself, ‘because of his great wig.’",
+    "The judge, by the way, was the King; and as he wore his crown over the",
+    "wig, (look at the frontispiece if you want to see how he did it,) he did",
+    "not look at all comfortable, and it was certainly not becoming.",
+    "‘And that’s the jury-box,’ thought Alice, ‘and those twelve creatures,’",
+    "(she was obliged to say ‘creatures,’ you see, because some of them were",
+    "animals, and some were birds,) ‘I suppose they are the jurors.’ She said",
+    "this last word two or three times over to herself, being rather proud of",
+    "it: for she thought, and rightly too, that very few little girls of her",
+    "age knew the meaning of it at all. However, ‘jury-men’ would have done",
+    "just as well.",
+    "The twelve jurors were all writing very busily on slates. ‘What are they",
+    "doing?’ Alice whispered to the Gryphon. ‘They can’t have anything to put",
+    "down yet, before the trial’s begun.’",
+    "‘They’re putting down their names,’ the Gryphon whispered in reply, ‘for",
+    "fear they should forget them before the end of the trial.’",
+    "‘Stupid things!’ Alice began in a loud, indignant voice, but she stopped",
+    "hastily, for the White Rabbit cried out, ‘Silence in the court!’ and the",
+    "King put on his spectacles and looked anxiously round, to make out who",
+    "was talking.",
+    "Alice could see, as well as if she were looking over their shoulders,",
+    "that all the jurors were writing down ‘stupid things!’ on their slates,",
+    "and she could even make out that one of them didn’t know how to spell",
+    "‘stupid,’ and that he had to ask his neighbour to tell him. ‘A nice",
+    "muddle their slates’ll be in before the trial’s over!’ thought Alice.",
+    "One of the jurors had a pencil that squeaked. This of course, Alice",
+    "could not stand, and she went round the court and got behind him, and",
+    "very soon found an opportunity of taking it away. She did it so quickly",
+    "that the poor little juror (it was Bill, the Lizard) could not make out",
+    "at all what had become of it; so, after hunting all about for it, he was",
+    "obliged to write with one finger for the rest of the day; and this was",
+    "of very little use, as it left no mark on the slate.",
+    "‘Herald, read the accusation!’ said the King.",
+    "On this the White Rabbit blew three blasts on the trumpet, and then",
+    "unrolled the parchment scroll, and read as follows:--",
+    "   ‘The Queen of Hearts, she made some tarts,",
+    "      All on a summer day:",
+    "    The Knave of Hearts, he stole those tarts,",
+    "      And took them quite away!’",
+    "‘Consider your verdict,’ the King said to the jury.",
+    "‘Not yet, not yet!’ the Rabbit hastily interrupted. ‘There’s a great",
+    "deal to come before that!’",
+    "‘Call the first witness,’ said the King; and the White Rabbit blew three",
+    "blasts on the trumpet, and called out, ‘First witness!’",
+    "The first witness was the Hatter. He came in with a teacup in one",
+    "hand and a piece of bread-and-butter in the other. ‘I beg pardon, your",
+    "Majesty,’ he began, ‘for bringing these in: but I hadn’t quite finished",
+    "my tea when I was sent for.’",
+    "‘You ought to have finished,’ said the King. ‘When did you begin?’",
+    "The Hatter looked at the March Hare, who had followed him into the",
+    "court, arm-in-arm with the Dormouse. ‘Fourteenth of March, I think it",
+    "was,’ he said.",
+    "‘Fifteenth,’ said the March Hare.",
+    "‘Sixteenth,’ added the Dormouse.",
+    "‘Write that down,’ the King said to the jury, and the jury eagerly",
+    "wrote down all three dates on their slates, and then added them up, and",
+    "reduced the answer to shillings and pence.",
+    "‘Take off your hat,’ the King said to the Hatter.",
+    "‘It isn’t mine,’ said the Hatter.",
+    "‘Stolen!’ the King exclaimed, turning to the jury, who instantly made a",
+    "memorandum of the fact.",
+    "‘I keep them to sell,’ the Hatter added as an explanation; ‘I’ve none of",
+    "my own. I’m a hatter.’",
+    "Here the Queen put on her spectacles, and began staring at the Hatter,",
+    "who turned pale and fidgeted.",
+    "‘Give your evidence,’ said the King; ‘and don’t be nervous, or I’ll have",
+    "you executed on the spot.’",
+    "This did not seem to encourage the witness at all: he kept shifting",
+    "from one foot to the other, looking uneasily at the Queen, and in",
+    "his confusion he bit a large piece out of his teacup instead of the",
+    "bread-and-butter.",
+    "Just at this moment Alice felt a very curious sensation, which puzzled",
+    "her a good deal until she made out what it was: she was beginning to",
+    "grow larger again, and she thought at first she would get up and leave",
+    "the court; but on second thoughts she decided to remain where she was as",
+    "long as there was room for her.",
+    "‘I wish you wouldn’t squeeze so.’ said the Dormouse, who was sitting",
+    "next to her. ‘I can hardly breathe.’",
+    "‘I can’t help it,’ said Alice very meekly: ‘I’m growing.’",
+    "‘You’ve no right to grow here,’ said the Dormouse.",
+    "‘Don’t talk nonsense,’ said Alice more boldly: ‘you know you’re growing",
+    "too.’",
+    "‘Yes, but I grow at a reasonable pace,’ said the Dormouse: ‘not in that",
+    "ridiculous fashion.’ And he got up very sulkily and crossed over to the",
+    "other side of the court.",
+    "All this time the Queen had never left off staring at the Hatter, and,",
+    "just as the Dormouse crossed the court, she said to one of the officers",
+    "of the court, ‘Bring me the list of the singers in the last concert!’ on",
+    "which the wretched Hatter trembled so, that he shook both his shoes off.",
+    "‘Give your evidence,’ the King repeated angrily, ‘or I’ll have you",
+    "executed, whether you’re nervous or not.’",
+    "‘I’m a poor man, your Majesty,’ the Hatter began, in a trembling voice,",
+    "‘--and I hadn’t begun my tea--not above a week or so--and what with the",
+    "bread-and-butter getting so thin--and the twinkling of the tea--’",
+    "‘The twinkling of the what?’ said the King.",
+    "‘It began with the tea,’ the Hatter replied.",
+    "‘Of course twinkling begins with a T!’ said the King sharply. ‘Do you",
+    "take me for a dunce? Go on!’",
+    "‘I’m a poor man,’ the Hatter went on, ‘and most things twinkled after",
+    "that--only the March Hare said--’",
+    "‘I didn’t!’ the March Hare interrupted in a great hurry.",
+    "‘You did!’ said the Hatter.",
+    "‘I deny it!’ said the March Hare.",
+    "‘He denies it,’ said the King: ‘leave out that part.’",
+    "‘Well, at any rate, the Dormouse said--’ the Hatter went on, looking",
+    "anxiously round to see if he would deny it too: but the Dormouse denied",
+    "nothing, being fast asleep.",
+    "‘After that,’ continued the Hatter, ‘I cut some more bread-and-butter--’",
+    "‘But what did the Dormouse say?’ one of the jury asked.",
+    "‘That I can’t remember,’ said the Hatter.",
+    "‘You MUST remember,’ remarked the King, ‘or I’ll have you executed.’",
+    "The miserable Hatter dropped his teacup and bread-and-butter, and went",
+    "down on one knee. ‘I’m a poor man, your Majesty,’ he began.",
+    "‘You’re a very poor speaker,’ said the King.",
+    "Here one of the guinea-pigs cheered, and was immediately suppressed by",
+    "the officers of the court. (As that is rather a hard word, I will just",
+    "explain to you how it was done. They had a large canvas bag, which tied",
+    "up at the mouth with strings: into this they slipped the guinea-pig,",
+    "head first, and then sat upon it.)",
+    "‘I’m glad I’ve seen that done,’ thought Alice. ‘I’ve so often read",
+    "in the newspapers, at the end of trials, “There was some attempts",
+    "at applause, which was immediately suppressed by the officers of the",
+    "court,” and I never understood what it meant till now.’",
+    "‘If that’s all you know about it, you may stand down,’ continued the",
+    "King.",
+    "‘I can’t go no lower,’ said the Hatter: ‘I’m on the floor, as it is.’",
+    "‘Then you may SIT down,’ the King replied.",
+    "Here the other guinea-pig cheered, and was suppressed.",
+    "‘Come, that finished the guinea-pigs!’ thought Alice. ‘Now we shall get",
+    "on better.’",
+    "‘I’d rather finish my tea,’ said the Hatter, with an anxious look at the",
+    "Queen, who was reading the list of singers.",
+    "‘You may go,’ said the King, and the Hatter hurriedly left the court,",
+    "without even waiting to put his shoes on.",
+    "‘--and just take his head off outside,’ the Queen added to one of the",
+    "officers: but the Hatter was out of sight before the officer could get",
+    "to the door.",
+    "‘Call the next witness!’ said the King.",
+    "The next witness was the Duchess’s cook. She carried the pepper-box in",
+    "her hand, and Alice guessed who it was, even before she got into the",
+    "court, by the way the people near the door began sneezing all at once.",
+    "‘Give your evidence,’ said the King.",
+    "‘Shan’t,’ said the cook.",
+    "The King looked anxiously at the White Rabbit, who said in a low voice,",
+    "‘Your Majesty must cross-examine THIS witness.’",
+    "‘Well, if I must, I must,’ the King said, with a melancholy air, and,",
+    "after folding his arms and frowning at the cook till his eyes were",
+    "nearly out of sight, he said in a deep voice, ‘What are tarts made of?’",
+    "‘Pepper, mostly,’ said the cook.",
+    "‘Treacle,’ said a sleepy voice behind her.",
+    "‘Collar that Dormouse,’ the Queen shrieked out. ‘Behead that Dormouse!",
+    "Turn that Dormouse out of court! Suppress him! Pinch him! Off with his",
+    "whiskers!’",
+    "For some minutes the whole court was in confusion, getting the Dormouse",
+    "turned out, and, by the time they had settled down again, the cook had",
+    "disappeared.",
+    "‘Never mind!’ said the King, with an air of great relief. ‘Call the next",
+    "witness.’ And he added in an undertone to the Queen, ‘Really, my dear,",
+    "YOU must cross-examine the next witness. It quite makes my forehead",
+    "ache!’",
+    "Alice watched the White Rabbit as he fumbled over the list, feeling very",
+    "curious to see what the next witness would be like, ‘--for they haven’t",
+    "got much evidence YET,’ she said to herself. Imagine her surprise, when",
+    "the White Rabbit read out, at the top of his shrill little voice, the",
+    "name ‘Alice!’",
+    "CHAPTER XII. Alice’s Evidence",
+    "‘Here!’ cried Alice, quite forgetting in the flurry of the moment how",
+    "large she had grown in the last few minutes, and she jumped up in such",
+    "a hurry that she tipped over the jury-box with the edge of her skirt,",
+    "upsetting all the jurymen on to the heads of the crowd below, and there",
+    "they lay sprawling about, reminding her very much of a globe of goldfish",
+    "she had accidentally upset the week before.",
+    "‘Oh, I BEG your pardon!’ she exclaimed in a tone of great dismay, and",
+    "began picking them up again as quickly as she could, for the accident of",
+    "the goldfish kept running in her head, and she had a vague sort of idea",
+    "that they must be collected at once and put back into the jury-box, or",
+    "they would die.",
+    "‘The trial cannot proceed,’ said the King in a very grave voice, ‘until",
+    "all the jurymen are back in their proper places--ALL,’ he repeated with",
+    "great emphasis, looking hard at Alice as he said do.",
+    "Alice looked at the jury-box, and saw that, in her haste, she had put",
+    "the Lizard in head downwards, and the poor little thing was waving its",
+    "tail about in a melancholy way, being quite unable to move. She soon got",
+    "it out again, and put it right; ‘not that it signifies much,’ she said",
+    "to herself; ‘I should think it would be QUITE as much use in the trial",
+    "one way up as the other.’",
+    "As soon as the jury had a little recovered from the shock of being",
+    "upset, and their slates and pencils had been found and handed back to",
+    "them, they set to work very diligently to write out a history of the",
+    "accident, all except the Lizard, who seemed too much overcome to do",
+    "anything but sit with its mouth open, gazing up into the roof of the",
+    "court.",
+    "‘What do you know about this business?’ the King said to Alice.",
+    "‘Nothing,’ said Alice.",
+    "‘Nothing WHATEVER?’ persisted the King.",
+    "‘Nothing whatever,’ said Alice.",
+    "‘That’s very important,’ the King said, turning to the jury. They were",
+    "just beginning to write this down on their slates, when the White Rabbit",
+    "interrupted: ‘UNimportant, your Majesty means, of course,’ he said in a",
+    "very respectful tone, but frowning and making faces at him as he spoke.",
+    "‘UNimportant, of course, I meant,’ the King hastily said, and went on",
+    "to himself in an undertone,",
+    "‘important--unimportant--unimportant--important--’ as if he were trying",
+    "which word sounded best.",
+    "Some of the jury wrote it down ‘important,’ and some ‘unimportant.’",
+    "Alice could see this, as she was near enough to look over their slates;",
+    "‘but it doesn’t matter a bit,’ she thought to herself.",
+    "At this moment the King, who had been for some time busily writing in",
+    "his note-book, cackled out ‘Silence!’ and read out from his book, ‘Rule",
+    "Forty-two. ALL PERSONS MORE THAN A MILE HIGH TO LEAVE THE COURT.’",
+    "Everybody looked at Alice.",
+    "‘I’M not a mile high,’ said Alice.",
+    "‘You are,’ said the King.",
+    "‘Nearly two miles high,’ added the Queen.",
+    "‘Well, I shan’t go, at any rate,’ said Alice: ‘besides, that’s not a",
+    "regular rule: you invented it just now.’",
+    "‘It’s the oldest rule in the book,’ said the King.",
+    "‘Then it ought to be Number One,’ said Alice.",
+    "The King turned pale, and shut his note-book hastily. ‘Consider your",
+    "verdict,’ he said to the jury, in a low, trembling voice.",
+    "‘There’s more evidence to come yet, please your Majesty,’ said the White",
+    "Rabbit, jumping up in a great hurry; ‘this paper has just been picked",
+    "up.’",
+    "‘What’s in it?’ said the Queen.",
+    "‘I haven’t opened it yet,’ said the White Rabbit, ‘but it seems to be a",
+    "letter, written by the prisoner to--to somebody.’",
+    "‘It must have been that,’ said the King, ‘unless it was written to",
+    "nobody, which isn’t usual, you know.’",
+    "‘Who is it directed to?’ said one of the jurymen.",
+    "‘It isn’t directed at all,’ said the White Rabbit; ‘in fact, there’s",
+    "nothing written on the OUTSIDE.’ He unfolded the paper as he spoke, and",
+    "added ‘It isn’t a letter, after all: it’s a set of verses.’",
+    "‘Are they in the prisoner’s handwriting?’ asked another of the jurymen.",
+    "‘No, they’re not,’ said the White Rabbit, ‘and that’s the queerest thing",
+    "about it.’ (The jury all looked puzzled.)",
+    "‘He must have imitated somebody else’s hand,’ said the King. (The jury",
+    "all brightened up again.)",
+    "‘Please your Majesty,’ said the Knave, ‘I didn’t write it, and they",
+    "can’t prove I did: there’s no name signed at the end.’",
+    "‘If you didn’t sign it,’ said the King, ‘that only makes the matter",
+    "worse. You MUST have meant some mischief, or else you’d have signed your",
+    "name like an honest man.’",
+    "There was a general clapping of hands at this: it was the first really",
+    "clever thing the King had said that day.",
+    "‘That PROVES his guilt,’ said the Queen.",
+    "‘It proves nothing of the sort!’ said Alice. ‘Why, you don’t even know",
+    "what they’re about!’",
+    "‘Read them,’ said the King.",
+    "The White Rabbit put on his spectacles. ‘Where shall I begin, please",
+    "your Majesty?’ he asked.",
+    "‘Begin at the beginning,’ the King said gravely, ‘and go on till you",
+    "come to the end: then stop.’",
+    "These were the verses the White Rabbit read:--",
+    "   ‘They told me you had been to her,",
+    "    And mentioned me to him:",
+    "   She gave me a good character,",
+    "    But said I could not swim.",
+    "   He sent them word I had not gone",
+    "    (We know it to be true):",
+    "   If she should push the matter on,",
+    "    What would become of you?",
+    "   I gave her one, they gave him two,",
+    "    You gave us three or more;",
+    "   They all returned from him to you,",
+    "    Though they were mine before.",
+    "   If I or she should chance to be",
+    "    Involved in this affair,",
+    "   He trusts to you to set them free,",
+    "    Exactly as we were.",
+    "   My notion was that you had been",
+    "    (Before she had this fit)",
+    "   An obstacle that came between",
+    "    Him, and ourselves, and it.",
+    "   Don’t let him know she liked them best,",
+    "    For this must ever be",
+    "   A secret, kept from all the rest,",
+    "    Between yourself and me.’",
+    "‘That’s the most important piece of evidence we’ve heard yet,’ said the",
+    "King, rubbing his hands; ‘so now let the jury--’",
+    "‘If any one of them can explain it,’ said Alice, (she had grown so large",
+    "in the last few minutes that she wasn’t a bit afraid of interrupting",
+    "him,) ‘I’ll give him sixpence. _I_ don’t believe there’s an atom of",
+    "meaning in it.’",
+    "The jury all wrote down on their slates, ‘SHE doesn’t believe there’s an",
+    "atom of meaning in it,’ but none of them attempted to explain the paper.",
+    "‘If there’s no meaning in it,’ said the King, ‘that saves a world of",
+    "trouble, you know, as we needn’t try to find any. And yet I don’t know,’",
+    "he went on, spreading out the verses on his knee, and looking at them",
+    "with one eye; ‘I seem to see some meaning in them, after all. “--SAID",
+    "I COULD NOT SWIM--” you can’t swim, can you?’ he added, turning to the",
+    "Knave.",
+    "The Knave shook his head sadly. ‘Do I look like it?’ he said. (Which he",
+    "certainly did NOT, being made entirely of cardboard.)",
+    "‘All right, so far,’ said the King, and he went on muttering over",
+    "the verses to himself: ‘“WE KNOW IT TO BE TRUE--” that’s the jury, of",
+    "course--“I GAVE HER ONE, THEY GAVE HIM TWO--” why, that must be what he",
+    "did with the tarts, you know--’",
+    "‘But, it goes on “THEY ALL RETURNED FROM HIM TO YOU,”’ said Alice.",
+    "‘Why, there they are!’ said the King triumphantly, pointing to the tarts",
+    "on the table. ‘Nothing can be clearer than THAT. Then again--“BEFORE SHE",
+    "HAD THIS FIT--” you never had fits, my dear, I think?’ he said to the",
+    "Queen.",
+    "‘Never!’ said the Queen furiously, throwing an inkstand at the Lizard",
+    "as she spoke. (The unfortunate little Bill had left off writing on his",
+    "slate with one finger, as he found it made no mark; but he now hastily",
+    "began again, using the ink, that was trickling down his face, as long as",
+    "it lasted.)",
+    "‘Then the words don’t FIT you,’ said the King, looking round the court",
+    "with a smile. There was a dead silence.",
+    "‘It’s a pun!’ the King added in an offended tone, and everybody laughed,",
+    "‘Let the jury consider their verdict,’ the King said, for about the",
+    "twentieth time that day.",
+    "‘No, no!’ said the Queen. ‘Sentence first--verdict afterwards.’",
+    "‘Stuff and nonsense!’ said Alice loudly. ‘The idea of having the",
+    "sentence first!’",
+    "‘Hold your tongue!’ said the Queen, turning purple.",
+    "‘I won’t!’ said Alice.",
+    "‘Off with her head!’ the Queen shouted at the top of her voice. Nobody",
+    "moved.",
+    "‘Who cares for you?’ said Alice, (she had grown to her full size by this",
+    "time.) ‘You’re nothing but a pack of cards!’",
+    "At this the whole pack rose up into the air, and came flying down upon",
+    "her: she gave a little scream, half of fright and half of anger, and",
+    "tried to beat them off, and found herself lying on the bank, with her",
+    "head in the lap of her sister, who was gently brushing away some dead",
+    "leaves that had fluttered down from the trees upon her face.",
+    "‘Wake up, Alice dear!’ said her sister; ‘Why, what a long sleep you’ve",
+    "had!’",
+    "‘Oh, I’ve had such a curious dream!’ said Alice, and she told her",
+    "sister, as well as she could remember them, all these strange Adventures",
+    "of hers that you have just been reading about; and when she had",
+    "finished, her sister kissed her, and said, ‘It WAS a curious dream,",
+    "dear, certainly: but now run in to your tea; it’s getting late.’ So",
+    "Alice got up and ran off, thinking while she ran, as well she might,",
+    "what a wonderful dream it had been.",
+    "But her sister sat still just as she left her, leaning her head on her",
+    "hand, watching the setting sun, and thinking of little Alice and all her",
+    "wonderful Adventures, till she too began dreaming after a fashion, and",
+    "this was her dream:--",
+    "First, she dreamed of little Alice herself, and once again the tiny",
+    "hands were clasped upon her knee, and the bright eager eyes were looking",
+    "up into hers--she could hear the very tones of her voice, and see that",
+    "queer little toss of her head to keep back the wandering hair that",
+    "WOULD always get into her eyes--and still as she listened, or seemed to",
+    "listen, the whole place around her became alive with the strange creatures",
+    "of her little sister’s dream.",
+    "The long grass rustled at her feet as the White Rabbit hurried by--the",
+    "frightened Mouse splashed his way through the neighbouring pool--she",
+    "could hear the rattle of the teacups as the March Hare and his friends",
+    "shared their never-ending meal, and the shrill voice of the Queen",
+    "ordering off her unfortunate guests to execution--once more the pig-baby",
+    "was sneezing on the Duchess’s knee, while plates and dishes crashed",
+    "around it--once more the shriek of the Gryphon, the squeaking of the",
+    "Lizard’s slate-pencil, and the choking of the suppressed guinea-pigs,",
+    "filled the air, mixed up with the distant sobs of the miserable Mock",
+    "Turtle.",
+    "So she sat on, with closed eyes, and half believed herself in",
+    "Wonderland, though she knew she had but to open them again, and all",
+    "would change to dull reality--the grass would be only rustling in the",
+    "wind, and the pool rippling to the waving of the reeds--the rattling",
+    "teacups would change to tinkling sheep-bells, and the Queen’s shrill",
+    "cries to the voice of the shepherd boy--and the sneeze of the baby, the",
+    "shriek of the Gryphon, and all the other queer noises, would change (she",
+    "knew) to the confused clamour of the busy farm-yard--while the lowing",
+    "of the cattle in the distance would take the place of the Mock Turtle’s",
+    "heavy sobs.",
+    "Lastly, she pictured to herself how this same little sister of hers",
+    "would, in the after-time, be herself a grown woman; and how she would",
+    "keep, through all her riper years, the simple and loving heart of her",
+    "childhood: and how she would gather about her other little children, and",
+    "make THEIR eyes bright and eager with many a strange tale, perhaps even",
+    "with the dream of Wonderland of long ago: and how she would feel with",
+    "all their simple sorrows, and find a pleasure in all their simple joys,",
+    "remembering her own child-life, and the happy summer days.",
+    "              THE END",
+    "End of Project Gutenberg’s Alice’s Adventures in Wonderland, by Lewis Carroll",
+    "*** END OF THIS PROJECT GUTENBERG EBOOK ALICE’S ADVENTURES IN WONDERLAND ***",
+    "***** This file should be named 11-0.txt or 11-0.zip *****",
+    "This and all associated files of various formats will be found in:",
+    "        http://www.gutenberg.org/1/11/",
+    "Updated editions will replace the previous one--the old editions",
+    "will be renamed.",
+    "Creating the works from public domain print editions means that no",
+    "one owns a United States copyright in these works, so the Foundation",
+    "(and you!) can copy and distribute it in the United States without",
+    "permission and without paying copyright royalties.  Special rules,",
+    "set forth in the General Terms of Use part of this license, apply to",
+    "copying and distributing Project Gutenberg-tm electronic works to",
+    "protect the PROJECT GUTENBERG-tm concept and trademark.  Project",
+    "Gutenberg is a registered trademark, and may not be used if you",
+    "charge for the eBooks, unless you receive specific permission.  If you",
+    "do not charge anything for copies of this eBook, complying with the",
+    "rules is very easy.  You may use this eBook for nearly any purpose",
+    "such as creation of derivative works, reports, performances and",
+    "research.  They may be modified and printed and given away--you may do",
+    "practically ANYTHING with public domain eBooks.  Redistribution is",
+    "subject to the trademark license, especially commercial",
+    "redistribution.",
+    "*** START: FULL LICENSE ***",
+    "THE FULL PROJECT GUTENBERG LICENSE",
+    "PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK",
+    "To protect the Project Gutenberg-tm mission of promoting the free",
+    "distribution of electronic works, by using or distributing this work",
+    "(or any other work associated in any way with the phrase “Project",
+    "Gutenberg”), you agree to comply with all the terms of the Full Project",
+    "Gutenberg-tm License (available with this file or online at",
+    "http://gutenberg.org/license).",
+    "Section 1.  General Terms of Use and Redistributing Project Gutenberg-tm",
+    "electronic works",
+    "1.A.  By reading or using any part of this Project Gutenberg-tm",
+    "electronic work, you indicate that you have read, understand, agree to",
+    "and accept all the terms of this license and intellectual property",
+    "(trademark/copyright) agreement.  If you do not agree to abide by all",
+    "the terms of this agreement, you must cease using and return or destroy",
+    "all copies of Project Gutenberg-tm electronic works in your possession.",
+    "If you paid a fee for obtaining a copy of or access to a Project",
+    "Gutenberg-tm electronic work and you do not agree to be bound by the",
+    "terms of this agreement, you may obtain a refund from the person or",
+    "entity to whom you paid the fee as set forth in paragraph 1.E.8.",
+    "1.B.  “Project Gutenberg” is a registered trademark.  It may only be",
+    "used on or associated in any way with an electronic work by people who",
+    "agree to be bound by the terms of this agreement.  There are a few",
+    "things that you can do with most Project Gutenberg-tm electronic works",
+    "even without complying with the full terms of this agreement.  See",
+    "paragraph 1.C below.  There are a lot of things you can do with Project",
+    "Gutenberg-tm electronic works if you follow the terms of this agreement",
+    "and help preserve free future access to Project Gutenberg-tm electronic",
+    "works.  See paragraph 1.E below.",
+    "1.C.  The Project Gutenberg Literary Archive Foundation (“the Foundation”",
+    " or PGLAF), owns a compilation copyright in the collection of Project",
+    "Gutenberg-tm electronic works.  Nearly all the individual works in the",
+    "collection are in the public domain in the United States.  If an",
+    "individual work is in the public domain in the United States and you are",
+    "located in the United States, we do not claim a right to prevent you from",
+    "copying, distributing, performing, displaying or creating derivative",
+    "works based on the work as long as all references to Project Gutenberg",
+    "are removed.  Of course, we hope that you will support the Project",
+    "Gutenberg-tm mission of promoting free access to electronic works by",
+    "freely sharing Project Gutenberg-tm works in compliance with the terms of",
+    "this agreement for keeping the Project Gutenberg-tm name associated with",
+    "the work.  You can easily comply with the terms of this agreement by",
+    "keeping this work in the same format with its attached full Project",
+    "Gutenberg-tm License when you share it without charge with others.",
+    "1.D.  The copyright laws of the place where you are located also govern",
+    "what you can do with this work.  Copyright laws in most countries are in",
+    "a constant state of change.  If you are outside the United States, check",
+    "the laws of your country in addition to the terms of this agreement",
+    "before downloading, copying, displaying, performing, distributing or",
+    "creating derivative works based on this work or any other Project",
+    "Gutenberg-tm work.  The Foundation makes no representations concerning",
+    "the copyright status of any work in any country outside the United",
+    "States.",
+    "1.E.  Unless you have removed all references to Project Gutenberg:",
+    "1.E.1.  The following sentence, with active links to, or other immediate",
+    "access to, the full Project Gutenberg-tm License must appear prominently",
+    "whenever any copy of a Project Gutenberg-tm work (any work on which the",
+    "phrase “Project Gutenberg” appears, or with which the phrase “Project",
+    "Gutenberg” is associated) is accessed, displayed, performed, viewed,",
+    "copied or distributed:",
+    "This eBook is for the use of anyone anywhere at no cost and with",
+    "almost no restrictions whatsoever.  You may copy it, give it away or",
+    "re-use it under the terms of the Project Gutenberg License included",
+    "with this eBook or online at www.gutenberg.org",
+    "1.E.2.  If an individual Project Gutenberg-tm electronic work is derived",
+    "from the public domain (does not contain a notice indicating that it is",
+    "posted with permission of the copyright holder), the work can be copied",
+    "and distributed to anyone in the United States without paying any fees",
+    "or charges.  If you are redistributing or providing access to a work",
+    "with the phrase “Project Gutenberg” associated with or appearing on the",
+    "work, you must comply either with the requirements of paragraphs 1.E.1",
+    "through 1.E.7 or obtain permission for the use of the work and the",
+    "Project Gutenberg-tm trademark as set forth in paragraphs 1.E.8 or",
+    "1.E.9.",
+    "1.E.3.  If an individual Project Gutenberg-tm electronic work is posted",
+    "with the permission of the copyright holder, your use and distribution",
+    "must comply with both paragraphs 1.E.1 through 1.E.7 and any additional",
+    "terms imposed by the copyright holder.  Additional terms will be linked",
+    "to the Project Gutenberg-tm License for all works posted with the",
+    "permission of the copyright holder found at the beginning of this work.",
+    "1.E.4.  Do not unlink or detach or remove the full Project Gutenberg-tm",
+    "License terms from this work, or any files containing a part of this",
+    "work or any other work associated with Project Gutenberg-tm.",
+    "1.E.5.  Do not copy, display, perform, distribute or redistribute this",
+    "electronic work, or any part of this electronic work, without",
+    "prominently displaying the sentence set forth in paragraph 1.E.1 with",
+    "active links or immediate access to the full terms of the Project",
+    "Gutenberg-tm License.",
+    "1.E.6.  You may convert to and distribute this work in any binary,",
+    "compressed, marked up, nonproprietary or proprietary form, including any",
+    "word processing or hypertext form.  However, if you provide access to or",
+    "distribute copies of a Project Gutenberg-tm work in a format other than",
+    "“Plain Vanilla ASCII” or other format used in the official version",
+    "posted on the official Project Gutenberg-tm web site (www.gutenberg.org),",
+    "you must, at no additional cost, fee or expense to the user, provide a",
+    "copy, a means of exporting a copy, or a means of obtaining a copy upon",
+    "request, of the work in its original “Plain Vanilla ASCII” or other",
+    "form.  Any alternate format must include the full Project Gutenberg-tm",
+    "License as specified in paragraph 1.E.1.",
+    "1.E.7.  Do not charge a fee for access to, viewing, displaying,",
+    "performing, copying or distributing any Project Gutenberg-tm works",
+    "unless you comply with paragraph 1.E.8 or 1.E.9.",
+    "1.E.8.  You may charge a reasonable fee for copies of or providing",
+    "access to or distributing Project Gutenberg-tm electronic works provided",
+    "that",
+    "- You pay a royalty fee of 20% of the gross profits you derive from",
+    "     the use of Project Gutenberg-tm works calculated using the method",
+    "     you already use to calculate your applicable taxes.  The fee is",
+    "     owed to the owner of the Project Gutenberg-tm trademark, but he",
+    "     has agreed to donate royalties under this paragraph to the",
+    "     Project Gutenberg Literary Archive Foundation.  Royalty payments",
+    "     must be paid within 60 days following each date on which you",
+    "     prepare (or are legally required to prepare) your periodic tax",
+    "     returns.  Royalty payments should be clearly marked as such and",
+    "     sent to the Project Gutenberg Literary Archive Foundation at the",
+    "     address specified in Section 4, “Information about donations to",
+    "     the Project Gutenberg Literary Archive Foundation.”",
+    "- You provide a full refund of any money paid by a user who notifies",
+    "     you in writing (or by e-mail) within 30 days of receipt that s/he",
+    "     does not agree to the terms of the full Project Gutenberg-tm",
+    "     License.  You must require such a user to return or",
+    "     destroy all copies of the works possessed in a physical medium",
+    "     and discontinue all use of and all access to other copies of",
+    "     Project Gutenberg-tm works.",
+    "- You provide, in accordance with paragraph 1.F.3, a full refund of any",
+    "     money paid for a work or a replacement copy, if a defect in the",
+    "     electronic work is discovered and reported to you within 90 days",
+    "     of receipt of the work.",
+    "- You comply with all other terms of this agreement for free",
+    "     distribution of Project Gutenberg-tm works.",
+    "1.E.9.  If you wish to charge a fee or distribute a Project Gutenberg-tm",
+    "electronic work or group of works on different terms than are set",
+    "forth in this agreement, you must obtain permission in writing from",
+    "both the Project Gutenberg Literary Archive Foundation and Michael",
+    "Hart, the owner of the Project Gutenberg-tm trademark.  Contact the",
+    "Foundation as set forth in Section 3 below.",
+    "1.F.",
+    "1.F.1.  Project Gutenberg volunteers and employees expend considerable",
+    "effort to identify, do copyright research on, transcribe and proofread",
+    "public domain works in creating the Project Gutenberg-tm",
+    "collection.  Despite these efforts, Project Gutenberg-tm electronic",
+    "works, and the medium on which they may be stored, may contain",
+    "“Defects,” such as, but not limited to, incomplete, inaccurate or",
+    "corrupt data, transcription errors, a copyright or other intellectual",
+    "property infringement, a defective or damaged disk or other medium, a",
+    "computer virus, or computer codes that damage or cannot be read by",
+    "your equipment.",
+    "1.F.2.  LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for the “Right",
+    "of Replacement or Refund” described in paragraph 1.F.3, the Project",
+    "Gutenberg Literary Archive Foundation, the owner of the Project",
+    "Gutenberg-tm trademark, and any other party distributing a Project",
+    "Gutenberg-tm electronic work under this agreement, disclaim all",
+    "liability to you for damages, costs and expenses, including legal",
+    "fees.  YOU AGREE THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT",
+    "LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT EXCEPT THOSE",
+    "PROVIDED IN PARAGRAPH F3.  YOU AGREE THAT THE FOUNDATION, THE",
+    "TRADEMARK OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE",
+    "LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE OR",
+    "INCIDENTAL DAMAGES EVEN IF YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH",
+    "DAMAGE.",
+    "1.F.3.  LIMITED RIGHT OF REPLACEMENT OR REFUND - If you discover a",
+    "defect in this electronic work within 90 days of receiving it, you can",
+    "receive a refund of the money (if any) you paid for it by sending a",
+    "written explanation to the person you received the work from.  If you",
+    "received the work on a physical medium, you must return the medium with",
+    "your written explanation.  The person or entity that provided you with",
+    "the defective work may elect to provide a replacement copy in lieu of a",
+    "refund.  If you received the work electronically, the person or entity",
+    "providing it to you may choose to give you a second opportunity to",
+    "receive the work electronically in lieu of a refund.  If the second copy",
+    "is also defective, you may demand a refund in writing without further",
+    "opportunities to fix the problem.",
+    "1.F.4.  Except for the limited right of replacement or refund set forth",
+    "in paragraph 1.F.3, this work is provided to you ‘AS-IS’ WITH NO OTHER",
+    "WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO",
+    "WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR ANY PURPOSE.",
+    "1.F.5.  Some states do not allow disclaimers of certain implied",
+    "warranties or the exclusion or limitation of certain types of damages.",
+    "If any disclaimer or limitation set forth in this agreement violates the",
+    "law of the state applicable to this agreement, the agreement shall be",
+    "interpreted to make the maximum disclaimer or limitation permitted by",
+    "the applicable state law.  The invalidity or unenforceability of any",
+    "provision of this agreement shall not void the remaining provisions.",
+    "1.F.6.  INDEMNITY - You agree to indemnify and hold the Foundation, the",
+    "trademark owner, any agent or employee of the Foundation, anyone",
+    "providing copies of Project Gutenberg-tm electronic works in accordance",
+    "with this agreement, and any volunteers associated with the production,",
+    "promotion and distribution of Project Gutenberg-tm electronic works,",
+    "harmless from all liability, costs and expenses, including legal fees,",
+    "that arise directly or indirectly from any of the following which you do",
+    "or cause to occur: (a) distribution of this or any Project Gutenberg-tm",
+    "work, (b) alteration, modification, or additions or deletions to any",
+    "Project Gutenberg-tm work, and (c) any Defect you cause.",
+    "Section  2.  Information about the Mission of Project Gutenberg-tm",
+    "Project Gutenberg-tm is synonymous with the free distribution of",
+    "electronic works in formats readable by the widest variety of computers",
+    "including obsolete, old, middle-aged and new computers.  It exists",
+    "because of the efforts of hundreds of volunteers and donations from",
+    "people in all walks of life.",
+    "Volunteers and financial support to provide volunteers with the",
+    "assistance they need, is critical to reaching Project Gutenberg-tm’s",
+    "goals and ensuring that the Project Gutenberg-tm collection will",
+    "remain freely available for generations to come.  In 2001, the Project",
+    "Gutenberg Literary Archive Foundation was created to provide a secure",
+    "and permanent future for Project Gutenberg-tm and future generations.",
+    "To learn more about the Project Gutenberg Literary Archive Foundation",
+    "and how your efforts and donations can help, see Sections 3 and 4",
+    "and the Foundation web page at http://www.pglaf.org.",
+    "Section 3.  Information about the Project Gutenberg Literary Archive",
+    "Foundation",
+    "The Project Gutenberg Literary Archive Foundation is a non profit",
+    "501(c)(3) educational corporation organized under the laws of the",
+    "state of Mississippi and granted tax exempt status by the Internal",
+    "Revenue Service.  The Foundation’s EIN or federal tax identification",
+    "number is 64-6221541.  Its 501(c)(3) letter is posted at",
+    "http://pglaf.org/fundraising.  Contributions to the Project Gutenberg",
+    "Literary Archive Foundation are tax deductible to the full extent",
+    "permitted by U.S. federal laws and your state’s laws.",
+    "The Foundation’s principal office is located at 4557 Melan Dr. S.",
+    "Fairbanks, AK, 99712., but its volunteers and employees are scattered",
+    "throughout numerous locations.  Its business office is located at",
+    "809 North 1500 West, Salt Lake City, UT 84116, (801) 596-1887, email",
+    "business at pglaf.org.  Email contact links and up to date contact",
+    "information can be found at the Foundation’s web site and official",
+    "page at http://pglaf.org",
+    "For additional contact information:",
+    "     Dr. Gregory B. Newby",
+    "     Chief Executive and Director",
+    "     gbnewby at pglaf.org",
+    "Section 4.  Information about Donations to the Project Gutenberg",
+    "Literary Archive Foundation",
+    "Project Gutenberg-tm depends upon and cannot survive without wide",
+    "spread public support and donations to carry out its mission of",
+    "increasing the number of public domain and licensed works that can be",
+    "freely distributed in machine readable form accessible by the widest",
+    "array of equipment including outdated equipment.  Many small donations",
+    "($1 to $5,000) are particularly important to maintaining tax exempt",
+    "status with the IRS.",
+    "The Foundation is committed to complying with the laws regulating",
+    "charities and charitable donations in all 50 states of the United",
+    "States.  Compliance requirements are not uniform and it takes a",
+    "considerable effort, much paperwork and many fees to meet and keep up",
+    "with these requirements.  We do not solicit donations in locations",
+    "where we have not received written confirmation of compliance.  To",
+    "SEND DONATIONS or determine the status of compliance for any",
+    "particular state visit http://pglaf.org",
+    "While we cannot and do not solicit contributions from states where we",
+    "have not met the solicitation requirements, we know of no prohibition",
+    "against accepting unsolicited donations from donors in such states who",
+    "approach us with offers to donate.",
+    "International donations are gratefully accepted, but we cannot make",
+    "any statements concerning tax treatment of donations received from",
+    "outside the United States.  U.S. laws alone swamp our small staff.",
+    "Please check the Project Gutenberg Web pages for current donation",
+    "methods and addresses.  Donations are accepted in a number of other",
+    "ways including checks, online payments and credit card donations.",
+    "To donate, please visit: http://pglaf.org/donate",
+    "Section 5.  General Information About Project Gutenberg-tm electronic",
+    "works.",
+    "Professor Michael S. Hart is the originator of the Project Gutenberg-tm",
+    "concept of a library of electronic works that could be freely shared",
+    "with anyone.  For thirty years, he produced and distributed Project",
+    "Gutenberg-tm eBooks with only a loose network of volunteer support.",
+    "Project Gutenberg-tm eBooks are often created from several printed",
+    "editions, all of which are confirmed as Public Domain in the U.S.",
+    "unless a copyright notice is included.  Thus, we do not necessarily",
+    "keep eBooks in compliance with any particular paper edition.",
+    "Most people start at our Web site which has the main PG search facility:",
+    "     http://www.gutenberg.org",
+    "This Web site includes information about Project Gutenberg-tm,",
+    "including how to make donations to the Project Gutenberg Literary",
+    "Archive Foundation, how to help produce our new eBooks, and how to",
+    "subscribe to our email newsletter to hear about new eBooks.",
+    ""
+};
diff --git a/deps/libcaption/format.sh b/deps/libcaption/format.sh
new file mode 100644
index 0000000..094312b
--- /dev/null
+++ b/deps/libcaption/format.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+cd "$(dirname "$0")"
+find . \( -name '*.cpp' -o -name '*.c' -o -name '*.h' -o -name '*.hpp' -o -name '*.re2c' \) -exec astyle --style=stroustrup --attach-extern-c --break-blocks --pad-header --pad-paren-out --unpad-paren --add-brackets --keep-one-line-blocks --keep-one-line-statements --convert-tabs --align-pointer=type --align-reference=type --suffix=none --lineend=linux --max-code-length=180 {} \;
diff --git a/deps/libcaption/src/avc.c b/deps/libcaption/src/avc.c
new file mode 100644
index 0000000..4b46ef6
--- /dev/null
+++ b/deps/libcaption/src/avc.c
@@ -0,0 +1,595 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+
+#include "avc.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+////////////////////////////////////////////////////////////////////////////////
+// AVC RBSP Methods
+//  TODO move the to a avcutils file
+static size_t _find_emulation_prevention_byte (const uint8_t* data, size_t size)
+{
+    size_t offset = 2;
+
+    while (offset < size) {
+        if (0 == data[offset]) {
+            // 0 0 X 3 //; we know X is zero
+            offset += 1;
+        } else if (3 != data[offset]) {
+            // 0 0 X 0 0 3; we know X is not 0 and not 3
+            offset += 3;
+        } else if (0 != data[offset-1]) {
+            // 0 X 0 0 3
+            offset += 2;
+        } else if (0 != data[offset-2]) {
+            // X 0 0 3
+            offset += 1;
+        } else {
+            // 0 0 3
+            return offset;
+        }
+    }
+
+    return size;
+}
+
+static size_t _copy_to_rbsp (uint8_t* destData, size_t destSize, const uint8_t* sorcData, size_t sorcSize)
+{
+    size_t toCopy, totlSize = 0;
+
+    for (;;) {
+        if (destSize >= sorcSize) {
+            return 0;
+        }
+
+        // The following line IS correct! We want to look in sorcData up to destSize bytes
+        // We know destSize is smaller than sorcSize because of the previous line
+        toCopy = _find_emulation_prevention_byte (sorcData,destSize);
+        memcpy (destData, sorcData, toCopy);
+        totlSize += toCopy;
+        destData += toCopy;
+        destSize -= toCopy;
+
+        if (0 == destSize) {
+            return totlSize;
+        }
+
+        // skip the emulation prevention byte
+        totlSize += 1;
+        sorcData += toCopy + 1;
+        sorcSize -= toCopy + 1;
+    }
+
+    return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+static inline size_t _find_emulated (uint8_t* data, size_t size)
+{
+    size_t offset = 2;
+
+    while (offset < size) {
+        if (3 < data[offset]) {
+            // 0 0 X; we know X is not 0, 1, 2 or 3
+            offset += 3;
+        } else if (0 != data[offset-1]) {
+            // 0 X 0 0 1
+            offset += 2;
+        } else if (0 != data[offset-2]) {
+            // X 0 0 1
+            offset += 1;
+        } else {
+            // 0 0 0, 0 0 1
+            return offset;
+        }
+    }
+
+    return size;
+}
+
+size_t _copy_from_rbsp (uint8_t* data, uint8_t* payloadData, size_t payloadSize)
+{
+    size_t total = 0;
+
+    while (payloadSize) {
+        size_t bytes = _find_emulated (payloadData,payloadSize);
+
+        if (bytes > payloadSize) {
+            return 0;
+        }
+
+        memcpy (data, payloadData, bytes);
+
+        if (bytes == payloadSize) {
+            return total + bytes;
+        }
+
+        data[bytes] = 3; // insert emulation prevention byte
+        data += bytes + 1; total += bytes + 1;
+        payloadData += bytes; payloadSize -= bytes;
+    }
+
+    return total;
+}
+////////////////////////////////////////////////////////////////////////////////
+struct _sei_message_t {
+    size_t size;
+    sei_msgtype_t type;
+    struct _sei_message_t* next;
+};
+
+sei_message_t* sei_message_next (sei_message_t* msg) { return ( (struct _sei_message_t*) msg)->next; }
+sei_msgtype_t  sei_message_type (sei_message_t* msg) { return ( (struct _sei_message_t*) msg)->type; }
+size_t         sei_message_size (sei_message_t* msg) { return ( (struct _sei_message_t*) msg)->size; }
+uint8_t*       sei_message_data (sei_message_t* msg) { return ( (uint8_t*) msg) + sizeof (struct _sei_message_t); }
+void           sei_message_free (sei_message_t* msg) { if (msg) { free (msg); } }
+
+sei_message_t* sei_message_new (sei_msgtype_t type, uint8_t* data, size_t size)
+{
+    struct _sei_message_t* msg = (struct _sei_message_t*) malloc (sizeof (struct _sei_message_t) + size);
+    msg->next = 0; msg->type = type; msg->size = size;
+
+    if (data) {
+        memcpy (sei_message_data (msg), data, size);
+    } else {
+        memset (sei_message_data (msg), 0, size);
+    }
+
+    return (sei_message_t*) msg;
+}
+////////////////////////////////////////////////////////////////////////////////
+void sei_init (sei_t* sei)
+{
+    sei->dts = -1;
+    sei->cts = -1;
+    sei->head = 0;
+    sei->tail = 0;
+}
+
+void sei_message_append (sei_t* sei, sei_message_t* msg)
+{
+    if (0 == sei->head) {
+        sei->head = msg;
+        sei->tail = msg;
+    } else {
+        sei->tail->next = msg;
+        sei->tail = msg;
+    }
+}
+
+void sei_free (sei_t* sei)
+{
+    sei_message_t* tail;
+
+    while (sei->head) {
+        tail = sei->head->next;
+        free (sei->head);
+        sei->head = tail;
+    }
+
+    sei_init (sei);
+}
+
+void sei_dump (sei_t* sei)
+{
+    fprintf (stderr,"SEI %p\n", sei);
+    sei_dump_messages (sei->head);
+}
+
+void sei_dump_messages (sei_message_t* head)
+{
+    cea708_t cea708;
+    sei_message_t* msg;
+    cea708_init (&cea708);
+
+    for (msg = head ; msg ; msg = sei_message_next (msg)) {
+        uint8_t* data = sei_message_data (msg);
+        size_t size =  sei_message_size (msg);
+        fprintf (stderr,"-- Message %p\n-- Message Type: %d\n-- Message Size: %d\n", data, sei_message_type (msg), (int) size);
+
+        while (size) {
+            fprintf (stderr,"%02X ", *data);
+            ++data; --size;
+        }
+
+        fprintf (stderr,"\n");
+
+        if (sei_type_user_data_registered_itu_t_t35 == sei_message_type (msg)) {
+            cea708_parse (sei_message_data (msg), sei_message_size (msg), &cea708);
+            cea708_dump (&cea708);
+        }
+
+
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+size_t sei_render_size (sei_t* sei)
+{
+    size_t size = 2; // nalu_type + stop bit
+    sei_message_t* msg;
+
+    for (msg = sei_message_head (sei) ; msg ; msg = sei_message_next (msg)) {
+        size += 1 + (msg->type / 255);
+        size += 1 + (msg->size / 255);
+        size += 1 + (msg->size * 4/3);
+    }
+
+    return size;
+}
+
+// we can safely assume sei_render_size() bytes have been allocated for data
+size_t sei_render (sei_t* sei, uint8_t* data)
+{
+    size_t escaped_size, size = 2; // nalu_type + stop bit
+    sei_message_t* msg;
+    (*data) = 6; ++data;
+
+    for (msg = sei_message_head (sei) ; msg ; msg = sei_message_next (msg)) {
+        int payloadType      = sei_message_type (msg);
+        int payloadSize      = (int) sei_message_size (msg);
+        uint8_t* payloadData = sei_message_data (msg);
+
+        while (255 <= payloadType) {
+            (*data) = 255;
+            ++data; ++size;
+            payloadType -= 255;
+        }
+
+        (*data) = payloadType;
+        ++data; ++size;
+
+        while (255 <= payloadSize) {
+            (*data) = 255;
+            ++data; ++size;
+            payloadSize -= 255;
+        }
+
+        (*data) = payloadSize;
+        ++data; ++size;
+
+        if (0 >= (escaped_size = _copy_from_rbsp (data,payloadData,payloadSize))) {
+            return 0;
+        }
+
+        data += escaped_size;
+        size += escaped_size;
+    }
+
+    // write stop bit and return
+    (*data) = 0x80;
+    return size;
+}
+
+uint8_t* sei_render_alloc (sei_t* sei, size_t* size)
+{
+    size_t aloc = sei_render_size (sei);
+    uint8_t* data = malloc (aloc);
+    (*size) = sei_render (sei, data);
+    return data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int sei_parse_nalu (sei_t* sei, const uint8_t* data, size_t size, double dts, double cts)
+{
+    assert (0<=cts); // cant present before decode
+    sei->dts = dts;
+    sei->cts = cts;
+    int ret = 0;
+
+    if (0 == data || 0 == size) {
+        return 0;
+    }
+
+    uint8_t nal_unit_type = (*data) & 0x1F;
+    ++data; --size;
+
+    if (6 != nal_unit_type) {
+        return 0;
+    }
+
+    // SEI may contain more than one payload
+    while (1<size) {
+        int payloadType = 0;
+        int payloadSize = 0;
+
+        while (0 < size && 255 == (*data)) {
+            payloadType += 255;
+            ++data; --size;
+        }
+
+        if (0 == size) {
+            goto error;
+        }
+
+        payloadType += (*data);
+        ++data; --size;
+
+        while (0 < size && 255 == (*data)) {
+            payloadSize += 255;
+            ++data; --size;
+        }
+
+        if (0 == size) {
+            goto error;
+        }
+
+        payloadSize += (*data);
+        ++data; --size;
+
+        if (payloadSize) {
+            sei_message_t* msg = sei_message_new ( (sei_msgtype_t) payloadType, 0, payloadSize);
+            uint8_t* payloadData = sei_message_data (msg);
+            size_t bytes = _copy_to_rbsp (payloadData, payloadSize, data, size);
+            sei_message_append (sei, msg);
+
+            if ( (int) bytes < payloadSize) {
+                goto error;
+            }
+
+            data += bytes; size -= bytes;
+            ++ret;
+        }
+    }
+
+    // There should be one trailing byte, 0x80. But really, we can just ignore that fact.
+    return ret;
+error:
+    sei_init (sei);
+    return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+libcaption_stauts_t sei_to_caption_frame (sei_t* sei, caption_frame_t* frame)
+{
+    cea708_t cea708;
+    sei_message_t* msg;
+    libcaption_stauts_t status = LIBCAPTION_OK;
+
+    cea708_init (&cea708);
+
+    for (msg = sei_message_head (sei) ; msg ; msg = sei_message_next (msg)) {
+        if (sei_type_user_data_registered_itu_t_t35 == sei_message_type (msg)) {
+            cea708_parse (sei_message_data (msg), sei_message_size (msg), &cea708);
+            status = libcaption_status_update (status, cea708_to_caption_frame (frame, &cea708, sei_pts (sei)));
+        }
+    }
+
+    if (LIBCAPTION_READY == status) {
+        frame->timestamp = sei->dts + sei->cts;
+        frame->duration = 0;
+    }
+
+    return status;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+#define DEFAULT_CHANNEL 0
+
+void sei_append_708 (sei_t* sei, cea708_t* cea708)
+{
+    sei_message_t* msg = sei_message_new (sei_type_user_data_registered_itu_t_t35, 0, CEA608_MAX_SIZE);
+    msg->size = cea708_render (cea708, sei_message_data (msg), sei_message_size (msg));
+    sei_message_append (sei,msg);
+    // cea708_dump (cea708);
+    cea708_init (cea708); // will confgure using HLS compatiable defaults
+}
+
+// This should be moved to 708.c
+// This works for popon, but bad for paint on and roll up
+// Please understand this function before you try to use it, setting null values have different effects than you may assume
+void sei_encode_eia608 (sei_t* sei, cea708_t* cea708, uint16_t cc_data)
+{
+    // This one is full, flush and init a new one
+    // shoudl this be 32? I cant remember
+    if (31 == cea708->user_data.cc_count) {
+        sei_append_708 (sei,cea708);
+    }
+
+    if (0 == cea708->user_data.cc_count) { // This is a new 708 header, but a continuation of a 608 stream
+        cea708_add_cc_data (cea708, 1, cc_type_ntsc_cc_field_1, eia608_control_command (eia608_control_resume_caption_loading, DEFAULT_CHANNEL));
+    }
+
+    if (0 == cc_data) { // Finished
+        sei_encode_eia608 (sei,cea708,eia608_control_command (eia608_control_end_of_caption, DEFAULT_CHANNEL));
+        sei_append_708 (sei,cea708);
+        return;
+    }
+
+    cea708_add_cc_data (cea708, 1, cc_type_ntsc_cc_field_1, cc_data);
+}
+////////////////////////////////////////////////////////////////////////////////
+// TODO use alternate charcters instead of always using space before extended charcters
+// TODO rewrite this function with better logic
+int sei_from_caption_frame (sei_t* sei, caption_frame_t* frame)
+{
+    int r,c;
+    cea708_t cea708;
+    const char* data;
+    uint16_t prev_cc_data;
+
+    cea708_init (&cea708); // set up a new popon frame
+    cea708_add_cc_data (&cea708, 1, cc_type_ntsc_cc_field_1, eia608_control_command (eia608_control_erase_non_displayed_memory, DEFAULT_CHANNEL));
+    cea708_add_cc_data (&cea708, 1, cc_type_ntsc_cc_field_1, eia608_control_command (eia608_control_resume_caption_loading, DEFAULT_CHANNEL));
+
+    for (r=0; r<SCREEN_ROWS; ++r) {
+        // Calculate preamble
+        for (c=0; c<SCREEN_COLS && 0 == *caption_frame_read_char (frame,r,c,0,0) ; ++c) {}
+
+        // This row is blank
+        if (SCREEN_COLS == c) {
+            continue;
+        }
+
+        // Write preamble
+        sei_encode_eia608 (sei, &cea708, eia608_row_column_pramble (r,c,DEFAULT_CHANNEL,0));
+        int tab = c % 4;
+
+        if (tab) {
+            sei_encode_eia608 (sei, &cea708, eia608_tab (tab,DEFAULT_CHANNEL));
+        }
+
+        // Write the row
+        for (prev_cc_data = 0, data = caption_frame_read_char (frame,r,c,0,0) ;
+                (*data) && c < SCREEN_COLS ; ++c, data = caption_frame_read_char (frame,r,c,0,0)) {
+            uint16_t cc_data = eia608_from_utf8_1 (data,DEFAULT_CHANNEL);
+
+            if (!cc_data) {
+                // We do't want to write bad data, so just ignore it.
+            } else if (eia608_is_basicna (prev_cc_data)) {
+                if (eia608_is_basicna (cc_data)) {
+                    // previous and current chars are both basicna, combine them into current
+                    sei_encode_eia608 (sei, &cea708, eia608_from_basicna (prev_cc_data,cc_data));
+                } else if (eia608_is_westeu (cc_data)) {
+                    // extended charcters overwrite the previous charcter, so insert a dummy char thren write the extended char
+                    sei_encode_eia608 (sei, &cea708, eia608_from_basicna (prev_cc_data,eia608_from_utf8_1 (EIA608_CHAR_SPACE,DEFAULT_CHANNEL)));
+                    sei_encode_eia608 (sei, &cea708, cc_data);
+                } else {
+                    // previous was basic na, but current isnt; write previous and current
+                    sei_encode_eia608 (sei, &cea708, prev_cc_data);
+                    sei_encode_eia608 (sei, &cea708, cc_data);
+                }
+
+                prev_cc_data = 0; // previous is handled, we can forget it now
+            } else if (eia608_is_westeu (cc_data)) {
+                // extended chars overwrite the previous chars, so insert a dummy char
+                sei_encode_eia608 (sei, &cea708, eia608_from_utf8_1 (EIA608_CHAR_SPACE,DEFAULT_CHANNEL));
+                sei_encode_eia608 (sei, &cea708, cc_data);
+            } else if (eia608_is_basicna (cc_data)) {
+                prev_cc_data = cc_data;
+            } else {
+                sei_encode_eia608 (sei, &cea708, cc_data);
+            }
+
+            if (eia608_is_specialna (cc_data)) {
+                // specialna are treated as controll charcters. Duplicated controll charcters are discarded
+                // So we for a resume after a specialna as a noop to break repetition detection
+                // TODO only do this if the same charcter is repeated
+                sei_encode_eia608 (sei, &cea708, eia608_control_command (eia608_control_resume_caption_loading, DEFAULT_CHANNEL));
+            }
+        }
+
+        if (0 != prev_cc_data) {
+            sei_encode_eia608 (sei, &cea708, prev_cc_data);
+        }
+    }
+
+    sei_encode_eia608 (sei, &cea708, 0); // flush
+    sei->dts = frame->timestamp; // assumes in order frames
+    // sei_dump (sei);
+    return 1;
+}
+////////////////////////////////////////////////////////////////////////////////
+static int avc_is_start_code (const uint8_t* data, int size, int* len)
+{
+    if (3 > size) {
+        return -1;
+    }
+
+    if (1 < data[2]) {
+        return 3;
+    }
+
+    if (0 != data[1]) {
+        return 2;
+    }
+
+    if (0 == data[0]) {
+        if (1 == data[2]) {
+            *len = 3;
+            return 0;
+        }
+
+        if (4 <= size && 1 == data[3]) {
+            *len = 4;
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+
+static int avc_find_start_code (const uint8_t* data, int size, int* len)
+{
+    int pos = 0;
+
+    for (;;) {
+        // is pos pointing to a start code?
+        int isc = avc_is_start_code (data + pos, size - pos, len);
+
+        if (0 < isc) {
+            pos += isc;
+        } else if (0 > isc) {
+            // No start code found
+            return isc;
+        } else {
+            // Start code found at pos
+            return pos;
+        }
+    }
+}
+
+
+static int avc_find_start_code_increnental (const uint8_t* data, int size, int prev_size, int* len)
+{
+    int offset = (3 <= prev_size) ? (prev_size - 3) : 0;
+    int pos = avc_find_start_code (data + offset, size - offset, len);
+
+    if (0 <= pos) {
+        return pos + offset;
+    }
+
+    return pos;
+}
+
+void avcnalu_init (avcnalu_t* nalu)
+{
+    memset (nalu,0,sizeof (avcnalu_t));
+}
+
+int avcnalu_parse_annexb (avcnalu_t* nalu, const uint8_t** data, size_t* size)
+{
+    int scpos, sclen;
+    int new_size = (int) (nalu->size + (*size));
+
+    if (new_size > MAX_NALU_SIZE) {
+        (*size) = nalu->size = 0;
+        return LIBCAPTION_ERROR;
+    }
+
+    memcpy (&nalu->data[nalu->size], (*data), (*size));
+    scpos = avc_find_start_code_increnental (&nalu->data[0], new_size, (int) nalu->size, &sclen);
+
+    if (0<=scpos) {
+        (*data) += (scpos - nalu->size) + sclen;
+        (*size) -= (scpos - nalu->size) + sclen;
+        nalu->size = scpos;
+        return 0 < nalu->size ? LIBCAPTION_READY : LIBCAPTION_OK;
+    } else {
+        (*size) = 0;
+        nalu->size = new_size;
+        return LIBCAPTION_OK;
+    }
+}
diff --git a/deps/libcaption/src/caption.c b/deps/libcaption/src/caption.c
new file mode 100644
index 0000000..9af6a51
--- /dev/null
+++ b/deps/libcaption/src/caption.c
@@ -0,0 +1,491 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include "utf8.h"
+#include "xds.h"
+#include "eia608.h"
+#include "caption.h"
+#include <stdio.h>
+#include <string.h>
+////////////////////////////////////////////////////////////////////////////////
+void caption_frame_buffer_clear (caption_frame_buffer_t* buff)
+{
+    memset (buff,0,sizeof (caption_frame_buffer_t));
+}
+
+void caption_frame_state_clear (caption_frame_t* frame)
+{
+    frame->timestamp = -1;
+    frame->duration = 0;
+    frame->state = (caption_frame_state_t) {0,0,0,0,0,0,0}; // clear global state
+}
+
+void caption_frame_init (caption_frame_t* frame)
+{
+    caption_frame_state_clear (frame);
+    xds_init (&frame->xds);
+    caption_frame_buffer_clear (&frame->back);
+    caption_frame_buffer_clear (&frame->front);
+}
+////////////////////////////////////////////////////////////////////////////////
+#define CAPTION_CLEAR     0
+#define CAPTION_POP_ON    2
+#define CAPTION_PAINT_ON  3
+#define CAPTION_ROLL_UP   4
+////////////////////////////////////////////////////////////////////////////////
+// Helpers
+static caption_frame_cell_t* frame_buffer_cell (caption_frame_buffer_t* buff, int row, int col)
+{
+    return &buff->cell[row][col];
+}
+
+static caption_frame_buffer_t* frame_write_buffer (caption_frame_t* frame)
+{
+    if (CAPTION_POP_ON == frame->state.mod) {
+        return &frame->back;
+    } else if (CAPTION_PAINT_ON == frame->state.mod || CAPTION_ROLL_UP == frame->state.mod) {
+        return &frame->front;
+    } else {
+        return 0;
+    }
+}
+
+static caption_frame_cell_t* frame_cell (caption_frame_t* frame, int row, int col)
+{
+    return frame_buffer_cell (&frame->front,row,col);
+}
+
+static caption_frame_cell_t* frame_cell_get (caption_frame_t* frame)
+{
+    return frame_cell (frame, frame->state.row, frame->state.col);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+uint16_t _eia608_from_utf8 (const char* s); // function is in eia608.c.re2c
+int caption_frame_write_char (caption_frame_t* frame, int row, int col, eia608_style_t style, int underline, const char* c)
+{
+    caption_frame_buffer_t* buff = frame_write_buffer (frame);
+
+    if (!buff || ! _eia608_from_utf8 (c)) {
+        return 0;
+    }
+
+    caption_frame_cell_t* cell = frame_buffer_cell (buff,row,col);
+
+    if (utf8_char_copy (&cell->data[0],c)) {
+        cell->uln = underline;
+        cell->sty = style;
+        return 1;
+    }
+
+    return 0;
+}
+
+const utf8_char_t* caption_frame_read_char (caption_frame_t* frame, int row, int col, eia608_style_t* style, int* underline)
+{
+    caption_frame_cell_t* cell = frame_cell (frame, row, col);
+
+    if (!cell) {
+        if (style) {
+            (*style) = eia608_style_white;
+        }
+
+        if (underline) {
+            (*underline) = 0;
+        }
+
+        return EIA608_CHAR_NULL;
+    }
+
+    if (style) {
+        (*style) = cell->sty;
+    }
+
+    if (underline) {
+        (*underline) = cell->uln;
+    }
+
+    return &cell->data[0];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Parsing
+libcaption_stauts_t caption_frame_carriage_return (caption_frame_t* frame)
+{
+    caption_frame_buffer_t* buff = frame_write_buffer (frame);
+
+    if (!buff) {
+        return LIBCAPTION_OK;
+    }
+
+    int r = frame->state.row - (frame->state.rup-1);
+
+    if (0  >= r || CAPTION_ROLL_UP != frame->state.mod) {
+        return LIBCAPTION_OK;
+    }
+
+    for (; r < SCREEN_ROWS; ++r) {
+        uint8_t* dst = (uint8_t*) frame_buffer_cell (buff,r-1,0);
+        uint8_t* src = (uint8_t*) frame_buffer_cell (buff,r-0,0);
+        memcpy (dst,src,sizeof (caption_frame_cell_t) * SCREEN_COLS);
+    }
+
+    memset (frame_buffer_cell (buff,SCREEN_ROWS-1,0), 0,sizeof (caption_frame_cell_t) * SCREEN_COLS);
+    return LIBCAPTION_OK;
+}
+////////////////////////////////////////////////////////////////////////////////
+libcaption_stauts_t eia608_write_char (caption_frame_t* frame, char* c)
+{
+    if (0 == c || 0 == c[0] ||
+            SCREEN_ROWS <= frame->state.row || 0 > frame->state.row ||
+            SCREEN_COLS <= frame->state.col || 0 > frame->state.col) {
+        // NO-OP
+    } else if (caption_frame_write_char (frame,frame->state.row,frame->state.col,frame->state.sty,frame->state.uln, c)) {
+        frame->state.col += 1;
+    }
+
+    return LIBCAPTION_OK;
+}
+
+libcaption_stauts_t caption_frame_end (caption_frame_t* frame)
+{
+    memcpy (&frame->front,&frame->back,sizeof (caption_frame_buffer_t));
+    caption_frame_state_clear (frame);
+    caption_frame_buffer_clear (&frame->back);
+    return LIBCAPTION_READY;
+}
+
+libcaption_stauts_t caption_frame_decode_preamble (caption_frame_t* frame, uint16_t cc_data)
+{
+    eia608_style_t sty;
+    int row, col, chn, uln;
+
+    if (eia608_parse_preamble (cc_data, &row, &col, &sty, &chn, &uln)) {
+        frame->state.row = row;
+        frame->state.col = col;
+        frame->state.sty = sty;
+        frame->state.uln = uln;
+    }
+
+    return LIBCAPTION_OK;
+}
+
+libcaption_stauts_t caption_frame_decode_midrowchange (caption_frame_t* frame, uint16_t cc_data)
+{
+    eia608_style_t sty;
+    int chn, unl;
+
+    if (eia608_parse_midrowchange (cc_data,&chn,&sty,&unl)) {
+        frame->state.sty = sty;
+        frame->state.uln = unl;
+    }
+
+    return LIBCAPTION_OK;
+}
+
+libcaption_stauts_t caption_frame_backspace (caption_frame_t* frame)
+{
+    // do not reverse wrap (tw 28:20)
+    frame->state.col = (0 < frame->state.col) ? (frame->state.col - 1) : 0;
+    caption_frame_write_char (frame,frame->state.row,frame->state.col,eia608_style_white,0,EIA608_CHAR_NULL);
+    return LIBCAPTION_READY;
+}
+
+libcaption_stauts_t caption_frame_decode_control (caption_frame_t* frame, uint16_t cc_data)
+{
+    int cc;
+    eia608_control_t cmd = eia608_parse_control (cc_data,&cc);
+
+    switch (cmd) {
+    // PAINT ON
+    case eia608_control_resume_direct_captioning:
+        frame->state.rup = 0;
+        frame->state.mod = CAPTION_PAINT_ON;
+        return LIBCAPTION_OK;
+
+    case eia608_control_erase_display_memory:
+        caption_frame_buffer_clear (&frame->front);
+        return LIBCAPTION_OK;
+
+    // ROLL-UP
+    case eia608_control_roll_up_2:
+        frame->state.rup = 1;
+        frame->state.mod = CAPTION_ROLL_UP;
+        return LIBCAPTION_OK;
+
+    case eia608_control_roll_up_3:
+        frame->state.rup = 2;
+        frame->state.mod = CAPTION_ROLL_UP;
+        return LIBCAPTION_OK;
+
+    case eia608_control_roll_up_4:
+        frame->state.rup = 3;
+        frame->state.mod = CAPTION_ROLL_UP;
+        return LIBCAPTION_OK;
+
+    case eia608_control_carriage_return:
+        return caption_frame_carriage_return (frame);
+
+    // Corrections (Is this only valid as part of paint on?)
+    case eia608_control_backspace:
+        return caption_frame_backspace (frame);
+
+    case eia608_control_delete_to_end_of_row: {
+        int c;
+
+        for (c = frame->state.col ; c < SCREEN_COLS ; ++c) {
+            caption_frame_write_char (frame,frame->state.row,c,eia608_style_white,0,EIA608_CHAR_NULL);
+        }
+    }
+
+    return LIBCAPTION_READY;
+
+    // POP ON
+    case eia608_control_resume_caption_loading:
+        frame->state.rup = 0;
+        frame->state.mod = CAPTION_POP_ON;
+        return LIBCAPTION_OK;
+
+    case eia608_control_erase_non_displayed_memory:
+        caption_frame_buffer_clear (&frame->back);
+        return LIBCAPTION_OK;
+
+    case eia608_control_end_of_caption:
+        return caption_frame_end (frame);
+
+    // cursor positioning
+    case eia608_tab_offset_0:
+    case eia608_tab_offset_1:
+    case eia608_tab_offset_2:
+    case eia608_tab_offset_3:
+        frame->state.col += (cmd - eia608_tab_offset_0);
+        return LIBCAPTION_OK;
+
+    // Unhandled
+    default:
+    case eia608_control_alarm_off:
+    case eia608_control_alarm_on:
+    case eia608_control_text_restart:
+    case eia608_control_text_resume_text_display:
+        return LIBCAPTION_OK;
+    }
+}
+
+libcaption_stauts_t caption_frame_decode_text (caption_frame_t* frame, uint16_t cc_data)
+{
+    int chan;
+    char char1[5], char2[5];
+    size_t chars = eia608_to_utf8 (cc_data, &chan, &char1[0], &char2[0]);
+
+    if (eia608_is_westeu (cc_data)) {
+        // Extended charcters replace the previous charcter for back compatibility
+        caption_frame_backspace (frame);
+    }
+
+    if (0 < chars) {
+        eia608_write_char (frame,char1);
+    }
+
+    if (1 < chars) {
+        eia608_write_char (frame,char2);
+    }
+
+    return LIBCAPTION_OK;
+}
+
+libcaption_stauts_t caption_frame_decode (caption_frame_t* frame, uint16_t cc_data, double timestamp)
+{
+    libcaption_stauts_t status = LIBCAPTION_OK;
+
+    if (!eia608_parity_varify (cc_data)) {
+        return LIBCAPTION_ERROR;
+    }
+
+    if (eia608_is_padding (cc_data)) {
+        return LIBCAPTION_OK;
+    }
+
+    // skip duplicate controll commands. We also skip duplicate specialna to match the behaviour of iOS/vlc
+    if ( (eia608_is_specialna (cc_data) || eia608_is_control (cc_data)) && cc_data == frame->state.cc_data) {
+        return LIBCAPTION_OK;
+    }
+
+    if (0 > frame->timestamp && 0 < timestamp) {
+        frame->timestamp = timestamp;
+    }
+
+    frame->state.cc_data = cc_data;
+
+    if (frame->xds.state) {
+        status = xds_decode (&frame->xds,cc_data);
+    } else if (eia608_is_xds (cc_data)) {
+        status = xds_decode (&frame->xds,cc_data);
+    } else if (eia608_is_control (cc_data)) {
+        status = caption_frame_decode_control (frame,cc_data);
+    } else if (eia608_is_basicna (cc_data) ||
+               eia608_is_specialna (cc_data) ||
+               eia608_is_westeu (cc_data)) {
+
+        // Don't decode text if we dont know what mode we are in.
+        if (CAPTION_CLEAR == frame->state.mod) {
+            return LIBCAPTION_OK;
+        }
+
+        status = caption_frame_decode_text (frame,cc_data);
+
+        // If we are in paint on mode, display immiditally
+        if (1 == status && (CAPTION_PAINT_ON == frame->state.mod || CAPTION_ROLL_UP == frame->state.mod)) {
+            status = LIBCAPTION_READY;
+        }
+    } else if (eia608_is_preamble (cc_data)) {
+        status = caption_frame_decode_preamble (frame,cc_data);
+    } else if (eia608_is_midrowchange (cc_data)) {
+        status = caption_frame_decode_midrowchange (frame,cc_data);
+    }
+
+    return status;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int caption_frame_from_text (caption_frame_t* frame, const utf8_char_t* data)
+{
+    int r, c, chan = 0;
+    ssize_t size = (ssize_t) strlen (data);
+    size_t char_count, char_length, line_length = 0, trimmed_length = 0;
+    caption_frame_init (frame);
+    frame->state.mod = CAPTION_POP_ON;
+
+    for (r = 0 ; 0 < size && SCREEN_ROWS > r ; ++r) {
+        const utf8_char_t* cap_data = data;
+        line_length = utf8_line_length (cap_data);
+        trimmed_length = utf8_trimmed_length (cap_data,line_length);
+        char_count = utf8_char_count (cap_data,trimmed_length);
+
+        // If char_count is greater than one line can display, split it.
+        if (SCREEN_COLS < char_count) {
+            char_count = utf8_wrap_length (cap_data,SCREEN_COLS);
+            line_length = utf8_string_length (cap_data,char_count+1);
+        }
+
+        // Write the line
+        for (c = 0 ; c < (int) char_count ; ++c) {
+            caption_frame_write_char (frame,r,c,eia608_style_white,0,&cap_data[0]);
+            char_length = utf8_char_length (cap_data);
+            cap_data += char_length;
+        }
+
+        data += line_length;
+        size -= (ssize_t) line_length;
+    }
+
+    caption_frame_end (frame);
+    return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+void caption_frame_to_text (caption_frame_t* frame, utf8_char_t* data)
+{
+    int r, c, x, s, uln;
+    eia608_style_t sty;
+
+    data[0] = 0;
+
+    for (r = 0 ; r < SCREEN_ROWS ; ++r) {
+        for (c = 0, x = 0 ; c < SCREEN_COLS ; ++c) {
+            const char* chr  = caption_frame_read_char (frame, r, c, &sty, &uln);
+
+            if (0 < (s = (int) utf8_char_copy (data,chr))) {
+                ++x; data += s;
+            }
+        }
+
+        if (x) {
+            strcpy ( (char*) data,"\r\n");
+            data += 2;
+        }
+    }
+}
+////////////////////////////////////////////////////////////////////////////////
+size_t caption_frame_dump_buffer (caption_frame_t* frame, utf8_char_t* buf)
+{
+    int r, c;
+    size_t bytes, total = 0;
+    bytes = sprintf (buf, "   row: %d\tcol: %d\n   mode: %s\troll-up: %d\n",
+                     frame->state.row, frame->state.col,
+                     eia608_mode_map[frame->state.mod],frame->state.rup?1+frame->state.rup:0);
+    total += bytes; buf += bytes;
+    bytes = sprintf (buf, "   00000000001111111111222222222233\n   01234567890123456789012345678901\n  %s--------------------------------%s\n",
+                     EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT, EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT);
+    total += bytes; buf += bytes;
+
+    for (r = 0 ; r < SCREEN_ROWS ; ++r) {
+        bytes = sprintf (buf, "%02d%s", r, EIA608_CHAR_VERTICAL_LINE);
+        total += bytes; buf += bytes;
+
+        for (c = 0 ; c < SCREEN_COLS ; ++c) {
+            caption_frame_cell_t* cell = frame_cell (frame,r,c);
+            bytes = utf8_char_copy (buf, (0==cell->data[0]) ?EIA608_CHAR_SPACE:&cell->data[0]);
+            total += bytes; buf += bytes;
+        }
+
+        bytes = sprintf (buf, "%s\n", EIA608_CHAR_VERTICAL_LINE);
+        total += bytes; buf += bytes;
+    }
+
+    bytes = sprintf (buf, "  %s--------------------------------%s\n",
+                     EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT, EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT);
+    total += bytes; buf += bytes;
+    return total;
+}
+
+void caption_frame_dump (caption_frame_t* frame)
+{
+    utf8_char_t buff[CAPTION_FRAME_DUMP_BUF_SIZE];
+    size_t size = caption_frame_dump_buffer (frame, buff);
+    fprintf (stderr,"%s\n", buff);
+}
+
+size_t caption_frame_json (caption_frame_t* frame, utf8_char_t* buf)
+{
+    size_t bytes, total = 0;
+    int r,c,count = 0;
+    bytes = sprintf (buf, "{\"format\":\"eia608\",\"mode\":\"%s\",\"rollUp\":%d,\"data\":[",
+                     eia608_mode_map[frame->state.mod],frame->state.rup?1+frame->state.rup:0);
+    total += bytes; buf += bytes;
+
+    for (r = 0 ; r < SCREEN_ROWS ; ++r) {
+        for (c = 0 ; c < SCREEN_COLS ; ++c) {
+            caption_frame_cell_t* cell = frame_cell (frame,r,c);
+
+            if (0 != cell->data[0]) {
+                const char* data = ('"' == cell->data[0]) ?"\\\"": (const char*) &cell->data[0]; //escape quote
+                bytes = sprintf (buf, "%s\n{\"row\":%d,\"col\":%d,\"char\":\"%s\",\"style\":\"%s\"}",
+                                 (0<count?",":""),r,c,data,eia608_style_map[cell->sty]);
+                total += bytes; buf += bytes; ++count;
+            }
+        }
+    }
+
+    bytes = sprintf (buf, "\n]}\n");
+    total += bytes; buf += bytes;
+    return total;
+}
diff --git a/deps/libcaption/src/cea708.c b/deps/libcaption/src/cea708.c
new file mode 100644
index 0000000..8eb7068
--- /dev/null
+++ b/deps/libcaption/src/cea708.c
@@ -0,0 +1,207 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include "cea708.h"
+#include <memory.h>
+
+int cea708_cc_count (user_data_t* data)
+{
+    return data->cc_count;
+}
+
+uint16_t cea708_cc_data (user_data_t* data, int index, int* valid, cea708_cc_type_t* type)
+{
+    (*valid) = data->cc_data[index].cc_valid;
+    (*type) = data->cc_data[index].cc_type;
+    return data->cc_data[index].cc_data;
+}
+
+
+int cea708_init (cea708_t* cea708)
+{
+    memset (cea708,0,sizeof (cea708_t));
+    cea708->country = country_united_states;
+    cea708->provider = t35_provider_atsc;
+    cea708->user_identifier = ('G'<<24) | ('A'<<16) | ('9'<<8) | ('4');
+    cea708->atsc1_data_user_data_type_code = 3; //what does 3 mean here?
+    cea708->directv_user_data_length = 0;
+    ///////////
+    cea708->user_data.process_em_data_flag = 0;
+    cea708->user_data.process_cc_data_flag = 1;
+    cea708->user_data.additional_data_flag = 0;
+    cea708->user_data.cc_count = 0;
+    return 1;
+}
+
+// 00 00 00  06 C1  FF FC 34 B9 FF : onCaptionInfo.
+int cea708_parse (uint8_t* data, size_t size, cea708_t* cea708)
+{
+    int i;
+    cea708->country = (itu_t_t35_country_code_t) (data[0]);
+    cea708->provider = (itu_t_t35_provider_code_t) ( (data[1] <<8) | data[2]);
+    cea708->atsc1_data_user_data_type_code = 0;
+    cea708->user_identifier = 0;
+    data += 3; size -= 3;
+
+    if (t35_provider_atsc == cea708->provider) {
+        // GA94
+        cea708->user_identifier = (data[0] <<24) | (data[1] <<16) | (data[2] <<8) | data[3];
+        data += 4; size -= 4;
+    }
+
+    // Im not sure what this extra byt is. It sonly seesm to come up in onCaptionInfo
+    // where country and provider are zero
+    if (0 == cea708->provider) {
+        data += 1; size -= 1;
+    } else if (t35_provider_atsc == cea708->provider || t35_provider_direct_tv == cea708->provider) {
+        cea708->atsc1_data_user_data_type_code = data[0];
+        data += 1; size -= 1;
+    }
+
+    if (t35_provider_direct_tv == cea708->provider) {
+        cea708->directv_user_data_length = data[0];
+        data += 1; size -= 1;
+    }
+
+    // TODO I believe this is condational on the above.
+    cea708->user_data.process_em_data_flag = !! (data[0]&0x80);
+    cea708->user_data.process_cc_data_flag = !! (data[0]&0x40);
+    cea708->user_data.additional_data_flag = !! (data[0]&0x20);
+    cea708->user_data.cc_count             = (data[0]&0x1F);
+    cea708->user_data.em_data              = data[1];
+    data += 2; size -= 2;
+
+    if (size < 3 * cea708->user_data.cc_count) {
+        cea708_init (cea708);
+        return 0;
+    }
+
+    for (i = 0 ; i < (int) cea708->user_data.cc_count ; ++i) {
+        cea708->user_data.cc_data[i].marker_bits = data[0]>>3;
+        cea708->user_data.cc_data[i].cc_valid    = data[0]>>2;
+        cea708->user_data.cc_data[i].cc_type     = data[0]>>0;
+        cea708->user_data.cc_data[i].cc_data     = data[1]<<8|data[2];
+        data += 3; size -= 3;
+    }
+
+    return 1;
+}
+
+int cea708_add_cc_data (cea708_t* cea708, int valid, cea708_cc_type_t type, uint16_t cc_data)
+{
+    if (31 <= cea708->user_data.cc_count) {
+        return 0;
+    }
+
+    cea708->user_data.cc_data[cea708->user_data.cc_count].marker_bits = 0x1F;
+    cea708->user_data.cc_data[cea708->user_data.cc_count].cc_valid = valid;
+    cea708->user_data.cc_data[cea708->user_data.cc_count].cc_type = type;
+    cea708->user_data.cc_data[cea708->user_data.cc_count].cc_data = cc_data;
+    ++cea708->user_data.cc_count;
+    return 1;
+}
+
+int cea708_render (cea708_t* cea708, uint8_t* data, size_t size)
+{
+    int i;    size_t total = 0;
+    data[0] = cea708->country;
+    data[1] = cea708->provider>>8;
+    data[2] = cea708->provider>>0;
+    total += 3; data += 3; size -= 3;
+
+    if (t35_provider_atsc == cea708->provider) {
+
+        data[0] = cea708->user_identifier >> 24;
+        data[1] = cea708->user_identifier >> 16;
+        data[2] = cea708->user_identifier >> 8;
+        data[3] = cea708->user_identifier >> 0;
+        total += 4; data += 4; size -= 4;
+    }
+
+    if (t35_provider_atsc == cea708->provider || t35_provider_direct_tv == cea708->provider) {
+        data[0] = cea708->atsc1_data_user_data_type_code;
+        total += 1; data += 1; size -= 1;
+    }
+
+    if (t35_provider_direct_tv == cea708->provider) {
+        data[0] = cea708->directv_user_data_length;
+        total += 1; data += 1; size -= 1;
+    }
+
+    data[1] = cea708->user_data.em_data;
+    data[0] = (cea708->user_data.process_em_data_flag?0x80:0x00)
+              | (cea708->user_data.process_cc_data_flag?0x40:0x00)
+              | (cea708->user_data.additional_data_flag?0x20:0x00)
+              | (cea708->user_data.cc_count & 0x1F);
+
+    total += 2; data += 2; size -= 2;
+
+    for (i = 0 ; i < (int) cea708->user_data.cc_count ; ++i) {
+        data[0] = (cea708->user_data.cc_data[i].marker_bits<<3)
+                  | (data[0] = cea708->user_data.cc_data[i].cc_valid<<2)
+                  | (data[0] = cea708->user_data.cc_data[i].cc_type);
+        data[1] = cea708->user_data.cc_data[i].cc_data>>8;
+        data[2] = cea708->user_data.cc_data[i].cc_data>>0;
+        total += 3; data += 3; size -= 3;
+    }
+
+    data[0] = 0xFF;
+    return (int) (total + 1);
+}
+
+cc_data_t cea708_encode_cc_data (int cc_valid, cea708_cc_type_t type, uint16_t cc_data)
+{
+    cc_data_t data = { 0x1F, cc_valid,type,cc_data};
+    return data;
+}
+
+void cea708_dump (cea708_t* cea708)
+{
+    int i;
+
+    for (i = 0 ; i < (int) cea708->user_data.cc_count ; ++i) {
+        cea708_cc_type_t type; int valid;
+        uint16_t cc_data = cea708_cc_data (&cea708->user_data, i, &valid, &type);
+
+        if (valid && cc_type_ntsc_cc_field_1 == type) {
+            eia608_dump (cc_data);
+        }
+    }
+}
+
+libcaption_stauts_t cea708_to_caption_frame (caption_frame_t* frame, cea708_t* cea708, double pts)
+{
+    int i, count = cea708_cc_count (&cea708->user_data);
+    libcaption_stauts_t status = LIBCAPTION_OK;
+
+    for (i = 0 ; i < count ; ++i) {
+        cea708_cc_type_t type; int valid;
+        uint16_t cc_data = cea708_cc_data (&cea708->user_data, i, &valid, &type);
+
+        if (valid && cc_type_ntsc_cc_field_1 == type) {
+            status = libcaption_status_update (status,caption_frame_decode (frame,cc_data, pts));
+        }
+    }
+
+    return status;
+}
diff --git a/deps/libcaption/src/eia608.c b/deps/libcaption/src/eia608.c
new file mode 100644
index 0000000..26add0d
--- /dev/null
+++ b/deps/libcaption/src/eia608.c
@@ -0,0 +1,754 @@
+/* Generated by re2c 0.15.3 on Tue Nov 22 15:42:35 2016 */
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include "eia608.h"
+#include <string.h>
+#include <stdio.h>
+
+////////////////////////////////////////////////////////////////////////////////
+int eia608_row_map[] = {10, -1, 0, 1, 2, 3, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9};
+int eia608_reverse_row_map[] = {2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0, 6, 7, 8, 9, 1};
+
+const char* eia608_mode_map[] = {
+    "clear",
+    "loading",
+    "popOn",
+    "paintOn",
+    "rollUp",
+};
+
+const char* eia608_style_map[] = {
+    "white",
+    "green",
+    "blue",
+    "cyan",
+    "red",
+    "yellow",
+    "magenta",
+    "italics",
+};
+
+static inline uint16_t eia608_row_pramble (int row, int chan, int x, int underline)
+{
+    row = eia608_reverse_row_map[row&0x0F];
+    return eia608_parity (0x1040 | (chan?0x0800:0x0000) | ( (row<<7) &0x0700) | ( (row<<5) &0x0020)) | ( (x<<1) &0x001E) | (underline?0x0001:0x0000);
+}
+
+uint16_t eia608_row_column_pramble (int row, int col, int chan, int underline) { return eia608_row_pramble (row,chan,0x10| (col/4),underline); }
+uint16_t eia608_row_style_pramble (int row, eia608_style_t style, int chan, int underline) { return eia608_row_pramble (row,chan,style,underline); }
+
+int eia608_parse_preamble (uint16_t cc_data, int* row, int* col, eia608_style_t* style, int* chan, int* underline)
+{
+    (*row) = eia608_row_map[ ( (0x0700 & cc_data) >> 7) | ( (0x0020 & cc_data) >> 5)];
+    (*chan) = !! (0x0800 & cc_data);
+    (*underline) = 0x0001 & cc_data;
+
+    if (0x0010 & cc_data) {
+        (*style) = eia608_style_white;
+        (*col) = 4* ( (0x000E & cc_data) >> 1);
+    } else {
+        (*style) = (0x000E & cc_data) >> 1;
+        (*col) = 0;
+    }
+
+    return 1;
+}
+
+int eia608_parse_midrowchange (uint16_t cc_data, int* chan, eia608_style_t* style, int* underline)
+{
+    (*chan) = !! (0x0800 & cc_data);
+
+    if (0x1120 == (0x7770 & cc_data)) {
+        (*style) = (0x000E & cc_data) >> 1;
+        (*underline) = 0x0001 & cc_data;
+    }
+
+    return 1;
+}
+////////////////////////////////////////////////////////////////////////////////
+// control command
+eia608_control_t eia608_parse_control (uint16_t cc_data, int* cc)
+{
+    if (0x0200&cc_data) {
+        (*cc) = (cc_data&0x0800?0x01:0x00);
+        return (eia608_control_t) (0x177F & cc_data);
+    } else {
+        (*cc) = (cc_data&0x0800?0x01:0x00) | (cc_data&0x0100?0x02:0x00);
+        return (eia608_control_t) (0x167F & cc_data);
+    }
+}
+
+uint16_t eia608_control_command (eia608_control_t cmd, int cc)
+{
+    uint16_t c = (cc&0x01) ?0x0800:0x0000;
+    uint16_t f = (cc&0x02) ?0x0100:0x0000;
+
+    if (eia608_tab_offset_0 == (eia608_control_t) (cmd&0xFFC0)) {
+        return (eia608_control_t) eia608_parity (cmd|c);
+    } else {
+        return (eia608_control_t) eia608_parity (cmd|c|f);
+    }
+}
+////////////////////////////////////////////////////////////////////////////////
+// text
+static const char* utf8_from_index (int idx) { return (0<=idx && EIA608_CHAR_COUNT>idx) ? eia608_char_map[idx] : ""; }
+static int eia608_to_index (uint16_t cc_data, int* chan, int* c1, int* c2)
+{
+    (*c1) = (*c2) = -1; (*chan) = 0;
+    cc_data &= 0x7F7F; // strip off parity bits
+
+    // Handle Basic NA BEFORE we strip the channel bit
+    if (eia608_is_basicna (cc_data)) {
+        // we got first char, yes. But what about second char?
+        (*c1) = (cc_data>>8) - 0x20;
+        cc_data &= 0x00FF;
+
+        if (0x0020<=cc_data && 0x0080>cc_data) {
+            (*c2) = cc_data - 0x20;
+            return 2;
+        }
+
+        return 1;
+    }
+
+    // Check then strip second channel toggle
+    (*chan) = cc_data & 0x0800;
+    cc_data = cc_data & 0xF7FF;
+
+    if (eia608_is_specialna (cc_data)) {
+        // Special North American character
+        (*c1) = cc_data - 0x1130 + 0x60;
+        return 1;
+    }
+
+    if (0x1220<=cc_data && 0x1240>cc_data) {
+        // Extended Western European character set, Spanish/Miscellaneous/French
+        (*c1) = cc_data - 0x1220 + 0x70;
+        return 1;
+    }
+
+    if (0x1320<=cc_data && 0x1340>cc_data) {
+        // Extended Western European character set, Portuguese/German/Danish
+        (*c1) = cc_data - 0x1320 + 0x90;
+        return 1;
+    }
+
+    return 0;
+}
+
+
+int eia608_to_utf8 (uint16_t c, int* chan, char* str1,  char* str2)
+{
+    int c1, c2;
+    size_t size = eia608_to_index (c,chan,&c1,&c2);
+    strncpy (str1, utf8_from_index (c1),5);
+    strncpy (str2, utf8_from_index (c2),5);
+    return (int)size;
+}
+
+uint16_t eia608_from_basicna (uint16_t bna1, uint16_t bna2)
+{
+    if (! eia608_is_basicna (bna1) || ! eia608_is_basicna (bna2)) {
+        return 0;
+    }
+
+    return eia608_parity ( ( (0xFF00&bna1) >>0) | ( (0xFF00&bna2) >>8));
+}
+
+// prototype for re2c generated function
+uint16_t _eia608_from_utf8 (const utf8_char_t* s);
+uint16_t eia608_from_utf8_1 (const utf8_char_t* c, int chan)
+{
+    uint16_t cc_data = _eia608_from_utf8 (c);
+
+    if (0 == cc_data) {
+        return cc_data;
+    }
+
+    if (chan && ! eia608_is_basicna (cc_data)) {
+        cc_data |= 0x0800;
+    }
+
+    return eia608_parity (cc_data);
+}
+
+uint16_t eia608_from_utf8_2 (const utf8_char_t* c1, const utf8_char_t* c2)
+{
+    uint16_t cc1 = _eia608_from_utf8 (c1);
+    uint16_t cc2 = _eia608_from_utf8 (c2);
+    return eia608_from_basicna (cc1,cc2);
+}
+////////////////////////////////////////////////////////////////////////////////
+void eia608_dump (uint16_t cc_data)
+{
+    eia608_style_t style;
+    const char* text = 0;
+    char char1[5], char2[5];
+    char1[0] = char2[0] = 0;
+    int row, col, chan, underline;
+
+    if (!eia608_parity_varify (cc_data)) {
+        text = "parity failed";
+    } else if (0 == eia608_parity_strip (cc_data)) {
+        text = "pad";
+    } else if (eia608_is_basicna (cc_data)) {
+        text = "basicna";
+        eia608_to_utf8 (cc_data,&chan,&char1[0],&char2[0]);
+    } else if (eia608_is_specialna (cc_data)) {
+        text = "specialna";
+        eia608_to_utf8 (cc_data,&chan,&char1[0],&char2[0]);
+    } else if (eia608_is_westeu (cc_data)) {
+        text = "westeu";
+        eia608_to_utf8 (cc_data,&chan,&char1[0],&char2[0]);
+    } else if (eia608_is_xds (cc_data)) {
+        text = "xds";
+    } else if (eia608_is_midrowchange (cc_data)) {
+        text = "midrowchange";
+    } else if (eia608_is_norpak (cc_data)) {
+        text = "norpak";
+    } else if (eia608_is_preamble (cc_data)) {
+        text = "preamble";
+        eia608_parse_preamble (cc_data, &row, &col, &style, &chan, &underline);
+        fprintf (stderr,"preamble %d %d %d %d %d\n", row, col, style, chan, underline);
+
+    } else if (eia608_is_control (cc_data)) {
+        switch (eia608_parse_control (cc_data,&chan)) {
+
+        default: text = "unknown_control"; break;
+
+        case eia608_tab_offset_0: text = "eia608_tab_offset_0"; break;
+
+        case eia608_tab_offset_1: text = "eia608_tab_offset_1"; break;
+
+        case eia608_tab_offset_2:text = "eia608_tab_offset_2"; break;
+
+        case eia608_tab_offset_3: text = "eia608_tab_offset_3"; break;
+
+        case eia608_control_resume_caption_loading: text = "eia608_control_resume_caption_loading"; break;
+
+        case eia608_control_backspace: text = "eia608_control_backspace"; break;
+
+        case eia608_control_alarm_off: text = "eia608_control_alarm_off"; break;
+
+        case eia608_control_alarm_on: text = "eia608_control_alarm_on"; break;
+
+        case eia608_control_delete_to_end_of_row: text = "eia608_control_delete_to_end_of_row"; break;
+
+        case eia608_control_roll_up_2: text = "eia608_control_roll_up_2"; break;
+
+        case eia608_control_roll_up_3: text = "eia608_control_roll_up_3"; break;
+
+        case eia608_control_roll_up_4: text = "eia608_control_roll_up_4"; break;
+
+        case eia608_control_resume_direct_captioning: text = "eia608_control_resume_direct_captioning"; break;
+
+        case eia608_control_text_restart: text = "eia608_control_text_restart"; break;
+
+        case eia608_control_text_resume_text_display: text = "eia608_control_text_resume_text_display"; break;
+
+        case eia608_control_erase_display_memory: text = "eia608_control_erase_display_memory"; break;
+
+        case eia608_control_carriage_return: text = "eia608_control_carriage_return"; break;
+
+        case eia608_control_erase_non_displayed_memory:text = "eia608_control_erase_non_displayed_memory"; break;
+
+        case eia608_control_end_of_caption: text = "eia608_control_end_of_caption"; break;
+        }
+    } else {
+        text = "unhandled";
+    }
+
+    fprintf (stderr,"cc %04X (%04X) '%s' '%s' (%s)\n", cc_data, eia608_parity_strip (cc_data), char1, char2, text);
+}
+////////////////////////////////////////////////////////////////////////////////
+// below this line is re2c
+uint16_t _eia608_from_utf8 (const utf8_char_t* s)
+{
+    const unsigned char* YYMARKER; // needed by default rule
+    const unsigned char* YYCURSOR = (const unsigned char*) s;
+
+    if (0==s) { return 0x0000;}
+
+    
+{
+    unsigned char yych;
+    yych = *YYCURSOR;
+    if (yych <= '`') {
+        if (yych <= '*') {
+            if (yych <= '&') {
+                if (yych <= 0x00) goto yy2;
+                if (yych <= 0x1F) goto yy32;
+                goto yy26;
+            } else {
+                if (yych <= '\'') goto yy4;
+                if (yych <= ')') goto yy26;
+                goto yy6;
+            }
+        } else {
+            if (yych <= ']') {
+                if (yych == '\\') goto yy8;
+                goto yy26;
+            } else {
+                if (yych <= '^') goto yy10;
+                if (yych <= '_') goto yy12;
+                goto yy14;
+            }
+        }
+    } else {
+        if (yych <= 0x7F) {
+            if (yych <= '|') {
+                if (yych <= 'z') goto yy26;
+                if (yych <= '{') goto yy16;
+                goto yy18;
+            } else {
+                if (yych <= '}') goto yy20;
+                if (yych <= '~') goto yy22;
+                goto yy24;
+            }
+        } else {
+            if (yych <= 0xC3) {
+                if (yych <= 0xC1) goto yy32;
+                if (yych <= 0xC2) goto yy31;
+                goto yy28;
+            } else {
+                if (yych == 0xE2) goto yy30;
+                goto yy32;
+            }
+        }
+    }
+yy2:
+    ++YYCURSOR;
+    { /*NULL*/ return 0x0000; }
+yy4:
+    ++YYCURSOR;
+    { /*APOSTROPHE -> RIGHT_SINGLE_QUOTATION_MARK*/ return 0x1229; }
+yy6:
+    ++YYCURSOR;
+    { /*ASTERISK*/ return 0x1228; }
+yy8:
+    ++YYCURSOR;
+    { /*REVERSE_SOLIDUS*/ return 0x132B; }
+yy10:
+    ++YYCURSOR;
+    { /*CIRCUMFLEX_ACCENT*/ return 0x132C; }
+yy12:
+    ++YYCURSOR;
+    { /*LOW_LINE*/ return 0x132D; }
+yy14:
+    ++YYCURSOR;
+    { /*GRAVE_ACCENT, No equivalent return 0x0000; return 1;*/ /*LEFT_SINGLE_QUOTATION_MARK*/ return 0x1226; }
+yy16:
+    ++YYCURSOR;
+    { /*LEFT_CURLY_BRACKET*/ return 0x1329; }
+yy18:
+    ++YYCURSOR;
+    { /*VERTICAL_LINE*/ return 0x132E; }
+yy20:
+    ++YYCURSOR;
+    { /*RIGHT_CURLY_BRACKET*/ return 0x132A; }
+yy22:
+    ++YYCURSOR;
+    { /*TILDE*/ return 0x132F; }
+yy24:
+    ++YYCURSOR;
+    { /*DEL/BACKSPACE. Need to set bits 9 and 12! return 0x1421;*/ return 0x0000; }
+yy26:
+    ++YYCURSOR;
+    { /*ASCII range*/ return (s[0]<<8) &0xFF00; }
+yy28:
+    ++YYCURSOR;
+    switch ((yych = *YYCURSOR)) {
+    case 0x80:    goto yy157;
+    case 0x81:    goto yy169;
+    case 0x82:    goto yy155;
+    case 0x83:    goto yy129;
+    case 0x84:    goto yy111;
+    case 0x85:    goto yy101;
+    case 0x87:    goto yy153;
+    case 0x88:    goto yy151;
+    case 0x89:    goto yy167;
+    case 0x8A:    goto yy149;
+    case 0x8B:    goto yy147;
+    case 0x8C:    goto yy123;
+    case 0x8D:    goto yy125;
+    case 0x8E:    goto yy143;
+    case 0x8F:    goto yy141;
+    case 0x91:    goto yy187;
+    case 0x92:    goto yy119;
+    case 0x93:    goto yy165;
+    case 0x94:    goto yy137;
+    case 0x95:    goto yy115;
+    case 0x96:    goto yy107;
+    case 0x98:    goto yy97;
+    case 0x99:    goto yy135;
+    case 0x9A:    goto yy163;
+    case 0x9B:    goto yy131;
+    case 0x9C:    goto yy161;
+    case 0x9F:    goto yy103;
+    case 0xA0:    goto yy183;
+    case 0xA1:    goto yy201;
+    case 0xA2:    goto yy179;
+    case 0xA3:    goto yy127;
+    case 0xA4:    goto yy109;
+    case 0xA5:    goto yy99;
+    case 0xA7:    goto yy191;
+    case 0xA8:    goto yy181;
+    case 0xA9:    goto yy199;
+    case 0xAA:    goto yy177;
+    case 0xAB:    goto yy145;
+    case 0xAC:    goto yy121;
+    case 0xAD:    goto yy197;
+    case 0xAE:    goto yy175;
+    case 0xAF:    goto yy139;
+    case 0xB1:    goto yy185;
+    case 0xB2:    goto yy117;
+    case 0xB3:    goto yy195;
+    case 0xB4:    goto yy173;
+    case 0xB5:    goto yy113;
+    case 0xB6:    goto yy105;
+    case 0xB7:    goto yy189;
+    case 0xB8:    goto yy95;
+    case 0xB9:    goto yy133;
+    case 0xBA:    goto yy193;
+    case 0xBB:    goto yy171;
+    case 0xBC:    goto yy159;
+    default:    goto yy29;
+    }
+yy29:
+    { /*DEFAULT_RULE*/ return 0x0000; }
+yy30:
+    yych = *(YYMARKER = ++YYCURSOR);
+    switch (yych) {
+    case 0x80:    goto yy63;
+    case 0x84:    goto yy64;
+    case 0x94:    goto yy61;
+    case 0x96:    goto yy66;
+    case 0x99:    goto yy65;
+    default:    goto yy29;
+    }
+yy31:
+    yych = *++YYCURSOR;
+    switch (yych) {
+    case 0xA0:    goto yy47;
+    case 0xA1:    goto yy45;
+    case 0xA2:    goto yy51;
+    case 0xA3:    goto yy49;
+    case 0xA4:    goto yy35;
+    case 0xA5:    goto yy37;
+    case 0xA6:    goto yy33;
+    case 0xA9:    goto yy43;
+    case 0xAB:    goto yy41;
+    case 0xAE:    goto yy59;
+    case 0xB0:    goto yy57;
+    case 0xBB:    goto yy39;
+    case 0xBD:    goto yy55;
+    case 0xBF:    goto yy53;
+    default:    goto yy29;
+    }
+yy32:
+    yych = *++YYCURSOR;
+    goto yy29;
+yy33:
+    ++YYCURSOR;
+    { /*BROKEN_BAR*/ return 0x1337; }
+yy35:
+    ++YYCURSOR;
+    { /*CURRENCY_SIGN*/ return 0x1336; }
+yy37:
+    ++YYCURSOR;
+    { /*YEN_SIGN*/ return 0x1335; }
+yy39:
+    ++YYCURSOR;
+    { /*RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK*/ return 0x123F; }
+yy41:
+    ++YYCURSOR;
+    { /*LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK*/ return 0x123E; }
+yy43:
+    ++YYCURSOR;
+    { /*COPYRIGHT_SIGN*/ return 0x122B; }
+yy45:
+    ++YYCURSOR;
+    { /*INVERTED_EXCLAMATION_MARK*/ return 0x1227; }
+yy47:
+    ++YYCURSOR;
+    { /*NO_BREAK_SPACE*/ return 0x1139; }
+yy49:
+    ++YYCURSOR;
+    { /*POUND_SIGN*/ return 0x1136; }
+yy51:
+    ++YYCURSOR;
+    { /*CENT_SIGN*/ return 0x1135; }
+yy53:
+    ++YYCURSOR;
+    { /*INVERTED_QUESTION_MARK*/ return 0x1133; }
+yy55:
+    ++YYCURSOR;
+    { /*VULGAR_FRACTION_ONE_HALF*/ return 0x1132; }
+yy57:
+    ++YYCURSOR;
+    { /*DEGREE_SIGN*/ return 0x1131; }
+yy59:
+    ++YYCURSOR;
+    { /*REGISTERED_SIGN*/ return 0x1130; }
+yy61:
+    yych = *++YYCURSOR;
+    switch (yych) {
+    case 0x8C:    goto yy87;
+    case 0x90:    goto yy89;
+    case 0x94:    goto yy91;
+    case 0x98:    goto yy93;
+    default:    goto yy62;
+    }
+yy62:
+    YYCURSOR = YYMARKER;
+    goto yy29;
+yy63:
+    yych = *++YYCURSOR;
+    switch (yych) {
+    case 0x94:    goto yy79;
+    case 0x98:    goto yy75;
+    case 0x99:    goto yy77;
+    case 0x9C:    goto yy83;
+    case 0x9D:    goto yy85;
+    case 0xA2:    goto yy81;
+    default:    goto yy62;
+    }
+yy64:
+    yych = *++YYCURSOR;
+    if (yych == 0xA0) goto yy73;
+    if (yych == 0xA2) goto yy71;
+    goto yy62;
+yy65:
+    yych = *++YYCURSOR;
+    if (yych == 0xAA) goto yy69;
+    goto yy62;
+yy66:
+    yych = *++YYCURSOR;
+    if (yych != 0x88) goto yy62;
+    ++YYCURSOR;
+    { /*FULL_BLOCK*/ return 0x7F00; }
+yy69:
+    ++YYCURSOR;
+    { /*EIGHTH_NOTE*/ return 0x1137; }
+yy71:
+    ++YYCURSOR;
+    { /*TRADE_MARK_SIGN*/ return 0x1134; }
+yy73:
+    ++YYCURSOR;
+    { /*SERVICE_MARK*/ return 0x122C; }
+yy75:
+    ++YYCURSOR;
+    { /*LEFT_SINGLE_QUOTATION_MARK*/ return 0x1226; }
+yy77:
+    ++YYCURSOR;
+    { /*RIGHT_SINGLE_QUOTATION_MARK -> APOSTROPHE*/ return 0x2700; }
+yy79:
+    ++YYCURSOR;
+    { /*EM_DASH*/ return 0x122A; }
+yy81:
+    ++YYCURSOR;
+    { /*BULLET*/ return 0x122D; }
+yy83:
+    ++YYCURSOR;
+    { /*LEFT_DOUBLE_QUOTATION_MARK*/ return 0x122E; }
+yy85:
+    ++YYCURSOR;
+    { /*RIGHT_DOUBLE_QUOTATION_MARK*/ return 0x122F; }
+yy87:
+    ++YYCURSOR;
+    { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT*/ return 0x133C; }
+yy89:
+    ++YYCURSOR;
+    { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT*/ return 0x133D; }
+yy91:
+    ++YYCURSOR;
+    { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT*/ return 0x133E; }
+yy93:
+    ++YYCURSOR;
+    { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT*/ return 0x133F; }
+yy95:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_O_WITH_STROKE*/ return 0x133B; }
+yy97:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_O_WITH_STROKE*/ return 0x133A; }
+yy99:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_A_WITH_RING_ABOVE*/ return 0x1339; }
+yy101:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE*/ return 0x1338; }
+yy103:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_SHARP_S*/ return 0x1334; }
+yy105:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_O_WITH_DIAERESIS*/ return 0x1333; }
+yy107:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS*/ return 0x1332; }
+yy109:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_A_WITH_DIAERESIS*/ return 0x1331; }
+yy111:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS*/ return 0x1330; }
+yy113:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_O_WITH_TILDE*/ return 0x1328; }
+yy115:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_O_WITH_TILDE*/ return 0x1327; }
+yy117:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_O_WITH_GRAVE*/ return 0x1326; }
+yy119:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_O_WITH_GRAVE*/ return 0x1325; }
+yy121:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_I_WITH_GRAVE*/ return 0x1324; }
+yy123:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_I_WITH_GRAVE*/ return 0x1323; }
+yy125:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_I_WITH_ACUTE*/ return 0x1322; }
+yy127:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_A_WITH_TILDE*/ return 0x1321; }
+yy129:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_A_WITH_TILDE*/ return 0x1320; }
+yy131:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX*/ return 0x123D; }
+yy133:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_U_WITH_GRAVE*/ return 0x123C; }
+yy135:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_U_WITH_GRAVE*/ return 0x123B; }
+yy137:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX*/ return 0x123A; }
+yy139:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_I_WITH_DIAERESIS*/ return 0x1239; }
+yy141:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS*/ return 0x1238; }
+yy143:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX*/ return 0x1237; }
+yy145:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_E_WITH_DIAERESIS*/ return 0x1236; }
+yy147:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS*/ return 0x1235; }
+yy149:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX*/ return 0x1234; }
+yy151:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_E_WITH_GRAVE*/ return 0x1233; }
+yy153:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_C_WITH_CEDILLA*/ return 0x1232; }
+yy155:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX*/ return 0x1231; }
+yy157:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_A_WITH_GRAVE*/ return 0x1230; }
+yy159:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_U_WITH_DIAERESIS*/ return 0x1225; }
+yy161:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS*/ return 0x1224; }
+yy163:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_U_WITH_ACUTE*/ return 0x1223; }
+yy165:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_O_WITH_ACUTE*/ return 0x1222; }
+yy167:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_E_WITH_ACUTE*/ return 0x1221; }
+yy169:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_A_WITH_ACUTE*/ return 0x1220; }
+yy171:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX*/ return 0x113F; }
+yy173:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX*/ return 0x113E; }
+yy175:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX*/ return 0x113D; }
+yy177:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX*/ return 0x113C; }
+yy179:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX*/ return 0x113B; }
+yy181:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_E_WITH_GRAVE*/ return 0x113A; }
+yy183:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_A_WITH_GRAVE*/ return 0x1138; }
+yy185:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_N_WITH_TILDE*/ return 0x7E00; }
+yy187:
+    ++YYCURSOR;
+    { /*LATIN_CAPITAL_LETTER_N_WITH_TILDE*/ return 0x7D00; }
+yy189:
+    ++YYCURSOR;
+    { /*DIVISION_SIGN*/ return 0x7C00; }
+yy191:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_C_WITH_CEDILLA*/ return 0x7B00; }
+yy193:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_U_WITH_ACUTE*/ return 0x6000; }
+yy195:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_O_WITH_ACUTE*/ return 0x5F00; }
+yy197:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_I_WITH_ACUTE*/ return 0x5E00; }
+yy199:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_E_WITH_ACUTE*/ return 0x5C00; }
+yy201:
+    ++YYCURSOR;
+    { /*LATIN_SMALL_LETTER_A_WITH_ACUTE*/ return 0x2A00; }
+}
+
+}
diff --git a/deps/libcaption/src/eia608.c.re2c b/deps/libcaption/src/eia608.c.re2c
new file mode 100644
index 0000000..633aa9d
--- /dev/null
+++ b/deps/libcaption/src/eia608.c.re2c
@@ -0,0 +1,421 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include "eia608.h"
+#include <string.h>
+#include <stdio.h>
+
+////////////////////////////////////////////////////////////////////////////////
+int eia608_row_map[] = {10, -1, 0, 1, 2, 3, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9};
+int eia608_reverse_row_map[] = {2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0, 6, 7, 8, 9, 1};
+
+const char* eia608_mode_map[] = {
+    "clear",
+    "loading",
+    "popOn",
+    "paintOn",
+    "rollUp",
+};
+
+const char* eia608_style_map[] = {
+    "white",
+    "green",
+    "blue",
+    "cyan",
+    "red",
+    "yellow",
+    "magenta",
+    "italics",
+};
+
+static inline uint16_t eia608_row_pramble (int row, int chan, int x, int underline)
+{
+    row = eia608_reverse_row_map[row&0x0F];
+    return eia608_parity (0x1040 | (chan?0x0800:0x0000) | ( (row<<7) &0x0700) | ( (row<<5) &0x0020)) | ( (x<<1) &0x001E) | (underline?0x0001:0x0000);
+}
+
+uint16_t eia608_row_column_pramble (int row, int col, int chan, int underline) { return eia608_row_pramble (row,chan,0x10| (col/4),underline); }
+uint16_t eia608_row_style_pramble (int row, eia608_style_t style, int chan, int underline) { return eia608_row_pramble (row,chan,style,underline); }
+
+int eia608_parse_preamble (uint16_t cc_data, int* row, int* col, eia608_style_t* style, int* chan, int* underline)
+{
+    (*row) = eia608_row_map[ ( (0x0700 & cc_data) >> 7) | ( (0x0020 & cc_data) >> 5)];
+    (*chan) = !! (0x0800 & cc_data);
+    (*underline) = 0x0001 & cc_data;
+
+    if (0x0010 & cc_data) {
+        (*style) = eia608_style_white;
+        (*col) = 4* ( (0x000E & cc_data) >> 1);
+    } else {
+        (*style) = (0x000E & cc_data) >> 1;
+        (*col) = 0;
+    }
+
+    return 1;
+}
+
+int eia608_parse_midrowchange (uint16_t cc_data, int* chan, eia608_style_t* style, int* underline)
+{
+    (*chan) = !! (0x0800 & cc_data);
+
+    if (0x1120 == (0x7770 & cc_data)) {
+        (*style) = (0x000E & cc_data) >> 1;
+        (*underline) = 0x0001 & cc_data;
+    }
+
+    return 1;
+}
+////////////////////////////////////////////////////////////////////////////////
+// control command
+eia608_control_t eia608_parse_control (uint16_t cc_data, int* cc)
+{
+    if (0x0200&cc_data) {
+        (*cc) = (cc_data&0x0800?0x01:0x00);
+        return (eia608_control_t) (0x177F & cc_data);
+    } else {
+        (*cc) = (cc_data&0x0800?0x01:0x00) | (cc_data&0x0100?0x02:0x00);
+        return (eia608_control_t) (0x167F & cc_data);
+    }
+}
+
+uint16_t eia608_control_command (eia608_control_t cmd, int cc)
+{
+    uint16_t c = (cc&0x01) ?0x0800:0x0000;
+    uint16_t f = (cc&0x02) ?0x0100:0x0000;
+
+    if (eia608_tab_offset_0 == (eia608_control_t) (cmd&0xFFC0)) {
+        return (eia608_control_t) eia608_parity (cmd|c);
+    } else {
+        return (eia608_control_t) eia608_parity (cmd|c|f);
+    }
+}
+////////////////////////////////////////////////////////////////////////////////
+// text
+static const char* utf8_from_index (int idx) { return (0<=idx && EIA608_CHAR_COUNT>idx) ? eia608_char_map[idx] : ""; }
+static int eia608_to_index (uint16_t cc_data, int* chan, int* c1, int* c2)
+{
+    (*c1) = (*c2) = -1; (*chan) = 0;
+    cc_data &= 0x7F7F; // strip off parity bits
+
+    // Handle Basic NA BEFORE we strip the channel bit
+    if (eia608_is_basicna (cc_data)) {
+        // we got first char, yes. But what about second char?
+        (*c1) = (cc_data>>8) - 0x20;
+        cc_data &= 0x00FF;
+
+        if (0x0020<=cc_data && 0x0080>cc_data) {
+            (*c2) = cc_data - 0x20;
+            return 2;
+        }
+
+        return 1;
+    }
+
+    // Check then strip second channel toggle
+    (*chan) = cc_data & 0x0800;
+    cc_data = cc_data & 0xF7FF;
+
+    if (eia608_is_specialna (cc_data)) {
+        // Special North American character
+        (*c1) = cc_data - 0x1130 + 0x60;
+        return 1;
+    }
+
+    if (0x1220<=cc_data && 0x1240>cc_data) {
+        // Extended Western European character set, Spanish/Miscellaneous/French
+        (*c1) = cc_data - 0x1220 + 0x70;
+        return 1;
+    }
+
+    if (0x1320<=cc_data && 0x1340>cc_data) {
+        // Extended Western European character set, Portuguese/German/Danish
+        (*c1) = cc_data - 0x1320 + 0x90;
+        return 1;
+    }
+
+    return 0;
+}
+
+
+int eia608_to_utf8 (uint16_t c, int* chan, char* str1,  char* str2)
+{
+    int c1, c2;
+    int size = (int) eia608_to_index (c,chan,&c1,&c2);
+    strncpy (str1, utf8_from_index (c1),5);
+    strncpy (str2, utf8_from_index (c2),5);
+    return size;
+}
+
+uint16_t eia608_from_basicna (uint16_t bna1, uint16_t bna2)
+{
+    if (! eia608_is_basicna (bna1) || ! eia608_is_basicna (bna2)) {
+        return 0;
+    }
+
+    return eia608_parity ( ( (0xFF00&bna1) >>0) | ( (0xFF00&bna2) >>8));
+}
+
+// prototype for re2c generated function
+uint16_t _eia608_from_utf8 (const utf8_char_t* s);
+uint16_t eia608_from_utf8_1 (const utf8_char_t* c, int chan)
+{
+    uint16_t cc_data = _eia608_from_utf8 (c);
+
+    if (0 == cc_data) {
+        return cc_data;
+    }
+
+    if (chan && ! eia608_is_basicna (cc_data)) {
+        cc_data |= 0x0800;
+    }
+
+    return eia608_parity (cc_data);
+}
+
+uint16_t eia608_from_utf8_2 (const utf8_char_t* c1, const utf8_char_t* c2)
+{
+    uint16_t cc1 = _eia608_from_utf8 (c1);
+    uint16_t cc2 = _eia608_from_utf8 (c2);
+    return eia608_from_basicna (cc1,cc2);
+}
+////////////////////////////////////////////////////////////////////////////////
+void eia608_dump (uint16_t cc_data)
+{
+    eia608_style_t style;
+    const char* text = 0;
+    char char1[5], char2[5];
+    char1[0] = char2[0] = 0;
+    int row, col, chan, underline;
+
+    if (!eia608_parity_varify (cc_data)) {
+        text = "parity failed";
+    } else if (0 == eia608_parity_strip (cc_data)) {
+        text = "pad";
+    } else if (eia608_is_basicna (cc_data)) {
+        text = "basicna";
+        eia608_to_utf8 (cc_data,&chan,&char1[0],&char2[0]);
+    } else if (eia608_is_specialna (cc_data)) {
+        text = "specialna";
+        eia608_to_utf8 (cc_data,&chan,&char1[0],&char2[0]);
+    } else if (eia608_is_westeu (cc_data)) {
+        text = "westeu";
+        eia608_to_utf8 (cc_data,&chan,&char1[0],&char2[0]);
+    } else if (eia608_is_xds (cc_data)) {
+        text = "xds";
+    } else if (eia608_is_midrowchange (cc_data)) {
+        text = "midrowchange";
+    } else if (eia608_is_norpak (cc_data)) {
+        text = "norpak";
+    } else if (eia608_is_preamble (cc_data)) {
+        text = "preamble";
+        eia608_parse_preamble (cc_data, &row, &col, &style, &chan, &underline);
+        fprintf (stderr,"preamble %d %d %d %d %d\n", row, col, style, chan, underline);
+
+    } else if (eia608_is_control (cc_data)) {
+        switch (eia608_parse_control (cc_data,&chan)) {
+
+        default: text = "unknown_control"; break;
+
+        case eia608_tab_offset_0: text = "eia608_tab_offset_0"; break;
+
+        case eia608_tab_offset_1: text = "eia608_tab_offset_1"; break;
+
+        case eia608_tab_offset_2:text = "eia608_tab_offset_2"; break;
+
+        case eia608_tab_offset_3: text = "eia608_tab_offset_3"; break;
+
+        case eia608_control_resume_caption_loading: text = "eia608_control_resume_caption_loading"; break;
+
+        case eia608_control_backspace: text = "eia608_control_backspace"; break;
+
+        case eia608_control_alarm_off: text = "eia608_control_alarm_off"; break;
+
+        case eia608_control_alarm_on: text = "eia608_control_alarm_on"; break;
+
+        case eia608_control_delete_to_end_of_row: text = "eia608_control_delete_to_end_of_row"; break;
+
+        case eia608_control_roll_up_2: text = "eia608_control_roll_up_2"; break;
+
+        case eia608_control_roll_up_3: text = "eia608_control_roll_up_3"; break;
+
+        case eia608_control_roll_up_4: text = "eia608_control_roll_up_4"; break;
+
+        case eia608_control_resume_direct_captioning: text = "eia608_control_resume_direct_captioning"; break;
+
+        case eia608_control_text_restart: text = "eia608_control_text_restart"; break;
+
+        case eia608_control_text_resume_text_display: text = "eia608_control_text_resume_text_display"; break;
+
+        case eia608_control_erase_display_memory: text = "eia608_control_erase_display_memory"; break;
+
+        case eia608_control_carriage_return: text = "eia608_control_carriage_return"; break;
+
+        case eia608_control_erase_non_displayed_memory:text = "eia608_control_erase_non_displayed_memory"; break;
+
+        case eia608_control_end_of_caption: text = "eia608_control_end_of_caption"; break;
+        }
+    } else {
+        text = "unhandled";
+    }
+
+    fprintf (stderr,"cc %04X (%04X) '%s' '%s' (%s)\n", cc_data, eia608_parity_strip (cc_data), char1, char2, text);
+}
+////////////////////////////////////////////////////////////////////////////////
+// below this line is re2c
+uint16_t _eia608_from_utf8 (const utf8_char_t* s)
+{
+    const unsigned char* YYMARKER; // needed by default rule
+    const unsigned char* YYCURSOR = (const unsigned char*) s;
+
+    if (0==s) { return 0x0000;}
+
+    /*!re2c
+    re2c:yyfill:enable = 0;
+    re2c:indent:string = "    ";
+    re2c:define:YYCTYPE = "unsigned char";
+
+    /*Ascii Exceptions*/
+    "\x00" { /*NULL*/ return 0x0000; }
+    "\x27" { /*APOSTROPHE -> RIGHT_SINGLE_QUOTATION_MARK*/ return 0x1229; }
+    "\x2A" { /*ASTERISK*/ return 0x1228; }
+    "\x5C" { /*REVERSE_SOLIDUS*/ return 0x132B; }
+    "\x5E" { /*CIRCUMFLEX_ACCENT*/ return 0x132C; }
+    "\x5F" { /*LOW_LINE*/ return 0x132D; }
+    /*Lets Map this to a LEFT_SINGLE_QUOTATION_MARK, just so we have a cc_data for every printable ASCII value*/
+    "\x60" { /*GRAVE_ACCENT, No equivalent return 0x0000; return 1;*/ /*LEFT_SINGLE_QUOTATION_MARK*/ return 0x1226; }
+    "\x7B" { /*LEFT_CURLY_BRACKET*/ return 0x1329; }
+    "\x7C" { /*VERTICAL_LINE*/ return 0x132E; }
+    "\x7D" { /*RIGHT_CURLY_BRACKET*/ return 0x132A; }
+    "\x7E" { /*TILDE*/ return 0x132F; }
+    /*There is a controll equivilant. Havnt decided if we want to habcle that here, or not*/
+    "\x7F" { /*DEL/BACKSPACE. Need to set bits 9 and 12! return 0x1421;*/ return 0x0000; }
+
+    /* Rules are processed top to bottom. So All single byte chars MUST be above this line!*/
+    [\x20-\x7F] { /*ASCII range*/ return (s[0]<<8) &0xFF00; } /* Should we use yych instead of s[0]?*/
+
+    /*This is the second half of the ascii exceptions*/
+    "\xC3\xA1" { /*LATIN_SMALL_LETTER_A_WITH_ACUTE*/ return 0x2A00; }
+    "\xC3\xA9" { /*LATIN_SMALL_LETTER_E_WITH_ACUTE*/ return 0x5C00; }
+    "\xC3\xAD" { /*LATIN_SMALL_LETTER_I_WITH_ACUTE*/ return 0x5E00; }
+    "\xC3\xB3" { /*LATIN_SMALL_LETTER_O_WITH_ACUTE*/ return 0x5F00; }
+    "\xC3\xBA" { /*LATIN_SMALL_LETTER_U_WITH_ACUTE*/ return 0x6000; }
+    "\xC3\xA7" { /*LATIN_SMALL_LETTER_C_WITH_CEDILLA*/ return 0x7B00; }
+    "\xC3\xB7" { /*DIVISION_SIGN*/ return 0x7C00; }
+    "\xC3\x91" { /*LATIN_CAPITAL_LETTER_N_WITH_TILDE*/ return 0x7D00; }
+    "\xC3\xB1" { /*LATIN_SMALL_LETTER_N_WITH_TILDE*/ return 0x7E00; }
+    "\xE2\x96\x88" { /*FULL_BLOCK*/ return 0x7F00; }
+
+    /*Special North American character set*/
+    "\xC2\xAE" { /*REGISTERED_SIGN*/ return 0x1130; }
+    "\xC2\xB0" { /*DEGREE_SIGN*/ return 0x1131; }
+    "\xC2\xBD" { /*VULGAR_FRACTION_ONE_HALF*/ return 0x1132; }
+    "\xC2\xBF" { /*INVERTED_QUESTION_MARK*/ return 0x1133; }
+    "\xE2\x84\xA2" { /*TRADE_MARK_SIGN*/ return 0x1134; }
+    "\xC2\xA2" { /*CENT_SIGN*/ return 0x1135; }
+    "\xC2\xA3" { /*POUND_SIGN*/ return 0x1136; }
+    "\xE2\x99\xAA" { /*EIGHTH_NOTE*/ return 0x1137; }
+    "\xC3\xA0" { /*LATIN_SMALL_LETTER_A_WITH_GRAVE*/ return 0x1138; }
+    "\xC2\xA0" { /*NO_BREAK_SPACE*/ return 0x1139; }
+    "\xC3\xA8" { /*LATIN_SMALL_LETTER_E_WITH_GRAVE*/ return 0x113A; }
+    "\xC3\xA2" { /*LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX*/ return 0x113B; }
+    "\xC3\xAA" { /*LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX*/ return 0x113C; }
+    "\xC3\xAE" { /*LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX*/ return 0x113D; }
+    "\xC3\xB4" { /*LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX*/ return 0x113E; }
+    "\xC3\xBB" { /*LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX*/ return 0x113F; }
+
+    /*Extended Spanish/Miscellaneous*/
+    "\xC3\x81" { /*LATIN_CAPITAL_LETTER_A_WITH_ACUTE*/ return 0x1220; }
+    "\xC3\x89" { /*LATIN_CAPITAL_LETTER_E_WITH_ACUTE*/ return 0x1221; }
+    "\xC3\x93" { /*LATIN_CAPITAL_LETTER_O_WITH_ACUTE*/ return 0x1222; }
+    "\xC3\x9A" { /*LATIN_CAPITAL_LETTER_U_WITH_ACUTE*/ return 0x1223; }
+    "\xC3\x9C" { /*LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS*/ return 0x1224; }
+    "\xC3\xBC" { /*LATIN_SMALL_LETTER_U_WITH_DIAERESIS*/ return 0x1225; }
+    "\xE2\x80\x98" { /*LEFT_SINGLE_QUOTATION_MARK*/ return 0x1226; }
+    "\xC2\xA1" { /*INVERTED_EXCLAMATION_MARK*/ return 0x1227; }
+    /*ASTERISK handled in ASCII mapping*/
+    "\xE2\x80\x99" { /*RIGHT_SINGLE_QUOTATION_MARK -> APOSTROPHE*/ return 0x2700; }
+    "\xE2\x80\x94" { /*EM_DASH*/ return 0x122A; }
+    "\xC2\xA9" { /*COPYRIGHT_SIGN*/ return 0x122B; }
+    "\xE2\x84\xA0" { /*SERVICE_MARK*/ return 0x122C; }
+    "\xE2\x80\xA2" { /*BULLET*/ return 0x122D; }
+    "\xE2\x80\x9C" { /*LEFT_DOUBLE_QUOTATION_MARK*/ return 0x122E; }
+    "\xE2\x80\x9D" { /*RIGHT_DOUBLE_QUOTATION_MARK*/ return 0x122F; }
+
+    /*Extended French*/
+    "\xC3\x80" { /*LATIN_CAPITAL_LETTER_A_WITH_GRAVE*/ return 0x1230; }
+    "\xC3\x82" { /*LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX*/ return 0x1231; }
+    "\xC3\x87" { /*LATIN_CAPITAL_LETTER_C_WITH_CEDILLA*/ return 0x1232; }
+    "\xC3\x88" { /*LATIN_CAPITAL_LETTER_E_WITH_GRAVE*/ return 0x1233; }
+    "\xC3\x8A" { /*LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX*/ return 0x1234; }
+    "\xC3\x8B" { /*LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS*/ return 0x1235; }
+    "\xC3\xAB" { /*LATIN_SMALL_LETTER_E_WITH_DIAERESIS*/ return 0x1236; }
+    "\xC3\x8E" { /*LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX*/ return 0x1237; }
+    "\xC3\x8F" { /*LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS*/ return 0x1238; }
+    "\xC3\xAF" { /*LATIN_SMALL_LETTER_I_WITH_DIAERESIS*/ return 0x1239; }
+    "\xC3\x94" { /*LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX*/ return 0x123A; }
+    "\xC3\x99" { /*LATIN_CAPITAL_LETTER_U_WITH_GRAVE*/ return 0x123B; }
+    "\xC3\xB9" { /*LATIN_SMALL_LETTER_U_WITH_GRAVE*/ return 0x123C; }
+    "\xC3\x9B" { /*LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX*/ return 0x123D; }
+    "\xC2\xAB" { /*LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK*/ return 0x123E; }
+    "\xC2\xBB" { /*RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK*/ return 0x123F; }
+
+    /*Portuguese*/
+    "\xC3\x83" { /*LATIN_CAPITAL_LETTER_A_WITH_TILDE*/ return 0x1320; }
+    "\xC3\xA3" { /*LATIN_SMALL_LETTER_A_WITH_TILDE*/ return 0x1321; }
+    "\xC3\x8D" { /*LATIN_CAPITAL_LETTER_I_WITH_ACUTE*/ return 0x1322; }
+    "\xC3\x8C" { /*LATIN_CAPITAL_LETTER_I_WITH_GRAVE*/ return 0x1323; }
+    "\xC3\xAC" { /*LATIN_SMALL_LETTER_I_WITH_GRAVE*/ return 0x1324; }
+    "\xC3\x92" { /*LATIN_CAPITAL_LETTER_O_WITH_GRAVE*/ return 0x1325; }
+    "\xC3\xB2" { /*LATIN_SMALL_LETTER_O_WITH_GRAVE*/ return 0x1326; }
+    "\xC3\x95" { /*LATIN_CAPITAL_LETTER_O_WITH_TILDE*/ return 0x1327; }
+    "\xC3\xB5" { /*LATIN_SMALL_LETTER_O_WITH_TILDE*/ return 0x1328; }
+    /*LEFT_CURLY_BRACKET handled in ASCII mapping*/
+    /*RIGHT_CURLY_BRACKET handled in ASCII mapping*/
+    /*REVERSE_SOLIDUS handled in ASCII mapping*/
+    /*CIRCUMFLEX_ACCENT handled in ASCII mapping*/
+    /*LOW_LINE handled in ASCII mapping*/
+    /*VERTICAL_LINE handled in ASCII mapping*/
+    /*TILDE handled in ASCII mapping*/
+
+    /*German/Danish*/
+    "\xC3\x84" { /*LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS*/ return 0x1330; }
+    "\xC3\xA4" { /*LATIN_SMALL_LETTER_A_WITH_DIAERESIS*/ return 0x1331; }
+    "\xC3\x96" { /*LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS*/ return 0x1332; }
+    "\xC3\xB6" { /*LATIN_SMALL_LETTER_O_WITH_DIAERESIS*/ return 0x1333; }
+    "\xC3\x9F" { /*LATIN_SMALL_LETTER_SHARP_S*/ return 0x1334; }
+    "\xC2\xA5" { /*YEN_SIGN*/ return 0x1335; }
+    "\xC2\xA4" { /*CURRENCY_SIGN*/ return 0x1336; }
+    "\xC2\xA6" { /*BROKEN_BAR*/ return 0x1337; }
+    "\xC3\x85" { /*LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE*/ return 0x1338; }
+    "\xC3\xA5" { /*LATIN_SMALL_LETTER_A_WITH_RING_ABOVE*/ return 0x1339; }
+    "\xC3\x98" { /*LATIN_CAPITAL_LETTER_O_WITH_STROKE*/ return 0x133A; }
+    "\xC3\xB8" { /*LATIN_SMALL_LETTER_O_WITH_STROKE*/ return 0x133B; }
+    "\xE2\x94\x8C" { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT*/ return 0x133C; }
+    "\xE2\x94\x90" { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT*/ return 0x133D; }
+    "\xE2\x94\x94" { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT*/ return 0x133E; }
+    "\xE2\x94\x98" { /*EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT*/ return 0x133F; }
+
+    /*Default rule*/
+    [^] { /*DEFAULT_RULE*/ return 0x0000; }
+    */
+}
diff --git a/deps/libcaption/src/eia608_charmap.c b/deps/libcaption/src/eia608_charmap.c
new file mode 100644
index 0000000..0c05652
--- /dev/null
+++ b/deps/libcaption/src/eia608_charmap.c
@@ -0,0 +1,54 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include "eia608_charmap.h"
+// 0 - 95: Basic North American character set
+// 96 - 111: Special North American character
+// 112 - 127: Extended Western European character set : Extended Spanish/Miscellaneous
+// 128 - 143: Extended Western European character set : Extended French
+// 144 - 159: Extended Western European character set : Portuguese
+// 160 - 175: Extended Western European character set : German/Danish
+const char* eia608_char_map[] = {
+    EIA608_CHAR_SPACE, EIA608_CHAR_EXCLAMATION_MARK, EIA608_CHAR_QUOTATION_MARK, EIA608_CHAR_NUMBER_SIGN, EIA608_CHAR_DOLLAR_SIGN, EIA608_CHAR_PERCENT_SIGN, EIA608_CHAR_AMPERSAND, EIA608_CHAR_RIGHT_SINGLE_QUOTATION_MARK,
+    EIA608_CHAR_LEFT_PARENTHESIS, EIA608_CHAR_RIGHT_PARENTHESIS, EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_ACUTE, EIA608_CHAR_PLUS_SIGN, EIA608_CHAR_COMMA, EIA608_CHAR_HYPHEN_MINUS, EIA608_CHAR_FULL_STOP, EIA608_CHAR_SOLIDUS,
+    EIA608_CHAR_DIGIT_ZERO, EIA608_CHAR_DIGIT_ONE, EIA608_CHAR_DIGIT_TWO, EIA608_CHAR_DIGIT_THREE, EIA608_CHAR_DIGIT_FOUR, EIA608_CHAR_DIGIT_FIVE, EIA608_CHAR_DIGIT_SIX, EIA608_CHAR_DIGIT_SEVEN, EIA608_CHAR_DIGIT_EIGHT,
+    EIA608_CHAR_DIGIT_NINE, EIA608_CHAR_COLON, EIA608_CHAR_SEMICOLON, EIA608_CHAR_LESS_THAN_SIGN, EIA608_CHAR_EQUALS_SIGN, EIA608_CHAR_GREATER_THAN_SIGN, EIA608_CHAR_QUESTION_MARK, EIA608_CHAR_COMMERCIAL_AT,
+    EIA608_CHAR_LATIN_CAPITAL_LETTER_A, EIA608_CHAR_LATIN_CAPITAL_LETTER_B, EIA608_CHAR_LATIN_CAPITAL_LETTER_C, EIA608_CHAR_LATIN_CAPITAL_LETTER_D, EIA608_CHAR_LATIN_CAPITAL_LETTER_E, EIA608_CHAR_LATIN_CAPITAL_LETTER_F, EIA608_CHAR_LATIN_CAPITAL_LETTER_G, EIA608_CHAR_LATIN_CAPITAL_LETTER_H,
+    EIA608_CHAR_LATIN_CAPITAL_LETTER_I, EIA608_CHAR_LATIN_CAPITAL_LETTER_J, EIA608_CHAR_LATIN_CAPITAL_LETTER_K, EIA608_CHAR_LATIN_CAPITAL_LETTER_L, EIA608_CHAR_LATIN_CAPITAL_LETTER_M, EIA608_CHAR_LATIN_CAPITAL_LETTER_N, EIA608_CHAR_LATIN_CAPITAL_LETTER_O, EIA608_CHAR_LATIN_CAPITAL_LETTER_P,
+    EIA608_CHAR_LATIN_CAPITAL_LETTER_Q, EIA608_CHAR_LATIN_CAPITAL_LETTER_R, EIA608_CHAR_LATIN_CAPITAL_LETTER_S, EIA608_CHAR_LATIN_CAPITAL_LETTER_T, EIA608_CHAR_LATIN_CAPITAL_LETTER_U, EIA608_CHAR_LATIN_CAPITAL_LETTER_V, EIA608_CHAR_LATIN_CAPITAL_LETTER_W, EIA608_CHAR_LATIN_CAPITAL_LETTER_X,
+    EIA608_CHAR_LATIN_CAPITAL_LETTER_Y, EIA608_CHAR_LATIN_CAPITAL_LETTER_Z, EIA608_CHAR_LEFT_SQUARE_BRACKET, EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_ACUTE, EIA608_CHAR_RIGHT_SQUARE_BRACKET, EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_ACUTE, EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_ACUTE,
+    EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_ACUTE, EIA608_CHAR_LATIN_SMALL_LETTER_A, EIA608_CHAR_LATIN_SMALL_LETTER_B, EIA608_CHAR_LATIN_SMALL_LETTER_C, EIA608_CHAR_LATIN_SMALL_LETTER_D, EIA608_CHAR_LATIN_SMALL_LETTER_E, EIA608_CHAR_LATIN_SMALL_LETTER_F, EIA608_CHAR_LATIN_SMALL_LETTER_G, EIA608_CHAR_LATIN_SMALL_LETTER_H,
+    EIA608_CHAR_LATIN_SMALL_LETTER_I, EIA608_CHAR_LATIN_SMALL_LETTER_J, EIA608_CHAR_LATIN_SMALL_LETTER_K, EIA608_CHAR_LATIN_SMALL_LETTER_L, EIA608_CHAR_LATIN_SMALL_LETTER_M, EIA608_CHAR_LATIN_SMALL_LETTER_N, EIA608_CHAR_LATIN_SMALL_LETTER_O, EIA608_CHAR_LATIN_SMALL_LETTER_P,
+    EIA608_CHAR_LATIN_SMALL_LETTER_Q, EIA608_CHAR_LATIN_SMALL_LETTER_R, EIA608_CHAR_LATIN_SMALL_LETTER_S, EIA608_CHAR_LATIN_SMALL_LETTER_T, EIA608_CHAR_LATIN_SMALL_LETTER_U, EIA608_CHAR_LATIN_SMALL_LETTER_V, EIA608_CHAR_LATIN_SMALL_LETTER_W, EIA608_CHAR_LATIN_SMALL_LETTER_X,
+    EIA608_CHAR_LATIN_SMALL_LETTER_Y, EIA608_CHAR_LATIN_SMALL_LETTER_Z, EIA608_CHAR_LATIN_SMALL_LETTER_C_WITH_CEDILLA, EIA608_CHAR_DIVISION_SIGN, EIA608_CHAR_LATIN_CAPITAL_LETTER_N_WITH_TILDE, EIA608_CHAR_LATIN_SMALL_LETTER_N_WITH_TILDE, EIA608_CHAR_FULL_BLOCK,
+    EIA608_CHAR_REGISTERED_SIGN, EIA608_CHAR_DEGREE_SIGN, EIA608_CHAR_VULGAR_FRACTION_ONE_HALF, EIA608_CHAR_INVERTED_QUESTION_MARK, EIA608_CHAR_TRADE_MARK_SIGN, EIA608_CHAR_CENT_SIGN, EIA608_CHAR_POUND_SIGN, EIA608_CHAR_EIGHTH_NOTE,
+    EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_GRAVE, EIA608_CHAR_NO_BREAK_SPACE, EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_GRAVE, EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX, EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX, EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX, EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX, EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX,
+    EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_ACUTE, EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_ACUTE, EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_ACUTE, EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_ACUTE, EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS, EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_DIAERESIS, EIA608_CHAR_LEFT_SINGLE_QUOTATION_MARK, EIA608_CHAR_INVERTED_EXCLAMATION_MARK,
+    EIA608_CHAR_ASTERISK, EIA608_CHAR_APOSTROPHE, EIA608_CHAR_EM_DASH, EIA608_CHAR_COPYRIGHT_SIGN, EIA608_CHAR_SERVICE_MARK, EIA608_CHAR_BULLET, EIA608_CHAR_LEFT_DOUBLE_QUOTATION_MARK, EIA608_CHAR_RIGHT_DOUBLE_QUOTATION_MARK,
+    EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_GRAVE, EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX, EIA608_CHAR_LATIN_CAPITAL_LETTER_C_WITH_CEDILLA, EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_GRAVE, EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX, EIA608_CHAR_LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS, EIA608_CHAR_LATIN_SMALL_LETTER_E_WITH_DIAERESIS, EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX,
+    EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS, EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_DIAERESIS, EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX, EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_GRAVE, EIA608_CHAR_LATIN_SMALL_LETTER_U_WITH_GRAVE, EIA608_CHAR_LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX, EIA608_CHAR_LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK, EIA608_CHAR_RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK,
+    EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_TILDE, EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_TILDE, EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_ACUTE, EIA608_CHAR_LATIN_CAPITAL_LETTER_I_WITH_GRAVE, EIA608_CHAR_LATIN_SMALL_LETTER_I_WITH_GRAVE, EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_GRAVE, EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_GRAVE, EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_TILDE,
+    EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_TILDE, EIA608_CHAR_LEFT_CURLY_BRACKET, EIA608_CHAR_RIGHT_CURLY_BRACKET, EIA608_CHAR_REVERSE_SOLIDUS, EIA608_CHAR_CIRCUMFLEX_ACCENT, EIA608_CHAR_LOW_LINE, EIA608_CHAR_VERTICAL_LINE, EIA608_CHAR_TILDE,
+    EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS, EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_DIAERESIS, EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS, EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_DIAERESIS, EIA608_CHAR_LATIN_SMALL_LETTER_SHARP_S, EIA608_CHAR_YEN_SIGN, EIA608_CHAR_CURRENCY_SIGN, EIA608_CHAR_BROKEN_BAR,
+    EIA608_CHAR_LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE, EIA608_CHAR_LATIN_SMALL_LETTER_A_WITH_RING_ABOVE, EIA608_CHAR_LATIN_CAPITAL_LETTER_O_WITH_STROKE, EIA608_CHAR_LATIN_SMALL_LETTER_O_WITH_STROKE, EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT, EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT, EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT, EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT,
+};
diff --git a/deps/libcaption/src/scc.c b/deps/libcaption/src/scc.c
new file mode 100644
index 0000000..7b42487
--- /dev/null
+++ b/deps/libcaption/src/scc.c
@@ -0,0 +1,54 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include "scc.h"
+#include "utf8.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define FRAME_RATE (1000.0/30)
+#define SCCTIME2MS(HH,MM,SS,FF) (((HH*3600.0 + MM*60.0 + SS) * 1000.0) + ( FF * FRAME_RATE ))
+
+// 00:00:25:16  9420 9440 aeae ae79 ef75 2068 6176 e520 79ef 75f2 20f2 ef62 eff4 e9e3 732c 2061 6e64 2049 94fe 9723 ea75 73f4 20f7 616e f420 f4ef 2062 e520 61f7 e573 ef6d e520 e96e 2073 7061 e3e5 ae80 942c 8080 8080 942f
+
+int scc_to_608 (const char* line, double* pts, uint16_t* cc, int cc_max)
+{
+    int cc_count = 0, cc_data = 0, hh = 0, mm = 0, ss = 0, ff = 0;
+
+    // TODO if ';' use 29.79 fps, if ':' use 30 fls
+    if (4 == sscanf (line, "%2d:%2d:%2d%*1[:;]%2d", &hh, &mm, &ss, &ff)) {
+        (*pts) = SCCTIME2MS (hh,mm,ss,ff); // scc files start at one hour for some reason
+        line += 12;
+
+        while (1 == sscanf (line, "%04x ", &cc_data)) {
+            line += 5; cc[cc_count] = cc_data; ++cc_count;
+
+            if (cc_count >= cc_max) {
+                break;
+            }
+        }
+    }
+
+    return cc_count;
+}
diff --git a/deps/libcaption/src/srt.c b/deps/libcaption/src/srt.c
new file mode 100644
index 0000000..badf5e4
--- /dev/null
+++ b/deps/libcaption/src/srt.c
@@ -0,0 +1,194 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+#include "srt.h"
+#include "utf8.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+
+srt_t* srt_new (const utf8_char_t* data, size_t size, double timestamp, srt_t* prev, srt_t** head)
+{
+    srt_t* srt = malloc (sizeof (srt_t)+size+1);
+    srt->next = 0;
+    srt->duration = 0;
+    srt->aloc = size;
+    srt->timestamp = timestamp;
+    utf8_char_t* dest = (utf8_char_t*) srt_data (srt);
+
+    if (prev) {
+        prev->next = srt;
+        prev->duration = timestamp - prev->timestamp;
+    }
+
+    if (head && 0 == (*head)) {
+        (*head) = srt;
+    }
+
+    if (data) {
+        memcpy (dest, data, size);
+    } else {
+        memset (dest, 0, size);
+    }
+
+    dest[size] = '\0';
+    return srt;
+}
+
+srt_t* srt_free_head (srt_t* head)
+{
+    srt_t* next = head->next;
+    free (head);
+    return next;
+}
+
+void srt_free (srt_t* srt)
+{
+    while (srt) {
+        srt = srt_free_head (srt);
+    }
+}
+
+#define SRTTIME2SECONDS(HH,MM,SS,MS) ((HH*3600.0) + (MM*60.0) + SS + (MS/1000.0))
+srt_t* srt_parse (const utf8_char_t* data, size_t size)
+{
+    int counter;
+    srt_t* head = 0, *prev = 0;
+    double str_pts = 0, end_pts = 0;
+    size_t line_length = 0, trimmed_length = 0;
+    int hh1, hh2, mm1, mm2, ss1, ss2, ms1, ms2;
+
+    for (;;) {
+        line_length = 0;
+
+        do {
+            data += line_length;
+            size -= line_length;
+            line_length = utf8_line_length (data);
+            trimmed_length = utf8_trimmed_length (data,line_length);
+            // Skip empty lines
+        } while (0 < line_length && 0 == trimmed_length);
+
+        // linelength cant be zero before EOF
+        if (0 == line_length) {
+            break;
+        }
+
+        counter = atoi (data);
+        // printf ("counter (%d): '%.*s'\n", line_length, (int) line_length, data);
+        data += line_length;
+        size -= line_length;
+
+        line_length = utf8_line_length (data);
+        // printf ("time (%d): '%.*s'\n", line_length, (int) line_length, data);
+
+        {
+            if (8 == sscanf (data, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d", &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2)) {
+                str_pts = SRTTIME2SECONDS (hh1, mm1, ss1, ms1);
+                end_pts = SRTTIME2SECONDS (hh2, mm2, ss2, ms2);
+            }
+
+            data += line_length;
+            size -= line_length;
+        }
+
+        // Caption text starts here
+        const utf8_char_t* text = data;
+        size_t text_size = 0;
+        // printf ("time: '(%f --> %f)\n",srt.srt_time, srt.end_time);
+
+        do {
+            line_length = utf8_line_length (data);
+            trimmed_length = utf8_trimmed_length (data,line_length);
+            // printf ("cap (%d): '%.*s'\n", line_length, (int) trimmed_length, data);
+            data += line_length;
+            size -= line_length;
+            text_size += line_length;
+        } while (trimmed_length);
+
+        // should we trim here?
+        srt_t* srt = srt_new (text,text_size,str_pts,prev,&head);
+        srt->duration = end_pts - str_pts;
+        prev = srt;
+    }
+
+    return head;
+}
+
+int srt_to_caption_frame (srt_t* srt, caption_frame_t* frame)
+{
+    const char* data = srt_data (srt);
+    return caption_frame_from_text (frame,data);
+}
+
+srt_t* srt_from_caption_frame (caption_frame_t* frame, srt_t* prev, srt_t** head)
+{
+    // CRLF per row, plus an extra at the end
+    srt_t* srt = srt_new (0, 2+CAPTION_FRAME_TEXT_BYTES, frame->timestamp, prev, head);
+    utf8_char_t* data = srt_data (srt);
+
+    caption_frame_to_text (frame,data);
+    // srt requires an extra new line
+    strcat ( (char*) data,"\r\n");
+
+    return srt;
+}
+
+static inline void _crack_time (double tt, int* hh, int* mm, int* ss, int* ms)
+{
+    (*ms) = (int) ((int64_t) (tt * 1000.0) % 1000);
+    (*ss) = (int) ((int64_t) (tt) % 60);
+    (*mm) = (int) ((int64_t) (tt / (60.0)) % 60);
+    (*hh) = (int) ((int64_t) (tt / (60.0*60.0)));
+}
+
+static void _dump (srt_t* head, char type)
+{
+    int i;
+    srt_t* srt;
+
+    if ('v' == type) {
+        printf ("WEBVTT\r\n");
+    }
+
+    for (srt = head, i = 1; srt; srt=srt_next (srt), ++i) {
+        int hh1, hh2, mm1, mm2, ss1, ss2, ms1, ms2;
+        _crack_time (srt->timestamp, &hh1, &mm1, &ss1, &ms1);
+        _crack_time (srt->timestamp + srt->duration, &hh2, &mm2, &ss2, &ms2);
+
+        if ('s' == type) {
+            printf ("%02d\r\n%d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n%s\r\n", i,
+                    hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2, srt_data (srt));
+        }
+
+        else if ('v' == type) {
+            printf ("%d:%02d:%02d.%03d --> %02d:%02d:%02d.%03d\r\n%s\r\n",
+                    hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2, srt_data (srt));
+        }
+    }
+}
+
+void srt_dump (srt_t* head) { _dump (head,'s'); }
+void vtt_dump (srt_t* head) { _dump (head,'v'); }
diff --git a/deps/libcaption/src/utf8.c b/deps/libcaption/src/utf8.c
new file mode 100644
index 0000000..d237eb2
--- /dev/null
+++ b/deps/libcaption/src/utf8.c
@@ -0,0 +1,170 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+
+
+
+#include "utf8.h"
+#include <string.h>
+
+const utf8_char_t* utf8_char_next (const char* s)
+{
+    if (0x80 == (s[0]&0xC0)) { ++s; }
+
+    return s;
+}
+
+// returnes the length of the char in bytes
+size_t utf8_char_length (const utf8_char_t* c)
+{
+    // count null term as zero size
+    if (0x00 == c[0]) { return 0; }
+
+    if (0x00 == (c[0]&0x80)) { return 1; }
+
+    if (0xC0 == (c[0]&0xE0) && 0x80 == (c[1]&0xC0)) { return 2; }
+
+    if (0xE0 == (c[0]&0xF0) && 0x80 == (c[1]&0xC0) && 0x80 == (c[2]&0xC0)) { return 3; }
+
+    if (0xF0 == (c[0]&0xF8) && 0x80 == (c[1]&0xC0) && 0x80 == (c[2]&0xC0) && 0x80 == (c[3]&0xC0)) { return 4; }
+
+    return 0;
+}
+
+// returns length of the string in bytes
+// size is number of charcter to count (0 to count until NULL term)
+size_t utf8_string_length (const utf8_char_t* data, utf8_size_t size)
+{
+    size_t char_length, byts = 0;
+
+    if (0 == size) {
+        size = utf8_char_count (data,0);
+    }
+
+    for (; 0 < size ; --size) {
+        if (0 == (char_length = utf8_char_length (data))) {
+            break;
+        }
+
+        data += char_length;
+        byts += char_length;
+    }
+
+    return byts;
+}
+
+size_t utf8_char_copy (utf8_char_t* dst, const utf8_char_t* src)
+{
+    size_t bytes = utf8_char_length (src);
+
+    if (bytes&&dst) {
+        memcpy (dst,src,bytes);
+        dst[bytes] = '\0';
+    }
+
+    return bytes;
+}
+
+// returnes the number of utf8 charcters in a string given the number of bytes
+// to count until the a null terminator, pass 0 for size
+utf8_size_t utf8_char_count (const char* data, size_t size)
+{
+    size_t i, bytes = 0;
+    utf8_size_t count = 0;
+
+    if (0 == size) {
+        size = strlen (data);
+    }
+
+    for (i = 0 ; i < size ; ++count, i += bytes) {
+        if (0 == (bytes = utf8_char_length (&data[i]))) {
+            break;
+        }
+    }
+
+    return count;
+}
+
+// returnes the length of the line in bytes triming not printable charcters at the end
+size_t utf8_trimmed_length (const char* data, size_t size)
+{
+    for (; 0 < size && ' ' >= (uint8_t) data[size-1] ; --size) { }
+
+    return size;
+}
+
+// returns the length in bytes of the line including the new line charcter(s)
+// auto detects between windows(CRLF), unix(LF), mac(CR) and riscos (LFCR) line endings
+size_t utf8_line_length (const char* data)
+{
+    size_t len = 0;
+
+    for (len = 0; 0 != data[len]; ++len) {
+        if ('\r' == data[len]) {
+            if ('\n' == data[len+1]) {
+                return len + 2; // windows
+            } else {
+                return len + 1; // unix
+            }
+        } else if ('\n' == data[len]) {
+            if ('\r' == data[len+1]) {
+                return len + 2; // riscos
+            } else {
+                return len + 1; // macos
+            }
+        }
+    }
+
+    return len;
+}
+
+// returns number of chars to include before split
+utf8_size_t utf8_wrap_length (const utf8_char_t* data, utf8_size_t size)
+{
+    // Set split_at to size, so if a split point cna not be found, retuns the size passed in
+    size_t char_length, char_count, split_at = size;
+
+    for (char_count = 0 ; char_count <= size ; ++char_count) {
+        if (' ' >= (*data)) {
+            split_at = char_count;
+        }
+
+        char_length = utf8_char_length (data);
+        data += char_length;
+    }
+
+    return split_at;
+}
+
+int utf8_line_count (const utf8_char_t* data)
+{
+    size_t len = 0;
+    int count = 0;
+
+    do {
+        len = utf8_line_length (data);
+        data += len; ++count;
+    } while (0<len);
+
+    return count-1;
+}
diff --git a/deps/libcaption/src/xds.c b/deps/libcaption/src/xds.c
new file mode 100644
index 0000000..1250dac
--- /dev/null
+++ b/deps/libcaption/src/xds.c
@@ -0,0 +1,51 @@
+/**********************************************************************************************/
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file  */
+/* except in compliance with the License. A copy of the License is located at                 */
+/*                                                                                            */
+/*     http://aws.amazon.com/apache2.0/                                                       */
+/*                                                                                            */
+/* or in the "license" file accompanying this file. This file is distributed on an "AS IS"    */
+/* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the    */
+/* License for the specific language governing permissions and limitations under the License. */
+/**********************************************************************************************/
+// http://www.theneitherworld.com/mcpoodle/SCC_TOOLS/DOCS/CC_XDS.HTML#PR
+#include "xds.h"
+#include "caption.h"
+#include <string.h>
+
+void xds_init (xds_t* xds)
+{
+    memset (xds,0,sizeof (xds_t));
+}
+
+int xds_decode (xds_t* xds, uint16_t cc)
+{
+    switch (xds->state) {
+    default:
+    case 0:
+        xds_init (xds);
+        xds->class = (cc&0x0F00) >>8;
+        xds->type = (cc&0x000F);
+        xds->state = 1;
+        return LIBCAPTION_OK;
+
+    case 1:
+        if (0x8F00 == (cc&0xFF00)) {
+            xds->checksum = (cc&0x007F);
+            xds->state = 0;
+            return LIBCAPTION_READY;
+        }
+
+        if (xds->size < 32) {
+            xds->content[xds->size+0] = (cc&0x7F00) >>8;
+            xds->content[xds->size+1] = (cc&0x007F);
+            xds->size += 2;
+            return LIBCAPTION_OK;
+        }
+    }
+
+    xds->state = 0;
+    return LIBCAPTION_ERROR;
+}
diff --git a/deps/libcaption/unit_tests/eia608_test.c b/deps/libcaption/unit_tests/eia608_test.c
new file mode 100644
index 0000000..9712107
--- /dev/null
+++ b/deps/libcaption/unit_tests/eia608_test.c
@@ -0,0 +1,280 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+
+#include "eia608.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+// all possible utf8 valies, including invalid ones
+void encode_utf8ish (int32_t in, char out[7])
+{
+    if (0 > in) {
+        out[0] = 0;
+        return;
+    }
+
+    // 0xxxxxxx, 7 bits
+    if (0x80 > in) {
+        out[0] = in;
+        out[1] = 0;
+        return;
+    }
+
+    // 110xxxxx   10xxxxxx, 11 bits
+    if (0x800 > in) {
+        out[0] = 0xC0 | ( (in >> (6*1)) & 0x1F);
+        out[1] = 0x80 | ( (in >> (6*0)) & 0x3F);
+        out[2] = 0;
+        return;
+    }
+
+    // 1110xxxx   10xxxxxx    10xxxxxx, 16 bits
+    if (0x10000 > in) {
+        out[0] = 0xE0 | ( (in >> (6*2)) & 0x0F);
+        out[1] = 0x80 | ( (in >> (6*1)) & 0x3F);
+        out[2] = 0x80 | ( (in >> (6*0)) & 0x3F);
+        out[3] = 0;
+        return;
+    }
+
+    // 11110xxx   10xxxxxx    10xxxxxx    10xxxxxx, 21 bits
+    if (0x200000 > in) {
+        out[0] = 0xF0 | ( (in >> (6*3)) & 0x07);
+        out[1] = 0x80 | ( (in >> (6*2)) & 0x3F);
+        out[2] = 0x80 | ( (in >> (6*1)) & 0x3F);
+        out[3] = 0x80 | ( (in >> (6*0)) & 0x3F);
+        out[4] = 0;
+        return;
+    }
+
+    // 111110xx   10xxxxxx    10xxxxxx    10xxxxxx    10xxxxxx, 26 bits
+    if (0x4000000 > in) {
+        out[0] = 0xF8 | ( (in >> (6*4)) & 0x03);
+        out[1] = 0x80 | ( (in >> (6*3)) & 0x3F);
+        out[2] = 0x80 | ( (in >> (6*2)) & 0x3F);
+        out[3] = 0x80 | ( (in >> (6*1)) & 0x3F);
+        out[4] = 0x80 | ( (in >> (6*0)) & 0x3F);
+        out[5] = 0;
+        return;
+    }
+
+    // 1111110x   10xxxxxx    10xxxxxx    10xxxxxx    10xxxxxx    10xxxxxx, 31 bits
+    if (0x80000000 > in) {
+        out[0] = 0xFC | ( (in >> (6*5)) & 0x01);
+        out[1] = 0x80 | ( (in >> (6*4)) & 0x3F);
+        out[2] = 0x80 | ( (in >> (6*3)) & 0x3F);
+        out[3] = 0x80 | ( (in >> (6*2)) & 0x3F);
+        out[4] = 0x80 | ( (in >> (6*1)) & 0x3F);
+        out[5] = 0x80 | ( (in >> (6*0)) & 0x3F);
+        out[6] = 0;
+        return;
+    }
+}
+
+void test_all_utf8()
+{
+    char s[7]; size_t size, count = 0; uint16_t code1, code2;
+
+    for (int i = 0 ; i < 0x80000000 ; ++i) {
+        encode_utf8ish (i, &s[0]);
+        code1 = eia608_from_utf8 ( (const char*) &s[0], 0, &size);
+
+        // code2 = eia608_from_utf8 ( (const char*) &s[0], 1, &size);
+        if (code1) {
+            ++count;
+            printf ("%d: string: '%s' code: %04X\n",count, &s[0],code1);
+        }
+    }
+
+    // Count must be 177
+    // 176 charcters, pile we have two mapping for left quote mark
+}
+
+#define BIN "%d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d"
+#define BIND(D) ((D)>>15)&0x01, ((D)>>14)&0x01,((D)>>13)&0x01,((D)>>12)&0x01,((D)>>11)&0x01,((D)>>10)&0x01,((D)>>9)&0x01,((D)>>8)&0x01,((D)>>7)&0x01,((D)>>6)&0x01,((D)>>5)&0x01,((D)>>4)&0x01,((D)>>3)&0x01,((D)>>2)&0x01,((D)>>1)&0x01,((D)>>0)&0x01
+
+
+void print_bin (int n)
+{
+    int mask = 0x80;
+
+    for (int mask = 0x80 ; mask ; mask >>= 1) {
+        printf ("%s", n & mask ? "1" : "0");
+    }
+
+    printf ("\n");
+}
+
+void void_test_all_possible_code_words()
+{
+    for (int i = 0 ; i <= 0x3FFF ; ++i) {
+        int16_t code = eia608_parity ( ( (i<<1) &0x7F00) | (i&0x7F));
+
+        int count =eia608_cc_data_is_extended_data_service (code)+
+                   eia608_cc_data_is_basic_north_american_character (code) +
+                   eia608_cc_data_is_special_north_american_character (code) +
+                   eia608_cc_data_is_extended_western_european_character (code) +
+                   eia608_cc_data_is_nonwestern_norpak_character (code) +
+                   eia608_cc_data_is_row_preamble (code) +
+                   eia608_cc_data_is_control_command (code);
+
+        if (1 < count) {
+            printf ("code 0x%04X matched >1\n",code&0x7F7F);
+        }
+
+        // if (0 == count) {
+        //     printf ("code 0x%04X not matched %d\n",eia608_strip_parity_bits (code), i);
+        // }
+    }
+}
+
+void print_charmap()
+{
+    for (int i = 0 ; i < EIA608_CHAR_COUNT ; ++i) {
+        printf ("%s", eia608_char_map[i]);
+    }
+
+    printf ("\n");
+}
+
+void dance()
+{
+    for (int i = 0 ; i < 100 ; ++i) {
+        const char* l = 0 == rand() % 2 ? EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT : EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT;
+        const char* r = 0 == rand() % 2 ? EIA608_CHAR_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT : EIA608_CHAR_BOX_DRAWINGS_LIGHT_UP_AND_LEFT;
+        printf ("%s %s%s%s%s%s%s%s %s ", EIA608_CHAR_EIGHTH_NOTE, l, EIA608_CHAR_LEFT_PARENTHESIS, EIA608_CHAR_EM_DASH, EIA608_CHAR_LOW_LINE, EIA608_CHAR_EM_DASH,
+                EIA608_CHAR_RIGHT_PARENTHESIS, r, EIA608_CHAR_EIGHTH_NOTE);
+    }
+
+}
+
+
+int main (int argc, const char** arg)
+{
+    // print_charmap();
+    // // return 0;
+    // srand (time (0));
+    // // test_all_utf8();
+    // // void_test_all_possible_code_words();
+    // // return 0;
+    // // print_charmap();
+    // dance();
+    // return 0;
+    for (int i = 0 ; i <= 0x3FFF ; ++i) {
+        uint16_t code1 = eia608_parity ( ( (i<<1) &0x7F00) | (i&0x7F));
+
+        switch (eia608_cc_data_type (code1)) {
+        default:
+        case EIA608_CC_DATA_UNKNOWN:
+            // printf ("Unknown code %04X\n",code);
+            break;
+
+        case EIA608_CC_DATA_CONTROL_COMMAND: {
+            int cc;
+            eia608_control_t cmd = eia608_parse_control (code1, &cc);
+            uint16_t code2 = eia608_control_command (cmd,cc);
+
+            if (code1 != code2) {
+                printf (BIN " != " BIN " (0x%04x != 0x%04x) cc: %d\n", BIND (code1), BIND (code2),code1,code2,cc);
+            }
+        } break;
+
+
+        case EIA608_CC_DATA_BASIC_NORTH_AMERICAN_CHARACTER: {
+            char char1[5], char2[5]; int chan; size_t size;
+
+            if (eia608_to_utf8 (code1, &chan, &char1[0], &char2[0])) {
+                uint16_t code2 = eia608_from_utf8_2 (&char1[0], &char2[0]);
+
+                // if the second char is invalid, mask it off, we will accept the first
+                if (0x80 < (code1 &0x007F) || 0x20 > (code1 &0x007F)) {
+                    code1 = (code1&0xFF00) |0x0080;
+                }
+
+                if (code1 == code2) {
+                    // printf ("%s " BIN " == " BIN " (0x%04x == 0x%04x)\n", &char1[0], BIND (code1), BIND (code2),code1,code2);
+                } else {
+                    printf ("%s %s " BIN " != " BIN " (0x%04x != 0x%04x)\n", &char1[0], &char2[0], BIND (code1), BIND (code2),code1,code2);
+                }
+            }
+
+        } break;
+
+        case EIA608_CC_DATA_SPECIAL_NORTH_AMERICAN_CHARACTER:
+        case EIA608_CC_DATA_EXTENDED_WESTERN_EUROPEAN_CHARACTER: {
+            char char1[5], char2[5]; int chan; size_t size;
+
+            if (eia608_to_utf8 (code1, &chan, &char1[0], &char2[0])) {
+                uint16_t code2 = eia608_from_utf8 (&char1[0], chan, &size);
+
+                if (code1 == code2) {
+                    // printf ("%s " BIN " == " BIN " (0x%04x == 0x%04x)\n", &char1[0], BIND (code1), BIND (code2),code1,code2);
+                } else {
+                    printf ("%s " BIN " != " BIN " (0x%04x != 0x%04x)\n", &char1[0], BIND (code1), BIND (code2),code1,code2);
+                }
+            }
+        } break;
+
+            // #define EIA608_CODE_ROW_PREAMBLE                        4
+            // #define EIA608_CODE_EXTENDED_DATA_SERVICE               5
+            // #define EIA608_CODE_CONTROL_COMMAND                     6
+        }
+    }
+
+    return 0;
+}
+
+
+
+
+//     for (uint16_t i  = 0 ; i < 0x4000; ++i) {
+//         int chan;
+//         char str[7];
+//         uint16_t code = ( (i<<1) &0x7F00) | (i & 0x007F);
+//
+//         if (eia608_to_utf8 (code,&chan,str)) {
+//             printf ("code: 0x%04X  str: '%s'\n", code,str);
+//         }
+//     }
+//
+//     // for(int i = 0 ; i < cie608_char_count ; ++i)
+//     // {
+//     //     cie608_char_map[i]
+//     //
+//     // }
+//
+//
+//     for (int i = 0 ; i < 128 ; ++i) {
+//         // print_bin( B7( i ) );
+//         // print_bin( eia608_parity_table[i] );
+//         printf ("%d  %d %d\n", i, 0x7F & eia608_parity_table[i], eia608_parity_table[i]);
+//         // if ( i != eia608_parity_table[i] )
+//         // {
+//         //   printf( "ERROR\n" );
+//         //
+//         // }
+//     }
+//
+// }
diff --git a/deps/libcaption/unit_tests/test_sei.c b/deps/libcaption/unit_tests/test_sei.c
new file mode 100644
index 0000000..0e321b3
--- /dev/null
+++ b/deps/libcaption/unit_tests/test_sei.c
@@ -0,0 +1,148 @@
+/**********************************************************************************************/
+/* The MIT License                                                                            */
+/*                                                                                            */
+/* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved.       */
+/*                                                                                            */
+/* Permission is hereby granted, free of charge, to any person obtaining a copy               */
+/* of this software and associated documentation files (the "Software"), to deal              */
+/* in the Software without restriction, including without limitation the rights               */
+/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                  */
+/* copies of the Software, and to permit persons to whom the Software is                      */
+/* furnished to do so, subject to the following conditions:                                   */
+/*                                                                                            */
+/* The above copyright notice and this permission notice shall be included in                 */
+/* all copies or substantial portions of the Software.                                        */
+/*                                                                                            */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                 */
+/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                   */
+/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                */
+/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                     */
+/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,              */
+/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                  */
+/* THE SOFTWARE.                                                                              */
+/**********************************************************************************************/
+
+#include "avcsei.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+uint8_t sei1[] = { 0x06, 0x04, 0x68, 0xB5, 0x00, 0x31, 0x47, 0x41, 0x39, 0x34, 0x03, 0xDF, 0xFF, 0xFC, 0xEC, 0xE5,
+                   0xFC, 0xAE, 0x80, 0xFC, 0x94, 0x52, 0xFC, 0x97, 0xA1, 0xFC, 0x2A, 0x20, 0xFC, 0xDC, 0x20, 0xFC,
+                   0x5E, 0x20, 0xFC, 0xDF, 0x20, 0xFC, 0xE0, 0x20, 0xFC, 0x91, 0x38, 0xFC, 0x20, 0x80, 0xFC, 0x91,
+                   0xBA, 0xFC, 0x20, 0xE9, 0xFC, 0x13, 0xA4, 0xFC, 0x20, 0xEF, 0xFC, 0x13, 0x26, 0xFC, 0x20, 0x75,
+                   0xFC, 0x92, 0xBC, 0xFC, 0x94, 0xF2, 0xFC, 0x97, 0xA1, 0xFC, 0x61, 0x80, 0xFC, 0x13, 0x31, 0xFC,
+                   0x20, 0xE5, 0xFC, 0x92, 0xB6, 0xFC, 0x20, 0xE9, 0xFC, 0x92, 0xB9, 0xFC, 0x20, 0xEF, 0xFC, 0x13,
+                   0xB3, 0xFC, 0x20, 0x75, 0xFC, 0x92, 0x25, 0xFC, 0x20, 0x80, 0xFF, 0x80,
+                 };
+
+uint8_t sei2[] = { 0x06, 0x04, 0x35, 0xB5, 0x00, 0x31, 0x47, 0x41, 0x39, 0x34, 0x03, 0xCE, 0xFF, 0xFC, 0x94, 0x26,
+                   0xFC, 0x94, 0xAD, 0xFC, 0x94, 0xF2, 0xFC, 0x43, 0xC1, 0xFC, 0xD0, 0x54, 0xFC, 0x49, 0x4F, 0xFC,
+                   0xCE, 0x20, 0xFC, 0x4C, 0x49, 0xFC, 0xCE, 0x45, 0xFC, 0xD3, 0x20, 0xFC, 0x52, 0x4F, 0xFC, 0x4C,
+                   0x4C, 0xFC, 0x20, 0xD5, 0xFC, 0xD0, 0x80, 0xFF, 0x80,
+                 };
+
+
+uint8_t sei3[] = { 0x06,
+                   0x04, 0x68, 0xB5, 0x00, 0x31, 0x47, 0x41, 0x39, 0x34, 0x03, 0xDF, 0xFF, 0xFC, 0xEC, 0xE5, 0xFC,
+                   0xAE, 0x80, 0xFC, 0x94, 0x52, 0xFC, 0x97, 0xA1, 0x00, 0x00, 0x03, 0x00, 0xFC, 0xDC, 0x20, 0xFC,
+                   0x5E, 0x20, 0xFC, 0xDF, 0x20, 0xFC, 0xE0, 0x20, 0xFC, 0x91, 0x38, 0xFC, 0x20, 0x80, 0xFC, 0x91,
+                   0xBA, 0xFC, 0x20, 0xE9, 0xFC, 0x13, 0xA4, 0xFC, 0x20, 0xEF, 0xFC, 0x13, 0x26, 0xFC, 0x20, 0x75,
+                   0xFC, 0x92, 0xBC, 0xFC, 0x94, 0xF2, 0xFC, 0x97, 0xA1, 0xFC, 0x61, 0x80, 0xFC, 0x13, 0x31, 0xFC,
+                   0x20, 0xE5, 0xFC, 0x92, 0xB6, 0xFC, 0x20, 0xE9, 0xFC, 0x92, 0xB9, 0xFC, 0x20, 0xEF, 0xFC, 0x13,
+                   0xB3, 0xFC, 0x20, 0x75, 0xFC, 0x92, 0x25, 0xFC, 0x20, 0x80, 0xFF,
+
+                   0x04, 0x68, 0xB5, 0x00, 0x31, 0x47, 0x41, 0x39, 0x34, 0x03, 0xDF, 0xFF, 0xFC, 0xEC, 0xE5,
+                   0xFC, 0xAE, 0x80, 0xFC, 0x94, 0x52, 0xFC, 0x97, 0xA1, 0x00, 0x00, 0x03, 0x00, 0xFC, 0xDC, 0x20,
+                   0xFC, 0x5E, 0x20, 0xFC, 0xDF, 0x20, 0xFC, 0xE0, 0x20, 0xFC, 0x91, 0x38, 0xFC, 0x20, 0x80, 0xFC,
+                   0x91, 0xBA, 0xFC, 0x20, 0xE9, 0xFC, 0x13, 0xA4, 0xFC, 0x20, 0xEF, 0xFC, 0x13, 0x26, 0xFC, 0x20,
+                   0x75, 0xFC, 0x92, 0xBC, 0xFC, 0x94, 0xF2, 0xFC, 0x97, 0xA1, 0xFC, 0x61, 0x80, 0xFC, 0x13, 0x31,
+                   0xFC, 0x20, 0xE5, 0xFC, 0x92, 0xB6, 0xFC, 0x20, 0xE9, 0xFC, 0x92, 0xB9, 0xFC, 0x20, 0xEF, 0xFC,
+                   0x13, 0xB3, 0xFC, 0x20, 0x75, 0xFC, 0x92, 0x25, 0xFC, 0x20, 0x80, 0xFF,
+                   0x80,
+                 };
+
+
+// TODO make SEI with multiple messages
+// TODO make SEI with emupation prevention
+
+
+uint8_t* read_file (const char* file, size_t* size)
+{
+    FILE* f = fopen (file, "rb");
+
+    if (! f) {
+        return 0;
+    }
+
+    fseek (f,0,SEEK_END);
+    (*size) = ftell (f);
+    fseek (f,0,SEEK_SET);
+    uint8_t* data = (uint8_t*) malloc (*size);
+
+    for (int i = 0 ; i < (*size) ;) {
+        i += fread (&data[i], 1, *size, f);
+    }
+
+    fclose (f);
+    return data;
+}
+
+int test_emulation_byte()
+{
+    avcsei_t sei;
+    avcsei_init (&sei);
+    avcsei_parse (&sei,sei3,sizeof (sei3));
+    avcsei_dump (&sei);
+    avcsei_free (&sei);
+}
+
+
+int main (int argc, const char** argv)
+{
+    // test_emulation_byte();
+    // return 0;
+
+    size_t size;
+    avcsei_t sei;
+    cea708_t cea708;
+    eia608_screen_t screen;
+    char screen_buf[EIA608_SCREEN_DUMP_BUF_SIZE];
+    char json_buf[EIA608_SCREEN_JSON_BUF_SIZE];
+
+    // uint8_t* data =
+    for (int i = 1 ; i < argc ; ++i) {
+        avcsei_init (&sei);
+        eia608_screen_init (&screen);
+        uint8_t* data = read_file (argv[i],&size);
+        avcsei_parse (&sei,data,size);
+        free (data);
+
+        // avcsei_parse (&sei,sei1,sizeof (sei1));
+
+        for (avcsei_message_t* msg = avcsei_message_head (&sei) ; msg ; msg = avcsei_message_next (msg)) {
+            if (sei_type_user_data_registered_itu_t_t35 == avcsei_message_type (msg)) {
+                // avcsei_dump (&sei);
+                avcsei_decode_cea708 (msg,&cea708);
+                int count = cea708_cc_count (&cea708.user_data);
+
+                for (int i = 0 ; i < count ; ++i) {
+                    cea708_cc_type_t type; int valid;
+                    uint16_t cc_data = cea708_cc_data (&cea708.user_data, i, &valid, &type);
+
+                    if (valid && (cc_type_ntsc_cc_field_1 == type || cc_type_ntsc_cc_field_2 == type)) {
+                        eia608_screen_decode (&screen,cc_data);
+                    }
+                }
+
+                // eia608_screen_dump (&screen, &screen_buf[0]);
+                // printf ("screen:\n%s\n",&screen_buf[0]);
+
+                eia608_screen_json (&screen, &json_buf[0]);
+                printf ("json:\n%s\n",&json_buf[0]);
+
+            }
+        }
+
+        avcsei_free (&sei);
+    }
+}
diff --git a/deps/libcaption/unit_tests/tos.scc b/deps/libcaption/unit_tests/tos.scc
new file mode 100644
index 0000000..70ce99d
--- /dev/null
+++ b/deps/libcaption/unit_tests/tos.scc
@@ -0,0 +1,154 @@
+Scenarist_SCC V1.0
+
+00:00:22:10	9420 94f2 97a2 d9ef 75a7 f2e5 2061 20ea e5f2 6b2c 2054 68ef 6dae 942c 8080 8080 942f
+
+00:00:23:28	9420 947c 97a2 4cef ef6b 2043 e5ec e961 2c20 f7e5 2068 6176 e520 f4ef 20e6 efec ecef f720 ef75 f220 7061 7373 e9ef 6e73 3b80 942c 8080 8080 942f
+
+00:00:25:16	9420 9440 aeae ae79 ef75 2068 6176 e520 79ef 75f2 20f2 ef62 eff4 e9e3 732c 2061 6e64 2049 94fe 9723 ea75 73f4 20f7 616e f420 f4ef 2062 e520 61f7 e573 ef6d e520 e96e 2073 7061 e3e5 ae80 942c 8080 8080 942f
+
+00:00:29:09	9420 9440 97a1 5768 7920 64ef 6ea7 f420 79ef 7520 ea75 73f4 2061 646d e9f4 20f4 6861 f480 94fe 97a2 79ef 75a7 f2e5 20e6 f2e5 616b e564 20ef 75f4 2062 7920 6d79 20f2 ef62 eff4 2068 616e 64bf 942c 8080 8080 942f
+
+00:00:33:19	9420 94e0 49a7 6d20 6eef f420 e6f2 e561 6be5 6420 ef75 f420 6279 ad20 e9f4 a773 aeae ae80 942c 8080 8080 942f
+
+00:00:36:10	9420 94f2 9723 aeae ae61 ecf2 e967 68f4 a120 46e9 6ee5 a180 942c 8080 8080 942f
+
+00:00:36:29	9420 945e 9723 49a7 6d20 e6f2 e561 6be5 6420 ef75 f4a1 2049 2068 6176 e520 6ee9 6768 f46d 61f2 e573 94f2 f468 61f4 2049 a76d 2062 e5e9 6e67 20e3 6861 73e5 64ae aeae 942c 8080 8080 942f
+
+00:00:39:27	9420 947c 97a2 aeae ae62 7920 f468 e573 e520 67e9 616e f420 f2ef 62ef f4e9 e320 e3ec 61f7 7320 efe6 2064 e561 f468 aeae ae80 942c 8080 8080 942f
+
+00:00:40:29	9420 9452 97a2 a246 ef75 f2f4 7920 79e5 61f2 7320 ec61 f4e5 f2a2 94e0 97a2 5768 61f4 e576 e5f2 2c20 5468 ef6d ae20 57e5 a7f2 e520 64ef 6ee5 ae80 942c 8080 8080 942f
+
+00:00:49:02	9420 94fe 9723 52ef 62ef f4a7 7320 6de5 6def f279 2073 796e e3e5 6420 616e 6420 ecef e36b e564 a180 942c 8080 8080 942f
+
+00:01:00:08	9420 94f2 97a1 5468 e973 20e9 7320 70f2 e5f4 f479 20e6 f2e5 616b 79ae 942c 8080 8080 942f
+
+00:01:56:03	9420 94e0 97a2 d368 ef75 ec64 6ea7 f420 79ef 7520 62e5 2064 eff7 6e20 f468 e5f2 e5bf 942c 8080 8080 942f
+
+00:02:09:29	9420 94fe 97a2 4920 68e5 61f2 6420 79ef 7520 6775 7973 20f4 61ec 6be9 6e67 20ec 6173 f420 6ee9 6768 f4ae 942c 8080 8080 942f
+
+00:02:15:02	9420 94e0 97a2 49f4 a773 206e eff4 206d 7920 e661 75ec f42c 2079 ef75 206b 6eef f7ae 942c 8080 8080 942f
+
+00:03:10:08	9420 94f4 97a1 c1f2 e520 79ef 7520 f2e5 6164 79bf 942c 8080 8080 942f
+
+00:03:11:24	9420 947c 9723 4fe6 20e3 ef75 f273 e520 79ef 75a7 f2e5 20f2 e561 6479 2c20 79ef 75a7 f2e5 2061 20f2 efe3 6b73 f461 f2ae 942c 8080 8080 942f
+
+00:03:16:02	9420 94e0 9723 c8ef f7a7 7320 e9f4 20ec efef 6be9 6e67 2c20 c261 f2ec e579 bf80 942c 8080 8080 942f
+
+00:03:17:27	9420 94fe 97a2 57e5 2073 68ef 75ec 6420 6861 76e5 2061 62ef 75f4 20f4 e56e 206d e96e 75f4 e573 aeae ae80 942c 8080 8080 942f
+
+00:03:20:19	9420 94f2 97a2 57e5 ecec 20f4 6861 f4a7 7320 70e5 f2e6 e5e3 f4ae 942c 8080 8080 942f
+
+00:03:22:05	9420 9440 57e5 a7f2 e520 ef6e 20e9 6e20 ef6e e5a1 20c1 ecec 2073 7973 f4e5 6d73 2067 efa1 94f4 97a1 d9e5 6168 2079 ef75 2c20 67ef a180 942c 8080 8080 942f
+
+00:03:26:29	9420 94e0 97a1 c7ef a120 cdef 76e5 2079 ef75 f220 6173 73e5 73a1 20c7 ef20 67ef 2067 efa1 942c 8080 8080 942f
+
+00:03:32:03	9420 94f2 4920 ecef 76e5 20e9 f4a1 2043 ef6d e520 ef6e 2c20 67ef a180 942c 8080 8080 942f
+
+00:03:42:08	9420 94f4 97a2 5468 61f4 a773 206e e9e3 e5ae 942c 8080 8080 942f
+
+00:03:43:18	9420 94f2 ceef f468 e96e 6720 f4ef 20f7 eff2 f279 2061 62ef 75f4 ae80 942c 8080 8080 942f
+
+00:03:45:11	9420 9476 97a1 5468 ef6d ae80 942c 8080 8080 942f
+
+00:03:50:07	9420 94f4 97a1 5468 e5f2 e520 7368 e520 e973 ae80 942c 8080 8080 942f
+
+00:03:52:27	9420 9476 97a2 ceef f7ae 942c 8080 8080 942f
+
+00:03:54:06	9420 94f4 97a1 d9ef 7520 ecef 76e5 2068 e5f2 ae80 942c 8080 8080 942f
+
+00:03:56:03	9420 94f2 97a2 d368 e520 e973 2079 ef75 f220 7061 7373 e9ef 6ea1 942c 8080 8080 942f
+
+00:03:59:04	9420 94f2 9723 c2e5 20f4 e56e 64e5 f220 f4ef 2068 e5f2 ae80 942c 8080 8080 942f
+
+00:04:00:15	9420 94e0 9723 c2e5 2068 ef6e e573 f4a1 2045 68ad 2062 e520 f4e5 6e64 e5f2 ae80 942c 8080 8080 942f
+
+00:04:04:02	9420 94f2 52e5 6de9 6e64 2068 e5f2 20f7 6861 f420 ecef 76e5 20e9 73ae 942c 8080 8080 942f
+
+00:04:51:05	9420 94f4 aeae ae61 6e64 2c20 61e3 f4e9 ef6e a180 942c 8080 8080 942f
+
+00:04:55:12	9420 94e0 97a1 cde5 6def f279 20ef 76e5 f2f7 f2e9 f4e5 20e9 6e20 70f2 ef67 f2e5 7373 a180 942c 8080 8080 942f
+
+00:04:58:02	9420 94f2 97a2 d9ef 75a7 f2e5 2061 20ea e5f2 6b2c 2054 68ef 6da1 942c 8080 8080 942f
+
+00:05:01:17	9420 94f2 9723 4f68 70ad 20d3 eff2 f279 a120 d3ef f2f2 79ae 942c 8080 8080 942f
+
+00:05:15:05	9420 94f4 97a2 4cef ef6b 2043 e5ec e961 ae80 942c 8080 8080 942f
+
+00:05:16:26	9420 94e0 57e5 2068 6176 e520 f4ef 20e6 efec ecef f720 ef75 f220 7061 7373 e9ef 6e73 ae80 942c 8080 8080 942f
+
+00:05:19:28	9420 94e0 9723 d9ef 7520 6861 76e5 2079 ef75 f220 f2ef 62ef f4e9 e373 aeae ae80 942c 8080 8080 942f
+
+00:05:23:20	9420 947c 9723 aeae ae61 6e64 2049 20ea 7573 f420 f761 6ef4 20f4 ef20 62e5 2061 f7e5 73ef 6de5 20e9 6e20 7370 61e3 e5ae 942c 8080 8080 942f
+
+00:05:37:21	9420 94fe 4f6b 6179 2c20 f468 e579 a7f2 e520 e3ef 6de9 6e67 ae20 54f7 ef20 6de9 6e75 f4e5 7320 ece5 e6f4 a180 942c 8080 8080 942f
+
+00:05:42:01	9420 94f2 9723 d370 e5e5 6420 e9f4 2075 702c 2054 68ef 6da1 942c 8080 8080 942f
+
+00:05:44:04	9420 94f4 97a2 d6e9 7661 e3e9 7373 e96d efa1 942c 8080 8080 942f
+
+00:05:45:05	9420 945e 97a2 5768 7920 64ef 6ea7 f420 79ef 7520 ea75 73f4 2061 646d e9f4 20f4 6861 f420 79ef 75a7 f2e5 94e0 97a1 e6f2 e561 6be5 6420 ef75 f420 6279 206d 7920 f2ef 62ef f420 6861 6e64 bf80 942c 8080 8080 942f
+
+00:05:54:26	9420 94e0 97a2 4ce9 73f4 e56e 2043 e5ec e961 2c20 4920 f761 7320 79ef 756e 67ae aeae 942c 8080 8080 942f
+
+00:05:58:18	9420 94f4 97a1 aeae ae61 6e64 2061 2064 e9e3 6bae 942c 8080 8080 942f
+
+00:05:59:18	9420 9452 c275 f420 f468 61f4 a773 206e ef20 f2e5 6173 ef6e 20f4 ef80 94f2 9723 64e5 73f4 f2ef 7920 f468 e520 f7ef f2ec 64ae 942c 8080 8080 942f
+
+00:06:04:00	9420 94f2 97a2 5768 7920 64ef e573 2068 e520 64ef 20f4 68e9 73bf 942c 8080 8080 942f
+
+00:06:05:12	9420 94e0 9723 57e5 2061 ecf2 e561 6479 20f4 f2e9 e564 20f4 6861 f420 ef6e e5a1 942c 8080 8080 942f
+
+00:06:10:21	9420 9476 97a1 c162 eff2 f4a1 942c 8080 8080 942f
+
+00:06:12:07	9420 9476 97a2 4375 f4a1 942c 8080 8080 942f
+
+00:06:13:06	9420 9476 5768 ef61 6161 a180 942c 8080 8080 942f
+
+00:06:18:06	9420 9476 5768 ef61 6161 a180 942c 8080 8080 942f
+
+00:06:20:06	9420 9476 ceef efef efef a180 942c 8080 8080 942f
+
+00:06:21:29	9420 94f2 97a2 d9ef 7520 62f2 ef6b e520 6d79 2068 e561 f2f4 ae80 942c 8080 8080 942f
+
+00:06:25:06	9420 9476 4920 6b6e eff7 ae80 942c 8080 8080 942f
+
+00:06:25:28	9420 94f2 d9ef 7520 e6ef f267 eff4 206d e520 ef6e 20e5 61f2 f468 ae80 942c 8080 8080 942f
+
+00:06:28:06	9420 9476 4920 6b6e eff7 ae80 942c 8080 8080 942f
+
+00:06:29:13	9420 94f2 4920 7368 ef75 ec64 20ea 7573 f420 e3f2 7573 6820 79ef 75ae 942c 8080 8080 942f
+
+00:06:35:07	9420 9476 97a2 49a7 6dad 942c 8080 8080 942f
+
+00:06:46:03	9420 94f4 9723 49a7 6d20 73ef f2f2 79ae 942c 8080 8080 942f
+
+00:06:49:02	9420 94f4 97a2 c7ef ef64 2061 64ad ece9 62ae 942c 8080 8080 942f
+
+00:06:58:01	9420 94f4 97a1 ceef f420 6d79 20e6 6175 ecf4 a180 942c 8080 8080 942f
+
+00:07:01:03	9420 94f4 9723 5468 e973 20f4 e96d e5ae 942c 8080 8080 942f
+
+00:07:07:01	9420 94f4 97a1 5175 e9e5 f420 ef6e 2073 e5f4 a180 942c 8080 8080 942f
+
+00:07:08:29	9420 94f2 9723 57e5 a7f2 e520 ef75 f420 efe6 20f4 e96d e5a1 942c 8080 8080 942f
+
+00:08:12:03	9420 9476 43ef 6de5 20ef 6ea1 942c 8080 8080 942f
+
+00:08:20:29	9420 94f4 97a2 52c1 c1c1 c1c1 c1c1 c1c8 a180 942c 8080 8080 942f
+
+00:08:22:24	9420 94f2 97a1 cde5 6def f279 20ef 76e5 f2f7 f2e9 f4e5 2c20 b9b0 25ae 942c 8080 8080 942f
+
+00:08:24:22	9420 94e0 9723 4361 70f4 61e9 6ea1 2057 e520 6861 76e5 20f4 ef20 6162 eff2 f4a1 942c 8080 8080 942f
+
+00:08:36:20	9420 94e0 97a1 5468 e520 f7ef f2ec 64a7 7320 e368 616e 67e5 642c 2043 e5ec e961 aeae ae80 942c 8080 8080 942f
+
+00:08:52:24	9420 94f2 97a2 aeae ae6d 6179 62e5 20f7 e520 e361 6e20 f4ef efae 942c 8080 8080 942f
+
+00:08:56:21	9420 94e0 9723 cde5 6def f279 20ef 76e5 f2f7 f2e9 f4e5 20e3 ef6d 70ec e5f4 e5a1 942c 8080 8080 942f
+
+00:09:17:29	9420 94f4 9723 d9ef 7520 6b6e eff7 ae80 942c 8080 8080 942f
+
+00:09:20:13	9420 947c 9723 5468 e5f2 e5a7 7320 6120 ece5 7373 ef6e 20f4 ef20 62e5 20ec e561 f26e e564 20e6 f2ef 6d20 f468 e973 ae80 942c 8080 8080 942f
+
+00:09:24:24	9420 94f2 97a2 43ef 75ec 64a7 6120 67ef 6ee5 20f7 eff2 73e5 ae80 942c 8080 8080 942f
+
diff --git a/deps/libff/libff/ff-decoder.c b/deps/libff/libff/ff-decoder.c
index a0e4088..6e9d05d 100644
--- a/deps/libff/libff/ff-decoder.c
+++ b/deps/libff/libff/ff-decoder.c
@@ -178,7 +178,7 @@ void ff_decoder_refresh(void *opaque)
 
 	struct ff_frame *frame;
 
-	if (decoder && decoder->stream) {
+	if (decoder->stream) {
 		if (decoder->frame_queue.size == 0) {
 			if (!decoder->eof || !decoder->finished) {
 				// We expected a frame, but there were none
diff --git a/deps/libff/libff/ff-demuxer.c b/deps/libff/libff/ff-demuxer.c
index 2feef7a..f027ad4 100644
--- a/deps/libff/libff/ff-demuxer.c
+++ b/deps/libff/libff/ff-demuxer.c
@@ -297,7 +297,13 @@ static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream)
 	}
 
 	if (codec == NULL) {
-		codec = avcodec_find_decoder(codec_context->codec_id);
+		if (codec_context->codec_id == AV_CODEC_ID_VP8)
+			codec = avcodec_find_decoder_by_name("libvpx");
+		else if (codec_context->codec_id == AV_CODEC_ID_VP9)
+			codec = avcodec_find_decoder_by_name("libvpx-vp9");
+
+		if (!codec)
+			codec = avcodec_find_decoder(codec_context->codec_id);
 		if (codec == NULL) {
 			av_log(NULL, AV_LOG_WARNING, "no decoder found for"
                                                      " codec with id %d",
@@ -377,7 +383,7 @@ static bool open_input(struct ff_demuxer *demuxer,
 	}
 
 	if (avformat_open_input(format_context, demuxer->input,
-			input_format, NULL) != 0)
+			input_format, &demuxer->options.custom_options) != 0)
 		return false;
 
 	return avformat_find_stream_info(*format_context, NULL) >= 0;
diff --git a/deps/libff/libff/ff-demuxer.h b/deps/libff/libff/ff-demuxer.h
index 48192f9..55562e4 100644
--- a/deps/libff/libff/ff-demuxer.h
+++ b/deps/libff/libff/ff-demuxer.h
@@ -40,6 +40,7 @@ struct ff_demuxer_options
 	bool is_hw_decoding;
 	bool is_looping;
 	enum AVDiscard frame_drop;
+	AVDictionary *custom_options;
 };
 
 typedef struct ff_demuxer_options ff_demuxer_options_t;
diff --git a/deps/libff/libff/ff-util.c b/deps/libff/libff/ff-util.c
index 814ca1b..ca6aa91 100644
--- a/deps/libff/libff/ff-util.c
+++ b/deps/libff/libff/ff-util.c
@@ -99,7 +99,8 @@ static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev)
 
 static void add_codec_to_list(const struct ff_format_desc *format_desc,
 		struct ff_codec_desc **first, struct ff_codec_desc **current,
-		enum AVCodecID id, const AVCodec *codec)
+		enum AVCodecID id, const AVCodec *codec,
+		bool ignore_compatability)
 {
 	if (codec == NULL)
 		codec = avcodec_find_encoder(id);
@@ -112,11 +113,13 @@ static void add_codec_to_list(const struct ff_format_desc *format_desc,
 	if (!av_codec_is_encoder(codec))
 		return;
 
-	// Format doesn't support this codec
-	unsigned int tag = av_codec_get_tag(format_desc->codec_tags,
-			codec->id);
-	if (tag == 0)
-		return;
+	if (!ignore_compatability) {
+		// Format doesn't support this codec
+		unsigned int tag = av_codec_get_tag(format_desc->codec_tags,
+				codec->id);
+		if (tag == 0)
+			return;
+	}
 
 	struct ff_codec_desc *d = av_mallocz(sizeof(struct ff_codec_desc));
 
@@ -150,16 +153,17 @@ static void add_codec_to_list(const struct ff_format_desc *format_desc,
 
 static void get_codecs_for_id(const struct ff_format_desc *format_desc,
 		struct ff_codec_desc **first, struct ff_codec_desc **current,
-		enum AVCodecID id)
+		enum AVCodecID id, bool ignore_compatability)
 {
 	const AVCodec *codec = NULL;
 	while ((codec = next_codec_for_id(id, codec)))
 		add_codec_to_list(format_desc, first, current, codec->id,
-				codec);
+				codec, ignore_compatability);
 }
 
 const struct ff_codec_desc *ff_codec_supported(
-		const struct ff_format_desc *format_desc)
+		const struct ff_format_desc *format_desc,
+		bool ignore_compatability)
 {
 	const AVCodecDescriptor **codecs;
 	unsigned int size;
@@ -172,7 +176,8 @@ const struct ff_codec_desc *ff_codec_supported(
 
 	for(i = 0; i < size; i++) {
 		const AVCodecDescriptor *codec = codecs[i];
-		get_codecs_for_id(format_desc, &first, &current, codec->id);
+		get_codecs_for_id(format_desc, &first, &current, codec->id,
+				ignore_compatability);
 	}
 
 	av_free((void *)codecs);
diff --git a/deps/libff/libff/ff-util.h b/deps/libff/libff/ff-util.h
index 7594676..ca6875d 100644
--- a/deps/libff/libff/ff-util.h
+++ b/deps/libff/libff/ff-util.h
@@ -37,7 +37,8 @@ const char *ff_codec_name_from_id(int codec_id);
 
 // Codec Description
 const struct ff_codec_desc *ff_codec_supported(
-		const struct ff_format_desc *format_desc);
+		const struct ff_format_desc *format_desc,
+		bool ignore_compatability);
 void ff_codec_desc_free(const struct ff_codec_desc *codec_desc);
 const char *ff_codec_desc_name(const struct ff_codec_desc *codec_desc);
 const char *ff_codec_desc_long_name(const struct ff_codec_desc *codec_desc);
diff --git a/deps/w32-pthreads/ANNOUNCE b/deps/w32-pthreads/ANNOUNCE
deleted file mode 100644
index 950c86f..0000000
--- a/deps/w32-pthreads/ANNOUNCE
+++ /dev/null
@@ -1,483 +0,0 @@
-PTHREADS-WIN32 RELEASE 2.9.0 (2012-05-25)
------------------------------------------
-Web Site: http://sourceware.org/pthreads-win32/
-FTP Site: ftp://sourceware.org/pub/pthreads-win32
-Maintainer: Ross Johnson <ross.johnson at loungebythelake.net>
-
-
-We are pleased to announce the availability of a new release of
-Pthreads-win32, an Open Source Software implementation of the
-Threads component of the POSIX 1003.1 2001 Standard for Microsoft's
-Win32 environment. Some functions from other sections of POSIX
-1003.1 2001 are also supported including semaphores and scheduling
-functions.
-
-Some common non-portable functions are also implemented for
-additional compatibility, as are a few functions specific
-to pthreads-win32 for easier integration with Win32 applications.
-
-Pthreads-win32 is free software, distributed under the GNU Lesser
-General Public License (LGPL).
-
-
-Acknowledgements
-----------------
-This library is based originally on a Win32 pthreads
-implementation contributed by John Bossom.
-
-The implementation of Condition Variables uses algorithms developed
-by Alexander Terekhov and Louis Thomas.
-
-The implementation of POSIX mutexes has been improved by Thomas Pfaff
-and later by Alexander Terekhov.
-
-The implementation of Spinlocks and Barriers was contributed
-by Ross Johnson.
-
-The implementation of read/write locks was contributed by
-Aurelio Medina and improved by Alexander Terekhov.
-
-Many others have contributed significant time and effort to solve crutial
-problems in order to make the library workable, robust and reliable.
-
-Thanks to Xavier Leroy for granting permission to use and modify his
-LinuxThreads manual pages.
-
-Thanks to The Open Group for making the Single Unix Specification
-publicly available - many of the manual pages included in the package
-were extracted from it.
-
-There is also a separate CONTRIBUTORS file. This file and others are
-on the web site:
-
-	http://sourceware.org/pthreads-win32
-
-As much as possible, the ChangeLog file acknowledges contributions to the
-code base in more detail.
-
-
-Changes since the last release
-------------------------------
-These are now documented in the NEWS file.
-See the ChangeLog file also.
-
-
-Known Bugs
-----------
-These are now documented in the BUGS file.
-
-
-Level of standards conformance
-------------------------------
-
-The following POSIX 1003.1 2001 options are defined and set to 200112L:
-
-      _POSIX_THREADS
-      _POSIX_THREAD_SAFE_FUNCTIONS
-      _POSIX_THREAD_ATTR_STACKSIZE
-      _POSIX_THREAD_PRIORITY_SCHEDULING
-      _POSIX_SEMAPHORES
-      _POSIX_READER_WRITER_LOCKS
-      _POSIX_SPIN_LOCKS
-      _POSIX_BARRIERS
-
-
-The following POSIX 1003.1 2001 options are defined and set to -1:
-
-      _POSIX_THREAD_ATTR_STACKADDR
-      _POSIX_THREAD_PRIO_INHERIT
-      _POSIX_THREAD_PRIO_PROTECT
-      _POSIX_THREAD_PROCESS_SHARED
-
-
-The following POSIX 1003.1 2001 limits are defined and set:
-
-      _POSIX_THREAD_THREADS_MAX
-      _POSIX_SEM_VALUE_MAX
-      _POSIX_SEM_NSEMS_MAX
-      _POSIX_THREAD_KEYS_MAX
-      _POSIX_THREAD_DESTRUCTOR_ITERATIONS
-      PTHREAD_STACK_MIN
-      PTHREAD_THREADS_MAX
-      SEM_VALUE_MAX
-      SEM_NSEMS_MAX
-      PTHREAD_KEYS_MAX
-      PTHREAD_DESTRUCTOR_ITERATIONS
-
-
-The following functions are implemented:
-
-      ---------------------------
-      PThreads
-      ---------------------------
-      pthread_attr_init
-      pthread_attr_destroy
-      pthread_attr_getdetachstate
-      pthread_attr_getstackaddr
-      pthread_attr_getstacksize
-      pthread_attr_setdetachstate
-      pthread_attr_setstackaddr
-      pthread_attr_setstacksize
-
-      pthread_create
-      pthread_detach
-      pthread_equal
-      pthread_exit
-      pthread_join
-      pthread_once
-      pthread_self
-
-      pthread_cancel
-      pthread_cleanup_pop
-      pthread_cleanup_push
-      pthread_setcancelstate
-      pthread_setcanceltype
-      pthread_testcancel
-
-      ---------------------------
-      Thread Specific Data
-      ---------------------------
-      pthread_key_create
-      pthread_key_delete
-      pthread_setspecific
-      pthread_getspecific
-
-      ---------------------------
-      Mutexes
-      ---------------------------
-      pthread_mutexattr_init
-      pthread_mutexattr_destroy
-      pthread_mutexattr_getpshared
-      pthread_mutexattr_setpshared
-      pthread_mutexattr_gettype
-      pthread_mutexattr_settype (types: PTHREAD_MUTEX_DEFAULT
-					PTHREAD_MUTEX_NORMAL
-					PTHREAD_MUTEX_ERRORCHECK
-					PTHREAD_MUTEX_RECURSIVE  )
-      pthread_mutexattr_getrobust
-      pthread_mutexattr_setrobust (values: PTHREAD_MUTEX_STALLED
-                                           PTHREAD_MUTEX_ROBUST)
-      pthread_mutex_init
-      pthread_mutex_destroy
-      pthread_mutex_lock
-      pthread_mutex_trylock
-      pthread_mutex_timedlock
-      pthread_mutex_unlock
-      pthread_mutex_consistent
-
-      ---------------------------
-      Condition Variables
-      ---------------------------
-      pthread_condattr_init
-      pthread_condattr_destroy
-      pthread_condattr_getpshared
-      pthread_condattr_setpshared
-
-      pthread_cond_init
-      pthread_cond_destroy
-      pthread_cond_wait
-      pthread_cond_timedwait
-      pthread_cond_signal
-      pthread_cond_broadcast
-
-      ---------------------------
-      Read/Write Locks
-      ---------------------------
-      pthread_rwlock_init
-      pthread_rwlock_destroy
-      pthread_rwlock_tryrdlock
-      pthread_rwlock_trywrlock
-      pthread_rwlock_rdlock
-      pthread_rwlock_timedrdlock
-      pthread_rwlock_rwlock
-      pthread_rwlock_timedwrlock
-      pthread_rwlock_unlock
-      pthread_rwlockattr_init
-      pthread_rwlockattr_destroy
-      pthread_rwlockattr_getpshared
-      pthread_rwlockattr_setpshared
-
-      ---------------------------
-      Spin Locks
-      ---------------------------
-      pthread_spin_init
-      pthread_spin_destroy
-      pthread_spin_lock
-      pthread_spin_unlock
-      pthread_spin_trylock
-
-      ---------------------------
-      Barriers
-      ---------------------------
-      pthread_barrier_init
-      pthread_barrier_destroy
-      pthread_barrier_wait
-      pthread_barrierattr_init
-      pthread_barrierattr_destroy
-      pthread_barrierattr_getpshared
-      pthread_barrierattr_setpshared
-
-      ---------------------------
-      Semaphores
-      ---------------------------
-      sem_init
-      sem_destroy
-      sem_post
-      sem_wait
-      sem_trywait
-      sem_timedwait
-      sem_getvalue	     (# free if +ve, # of waiters if -ve)
-      sem_open		     (returns an error ENOSYS)
-      sem_close 	     (returns an error ENOSYS)
-      sem_unlink	     (returns an error ENOSYS)
-
-      ---------------------------
-      RealTime Scheduling
-      ---------------------------
-      pthread_attr_getschedparam
-      pthread_attr_setschedparam
-      pthread_attr_getinheritsched
-      pthread_attr_setinheritsched
-      pthread_attr_getschedpolicy (only supports SCHED_OTHER)
-      pthread_attr_setschedpolicy (only supports SCHED_OTHER)
-      pthread_getschedparam
-      pthread_setschedparam
-      pthread_getconcurrency
-      pthread_setconcurrency
-      pthread_attr_getscope
-      pthread_attr_setscope  (only supports PTHREAD_SCOPE_SYSTEM)
-      sched_get_priority_max
-      sched_get_priority_min
-      sched_rr_get_interval  (returns an error ENOTSUP)
-      sched_setscheduler     (only supports SCHED_OTHER)
-      sched_getscheduler     (only supports SCHED_OTHER)
-      sched_yield
-
-      ---------------------------
-      Signals
-      ---------------------------
-      pthread_sigmask
-      pthread_kill           (only supports zero sig value,
-                              for thread validity checking)
-
-      ---------------------------
-      Non-portable routines (see the README.NONPORTABLE file for usage)
-      ---------------------------
-      pthread_getw32threadhandle_np
-      pthread_timechange_handler_np
-      pthread_delay_np
-      pthread_getunique_np
-      pthread_mutexattr_getkind_np
-      pthread_mutexattr_setkind_np	(types: PTHREAD_MUTEX_FAST_NP,
-						PTHREAD_MUTEX_ERRORCHECK_NP,
-						PTHREAD_MUTEX_RECURSIVE_NP,
-						PTHREAD_MUTEX_ADAPTIVE_NP,
-						PTHREAD_MUTEX_TIMED_NP)
-      pthread_num_processors_np
-      (The following four routines may be required when linking statically.
-       The process_* routines should not be needed for MSVC or GCC.)
-      pthread_win32_process_attach_np
-      pthread_win32_process_detach_np
-      (The following routines should only be needed to manage implicit
-       POSIX handles i.e. when Win native threads call POSIX thread routines
-       (other than pthread_create))
-      pthread_win32_thread_attach_np
-      pthread_win32_thread_detach_np
-
-      ---------------------------
-      Static Initializers
-      ---------------------------
-      PTHREAD_ONCE_INIT
-      PTHREAD_MUTEX_INITIALIZER
-      PTHREAD_RECURSIVE_MUTEX_INITIALIZER
-      PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
-      PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
-      PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-      PTHREAD_COND_INITIALIZER
-      PTHREAD_RWLOCK_INITIALIZER
-      PTHREAD_SPINLOCK_INITIALIZER
-
-
-The library includes two non-API functions for creating cancellation
-points in applications and libraries:
-      
-      pthreadCancelableWait
-      pthreadCancelableTimedWait
-
-      
-The following functions are not implemented:
-
-      ---------------------------
-      RealTime Scheduling
-      ---------------------------
-      pthread_mutex_getprioceiling
-      pthread_mutex_setprioceiling
-      pthread_mutex_attr_getprioceiling
-      pthread_mutex_attr_getprotocol
-      pthread_mutex_attr_setprioceiling
-      pthread_mutex_attr_setprotocol
-
-      ---------------------------
-      Fork Handlers
-      ---------------------------
-      pthread_atfork
-
-      ---------------------------
-      Stdio
-      --------------------------- 
-      flockfile
-      ftrylockfile
-      funlockfile
-      getc_unlocked
-      getchar_unlocked	
-      putc_unlocked
-      putchar_unlocked
-
-      ---------------------------
-      Thread-Safe C Runtime Library
-      ---------------------------
-      readdir_r
-      getgrgid_r
-      getgrnam_r
-      getpwuid_r
-      getpwnam_r
-      
-      ---------------------------
-      Signals
-      ---------------------------
-      sigtimedwait
-      sigwait
-      sigwaitinfo
-
-      ---------------------------
-      General
-      ---------------------------
-      sysconf      
-
-      ---------------------------
-      Thread-Safe C Runtime Library (macros)
-      ---------------------------
-      strtok_r
-      asctime_r
-      ctime_r
-      gmtime_r
-      localtime_r
-      rand_r
-
-
-Availability
------------- 
-
-The prebuilt DLL, export libs (for both MSVC and Mingw32), and the header
-files (pthread.h, semaphore.h, sched.h) are available along with the
-complete source code.
-
-The source code can be found at:
-
-	ftp://sources.redhat.com/pub/pthreads-win32
-
-and as individual source code files at
-
-	ftp://sources.redhat.com/pub/pthreads-win32/source
-
-The pre-built DLL, export libraries and include files can be found at:
-
-	ftp://sources.redhat.com/pub/pthreads-win32/dll-latest
-
-
-      
-Mailing List 
-------------  
-      
-There is a mailing list for discussing pthreads on Win32. To join,
-send email to:
-
-	pthreads-win32-subscribe at sourceware.cygnus.com
-      
-
-Application Development Environments
-------------------------------------
-
-See the README file for more information.
-      
-MSVC:
-MSVC using SEH works. Distribute pthreadVSE.dll with your application.
-MSVC using C++ EH works. Distribute pthreadVCE.dll with your application.
-MSVC using C setjmp/longjmp works. Distribute pthreadVC.dll with your application.
-
-
-Mingw32:
-See the FAQ, Questions 6 and 10.
-
-Mingw using C++ EH works. Distribute pthreadGCE.dll with your application.
-Mingw using C setjmp/longjmp works. Distribute pthreadGC.dll with your application.
-
-
-Cygwin: (http://sourceware.cygnus.com/cygwin/)
-Developers using Cygwin do not need pthreads-win32 since it has POSIX threads
-support. Refer to its documentation for details and extent.
-
-
-UWIN:
-UWIN is a complete Unix-like environment for Windows from AT&T. Pthreads-win32
-doesn't currently support UWIN (and vice versa), but that may change in the
-future.
-
-Generally:
-For convenience, the following pre-built files are available on the FTP site
-(see Availability above):
-
-	pthread.h	- for POSIX threads
-	semaphore.h	- for POSIX semaphores
-	sched.h 	- for POSIX scheduling
-	pthreadVCE.dll	- built with MSVC++ compiler using C++ EH
-	pthreadVCE.lib
-	pthreadVC.dll	- built with MSVC compiler using C setjmp/longjmp
-	pthreadVC.lib
-	pthreadVSE.dll	- built with MSVC compiler using SEH
-	pthreadVSE.lib
-	pthreadGCE.dll	- built with Mingw32 G++ 2.95.2-1
-	pthreadGC.dll	- built with Mingw32 GCC 2.95.2-1 using setjmp/longjmp
-	libpthreadGCE.a - derived from pthreadGCE.dll
-	libpthreadGC.a	- derived from pthreadGC.dll
-	gcc.dll 	- needed if distributing applications that use
-			  pthreadGCE.dll (but see the FAQ Q 10 for the latest
-			  related information)
-
-These are the only files you need in order to build POSIX threads
-applications for Win32 using either MSVC or Mingw32.
-
-See the FAQ file in the source tree for additional information.
-
-
-Documentation
--------------
-
-For the authoritative reference, see the online POSIX
-standard reference at:
-
-       http://www.OpenGroup.org
-
-For POSIX Thread API programming, several reference books are
-available:
-
-       Programming with POSIX Threads
-       David R. Butenhof
-       Addison-Wesley (pub)
-
-       Pthreads Programming
-       By Bradford Nichols, Dick Buttlar & Jacqueline Proulx Farrell
-       O'Reilly (pub)
-
-On the web: see the links at the bottom of the pthreads-win32 site:
-
-       http://sources.redhat.com/pthreads-win32/
-
-       Currently, there is no documentation included in the package apart
-       from the copious comments in the source code.
-
-
-
-Enjoy!
-
-Ross Johnson
diff --git a/deps/w32-pthreads/BUGS b/deps/w32-pthreads/BUGS
deleted file mode 100644
index 285ba4e..0000000
--- a/deps/w32-pthreads/BUGS
+++ /dev/null
@@ -1,141 +0,0 @@
-----------
-Known bugs
-----------
-
-1. Not strictly a bug, more of a gotcha.
-
-   Under MS VC++ (only tested with version 6.0), a term_func
-   set via the standard C++ set_terminate() function causes the
-   application to abort.
-
-   Notes from the MSVC++ manual:
-         1) A term_func() should call exit(), otherwise
-            abort() will be called on return to the caller.
-            A call to abort() raises SIGABRT and the default signal handler
-            for all signals terminates the calling program with
-            exit code 3.
-         2) A term_func() must not throw an exception. Therefore
-            term_func() should not call pthread_exit(), which
-            works by throwing an exception (pthreadVCE or pthreadVSE)
-            or by calling longjmp (pthreadVC).
-
-   Workaround: avoid using pthread_exit() in C++ applications. Exit
-   threads by dropping through the end of the thread routine.
-
-2. Cancellation problems in C++ builds
-   - Milan Gardian
-
-   [Note: It's not clear if this problem isn't simply due to the context
-   switch in pthread_cancel() which occurs unless the QueueUserAPCEx
-   library and driver are installed and used. Just like setjmp/longjmp,
-   this is probably not going to work well in C++. In any case, unless for
-   some very unusual reason you really must use the C++ build then please
-   use the C build pthreadVC2.dll or pthreadGC2.dll, i.e. for C++
-   applications.]
-
-   This is suspected to be a compiler bug in VC6.0, and also seen in
-   VC7.0 and VS .NET 2003. The GNU C++ compiler does not have a problem
-   with this, and it has been reported that the Intel C++ 8.1 compiler
-   and Visual C++ 2005 Express Edition Beta2 pass tests\semaphore4.c
-   (which exposes the bug).
-
-   Workaround [rpj - 2 Feb 2002]
-   -----------------------------
-   [Please note: this workaround did not solve a similar problem in
-   snapshot-2004-11-03 or later, even though similar symptoms were seen.
-   tests\semaphore4.c fails in that snapshot for the VCE version of the
-   DLL.]
-
-   The problem disappears when /Ob0 is used, i.e. /O2 /Ob0 works OK,
-   but if you want to use inlining optimisation you can be much more
-   specific about where it's switched off and on by using a pragma.
-
-   So the inlining optimisation is interfering with the way that cleanup
-   handlers are run. It appears to relate to auto-inlining of class methods
-   since this is the only auto inlining that is performed at /O1 optimisation
-   (functions with the "inline" qualifier are also inlined, but the problem
-   doesn't appear to involve any such functions in the library or testsuite).
-
-   In order to confirm the inlining culprit, the following use of pragmas
-   eliminate the problem but I don't know how to make it transparent, putting
-   it in, say, pthread.h where pthread_cleanup_push defined as a macro.
-
-   #pragma inline_depth(0)
-     pthread_cleanup_push(handlerFunc, (void *) &arg);
-
-        /* ... */
-
-     pthread_cleanup_pop(0);
-   #pragma inline_depth()
-
-   Note the empty () pragma value after the pop macro. This resets depth to the
-   default. Or you can specify a non-zero depth here.
-
-   The pragma is also needed (and now used) within the library itself wherever
-   cleanup handlers are used (condvar.c and rwlock.c).
-
-   Use of these pragmas allows compiler optimisations /O1 and /O2 to be
-   used for either or both the library and applications.
-
-   Experimenting further, I found that wrapping the actual cleanup handler
-   function with #pragma auto_inline(off|on) does NOT work.
-
-   MSVC6.0 doesn't appear to support the C99 standard's _Pragma directive,
-   however, later versions may. This form is embeddable inside #define
-   macros, which would be ideal because it would mean that it could be added
-   to the push/pop macro definitions in pthread.h and hidden from the
-   application programmer.
-
-   [/rpj]
-
-   Original problem description
-   ----------------------------
-
-   The cancellation (actually, cleanup-after-cancel) tests fail when using VC
-   (professional) optimisation switches (/O1 or /O2) in pthreads library. I
-   have not investigated which concrete optimisation technique causes this
-   problem (/Og, /Oi, /Ot, /Oy, /Ob1, /Gs, /Gf, /Gy, etc.), but here is a
-   summary of builds and corresponding failures:
-
-     * pthreads VSE (optimised tests): OK
-     * pthreads VCE (optimised tests): Failed "cleanup1" test (runtime)
-
-     * pthreads VSE (DLL in CRT, optimised tests): OK
-     * pthreads VCE (DLL in CRT, optimised tests): Failed "cleanup1" test
-   (runtime)
-
-   Please note that while in VSE version of the pthreads library the
-   optimisation does not really have any impact on the tests (they pass OK), in
-   VCE version addition of optimisation (/O2 in this case) causes the tests to
-   fail uniformly - either in "cleanup0" or "cleanup1" test cases.
-
-   Please note that all the tests above use default pthreads DLL (no
-   optimisations, linked with either static or DLL CRT, based on test type).
-   Therefore the problem lies not within the pthreads DLL but within the
-   compiled client code (the application using pthreads -> involvement of
-   "pthread.h").
-
-   I think the message of this section is that usage of VCE version of pthreads
-   in applications relying on cancellation/cleanup AND using optimisations for
-   creation of production code is highly unreliable for the current version of
-   the pthreads library.
-
-3. The Borland Builder 5.5 version of the library produces memory read exceptions
-in some tests.
-
-4. pthread_barrier_wait() can deadlock if the number of potential calling
-threads for a particular barrier is greater than the barrier count parameter
-given to pthread_barrier_init() for that barrier.
-
-This is due to the very lightweight implementation of pthread-win32 barriers.
-To cope with more than "count" possible waiters, barriers must effectively
-implement all the same safeguards as condition variables, making them much
-"heavier" than at present.
-
-The workaround is to ensure that no more than "count" threads attempt to wait
-at the barrier.
-
-5. Canceling a thread blocked on pthread_once appears not to work in the MSVC++
-version of the library "pthreadVCE.dll". The test case "once3.c" hangs. I have no
-clues on this at present. All other versions pass this test ok - pthreadsVC.dll,
-pthreadsVSE.dll, pthreadsGC.dll and pthreadsGCE.dll. 
diff --git a/deps/w32-pthreads/Bmakefile b/deps/w32-pthreads/Bmakefile
deleted file mode 100644
index ea25dec..0000000
--- a/deps/w32-pthreads/Bmakefile
+++ /dev/null
@@ -1,268 +0,0 @@
-# This makefile is compatible with BCB make.  Use "make -fBMakefile" to compile.
-# 
-# The variables $DLLDEST and $LIBDEST hold the destination directories for the
-# dll and the lib, respectively. Probably all that needs to change is $DEVROOT.
-#
-# Currently only the recommended pthreadBC.dll is built by this makefile.
-#
-
-
-DLL_VER	= 2
-
-DEVROOT	= .
-
-DLLDEST	= $(DEVROOT)\DLL
-LIBDEST	= $(DEVROOT)\DLL
-
-DLLS	= pthreadBC$(DLL_VER).dll
-
-OPTIM	= /O2
-
-RC	= brcc32
-RCFLAGS	= -i.
-
-CFLAGS	= /q /I. /D_WIN32_WINNT=0x400 /DHAVE_PTW32_CONFIG_H=1 /4 /tWD /tWM \
-	  /w-aus /w-asc /w-par
-
-#C cleanup code
-BCFLAGS	= $(PTW32_FLAGS) $(CFLAGS)
-
-# Agregate modules for inlinability
-DLL_OBJS	= \
-		attr.obj \
-		barrier.obj \
-		cancel.obj \
-		cleanup.obj \
-		condvar.obj \
-		create.obj \
-		dll.obj \
-		errno.obj \
-		exit.obj \
-		fork.obj \
-		global.obj \
-		misc.obj \
-		mutex.obj \
-		nonportable.obj \
-		private.obj \
-		rwlock.obj \
-		sched.obj \
-		semaphore.obj \
-		signal.obj \
-		spin.obj \
-		sync.obj \
-		tsd.obj
-
-INCL	= config.h implement.h semaphore.h pthread.h need_errno.h
-
-ATTR_SRCS	= \
-		pthread_attr_init.c \
-		pthread_attr_destroy.c \
-		pthread_attr_getdetachstate.c \
-		pthread_attr_setdetachstate.c \
-		pthread_attr_getstackaddr.c \
-		pthread_attr_setstackaddr.c \
-		pthread_attr_getstacksize.c \
-		pthread_attr_setstacksize.c \
-		pthread_attr_getscope.c \
-		pthread_attr_setscope.c
-
-BARRIER_SRCS = \
-		pthread_barrier_init.c \
-		pthread_barrier_destroy.c \
-		pthread_barrier_wait.c \
-		pthread_barrierattr_init.c \
-		pthread_barrierattr_destroy.c \
-		pthread_barrierattr_setpshared.c \
-		pthread_barrierattr_getpshared.c
-
-CANCEL_SRCS	= \
-		pthread_setcancelstate.c \
-		pthread_setcanceltype.c \
-		pthread_testcancel.c \
-		pthread_cancel.c 
-
-CONDVAR_SRCS	= \
-		ptw32_cond_check_need_init.c \
-		pthread_condattr_destroy.c \
-		pthread_condattr_getpshared.c \
-		pthread_condattr_init.c \
-		pthread_condattr_setpshared.c \
-		pthread_cond_destroy.c \
-		pthread_cond_init.c \
-		pthread_cond_signal.c \
-		pthread_cond_wait.c
-
-EXIT_SRCS	= \
-		pthread_exit.c
-
-MISC_SRCS	= \
-		pthread_equal.c \
-		pthread_getconcurrency.c \
-		pthread_once.c \
-		pthread_self.c \
-		pthread_setconcurrency.c \
-		ptw32_calloc.c \
-		ptw32_MCS_lock.c \
-		ptw32_new.c \
-		w32_CancelableWait.c
-
-MUTEX_SRCS	= \
-		ptw32_mutex_check_need_init.c \
-		pthread_mutex_init.c \
-		pthread_mutex_destroy.c \
-		pthread_mutexattr_init.c \
-		pthread_mutexattr_destroy.c \
-		pthread_mutexattr_getpshared.c \
-		pthread_mutexattr_setpshared.c \
-		pthread_mutexattr_settype.c \
-		pthread_mutexattr_gettype.c \
-		pthread_mutexattr_setrobust.c \
-		pthread_mutexattr_getrobust.c \
-		pthread_mutex_lock.c \
-		pthread_mutex_timedlock.c \
-		pthread_mutex_unlock.c \
-		pthread_mutex_trylock.c \
-		pthread_mutex_consistent.c
-
-NONPORTABLE_SRCS = \
-		pthread_mutexattr_setkind_np.c \
-		pthread_mutexattr_getkind_np.c \
-		pthread_getw32threadhandle_np.c \
-		pthread_delay_np.c \
-		pthread_num_processors_np.c \
-		pthread_win32_attach_detach_np.c \
-		pthread_timechange_handler_np.c 
-
-PRIVATE_SRCS	= \
-		ptw32_is_attr.c \
-		ptw32_processInitialize.c \
-		ptw32_processTerminate.c \
-		ptw32_threadStart.c \
-		ptw32_threadDestroy.c \
-		ptw32_tkAssocCreate.c \
-		ptw32_tkAssocDestroy.c \
-		ptw32_callUserDestroyRoutines.c \
-		ptw32_timespec.c \
-		ptw32_relmillisecs.c \
-		ptw32_throw.c \
-		ptw32_getprocessors.c
-
-RWLOCK_SRCS	= \
-		ptw32_rwlock_check_need_init.c \
-		ptw32_rwlock_cancelwrwait.c \
-		pthread_rwlock_init.c \
-		pthread_rwlock_destroy.c \
-		pthread_rwlockattr_init.c \
-		pthread_rwlockattr_destroy.c \
-		pthread_rwlockattr_getpshared.c \
-		pthread_rwlockattr_setpshared.c \
-		pthread_rwlock_rdlock.c \
-		pthread_rwlock_timedrdlock.c \
-		pthread_rwlock_wrlock.c \
-		pthread_rwlock_timedwrlock.c \
-		pthread_rwlock_unlock.c \
-		pthread_rwlock_tryrdlock.c \
-		pthread_rwlock_trywrlock.c
-
-SCHED_SRCS	= \
-		pthread_attr_setschedpolicy.c \
-		pthread_attr_getschedpolicy.c \
-		pthread_attr_setschedparam.c \
-		pthread_attr_getschedparam.c \
-		pthread_attr_setinheritsched.c \
-		pthread_attr_getinheritsched.c \
-		pthread_setschedparam.c \
-		pthread_getschedparam.c \
-		sched_get_priority_max.c \
-		sched_get_priority_min.c \
-		sched_setscheduler.c \
-		sched_getscheduler.c \
-		sched_yield.c
-
-SEMAPHORE_SRCS = \
-		sem_init.c \
-		sem_destroy.c \
-		sem_trywait.c \
-		sem_timedwait.c \
-		sem_wait.c \
-		sem_post.c \
-		sem_post_multiple.c \
-		sem_getvalue.c \
-		sem_open.c \
-		sem_close.c \
-		sem_unlink.c
-
-SPIN_SRCS	= \
-		ptw32_spinlock_check_need_init.c \
-		pthread_spin_init.c \
-		pthread_spin_destroy.c \
-		pthread_spin_lock.c \
-		pthread_spin_unlock.c \
-		pthread_spin_trylock.c
-
-SYNC_SRCS	= \
-		pthread_detach.c \
-		pthread_join.c
-
-TSD_SRCS	= \
-		pthread_key_create.c \
-		pthread_key_delete.c \
-		pthread_setspecific.c \
-		pthread_getspecific.c
-
-
-all: clean $(DLLS)
-
-realclean: clean
-	if exist pthread*.dll del pthread*.dll
-	if exist pthread*.lib del pthread*.lib
-	if exist *.stamp del *.stamp
-
-clean:
-	if exist *.obj del *.obj
-	if exist *.ilk del *.ilk
-	if exist *.ilc del *.ilc
-	if exist *.ild del *.ild
-	if exist *.ilf del *.ilf
-	if exist *.ils del *.ils
-	if exist *.tds del *.tds
-	if exist *.pdb del *.pdb
-	if exist *.exp del *.exp
-	if exist *.map del *.map
-	if exist *.o del *.o
-	if exist *.i del *.i
-	if exist *.res del *.res
-
-
-install: $(DLLS)
-	copy pthread*.dll $(DLLDEST)
-	copy pthread*.lib $(LIBDEST)
-
-$(DLLS): $(DLL_OBJS) version.res
-	ilink32 /Tpd /Gi c0d32x.obj $(DLL_OBJS), \
-		$@, ,\
-		cw32mti.lib import32.lib, ,\
-		version.res
-
-.c.obj:
-	$(CC) $(OPTIM) $(BCFLAGS) -c $<
-
-.rc.res:
-	$(RC) $(RCFLAGS) $<
-
-attr.obj:	attr.c $(ATTR_SRCS) $(INCL)
-barrier.obj:	barrier.c $(BARRIER_SRCS) $(INCL)
-cancel.obj:	cancel.c $(CANCEL_SRCS) $(INCL)
-condvar.obj:	condvar.c $(CONDVAR_SRCS) $(INCL)
-exit.obj:	exit.c $(EXIT_SRCS) $(INCL)
-misc.obj:	misc.c $(MISC_SRCS) $(INCL)
-mutex.obj:	mutex.c $(MUTEX_SRCS) $(INCL)
-nonportable.obj:	nonportable.c $(NONPORTABLE_SRCS) $(INCL)
-private.obj:	private.c $(PRIVATE_SRCS) $(INCL)
-rwlock.obj:	rwlock.c $(RWLOCK_SRCS) $(INCL)
-sched.obj:	sched.c $(SCHED_SRCS) $(INCL)
-semaphore.obj:	semaphore.c $(SEMAPHORE_SRCS) $(INCL)
-spin.obj:	spin.c $(SPIN_SRCS) $(INCL)
-sync.obj:	sync.c $(SYNC_SRCS) $(INCL)
-tsd.obj:	tsd.c $(TSD_SRCS) $(INCL)
-version.res:	version.rc $(INCL)
diff --git a/deps/w32-pthreads/CMakeLists.txt b/deps/w32-pthreads/CMakeLists.txt
deleted file mode 100644
index 992ec69..0000000
--- a/deps/w32-pthreads/CMakeLists.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-project(w32-pthreads)
-
-if(NOT WIN32)
-	return()
-endif()
-
-set(w32-pthreads_SOURCES
-	pthread.c)
-
-set(w32-pthreads_HEADERS
-	implement.h
-	pthread.h
-	sched.h
-	semaphore.h)
-
-add_library(w32-pthreads SHARED
-	${w32-pthreads_SOURCES}
-	${w32-pthreads_HEADERS})
-target_compile_definitions(w32-pthreads
-	PRIVATE __CLEANUP_C PTW32_BUILD)
-target_include_directories(w32-pthreads
-	PUBLIC
-		"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
-target_link_libraries(w32-pthreads)
-
-install_obs_core(w32-pthreads EXPORT w32-pthreads)
diff --git a/deps/w32-pthreads/CONTRIBUTORS b/deps/w32-pthreads/CONTRIBUTORS
deleted file mode 100644
index da31ff2..0000000
--- a/deps/w32-pthreads/CONTRIBUTORS
+++ /dev/null
@@ -1,140 +0,0 @@
-Contributors (in approximate order of appearance)
-
-[See also the ChangeLog file where individuals are
-attributed in log entries. Likewise in the FAQ file.]
-
-Ben Elliston		bje at cygnus dot com
-					Initiated the project;
-					setup the project infrastructure (CVS, web page, etc.);
-					early prototype routines.
-Ross Johnson		Ross dot Johnson at  dot homemail dot com dot au
-					early prototype routines;
-					ongoing project coordination/maintenance;
-					implementation of spin locks and barriers;
-					various enhancements;
-					bug fixes;
-					documentation;
-					testsuite.
-Robert Colquhoun	rjc at trump dot net dot au
-					Early bug fixes.
-John E. Bossom		John dot Bossom at cognos dot com
-					Contributed substantial original working implementation;
-					bug fixes;
-					ongoing guidance and standards interpretation.
-Anders Norlander	anorland at hem2 dot passagen dot se
-					Early enhancements and runtime checking for supported
-					Win32 routines.
-Tor Lillqvist		tml at iki dot fi
-					General enhancements;
-					early bug fixes to condition variables.
-Scott Lightner		scott at curriculum dot com
-					Bug fix.
-Kevin Ruland		Kevin dot Ruland at anheuser-busch dot com
-					Various bug fixes.
-Mike Russo		miker at eai dot com
-					Bug fix.
-Mark E. Armstrong	avail at pacbell dot net
-					Bug fixes.
-Lorin Hochstein 	lmh at xiphos dot ca
-					general bug fixes; bug fixes to condition variables.
-Peter Slacik		Peter dot Slacik at tatramed dot sk
-					Bug fixes.
-Mumit Khan		khan at xraylith dot wisc dot edu
-					Fixes to work with Mingw32.
-Milan Gardian		mg at tatramed dot sk
-					Bug fixes and reports/analyses of obscure problems.
-Aurelio Medina		aureliom at crt dot com
-					First implementation of read-write locks.
-Graham Dumpleton	Graham dot Dumpleton at ra dot pad dot otc dot telstra dot com dot au
-					Bug fix in condition variables.
-Tristan Savatier	tristan at mpegtv dot com
-					WinCE port.
-Erik Hensema		erik at hensema dot xs4all dot nl
-					Bug fixes.
-Rich Peters		rpeters at micro-magic dot com
-Todd Owen		towen at lucidcalm dot dropbear dot id dot au
-					Bug fixes to dll loading.
-Jason Nye		jnye at nbnet dot nb dot ca
-					Implementation of async cancelation.
-Fred Forester		fforest at eticomm dot net
-Kevin D. Clark		kclark at cabletron dot com
-David Baggett		dmb at itasoftware dot com
-					Bug fixes.
-Paul Redondo		paul at matchvision dot com
-Scott McCaskill 	scott at 3dfx dot com
-					Bug fixes.
-Jef Gearhart		jgearhart at tpssys dot com
-					Bug fix.
-Arthur Kantor		akantor at bexusa dot com
-					Mutex enhancements.
-Steven Reddie		smr at essemer dot com dot au
-					Bug fix.
-Alexander Terekhov	TEREKHOV at de dot ibm dot com
-					Re-implemented and improved read-write locks;
-					(with Louis Thomas) re-implemented and improved
-					condition variables;
-					enhancements to semaphores;
-					enhancements to mutexes;
-					new mutex implementation in 'futex' style;
-					suggested a robust implementation of pthread_once
-					similar to that implemented by V.Kliathcko;
-					system clock change handling re CV timeouts;
-					bug fixes.
-Thomas Pfaff		tpfaff at gmx dot net
-					Changes to make C version usable with C++ applications;
-					re-implemented mutex routines to avoid Win32 mutexes
-					and TryEnterCriticalSection;
-					procedure to fix Mingw32 thread-safety issues.
-Franco Bez		franco dot bez at gmx dot de
-					procedure to fix Mingw32 thread-safety issues.
-Louis Thomas		lthomas at arbitrade dot com
-					(with Alexander Terekhov) re-implemented and improved
-					condition variables.
-David Korn		dgk at research dot att dot com
-					Ported to UWIN.
-Phil Frisbie, Jr.	phil at hawksoft dot com
-					Bug fix.
-Ralf Brese		Ralf dot Brese at pdb4 dot siemens dot de
-					Bug fix.
-prionx at juno dot com 	prionx at juno dot com
-					Bug fixes.
-Max Woodbury		mtew at cds dot duke dot edu
-					POSIX versioning conditionals;
-					reduced namespace pollution;
-					idea to separate routines to reduce statically
-					linked image sizes.
-Rob Fanner		rfanner at stonethree dot com
-					Bug fix.
-Michael Johnson 	michaelj at maine dot rr dot com
-					Bug fix.
-Nicolas Barry		boozai at yahoo dot com
-					Bug fixes.
-Piet van Bruggen	pietvb at newbridges dot nl
-					Bug fix.
-Makoto Kato		raven at oldskool dot jp
-					AMD64 port.
-Panagiotis E. Hadjidoukas	peh at hpclab dot ceid dot upatras dot gr
-                                phadjido at cs dot uoi dot gr
-					Contributed the QueueUserAPCEx package which
-					makes preemptive async cancelation possible.
-Will Bryant		will dot bryant at ecosm dot com
-					Borland compiler patch and makefile.
-Anuj Goyal		anuj dot goyal at gmail dot com
-					Port to Digital Mars compiler.
-Gottlob Frege		gottlobfrege at  gmail dot com
-					re-implemented pthread_once (version 2)
-					(pthread_once cancellation added by rpj).
-Vladimir Kliatchko	vladimir at kliatchko dot com
-					reimplemented pthread_once with the same form
-					as described by A.Terekhov (later version 2);
-					implementation of MCS (Mellor-Crummey/Scott) locks.
-Ramiro Polla		ramiro.polla at gmail dot com
-					static library auto init/cleanup on application
-					start/exit via RT hooks (MSC and GCC compilers only).
-Daniel Richard G.			skunk at iSKUNK dot org
-					Patches and cleanups for x86 and x64, particularly
-					across a range of MS build environments.
-John Kamp		john dot kamp at globalgraphics dot com
-					Patches to fix various problems on x64; brutal testing
-					particularly using high memory run environments.
-
diff --git a/deps/w32-pthreads/COPYING b/deps/w32-pthreads/COPYING
deleted file mode 100644
index cac5794..0000000
--- a/deps/w32-pthreads/COPYING
+++ /dev/null
@@ -1,150 +0,0 @@
-	pthreads-win32 - a POSIX threads library for Microsoft Windows
-
-
-This file is Copyrighted
-------------------------
-
-    This file is covered under the following Copyright:
-
-	Copyright (C) 2001,2006 Ross P. Johnson
-	All rights reserved.
-
-	Everyone is permitted to copy and distribute verbatim copies
-	of this license document, but changing it is not allowed.
-
-Pthreads-win32 is covered by the GNU Lesser General Public License
-------------------------------------------------------------------
-
-    Pthreads-win32 is open software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public License
-    as published by the Free Software Foundation version 2.1 of the
-    License.
-
-    Pthreads-win32 is several binary link libraries, several modules,
-    associated interface definition files and scripts used to control
-    its compilation and installation.
-
-    Pthreads-win32 is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    A copy of the GNU Lesser General Public License is distributed with
-    pthreads-win32 under the filename:
-
-	    COPYING.LIB
-
-    You should have received a copy of the version 2.1 GNU Lesser General
-    Public License with pthreads-win32; if not, write to:
-
-	    Free Software Foundation, Inc.
-	    51 Franklin Street
-	    Fifth Floor
-	    Boston, MA	02110-1301
-	    USA
-
-    The contact addresses for pthreads-win32 is as follows:
-
-        Web:	http://sources.redhat.com/pthreads-win32
-        Email:  Ross Johnson
-                Please use: Firstname.Lastname at homemail.com.au
-
-
-
-Pthreads-win32 copyrights and exception files
----------------------------------------------
-
-    With the exception of the files listed below, Pthreads-win32
-    is covered under the following GNU Lesser General Public License
-    Copyrights:
-
-	Pthreads-win32 - POSIX Threads Library for Win32
-	Copyright(C) 1998 John E. Bossom
-	Copyright(C) 1999,2006 Pthreads-win32 contributors
-
-	The current list of contributors is contained
-        in the file CONTRIBUTORS included with the source
-	code distribution. The current list of CONTRIBUTORS
-	can also be seen at the following WWW location:
-        http://sources.redhat.com/pthreads-win32/contributors.html
-
-    Contact Email: Ross Johnson
-                   Please use: Firstname.Lastname at homemail.com.au
-
-    These files are not covered under one of the Copyrights listed above:
-
-            COPYING
-	    COPYING.LIB
-            tests/rwlock7.c
-
-    This file, COPYING, is distributed under the Copyright found at the
-    top of this file.  It is important to note that you may distribute
-    verbatim copies of this file but you may not modify this file.
-
-    The file COPYING.LIB, which contains a copy of the version 2.1
-    GNU Lesser General Public License, is itself copyrighted by the
-    Free Software Foundation, Inc.  Please note that the Free Software
-    Foundation, Inc. does NOT have a copyright over Pthreads-win32,
-    only the COPYING.LIB that is supplied with pthreads-win32.
-
-    The file tests/rwlock7.c is derived from code written by
-    Dave Butenhof for his book 'Programming With POSIX(R) Threads'.
-    The original code was obtained by free download from his website
-    http://home.earthlink.net/~anneart/family/Threads/source.html
-    and did not contain a copyright or author notice. It is assumed to
-    be freely distributable.
-
-    In all cases one may use and distribute these exception files freely.
-    And because one may freely distribute the LGPL covered files, the
-    entire pthreads-win32 source may be freely used and distributed.
-
-
-
-General Copyleft and License info
----------------------------------
-
-    For general information on Copylefts, see:
-
-	http://www.gnu.org/copyleft/
-
-    For information on GNU Lesser General Public Licenses, see:
-
-	http://www.gnu.org/copyleft/lesser.html
-	http://www.gnu.org/copyleft/lesser.txt
-
-
-Why pthreads-win32 did not use the GNU General Public License
--------------------------------------------------------------
-
-    The goal of the pthreads-win32 project has been to
-    provide a quality and complete implementation of the POSIX
-    threads API for Microsoft Windows within the limits imposed
-    by virtue of it being a stand-alone library and not
-    linked directly to other POSIX compliant libraries. For
-    example, some functions and features, such as those based
-    on POSIX signals, are missing.
-
-    Pthreads-win32 is a library, available in several different
-    versions depending on supported compilers, and may be used
-    as a dynamically linked module or a statically linked set of
-    binary modules. It is not an application on it's own.
-
-    It was fully intended that pthreads-win32 be usable with
-    commercial software not covered by either the GPL or the LGPL
-    licenses. Pthreads-win32 has many contributors to it's
-    code base, many of whom have done so because they have
-    used the library in commercial or proprietry software
-    projects.
-
-    Releasing pthreads-win32 under the LGPL ensures that the
-    library can be used widely, while at the same time ensures
-    that bug fixes and improvements to the pthreads-win32 code
-    itself is returned to benefit all current and future users
-    of the library.
-
-    Although pthreads-win32 makes it possible for applications
-    that use POSIX threads to be ported to Win32 platforms, the
-    broader goal of the project is to encourage the use of open
-    standards, and in particular, to make it just a little easier
-    for developers writing Win32 applications to consider
-    widening the potential market for their products.
diff --git a/deps/w32-pthreads/COPYING.LIB b/deps/w32-pthreads/COPYING.LIB
deleted file mode 100644
index db01cf0..0000000
--- a/deps/w32-pthreads/COPYING.LIB
+++ /dev/null
@@ -1,504 +0,0 @@
-		  GNU LESSER GENERAL PUBLIC LICENSE
-		       Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
-		  GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-			    NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/deps/w32-pthreads/ChangeLog b/deps/w32-pthreads/ChangeLog
deleted file mode 100644
index 42abcc4..0000000
--- a/deps/w32-pthreads/ChangeLog
+++ /dev/null
@@ -1,5211 +0,0 @@
-2012-03-18  Ross Johnson <ross dot johnson at homemail dot com dot au>
-
-	* create.c (pthread_create): add __cdecl attribute to thread routine
-	arg
-	* implement.h (pthread_key_t): add __cdecl attribute to destructor
-	element
-	(ThreadParms): likewise for start element
-	* pthread.h (pthread_create): add __cdecl to prototype start arg
-	(pthread_once): likewise for init_routine arg
-	(pthread_key_create): likewise for destructor arg
-	(ptw32_cleanup_push): replace type of routine arg with previously
-	defined ptw32_cleanup_callback_t
-	* pthread_key_create.c: add __cdecl attribute to destructor arg
-	* pthread_once.c: add __cdecl attribute to init_routine arg
-	* ptw32_threadStart.c (start): add __cdecl to start variable type
-
-
-2011-07-06  Ross Johnson <ross dot johnson at homemail dot com dot au>
-
-	* pthread_cond_wait.c (pragma inline_depth): this is almost redundant
-	now nevertheless fixed thei controlling MSC_VER from "< 800" to
-	"< 1400" (i.e. any prior to VC++ 8.0).
-	* pthread_once.ci (pragma inline_depth): Likewise.
-	* pthread_rwlock_timedwrlock.ci (pragma inline_depth): Likewise.
-	* pthread_rwlock_wrlock.ci (pragma inline_depth): Likewise.
-	* sem_timedwait.ci (pragma inline_depth): Likewise.
-	* sem_wait.ci (pragma inline_depth): Likewise.
-
-2011-07-05  Ross Johnson <ross dot johnson at homemail dot com dot au>
-
-	* pthread_win32_attach_detach_np.c: Use strncat_s if available
-	to removei a compile warning; MingW supports this routine but we
-	continue to use strncat anyway there because it is secure if
-	given the correct parameters; fix strncat param 3 to avoid
-	buffer overrun exploitation potential.
-
-2011-07-03  Ross Johnson <ross dot johnson at homemail dot com dot au>
-
-	* pthread_spin_unlock.c (EPERM): Return success if unlocking a lock
-	that is not locked, because single CPU machines wrap a
-	PTHREAD_MUTEX_NORMAL mutex, which returns success in this case.
-	* pthread_win32_attach_detach_np.c (QUSEREX.DLL): Load from an
-	absolute path only which must be the Windows System folder.
-
-2011-07-03 Daniel Richard G. <skunk at iskunk dot org>
-
-	* Makefile (_WIN32_WINNT): Removed; duplicate definition in
-	implement.h; more cleanup and enhancements.
-
-2011-07-02 Daniel Richard G. <skunk at iskunk dot org>
-
-	* Makefile: Cleanups and implovements.
-	* ptw32_MCS_locks.c: Casting fixes.
-	* implement.h: Interlocked call and argument casting macro fixes
-	to support older and newer build environments.
-
-2011-07-01  Ross Johnson <ross dot johnson at homemail dot com dot au>
-
-	* *.[ch] (PTW32_INTERLOCKED_*): Redo 23 and 64 bit versions of these
-	macros and re-apply in code to undo the incorrect changes from
-	2011-06-29; remove some size_t casts which should not be required
-	and may be problematic.a
-	There are now two sets of macros:
-	PTW32_INTERLOCKED_*_LONG which work only on 32 bit integer variables;
-	PTW32_INTERLOCKED_*_SIZE which work on size_t integer variables, i.e.
-	LONG for 32 bit systems and LONGLONG for 64 bit systems.
-	* implement.h (MCS locks): nextFlag and waitFlag are now HANDLE type.
-	* ptw32_MCS_locks.c: Likewise.
-	* pthread.h (#include <setjmp.h>): Removed.
-	* ptw32_throw.c (#include <setjmp.h>): Added.
-	* ptw32_threadStart.c (#include <setjmp.h>): Added.
-	* implement.h (#include <setjmp.h>): Added.
-
-2011-06-30  Ross Johnson <ross dot johnson at homemail dot com dot au>
-
-	* pthread_once.c: Tighten 'if' statement casting; fix interlocked
-	pointer cast for 64 bit compatibility (missed yesterday); remove
-	the superfluous static cleanup routine and call the release routine
-	directly if popped.
-	* create.c (stackSize): Now type size_t.
-	* pthread.h (struct ptw32_thread_t_): Rearrange to fix element alignments.
-
-2011-06-29 Daniel Richard G. <skunk at iskunk dot org>
-
-	* ptw32_relmillisecs.c (ftime):
-	  _ftime64_s() is only available in MSVC 2005 or later;
-	  _ftime64() is available in MinGW or MSVC 2002 or later;
-	  _ftime() is always available.
-	* pthread.h (long long): Not defined in older MSVC 6.
-	* implement.h (long long): Likewise.
-	* pthread_getunique_np.c (long long): Likewise.
-
-2011-06-29  Ross Johnson <ross dot johnson at homemail dot com dot au>
-
-	* *.[ch] (PTW32_INTERLOCKED_*): These macros should now work for
-	both 32 and 64 bit builds. The MingW versions are all inlined asm
-	while the MSVC versions expand to their Interlocked* or Interlocked*64
-	counterparts appropriately. The argument type have also been changed
-	to cast to the appropriate value or pointer size for the architecture.
-
-2011-05-29  Ross Johnson <ross dot johnson at homemail dot com dot au>
-
-	* *.[ch] (#ifdef): Extended cleanup to whole project.
-
-2011-05-29 Daniel Richard G. <skunk at iskunk dot org>
-
-	* Makefile (CC): Define  CC to allow use of other compatible
-	compilers such as the Intel compilter icl.
-	* implement.h (#if): Fix forms like #if HAVE_SOMETHING.
-	* pthread.h: Likewise.
-	* sched.h: Likewise; PTW32_LEVEL_* becomes PTW32_SCHED_LEVEL_*.
-	* semaphore.h: Likewise.
-
-2011-05-11  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* ptw32_callUserDestroyRoutines.c (terminate): Altered includes
-	to match ptw32_threadStart.c.
-	* GNUmakefile (GCE-inlined-debug, DOPT): Fixed.
-
-2011-04-31  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* (robust mutexes): Added this API. The API is not
-	mandatory for implementations that don't support PROCESS_SHARED
-	mutexes, nevertheless it was considered useful both functionally
-	and for source-level compatibility.
-	
-2011-03-26  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* pthread_getunique_np.c: New non-POSIX interface for compatibility
-	with some other implementations; returns a 64 bit sequence number
-	that is unique to each thread in the process.
-	* pthread.h (pthread_getunique_np): Added.
-	* global.c: Add global sequence counter for above.
-	* implement.h: Likewise.
-
-2011-03-25  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* (cancelLock): Convert to an MCS lock and rename to stateLock.
-	* (threadLock): Likewise.
-	* (keyLock): Likewise.
-	* pthread_mutex*.c: First working robust mutexes.
-
-2011-03-11  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* implement.h (PTW32_INTERLOCKED_*CREMENT macros): increment/decrement
-	using ++/-- instead of add/subtract 1.
-	* ptw32_MCS_lock.c: Make casts consistent.
-
-2011-03-09  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* implement.h (ptw32_thread_t_): Add process unique sequence number.
-	* global.c: Replace global Critical Section objects with MCS
-	queue locks.
-	* implement.h: Likewise.
-	* pthread_cond_destroy.c: Likewise.
-	* pthread_cond_init.c: Likewise.
-	* pthread_detach.c: Likewise.
-	* pthread_join.c: Likewise.
-	* pthread_kill.c: Likewise.
-	* pthread_mutex_destroy.c: Likewise.
-	* pthread_rwlock_destroy.c: Likewise.
-	* pthread_spin_destroy.c: Likewise.
-	* pthread_timechange_handler_np.c: Likewise.
-	* ptw32_cond_check_need_init.c: Likewise.
-	* ptw32_mutex_check_need_init.c: Likewise.
-	* ptw32_processInitialize.c: Likewise.
-	* ptw32_processTerminate.c: Likewise.
-	* ptw32_reuse.c: Likewise.
-	* ptw32_rwlock_check_need_init.c: Likewise.
-	* ptw32_spinlock_check_need_init.c: Likewise.
-
-2011-03-06  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* several (MINGW64): Cast and call fixups for 64 bit compatibility;
-	clean build via x86_64-w64-mingw32 cross toolchain on Linux i686
-	targeting x86_64 win64.
-	* ptw32_threadStart.c (ptw32_threadStart): Routine no longer attempts
-	to pass [unexpected C++] exceptions out of scope but ends the thread
-	normally setting EINTR as the exit status.
-	* ptw32_throw.c: Fix C++ exception throwing warnings; ignore
-	informational warning.
-	* implement.h: Likewise with the corresponding header definition.
-
-2011-03-04  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* implement.h (PTW32_INTERLOCKED_*): Mingw32 does not provide
-	the __sync_* intrinsics so implemented them here as macro
-	assembler routines. MSVS Interlocked* are emmitted as intrinsics
-	wherever possible, so we want mingw to match it; Extended to
-	include all interlocked routines used by the library; implemented
-	x86_64 versions also.
-	* ptw32_InterlockedCompareExchange.c: No code remaining here.
-	* ptw32_MCS_lock.c: Converted interlocked calls to use new macros.
-	* pthread_barrier_wait.c: Likewise.
-	* pthread_once.c: Likewise.
-	* ptw32_MCS_lock.c (ptw32_mcs_node_substitute): Name changed to
-	ptw32_mcs_node_transfer.
-
-2011-02-28  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* ptw32_relmillisecs.c: If possible, use _ftime64_s or _ftime64
-	before resorting to _ftime.
-
-2011-02-27  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* sched_setscheduler.c: Ensure the handle is closed after use.
-	* sched_getscheduler.c: Likewise.
-	* pthread.h: Remove POSIX compatibility macros; don't define
-	timespec if already defined.
-	* context.h: Changes for 64 bit.
-	* pthread_cancel.c: Likewise.
-	* pthread_exit.c: Likewise.
-	* pthread_spin_destroy.c: Likewise.
-	* pthread_timechange_handler_np.c: Likewise.
-	* ptw32_MCS_lock.c: Likewise; some of these changes may
-	not be compatible with pre Windows 2000 systems; reverse the order of
-	the includes.
-	* ptw32_threadStart.c: Likewise.
-	* ptw32_throw.c: Likewise.
-
-2011-02-13  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* pthread_self: Add comment re returning 'nil' value to
-	indicate failure only to win32 threads that call us.
-	* pthread_attr_setstackaddr: Fix comments; note this
-	function and it's compliment are now removed from SUSv4.
-
-2011-02-12  Ross Johnson <ross.johnson at homemail.com.au>
-
-	README.NONPORTABLE: Record a description of an obvious
-	method for nulling/comparing/hashing pthread_t using a
-	union; plus and investigation of a change of type for
-	pthread_t (to a union) to neutralise any padding bits and
-	bytes if they occur in pthread_t (the current pthread_t struct
-	does not contain padding AFAIK, but porting the library to a
-	future architecture may introduce them). Padding affects
-	byte-by-byte copies and compare operations.
-
-2010-11-16  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* ChangeLog: Add this entry ;-)
-	Restore entries from 2007 through 2009 that went missing
-	at the last update.
-
-2010-06-19  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* ptw32_MCS_lock.c (ptw32_mcs_node_substitute): Fix variable
-	names to avoid using C++ keyword ("new").
-	* implement.h (ptw32_mcs_node_substitute): Likewise.
-	* pthread_barrier_wait.c: Fix signed/unsigned comparison warning.
-
-2010-06-18  Ramiro Polla  <ramiro.polla at gmail.com >
-
-	* autostatic.c: New file; call pthread_win32_process_*()
-	libary init/cleanup routines automatically on application start
-	when statically linked.
-	* pthread.c (autostatic.c): Included.
-	* pthread.h (declspec): Remove import/export defines if compiler
-	is MINGW.
-	* sched.h (declspec): Likewise.
-	* semaphore.h (declspec): Likewise.
-	* need_errno.h (declspec): Likewise.
-	* Makefile (autostatic.obj): Add for small static builds.
-	* GNUmakefile (autostatic.o): Likewise.
-	* NEWS (Version 2.9.0): Add changes.
-	* README.NONPORTABLE (pthread_win32_process_*): Update
-	description.
-
-2010-06-15  Ramiro Polla  <ramiro.polla at gmail.com >
-
-	* Makefile: Remove linkage with the winsock library by default.
-	* GNUmakefile: Likewise.
-	* pthread_getspecific.c: Likewise by removing calls to WSA
-	functions.
-	* config.h (RETAIN_WSALASTERROR): Can be defined if necessary.
-
-2010-01-26  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* ptw32_MCS_lock.c (ptw32_mcs_node_substitute): New routine
-	to allow relocating the lock owners thread-local node to somewhere
-	else, e.g. to global space so that another thread can release the
-	lock. Used in pthread_barrier_wait.
-	(ptw32_mcs_lock_try_acquire): New routine.
-	* pthread_barrier_init: Only one semaphore is used now.
-	* pthread_barrier_wait: Added an MCS guard lock with the last thread
-	to leave the barrier releasing the lock. This removes a deadlock bug
-	observed when there are greater than barrier-count threads
-	attempting to cross.
-	* pthread_barrier_destroy: Added an MCS guard lock.
-        
-2009-03-03  Stephan O'Farrill <stephan dot ofarrill at gmail dot com>
-
-	* pthread_attr_getschedpolicy.c: Add "const" to function parameter
-	in accordance with SUSv3 (POSIX).
-	* pthread_attr_getinheritsched.c: Likewise.
-	* pthread_mutexattr_gettype.c: Likewise.
-
-2008-06-06  Robert Kindred  <RKindred at SwRI dot edu>
-
-	* ptw32_throw.c (ptw32_throw): Remove possible reference to NULL
-	pointer. (At the same time made the switch block conditionally
-	included only if exitCode is needed - RPJ.)
-	* pthread_testcancel.c (pthread_testcancel): Remove duplicate and
-	misplaced pthread_mutex_unlock().
-
-2008-02-21  Sebastian Gottschalk  <seppig_relay at gmx dot de>
-
-	* pthread_attr_getdetachstate.c (pthread_attr_getdetachstate):
-	Remove potential and superfluous null pointer assignment.
-
-2007-11-22  Ivan Pizhenko  <ivanp4 at ua dot fm>
-
-	* pthread.h (gmtime_r): gmtime returns 0 if tm represents a time
-	prior to 1/1/1970. Notice this to prevent raising an exception.
-	* pthread.h (localtime_r): Likewise for localtime.
-
-2007-07-14  Marcel Ruff  <mr at marcelruff dot info>
-
-	* errno.c (_errno): Fix test for pthread_self() success.
-	* need_errno.h: Remove unintentional line wrap from #if line.
-
-2007-07-14  Mike Romanchuk  <mromanchuk at empirix dot com>
-
-	* pthread.h (timespec): Fix tv_sec type.
-
-2007-01-07  Sinan Kaya <sinan.kaya at siemens dot com>
-
-	* need_errno.h: Fix declaration of _errno - the local version of
-	_errno() is used, e.g. by WinCE.
-
-2007-01-06  Ross Johnson <ross.johnson at homemail dot com dot au>
-
-	* ptw32_semwait.c: Add check for invalid sem_t after acquiring the
-	sem_t state guard mutex and before affecting changes to sema state.
-                
-2007-01-06  Marcel Ruff <mr at marcelruff dot info>
-
-	* error.c: Fix reference to pthread handle exitStatus member for
-	builds that use NEED_ERRNO (i.e. WINCE).
-	* context.h: Add support for ARM processor (WinCE).
-	* mutex.c (process.h): Exclude for WINCE.
-	* create.c: Likewise.
-	* exit.c: Likewise.
-	* implement.h: Likewise.
-	* pthread_detach.c (signal.h): Exclude for WINCE.
-	* pthread_join.c: Likewise.
-	* pthread_kill.c: Likewise.
-	* pthread_rwlock_init.c (errno.h): Remove - included by pthread.h.
-	* pthread_rwlock_destroy.c: Likewise.
-	* pthread_rwlock_rdlock.c: Likewise.
-	* pthread_rwlock_timedrdlock.c: Likewise.
-	* pthread_rwlock_timedwrlock.c: Likewise.
-	* pthread_rwlock_tryrdlock.c: Likewise.
-	* pthread_rwlock_trywrlock.c: likewise.
-	* pthread_rwlock_unlock.c: Likewise.
-	* pthread_rwlock_wrlock.c: Likewise.
-	* pthread_rwlockattr_destroy.c: Likewise.
-	* pthread_rwlockattr_getpshared.c: Likewise.
-	* pthread_rwlockattr_init.c: Likewise.
-	* pthread_rwlockattr_setpshared.c: Likewise.
-
-2007-01-06  Romano Paolo Tenca <rotenca at telvia dot it>
-
-	* pthread_cond_destroy.c: Replace sem_wait() with non-cancelable
-	ptw32_semwait() since pthread_cond_destroy() is not a cancelation
-	point.
-	* implement.h (ptw32_spinlock_check_need_init): Add prototype.
-	* ptw32_MCS_lock.c: Reverse order of includes.
-
-2007-01-06  Eric Berge <eric dot berge at quantum dot com>
-
-	* pthread_cond_destroy.c: Add LeaveCriticalSection before returning
-	after errors.
-
-2007-01-04  Ross Johnson <ross.johnson at homemail dot com dot au>
-
-	* ptw32_InterlockedCompareExchange.c: Conditionally skip for
-	Win64 as not required.
-	* pthread_win32_attach_detach_np.c (pthread_win32_process_attach_np):
-	Test for InterlockedCompareExchange is not required for Win64.
-	* context.h: New file. Included by pthread_cancel.h and any tests
-	that need it (e.g. context1.c).
-	* pthread_cancel.c: Architecture-dependent context macros moved
-	to context.h.
-
-2007-01-04  Kip Streithorst <KSTREITH at ball dot com>
-
-	* implement.h (PTW32_INTERLOCKED_COMPARE_EXCHANGE): Add Win64
-	support.
-
-2006-12-20  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* sem_destroy.c: Fix the race involving invalidation of the sema;
-	fix incorrect return of EBUSY resulting from the mutex trylock
-	on the private mutex guard.
-	* sem_wait.c: Add check for invalid sem_t after acquiring the
-	sem_t state guard mutex and before affecting changes to sema state.
-	* sem_trywait.c: Likewise.
-	* sem_timedwait.c: Likewise.
-	* sem_getvalue.c: Likewise.
-	* sem_post.c: Similar.
-	* sem_post_multiple.c: Likewise.
-	* sem_init.c: Set max Win32 semaphore count to SEM_VALUE_MAX (was
-	_POSIX_SEM_VALUE_MAX, which is a lower value - the minimum).
-
-	* pthread_win32_attach_detach_np.c (pthread_win32_process_attach_np):
-	Load COREDLL.DLL under WINCE to check existence of
-	InterlockedCompareExchange() routine. This used to be done to test
-	for TryEnterCriticalSection() but was removed when this was no
-	longer needed.
-
-2006-01-25  Prashant Thakre <prashant.thakre at gmail.com>
-
-	* pthread_cancel.c: Added _M_IA64 register context support.
-
-2005-05-13  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* pthread_kill.c (pthread_kill): Remove check for Win32 thread
-	priority (to confirm HANDLE validity). Useless since thread HANDLEs
-	a not recycle-unique.
-
-2005-05-30  Vladimir Kliatchko  <vladimir at kliatchko.com>
-
-	* pthread_once.c: Re-implement using an MCS queue-based lock. The form
-	of pthread_once is as proposed by Alexander Terekhov (see entry of
-	2005-03-13). The MCS lock implementation does not require a unique
-	'name' to identify the lock between threads. Attempts to get the Event
-	or Semaphore based versions of pthread_once to a satisfactory level
-	of robustness have thus far failed. The last problem (avoiding races
-	involving non recycle-unique Win32 HANDLEs) was giving everyone
-	grey hair trying to solve it.
-
-	* ptw32_MCS_lock.c: New MCS queue-based lock implementation. These
-	locks are efficient: they have very low overhead in the uncontended case;
-	are efficient in contention and minimise cache-coherence updates in
-	managing the user level FIFO queue; do not require an ABI change in the
-	library.
-
-2005-05-27  Alexander Gottwald <alexander.gottwald at s1999.tu-chemnitz.de>
-
-	* pthread.h: Some things, like HANDLE, were only defined if
-	PTW32_LEVEL was >= 3. They should always be defined.
-
-2005-05-25  Vladimir Kliatchko  <vladimir at kliatchko.com>
-
-	* pthread_once.c: Eliminate all priority operations and other
-	complexity by replacing the event with a semaphore. The advantage
-	of the change is the ability to release just one waiter if the
-	init_routine thread is cancelled yet still release all waiters when
-	done. Simplify once_control state checks to improve efficiency
-	further.
-
-2005-05-24  Mikael Magnusson  <mikaelmagnusson at glocalnet.net>
-
-	* GNUmakefile: Patched to allow cross-compile with mingw32 on Linux.
-	It uses macros instead of referencing dlltool, gcc and g++ directly;
-	added a call to ranlib. For example the GC static library can be
-	built with:
-	make CC=i586-mingw32msvc-gcc RC=i586-mingw32msvc-windres \
-	RANLIB=i586-mingw32msvc-ranlib clean GC-static
-
-2005-05-13  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* pthread_win32_attach_detach_np.c (pthread_win32_thread_detach_np):
-	Move on-exit-only stuff from ptw32_threadDestroy() to here.
-	* ptw32_threadDestroy.c: It's purpose is now only to reclaim thread
-	resources for detached threads, or via pthread_join() or
-	pthread_detach() on joinable threads.
-	* ptw32_threadStart.c: Calling user destruct routines has moved to
-	pthread_win32_thread_detach_np(); call pthread_win32_thread_detach_np()
-	directly if statically linking, otherwise do so via dllMain; store
-	thread return value in thread struct for all cases, including
-	cancellation and exception exits; thread abnormal exits	go via
-	pthread_win32_thread_detach_np.
-	* pthread_join.c (pthread_join): Don't try to get return code from
-	Win32 thread - always get it from he thread struct.
-	* pthread_detach.c (pthread_detach): reduce extent of the thread
-	existence check since we now don't care if the Win32 thread HANDLE has
-	been closed; reclaim thread resources if the thread has exited already.
-	* ptw32_throw.c (ptw32_throw): For Win32 threads that are not implicit,
-	only Call thread cleanup if statically linking, otherwise leave it to
-	dllMain.
-	* sem_post.c (_POSIX_SEM_VALUE_MAX): Change to SEM_VALUE_MAX.
-	* sem_post_multiple.c: Likewise.
-	* sem_init.c: Likewise.
-
-2005-05-10  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* pthread_join.c (pthread_join): Add missing check for thread ID
-	reference count in thread existence test; reduce extent of the
-	existence test since we don't care if the Win32 thread HANDLE has
-	been closed.
-
-2005-05-09  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* ptw32_callUserDestroyRoutines.c: Run destructor process (i.e.
-	loop over all keys calling destructors) up to
-	PTHREAD_DESTRUCTOR_ITERATIONS times if TSD value isn't NULL yet;
-	modify assoc management.
-	* pthread_key_delete.c: Modify assoc management.
-	* ptw32_tkAssocDestroy.c: Fix error in assoc removal from chains.
-	* pthread.h
-	(_POSIX_THREAD_DESTRUCTOR_ITERATIONS): Define to value specified by
-	POSIX.
-	(_POSIX_THREAD_KEYS_MAX): Define to value specified by POSIX.
-	(PTHREAD_KEYS_MAX): Redefine [upward] to minimum required by POSIX.
-	(SEM_NSEMS_MAX): Define to implementation value.
-	(SEM_VALUE_MAX): Define to implementation value.
-	(_POSIX_SEM_NSEMS_MAX): Redefine to value specified by POSIX.
-	(_POSIX_SEM_VALUE_MAX): Redefine to value specified by POSIX.
-
-2005-05-06  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* signal.c (sigwait): Add a cancellation point to this otherwise
-	no-op.
-	* sem_init.c (sem_init): Check for and return ERANGE error.
-	* sem_post.c (sem_post): Likewise.
-	* sem_post_multiple.c (sem_post_multiple): Likewise.
-	* manual (directory): Added; see ChangeLog inside.
-
-2005-05-02  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* implement.h (struct pthread_key_t_): Change threadsLock to keyLock
-	so as not to be confused with the per thread lock 'threadlock';
-	change all references to it.
-	* implement.h (struct ThreadKeyAssoc): Remove lock; add prevKey
-	and prevThread pointers; re-implemented all routines that use this
-	struct. The effect of this is to save one handle per association,
-	which could potentially equal the number of keys multiplied by the
-	number of threads, accumulating over time - and to free the
-	association memory as soon as it is no longer referenced by either
-	the key or the thread. Previously, the handle and memory were
-	released only after BOTH key and thread no longer referenced the
-	association. That is, often no association resources were released
-	until the process itself exited. In addition, at least one race
-	condition has been removed - where two threads could attempt to
-	release the association resources simultaneously - one via
-	ptw32_callUserDestroyRoutines and the other via
-	pthread_key_delete.
-	- thanks to Richard Hughes at Aculab for discovering the problem.
-	* pthread_key_create.c: See above.
-	* pthread_key_delete.c: See above.
-	* pthread_setspecific.c: See above.
-	* ptw32_callUserDestroyRoutines.c: See above.
-	* ptw32_tkAssocCreate.c: See above.
-	* ptw32_tkAssocDestroy.c: See above.
-
-2005-04-27  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* sem_wait.c (ptw32_sem_wait_cleanup): after cancellation re-attempt
-	to acquire the semaphore to avoid a race with a late sem_post.
-	* sem_timedwait.c: Modify comments.
-
-2005-04-25  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* ptw32_relmillisecs.c: New module; converts future abstime to 
-	milliseconds relative to 'now'.
-	* pthread_mutex_timedlock.c: Use new ptw32_relmillisecs routine in
-	place of internal code; remove the NEED_SEM code - this routine is now
-	implemented for builds that define NEED_SEM (WinCE etc)
-	* sem_timedwait.c: Likewise; after timeout or cancellation,
-	re-attempt to acquire the semaphore in case one has been posted since
-	the timeout/cancel occurred. Thanks to Stefan Mueller.
-	* Makefile: Add ptw32_relmillisecs.c module; remove
-	ptw32_{in,de}crease_semaphore.c modules.
-	* GNUmakefile: Likewise.
-	* Bmakefile: Likewise.
-
-	* sem_init.c: Re-write the NEED_SEM code to be consistent with the
-	non-NEED_SEM code, but retaining use of an event in place of the w32 sema
-	for w32 systems that don't include semaphores (WinCE);
-	the NEED_SEM versions of semaphores has been broken for a long time but is
-	now fixed and supports all of the same routines as the non-NEED_SEM case.
-	* sem_destroy.c: Likewise.
-	* sem_wait.c: Likewise.
-	* sem_post.c: Likewise.
-	* sem_post_multple.c: Likewise.
-	* implement.h: Likewise.
-	* sem_timedwait.c: Likewise; this routine is now
-	implemented for builds that define NEED_SEM (WinCE etc).
-	* sem_trywait.c: Likewise.
-	* sem_getvalue.c: Likewise.
-
-	* pthread_once.c: Yet more changes, reverting closer to Gottlob Frege's
-	first design, but retaining cancellation, priority boosting, and adding
-	preservation of W32 error codes to make pthread_once transparent to
-	GetLastError.
-
-2005-04-11  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* pthread_once.c (pthread_once): Added priority boosting to
-	solve starvation problem after once_routine cancellation.
-	See notes in file.
-
-2005-04-06  Kevin Lussier <Kevin at codegreennetworks.com>
-
-	* Makefile: Added debug targets for all versions of the library.
-
-2005-04-01  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* GNUmakefile: Add target to build libpthreadGC1.a as a static link
-	library.
-	* Makefile: Likewise for pthreadGC1.lib.
-
-2005-04-01  Kevin Lussier <Kevin at codegreennetworks.com>
-
-	* sem_timedwait.c (sem_timedwait): Increase size of temp variables to
-	avoid int overflows for large timeout values.
-	* implement.h (int64_t): Include or define.
-
-2005-03-31   Dimitar Panayotov <develop at mail.bg>^M
-
-	* pthread.h: Fix conditional defines for static linking.
-	* sched.h: Liekwise.
-	* semaphore.h: Likewise.
-	* dll.c (PTW32_STATIC_LIB): Module is conditionally included
-	in the build.
-
-2005-03-16  Ross Johnson  <ross at callisto.canberra.edu.au>^M
-
-	* pthread_setcancelstate.c: Undo the last change.
-
-2005-03-16  Ross Johnson  <ross at callisto.canberra.edu.au>^M
-
-	* pthread_setcancelstate.c: Don't check for an async cancel event
-	if the library is using alertable async cancel..
-
-2005-03-14  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* pthread_once.c (pthread_once): Downgrade interlocked operations to simple
-	memory operations where these are protected by the critical section; edit
-	comments.
-
-2005-03-13  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_once.c (pthread_once): Completely redesigned; a change was
-	required to the ABI (pthread_once_t_), and resulting in a version
-	compatibility index increment.
-
-	NOTES:
-	The design (based on pseudo code contributed by Gottlob Frege) avoids
-	creating a kernel object if there is no contention. See URL for details:-
-	http://sources.redhat.com/ml/pthreads-win32/2005/msg00029.html
-	This uses late initialisation similar to the technique already used for
-	pthreads-win32 mutexes and semaphores (from Alexander Terekhov).
-
-	The subsequent cancelation cleanup additions (by rpj) could not be implemented
-	without sacrificing some of the efficiency in Gottlob's design. In particular,
-	although each once_control uses it's own event to block on, a global CS is
-	required to manage it - since the event must be either re-usable or
-	re-creatable under cancelation. This is not needed in the non-cancelable
-	design because it is able to mark the event as closed (forever).
-
-	When uncontested, a CS operation is equivalent to an Interlocked operation
-	in speed. So, in the final design with cancelability, an uncontested
-	once_control operation involves a minimum of five interlocked operations
-	(including the LeaveCS operation).
-	
-	ALTERNATIVES:
-	An alternative design from Alexander Terekhov proposed using a named mutex,
-	as sketched below:-
-
-	  if (!once_control) { // May be in TLS
-	    named_mutex::guard guard(&once_control2);
-	      if (!once_control2) {
-	         <init>
-	         once_control2 = true;
-	      }
-	    once_control = true;
-	  }
-	
-	A more detailed description of this can be found here:-
-	http://groups.yahoo.com/group/boost/message/15442
-
-	[Although the definition of a suitable PTHREAD_ONCE_INIT precludes use of the
-	TLS located flag, this is not critical.]
-	
-	There are three primary concerns though:-
-	1) The [named] mutex is 'created' even in the uncontended case.
-	2) A system wide unique name must be generated.
-	3) Win32 mutexes are VERY slow even in the uncontended 	case. An uncontested
-	Win32 mutex lock operation can be 50 (or more) times slower than an
-	uncontested EnterCS operation.
-
-	Ultimately, the named mutex trick is making use of the global locks maintained
-	by the kernel.
-
-	* pthread.h (pthread_once_t_): One flag and an event HANDLE added.
-	(PTHREAD_ONCE_INIT): Additional values included.
-
-2005-03-08  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_once.c (pthread_once): Redesigned to elliminate potential
-	starvation problem.
-	- reported by Gottlob Frege  <gottlobfrege at gmail.com>
-
-	* ptw32_threadDestroy.c (ptw32_threadDestroy): Implicit threads were
-	not closing their Win32 thread duplicate handle.
-	- reported by Dmitrii Semii <bogolt at gmail.com>
-
-2005-01-25  Ralf Kubis  <RKubis at mc.com>
-
-	* Attempted acquisition of recursive mutex was causing waiting
-	threads to not be woken when the mutex is released.
-
-	* GNUmakefile (GCE): Generate correct version resource comments.
-
-2005-01-01  Konstantin Voronkov  <beowinkle at yahoo.com>
-
-	* pthread_mutex_lock.c (pthread_mutex_lock): The new atomic exchange
-	mutex algorithm is known to allow a thread to steal the lock off
-	FIFO waiting threads. The next waiting FIFO thread gets a spurious
-	wake-up and must attempt to re-acquire the lock. The woken thread
-	was setting itself as the mutex's owner before the re-acquisition.
-
-2004-11-22  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Undo change
-	from 2004-11-02.
-	* Makefile (DLL_VER): Added for DLL naming suffix - see README.
-	* GNUmakefile (DLL_VER): Likewise.
-	* Wmakefile (DLL_VER): Likewise.
-	* Bmakefile (DLL_VER): Likewise.
-	* pthread.dsw (version.rc): Added to MSVS workspace.
-
-2004-11-20  Boudewijn Dekker  <b.dekker at ellipsis.nl>
-
-	* pthread_getspecific.c (pthread_getspecific): Check for
-	invalid (NULL) key argument.
-
-2004-11-19  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* config.h (PTW32_THREAD_ID_REUSE_INCREMENT): Added to allow
-	building the library for either unique thread IDs like Solaris
-	or non-unique thread IDs like Linux; allows application developers
-	to override the library's default insensitivity to some apps
-	that may not be strictly POSIX compliant.
-	* version.rc: New resource module to encode version information
-	within the DLL.
-	* pthread.h: Added PTW32_VERSION* defines and grouped sections
-	required by resource compiler together; bulk of file is skipped
-	if RC_INVOKED. Defined some error numbers and other names for
-	Borland compiler.
-
-2004-11-02  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Lock CV mutex at
-	start of cleanup handler rather than at the end.
-	* implement.h (PTW32_THREAD_REUSE_EMPTY): Renamed from *_BOTTOM.
-	(ptw32_threadReuseBottom): New global variable.
-	* global.c (ptw32_threadReuseBottom): Declare new variable.
-	* ptw32_reuse.c (ptw32_reuse): Change reuse LIFO stack to LILO queue
-	to more evenly distribute use of reusable thread IDs; use renamed
-	PTW32_THREAD_REUSE_EMPTY.
-	* ptw32_processTerminate.c (ptw2_processTerminate): Use renamed
-	PTW32_THREAD_REUSE_EMPTY.
-
-2004-10-31  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* implement.h (PThreadState): Add new state value
-	'PThreadStateCancelPending'.
-	* pthread_testcancel.c (pthread_testcancel): Use new thread
-	'PThreadStateCancelPending' state as short cut to avoid entering
-	kernel space via WaitForSingleObject() call. This was obviated
-	by user space sema acquisition in sem_wait() and sem_timedwait(),
-	which are also cancelation points. A call to pthread_testcancel()
-	was required, which introduced a kernel call, effectively nullifying
-	any gains made by the user space sem acquisition checks.
-	* pthread_cancel.c (pthread_cancel): Set new thread
-	'PThreadStateCancelPending' state.
-
-2004-10-29  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* implement.h (pthread_t): Renamed to ptw32_thread_t; struct contains
-	all thread state.
-	* pthread.h (ptw32_handle_t): New general purpose struct to serve
-	as a handle for various reusable object IDs - currently only used
-	by pthread_t; contains a pointer to ptw32_thread_t (thread state)
-	and a general purpose uint for use as a reuse counter or flags etc.
-	(pthread_t): typedef'ed to ptw32_handle_t; the uint is the reuse
-	counter that allows the library to maintain unique POSIX thread IDs.
-	When the pthread struct reuse stack was introduced, threads would
-	often acquire an identical ID to a previously destroyed thread. The
-	same was true for the pre-reuse stack library, by virtue of pthread_t
-	being the address of the thread struct. The new pthread_t retains
-	the reuse stack but provides virtually unique thread IDs.
-	* sem_wait.c (ptw32_sem_wait_cleanup): New routine used for
-	cancelation cleanup.
-	* sem_timedwait.c (ptw32_sem_timedwait_cleanup): Likewise.
-
-2004-10-22  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* sem_init.c (sem_init): Introduce a 'lock' element in order to
-	replace the interlocked operations with conventional serialisation.
-	This is needed in order to be able to atomically modify the sema
-	value and perform Win32 sema release operations. Win32 semaphores are
-	used instead of events in order to support efficient multiple posting.
-	If the whole modify/release isn't atomic, a race between
-	sem_timedwait() and sem_post() could result in a release when there is
-	no waiting semaphore, which would cause too many threads to proceed.
-	* sem_wait.c (sem_wait): Use new 'lock'element.
-	* sem_timedwait.c (sem_timedwait): Likewise.
-	* sem_trywait.c (sem_trywait): Likewise.
-	* sem_post.c (sem_post): Likewise.
-	* sem_post_multiple.c (sem_post_multiple): Likewise.
-	* sem_getvalue.c (sem_getvalue): Likewise.
-	* ptw32_semwait.c (ptw32_semwait): Likewise.
-	* sem_destroy.c (sem_destroy): Likewise; also tightened the conditions
-	for semaphore destruction; in particular, a semaphore will not be
-	destroyed if it has waiters.
-	* sem_timedwait.c (sem_timedwait): Added cancel cleanup handler to
-	restore sema value when cancelled.
-	* sem_wait.c (sem_wait): Likewise.
-
-2004-10-21  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_mutex_unlock.c (pthread_mutex_unlock): Must use PulseEvent()
-	rather than SetEvent() to reset the event if there are no waiters.
-
-2004-10-19  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* sem_init.c (sem_init): New semaphore model based on the same idea
-	as mutexes, i.e. user space interlocked check to avoid 
-	unnecessarily entering kernel space. Wraps the Win32 semaphore and
-	keeps it's own counter. Although the motivation to do this has existed
-	for a long time, credit goes to Alexander Terekhov for providing
-	the logic. I have deviated slightly from AT's logic to add the waiters
-	count, which has made the code more complicated by adding cancelation
-	cleanup. This also appears to have broken the VCE (C++ EH) version of
-	the library (the same problem as previously reported - see BUGS #2),
-	only apparently not fixable using the usual workaround, nor by turning
-	all optimisation off. The GCE version works fine, so it is presumed to
-	be a bug in MSVC++ 6.0. The cancelation exception is thrown and caught
-	correctly, but the cleanup class destructor is never called. The failing
-	test is tests\semaphore4.c.
-	* sem_wait.c (sem_wait): Implemented user space check model.
-	* sem_post.c (sem_post): Likewise.
-	* sem_trywait.c (sem_trywait): Likewise.
-	* sem_timedwait.c (sem_timedwait): Likewise.
-	* sem_post_multiple.c (sem_post_multiple): Likewise.
-	* sem_getvalue.c (sem_getvalue): Likewise.
-	* ptw32_semwait.c (ptw32_semwait): Likewise.
-	* implement.h (sem_t_): Add counter element.
-
-2004-10-15  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* implement.h (pthread_mutex_t_): Use an event in place of
-	the POSIX semaphore.
-	* pthread_mutex_init.c: Create the event; remove semaphore init.
-	* pthread_mutex_destroy.c: Delete the event.
-	* pthread_mutex_lock.c: Replace the semaphore wait with the event wait.
-	* pthread_mutex_trylock.c: Likewise.
-	* pthread_mutex_timedlock.c: Likewise.
-	* pthread_mutex_unlock.c: Set the event.
-	
-2004-10-14  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_mutex_lock.c (pthread_mutex_lock): New algorithm using
-	Terekhov's xchg based variation of Drepper's cmpxchg model.
-	Theoretically, xchg uses fewer clock cycles than cmpxchg (using IA-32
-	as a reference), however, in my opinion bus locking dominates the
-	equation on smp systems, so the model with the least number of bus
-	lock operations in the execution path should win, which is Terekhov's
-	variant. On IA-32 uni-processor systems, it's faster to use the
-	CMPXCHG instruction without locking the bus than to use the XCHG
-	instruction, which always locks the bus. This makes the two variants
-	equal for the non-contended lock (fast lane) execution path on up
-	IA-32. Testing shows that the xchg variant is faster on up IA-32 as
-	well if the test forces higher lock contention frequency, even though
-	kernel calls should be dominating the times (on up IA-32, both
-	variants used CMPXCHG instructions and neither locked the bus).
-	* pthread_mutex_timedlock.c pthread_mutex_timedlock(): Similarly.
-	* pthread_mutex_trylock.c (pthread_mutex_trylock): Similarly.
-	* pthread_mutex_unlock.c (pthread_mutex_unlock): Similarly.
-	* ptw32_InterlockedCompareExchange.c (ptw32_InterlockExchange): New
-	function.
-	(PTW32_INTERLOCKED_EXCHANGE): Sets up macro to use inlined
-	ptw32_InterlockedExchange.
-	* implement.h (PTW32_INTERLOCKED_EXCHANGE): Set default to
-	InterlockedExchange().
-	* Makefile: Building using /Ob2 so that asm sections within inline
-	functions are inlined.
-
-2004-10-08  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_mutex_destroy.c (pthread_mutex_destroy): Critical Section
-	element is no longer required.
-	* pthread_mutex_init.c (pthread_mutex_init): Likewise.
-	* pthread_mutex_lock.c (pthread_mutex_lock): New algorithm following
-	Drepper's paper at http://people.redhat.com/drepper/futex.pdf, but
-	using the existing semaphore in place of the futex described in the
-	paper. Idea suggested by Alexander Terekhov - see:
-	http://sources.redhat.com/ml/pthreads-win32/2003/msg00108.html
-	* pthread_mutex_timedlock.c pthread_mutex_timedlock(): Similarly.
-	* pthread_mutex_trylock.c (pthread_mutex_trylock): Similarly.
-	* pthread_mutex_unlock.c (pthread_mutex_unlock): Similarly.
-	* pthread_barrier_wait.c (pthread_barrier_wait): Use inlined version
-	of InterlockedCompareExchange() if possible - determined at
-	build-time.
-	* pthread_spin_destroy.c pthread_spin_destroy(): Likewise.
-	* pthread_spin_lock.c pthread_spin_lock():Likewise.
-	* pthread_spin_trylock.c (pthread_spin_trylock):Likewise.
-	* pthread_spin_unlock.c (pthread_spin_unlock):Likewise.
-	* ptw32_InterlockedCompareExchange.c: Sets up macro for inlined use.
-	* implement.h (pthread_mutex_t_): Remove Critical Section element.
-	(PTW32_INTERLOCKED_COMPARE_EXCHANGE): Set to default non-inlined
-	version of InterlockedCompareExchange().
-	* private.c: Include ptw32_InterlockedCompareExchange.c first for
-	inlining.
-	* GNUmakefile: Add commandline option to use inlined
-	InterlockedCompareExchange().
-	* Makefile: Likewise.
-
-2004-09-27  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_mutex_lock.c (pthread_mutex_lock): Separate
-	PTHREAD_MUTEX_NORMAL logic since we do not need to keep or check some
-	state required by other mutex types; do not check mutex pointer arg
-	for validity - leave this to the system since we are only checking
-	for NULL pointers. This should improve speed of NORMAL mutexes and
-	marginally improve speed of other type.
-	* pthread_mutex_trylock.c (pthread_mutex_trylock): Likewise.
-	* pthread_mutex_unlock.c (pthread_mutex_unlock): Likewise; also avoid
-	entering the critical section for the no-waiters case, with approx.
-	30% reduction in lock/unlock overhead for this case.
-	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise; also
-	no longer keeps mutex if post-timeout second attempt succeeds - this
-	will assist applications that wish to impose strict lock deadlines,
-	rather than simply to escape from frozen locks.
-
-2004-09-09  Tristan Savatier  <tristan at mpegtv.com>
-	* pthread.h (struct pthread_once_t_): Qualify the 'done' element
-	as 'volatile'.
-	* pthread_once.c: Concerned about possible race condition,
-	specifically on MPU systems re concurrent access to multibyte types.
-	[Maintainer's note: the race condition is harmless on SPU systems
-	and only a problem on MPU systems if concurrent access results in an
-	exception (presumably generated by a hardware interrupt). There are
-	other instances of similar harmless race conditions that have not
-	been identified as issues.]
-
-2004-09-09  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread.h: Declare additional types as volatile.
-
-2004-08-27  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_barrier_wait.c (pthread_barrier_wait): Remove excessive code
-	by substituting the internal non-cancelable version of sem_wait
-	(ptw32_semwait).
-
-2004-08-25  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_join.c (pthread_join): Rewrite and re-order the conditional
-	tests in an attempt to improve efficiency and remove a race
-	condition.
-
-2004-08-23  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* create.c (pthread_create): Don't create a thread if the thread
-	id pointer location (first arg) is inaccessible. A memory
-	protection fault will result if the thread id arg isn't an accessible
-	location. This is consistent with GNU/Linux but different to
-	Solaris or MKS (and possibly others), which accept NULL as meaning
-	'don't return the created thread's ID'. Applications that run
-	using pthreads-win32 will run on all other POSIX threads
-	implementations, at least w.r.t. this feature.
-
-	It was decided not to copy the Solaris et al behaviour because,
-	although it would have simplified some application porting (but only
-	from Solaris to Windows), the feature is not technically necessary,
-	and the alternative segfault behaviour helps avoid buggy application
-	code.
-
-2004-07-01  Anuj Goyal  <anuj.goyal at gmail.com>
-
-	* builddmc.bat: New; Windows bat file to build the library.
-	* config.h (__DMC__): Support for Digital Mars compiler.
-	* create.c (__DMC__): Likewise.
-	* pthread_exit.c (__DMC__): Likewise.
-	* pthread_join.c (__DMC__): Likewise.
-	* ptw32_threadDestroy.c (__DMC__): Likewise.
-	* ptw32_threadStart.c (__DMC__): Likewise.
-	* ptw32_throw.c (__DMC__): Likewise.
-
-2004-06-29  Anuj Goyal  <anuj.goyal at gmail.com>
-
-	* pthread.h (__DMC__): Initial support for Digital Mars compiler.
-
-2004-06-29  Will Bryant  <will.bryant at ecosm.com>
-
-	* README.Borland: New; description of Borland changes.
-	* Bmakefile: New makefile for the Borland make utility.
-	* ptw32_InterlockedCompareExchange.c:
-	Add Borland compatible asm code.
-
-2004-06-26  Jason Bard  <BardJA at Npt.NUWC.Navy.Mil>
-
-	* pthread.h (HAVE_STRUCT_TIMESPEC): If undefined, define it
-	to avoid timespec struct redefined errors elsewhere in an
-	application.
-
-2004-06-21  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread.h (PTHREAD_RECURSIVE_MUTEX_INITIALIZER): Mutex
-	initialiser added for compatibility with Linux threads and
-	others; currently not included in SUSV3.
-	* pthread.h (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER): Likewise.
-	* pthread.h (PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP): Likewise.
-	* pthread.h (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP): Likewise.
-
-	* ptw32_mutex_check_need_init.c (ptw32_mutex_check_need_init): 
-	Add new initialisers.
-
-	* pthread_mutex_lock.c (pthread_mutex_lock): Check for new
-	initialisers.
-	* pthread_mutex_trylock.c (pthread_mutex_trylock): Likewise.
-	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise.
-	* pthread_mutex_unlock.c (pthread_mutex_unlock): Likewise.
-	* pthread_mutex_destroy.c (pthread_mutex_destroy): Likewise.
-
-2004-05-20  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* README.NONPORTABLE: Document pthread_win32_test_features_np().
-	* FAQ: Update various answers.
-
-2004-05-19  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* Makefile: Don't define _WIN32_WINNT on compiler command line.
-	* GNUmakefile: Likewise.
-
-2004-05-16  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_cancel.c (pthread_cancel): Adapted to use auto-detected
-	QueueUserAPCEx features at run-time.
-	(ptw32_RegisterCancelation): Drop in replacement for QueueUserAPCEx()
-	if it can't be used. Provides older style non-preemptive async
-	cancelation.
-	* pthread_win32_attach_detach_np.c (pthread_win32_attach_np):
-	Auto-detect quserex.dll and the availability of alertdrv.sys;
-	initialise and close on process attach/detach.
-	* global.c (ptw32_register_cancelation): Pointer to either
-	QueueUserAPCEx() or ptw32_RegisterCancelation() depending on
-	availability. QueueUserAPCEx makes pre-emptive async cancelation
-	possible.
-	* implement.h: Add definitions and prototypes related to QueueUserAPC.
-
-2004-05-16  Panagiotis E. Hadjidoukas <peh at hpclab.ceid.upatras.gr>
-
-	* QueueUserAPCEx (separate contributed package): Provides preemptive
-	APC feature.
-	* pthread_cancel.c (pthread_cancel): Initial integration of
-	QueueUserAPCEx into pthreads-win32 to provide true pre-emptive
-	async cancelation of threads, including blocked threads.
-
-2004-05-06  Makoto Kato  <raven at oldskool.jp>
-
-	* pthread.h (DWORD_PTR): Define typedef for older MSVC.
-	* pthread_cancel.c (AMD64): Add architecture specific Context register.
-	* ptw32_getprocessors.c: Use correct types (DWORD_PTR) for mask
-	variables.
-
-2004-04-06  P. van Bruggen  <pietvb at newbridges.nl>
-
-	* ptw32_threadDestroy.c: Destroy threadLock mutex to
-	close a memory leak.
-
-2004-02-13  Gustav Hallberg  <gustav at virtutech.com>
-
-	* pthread_equal.c: Remove redundant equality logic.
-
-2003-12-10  Philippe Di Cristo  <philipped at voicebox.com>
-
-	* sem_timedwait.c (sem_timedwait): Fix timeout calculations.
-
-2003-10-20  Alexander Terekhov  <TEREKHOV at de.ibm.com>
-
-	* pthread_mutex_timedlock.c (ptw32_semwait): Move to individual module.
-	* ptw32_semwait.c: New module.
-	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Replace cancelable
-	sem_wait() call with non-cancelable ptw32_semwait() call.
-	* pthread.c (private.c): Re-order for inlining. GNU C warned that
-	function ptw32_semwait() was defined 'inline' after it was called.
-	* pthread_cond_signal.c (ptw32_cond_unblock): Likewise.
-	* pthread_delay_np.c: Disable Watcom warning with comment.
-	* *.c (process.h): Remove include from .c files. This is conditionally
-	included by the common project include files.
-
-2003-10-20  James Ewing  <james.ewing at sveasoft.com>
-
-	* ptw32_getprocessors.c: Some Win32 environments don't have
-	GetProcessAffinityMask(), so always return CPU count = 1 for them.
-	* config.h (NEED_PROCESSOR_AFFINITY_MASK): Define for WinCE.
-	
-2003-10-15  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* Re-indented all .c files using default GNU style to remove assorted
-	editor ugliness (used GNU indent utility in default style).
-
-2003-10-15  Alex Blanco  <Alex.Blanco at motorola.com>
-
-	* sem_init.c (sem_init): Would call CreateSemaphore even if the sema
-	struct calloc failed; was not freeing calloced memory if either
-	CreateSemaphore or CreateEvent failed.
-
-2003-10-14  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* pthread.h: Add Watcom compiler compatibility. Esssentially just add
-	the cdecl attribute to all exposed function prototypes so that Watcom
-	generates function call code compatible with non-Watcom built libraries.
-	By default, Watcom uses registers to pass function args if possible rather
-	than pushing to stack.
-	* semaphore.h: Likewise.
-	* sched.h: Likewise.
-	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Define with cdecl attribute
-	for Watcom compatibility. This routine is called via pthread_cleanup_push so
-	it had to match function arg definition.
-	* Wmakefile: New makefile for Watcom builds.
-
-2003-09-14  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_setschedparam.c (pthread_setschedparam): Attempt to map
-	all priority levels between max and min (as returned by
-	sched_get_priority_min/max) to reasonable Win32 priority levels - i.e.
-	levels between THREAD_PRIORITY_LOWEST/IDLE to THREAD_PRIORITY_LOWEST and
-	between THREAD_PRIORITY_HIGHEST/TIME_CRITICAL to THREAD_PRIORITY_HIGHEST
-	while others remain unchanged; record specified thread priority level
-	for return by pthread_getschedparam.
-
-	Note that, previously, specified levels not matching Win32 priority levels
-	would silently leave the current thread priority unaltered.
-
-	* pthread_getschedparam.c (pthread_getschedparam): Return the priority
-	level specified by the latest pthread_setschedparam or pthread_create rather
-	than the actual running thread priority as returned by GetThreadPriority - as
-	required by POSIX. I.e. temporary or adjusted actual priority levels are not
-	returned by this routine.
-
-	* pthread_create.c (pthread_create): For priority levels specified via
-	pthread attributes, attempt to map all priority levels between max and
-	min (as returned by sched_get_priority_min/max) to reasonable Win32
-	priority levels; record priority level given via attributes, or
-	inherited from parent thread, for later return by pthread_getschedparam.
-
-	* ptw32_new.c (ptw32_new): Initialise pthread_t_ sched_priority element.
-
-	* pthread_self.c (pthread_self): Set newly created implicit POSIX thread
-	sched_priority to Win32 thread's current actual priority. Temporarily
-	altered priorities can't be avoided in this case.
-
-	* implement.h (struct pthread_t_): Add new sched_priority element.
-
-2003-09-12  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* sched_get_priority_min.c (sched_get_priority_min): On error should return -1
-	with errno set.
-	* sched_get_priority_max.c (sched_get_priority_max): Likewise.
-
-2003-09-03  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* w32_cancelableWait.c (ptw32_cancelable_wait): Allow cancelation
-	of implicit POSIX threads as well.
-
-2003-09-02  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_win32_attach_detach_np.c (pthread_win32_thread_detach_np):
-	Add comment.
-
-	* pthread_exit.c (pthread_exit): Fix to recycle the POSIX thread handle in
-	addition to calling user TSD destructors. Move the implicit POSIX thread exit
-	handling to ptw32_throw to centralise the logic.
-
-	* ptw32_throw.c (ptw32_throw): Implicit POSIX threads have no point
-	to jump or throw to, so cleanup and exit the thread here in this case. For
-	processes using the C runtime, the exit code will be set to the POSIX
-	reason for the throw (i.e. PTHREAD_CANCEL or the value given to pthread_exit).
-	Note that pthread_exit() already had similar logic, which has been moved to
-	here.
-
-	* ptw32_threadDestroy.c (ptw32_threadDestroy): Don't close the Win32 handle
-	of implicit POSIX threads - expect this to be done by Win32?
-
-2003-09-01  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* pthread_self.c (pthread_self): The newly aquired pthread_t must be
-	assigned to the reuse stack, not freed, if the routine fails somehow.
-
-2003-08-13  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-	* pthread_getschedparam.c (pthread_getschedparam): An invalid thread ID
-	parameter was returning an incorrect error value; now uses a more exhaustive
-	check for validity.
-
-	* pthread_setschedparam.c (pthread_setschedparam): Likewise.
-
-	* pthread_join.c (pthread_join): Now uses a more exhaustive
-	check for validity.
-
-	* pthread_detach.c (pthread_detach): Likewise.
-
-	* pthread_cancel.c (pthread_cancel): Likewise.
-
-	* ptw32_threadDestroy.c (ptw32_threadDestroy): pthread_t structs are
-	never freed - push them onto a stack for reuse.
-
-	* ptw32_new.c (ptw32_new): Check for reusable pthread_t before dynamically
-	allocating new memory for the struct.
-
-	* pthread_kill.c (pthread_kill): New file; new routine; takes only a zero
-	signal arg so that applications can check the thread arg for validity; checks
-	that the underlying Win32 thread HANDLE is valid.
-
-	* pthread.h (pthread_kill): Add prototype.
-
-	* ptw32_reuse.c (ptw32_threadReusePop): New file; new routine; pop a
-	pthread_t off the reuse stack. pthread_t_ structs that have been destroyed, i.e.
-	have exited detached or have been joined, are cleaned up and put onto a reuse
-	stack. Consequently, thread IDs are no longer freed once calloced. The library
-	will attempt to get a struct off this stack before asking the system to alloc
-	new memory when creating threads. The stack is guarded by a global mutex.
-	(ptw32_threadReusePush): New routine; push a pthread_t onto the reuse stack.
-
-	* implement.h (ptw32_threadReusePush): Add new prototype.
-	(ptw32_threadReusePop): Likewise.
-	(pthread_t): Add new element.
-
-	* ptw32_processTerminate.c (ptw32_processTerminate): Delete the thread
-	reuse lock; free all thread ID structs on the thread reuse stack.
-
-	* ptw32_processInitialize.c (ptw32_processInitialize): Initialise the
-	thread reuse lock.
-
-2003-07-19  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-	* GNUmakefile: modified to work under MsysDTK environment.
-	* pthread_spin_lock.c (pthread_spin_lock): Check for NULL arg.
-	* pthread_spin_unlock.c (pthread_spin_unlock): Likewise.
-	* pthread_spin_trylock.c (pthread_spin_trylock): Likewise;
-	fix incorrect pointer value if lock is dynamically initialised by
-	this function.
-	* sem_init.c (sem_init): Initialise sem_t value to quell compiler warning.
-	* sem_destroy.c (sem_destroy): Likewise.
-	* ptw32_threadStart.c (non-MSVC code sections): Include <exception> rather
-	than old-style <new.h>; fix all std:: namespace entities such as
-	std::terminate_handler instances and associated methods.
-	* ptw32_callUserDestroyRoutines.c (non-MSVC code sections): Likewise.
-
-2003-06-24  Piet van Bruggen  <pietvb at newbridges.nl>
-
-	* pthread_spin_destroy.c (pthread_spin_destroy): Was not freeing the
-	spinlock struct.
-
-2003-06-22  Nicolas Barry  <boozai at yahoo.com>
-
-	* pthread_mutex_destroy.c (pthread_mutex_destroy): When called
-	with a recursive mutex that was locked by the current thread, the
-	function was failing with a success return code.
-
-2003-05-15  Steven Reddie  <Steven.Reddie at ca.com>
-
-	* pthread_win32_attach_detach_np.c (pthread_win32_process_detach_np):
-	NULLify ptw32_selfThreadKey after the thread is destroyed, otherwise
-	destructors calling pthreads routines might resurrect it again, creating
-	memory leaks. Call the underlying Win32 Tls routine directly rather than
-	pthread_setspecific().
-	(pthread_win32_thread_detach_np): Likewise.
-
-2003-05-14  Viv  <vcotirlea at hotmail.com>
-
-	* pthread.dsp: Change /MT compile flag to /MD.
-
-2003-03-04  Alexander Terekhov  <TEREKHOV at de.ibm.com>
-
-	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Fix failure to
-	set ownership of mutex on second grab after abstime timeout.
-	- bug reported by Robert Strycek <strycek at posam.sk>
-
-2002-12-17  Thomas Pfaff  <tpfaff at gmx.net>
-
-	* pthread_mutex_lock.c (ptw32_semwait): New static routine to provide
-	a non-cancelable sem_wait() function. This is consistent with the
-	way that pthread_mutex_timedlock.c does it.
-	(pthread_mutex_lock): Use ptw32_semwait() instead of sem_wait().
-
-2002-12-11  Thomas Pfaff  <tpfaff at gmx.net>
-
-	* pthread_mutex_trylock.c: Should return EBUSY rather than EDEADLK.
-	* pthread_mutex_destroy.c: Remove redundant ownership test (the
-	trylock call does this for us); do not destroy a recursively locked
-	mutex.
-
-2002-09-20  Michael Johnson  <michaelj at maine.rr.com>
-
-	* pthread_cond_destroy.c (pthread_cond_destroy): 
-	When two different threads exist, and one is attempting to
-	destroy a condition variable while the other is attempting to
-	initialize a condition variable that was created with
-	PTHREAD_COND_INITIALIZER, a deadlock can occur. Shrink
-	the ptw32_cond_list_lock critical section to fix it.
-
-2002-07-31  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* ptw32_threadStart.c (ptw32_threadStart): Thread cancelLock
-	destruction moved to ptw32_threadDestroy().
-
-	* ptw32_threadDestroy.c (ptw32_threadDestroy):  Destroy
-	the thread's cancelLock. Moved here from ptw32_threadStart.c
-	to cleanup implicit threads as well.
-
-2002-07-30  Alexander Terekhov  <TEREKHOV at de.ibm.com>
-
-	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): 
-	Remove code designed to avoid/prevent spurious wakeup
-	problems. It is believed that the sem_timedwait() call
-	is consuming a CV signal that it shouldn't and this is
-	breaking the avoidance logic.
-
-2002-07-30  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-	* sem_timedwait.c (sem_timedwait): Tighten checks for
-	unreasonable abstime values - that would result in
-	unexpected timeout values.
-
-	* w32_CancelableWait.c (ptw32_cancelable_wait):
-	Tighten up return value checking and add comments.
-
-
-2002-06-08  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* sem_getvalue.c (sem_getvalue): Now returns a value for the
-	NEED_SEM version (i.e. earlier versions of WinCE).
-
-
-2002-06-04  Rob Fanner  <rfanner at stonethree.com>
-
-	* sem_getvalue.c (sem_getvalue): The Johnson M. Hart
-	approach didn't work - we are forced to take an
-	intrusive approach. We try to decrement the sema
-	and then immediately release it again to get the
-	value. There is a small probability that this may
-	block other threads, but only momentarily.
-
-2002-06-03  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-	* sem_init.c (sem_init): Initialise Win32 semaphores
-	to _POSIX_SEM_VALUE_MAX (which this implementation
-	defines in pthread.h) so that sem_getvalue() can use
-	the trick described in the comments in sem_getvalue().
-	* pthread.h (_POSIX_SEM_VALUE_MAX): Defined.
-	(_POSIX_SEM_NSEMS_MAX): Defined - not used but may be
-	useful for source code portability.
-
-2002-06-03  Rob Fanner  <rfanner at stonethree.com>
-
-	* sem_getvalue.c (sem_getvalue): Did not work on NT.
-	Use approach suggested by Johnson M. Hart in his book
-	"Win32 System Programming".
-
-2002-02-28  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* errno.c: Compiler directive was incorrectly including code.
-	* pthread.h: Conditionally added some #defines from config.h
-	needed when not building the library. e.g. NEED_ERRNO, NEED_SEM.
-	(PTW32_DLLPORT): Now only defined if _DLL defined.
-	(_errno): Compiler directive was incorrectly including prototype.
-	* sched.h: Conditionally added some #defines from config.h
-	needed when not building the library.
-	* semaphore.h: Replace an instance of NEED_SEM that should
-	have been NEED_ERRNO. This change currently has nil effect.
-
-	* GNUmakefile: Correct some recent changes.
-
-	* Makefile: Add rule to generate pre-processor output.
-
-2002-02-23  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* pthread_rwlock_timedrdlock.c: New - untested.
-	* pthread_rwlock_timedwrlock.c: New - untested.
-	
-	* Testsuite passed (except known MSVC++ problems)
-
-	* pthread_cond_destroy.c: Expand the time change
-	critical section to solve deadlock problem.
-
-	* pthread.c: Add all remaining C modules.
-	* pthread.h: Use dllexport/dllimport attributes on functions
-	to avoid using pthread.def.
-	* sched.h: Likewise.
-	* semaphore.h: Likewise.
-	* GNUmakefile: Add new targets for single translation
-	unit build to maximise inlining potential; generate
-	pthread.def automatically.
-	* Makefile: Likewise, but no longer uses pthread.def.
-
-2002-02-20  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* pthread_cond_destroy.c (pthread_cond_destroy):
-	Enter the time change critical section earlier.
-
-2002-02-17  Ross Johnson  <rpj at setup1.ise.canberra.edu.au
-
-	* Testsuite passed.
-
-	* pthread_timechange_handler_np.c: New; following
-	a suggestion from Alexander Terekhov that CVs should
-	be broadcast so that they all re-evaluate their
-	condition variables and reset a new timeout if
-	required, whenever an application receives a
-	WM_TIMECHANGE message. This message indicates that
-	the system time has been changed. Therefore, CVs
-	waiting for a timeout set as an abs_time will possibly
-	not wake up at the expected time. Some applications
-	may not be tolerant of this.
-	* pthread_cond_init.c: Add CV to linked list.
-	* pthread_cond_destroy.c: Remove CV from linked list.
-	* global.c (ptw32_cond_list_head): New variable.
-	(ptw32_cond_list_tail): New variable.
-	(ptw32_cond_list_cs): New critical section.
-	* ptw32_processInitialize (ptw32_cond_list_cs): Initialize.
-	* ptw32_processTerminate (ptw32_cond_list_cs): Delete.
-
-
-	* Reduce executable size.
-	  -----------------------
-	When linking with the static library, only those
-	routines actually called, either directly or indirectly
-	should be included.
-
-	[Gcc has the -ffunction-segments option to do this but MSVC
-	doesn't have this feature as far as I can determine. Other
-	compilers are undetermined as well. - rpj]
-
-	* spin.c: Split file into function segments.
-	* ptw32_spinlock_check_need_init.c: Separated routine from spin.c.
-	* pthread_spin_init.c: Likewise.
-	* pthread_spin_destroy.c: Likewise.
-	* pthread_spin_lock.c: Likewise.
-	* pthread_spin_unlock.c: Likewise.
-	* pthread_spin_trylock.c: Likewise.
-
-	* sync.c: Split file into function segments.
-	* pthread_detach.c: Separated routine from sync.c.
-	* pthread_join.c: Likewise.
-
-	* tsd.c: Split file into function segments.
-	* pthread_key_create.c: Separated routine from tsd.c.
-	* pthread_key_delete.c: Likewise.
-	* pthread_setspecific.c: Likewise.
-	* pthread_getspecific.c: Likewise.
-
-	* sched.c: Split file into function segments.
-	* pthread_attr_setschedpolicy.c: Separated routine from sched.c.
-	* pthread_attr_getschedpolicy.c: Likewise.
-	* pthread_attr_setschedparam.c: Likewise.
-	* pthread_attr_getschedparam.c: Likewise.
-	* pthread_attr_setinheritsched.c: Likewise.
-	* pthread_attr_getinheritsched.c: Likewise.
-	* pthread_setschedparam.c: Likewise.
-	* pthread_getschedparam.c: Likewise.
-	* sched_get_priority_max.c: Likewise.
-	* sched_get_priority_min.c: Likewise.
-	* sched_setscheduler.c: Likewise.
-	* sched_getscheduler.c: Likewise.
-	* sched_yield.c: Likewise.
-
-
-2002-02-16  Ross Johnson  <rpj at setup1.ise.canberra.edu.au
-
-	Reduce executable size.
-	-----------------------
-	When linking with the static library, only those
-	routines actually called, either directly or indirectly
-	should be included.
-
-	[Gcc has the -ffunction-segments option to do this but MSVC
-	doesn't have this feature as far as I can determine. Other
-	compilers are undetermined as well. - rpj]
-
-	* mutex.c: Split file into function segments.
-	* pthread_mutexattr_destroy.c: Separated routine from mutex.c
-	* pthread_mutexattr_getpshared.c: Likewise.
-	* pthread_mutexattr_gettype.c: Likewise.
-	* pthread_mutexattr_init.c: Likewise.
-	* pthread_mutexattr_setpshared.c: Likewise.
-	* pthread_mutexattr_settype.c: Likewise.
-	* ptw32_mutex_check_need_init.c: Likewise.
-	* pthread_mutex_destroy.c: Likewise.
-	* pthread_mutex_init.c: Likewise.
-	* pthread_mutex_lock.c: Likewise.
-	* pthread_mutex_timedlock.c: Likewise.
-	* pthread_mutex_trylock.c: Likewise.
-	* pthread_mutex_unlock.c: Likewise.
-	
-	* private.c: Split file into function segments.
-	* ptw32_InterlockedCompareExchange.c: Separated routine from private.c
-	* ptw32_callUserDestroyRoutines.c: Likewise.
-	* ptw32_getprocessors.c: Likewise.
-	* ptw32_processInitialize.c: Likewise.
-	* ptw32_processTerminate.c: Likewise.
-	* ptw32_threadDestroy.c: Likewise.
-	* ptw32_threadStart.c: Likewise.
-	* ptw32_throw.c: Likewise.
-	* ptw32_timespec.c: Likewise.
-	* ptw32_tkAssocCreate.c: Likewise.
-	* ptw32_tkAssocDestroy.c: Likewise.
-
-	* rwlock.c: Split file into function segments.
-	* pthread_rwlockattr_destroy.c: Separated routine from rwlock.c
-	* pthread_rwlockattr_getpshared.c: Likewise.
-	* pthread_rwlockattr_init.c: Likewise.
-	* pthread_rwlockattr_setpshared.c: Likewise.
-	* ptw32_rwlock_check_need_init.c: Likewise.
-	* pthread_rwlock_destroy.c: Likewise.
-	* pthread_rwlock_init.c: Likewise.
-	* pthread_rwlock_rdlock.c: Likewise.
-	* pthread_rwlock_tryrdlock.c: Likewise.
-	* pthread_rwlock_trywrlock.c: Likewise.
-	* pthread_rwlock_unlock.c: Likewise.
-	* pthread_rwlock_wrlock.c: Likewise.
-
-2002-02-10  Ross Johnson  <rpj at setup1.ise.canberra.edu.au
-
-	Reduce executable size.
-	-----------------------
-	When linking with the static library, only those
-	routines actually called, either directly or indirectly
-	should be included.
-
-	[Gcc has the -ffunction-segments option to do this but MSVC
-	doesn't have this feature as far as I can determine. Other
-	compilers are undetermined as well. - rpj]
-
-	* nonportable.c: Split file into function segments.
-	* np_delay.c: Separated routine from nonportable.c
-	* np_getw32threadhandle.c: Likewise.
-	* np_mutexattr_setkind.c: Likewise.
-	* np_mutexattr_getkind.c: Likewise.
-	* np_num_processors.c: Likewise.
-	* np_win32_attach_detach.c: Likewise.
-
-	* misc.c: Split file into function segments.
-	* pthread_equal.c: Separated routine from nonportable.c.
-	* pthread_getconcurrency.c: Likewise.
-	* pthread_once.c: Likewise.
-	* pthread_self.c: Likewise.
-	* pthread_setconcurrency.c: Likewise.
-	* ptw32_calloc.c: Likewise.
-	* ptw32_new.c: Likewise.
-	* w32_CancelableWait.c: Likewise.
-	
-2002-02-09  Ross Johnson  <rpj at setup1.ise.canberra.edu.au
-
-	Reduce executable size.
-	-----------------------
-	When linking with the static library, only those
-	routines actually called, either directly or indirectly
-	should be included.
-
-	[Gcc has the -ffunction-segments option to do this but MSVC
-	doesn't have this feature as far as I can determine. Other
-	compilers are undetermined as well. - rpj]
-
-	* condvar.c: Split file into function segments.
-	* pthread_condattr_destroy.c: Separated routine from condvar.c.
-	* pthread_condattr_getpshared.c: Likewise.
-	* pthread_condattr_init.c: Likewise.
-	* pthread_condattr_setpshared.c: Likewise.
-	* ptw32_cond_check_need_init.c: Likewise.
-	* pthread_cond_destroy.c: Likewise.
-	* pthread_cond_init.c: Likewise.
-	* pthread_cond_signal.c: Likewise.
-	* pthread_cond_wait.c: Likewise.
-	
-2002-02-07  Alexander Terekhov<TEREKHOV at de.ibm.com>
-
-	* nonportable.c (pthread_delay_np): Make a true
-	cancelation point. Deferred cancels will interrupt the
-	wait.
-
-2002-02-07  Ross Johnson  <rpj at setup1.ise.canberra.edu.au
-
-	* misc.c (ptw32_new): Add creation of cancelEvent so that
-	implicit POSIX threads (Win32 threads with a POSIX face)
-	are cancelable; mainly so that pthread_delay_np doesn't fail
-	if called from the main thread.
-	* create.c (pthread_create): Remove creation of cancelEvent
-	from here; now in ptw32_new().
-
-	Reduce executable size.
-	-----------------------
-	When linking with the static library, only those
-	routines actually called, either directly or indirectly
-	should be included.
-
-	[Gcc has the -ffunction-segments option to do this but MSVC
-	doesn't have this feature as far as I can determine. Other
-	compilers are undetermined as well. - rpj]
-
-	* barrier.c: All routines are now in separate compilation units;
-	This file is used to congregate the separate modules for
-	potential inline optimisation and backward build compatibility.
-	* cancel.c: Likewise.
-	* pthread_barrierattr_destroy.c: Separated routine from cancel.c.
-	* pthread_barrierattr_getpshared.c: Likewise.
-	* pthread_barrierattr_init.c: Likewise.
-	* pthread_barrierattr_setpshared.c: Likewise.
-	* pthread_barrier_destroy.c: Likewise.
-	* pthread_barrier_init.c: Likewise.
-	* pthread_barrier_wait.c: Likewise.
-	* pthread_cancel.c: Likewise.
-	* pthread_setcancelstate.c: Likewise.
-	* pthread_setcanceltype.c: Likewise.
-	* pthread_testcancel.c: Likewise.
-
-2002-02-04  Max Woodbury <mtew at cds.duke.edu>
-
-	Reduced name space pollution.
-	-----------------------------
-	When the appropriate symbols are defined, the headers
-	will restrict the definitions of new names. In particular,
-	it must be possible to NOT include the <windows.h>
-	header and related definitions with some combination
-	of symbol definitions. Secondly, it should be possible
-	that additional definitions should be limited to POSIX 
-	compliant symbols by the definition of appropriate symbols.
-
-	* pthread.h: POSIX conditionals.
-	* sched.h: POSIX conditionals.
-	* semaphore.h: POSIX conditionals.
-
-	* semaphore.c: Included <limits.h>.
-	(sem_init): Changed magic 0x7FFFFFFFL to INT_MAX.
-	(sem_getvalue): Trial version.
-
-	Reduce executable size.
-	-----------------------
-	When linking with the static library, only those
-	routines actually called, either directly or indirectly
-	should be included.
-
-	[Gcc has the -ffunction-segments option to do this but MSVC
-	doesn't have this feature as far as I can determine. Other
-	compilers are undetermined as well. - rpj]
-
-	* semaphore.c: All routines are now in separate compilation units;
-	This file is used to congregate the separate modules for
-	potential inline optimisation and backward build compatibility.
-	* sem_close.c: Separated routine from semaphore.c.
-	* ptw32_decrease_semaphore.c: Likewise.
-	* sem_destroy.c: Likewise.
-	* sem_getvalue.c: Likewise.
-	* ptw32_increase_semaphore.c: Likewise.
-	* sem_init.c: Likewise.
-	* sem_open.c: Likewise.
-	* sem_post.c: Likewise.
-	* sem_post_multiple.c: Likewise.
-	* sem_timedwait.c: Likewise.
-	* sem_trywait.c: Likewise.
-	* sem_unlink.c: Likewise.
-	* sem_wait.c: Likewise.
-
-2002-02-04  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	The following extends the idea above to the rest of pthreads-win32 - rpj
-	
-	* attr.c: All routines are now in separate compilation units;
-	This file is used to congregate the separate modules for
-	potential inline optimisation and backward build compatibility.
-	* pthread_attr_destroy.c: Separated routine from attr.c.
-	* pthread_attr_getdetachstate.c: Likewise.
-	* pthread_attr_getscope.c: Likewise.
-	* pthread_attr_getstackaddr.c: Likewise.
-	* pthread_attr_getstacksize.c: Likewise.
-	* pthread_attr_init.c: Likewise.
-	* pthread_attr_is_attr.c: Likewise.
-	* pthread_attr_setdetachstate.c: Likewise.
-	* pthread_attr_setscope.c: Likewise.
-	* pthread_attr_setstackaddr.c: Likewise.
-	* pthread_attr_setstacksize.c: Likewise.
-
-	* pthread.c: Agregation of agregate modules for super-inlineability.
-
-2002-02-02  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* cancel.c: Rearranged some code and introduced checks
-	to disable cancelation at the start of a thread's cancelation
-	run to prevent double cancelation. The main problem
-	arises if a thread is canceling and then receives a subsequent
-	async cancel request.
-	* private.c: Likewise.
-	* condvar.c: Place pragmas around cleanup_push/pop to turn
-	off inline optimisation (/Obn where n>0 - MSVC only). Various
-	optimisation switches in MSVC turn this on, which interferes with
-	the way that cleanup handlers are run in C++ EH and SEH
-	code. Application code compiled with inline optimisation must
-	also wrap cleanup_push/pop blocks with the pragmas, e.g.
-	  #pragma inline_depth(0)
-	  pthread_cleanup_push(...)
-	    ...
-	  pthread_cleanup_pop(...)
-	  #pragma inline_depth(8)
-	* rwlock.c: Likewise.
-	* mutex.c: Remove attempts to inline some functions.
-	* signal.c: Modify misleading comment.
-
-2002-02-01  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* semaphore.c (sem_trywait): Fix missing errno return
-	for systems that define NEED_SEM (e.g. early WinCE).
-	* mutex.c (pthread_mutex_timedlock): Return ENOTSUP
-	for systems that define NEED_SEM since they don't
-	have sem_trywait().
-
-2002-01-27  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* mutex.c (pthread_mutex_timedlock): New function suggested by
-	Alexander Terekhov. The logic required to implement this
-	properly came from Alexander, with some collaboration
-	with Thomas Pfaff.
-	(pthread_mutex_unlock): Wrap the waiters check and sema
-	post in a critical section to prevent a race with
-	pthread_mutex_timedlock.
-	(ptw32_timed_semwait): New function;
-	returns a special result if the absolute timeout parameter
-	represents a time already passed when called; used by
-	pthread_mutex_timedwait(). Have deliberately not reused
-	the name "ptw32_sem_timedwait" because they are not the same
-	routine.
-	* condvar.c (ptw32_cond_timedwait): Use the new sem_timedwait()
-	instead of ptw32_sem_timedwait(), which now has a different
-	function. See previous.
-	* implement.h: Remove prototype for ptw32_sem_timedwait.
-	See next.
-	(pthread_mutex_t_): Add critical section element for access
-	to lock_idx during mutex post-timeout processing.
-	* semaphore.h (sem_timedwait): See next.
-	* semaphore.c (sem_timedwait): See next.
-	* private.c (ptw32_sem_timedwait): Move to semaphore.c
-	and rename as sem_timedwait().
-
-2002-01-18  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* sync.c (pthread_join): Was getting the exit code from the
-	calling thread rather than the joined thread if
-	defined(__MINGW32__) && !defined(__MSVCRT__).
-
-2002-01-15  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* pthread.h: Unless the build explicitly defines __CLEANUP_SEH,
-	__CLEANUP_CXX, or __CLEANUP_C, then the build defaults to
-	__CLEANUP_C style cleanup. This style uses setjmp/longjmp
-	in the cancelation and thread exit implementations and therefore
-	won't do stack unwinding if linked to applications that have it
-	(e.g. C++ apps). This is currently consistent with most/all
-	commercial Unix POSIX threads implementations.
-
-	* spin.c (pthread_spin_init): Edit renamed function call.
-	* nonportable.c (pthread_num_processors_np): New.
-	(pthread_getprocessors_np): Renamed to ptw32_getprocessors
-	and moved to private.c.
-	* private.c (pthread_getprocessors): Moved here from
-	nonportable.c.
-	* pthread.def (pthread_getprocessors_np): Removed
-	from export list.
-
-	* rwlock.c (pthread_rwlockattr_init): New.
-	(pthread_rwlockattr_destroy): New.
-	(pthread_rwlockattr_getpshared): New.
-	(pthread_rwlockattr_setpshared): New.
-
-2002-01-14  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* attr.c (pthread_attr_setscope): Fix struct pointer
-	indirection error introduced 2002-01-04.
-	(pthread_attr_getscope): Likewise.
-
-2002-01-12  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* pthread.dsp (SOURCE): Add missing source files.
-
-2002-01-08  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* mutex.c (pthread_mutex_trylock): use
-	ptw32_interlocked_compare_exchange function pointer
-	rather than ptw32_InterlockedCompareExchange() directly
-	to retain portability to non-iX86 processors,
-	e.g. WinCE etc. The pointer will point to the native
-	OS version of InterlockedCompareExchange() if the
-	OS supports it (see ChangeLog entry of 2001-10-17).
-
-2002-01-07  Thomas Pfaff <tpfaff at gmx.net>, Alexander Terekhov <TEREKHOV at de.ibm.com>
-
-	* mutex.c (pthread_mutex_init): Remove critical
-	section calls.
-	(pthread_mutex_destroy): Likewise.
-	(pthread_mutex_unlock): Likewise.
-	(pthread_mutex_trylock): Likewise; uses
-	ptw32_InterlockedCompareExchange() to avoid need for
-	critical section; library is no longer i386 compatible;
-	recursive mutexes now increment the lock count rather
-	than return EBUSY; errorcheck mutexes return EDEADLCK
-	rather than EBUSY. This behaviour is consistent with the
-	Solaris pthreads implementation.
-	* implement.h (pthread_mutex_t_): Remove critical
-	section element - no longer needed.
-	
-
-2002-01-04  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* attr.c (pthread_attr_setscope): Add more error
-	checking and actually store the scope value even
-	though it's not really necessary.
-	(pthread_attr_getscope): Return stored value.
-	* implement.h (pthread_attr_t_): Add new scope element.
-	* ANNOUNCE: Fix out of date comment next to
-	pthread_attr_setscope in conformance section.
-
-2001-12-21  Alexander Terekhov <TEREKHOV at de.ibm.com>
-
-	* mutex.c (pthread_mutex_lock): Decrementing lock_idx was
-	not thread-safe.
-	(pthread_mutex_trylock): Likewise.
-
-2001-10-26  prionx at juno.com
-
-	* semaphore.c (sem_init): Fix typo and missing bracket
-	in conditionally compiled code. Only older versions of
-	WinCE require this code, hence it doesn't normally get
-	tested; somehow when sem_t reverted to an opaque struct
-	the calloc NULL check was left in the conditionally included
-	section.
-	(sem_destroy): Likewise, the calloced sem_t wasn't being freed.
-
-2001-10-25  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* GNUmakefile (libwsock32): Add to linker flags for
-	WSAGetLastError() and WSASetLastError().
-	* Makefile (wsock32.lib): Likewise.
-	* create.c: Minor mostly inert changes.
-	* implement.h (PTW32_MAX): Move into here and renamed
-	from sched.h.
-	(PTW32_MIN): Likewise.
-	* GNUmakefile (TEST_ICE): Define if testing internal
-	implementation of InterlockedCompareExchange.
-	* Makefile (TEST_ICE): Likewise.
-	* private.c (TEST_ICE): Likewise.
-	
-2001-10-24  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* attr.c (pthread_attr_setstacksize): Quell warning
-	from LCC by conditionally compiling the stacksize
-	validity check. LCC correctly warns that the condition
-	(stacksize < PTHREAD_STACK_MIN) is suspicious
-	because STACK_MIN is 0 and stacksize is of type
-	size_t (or unsigned int).
-
-2001-10-17  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* barrier.c: Move _LONG and _LPLONG defines into
-	implement.h; rename to PTW32_INTERLOCKED_LONG and
-	PTW32_INTERLOCKED_LPLONG respectively.
-	* spin.c: Likewise; ptw32_interlocked_compare_exchange used
-	in place of InterlockedCompareExchange directly.
-	* global.c (ptw32_interlocked_compare_exchange): Add
-	prototype for this new routine pointer to be used when
-	InterlockedCompareExchange isn't supported by Windows.
-	* nonportable.c (pthread_win32_process_attach_np): Check for
-	support of InterlockedCompareExchange in kernel32 and assign its
-	address to ptw32_interlocked_compare_exchange if it exists, or
-	our own ix86 specific implementation ptw32_InterlockedCompareExchange.
-	*private.c (ptw32_InterlockedCompareExchange): An
-	implementation of InterlockedCompareExchange() which is
-	specific to ix86; written directly in assembler for either
-	MSVC or GNU C; needed because Windows 95 doesn't support
-	InterlockedCompareExchange().
-
-	* sched.c (sched_get_priority_min): Extend to return
-	THREAD_PRIORITY_IDLE.
-	(sched_get_priority_max): Extend to return
-	THREAD_PRIORITY_CRITICAL.
-
-2001-10-15  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* spin.c (pthread_spin_lock): PTHREAD_SPINLOCK_INITIALIZER
-	was causing a program fault.
-	(pthread_spin_init): Could have alloced memory
-	without freeing under some error conditions.
-
-	* mutex.c (pthread_mutex_init): Move memory
-	allocation of mutex struct after checking for
-	PROCESS_SHARED.
-
-2001-10-12  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* spin.c (pthread_spin_unlock): Was not returning
-	EPERM if the spinlock was not locked, for multi CPU
-	machines.
-
-2001-10-08  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* spin.c (pthread_spin_trylock): Was not returning
-	EBUSY for multi CPU machines.
-
-2001-08-24  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* condvar.c (pthread_cond_destroy): Remove cv element
-	that is no longer used.
-	* implement.h: Likewise.
-
-2001-08-23  Alexander Terekhov <TEREKHOV at de.ibm.com>
-
-	* condvar.c (pthread_cond_destroy): fix bug with
-	respect to deadlock in the case of concurrent
-	_destroy/_unblock; a condition variable can be destroyed
-	immediately after all the threads that are blocked on
-	it are awakened.
-
-2001-08-23  Phil Frisbie, Jr. <phil at hawksoft.com>
-
-	* tsd.c (pthread_getspecific): Preserve the last
-	winsock error [from WSAGetLastError()].
-
-2001-07-18  Scott McCaskill <scott at magruder.org>
-
-	* mutex.c (pthread_mutexattr_init): Return ENOMEM
-	immediately and don't dereference the NULL pointer
-	if calloc fails.
-	(pthread_mutexattr_getpshared): Don't dereference
-	a pointer that is possibly NULL.
-	* barrier.c (pthread_barrierattr_init): Likewise
-	(pthread_barrierattr_getpshared): Don't dereference
-	a pointer that is possibly NULL.
-	* condvar.c (pthread_condattr_getpshared): Don't dereference
-	a pointer that is possibly NULL.
-
-2001-07-15  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* rwlock.c (pthread_rwlock_wrlock): Is allowed to be
-	a cancelation point; re-enable deferred cancelability
-	around the CV call.
-
-2001-07-10  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* barrier.c: Still more revamping. The exclusive access
-	mutex isn't really needed so it has been removed and replaced
-	by an InterlockedDecrement(). nSerial has been removed.
-	iStep is now dual-purpose. The process shared attribute
-	is now stored in the barrier struct.
-	* implement.h (pthread_barrier_t_): Lost some/gained one
-	elements.
-	* private.c (ptw32_threadStart): Removed some comments.
-
-2001-07-10  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* barrier.c: Revamped to fix the race condition. Two alternating
-	semaphores are used instead of the PulseEvent. Also improved
-	overall throughput by returning PTHREAD_BARRIER_SERIAL_THREAD
-	to the first waking thread.
-	* implement.h (pthread_barrier_t_): Revamped.
-
-2001-07-09  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* barrier.c: Fix several bugs in all routines. Now passes
-	tests/barrier5.c which is fairly rigorous. There is still
-	a non-optimal work-around for a race condition between
-	the barrier breeched event signal and event wait. Basically
-	the last (signalling) thread to hit the barrier yields
-	to allow any other threads, which may have lost the race,
-	to complete.
-
-2001-07-07  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* barrier.c: Changed synchronisation mechanism to a
-	Win32 manual reset Event and use PulseEvent to signal
-	waiting threads. If the implementation continued to use
-	a semaphore it would require a second semaphore and
-	some management to use them alternately as barriers. A
-	single semaphore allows threads to cascade from one barrier
-	through the next, leaving some threads blocked at the first.
-	* implement.h (pthread_barrier_t_): As per above.
-	* general: Made a number of other routines inlinable.
-
-2001-07-07  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* spin.c: Revamped and working; included static initialiser.
-	Now beta level.
-	* barrier.c: Likewise.
-	* condvar.c: Macro constant change; inline auto init routine.
-	* mutex.c: Likewise.
-	* rwlock.c: Likewise.
-	* private.c: Add support for spinlock initialiser.
-	* global.c: Likewise.
-	* implement.h: Likewise.
-	* pthread.h (PTHREAD_SPINLOCK_INITIALIZER): Fix typo.
-
-2001-07-05  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* barrier.c: Remove static initialisation - irrelevent
-	for this object.
-	* pthread.h (PTHREAD_BARRIER_INITIALIZER): Removed.
-	* rwlock.c (pthread_rwlock_wrlock): This routine is
-	not a cancelation point - disable deferred
-	cancelation around call to pthread_cond_wait().
-
-2001-07-05  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* spin.c: New module implementing spin locks.
-	* barrier.c: New module implementing barriers.
-	* pthread.h (_POSIX_SPIN_LOCKS): defined.
-	(_POSIX_BARRIERS): Defined.
-	(pthread_spin_*): Defined.
-	(pthread_barrier*): Defined.
-	(PTHREAD_BARRIER_SERIAL_THREAD): Defined.
-	* implement.h (pthread_spinlock_t_): Defined.
-	(pthread_barrier_t_): Defined.
-	(pthread_barrierattr_t_): Defined.
-
-	* mutex.c (pthread_mutex_lock): Return with the error
-	if an auto-initialiser initialisation fails.
-
-	* nonportable.c (pthread_getprocessors_np): New; gets the
-	number of available processors for the current process.
-
-2001-07-03  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* pthread.h (_POSIX_READER_WRITER_LOCKS): Define it
-	if not already defined.
-
-2001-07-01  Alexander Terekhov <TEREKHOV at de.ibm.com>
-
-	* condvar.c: Fixed lost signal bug reported by Timur Aydin
-	(taydin at snet.net).
-	[RPJ (me) didn't translate the original algorithm
-	correctly.]
-	* semaphore.c: Added sem_post_multiple; this is a useful
-	routine, but it doesn't appear to be standard. For now it's
-	not an exported function.
-	
-2001-06-25  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* create.c (pthread_create): Add priority inheritance
-	attributes.
-	* mutex.c (pthread_mutex_lock): Remove some overhead for
-	PTHREAD_MUTEX_NORMAL mutex types. Specifically, avoid
-	calling pthread_self() and pthread_equal() to check/set
-	the mutex owner. Introduce a new pseudo owner for this
-	type. Test results suggest increases in speed of up to
-	90% for non-blocking locks.
-	This is the default type of mutex used internally by other
-	synchronising objects, ie. condition variables and
-	read-write locks. The test rwlock7.c shows about a
-	30-35% speed increase over snapshot 2001-06-06. The
-	price of this is that the application developer
-	must ensure correct behaviour, or explicitly set the
-	mutex to a safer type such as PTHREAD_MUTEX_ERRORCHECK.
-	For example, PTHREAD_MUTEX_NORMAL (or PTHREAD_MUTEX_DEFAULT)
-	type mutexes will not return an error if a thread which is not
-	the owner calls pthread_mutex_unlock. The call will succeed
-	in unlocking the mutex if it is currently locked, but a
-	subsequent unlock by the true owner will then fail with EPERM.
-	This is however consistent with some other implementations.
-	(pthread_mutex_unlock): Likewise.
-	(pthread_mutex_trylock): Likewise.
-	(pthread_mutex_destroy): Likewise.
-	* attr.c (pthread_attr_init): PTHREAD_EXPLICIT_SCHED is the
-	default inheritance attribute; THREAD_PRIORITY_NORMAL is
-	the default priority for new threads.
-	* sched.c (pthread_attr_setschedpolicy): Added routine.
-	(pthread_attr_getschedpolicy): Added routine.
-	(pthread_attr_setinheritsched): Added routine.
-	(pthread_attr_getinheritsched): Added routine.
-	* pthread.h (sched_rr_set_interval): Added as a macro;
-	returns -1 with errno set to ENOSYS.
-
-2001-06-23  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	*sched.c (pthread_attr_setschedparam): Add priority range
-	check.
-	(sched_setscheduler): New function; checks for a valid
-	pid and policy; checks for permission to set information
-	in the target process; expects pid to be a Win32 process ID,
-	not a process handle; the only scheduler policy allowed is
-	SCHED_OTHER.
-	(sched_getscheduler): Likewise, but checks for permission
-	to query.
-	* pthread.h (SCHED_*): Moved to sched.h as defined in the
-	POSIX standard.
-	* sched.h (SCHED_*): Moved from pthread.h.
-	(pid_t): Defined if necessary.
-	(sched_setscheduler): Defined.
-	(sched_getscheduler): Defined.
-	* pthread.def (sched_setscheduler): Exported.
-	(sched_getscheduler): Likewise.
-
-2001-06-23  Ralf Brese <Ralf.Brese at pdb4.siemens.de>
-
-	* create.c (pthread_create): Set thread priority from
-	thread attributes.
-
-2001-06-18  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* Made organisational-only changes to UWIN additions.
-	* dll.c (dllMain): Moved UWIN process attach code
-	to pthread_win32_process_attach_np(); moved
-	instance of pthread_count to global.c.
-	* global.c (pthread_count): Moved from dll.c.
-	* nonportable.c (pthread_win32_process_attach_np):
-	Moved _UWIN code to here from dll.c.
-	* implement.h (pthread_count): Define extern int.
-	* create.c (pthread_count): Remove extern int.
-	* private.c (pthread_count): Likewise.
-	* exit.c (pthread_count): Likewise.
-
-2001-06-18  David Korn <dgk at research.att.com>
-
-	* dll.c: Added changes necessary to work with UWIN.
-	* create.c: Likewise.
-	* pthread.h: Likewise.
-	* misc.c: Likewise.
-	* exit.c: Likewise.
-	* private.c: Likewise.
-	* implement.h: Likewise.
-	There is some room at the start of struct pthread_t_
-	to implement the signal semantics in UWIN's posix.dll
-	although this is not yet complete.
-	* Nmakefile: Compatible with UWIN's Nmake utility.
-	* Nmakefile.tests: Likewise - for running the tests.
-
-2001-06-08  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* semaphore.h (sem_t): Fixed for compile and test.
-	* implement.h (sem_t_): Likewise.
-	* semaphore.c: Likewise.
-	* private.c (ptw32_sem_timedwait): Updated to use new
-	opaque sem_t.
-
-2001-06-06  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* semaphore.h (sem_t): Is now an opaque pointer;
-	moved actual definition to implement.h.
-	* implement.h (sem_t_): Move here from semaphore.h;
-	was the definition of sem_t.
-	* semaphore.c: Wherever necessary, changed use of sem
-	from that of a pointer to a pointer-pointer; added
-	extra checks for a valid sem_t; NULL sem_t when
-	it is destroyed; added extra checks when creating
-	and destroying sem_t elements in the NEED_SEM
-	code branches; changed from using a pthread_mutex_t
-	((*sem)->mutex) to CRITICAL_SECTION ((*sem)->sem_lock_cs)
-	in NEED_SEM branches for access serialisation.
-
-2001-06-06  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* mutex.c (pthread_mutexattr_init): Remove 
-	ptw32_mutex_default_kind.
-	
-2001-06-05  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* nonportable.c (pthread_mutex_setdefaultkind_np):
-	Remove - should not have been included in the first place.
-	(pthread_mutex_getdefaultkind_np): Likewise.
-	* global.c (ptw32_mutex_default_kind): Likewise.
-	* mutex.c (pthread_mutex_init): Remove use of
-	ptw32_mutex_default_kind.
-	* pthread.h (pthread_mutex_setdefaultkind_np): Likewise.
-	(pthread_mutex_getdefaultkind_np): Likewise.
-	* pthread.def (pthread_mutexattr_setkind_np): Added.
-	(pthread_mutexattr_getkind_np): Likewise.
-
-	* README: Many changes that should have gone in before
-	the last snapshot.
-	* README.NONPORTABLE: New - referred to by ANNOUNCE
-	but never created; documents the non-portable routines
-	included in the library - moved from README with new
-	routines added.
-	* ANNOUNCE (pthread_mutexattr_setkind_np): Added to
-	compliance list.
-	(pthread_mutexattr_getkind_np): Likewise.
-
-2001-06-04  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* condvar.c: Add original description of the algorithm as
-	developed by Terekhov and Thomas, plus reference to
-	README.CV.
-
-2001-06-03  Alexander Terekhov <TEREKHOV at de.ibm.com>, Louis Thomas <lthomas at arbitrade.com>
-
-	* condvar.c (pthread_cond_init): Completely revamped.
-	(pthread_cond_destroy): Likewise.
-	(ptw32_cond_wait_cleanup): Likewise.
-	(ptw32_cond_timedwait): Likewise.
-	(ptw32_cond_unblock): New general signaling routine.
-	(pthread_cond_signal): Now calls ptw32_cond_unblock.
-	(pthread_cond_broadcast): Likewise.
-	* implement.h (pthread_cond_t_): Revamped.
-	* README.CV: New; explanation of the above changes.
-
-2001-05-30  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* pthread.h (rand_r): Fake using _seed argument to quell
-	compiler warning (compiler should optimise this away later).
-
-	* GNUmakefile (OPT): Leave symbolic information out of the library
-	and increase optimisation level - for smaller faster prebuilt
-	dlls.
-	
-2001-05-29  Milan Gardian <Milan.Gardian at LEIBINGER.com>
-
-	* Makefile: fix typo.
-	* pthreads.h: Fix problems with stdcall/cdecl conventions, in particular
-	remove the need for PT_STDCALL everywhere; remove warning supression.
-	* (errno): Fix the longstanding "inconsistent dll linkage" problem
-	with errno; now also works with /MD debugging libs - 
-	warnings emerged when compiling pthreads library with /MD (or /MDd)
-	compiler switch, instead of /MT (or /MTd) (i.e. when compiling pthreads
-	using Multithreaded DLL CRT instead of Multithreaded statically linked
-	CRT).
-	* create.c (pthread_create): Likewise; fix typo.
-	* private.c (ptw32_threadStart): Eliminate use of terminate() which doesn't
-	throw exceptions.
-	* Remove unnecessary #includes from a number of modules -
-	[I had to #include malloc.h in implement.h for gcc - rpj].
-
-2001-05-29  Thomas Pfaff <tpfaff at gmx.net>
-
-	* pthread.h (PTHREAD_MUTEX_DEFAULT): New; equivalent to
-	PTHREAD_MUTEX_DEFAULT_NP.
-	* (PTHREAD_MUTEX_NORMAL): Similarly.
-	* (PTHREAD_MUTEX_ERRORCHECK): Similarly.
-	* (PTHREAD_MUTEX_RECURSIVE): Similarly.
-	* (pthread_mutex_setdefaultkind_np): New; Linux compatibility stub
-	for pthread_mutexattr_settype.
-	* (pthread_mutexattr_getkind_np): New; Linux compatibility stub
-	for pthread_mutexattr_gettype.
-	* mutex.c (pthread_mutexattr_settype): New; allow
-	the following types of mutex:
-	  PTHREAD_MUTEX_DEFAULT_NP
-	  PTHREAD_MUTEX_NORMAL_NP
-	  PTHREAD_MUTEX_ERRORCHECK_NP
-	  PTHREAD_MUTEX_RECURSIVE_NP
-	* Note that PTHREAD_MUTEX_DEFAULT is equivalent to
-	PTHREAD_MUTEX_NORMAL - ie. mutexes should no longer
-	be recursive by default, and a thread will deadlock if it
-	tries to relock a mutex it already owns. This is inline with
-	other pthreads implementations.
-	* (pthread_mutex_lock): Process the lock request
-	according to the mutex type.
-	* (pthread_mutex_init): Eliminate use of Win32 mutexes as the
-	basis of POSIX mutexes - instead, a combination of one critical section
-	and one semaphore are used in conjunction with Win32 Interlocked* routines.
-	* (pthread_mutex_destroy): Likewise.
-	* (pthread_mutex_lock): Likewise.
-	* (pthread_mutex_trylock): Likewise.
-	* (pthread_mutex_unlock): Likewise.
-	* Use longjmp/setjmp to implement cancelation when building the library
-	using a C compiler which doesn't support exceptions, e.g. gcc -x c (note
-	that gcc -x c++ uses exceptions).
-	* Also fixed some of the same typos and eliminated PT_STDCALL as
-	Milan Gardian's patches above.
-
-2001-02-07  Alexander Terekhov <TEREKHOV at de.ibm.com>
-
-	* rwlock.c: Revamped.
-	* implement.h (pthread_rwlock_t_): Redefined.
-	This implementation does not have reader/writer starvation problem.
-	Rwlock attempts to behave more like a normal mutex with
-	races and scheduling policy determining who is more important;
-	It also supports recursive locking,
-	has less synchronization overhead (no broadcasts at all,
-	readers are not blocked on any condition variable) and seem to
-	be faster than the current implementation [W98 appears to be
-	approximately 15 percent faster at least - on top of speed increase
-	from Thomas Pfaff's changes to mutex.c - rpj].
-
-2000-12-29  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* Makefile: Back-out "for" loops which don't work.
-
-	* GNUmakefile: Remove the fake.a target; add the "realclean"
-	target; don't remove built libs under the "clean" target.
-
-	* config.h: Add a guard against multiple inclusion.
-
-	* semaphore.h: Add some defines from config.h to make
-	semaphore.h independent of config.h when building apps.
-
-	* pthread.h (_errno): Back-out previous fix until we know how to
-	fix it properly.
-
-	* implement.h (lockCount): Add missing element to pthread_mutex_t_.
-
-	* sync.c (pthread_join): Spelling fix in comment.
-
-	* private.c (ptw32_threadStart): Reset original termination
-	function (C++).
-	(ptw32_threadStart): Cleanup detached threads early in case
-	the library is statically linked.
-	(ptw32_callUserDestroyRoutines): Remove [SEH] __try block from
-	destructor call so that unhandled exceptions will be passed through
-	to the 	system; call terminate() from [C++] try block for the same
-	reason.
-
-	* tsd.c (pthread_getspecific): Add comment.
-
-	* mutex.c (pthread_mutex_init): Initialise new elements in
-	pthread_mutex_t.
-	(pthread_mutex_unlock): Invert "pthread_equal()" test.
-
-2000-12-28  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* semaphore.c (mode_t): Use ifndef HAVE_MODE_T to include definition.
-
-	* config.h.in (HAVE_MODE_T): Added.
-	(_UWIN): Start adding defines for the UWIN package.
-
-	* private.c (ptw32_threadStart): Unhandled exceptions are
-	now passed through to the system to deal with. This is consistent
-	with normal Windows behaviour. C++ applications may use
-	set_terminate() to override the default behaviour which is
-	to call ptw32_terminate(). Ptw32_terminate() cleans up some
-	POSIX thread stuff before calling the system default function
-	which calls abort(). The users termination function should conform
-	to standard C++ semantics which is to not return. It should
-	exit the thread (call pthread_exit()) or exit the application.
-	* private.c (ptw32_terminate): Added as the default set_terminate()
-	function. It calls the system default function after cleaning up
-	some POSIX thread stuff.
-
-	* implement.h (ptw32_try_enter_critical_section): Move
-	declaration.
-	* global.c (ptw32_try_enter_critical_section): Moved
-	from dll.c.
-	* dll.c: Move process and thread attach/detach code into
-	functions in nonportable.c.
-	* nonportable.c (pthread_win32_process_attach_np): Process
-	attach code from dll.c is now available to static linked
-	applications.
-	* nonportable.c (pthread_win32_process_detach_np): Likewise.
-	* nonportable.c (pthread_win32_thread_attach_np): Likewise.
-	* nonportable.c (pthread_win32_thread_detach_np): Likewise.
-
-	* pthread.h: Add new non-portable prototypes for static
-	linked applications.
-
-	* GNUmakefile (OPT): Increase optimisation flag and remove
-	debug info flag.
-
-	* pthread.def: Add new non-portable exports for static
-	linked applications.
-
-2000-12-11  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* FAQ: Update Answer 6 re getting a fully working
-	Mingw32 built library.
-
-2000-10-10  Steven Reddie <smr at essemer.com.au>
- 
-        * misc.c (pthread_self): Restore Win32 "last error"
-        cleared by TlsGetValue() call in
-        pthread_getspecific()
- 
-2000-09-20  Arthur Kantor <akantor at bexusa.com>
- 
-        * mutex.c (pthread_mutex_lock): Record the owner
-        of the mutex. This requires also keeping count of
-        recursive locks ourselves rather than leaving it
-        to Win32 since we need to know when to NULL the
-        thread owner when the mutex is unlocked.
-        (pthread_mutex_trylock): Likewise.
-        (pthread_mutex_unlock): Check that the calling
-        thread owns the mutex, decrement the recursive
-        lock count, and NULL the owner if zero. Return
-        EPERM if the mutex is owned by another thread.
-        * implement.h (pthread_mutex_t_): Add ownerThread
-        and lockCount members.
-
-2000-09-13  Jef Gearhart <jgearhart at tpssys.com>
-
-	* mutex.c (pthread_mutex_init): Call
-	TryEnterCriticalSection through the pointer
-	rather than directly so that the dll can load
-	on Windows versions that can't resolve the
-	function, eg. Windows 95
-
-2000-09-09  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* pthread.h (ctime_r): Fix arg.
-
-2000-09-08  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* GNUmakefile(_WIN32_WINNT=0x400): Define in CFLAGS;
-	doesn't seem to be needed though.
-
-	* cancel.c (pthread_cancel): Must get "self" through
-	calling pthread_self() which will ensure a POSIX thread
-	struct is built for non-POSIX threads; return an error
-	if this fails
-	- Ollie Leahy <ollie at mpt.ie>
-	(pthread_setcancelstate): Likewise.
-	(pthread_setcanceltype): Likewise.
-	* misc.c (ptw32_cancelable_wait): Likewise.
-
-	* private.c (ptw32_tkAssocCreate): Remove unused #if 0
-	wrapped code.
-
-	* pthread.h (ptw32_get_exception_services_code):
-	Needed to be forward declared unconditionally.
-
-2000-09-06  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* cancel.c (pthread_cancel): If called from the main
-	thread "self" would be NULL; get "self" via pthread_self()
-	instead of directly from TLS so that an implicit
-	pthread object is created.
-
-	* misc.c (pthread_equal): Strengthen test for NULLs.
-
-2000-09-02  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* condvar.c (ptw32_cond_wait_cleanup): Ensure that all
-	waking threads check if they are the last, and notify
-	the broadcaster if so - even if an error occurs in the
-	waiter.
-
-	* semaphore.c (_decrease_semaphore): Should be
-	a call to ptw32_decrease_semaphore.
-	(_increase_semaphore): Should be a call to
-	ptw32_increase_semaphore.
-
-	* misc.c (ptw32_cancelable_wait): Renamed from
-	CancelableWait.
-	* rwlock.c (_rwlock_check*): Renamed to
-	ptw32_rwlock_check*.
-	* mutex.c (_mutex_check*): Renamed to ptw32_mutex_check*.
-	* condvar.c (cond_timed*): Renamed to ptw32_cond_timed*.
-	(_cond_check*): Renamed to ptw32_cond_check*.
-	(cond_wait_cleanup*): Rename to ptw32_cond_wait_cleanup*.
-	(ptw32_cond_timedwait): Add comments.
-
-2000-08-22  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* private.c (ptw32_throw): Fix exception test;
-	move exceptionInformation declaration.
-
-	* tsd.c (pthread_key_create): newkey wrongly declared.
-
-	* pthread.h: Fix comment block.
-
-2000-08-18  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* mutex.c (pthread_mutex_destroy): Check that the mutex isn't
-	held; invalidate the mutex as early as possible to avoid
-	contention; not perfect - FIXME!
-
-	* rwlock.c (pthread_rwlock_init): Remove redundant assignment
-	to "rw".
-	(pthread_rwlock_destroy): Invalidate the rwlock before
-	freeing up any of it's resources - to avoid contention.
-
-	* private.c (ptw32_tkAssocCreate): Change assoc->lock
-	to use a dynamically initialised mutex - only consumes
-	a W32 mutex or critical section when first used,
-	not before.
-
-	* mutex.c (pthread_mutex_init): Remove redundant assignment
-	to "mx".
-	(pthread_mutexattr_destroy): Set attribute to NULL
-	before freeing it's memory - to avoid contention.
-
-	* implement.h (PTW32_EPS_CANCEL/PTW32_EPS_EXIT):
-	Must be defined for all compilers - used as generic
-	exception selectors by ptw32_throw().
-
-	* Several: Fix typos from scripted edit session
-	yesterday.
-
-	* nonportable.c (pthread_mutexattr_setforcecs_np):
-	Moved this function from mutex.c.
-	(pthread_getw32threadhandle_np): New function to
-	return the win32 thread handle that the POSIX
-	thread is using.
-	* mutex.c (pthread_mutexattr_setforcecs_np):
-	Moved to new file "nonportable.c".
-
-	* pthread.h (PTW32_BUILD): Only	redefine __except
-	and catch compiler keywords if we aren't building
-	the library (ie. PTW32_BUILD is not defined) - 
-	this is safer than defining and then undefining
-	if not building the library.
-	* implement.h: Remove __except and catch undefines.
-	* Makefile (CFLAGS): Define PTW32_BUILD.
-	* GNUmakefile (CFLAGS): Define PTW32_BUILD.
-
-	* All appropriate: Change Pthread_exception* to
-	ptw32_exception* to be consistent with internal
-	identifier naming.
-
-	* private.c (ptw32_throw): New function to provide
-	a generic exception throw for all internal
-	exceptions and EH schemes.
-	(ptw32_threadStart): pthread_exit() value is now
-	returned via the thread structure exitStatus
-	element.
-	* exit.c (pthread_exit): pthread_exit() value is now
-	returned via the thread structure exitStatus
-	element.
-	* cancel.c (ptw32_cancel_self): Now uses ptw32_throw.
-	(pthread_setcancelstate): Ditto.
-	(pthread_setcanceltype): Ditto.
-	(pthread_testcancel): Ditto.
-	(pthread_cancel): Ditto.
-	* misc.c (CancelableWait): Ditto.
-	* exit.c (pthread_exit): Ditto.
-	* All applicable: Change PTW32_ prefix to
-	PTW32_ prefix to remove leading underscores
-	from private library identifiers.
-
-2000-08-17  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* All applicable: Change _pthread_ prefix to
-	ptw32_ prefix to remove leading underscores
-	from private library identifiers (single
-	and double leading underscores are reserved in the
-	ANSI C standard for compiler implementations).
-
-	* tsd.c (pthread_create_key): Initialise temporary
-	key before returning it's address to avoid race
-	conditions.
-
-2000-08-13  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* errno.c: Add _MD precompile condition; thus far
-	had no effect when using /MD compile option but I
-	thnk it should be there.
-
-	* exit.c: Add __cplusplus to various #if lines;
-	was compiling SEH code even when VC++ had
-	C++ compile options.
-
-	* private.c: ditto.
-
-	* create.c (pthread_create): Add PT_STDCALL macro to
-	function pointer arg in _beginthread().
-
-	* pthread.h: PT_STDCALL really does need to be defined
-	in both this and impliment.h; don't set it to __cdecl
-	- this macro is only used to extend function pointer
-	casting for functions that will be passed as parameters.
-	(~PThreadCleanup): add cast and group expression.
-	(_errno): Add _MD compile conditional.
-	(PtW32NoCatchWarn): Change pragma message.
-
-	* implement.h: Move and change PT_STDCALL define.
-
-	* need_errno.h: Add _MD to compilation conditional.
-
-	* GNUmakefile: Substantial rewrite for new naming
-	convention; set for nil optimisation (turn it up
-	when we have a working library build; add target
-	"fake.a" to build a libpthreadw32.a from the VC++
-	built DLL pthreadVCE.dll.
-
-	* pthread.def (LIBRARY): Don't specify in the .def
-	file - it is specified on the linker command line
-	since we now use the same .def file for variously
-	named .dlls.
-
-	* Makefile: Substantial rewrite for new naming
-	convention; default nmake target only issues a
-	help message; run nmake with specific target
-	corresponding to the EH scheme being used.
-
-	* README: Update information; add naming convention
-	explanation.
-
-	* ANNOUNCE: Update information.
-
-2000-08-12  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* pthread.h: Add compile-time message when using
-	MSC_VER compiler and C++ EH to warn application
-	programmers to use PtW32Catch instead of catch(...)
-	if they want cancelation and pthread_exit to work.
-
-	* implement.h: Remove #include <semaphore.h>; we
-	use our own local semaphore.h.
-
-2000-08-10  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* cleanup.c (pthread_pop_cleanup): Remove _pthread
-	prefix from __except and catch keywords; implement.h
-	now simply undefines ptw32__except and
-	ptw32_catch if defined; VC++ was not textually
-	substituting ptw32_catch etc back to catch as
-	it was redefined; the reason for using the prefixed
-	version was to make it clear that it was not using
-	the pthread.h redefined catch keyword.
-
-	* private.c (ptw32_threadStart): Ditto.
-	(ptw32_callUserDestroyRoutines): Ditto.
-
-	* implement.h (ptw32__except): Remove #define.
-	(ptw32_catch): Remove #define.
-
-	* GNUmakefile (pthread.a): New target to build
-	libpthread32.a from pthread.dll using dlltool.
-
-	* buildlib.bat: Duplicate cl commands with args to
-	build C++ EH version of pthread.dll; use of .bat
-	files is redundant now that nmake compatible
-	Makefile is included; used as a kludge only now.
-
-	* Makefile: Localise some macros and fix up the clean:
-	target to extend it and work properly.
-
-	* CONTRIBUTORS: Add contributors.
-
-	* ANNOUNCE: Updated.
-
-	* README: Updated.
-
-2000-08-06  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* pthread.h: Remove #warning - VC++ doesn't accept it.
-
-2000-08-05  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* pthread.h (PtW32CatchAll): Add macro. When compiling
-	applications using VC++ with C++ EH rather than SEH
-	'PtW32CatchAll' must be used in place of any 'catch( ... )'
-	if the application wants pthread cancelation or
-	pthread_exit() to work.
-
-2000-08-03  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* pthread.h: Add a base class ptw32_exception for
-	library internal exceptions and change the "catch"
-	re-define macro to use it.
-
-2000-08-02  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* GNUmakefile (CFLAGS): Add -mthreads.
-	Add new targets to generate cpp and asm output.
-
-	* sync.c (pthread_join): Remove dead code.
-
-2000-07-25  Tristan Savatier <tristan at mpegtv.com>
-
-	* sched.c (sched_get_priority_max): Handle different WinCE and
-	Win32 priority values together.
-	(sched_get_priority_min): Ditto.
-
-2000-07-25  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* create.c (pthread_create): Force new threads to wait until
-	pthread_create has the new thread's handle; we also retain
-	a local copy of the handle for internal use until
-	pthread_create returns.
-
-	* private.c (ptw32_threadStart): Initialise ei[].
-	(ptw32_threadStart): When beginthread is used to start the
-	thread, force waiting until the creator thread had the 
-	thread handle.
-
-	* cancel.c (ptw32_cancel_thread): Include context switch
-	code for defined(_X86_) environments in addition to _M_IX86.
-
-	* rwlock.c (pthread_rwlock_destroy): Assignment changed
-	to avoid compiler warning.
-
-	* private.c (ptw32_get_exception_services_code): Cast
-	NULL return value to avoid compiler warning.
-
-	* cleanup.c (pthread_pop_cleanup): Initialise "cleanup" variable
-	to avoid compiler warnings.
-
-	* misc.c (ptw32_new): Change "new" variable to "t" to avoid
-	confusion with the C++ keyword of the same name.
-
-	* condvar.c (cond_wait_cleanup): Initialise lastWaiter variable.
-	(cond_timedwait): Remove unused local variables. to avoid
-	compiler warnings.
-
-	* dll.c (dllMain): Remove 2000-07-21 change - problem
-	appears to be in pthread_create().
-
-2000-07-22  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* tsd.c (pthread_key_create): If a destructor was given
-	and the pthread_mutex_init failed, then would try to
-	reference a NULL pointer (*key); eliminate this section of
-	code by using a dynamically initialised mutex
-	(PTHREAD_MUTEX_INITIALIZER).
-
-	* tsd.c (pthread_setspecific): Return an error if
-	unable to set the value; simplify cryptic conditional.
-
-	* tsd.c (pthread_key_delete): Locking threadsLock relied
-	on mutex_lock returning an error if the key has no destructor.
-	ThreadsLock is only initialised if the key has a destructor.
-	Making this mutex a static could reduce the number of mutexes
-	used by an application since it is actually created only at
-	first use and it's often destroyed soon after.
-	
-2000-07-22  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* FAQ: Added Q5 and Q6.
-
-2000-07-21  David Baggett <dmb at itasoftware.com>
-
-	* dll.c: Include resource leakage work-around. This is a
-	partial FIXME which doesn't stop all leakage. The real
-	problem needs to be found and fixed.
-
-2000-07-21  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* create.c (pthread_create): Set threadH to 0 (zero)
-	everywhere. Some assignments were using NULL. Maybe
-	it should be NULL everywhere - need to check. (I know
-	they are nearly always the same thing - but not by
-	definition.)
-
-	* misc.c (pthread_self): Try to catch NULL thread handles
-	at the point where they might be generated, even though
-	they should always be valid at this point.
-
-	* tsd.c (pthread_setspecific): return an error value if
-	pthread_self() returns NULL.
-
-	* sync.c (pthread_join): return an error value if
-	pthread_self() returns NULL.
-
-	* signal.c (pthread_sigmask): return an error value if
-	pthread_self() returns NULL.
-
-2000-03-02  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* attr.c (pthread_attr_init): Set default stacksize to zero (0)
-	rather than PTHREAD_STACK_MIN even though these are now the same.
-
-	* pthread.h (PTHREAD_STACK_MIN): Lowered to 0.
-
-2000-01-28  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* mutex.c (pthread_mutex_init): Free mutex if it has been alloced;
-	if critical sections can be used instead of Win32 mutexes, test
-	that the critical section works and return an error if not.
-
-2000-01-07  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* cleanup.c (pthread_pop_cleanup): Include SEH code only if MSC is not
-	compiling as C++.
-	(pthread_push_cleanup): Include SEH code only if MSC is not
-	compiling as C++.
-
-	* pthread.h: Include SEH code only if MSC is not
-	compiling as C++.
-
-	* implement.h: Include SEH code only if MSC is not
-	compiling as C++.
-
-	* cancel.c (ptw32_cancel_thread): Add _M_IX86 check.
-	(pthread_testcancel): Include SEH code only if MSC is not
-	compiling as C++.
-	(ptw32_cancel_self): Include SEH code only if MSC is not
-	compiling as C++.
-
-2000-01-06  Erik Hensema <erik.hensema at group2000.nl>
-
-	* Makefile: Remove inconsistencies in 'cl' args
-
-2000-01-04  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* private.c (ptw32_get_exception_services_code): New; returns
-	value of EXCEPTION_PTW32_SERVICES.
-	(ptw32_processInitialize): Remove initialisation of
-	ptw32_exception_services which is no longer needed.
-
-	* pthread.h (ptw32_exception_services): Remove extern.
-	(ptw32_get_exception_services_code): Add function prototype;
-	use this to return EXCEPTION_PTW32_SERVICES value instead of
-	using the ptw32_exception_services variable which I had
-	trouble exporting through pthread.def.
-
-	* global.c (ptw32_exception_services): Remove declaration.
-
-1999-11-22  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* implement.h: Forward declare ptw32_new();
-
-	* misc.c (ptw32_new): New; alloc and initialise a new pthread_t.
-	(pthread_self): New thread struct is generated 	by new routine
-	ptw32_new().
-
-	* create.c (pthread_create): New thread struct is generated
-	by new routine ptw32_new().
-
-1999-11-21  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* global.c (ptw32_exception_services): Declare new variable. 
-
-	* private.c (ptw32_threadStart): Destroy thread's
-	cancelLock mutex; make 'catch' and '__except' usageimmune to
-	redfinitions in pthread.h.
-	(ptw32_processInitialize): Init new constant ptw32_exception_services.
-
-	* create.c (pthread_create): Initialise thread's cancelLock
-	mutex.
-
-	* cleanup.c (pthread_pop_cleanup): Make 'catch' and '__except'
-	usage immune to redfinition s in pthread.h.
-
-	* private.c: Ditto.
-
-	* pthread.h (catch): Redefine 'catch' so that C++ applications
-	won't catch our internal exceptions.
-	(__except): ditto for __except.
-
-	* implement.h (ptw32_catch): Define internal version
-	of 'catch' because 'catch' is redefined by pthread.h.
-	(__except): ditto for __except.
-	(struct pthread_t_): Add cancelLock mutex for async cancel
-	safety.
-
-1999-11-21  Jason Nye <jnye at nbnet.nb.ca>, Erik Hensema <erik.hensema at group2000.nl>
-
-	* cancel.c (ptw32_cancel_self): New; part of the async
-	cancellation implementation.
-	(ptw32_cancel_thread): Ditto; this function is X86
-	processor specific.
-	(pthread_setcancelstate): Add check for pending async
-	cancel request and cancel the calling thread if
-	required; add async-cancel safety lock.
-	(pthread_setcanceltype): Ditto.
-
-1999-11-13  Erik Hensema <erik.hensema at group2000.nl>
-
-	* configure.in (AC_OUTPUT): Put generated output into GNUmakefile
-	rather than Makefile. Makefile will become the MSC nmake compatible
-	version
-
-1999-11-13  John Bossom (John.Bossom at cognos.com>
-
-	* misc.c (pthread_self): Add a note about GetCurrentThread
-	returning a pseudo-handle
-
-1999-11-10  Todd Owen <towen at lucidcalm.dropbear.id.au>
-
-	* dll.c (dllMain): Free kernel32 ASAP.
-	If TryEnterCriticalSection is not being used, then free
-	the kernel32.dll handle now, rather than leaving it until
-	DLL_PROCESS_DETACH.
-
-	Note: this is not a pedantic exercise in freeing unused
-	resources!  It is a work-around for a bug in Windows 95
-	(see microsoft knowledge base article, Q187684) which
-	does Bad Things when FreeLibrary is called within
-	the DLL_PROCESS_DETACH code, in certain situations.
-	Since w95 just happens to be a platform which does not
-	provide TryEnterCriticalSection, the bug will be
-	effortlessly avoided.
-
-1999-11-10  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* sync.c (pthread_join): Make it a deferred cancelation point.
-
-	* misc.c (pthread_self): Explicitly initialise implicitly
-	created thread state to default values.
-
-1999-11-05  Tristan Savatier <tristan at mpegtv.com>
-
-	* pthread.h (winsock.h): Include unconditionally.
-	(ETIMEDOUT): Change fallback value to that defined by winsock.h.
-	
-	* general: Patched for portability to WinCE. The details are
-	described in the file WinCE-PORT. Follow the instructions
-	in README.WinCE to make the appropriate changes in config.h.
-
-1999-10-30  Erik Hensema <erik.hensema at group2000.nl>
-
-	* create.c (pthread_create): Explicitly initialise thread state to
-	default values.
-
-	* cancel.c (pthread_setcancelstate): Check for NULL 'oldstate'
-	for compatibility with Solaris pthreads;
-	(pthread_setcanceltype): ditto:
-
-1999-10-23  Erik Hensema <erik.hensema at group2000.nl>
-
-	* pthread.h (ctime_r): Fix incorrect argument "_tm"
-
-1999-10-21  Aurelio Medina <aureliom at crt.com>
-
-	* pthread.h (_POSIX_THREADS): Only define it if it isn't
-	already defined. Projects may need to define this on
-	the CC command line under Win32 as it doesn't have unistd.h
-
-1999-10-17  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* rwlock.c (pthread_rwlock_destroy): Add cast to remove compile
-	warning.
-
-	* condvar.c (pthread_cond_broadcast): Only release semaphores
-	if there are waiting threads.
-
-1999-10-15  Lorin Hochstein <lmh at xiphos.ca>, Peter Slacik <Peter.Slacik at tatramed.sk>
-
-	* condvar.c (cond_wait_cleanup): New static cleanup handler for
-	cond_timedwait;
-	(cond_timedwait): pthread_cleanup_push args changed;
-	canceling a thread while it's in pthread_cond_wait
-	will now decrement the waiters count and cleanup if it's the
-	last waiter.
-
-1999-10-15  Graham Dumpleton <Graham.Dumpleton at ra.pad.otc.telstra.com.au>
-
-	* condvar.c (cond_wait_cleanup): the last waiter will now reset the CV's
-	wasBroadcast flag
-
-Thu Sep 16 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* rwlock.c (pthread_rwlock_destroy): Add serialisation.
-	(_rwlock_check_need_init): Check for detroyed rwlock.
-	* rwlock.c: Check return codes from _rwlock_check_need_init();
-	modify comments; serialise access to rwlock objects during
-	operations; rename rw_mutex to rw_lock.
-	* implement.h: Rename rw_mutex to rw_lock.
-	* mutex.c (pthread_mutex_destroy): Add serialisation.
-	(_mutex_check_need_init): Check for detroyed mutex.
-	* condvar.c (pthread_cond_destroy): Add serialisation.
-	(_cond_check_need_init): Check for detroyed condvar.
-	* mutex.c: Modify comments.
-	* condvar.c: Modify comments.
-
-1999-08-10  Aurelio Medina  <aureliom at crt.com>
-
-	* implement.h (pthread_rwlock_t_): Add.
-	* pthread.h (pthread_rwlock_t): Add.
-	(PTHREAD_RWLOCK_INITIALIZER): Add.
-	Add rwlock function prototypes.
-	* rwlock.c: New module.
-	* pthread.def: Add new rwlock functions.
-	* private.c (ptw32_processInitialize): initialise
-	ptw32_rwlock_test_init_lock critical section.
-	* global.c (ptw32_rwlock_test_init_lock): Add.
-
-	* mutex.c (pthread_mutex_destroy): Don't free mutex memory
-	if mutex is PTHREAD_MUTEX_INITIALIZER and has not been
-	initialised yet.
-
-1999-08-08 Milan Gardian <mg at tatramed.sk>
-
-	* mutex.c (pthread_mutex_destroy): Free mutex memory.
-
-1999-08-22  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* exit.c (pthread_exit): Fix reference to potentially
-	uninitialised pointer.
-
-1999-08-21  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_threadStart): Apply fix of 1999-08-19
-	this time to C++ and non-trapped C versions. Ommitted to
-	do this the first time through.
-
-1999-08-19  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_threadStart): Return exit status from
-	the application thread startup routine.
-	- Milan Gardian <mg at tatramed.sk>
-
-1999-08-18  John Bossom <john.Bossom at cognos.com>
-
-	* exit.c (pthread_exit): Put status into pthread_t->exitStatus
-	* private.c (ptw32_threadStart): Set pthread->exitStatus
-	on exit of try{} block.
-	* sync.c (pthread_join): use pthread_exitStatus value if the
-	thread exit doesn't return a value (for Mingw32 CRTDLL
-	which uses endthread instead of _endthreadex).
-
-Tue Aug 17 20:17:58 CDT 1999  Mumit Khan  <khan at xraylith.wisc.edu>
-
-        * create.c (pthread_create): Add CRTDLL suppport.
-        * exit.c (pthread_exit): Likewise.
-        * private.c (ptw32_threadStart): Likewise.
-        (ptw32_threadDestroy): Likewise.
-        * sync.c (pthread_join): Likewise.
-        * tests/join1.c (main): Warn about partial support for CRTDLL.
-
-Tue Aug 17 20:00:08 1999  Mumit Khan  <khan at xraylith.wisc.edu>
-
-        * Makefile.in (LD): Delete entry point.
-        * acconfig.h (STDCALL): Delete unused macro.
-        * configure.in: Remove test for STDCALL.
-        * config.h.in: Regenerate.
-        * errno.c (_errno): Fix self type.
-        * pthread.h (PT_STDCALL): Move from here to
-        * implement.h (PT_STDCALL): here.
-        (ptw32_threadStart): Fix prototype.
-        * private.c (ptw32_threadStart): Likewise.
-
-1999-08-14  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* exit.c (pthread_exit): Don't call pthread_self() but
-	get thread handle directly from TSD for efficiency.
-	
-1999-08-12  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_threadStart): ei[] only declared if _MSC_VER.
-
-	* exit.c (pthread_exit): Check for implicitly created threads
-	to avoid raising an unhandled exception.
-	
-1999-07-12  Peter Slacik <Peter.Slacik at tatramed.sk>
-
-	* condvar.c (pthread_cond_destroy): Add critical section.
-	(cond_timedwait): Add critical section; check for timeout
-	waiting on semaphore.
-	(pthread_cond_broadcast): Add critical section.
-
-1999-07-09  Lorin Hochstein <lmh at xiphos.ca>, John Bossom <John.Bossom at Cognos.COM>
-
-	The problem was that cleanup handlers were not executed when
-	pthread_exit() was called.
-
-	* implement.h (pthread_t_): Add exceptionInformation element for
-	C++ per-thread exception information.
-	(general): Define and rename exceptions.
-
-1999-07-09  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* misc.c (CancelableWait):  PTW32_EPS_CANCEL (SEH) and
-	ptw32_exception_cancel (C++) used to identify the exception.
-
-	* cancel.c (pthread_testcancel): PTW32_EPS_CANCEL (SEH) and
-	ptw32_exception_cancel (C++) used to identify the exception.
-
-	* exit.c (pthread_exit): throw/raise an exception to return to
-	ptw32_threadStart() to exit the thread. PTW32_EPS_EXIT (SEH)
-	and ptw32_exception_exit (C++) used to identify the exception.
-
-	* private.c (ptw32_threadStart): Add pthread_exit exception trap;
-	clean up and exit the thread directly rather than via pthread_exit().
-
-Sun May 30 00:25:02 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* semaphore.h (mode_t): Conditionally typedef it.
-
-Fri May 28 13:33:05 1999  Mark E. Armstrong <avail at pacbell.net>
-
-	* condvar.c (pthread_cond_broadcast): Fix possible memory fault
-	
-Thu May 27 13:08:46 1999  Peter Slacik <Peter.Slacik at tatramed.sk>
-
-	* condvar.c (pthread_cond_broadcast): Fix logic bug
-
-Thu May 27 13:08:46 1999  Bossom, John <John.Bossom at Cognos.COM>
-
-	* condvar.c (pthread_cond_broadcast): optimise sem_post loop
-
-Fri May 14 12:13:18 1999  Mike Russo <miker at eai.com>
-
-	* attr.c (pthread_attr_setdetachstate): Fix logic bug
-
-Sat May  8 09:42:30 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* pthread.def (sem_open): Add.
-	(sem_close): Add.
-	(sem_unlink): Add.
-	(sem_getvalue): Add.
-
-	* FAQ (Question 3): Add.
-
-Thu Apr  8 01:16:23 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* semaphore.c (sem_open): New function; returns an error (ENOSYS).
-	(sem_close): ditto.
-	(sem_unlink): ditto.
-	(sem_getvalue): ditto.
-
-	* semaphore.h (_POSIX_SEMAPHORES): define.
-	
-Wed Apr  7 14:09:52 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* errno.c (_REENTRANT || _MT): Invert condition.
-
-	* pthread.h (_errno): Conditionally include prototype.
-
-Wed Apr  7 09:37:00 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* *.c (comments): Remove individual attributions - these are
-	documented sufficiently elsewhere.
-
-	* implement.h (pthread.h): Remove extraneous include.
-
-Sun Apr  4 11:05:57 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* sched.c (sched.h): Include.
-
-	* sched.h: New file for POSIX 1b scheduling.
-
-	* pthread.h: Move opaque structures to implement.h; move sched_*
-	prototypes out and into sched.h.
-
-	* implement.h: Add opaque structures from pthread.h.
-
-	* sched.c (sched_yield): New function.
-
-	* condvar.c (ptw32_sem_*): Rename to sem_*; except for
-	ptw32_sem_timedwait which is an private function.
-
-Sat Apr  3 23:28:00 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* Makefile.in (OBJS): Add errno.o.
-
-Fri Apr  2 11:08:50 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h (ptw32_sem_*): Remove prototypes now defined in
-	semaphore.h.
-
-	* pthread.h (sempahore.h): Include.
-
-	* semaphore.h: New file for POSIX 1b semaphores.
-
-	* semaphore.c (ptw32_sem_timedwait): Moved to private.c.
-
-	* pthread.h (ptw32_sem_t): Change to sem_t. 
-
-	* private.c (ptw32_sem_timedwait): Moved from semaphore.c;
-	set errno on error.
-
-	* pthread.h (pthread_t_): Add per-thread errno element.
-
-Fri Apr  2 11:08:50 1999  John Bossom <jebossom at cognos.com>
-
-	* semaphore.c (ptw32_sem_*): Change to sem_*; these functions
-	will be exported from the library; set errno on error.
-
-	* errno.c (_errno): New file. New function.
-
-Fri Mar 26 14:11:45 1999  Tor Lillqvist <tml at iki.fi>
-
-	* semaphore.c (ptw32_sem_timedwait): Check for negative
-	milliseconds.
-
-Wed Mar 24 11:32:07 1999  John Bossom <jebossom at cognos.com>
-
-	* misc.c (CancelableWait): Initialise exceptionInformation[2].
-	(pthread_self): Get a real Win32 thread handle for implicit threads.
-
-	* cancel.c (pthread_testcancel): Initialise exceptionInformation[2].
-
-	* implement.h (SE_INFORMATION): Fix values.
-
-	* private.c (ptw32_threadDestroy): Close the thread handle.
-
-Fri Mar 19 12:57:27 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* cancel.c (comments): Update and cleanup.
-
-Fri Mar 19 09:12:59 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_threadStart): status returns PTHREAD_CANCELED.
-
-	* pthread.h (PTHREAD_CANCELED): defined.
-
-Tue Mar 16  1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* all: Add GNU LGPL and Copyright and Warranty.
-	
-Mon Mar 15 00:20:13 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* condvar.c (pthread_cond_init): fix possible uninitialised use
-	of cv.
-
-Sun Mar 14 21:01:59 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* condvar.c (pthread_cond_destroy): don't do full cleanup if
-	static initialised cv has never been used.
-	(cond_timedwait): check result of auto-initialisation.
-
-Thu Mar 11 09:01:48 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* pthread.h (pthread_mutex_t): revert to (pthread_mutex_t *);
-	define a value to serve as PTHREAD_MUTEX_INITIALIZER.
-	(pthread_mutex_t_): remove staticinit and valid elements.
-	(pthread_cond_t): revert to (pthread_cond_t_ *);
-	define a value to serve as PTHREAD_COND_INITIALIZER.
-	(pthread_cond_t_): remove staticinit and valid elements.
-
-	* mutex.c (pthread_mutex_t args): adjust indirection of references.
-	(all functions): check for PTHREAD_MUTEX_INITIALIZER value;
-	check for NULL (invalid).
-
-	* condvar.c (pthread_cond_t args): adjust indirection of references.
-	(all functions): check for PTHREAD_COND_INITIALIZER value;
-	check for NULL (invalid).
-
-Wed Mar 10 17:18:12 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* misc.c (CancelableWait): Undo changes from Mar 8 and 7.
-
-Mon Mar  8 11:18:59 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* misc.c (CancelableWait): Ensure cancelEvent handle is the lowest
-	indexed element in the handles array. Enhance test for abandoned
-	objects.
-
-	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Trailing elements not
-	initialised are set to zero by the compiler. This avoids the
-	problem of initialising the opaque critical section element in it.
-	(PTHREAD_COND_INITIALIZER): Ditto.
-
-	* semaphore.c (ptw32_sem_timedwait): Check sem == NULL earlier.
-
-Sun Mar  7 12:31:14 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* condvar.c (pthread_cond_init): set semaphore initial value
-	to 0, not 1. cond_timedwait was returning signaled immediately.
-
-	* misc.c (CancelableWait): Place the cancel event handle first
-	in the handle table for WaitForMultipleObjects. This ensures that
-	the cancel event is recognised and acted apon if both objects
-	happen to be signaled together.
-
-	* private.c (ptw32_cond_test_init_lock): Initialise and destroy.
-
-	* implement.h (ptw32_cond_test_init_lock): Add extern.
-
-	* global.c (ptw32_cond_test_init_lock): Add declaration. 
-
-	* condvar.c (pthread_cond_destroy): check for valid initialised CV;
-	flag destroyed CVs as invalid.
-	(pthread_cond_init): pthread_cond_t is no longer just a pointer.
-	This is because PTHREAD_COND_INITIALIZER needs state info to reside
-	in pthread_cond_t so that it can initialise on first use. Will work on
-	making pthread_cond_t (and other objects like it) opaque again, if
-	possible, later.
-	(cond_timedwait): add check for statically initialisation of
-	CV; initialise on first use.
-	(pthread_cond_signal): check for valid CV.
-	(pthread_cond_broadcast): check for valid CV.
-	(_cond_check_need_init): Add.
-
-	* pthread.h (PTHREAD_COND_INITIALIZER): Fix.
-	(pthread_cond_t): no longer a pointer to pthread_cond_t_.
-	(pthread_cond_t_): add 'staticinit' and 'valid' elements.
-
-Sat Mar 6 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h: Undate comments.
-
-Sun Feb 21 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* pthread.h (PTHREAD_MUTEX_INITIALIZER): missing braces around
-	cs element initialiser.
-
-1999-02-21  Ben Elliston  <bje at cygnus.com>
-
-	* pthread.h (pthread_exit): The return type of this function is
-	void, not int.
-
-	* exit.c (pthread_exit): Do not return 0.
-
-Sat Feb 20 16:03:30 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* dll.c (DLLMain): Expand TryEnterCriticalSection support test.
-
-	* mutex.c (pthread_mutex_trylock): The check for
-	ptw32_try_enter_critical_section == NULL should have been
-	removed long ago.
-
-Fri Feb 19 16:03:30 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* sync.c (pthread_join): Fix pthread_equal() test.
-
-	* mutex.c (pthread_mutex_trylock): Check mutex != NULL before
-	using it.
-
-Thu Feb 18 16:17:30 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* misc.c (pthread_equal): Fix inverted result.
-
-	* Makefile.in: Use libpthread32.a as the name of the DLL export
-	library instead of pthread.lib.
-
-	* condvar.c (pthread_cond_init): cv could have been used unitialised;
-	initialise.
-
-	* create.c (pthread_create): parms could have been used unitialised;
-	initialise.
-
-	* pthread.h (struct pthread_once_t_): Remove redefinition.
-
-Sat Feb 13 03:03:30 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* pthread.h (struct pthread_once_t_): Replaced.
-
-	* misc.c (pthread_once): Replace with John Bossom's version;
-	has lighter weight serialisation; fixes problem of not holding
-	competing threads until after the init_routine completes.
-
-Thu Feb 11 13:34:14 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* misc.c (CancelableWait): Change C++ exception throw.
-
-	* sync.c (pthread_join): Change FIXME comment - issue resolved.
-
-Wed Feb 10 12:49:11 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* configure: Various temporary changes.
-	- Kevin Ruland <Kevin.Ruland at anheuser-busch.com>
-
-	* README: Update.
-
-	* pthread.def (pthread_attr_getstackaddr): uncomment
-	(pthread_attr_setstackaddr): uncomment
-
-Fri Feb  5 13:42:30 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* semaphore.c: Comment format changes.
-
-Thu Feb  4 10:07:28 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* global.c: Remove ptw32_exception instantiation.
-
-	* cancel.c (pthread_testcancel): Change C++ exception throw.
-
-	* implement.h: Remove extern declaration.
-
-Wed Feb  3 13:04:44 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* cleanup.c: Rename ptw32_*_cleanup() to pthread_*_cleanup().
-
-	* pthread.def: Ditto.
-	
-	* pthread.h: Ditto.
-
-	* pthread.def (pthread_cleanup_push): Remove from export list;
-	the function is defined as a macro under all compilers.
-	(pthread_cleanup_pop): Ditto.
-
-	* pthread.h: Remove #if defined().
-
-Wed Feb  3 10:13:48 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* sync.c (pthread_join): Check for NULL value_ptr arg;
-	check for detached threads.
-
-Tue Feb  2 18:07:43 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* implement.h: Add #include <pthread.h>.
-	Change sem_t to ptw32_sem_t.
-
-Tue Feb  2 18:07:43 1999  Kevin Ruland <Kevin.Ruland at anheuser-busch.com>
-
-	* signal.c (pthread_sigmask): Add and modify casts.
-	Reverse LHS/RHS bitwise assignments.
-
-	* pthread.h: Remove #include <semaphore.h>.
-	(PTW32_ATTR_VALID): Add cast.
-	(struct pthread_t_): Add sigmask element.
-
-	* dll.c: Add "extern C" for DLLMain.
-	(DllMain): Add cast.
-
-	* create.c (pthread_create): Set sigmask in thread.
-
-	* condvar.c: Remove #include. Change sem_* to ptw32_sem_*.
-
-	* attr.c: Changed #include.
-
-	* Makefile.in: Additional targets and changes to build the library
-	as a DLL.
-
-Fri Jan 29 11:56:28 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* Makefile.in (OBJS): Add semaphore.o to list.
-
-	* semaphore.c (ptw32_sem_timedwait): Move from private.c.
-	Rename sem_* to ptw32_sem_*.
-
-	* pthread.h (pthread_cond_t): Change type of sem_t.
-	_POSIX_SEMAPHORES no longer defined.
-
-	* semaphore.h: Contents moved to implement.h.
-	Removed from source tree.
-
-	* implement.h: Add semaphore function prototypes and rename all
-	functions to prepend 'ptw32_'. They are
-	now private to the pthreads-win32 implementation.
-
-	* private.c: Change #warning.
-	Move ptw32_sem_timedwait() to semaphore.c.
-
-	* cleanup.c: Change #warning.
-
-	* misc.c: Remove #include <errno.h>
-
-	* pthread.def: Cleanup CVS merge conflicts.
-
-	* global.c: Ditto.
-
-	* ChangeLog: Ditto.
-
-	* cleanup.c: Ditto.
-
-Sun Jan 24 01:34:52 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* semaphore.c (sem_wait): Remove second arg to 
-	pthreadCancelableWait() call.
-
-Sat Jan 23 17:36:40 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* pthread.def: Add new functions to export list.
-
-	* pthread.h (PTHREAD_MUTEX_AUTO_CS_NP): New.
-	(PTHREAD_MUTEX_FORCE_CS_NP): New.
-
-	* README: Updated.
-
-Fri Jan 22 14:31:59 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* Makefile.in (CFLAGS): Remove -fhandle-exceptions. Not needed
-	with egcs. Add -g for debugging.
-
-	* create.c (pthread_create): Replace __stdcall with PT_STDCALL
-	macro. This is a hack and must be fixed.
-
-	* misc.c (CancelableWait): Remove redundant statement.
-
-	* mutex.c (pthread_mutexattr_init): Cast calloc return value.
-
-	* misc.c (CancelableWait): Add cast.
-	(pthread_self): Add cast.
-
-	* exit.c (pthread_exit): Add cast.
-
-	* condvar.c (pthread_condattr_init): Cast calloc return value.
-
-	* cleanup.c: Reorganise conditional compilation.
-
-	* attr.c (pthread_attr_init): Remove unused 'result'.
-	Cast malloc return value.
-
-	* private.c (ptw32_callUserDestroyRoutines): Redo conditional
-	compilation.
-
-	* misc.c (CancelableWait): C++ version uses 'throw'.
-
-	* cancel.c (pthread_testcancel): Ditto.
-
-	* implement.h (class ptw32_exception): Define for C++.
-
-	* pthread.h: Fix C, C++, and Win32 SEH condition compilation
-	mayhem around pthread_cleanup_* defines. C++ version now uses John
-	Bossom's cleanup handlers.
-	(pthread_attr_t): Make 'valid' unsigned.
-	Define '_timeb' as 'timeb' for Ming32.
-	Define PT_STDCALL as nothing for Mingw32. May be temporary.
-
-	* cancel.c (pthread_testcancel): Cast return value.
-
-Wed Jan 20 09:31:28 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* pthread.h (pthread_mutexattr_t): Changed to a pointer.
-
-	* mutex.c (pthread_mutex_init): Conditionally create Win32 mutex
-	- from John Bossom's implementation.
-	(pthread_mutex_destroy): Conditionally close Win32 mutex
-	- from John Bossom's implementation.
-	(pthread_mutexattr_init): Replaced by John Bossom's version.
-	(pthread_mutexattr_destroy): Ditto.
-	(pthread_mutexattr_getpshared): New function from John Bossom's
-	implementation.
-	(pthread_mutexattr_setpshared): New function from John Bossom's
-	implementation.
-
-Tue Jan 19 18:27:42 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* pthread.h (pthreadCancelableTimedWait): New prototype.
-	(pthreadCancelableWait): Remove second argument.
-
-	* misc.c (CancelableWait): New static function is 
-	pthreadCancelableWait() renamed.
-	(pthreadCancelableWait): Now just calls CancelableWait() with
-	INFINITE timeout.
-	(pthreadCancelableTimedWait): Just calls CancelableWait()
-	with passed in timeout.
-
-Tue Jan 19 18:27:42 1999  Scott Lightner <scott at curriculum.com>
-
-	* private.c (ptw32_sem_timedwait): 'abstime' arg really is
-	absolute time. Calculate relative time to wait from current
-	time before passing timeout to new routine 
-	pthreadCancelableTimedWait().
-
-Tue Jan 19 10:27:39 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* pthread.h (pthread_mutexattr_setforcecs_np): New prototype.
-	
-	* mutex.c (pthread_mutexattr_init): Init 'pshared' and 'forcecs'
-	attributes to 0.
-	(pthread_mutexattr_setforcecs_np): New function (not portable).
-
-	* pthread.h (pthread_mutex_t): 
-	Add 'mutex' element. Set to NULL in PTHREAD_MUTEX_INITIALIZER.
-	The pthread_mutex_*() routines will try to optimise performance
-	by choosing either mutexes or critical sections as the basis
-	for pthread mutexes for each indevidual mutex.
-	(pthread_mutexattr_t_): Add 'forcecs' element.
-	Some applications may choose to force use of critical sections
-	if they know that:-
-	     the mutex is PROCESS_PRIVATE and, 
-	         either the OS supports TryEnterCriticalSection() or
-	         pthread_mutex_trylock() will never be called on the mutex.
-	This attribute will be setable via a non-portable routine.
-
-	Note: We don't yet support PROCESS_SHARED mutexes, so the
-	implementation as it stands will default to Win32 mutexes only if
-	the OS doesn't support TryEnterCriticalSection. On Win9x, and early
-	versions of NT 'forcecs' will need to be set in order to get
-	critical section based mutexes.
-
-Sun Jan 17 12:01:26 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Init new 'staticinit'
-	value to '1' and existing 'valid' value to '1'.
-
-	* global.c (ptw32_mutex_test_init_lock): Add.
-
-	* implement.h (ptw32_mutex_test_init_lock.): Add extern.
-
-	* private.c (ptw32_processInitialize): Init critical section for
-	global lock used by _mutex_check_need_init().
-	(ptw32_processTerminate): Ditto (:s/Init/Destroy/).
-
-	* dll.c (dllMain): Move call to FreeLibrary() so that it is only
-	called once when the process detaches.
-
-	* mutex.c (_mutex_check_need_init): New static function to test
-	and init PTHREAD_MUTEX_INITIALIZER mutexes. Provides serialised
-	access to the internal state of the uninitialised static mutex. 
-	Called from pthread_mutex_trylock() and pthread_mutex_lock() which
-	do a quick unguarded test to check if _mutex_check_need_init()
-	needs to be called. This is safe as the test is conservative
- 	and is repeated inside the guarded section of 
-	_mutex_check_need_init(). Thus in all calls except the first
-	calls to lock static mutexes, the additional overhead to lock any
-	mutex is a single memory fetch and test for zero.
-
-	* pthread.h (pthread_mutex_t_): Add 'staticinit' member. Mutexes
-	initialised by PTHREAD_MUTEX_INITIALIZER aren't really initialised
-	until the first attempt to lock it. Using the 'valid'
-	flag (which flags the mutex as destroyed or not) to record this
-	information would be messy. It is possible for a statically
-	initialised mutex such as this to be destroyed before ever being
-	used.
-
-	* mutex.c (pthread_mutex_trylock): Call _mutex_check_need_init()
-	to test/init PTHREAD_MUTEX_INITIALIZER mutexes.
-	(pthread_mutex_lock): Ditto.
-	(pthread_mutex_unlock): Add check to ensure we don't try to unlock
-	an unitialised static mutex.
-	(pthread_mutex_destroy): Add check to ensure we don't try to delete
-	a critical section that we never created. Allows us to destroy
-	a static mutex that has never been locked (and hence initialised).
-	(pthread_mutex_init): Set 'staticinit' flag to 0 for the new mutex.
-
-Sun Jan 17 12:01:26 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_sem_timedwait): Move from semaphore.c.
-
-	* semaphore.c : Remove redundant #includes.
-	(ptw32_sem_timedwait): Move to private.c.
-	(sem_wait): Add missing abstime arg to pthreadCancelableWait() call.
-
-Fri Jan 15 23:38:05 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* condvar.c (cond_timedwait): Remove comment.
-
-Fri Jan 15 15:41:28 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* pthread.h: Add new 'abstime' arg to pthreadCancelableWait()
-	prototype.
-
-	* condvar.c (cond_timedwait): New generalised function called by
-	both pthread_cond_wait() and pthread_cond_timedwait(). This is
-	essentially pthread_cond_wait() renamed and modified to add the
-	'abstime' arg and call the new ptw32_sem_timedwait() instead of
-	sem_wait().
-	(pthread_cond_wait): Now just calls the internal static
-	function cond_timedwait() with an INFINITE wait.
-	(pthread_cond_timedwait): Now implemented. Calls the internal
-	static function cond_timedwait().
-
-	* implement.h (ptw32_sem_timedwait): New internal function
-	prototype.
-
-	* misc.c (pthreadCancelableWait): Added new 'abstime' argument
-	to allow shorter than INFINITE wait.
-
-	* semaphore.c (ptw32_sem_timedwait): New function for internal
-	use.  This is essentially sem_wait() modified to add the
-        'abstime' arg and call the modified (see above)
-        pthreadCancelableWait().
-
-Thu Jan 14 14:27:13 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* cleanup.c: Correct _cplusplus to __cplusplus wherever used.
-
-	* Makefile.in: Add CC=g++ and add -fhandle-exceptions to CFLAGS.
-	The derived Makefile will compile all units of the package as C++
-	so that those which include try/catch exception handling should work
-	properly. The package should compile ok if CC=gcc, however, exception
-	handling will not be included and thus thread cancellation, for
- 	example, will not work.
-
-	* cleanup.c (ptw32_pop_cleanup): Add #warning to compile this
- 	file as C++ if using a cygwin32 environment. Perhaps the whole package
-	should be compiled using g++ under cygwin.
-
-	* private.c (ptw32_threadStart): Change #error directive
-	into #warning and bracket for __CYGWIN__ and derivative compilers.
-
-Wed Jan 13 09:34:52 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* build.bat: Delete old binaries before compiling/linking.
-
-Tue Jan 12 09:58:38 1999  Tor Lillqvist <tml at iki.fi>
-
-	* dll.c: The Microsoft compiler pragmas probably are more
-	appropriately protected by _MSC_VER than by _WIN32.
-
-	* pthread.h: Define ETIMEDOUT. This should be returned by
-	pthread_cond_timedwait which is not implemented yet as of
-	snapshot-1999-01-04-1305. It was implemented in the older version.
-	The Microsoft compiler pragmas probably are more appropriately
-	protected by _MSC_VER than by _WIN32.
-
-	* pthread.def: pthread_mutex_destroy was missing from the def file
-
-	* condvar.c (pthread_cond_broadcast): Ensure we only wait on threads
-	if there were any waiting on the condition.
-	I think pthread_cond_broadcast should do the WaitForSingleObject
-	only if cv->waiters > 0? Otherwise it seems to hang, at least in the
-	testg thread program from glib.
-
-Tue Jan 12 09:58:38 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* condvar.c (pthread_cond_timedwait): Fix function description
-	comments.
-
-	* semaphore.c (sem_post): Correct typo in comment.
-
-Mon Jan 11 20:33:19 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* pthread.h: Re-arrange conditional compile of pthread_cleanup-*
-	macros.
-
-	* cleanup.c (ptw32_push_cleanup): Provide conditional 
-	compile of cleanup->prev.
-
-1999-01-11  Tor Lillqvist <tml at iki.fi>
-
-	* condvar.c (pthread_cond_init): Invert logic when testing the
-	return value from calloc().
-
-Sat Jan  9 14:32:08 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h: Compile-time switch for CYGWIN derived environments
-	to use CreateThread instead of _beginthreadex. Ditto for ExitThread.
-	Patch provided by Anders Norlander  <anorland at hem2.passagen.se>.
-
-Tue Jan  5 16:33:04 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* cleanup.c (ptw32_pop_cleanup): Add C++ version of __try/__except
-	block. Move trailing "}" out of #ifdef _WIN32 block left there by
-	(rpj's) mistake.
-
-	* private.c: Remove #include <errno.h> which is included by pthread.h.
-
-1998-12-11  Ben Elliston  <bje at toilet.to.cygnus.com>
-
-	* README: Update info about subscribing to the mailing list.
-
-Mon Jan  4 11:23:40 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* all: No code changes, just cleanup.
-	- remove #if 0 /* Pre Bossom */ enclosed code.
-	- Remove some redundant #includes.
-	* pthread.h: Update implemented/unimplemented routines list.
-	* Tag the bossom merge branch getting ready to merge back to main
-	trunk.
-
-Tue Dec 29 13:11:16 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h: Move the following struct definitions to pthread.h:
-	pthread_t_, pthread_attr_t_, pthread_mutex_t_, pthread_mutex_t_,
-	pthread_mutexattr_t_, pthread_key_t_, pthread_cond_t_,
-	pthread_condattr_t_, pthread_once_t_.
-
-	* pthread.h: Add "_" prefix to pthread_push_cleanup and 
-	pthread_pop_cleanup internal routines, and associated struct and
-	typedefs.
-
-	* buildlib.bat: Add compile command for semaphore.c
-
-	* pthread.def: Comment out pthread_atfork routine name. 
-	Now unimplemented.
-
-	* tsd.c (pthread_setspecific): Rename tkAssocCreate to
-	ptw32_tkAssocCreate.
-	(pthread_key_delete): Rename tkAssocDestroy to
-	ptw32_tkAssocDestroy.
-
-	* sync.c (pthread_join): Rename threadDestroy to ptw32_threadDestroy
-
-	* sched.c (is_attr): attr is now **attr (was *attr), so add extra
-	NULL pointer test.
-	(pthread_attr_setschedparam): Increase redirection for attr which is
-	now a **.
-	(pthread_attr_getschedparam): Ditto.
-	(pthread_setschedparam): Change thread validation and rename "thread"
- 	Win32 thread Handle element name to match John Bossom's version.
-	(pthread_getschedparam): Ditto.
-
-	* private.c (ptw32_threadDestroy): Rename call to
-	callUserDestroyRoutines() as ptw32_callUserDestroyRoutines()
-
-	* misc.c: Add #include "implement.h".
-
-	* dll.c: Remove defined(KLUDGE) wrapped code.
-
-	* fork.c: Remove redefinition of ENOMEM.
-	Remove pthread_atfork() and fork() with #if 0/#endif.
-
-	* create.c (pthread_create): Rename threadStart and threadDestroy calls
-	to ptw32_threadStart and ptw32_threadDestroy.
-
-	* implement.h: Rename "detachedstate" to "detachstate".
-
-	* attr.c: Rename "detachedstate" to "detachstate".
-
-Mon Dec 28 09:54:39 1998  John Bossom
-
-	* semaphore.c: Initial version.
-	* semaphore.h: Initial version.
-
-Mon Dec 28 09:54:39 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* pthread.h (pthread_attr_t_): Change to *pthread_attr_t.
-
-Mon Dec 28 09:54:39 1998  John Bossom, Ben Elliston
-
-	* attr.c (pthread_attr_setstacksize): Merge with John's version.
-	(pthread_attr_getstacksize): Merge with John's version.
-	(pthread_attr_setstackaddr): Merge with John's version.
-	(pthread_attr_getstackaddr): Merge with John's version.
-	(pthread_attr_init): Merge with John's version.
-	(pthread_attr_destroy): Merge with John's version.
-	(pthread_attr_getdetachstate): Merge with John's version.
-	(pthread_attr_setdetachstate): Merge with John's version.
-	(is_attr): attr is now **attr (was *attr), so add extra NULL pointer
-	test.
-
-Mon Dec 28 09:54:39 1998  Ross Johnson
-
-	* implement.h (pthread_attr_t_): Add and rename elements in JEB's
-	version to correspond to original, so that it can be used with
-	original attr routines.
-
-	* pthread.h: Add #endif at end which was truncated in merging.
-
-Sun Dec 20 14:51:58 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* misc.c (pthreadCancelableWait): New function by John Bossom. Non-standard
-	but provides a hook that can be used to implement cancellation points in
-	applications that use this library.
-
-	* pthread.h (pthread_cleanup_pop): C++ (non-WIN32) version uses
-	try/catch to emulate John Bossom's WIN32 __try/__finally behaviour.
-	In the WIN32 version __finally block, add a test for AbnormalTermination otherwise
-	cleanup is only run if the cleanup_pop execute arg is non-zero. Cancellation
-	should cause the cleanup to run irrespective of the execute arg.
-
-	* condvar.c (pthread_condattr_init): Replaced by John Bossom's version.
-	(pthread_condattr_destroy): Replaced by John Bossom's version.
-	(pthread_condattr_getpshared): Replaced by John Bossom's version.
-	(pthread_condattr_setpshared): Replaced by John Bossom's version.
-	(pthread_cond_init): Replaced by John Bossom's version.
-	Fix comment (refered to mutex rather than condition variable).
-	(pthread_cond_destroy): Replaced by John Bossom's version.
-	(pthread_cond_wait): Replaced by John Bossom's version.
-	(pthread_cond_timedwait): Replaced by John Bossom's version.
-	(pthread_cond_signal): Replaced by John Bossom's version.
-	(pthread_cond_broadcast): Replaced by John Bossom's version.
-
-Thu Dec 17 19:10:46 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* tsd.c (pthread_key_create): Replaced by John Bossom's version.
-	(pthread_key_delete): Replaced by John Bossom's version.
-	(pthread_setspecific): Replaced by John Bossom's version.
-	(pthread_getspecific): Replaced by John Bossom's version.
-
-Mon Dec  7 09:44:40 1998  John Bossom
-
-	* cancel.c (pthread_setcancelstate): Replaced.
-	(pthread_setcanceltype): Replaced.
-	(pthread_testcancel): Replaced.
-	(pthread_cancel): Replaced.
-	
-	* exit.c (pthread_exit): Replaced.
-
-	* misc.c (pthread_self): Replaced.
-	(pthread_equal): Replaced.
-
-	* sync.c (pthread_detach): Replaced.
-	(pthread_join): Replaced.
-
-	* create.c (pthread_create): Replaced.
-
-	* private.c (ptw32_processInitialize): New.
-	(ptw32_processTerminate): New.
-	(ptw32_threadStart): New.
- 	(ptw32_threadDestroy): New.
-	(ptw32_cleanupStack): New.
-	(ptw32_tkAssocCreate): New.
-	(ptw32_tkAssocDestroy): New.
-	(ptw32_callUserDestroyRoutines): New.
-
-	* implement.h: Added non-API structures and declarations.
-
-	* dll.c (PthreadsEntryPoint): Cast return value of GetProcAddress
-	to resolve compile warning from MSVC.
-
-	* dll.c (DLLmain): Replaced.
-	* dll.c (PthreadsEntryPoint):
-	Re-applied Anders Norlander's patch:-
-	Initialize ptw32_try_enter_critical_section at startup
-	and release kernel32 handle when DLL is being unloaded.
-
-Sun Dec  6 21:54:35 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* buildlib.bat: Fix args to CL when building the .DLL
-
-	* cleanup.c (ptw32_destructor_run_all): Fix TSD key management.
-	This is a tidy-up before TSD and Thread management is completely
-	replaced by John Bossom's code.
-
-	* tsd.c (pthread_key_create): Fix TSD key management.
-
-	* global.c (ptw32_key_virgin_next): Initialise.
-
-	* build.bat: New DOS script to compile and link a pthreads app
-	using Microsoft's CL compiler linker.
-	* buildlib.bat: New DOS script to compile all the object files
-	and create pthread.lib and pthread.dll using Microsoft's CL
-	compiler linker.
-
-1998-12-05  Anders Norlander  <anorland at hem2.passagen.se>
-
-	* implement.h (ptw32_try_enter_critical_section): New extern
-	* dll.c (ptw32_try_enter_critical_section): New pointer to
-	TryEnterCriticalSection if it exists; otherwise NULL.
-	* dll.c (PthreadsEntryPoint):
-	Initialize ptw32_try_enter_critical_section at startup
-	and release kernel32 handle when DLL is being unloaded.
-	* mutex.c (pthread_mutex_trylock): Replaced check for NT with
-	a check if ptw32_try_enter_critical_section is valid
-	pointer to a function. Call ptw32_try_enter_critical_section
-	instead of TryEnterCriticalSection to avoid errors on Win95.
-
-Thu Dec 3 13:32:00 1998  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-	* README: Correct cygwin32 compatibility statement.
-
-Sun Nov 15 21:24:06 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* cleanup.c (ptw32_destructor_run_all): Declare missing void * arg.
-	Fixup CVS merge conflicts.
-
-1998-10-30  Ben Elliston  <bje at cygnus.com>
-
-	* condvar.c (cond_wait): Fix semantic error. Test for equality
-	instead of making an assignment.
-
-Fri Oct 30 15:15:50 1998  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* cleanup.c (ptw32_handler_push): Fixed bug appending new
-	handler to list reported by Peter Slacik
-	<Peter.Slacik at leibinger.freinet.de>.
-	(new_thread): Rename poorly named local variable to
-	"new_handler".
-
-Sat Oct 24 18:34:59 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* global.c: Add TSD key management array and index declarations.
-
-	* implement.h: Ditto for externs.
-
-Fri Oct 23 00:08:09 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h (PTW32_TSD_KEY_REUSE): Add enum.
-
-	* private.c (ptw32_delete_thread): Add call to
-	ptw32_destructor_run_all() to clean up the threads keys.
-
-	* cleanup.c (ptw32_destructor_run_all): Check for no more dirty
-	keys to run destructors on. Assume that the destructor call always
-	succeeds and set the key value to NULL.
-
-Thu Oct 22 21:44:44 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* tsd.c (pthread_setspecific): Add key management code.
-	(pthread_key_create): Ditto.
-	(pthread_key_delete): Ditto.
-
-	* implement.h (struct ptw32_tsd_key): Add status member.
-
-	* tsd.c: Add description of pthread_key_delete() from the
-	standard as a comment.
-
-Fri Oct 16 17:38:47 1998  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* cleanup.c (ptw32_destructor_run_all): Fix and improve
-	stepping through the key table.
-
-Thu Oct 15 14:05:01 1998  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* private.c (ptw32_new_thread): Remove init of destructorstack.
-	No longer an element of pthread_t.
-
-	* tsd.c (pthread_setspecific): Fix type declaration and cast.
-	(pthread_getspecific): Ditto.
-	(pthread_getspecific): Change error return value to NULL if key
-	is not in use.
-
-Thu Oct 15 11:53:21 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* global.c (ptw32_tsd_key_table): Fix declaration.
-
-	* implement.h(ptw32_TSD_keys_TlsIndex): Add missing extern.
-	(ptw32_tsd_mutex): Ditto.
-
-	* create.c (ptw32_start_call): Fix "keys" array declaration.
-	Add comment.
-
-	* tsd.c (pthread_setspecific): Fix type declaration and cast.
-	(pthread_getspecific): Ditto.
-
-	* cleanup.c (ptw32_destructor_run_all): Declare missing loop
-	counter.
-
-Wed Oct 14 21:09:24 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_new_thread): Increment ptw32_threads_count.
-	(ptw32_delete_thread): Decrement ptw32_threads_count.
-	Remove some comments.
-
-	* exit.c (ptw32_exit): : Fix two pthread_mutex_lock() calls that
- 	should have been pthread_mutex_unlock() calls.
-	(ptw32_vacuum): Remove call to ptw32_destructor_pop_all().
-
-	* create.c (pthread_create): Fix two pthread_mutex_lock() calls that
- 	should have been pthread_mutex_unlock() calls.
-
-	* global.c (ptw32_tsd_mutex): Add mutex for TSD operations.
-
-	* tsd.c (pthread_key_create): Add critical section.
-	(pthread_setspecific): Ditto.
-	(pthread_getspecific): Ditto.
-	(pthread_key_delete): Ditto.
-
-	* sync.c (pthread_join): Fix two pthread_mutex_lock() calls that
- 	should have been pthread_mutex_unlock() calls.
-
-Mon Oct 12 00:00:44 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h (ptw32_tsd_key_table): New.
-
-	* create.c (ptw32_start_call): Initialise per-thread TSD keys
-	to NULL.
-
-	* misc.c (pthread_once): Correct typo in comment.
-
-	* implement.h (ptw32_destructor_push): Remove.
-	(ptw32_destructor_pop): Remove.
-	(ptw32_destructor_run_all): Rename from ptw32_destructor_pop_all.
-	(PTW32_TSD_KEY_DELETED): Add enum.
-	(PTW32_TSD_KEY_INUSE): Add enum.
-
-	* cleanup.c (ptw32_destructor_push): Remove.
-	(ptw32_destructor_pop): Remove.
-	(ptw32_destructor_run_all): Totally revamped TSD.
-
-	* dll.c (ptw32_TSD_keys_TlsIndex): Initialise.
-
-	* tsd.c (pthread_setspecific): Totally revamped TSD.
-	(pthread_getspecific): Ditto.
-	(pthread_create): Ditto.
-	(pthread_delete): Ditto.
-
-Sun Oct 11 22:44:55 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* global.c (ptw32_tsd_key_table): Add new global.
-
-	* implement.h (ptw32_tsd_key_t and struct ptw32_tsd_key):
-	Add.
-	(struct _pthread): Remove destructorstack.
-
-	* cleanup.c (ptw32_destructor_run_all): Rename from
- 	ptw32_destructor_pop_all. The key destructor stack was made
- 	global rather than per-thread. No longer removes destructor nodes
-	from the stack. Comments updated.
-
-1998-10-06  Ben Elliston  <bje at cygnus.com>
-
-	* condvar.c (cond_wait): Use POSIX, not Win32 mutex calls.
-	(pthread_cond_broadcast): Likewise.
-	(pthread_cond_signal): Likewise.
-
-1998-10-05  Ben Elliston  <bje at cygnus.com>
-
-	* pthread.def: Update. Some functions aren't available yet, others
-	are macros in <pthread.h>.
-
-	* tests/join.c: Remove; useless.
-
-Mon Oct  5 14:25:08 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* pthread.def: New file for building the DLL.
-
-1998-10-05  Ben Elliston  <bje at cygnus.com>
-
-	* misc.c (pthread_equal): Correct inverted logic bug.
-	(pthread_once): Use the POSIX mutex primitives, not Win32. Remove
-	irrelevant FIXME comment.
-
-	* global.c (PTHREAD_MUTEX_INITIALIZER): Move to pthread.h.
-
-	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Define.
-	(pthread_mutex_t): Reimplement as a struct containing a valid
-	flag. If the flag is ever down upon entry to a mutex operation,
-	we call pthread_mutex_create() to initialise the object. This
-	fixes the problem of how to handle statically initialised objects
-	that can't call InitializeCriticalSection() due to their context.
-	(PTHREAD_ONCE_INIT): Define.
-
-	* mutex.c (pthread_mutex_init): Set valid flag.
-	(pthread_mutex_destroy): Clear valid flag.
-	(pthread_mutex_lock): Check and handle the valid flag.
-	(pthread_mutex_unlock): Likewise.
-	(pthread_mutex_trylock): Likewise.
-
-	* tests/mutex3.c: New file; test for the static initialisation
-	macro. Passes.
-
-	* tests/create1.c: New file; test pthread_create(). Passes.
-	
-	* tests/equal.c: Poor test; remove.
-	
-	* tests/equal1.c New file; test pthread_equal(). Passes.
-
-	* tests/once1.c: New file; test for pthread_once(). Passes.
-
-	* tests/self.c: Remove; rename to self1.c.
-
-	* tests/self1.c: This is the old self.c.
-
-	* tests/self2.c: New file. Test pthread_self() with a single
-	thread. Passes.
-
-	* tests/self3.c: New file. Test pthread_self() with a couple of
-	threads to ensure their thread IDs differ. Passes.
-	
-1998-10-04  Ben Elliston  <bje at cygnus.com>
-
-	* tests/mutex2.c: Test pthread_mutex_trylock(). Passes.
-
-	* tests/mutex1.c: New basic test for mutex functions (it passes).
-	(main): Eliminate warning.
-
-	* configure.in: Test for __stdcall, not _stdcall. Typo.
-
-	* configure: Regenerate.
-
-	* attr.c (pthread_attr_setstackaddr): Remove FIXME comment. Win32
-	does know about ENOSYS after all.
-	(pthread_attr_setstackaddr): Likewise.
-
-1998-10-03  Ben Elliston  <bje at cygnus.com>
-
-	* configure.in: Test for the `_stdcall' keyword.  Define `STDCALL'
-	to `_stdcall' if we have it, null otherwise.
-
-	* configure: Regenerate.
-
-	* acconfig.h (STDCALL): New define.
-
-	* config.h.in: Regenerate.
-
-	* create.c (ptw32_start_call): Add STDCALL prefix.
-	
-	* mutex.c (pthread_mutex_init): Correct function signature.
-
-	* attr.c (pthread_attr_init): Only zero out the `sigmask' member
-	if we have the sigset_t type.
-
-	* pthread.h: No need to include <unistd.h>.  It doesn't even exist
-	on Win32! Again, an artifact of cross-compilation.	
-	(pthread_sigmask): Only provide if we have the sigset_t type.
-
-	* process.h: Remove. This was a stand-in before we started doing
-	native compilation under Win32.
-
-	* pthread.h (pthread_mutex_init): Make `attr' argument const.
-
-1998-10-02  Ben Elliston  <bje at cygnus.com>
-
-	* COPYING: Remove.
-
-	* COPYING.LIB: Add. This library is under the LGPL.
-
-1998-09-13  Ben Elliston  <bje at cygnus.com>
-
-	* configure.in: Test for required system features.
-
-	* configure: Generate. 
-
-	* acconfig.h: New file.
-
-	* config.h.in: Generate.
-
-	* Makefile.in: Renamed from Makefile.
-
-	* COPYING: Import from a recent GNU package.
-
-	* config.guess: Likewise.
-
-	* config.sub: Likewise.
-
-	* install-sh: Likewise.
-
-	* config.h: Remove.  
-
-	* Makefile: Likewise.
-
-1998-09-12  Ben Elliston  <bje at cygnus.com>
-
-	* windows.h: No longer needed; remove.
-
-	* windows.c: Likewise.
-
-Sat Sep 12 20:09:24 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* windows.h: Remove error number definitions. These are in <errno.h>
-	
-	* tsd.c: Add comment explaining rationale for not building
-	POSIX TSD on top of Win32 TLS.
-
-1998-09-12  Ben Elliston  <bje at cygnus.com>
-
-	* {most}.c: Include <errno.h> to get POSIX error values.
-
-	* signal.c (pthread_sigmask): Only provide if HAVE_SIGSET_T is
-	defined.
- 
-	* config.h: #undef features, don't #define them.  This will be
-	generated by autoconf very soon.
-	
-1998-08-11  Ben Elliston  <bje at cygnus.com>
-
-	* Makefile (LIB): Define.
-	(clean): Define target.
-	(all): Build a library not just the object files.
-
-	* pthread.h: Provide a definition for struct timespec if we don't
-	already have one.
-
-	* windows.c (TlsGetValue): Bug fix.
-	
-Thu Aug  6 15:19:22 1998  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* misc.c (pthread_once): Fix arg 1 of EnterCriticalSection()
- 	and LeaveCriticalSection() calls to pass address-of lock.
-
-	* fork.c (pthread_atfork): Typecast (void (*)(void *)) funcptr
-	in each ptw32_handler_push() call.
-
-	* exit.c (ptw32_exit): Fix attr arg in 
-	pthread_attr_getdetachstate() call.
-
-	* private.c (ptw32_new_thread): Typecast (HANDLE) NULL.
-	(ptw32_delete_thread): Ditto.
-
-	* implement.h: (PTW32_MAX_THREADS): Add define. This keeps
-	changing in an attempt to make thread administration data types
-	opaque and cleanup DLL startup.
-
-	* dll.c (PthreadsEntryPoint): 
-	(ptw32_virgins): Remove malloc() and free() calls.
-	(ptw32_reuse): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* global.c (_POSIX_THREAD_THREADS_MAX): Initialise with 
-	PTW32_MAX_THREADS.
-	(ptw32_virgins): Ditto.
-	(ptw32_reuse): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* create.c (pthread_create): Typecast (HANDLE) NULL.
-	Typecast (unsigned (*)(void *)) start_routine.
-
-	* condvar.c (pthread_cond_init): Add address-of operator & to
-	arg 1 of pthread_mutex_init() call.
-	(pthread_cond_destroy): Add address-of operator & to
-	arg 1 of pthread_mutex_destroy() call. 
-
-	* cleanup.c (ptw32_destructor_pop_all): Add (int) cast to 
-	pthread_getspecific() arg.
-	(ptw32_destructor_pop): Add (void *) cast to "if" conditional.
-	(ptw32_destructor_push): Add (void *) cast to
-	ptw32_handler_push() "key" arg.
-	(malloc.h): Add include.
-
-	* implement.h (ptw32_destructor_pop): Add prototype.
-
-	* tsd.c (implement.h): Add include.
-
-	* sync.c (pthread_join): Remove target_thread_mutex and it's
-	initialisation. Rename getdetachedstate to getdetachstate.
-	Remove unused variable "exitcode".
-	(pthread_detach): Remove target_thread_mutex and it's
-	initialisation. Rename getdetachedstate to getdetachstate.
-	Rename setdetachedstate to setdetachstate.
-
-	* signal.c (pthread_sigmask): Rename SIG_SET to SIG_SETMASK.
-	Cast "set" to (long *) in assignment to passify compiler warning.
-	Add address-of operator & to thread->attr.sigmask in memcpy() call
-	and assignment.
-	(pthread_sigmask): Add address-of operator & to thread->attr.sigmask
-	in memcpy() call and assignment.
-
-	* windows.h (THREAD_PRIORITY_ERROR_RETURN): Add.
-	(THREAD_PRIORITY_LOWEST): Add.
-	(THREAD_PRIORITY_HIGHEST): Add.
-
-	* sched.c (is_attr): Add function.
-	(implement.h): Add include.
-	(pthread_setschedparam): Rename all instances of "sched_policy"
-	to "sched_priority".
-	(pthread_getschedparam): Ditto.
-
-Tue Aug  4 16:57:58 1998  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* private.c (ptw32_delete_thread): Fix typo. Add missing ';'.
-
-	* global.c (ptw32_virgins): Change types from pointer to 
-	array pointer.
-	(ptw32_reuse): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* implement.h(ptw32_virgins): Change types from pointer to 
-	array pointer.
-	(ptw32_reuse): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* private.c (ptw32_delete_thread): Fix "entry" should be "thread".
-
-	* misc.c (pthread_self): Add extern for ptw32_threadID_TlsIndex.
-
-	* global.c: Add comment.
-
-	* misc.c (pthread_once): Fix member -> dereferences.
-	Change ptw32_once_flag to once_control->flag in "if" test.
-
-Tue Aug  4 00:09:30 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h(ptw32_virgins): Add extern.
-	(ptw32_virgin_next): Ditto.
-	(ptw32_reuse): Ditto.
-	(ptw32_reuse_top): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* global.c (ptw32_virgins): Changed from array to pointer.
-	Storage allocation for the array moved into dll.c.
-	(ptw32_reuse): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* dll.c (PthreadsEntryPoint): Set up thread admin storage when
-	DLL is loaded.
-
-	* fork.c (pthread_atfork): Fix function pointer arg to all
-	ptw32_handler_push() calls. Change "arg" arg to NULL in child push.
-
-	* exit.c: Add windows.h and process.h includes.
-	(ptw32_exit): Add local detachstate declaration.
-	(ptw32_exit): Fix incorrect name for pthread_attr_getdetachstate().
-
-	* pthread.h (_POSIX_THREAD_ATTR_STACKSIZE): Move from global.c
-	(_POSIX_THREAD_ATTR_STACKADDR): Ditto.
-
-	* create.c (pthread_create): Fix #if should be #ifdef.
-	(ptw32_start_call): Remove usused variables.
-
-	* process.h: Create.
-
-	* windows.h: Move _beginthreadex and _endthreadex into
-	process.h
-
-Mon Aug  3 21:19:57 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* condvar.c (pthread_cond_init): Add NULL attr to
-	pthread_mutex_init() call - default attributes will be used.
-	(cond_wait): Fix typo.
-	(cond_wait): Fix typo - cv was ev.
-	(pthread_cond_broadcast): Fix two identical typos.
-
-	* cleanup.c (ptw32_destructor_pop_all): Remove _ prefix from
-	PTHREAD_DESTRUCTOR_ITERATIONS.
-
-	* pthread.h: Move _POSIX_* values into posix.h
-
-	* pthread.h: Fix typo in pthread_mutex_init() prototype.
-
-	* attr.c (pthread_attr_init): Fix error in priority member init.
-
-	* windows.h (THREAD_PRIORITY_NORMAL): Add.
-
-	* pthread.h (sched_param): Add missing ';' to struct definition. 
-
-	* attr.c (pthread_attr_init): Remove obsolete pthread_attr_t
-	member initialisation - cancelstate, canceltype, cancel_pending.
-	(is_attr): Make arg "attr" a const.
-
-	* implement.h (PTW32_HANDLER_POP_LIFO): Remove definition.
-	(PTW32_HANDLER_POP_FIFO): Ditto.
-	(PTW32_VALID): Add missing newline escape (\).
-	(ptw32_handler_node): Make element "next" a pointer.
-
-1998-08-02  Ben Elliston  <bje at cygnus.com>
-
-	* windows.h: Remove duplicate TlsSetValue() prototype.  Add 
-	TlsGetValue() prototype.
-	(FALSE): Define.
-	(TRUE): Likewise.
-	Add forgotten errno values.  Guard against multiple #includes.
-
-	* windows.c: New file.  Implement stubs for Win32 functions.
-
-	* Makefile (SRCS): Remove.  Not explicitly needed.
-	(CFLAGS): Add -Wall for all warnings with GCC.
-
-Sun Aug  2 19:03:42 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* config.h: Create. This is a temporary stand-in for autoconf yet
-	to be done.
- 	(HAVE_SIGNAL_H): Add.
-
-	* pthread.h: Minor rearrangement for temporary config.h.
-
-Fri Jul 31 14:00:29 1998  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* cleanup.c (ptw32_destructor_pop): Implement. Removes
-	destructors associated with a key without executing them.
-	(ptw32_destructor_pop_all): Add FIXME comment.
-
-	* tsd.c (pthread_key_delete): Add call to ptw32_destructor_pop().
-
-Fri Jul 31 00:05:45 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* tsd.c (pthread_key_create): Update to properly associate
-	the destructor routine with the key.
-	(pthread_key_delete): Add FIXME comment.
-
-	* exit.c (ptw32_vacuum): Add call to
-	ptw32_destructor_pop_all().
-
-	* implement.h (ptw32_handler_pop_all): Add prototype.
-	(ptw32_destructor_pop_all): Ditto.
-
-	* cleanup.c (ptw32_destructor_push): Implement. This is just a
-	call to ptw32_handler_push().
-	(ptw32_destructor_pop_all): Implement. This is significantly
-	different to ptw32_handler_pop_all().
-
-	* Makefile (SRCS): Create. Preliminary.
-
-	* windows.h: Create. Contains Win32 definitions for compile
-	testing. This is just a standin for the real one.
-
-	* pthread.h (SIG_UNBLOCK): Fix typo. Was SIG_BLOCK.
-	(windows.h): Add include. Required for CRITICAL_SECTION.
-	(pthread_cond_t): Move enum declaration outside of struct
-	definition.
-	(unistd.h): Add include - may be temporary.
-
-	* condvar.c (windows.h): Add include.
-
-	* implement.h (PTW32_THIS): Remove - no longer required.
-	(PTW32_STACK): Use pthread_self() instead of PTW32_THIS.
-
-Thu Jul 30 23:12:45 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h: Remove ptw32_find_entry() prototype.
-
-	* private.c: Extend comments.
-	Remove ptw32_find_entry() - no longer needed.
-
-	* create.c (ptw32_start_call): Add call to TlsSetValue() to
-	store the thread ID.
-
-	* dll.c (PthreadsEntryPoint): Implement. This is called
-	whenever a process loads the DLL. Used to initialise thread
-	local storage.
-
-	* implement.h: Add ptw32_threadID_TlsIndex.
-	Add ()s around PTW32_VALID expression.
-
-	* misc.c (pthread_self): Re-implement using Win32 TLS to store
-	the threads own ID.
-
-Wed Jul 29 11:39:03 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* private.c: Corrections in comments.
-	(ptw32_new_thread): Alter "if" flow to be more natural.
-
-	* cleanup.c (ptw32_handler_push): Same as below.
-
-	* create.c (pthread_create): Same as below.
-
-	* private.c (ptw32_new_thread): Rename "new" to "new_thread".
-	Since when has a C programmer been required to know C++?
-
-Tue Jul 28 14:04:29 1998  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* implement.h: Add PTW32_VALID macro.
-
-	* sync.c (pthread_join): Modify to use the new thread
-	type and ptw32_delete_thread(). Rename "target" to "thread".
-	Remove extra local variable "target".
-	(pthread_detach): Ditto.
-
-	* signal.c (pthread_sigmask): Move init of "us" out of inner block.
-	Fix instance of "this" should have been "us". Rename "us" to "thread".
-
-	* sched.c (pthread_setschedparam): Modify to use the new thread
-	type.
-	(pthread_getschedparam): Ditto.
-
-	* private.c (ptw32_find_thread): Fix return type and arg.
-
-	* implement.h: Remove PTW32_YES and PTW32_NO.
-	(ptw32_new_thread): Add prototype.
-	(ptw32_find_thread): Ditto.
-	(ptw32_delete_thread): Ditto.
-	(ptw32_new_thread_entry): Remove prototype.
-	(ptw32_find_thread_entry): Ditto.
-	(ptw32_delete_thread_entry): Ditto.
-	(  PTW32_NEW, PTW32_INUSE, PTW32_EXITED, PTW32_REUSE):
-	Add.
-
-
-	* create.c (pthread_create): Minor rename "us" to "new" (I need
-	these cues but it doesn't stop me coming out with some major bugs
-	at times).
-	Load start_routine and arg into the thread so the wrapper can
-	call it.
-
-	* exit.c (pthread_exit): Fix pthread_this should be pthread_self.
-
-	* cancel.c (pthread_setcancelstate): Change
- 	ptw32_threads_thread_t * to pthread_t and init with
- 	pthread_this().
-	(pthread_setcanceltype): Ditto.
-
-	* exit.c (ptw32_exit): Add new pthread_t arg.
-	Rename ptw32_delete_thread_entry to ptw32_delete_thread.
-	Rename "us" to "thread".
-	(pthread_exit): Call ptw32_exit with added thread arg.
-
-	* create.c (ptw32_start_call): Insert missing ")".
-	Add "us" arg to ptw32_exit() call.
-	(pthread_create): Modify to use new thread allocation scheme.
-
-	* private.c: Added detailed explanation of the new thread
-	allocation scheme.
-	(ptw32_new_thread): Totally rewritten to use
-	new thread allocation scheme.
-	(ptw32_delete_thread): Ditto.
-	(ptw32_find_thread): Obsolete.
-
-Mon Jul 27 17:46:37 1998  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* create.c (pthread_create): Start of rewrite. Not completed yet.
-
-	* private.c (ptw32_new_thread_entry): Start of rewrite. Not
-	complete.
-
-	* implement.h (ptw32_threads_thread): Rename, remove thread
-	member, add win32handle and ptstatus members.
-	(ptw32_t): Add.
-
-	* pthread.h: pthread_t is no longer mapped directly to a Win32
-	HANDLE type. This is so we can let the Win32 thread terminate and
-	reuse the HANDLE while pthreads holds it's own thread ID until
-	the last waiting join exits.
-
-Mon Jul 27 00:20:37 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_delete_thread_entry): Destroy the thread
- 	entry attribute object before deleting the thread entry itself.
-
-	* attr.c (pthread_attr_init): Initialise cancel_pending = FALSE.
-	(pthread_attr_setdetachstate): Rename "detached" to "detachedstate".
-	(pthread_attr_getdetachstate): Ditto.
-
-	* exit.c (ptw32_exit): Fix incorrect check for detachedstate.
-
-	* implement.h (ptw32_call_t): Remove env member. 
-
-Sun Jul 26 13:06:12 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h (ptw32_new_thread_entry): Fix prototype.
-	(ptw32_find_thread_entry): Ditto.
-	(ptw32_delete_thread_entry): Ditto.
-	(ptw32_exit): Add prototype.
-
-	* exit.c (ptw32_exit): New function. Called from pthread_exit()
-	and ptw32_start_call() to exit the thread. It allows an extra
-	argument which is the return code passed to _endthreadex().
-	(ptw32_exit): Move thread entry delete call from ptw32_vacuum()
-	into here. Add more explanation of thread entry deletion.
-	(ptw32_exit): Clarify comment.
-
-	* create.c (ptw32_start_call): Change pthread_exit() call to
-	ptw32_exit() call.
-
-	* exit.c (ptw32_vacuum): Add thread entry deletion code
-	moved from ptw32_start_call(). See next item.
-	(pthread_exit): Remove longjmp(). Add mutex lock around thread table
-	manipulation code. This routine now calls _enthreadex().
-
-	* create.c (ptw32_start_call): Remove setjmp() call and move
-	cleanup code out. Call pthread_exit(NULL) to terminate the thread.
-
-1998-07-26  Ben Elliston  <bje at cygnus.com>
-
-	* tsd.c (pthread_getspecific): Update comments.
-
-	* mutex.c (pthread_mutexattr_setpshared): Not supported; remove.
-	(pthread_mutexattr_getpshared): Likewise.
-
-	* pthread.h (pthread_mutexattr_setpshared): Remove prototype.
-	(pthread_mutexattr_getpshared): Likewise.
-
-Sun Jul 26 00:09:59 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* sync.c: Rename all instances of ptw32_count_mutex to
-	ptw32_table_mutex.
-
-	* implement.h: Rename ptw32_count_mutex to
-	ptw32_table_mutex.
-
-	* global.c: Rename ptw32_count_mutex to
-	ptw32_table_mutex.
-
-	* create.c (pthread_create): Add critical sections.
-	(ptw32_start_call): Rename ptw32_count_mutex to
-	ptw32_table_mutex.
-
-	* cancel.c (pthread_setcancelstate): Fix indirection bug and rename
-	"this" to "us".
-
-	* signal.c (pthread_sigmask): Rename "this" to "us" and fix some
-	minor syntax errors. Declare "us" and initialise it.
-
-	* sync.c (pthread_detach): Rename "this" to "target".
-
-	* pthread.h: Converting PTHREAD_* defines to alias the (const int)
-	values in global.c.
-
-	* global.c: Started converting PTHREAD_* defines to (const int) as
- 	a part of making the eventual pthreads DLL binary compatible
- 	through version changes.
-
-	* condvar.c (cond_wait): Add cancelation point. This applies the
-	point to both pthread_cond_wait() and pthread_cond_timedwait().
-
-	* exit.c (pthread_exit): Rename "this" to "us".
-
-	* implement.h: Add comment.
-
-	* sync.c (pthread_join): I've satisfied myself that pthread_detach()
-	does set the detached attribute in the thread entry attributes
-	to PTHREAD_CREATE_DETACHED. "if" conditions were changed to test
-	that attribute instead of a separate flag.
-
-	* create.c (pthread_create): Rename "this" to "us".
-	(pthread_create): cancelstate and canceltype are not attributes
-	so the copy to thread entry attribute storage was removed.
-	Only the thread itself can change it's cancelstate or canceltype,
-	ie. the thread must exist already.
-
-	* private.c (ptw32_delete_thread_entry): Mutex locks removed.
-	Mutexes must be applied at the caller level.
-	(ptw32_new_thread_entry): Ditto.
-	(ptw32_new_thread_entry): Init cancelstate, canceltype, and
-	cancel_pending to default values.
-	(ptw32_new_thread_entry): Rename "this" to "new".
-	(ptw32_find_thread_entry): Rename "this" to "entry".
-	(ptw32_delete_thread_entry): Rename "thread_entry" to "entry".
-
-	* create.c (ptw32_start_call): Mutexes changed to
-	ptw32_count_mutex. All access to the threads table entries is
-	under the one mutex. Otherwise chaos reigns.
-
-Sat Jul 25 23:16:51 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h (ptw32_threads_thread): Move cancelstate and
- 	canceltype members out of pthread_attr_t into here.
-
-	* fork.c (fork): Add comment.
-
-1998-07-25  Ben Elliston  <bje at cygnus.com>
-
-	* fork.c (fork): Autoconfiscate.
-
-Sat Jul 25 00:00:13 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* create.c (ptw32_start_call): Set thread priority.  Ensure our
- 	thread entry is removed from the thread table but only if
- 	pthread_detach() was called and there are no waiting joins.
-	(pthread_create): Set detach flag in thread entry if the 
-	thread is created PTHREAD_CREATE_DETACHED.
-
-	* pthread.h (pthread_attr_t): Rename member "detachedstate".
-
-	* attr.c (pthread_attr_init): Rename attr members.
-
-	* exit.c (pthread_exit): Fix indirection mistake.
-
-	* implement.h (PTW32_THREADS_TABLE_INDEX): Add.
-
-	* exit.c (ptw32_vacuum): Fix incorrect args to
-	ptw32_handler_pop_all() calls.
-	Make thread entry removal conditional.
-
-	* sync.c (pthread_join): Add multiple join and async detach handling.
-
-	* implement.h (PTW32_THREADS_TABLE_INDEX): Add.
-
-	* global.c (ptw32_threads_mutex_table): Add.
-
-	* implement.h (ptw32_once_flag): Remove.
-	(ptw32_once_lock): Ditto.
-	(ptw32_threads_mutex_table): Add.
-
-	* global.c (ptw32_once_flag): Remove.
-	(ptw32_once_lock): Ditto.
-
-	* sync.c (pthread_join): Fix tests involving new return value
-	from ptw32_find_thread_entry().
-	(pthread_detach): Ditto.
-
-	* private.c (ptw32_find_thread_entry): Failure return code
-	changed from -1 to NULL.
-
-Fri Jul 24 23:09:33 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* create.c (pthread_create): Change . to -> in sigmask memcpy() args.
-
-	* pthread.h: (pthread_cancel): Add function prototype.
-	(pthread_testcancel): Ditto.
-
-1998-07-24  Ben Elliston  <bje at cygnus.com>
-
-	* pthread.h (pthread_condattr_t): Rename dummy structure member.
-	(pthread_mutexattr_t): Likewise.
-
-Fri Jul 24 21:13:55 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* cancel.c (pthread_cancel): Implement.
-	(pthread_testcancel): Implement.
-
-	* exit.c (pthread_exit): Add comment explaining the longjmp().
-
-	* implement.h (ptw32_threads_thread_t): New member cancelthread.
-	(PTW32_YES): Define.
-	(PTW32_NO): Define.
-	(RND_SIZEOF): Remove.
-
-	* create.c (pthread_create): Rename cancelability to cancelstate.
-
-	* pthread.h (pthread_attr_t): Rename cancelability to cancelstate.
-	(PTHREAD_CANCELED): Define.
-
-1998-07-24  Ben Elliston  <bje at cygnus.com>
-
-	* pthread.h (SIG_BLOCK): Define if not already defined.
-	(SIG_UNBLOCK): Likewise.
-	(SIG_SETMASK): Likewise.
-	(pthread_attr_t): Add signal mask member.
-	(pthread_sigmask): Add function prototype.
-
-	* signal.c (pthread_sigmask): Implement.
-
-	* create.c: #include <string.h> to get a prototype for memcpy().
-	(pthread_create): New threads inherit their creator's signal
-	mask.  Copy the signal mask to the new thread structure if we know
-	about signals.
-	
-Fri Jul 24 16:33:17 1998  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* fork.c (pthread_atfork): Add all the necessary push calls.
-	Local implementation semantics:
-	If we get an ENOMEM at any time then ALL handlers
-	(including those from previous pthread_atfork() calls) will be
-	popped off each of the three atfork stacks before we return.
-	(fork): Add all the necessary pop calls. Add the thread cancellation
-	and join calls to the child fork.
-	Add #includes.
-
-	* implement.h: (ptw32_handler_push): Fix return type and stack arg
-	type in prototype.
-	(ptw32_handler_pop): Fix stack arg type in prototype.
-	(ptw32_handler_pop_all): Fix stack arg type in prototype.
-
-	* cleanup.c (ptw32_handler_push): Change return type to int and
-	return ENOMEM if malloc() fails.
-
-	* sync.c (pthread_detach): Use equality test, not assignment.
-
-	* create.c (ptw32_start_call): Add call to Win32 CloseHandle()
-	if thread is detached.
-
-1998-07-24  Ben Elliston  <bje at cygnus.com>
-
-	* sync.c (pthread_detach): Close the Win32 thread handle to
-	emulate detached (or daemon) threads.
-
-Fri Jul 24 03:00:25 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* sync.c (pthread_join): Save valueptr arg in joinvalueptr for
-	pthread_exit() to use.
-
-	* private.c (ptw32_new_thread_entry): Initialise joinvalueptr to
-	NULL.
-
-	* create.c (ptw32_start_call): Rewrite to facilitate joins.
-	pthread_exit() will do a longjmp() back to here. Does appropriate
-	cleanup and exit/return from the thread.
-	(pthread_create): _beginthreadex() now passes a pointer to our
-	thread table entry instead of just the call member of that entry.
-
-	* implement.h (ptw32_threads_thread): New member 
-	void ** joinvalueptr.
-	(ptw32_call_t): New member jmpbuf env.
-
-	* exit.c (pthread_exit): Major rewrite to handle joins and handing
-	value pointer to joining thread. Uses longjmp() back to 
-	ptw32_start_call().
-
-	* create.c (pthread_create): Ensure values of new attribute members
-	are copied to the thread attribute object.
-
-	* attr.c (pthread_attr_destroy):  Fix merge conflicts.
-	(pthread_attr_getdetachstate):  Fix merge conflicts.
-	(pthread_attr_setdetachstate):  Fix merge conflicts.
-
-	* pthread.h:  Fix merge conflicts.
-
-	* sync.c (pthread_join): Fix merge conflicts.
-
-Fri Jul 24 00:21:21 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* sync.c (pthread_join): Add check for valid and joinable
-	thread.
-	(pthread_detach): Implement. After checking for a valid and joinable
-	thread, it's still a no-op.
-
-	* private.c (ptw32_find_thread_entry): Bug prevented returning
-	an error value in some cases.
-
-	* attr.c (pthread_attr_setdetachedstate): Implement.
-	(pthread_attr_getdetachedstate): Implement.
-
-	* implement.h: Move more hidden definitions into here from
-	pthread.h.
-
-1998-07-24  Ben Elliston  <bje at cygnus.com>
-
-	* pthread.h (PTHREAD_CREATE_JOINABLE): Define.
-	(PTHREAD_CREATE_DETACHED): Likewise.
-	(pthread_attr_t): Add new structure member `detached'.
-	(pthread_attr_getdetachstate): Add function prototype.
-	(pthread_attr_setdetachstate): Likewise.
-
-	* sync.c (pthread_join): Return if the target thread is detached.
-
-	* attr.c (pthread_attr_init): Initialise cancelability and
-	canceltype structure members.
-	(pthread_attr_getdetachstate): Implement.
-	(pthread_attr_setdetachstate): Likewise.
-
-	* implement.h (PTW32_CANCEL_DEFAULTS): Remove.  Bit fields
-	proved to be too cumbersome.  Set the defaults in attr.c using the
-	public PTHREAD_CANCEL_* constants.
-
-	* cancel.c: New file.
-
-	* pthread.h (sched_param): Define this type.
-	(pthread_attr_getschedparam): Add function prototype.
-	(pthread_attr_setschedparam): Likewise.
-	(pthread_setcancelstate): Likewise.
-	(pthread_setcanceltype): Likewise.
-	(sched_get_priority_min): Likewise.
-	(sched_get_priority_max): Likewise.
-	(pthread_mutexattr_setprotocol): Remove; not supported.
-	(pthread_mutexattr_getprotocol): Likewise.
-	(pthread_mutexattr_setprioceiling): Likewise.
-	(pthread_mutexattr_getprioceiling): Likewise.
-	(pthread_attr_t): Add canceltype member.  Update comments.
-	(SCHED_OTHER): Define this scheduling policy constant.
-	(SCHED_FIFO): Likewise.
-	(SCHED_RR): Likewise.
-	(SCHED_MIN): Define the lowest possible value for this constant.
-	(SCHED_MAX): Likewise, the maximum possible value.
-	(PTHREAD_CANCEL_ASYNCHRONOUS): Redefine.
-	(PTHREAD_CANCEL_DEFERRED): Likewise.
-	
-	* sched.c: New file.
-	(pthread_setschedparam): Implement.
-	(pthread_getschedparam): Implement.
-	(sched_get_priority_max): Validate policy argument.
-	(sched_get_priority_min): Likewise.
-
-	* mutex.c (pthread_mutexattr_setprotocol): Remove; not supported.
-	(pthread_mutexattr_getprotocol): Likewise.
-	(pthread_mutexattr_setprioceiling): Likewise.
-	(pthread_mutexattr_getprioceiling): Likewise.
-
-Fri Jul 24 00:21:21 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* create.c (pthread_create): Arg to ptw32_new_thread_entry()
-	changed. See next entry. Move mutex locks out. Changes made yesterday
-	and today allow us to start the new thread running rather than
-	temporarily suspended.
-
-	* private.c (ptw32_new_thread_entry): ptw32_thread_table
-	was changed back to a table of thread structures rather than pointers.
-	As such we're trading storage for increaded speed. This routine
-	was modified to work with the new table. Mutex lock put in around
-	global data accesses.
-	(ptw32_find_thread_entry): Ditto
-	(ptw32_delete_thread_entry): Ditto
-
-Thu Jul 23 23:25:30 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* global.c: New. Global data objects declared here. These moved from
-	pthread.h.
-
-	* pthread.h: Move implementation hidden definitions into
-	implement.h.
-
-	* implement.h: Move implementation hidden definitions from
-	pthread.h. Add constants to index into the different handler stacks.
-
-	* cleanup.c (ptw32_handler_push): Simplify args. Restructure.
-	(ptw32_handler_pop): Simplify args. Restructure.
-	(ptw32_handler_pop_all): Simplify args. Restructure.
-
-Wed Jul 22 00:16:22 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* attr.c, implement.h, pthread.h, ChangeLog: Resolve CVS merge
-	conflicts.
-
-	* private.c (ptw32_find_thread_entry): Changes to return type
-	to support leaner ptw32_threads_table[] which now only stores
-	ptw32_thread_thread_t *.
-	(ptw32_new_thread_entry): Internal changes.
-	(ptw32_delete_thread_entry): Internal changes to avoid contention.
- 	Calling routines changed accordingly.
-
-	* pthread.h: Modified cleanup macros to use new generic push and pop.
-	Added destructor and atfork stacks to ptw32_threads_thread_t.
-
-	* cleanup.c (ptw32_handler_push, ptw32_handler_pop,
-	ptw32_handler_pop_all): Renamed cleanup push and pop routines
-	and made generic to handle destructors and atfork handlers as
-	well.
-
-	* create.c (ptw32_start_call): New function is a wrapper for
-	all new threads. It allows us to do some cleanup when the thread
-	returns, ie. that is otherwise only done if the thread is cancelled.
-
-	* exit.c (ptw32_vacuum): New function contains code from 
-	pthread_exit() that we need in the new ptw32_start_call()
-	as well.
-
-	* implement.h: Various additions and minor changes.
-
-	* pthread.h: Various additions and minor changes.
-	Change cleanup handler macros to use generic handler push and pop
-	functions.
-
-	* attr.c: Minor mods to all functions.
-	(is_attr): Implemented missing function.
-
-	* create.c (pthread_create): More clean up.
-
-	* private.c (ptw32_find_thread_entry): Implement.
-	(ptw32_delete_thread_entry): Implement.
-	(ptw32_new_thread_entry): Implement.
-	These functions manipulate the implementations internal thread
-	table and are part of general code cleanup and modularisation.
-	They replace ptw32_getthreadindex() which was removed.
-
-	* exit.c (pthread_exit): Changed to use the new code above.
-
-	* pthread.h: Add cancelability constants. Update comments.
-
-1998-07-22  Ben Elliston  <bje at cygnus.com>
-
-	* attr.c (pthread_setstacksize): Update test of attr argument.
-	(pthread_getstacksize): Likewise.
-	(pthread_setstackaddr): Likewise.
-	(pthread_getstackaddr): Likewise.
-	(pthread_attr_init): No need to allocate any storage.
-	(pthread_attr_destroy): No need to free any storage.
-
-	* mutex.c (is_attr): Not likely to be needed; remove.
-	(remove_attr): Likewise.
-	(insert_attr): Likewise.
-
-	* implement.h (ptw32_mutexattr_t): Moved to a public definition
-	in pthread.h.  There was little gain in hiding these details.
-	(ptw32_condattr_t): Likewise.
-	(ptw32_attr_t): Likewise.
-
-	* pthread.h (pthread_atfork): Add function prototype.
-	(pthread_attr_t): Moved here from implement.h.
-
-	* fork.c (pthread_atfork): Preliminary implementation.
-	(ptw32_fork): Likewise.
-
-Wed Jul 22 00:16:22 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* cleanup.c (ptw32_cleanup_push): Implement.
-	(ptw32_cleanup_pop): Implement.
-	(ptw32_do_cancellation): Implement.
-	These are private to the implementation. The real cleanup functions
-	are macros. See below.
-
-	* pthread.h (pthread_cleanup_push): Implement as a macro.
-	(pthread_cleanup_pop): Implement as a macro.
-	Because these are macros which start and end a block, the POSIX scoping
-	requirement is observed. See the comment in the file.
-
-	* exit.c (pthread_exit): Refine the code.
-
-	* create.c (pthread_create): Code cleanup.
-
-	* implement.h (RND_SIZEOF): Add RND_SIZEOF(T) to round sizeof(T)
-	up to multiple of DWORD.
-	Add function prototypes.
-
-	* private.c (ptw32_getthreadindex): "*thread" should have been 
-	"thread". Detect empty slot fail condition.
-
-1998-07-20  Ben Elliston  <bje at cygnus.com>
-
-	* misc.c (pthread_once): Implement.  Don't use a per-application
-	flag and mutex--make `pthread_once_t' contain these elements in
-	their structure.  The earlier version had incorrect semantics.
-	
-	* pthread.h (ptw32_once_flag): Add new variable.  Remove.
-	(ptw32_once_lock): Add new mutex lock to ensure integrity of
-	access to ptw32_once_flag.  Remove.
-	(pthread_once): Add function prototype.
-	(pthread_once_t): Define this type.
-	
-Mon Jul 20 02:31:05 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_getthreadindex): Implement.
-
-	* pthread.h: Add application static data dependent on
-	_PTHREADS_BUILD_DLL define. This is needed to avoid allocating
-	non-sharable static data within the pthread DLL.
-
-	* implement.h: Add ptw32_cleanup_stack_t, ptw32_cleanup_node_t
-	and PTW32_HASH_INDEX.
-
-	* exit.c (pthread_exit): Begin work on cleanup and de-allocate
-	thread-private storage.
-
-	* create.c (pthread_create): Add thread to thread table.
-	Keep a thread-private copy of the attributes with default values
-	filled in when necessary. Same for the cleanup stack. Make 
-	pthread_create C run-time library friendly by using _beginthreadex()
-	instead of CreateThread(). Fix error returns.
-
-Sun Jul 19 16:26:23 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h: Rename pthreads_thread_count to ptw32_threads_count.
-	Create ptw32_threads_thread_t struct to keep thread specific data.
-
-	* create.c: Rename pthreads_thread_count to ptw32_threads_count.
-	(pthread_create): Handle errors from CreateThread().
-
-1998-07-19  Ben Elliston  <bje at cygnus.com>
-
-	* condvar.c (pthread_cond_wait): Generalise.  Moved from here ..
-	(cond_wait): To here.
-	(pthread_cond_timedwait): Implement; use generalised cond_wait().
-
-	* pthread.h (pthread_key_t): Define this type.
-	(pthread_key_create): Add function prototype.
-	(pthread_setspecific): Likewise.
-	(pthread_getspecific): Likwise.
-	(pthread_key_delete): Likewise.
-
-	* tsd.c (pthread_key_create): Implement.
-	(pthread_setspecific): Likewise.
-	(pthread_getspecific): Likewise.
-	(pthread_key_delete): Likewise.
-
-	* mutex.c (pthread_mutex_trylock): Return ENOSYS if this function
-	is called on a Win32 platform which is not Windows NT.
-
-1998-07-18  Ben Elliston  <bje at cygnus.com>
-
-	* condvar.c (pthread_condattr_init): Do not attempt to malloc any
-	storage; none is needed now that condattr_t is an empty struct.
-	(pthread_condattr_destory): Likewise; do not free storage.
-	(pthread_condattr_setpshared): No longer supported; return ENOSYS.
-	(pthread_condattr_getpshared): Likewise.
-	(pthread_cond_init): Implement with help from Douglas Schmidt.
-	Remember to initialise the cv's internal mutex.
-	(pthread_cond_wait): Likewise.
-	(pthread_cond_signal): Likewise.
-	(pthread_cond_broadcast): Likewise.
-	(pthread_cond_timedwait): Preliminary implementation, but I need
-	to see some API documentation for `WaitForMultipleObject'.
-	(pthread_destory): Implement.
-
-	* pthread.h (pthread_cond_init): Add function protoype.
-	(pthread_cond_broadcast): Likewise.
-	(pthread_cond_signal): Likewise.
-	(pthread_cond_timedwait): Likewise.
-	(pthread_cond_wait): Likewise.
-	(pthread_cond_destroy): Likewise.
-	(pthread_cond_t): Define this type.  Fix for u_int.  Do not assume
-	that the mutex contained withing the pthread_cond_t structure will
-	be a critical section.  Use our new POSIX type!
-
-	* implement.h (ptw32_condattr_t): Remove shared attribute.
-
-1998-07-17  Ben Elliston  <bje at cygnus.com>
-
-	* pthread.h (PTHREADS_PROCESS_PRIVATE): Remove.
-	(PTHREAD_PROCESS_SHARED): Likewise.  No support for mutexes shared
-	across processes for now.
-	(pthread_mutex_t): Use a Win32 CRITICAL_SECTION type for better
-	performance.
-	
-	* implement.h (ptw32_mutexattr_t): Remove shared attribute.
-	
-	* mutex.c (pthread_mutexattr_setpshared): This optional function
-	is no longer supported, since we want to implement POSIX mutex
-	variables using the much more efficient Win32 critical section
-	primitives.  Critical section objects in Win32 cannot be shared
-	between processes.
-	(pthread_mutexattr_getpshared): Likewise.
-	(pthread_mutexattr_init): No need to malloc any storage; the
-	attributes structure is now empty.
-	(pthread_mutexattr_destroy): This is now a nop.
-	(pthread_mutex_init): Use InitializeCriticalSection().
-	(pthread_mutex_destroy): Use DeleteCriticalSection().
-	(pthread_mutex_lock): Use EnterCriticalSection().
-	(pthread_mutex_trylock): Use TryEnterCriticalSection().  This is
-	not supported by Windows 9x, but trylock is a hack anyway, IMHO.
-	(pthread_mutex_unlock): Use LeaveCriticalSection().
-
-1998-07-14  Ben Elliston  <bje at cygnus.com>
-
-	* attr.c (pthread_attr_setstacksize): Implement.
-	(pthread_attr_getstacksize): Likewise.
-	(pthread_attr_setstackaddr): Likewise.
-	(pthread_attr_getstackaddr): Likewise.
-	(pthread_attr_init): Likewise.
-	(pthread_attr_destroy): Likewise.
-	
-	* condvar.c (pthread_condattr_init): Add `_cond' to function name.
-
-	* mutex.c (pthread_mutex_lock): Add `_mutex' to function name.
-	(pthread_mutex_trylock): Likewise.
-	(pthread_mutex_unlock): Likewise.
-
-	* pthread.h (pthread_condattr_setpshared): Fix typo.
-	(pthread_attr_init): Add function prototype.
-	(pthread_attr_destroy): Likewise.
-	(pthread_attr_setstacksize): Likewise.
-	(pthread_attr_getstacksize): Likewise.
-	(pthread_attr_setstackaddr): Likewise.
-	(pthread_attr_getstackaddr): Likewise.
-	
-Mon Jul 13 01:09:55 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h: Wrap in #ifndef _IMPLEMENT_H
-
-	* create.c (pthread_create): Map stacksize attr to Win32.
-
-	* mutex.c: Include implement.h
-
-1998-07-13  Ben Elliston  <bje at cygnus.com>
-
-	* condvar.c (pthread_condattr_init): Implement.
-	(pthread_condattr_destroy): Likewise.
-	(pthread_condattr_setpshared): Likewise.
-	(pthread_condattr_getpshared): Likewise.
-	
-	* implement.h (PTHREAD_THREADS_MAX): Remove trailing semicolon.
-	(PTHREAD_STACK_MIN): Specify; needs confirming.
-	(ptw32_attr_t): Define this type.
-	(ptw32_condattr_t): Likewise.
-
-	* pthread.h (pthread_mutex_t): Define this type.
-	(pthread_condattr_t): Likewise.
-	(pthread_mutex_destroy): Add function prototype.
-	(pthread_lock): Likewise.
-	(pthread_trylock): Likewise.
-	(pthread_unlock): Likewise.
-	(pthread_condattr_init): Likewise.
-	(pthread_condattr_destroy): Likewise.
-	(pthread_condattr_setpshared): Likewise.
-	(pthread_condattr_getpshared): Likewise.
-
-	* mutex.c (pthread_mutex_init): Implement.
-	(pthread_mutex_destroy): Likewise.
-	(pthread_lock): Likewise.
-	(pthread_trylock): Likewise.
-	(pthread_unlock): Likewise.
-
-1998-07-12  Ben Elliston  <bje at cygnus.com>
-
-	* implement.h (ptw32_mutexattr_t): Define this implementation
-	internal type.  Application programmers only see a mutex attribute
-	object as a void pointer.
-
-	* pthread.h (pthread_mutexattr_t): Define this type.
-	(pthread_mutexattr_init): Add function prototype.
-	(pthread_mutexattr_destroy): Likewise.
-	(pthread_mutexattr_setpshared): Likewise.
-	(pthread_mutexattr_getpshared): Likewise.
-	(pthread_mutexattr_setprotocol): Likewise.
-	(pthread_mutexattr_getprotocol): Likewise.
-	(pthread_mutexattr_setprioceiling): Likewise.
-	(pthread_mutexattr_getprioceiling): Likewise.
-	(PTHREAD_PROCESS_PRIVATE): Define.
-	(PTHREAD_PROCESS_SHARED): Define.
-
-	* mutex.c (pthread_mutexattr_init): Implement.
-	(pthread_mutexattr_destroy): Implement.
-	(pthread_mutexattr_setprotocol): Implement.
-	(pthread_mutexattr_getprotocol): Likewise.
-	(pthread_mutexattr_setprioceiling): Likewise.
-	(pthread_mutexattr_getprioceiling): Likewise.
-	(pthread_mutexattr_setpshared): Likewise.
-	(pthread_mutexattr_getpshared): Likewise.
-	(insert_attr): New function; very preliminary implementation!
-	(is_attr): Likewise.
-	(remove_attr): Likewise.
-	
-Sat Jul 11 14:48:54 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* implement.h: Preliminary implementation specific defines.
-
-	* create.c (pthread_create): Preliminary implementation.
-
-1998-07-11  Ben Elliston  <bje at cygnus.com>
-
-	* sync.c (pthread_join): Implement.
-
-	* misc.c (pthread_equal): Likewise.
-	
-	* pthread.h (pthread_join): Add function prototype.
-	(pthread_equal): Likewise.
-	
-1998-07-10  Ben Elliston  <bje at cygnus.com>
-
-	* misc.c (pthread_self): Implement.
-
-	* exit.c (pthread_exit): Implement.
-
-	* pthread.h (pthread_exit): Add function prototype.
-	(pthread_self): Likewise.
-	(pthread_t): Define this type.
-
-1998-07-09  Ben Elliston  <bje at cygnus.com>
-
-	* create.c (pthread_create): A dummy stub right now.
-
-	* pthread.h (pthread_create): Add function prototype.
diff --git a/deps/w32-pthreads/FAQ b/deps/w32-pthreads/FAQ
deleted file mode 100644
index cb1786c..0000000
--- a/deps/w32-pthreads/FAQ
+++ /dev/null
@@ -1,451 +0,0 @@
-		  =========================================
-		  PTHREADS-WIN32 Frequently Asked Questions
-		  =========================================
-
-INDEX
------
-
-Q 1	What is it?
-
-Q 2	Which of the several dll versions do I use?
-	or,
-	What are all these pthread*.dll and pthread*.lib files?
-
-Q 3	What is the library naming convention?
-
-Q 4	Cleanup code default style or: it used to work when I built
-	the library myself, but now it doesn't - why?
-
-Q 5	Why is the default library version now less exception-friendly?
-
-Q 6	Should I use Cygwin or Mingw32 as a development environment?
-
-Q 7	Now that pthreads-win32 builds under Mingw32, why do I get
-	memory access violations (segfaults)?
-
-Q 8	How do I use pthread.dll for Win32 (Visual C++ 5.0)
-
-Q 9	Cancelation doesn't work for me, why?
-
-Q 10	How do I generate pthreadGCE.dll and libpthreadw32.a for use
-	with Mingw32?
-
-Q 11    Why isn't pthread_t defined as a scalar (e.g. pointer or int)
-        like it is for other POSIX threads implementations?
-
-=============================================================================
-
-Q 1	What is it?
----
-
-Pthreads-win32 is an Open Source Software implementation of the
-Threads component of the POSIX 1003.1c 1995 Standard for Microsoft's
-Win32 environment. Some functions from POSIX 1003.1b are also
-supported including semaphores. Other related functions include
-the set of read-write lock functions. The library also supports
-some of the functionality of the Open Group's Single Unix
-specification, version 2, namely mutex types.
-
-See the file "ANNOUNCE" for more information including standards
-conformance details and list of supported routines.
-
-
-------------------------------------------------------------------------------
-
-Q 2	Which of the several dll versions do I use?
----	or,
-	What are all these pthread*.dll and pthread*.lib files?
-
-Simply, you only use one of them, but you need to choose carefully.
-
-The most important choice you need to make is whether to use a
-version that uses exceptions internally, or not (there are versions
-of the library that use exceptions as part of the thread
-cancelation and cleanup implementation, and one that uses
-setjmp/longjmp instead).
-
-There is some contension amongst POSIX threads experts as
-to how POSIX threads cancelation and exit should work
-with languages that include exceptions and handlers, e.g.
-C++ and even C (Microsoft's Structured Exceptions).
-
-The issue is: should cancelation of a thread in, say,
-a C++ application cause object destructors and C++ exception
-handlers to be invoked as the stack unwinds during thread
-exit, or not?
-
-There seems to be more opinion in favour of using the
-standard C version of the library (no EH) with C++ applications
-since this appears to be the assumption commercial pthreads
-implementations make. Therefore, if you use an EH version
-of pthreads-win32 then you may be under the illusion that
-your application will be portable, when in fact it is likely to
-behave very differently linked with other pthreads libraries.
-
-Now you may be asking: why have you kept the EH versions of
-the library?
-
-There are a couple of reasons:
-- there is division amongst the experts and so the code may
-  be needed in the future. (Yes, it's in the repository and we
-  can get it out anytime in the future, but ...)
-- pthreads-win32 is one of the few implementations, and possibly
-  the only freely available one, that has EH versions. It may be
-  useful to people who want to play with or study application
-  behaviour under these conditions.
-
-
-------------------------------------------------------------------------------
-
-Q 3	What is the library naming convention?
----
-
-Because the library is being built using various exception
-handling schemes and compilers - and because the library
-may not work reliably if these are mixed in an application,
-each different version of the library has it's own name.
-
-Note 1: the incompatibility is really between EH implementations
-of the different compilers. It should be possible to use the
-standard C version from either compiler with C++ applications
-built with a different compiler. If you use an EH version of
-the library, then you must use the same compiler for the
-application. This is another complication and dependency that
-can be avoided by using only the standard C library version.
-
-Note 2: if you use a standard C pthread*.dll with a C++
-application, then any functions that you define that are
-intended to be called via pthread_cleanup_push() must be
-__cdecl.
-
-Note 3: the intention is to also name either the VC or GC
-version (it should be arbitrary) as pthread.dll, including
-pthread.lib and libpthread.a as appropriate.
-
-In general:
-	pthread[VG]{SE,CE,C}.dll
-	pthread[VG]{SE,CE,C}.lib
-
-where:
-	[VG] indicates the compiler
-	V	- MS VC
-	G	- GNU C
-
-	{SE,CE,C} indicates the exception handling scheme
-	SE	- Structured EH
-	CE	- C++ EH
-	C	- no exceptions - uses setjmp/longjmp
-
-For example:
-	pthreadVSE.dll	(MSVC/SEH)
-	pthreadGCE.dll	(GNUC/C++ EH)
-	pthreadGC.dll	(GNUC/not dependent on exceptions)
-
-The GNU library archive file names have changed to:
-
-	libpthreadGCE.a
-	libpthreadGC.a
-
-
-------------------------------------------------------------------------------
-
-Q 4	Cleanup code default style or: it used to work when I built
----	the library myself, but now it doesn't - why?
-
-Up to and including snapshot 2001-07-12, if not defined, the cleanup
-style was determined automatically from the compiler used, and one
-of the following was defined accordingly:
-
-	__CLEANUP_SEH	MSVC only
-	__CLEANUP_CXX	C++, including MSVC++, GNU G++
-	__CLEANUP_C		C, including GNU GCC, not MSVC
-
-These defines determine the style of cleanup (see pthread.h) and,
-most importantly, the way that cancelation and thread exit (via
-pthread_exit) is performed (see the routine ptw32_throw() in private.c).
-
-In short, the exceptions versions of the library throw an exception
-when a thread is canceled or exits (via pthread_exit()), which is
-caught by a handler in the thread startup routine, so that the
-the correct stack unwinding occurs regardless of where the thread
-is when it's canceled or exits via pthread_exit().
-
-After snapshot 2001-07-12, unless your build explicitly defines (e.g.
-via a compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
-the build now ALWAYS defaults to __CLEANUP_C style cleanup. This style
-uses setjmp/longjmp in the cancelation and pthread_exit implementations,
-and therefore won't do stack unwinding even when linked to applications
-that have it (e.g. C++ apps). This is for consistency with most/all
-commercial Unix POSIX threads implementations.
-
-Although it was not clearly documented before, it is still necessary to
-build your application using the same __CLEANUP_* define as was
-used for the version of the library that you link with, so that the
-correct parts of pthread.h are included. That is, the possible
-defines require the following library versions:
-
-	__CLEANUP_SEH	pthreadVSE.dll
-	__CLEANUP_CXX	pthreadVCE.dll or pthreadGCE.dll
-	__CLEANUP_C		pthreadVC.dll or pthreadGC.dll
-
-THE POINT OF ALL THIS IS: if you have not been defining one of these
-explicitly, then the defaults have been set according to the compiler
-and language you are using, as described at the top of this
-section.
-
-THIS NOW CHANGES, as has been explained above. For example:
-
-If you were building your application with MSVC++ i.e. using C++
-exceptions (rather than SEH) and not explicitly defining one of
-__CLEANUP_*, then __CLEANUP_C++ was defined for you in pthread.h.
-You should have been linking with pthreadVCE.dll, which does
-stack unwinding.
-
-If you now build your application as you had before, pthread.h will now
-set __CLEANUP_C as the default style, and you will need to link
-with pthreadVC.dll. Stack unwinding will now NOT occur when a
-thread is canceled, nor when the thread calls pthread_exit().
-
-Your application will now most likely behave differently to previous
-versions, and in non-obvious ways. Most likely is that local
-objects may not be destroyed or cleaned up after a thread
-is canceled.
-
-If you want the same behaviour as before, then you must now define
-__CLEANUP_C++ explicitly using a compiler option and link with
-pthreadVCE.dll as you did before.
-
-
-------------------------------------------------------------------------------
-
-Q 5	Why is the default library version now less exception-friendly?
----
-
-Because most commercial Unix POSIX threads implementations don't allow you to
-choose to have stack unwinding. (Compaq's TRU64 Unix is possibly an exception.)
-
-Therefore, providing it in pthread-win32 as a default could be dangerous
-and non-portable. We still provide the choice but you must now consciously
-make it.
-
-WHY NOT REMOVE THE EXCEPTIONS VERSIONS OF THE LIBRARY ALTOGETHER?
-There are a few reasons:
-- because there are well respected POSIX threads people who believe
-  that POSIX threads implementations should be exceptions-aware and
-  do the expected thing in that context. (There are equally respected
-  people who believe it should not be easily accessible, if it's there
-  at all.)
-- because pthreads-win32 is one of the few implementations that has
-  the choice, perhaps the only freely available one, and so offers
-  a laboratory to people who may want to explore the effects;
-- although the code will always be around somewhere for anyone who
-  wants it, once it's removed from the current version it will not be
-  nearly as visible to people who may have a use for it.
-
-
-------------------------------------------------------------------------------
-
-Q 6	Should I use Cygwin or Mingw32 as a development environment?
----
-
-Important: see Q7 also.
-
-Use Mingw32 with the MSVCRT library to build applications that use
-the pthreads DLL.
-
-Cygwin's own internal support for POSIX threads is growing.
-Consult that project's documentation for more information.
-
-------------------------------------------------------------------------------
-
-Q 7	Now that pthreads-win32 builds under Mingw32, why do I get
----	memory access violations (segfaults)?
-
-The latest Mingw32 package has thread-safe exception handling (see Q10).
-Also, see Q6 above.
-
-------------------------------------------------------------------------------
-
-Q 8	How do I use pthread.dll for Win32 (Visual C++ 5.0)
----	
-
->
-> I'm a "rookie" when it comes to your pthread implementation.	I'm currently
-> desperately trying to install the prebuilt .dll file into my MSVC compiler.
-> Could you please provide me with explicit instructions on how to do this (or
-> direct me to a resource(s) where I can acquire such information)?
->
-> Thank you,
->
-
-You should have a .dll, .lib, .def, and three .h files. It is recommended
-that you use pthreadVC.dll, rather than pthreadVCE.dll or pthreadVSE.dll
-(see Q2 above).
-
-The .dll can go in any directory listed in your PATH environment
-variable, so putting it into C:\WINDOWS should work.
-
-The .lib file can go in any directory listed in your LIB environment
-variable.
-
-The .h files can go in any directory listed in your INCLUDE
-environment variable.
-
-Or you might prefer to put the .lib and .h files into a new directory
-and add its path to LIB and INCLUDE. You can probably do this easiest
-by editing the file:-
-
-C:\Program Files\DevStudio\vc\bin\vcvars32.bat
-
-The .def file isn't used by anything in the pre-compiled version but 
-is included for information.
-
-Cheers.
-Ross
-
-------------------------------------------------------------------------------
-
-Q 9	Cancelation doesn't work for me, why?
----
-
-> I'm investigating a problem regarding thread cancelation. The thread I want
-> to cancel has PTHREAD_CANCEL_ASYNCHRONOUS, however, this piece of code
-> blocks on the join():
->
->		if ((retv = Pthread_cancel( recvThread )) == 0)
->		{
->			retv = Pthread_join( recvThread, 0 );
->		}
->
-> Pthread_* are just macro's; they call pthread_*.
->
-> The thread recvThread seems to block on a select() call. It doesn't get
-> cancelled.
->
-> Two questions:
->
-> 1) is this normal behaviour?
->
-> 2) if not, how does the cancel mechanism work? I'm not very familliar to
-> win32 programming, so I don't really understand how the *Event() family of
-> calls work.
-
-The answer to your first question is, normal POSIX behaviour would  
-be to asynchronously cancel the thread. However, even that doesn't
-guarantee cancelation as the standard only says it should be
-cancelled as soon as possible.
-
-Snapshot 99-11-02 or earlier only partially supports asynchronous cancellation.
-Snapshots since then simulate async cancelation by poking the address of
-a cancelation routine into the PC of the threads context. This requires
-the thread to be resumed in some way for the cancelation to actually
-proceed. This is not true async cancelation, but it is as close as we've
-been able to get to it.
-
-If the thread you're trying to cancel is blocked (for instance, it could be
-waiting for data from the network), it will only get cancelled when it unblocks
-(when the data arrives). For true pre-emptive cancelation in these cases,
-pthreads-win32 from snapshot 2004-05-16 can automatically recognise and use the
-QueueUserAPCEx package by Panagiotis E. Hadjidoukas. This package is available
-from the pthreads-win32 ftp site and is included in the pthreads-win32
-self-unpacking zip from 2004-05-16 onwards.
-
-Using deferred cancelation would normally be the way to go, however,
-even though the POSIX threads standard lists a number of C library
-functions that are defined as deferred cancelation points, there is
-no hookup between those which are provided by Windows and the
-pthreads-win32 library.
-
-Incidently, it's worth noting for code portability that the older POSIX
-threads standards cancelation point lists didn't include "select" because
-(as I read in Butenhof) it wasn't part of POSIX. However, it does appear in
-the SUSV3.
-
-Effectively, the only mandatory cancelation points that pthreads-win32
-recognises are those the library implements itself, ie.
-	
-	pthread_testcancel
-	pthread_cond_wait
-	pthread_cond_timedwait
-	pthread_join
-	sem_wait
-	sem_timedwait
-	pthread_delay_np
-
-The following routines from the non-mandatory list in SUSV3 are
-cancelation points in pthreads-win32:
-
-	pthread_rwlock_wrlock
-	pthread_rwlock_timedwrlock
-
-The following routines from the non-mandatory list in SUSV3 are not
-cancelation points in pthreads-win32:
-
-	pthread_rwlock_rdlock
-	pthread_rwlock_timedrdlock
-
-Pthreads-win32 also provides two functions that allow you to create
-cancelation points within your application, but only for cases where
-a thread is going to block on a Win32 handle. These are:
-
-	pthreadCancelableWait(HANDLE waitHandle) /* Infinite wait */
- 
-	pthreadCancelableTimedWait(HANDLE waitHandle, DWORD timeout)
-
-------------------------------------------------------------------------------
- 
-
-Q 10	How do I create thread-safe applications using
-----	pthreadGCE.dll, libpthreadw32.a and Mingw32?
-
-This should not be a problem with recent versions of MinGW32.
-
-For early versions, see Thomas Pfaff's email at:
-http://sources.redhat.com/ml/pthreads-win32/2002/msg00000.html
-------------------------------------------------------------------------------
-
-Q 11    Why isn't pthread_t defined as a scalar (e.g. pointer or int)
-        like it is for other POSIX threads implementations?
-----
-
-Originally pthread_t was defined as a pointer (to the opaque pthread_t_
-struct) and later it was changed to a struct containing the original
-pointer plus a sequence counter. This is allowed under both the original
-POSIX Threads Standard and the current Single Unix Specification.
-
-When pthread_t is a simple pointer to a struct some very difficult to
-debug problems arise from the process of freeing and later allocing
-thread structs because new pthread_t handles can acquire the identity of
-previously detached threads. The change to a struct was made, along with
-some changes to their internal managment, in order to guarantee (for
-practical applications) that the pthread_t handle will be unique over the
-life of the running process.
-
-Where application code attempts to compare one pthread_t against another
-directly, a compiler error will be emitted because structs can't be
-compared at that level. This should signal a potentially serious problem
-in the code design, which would go undetected if pthread_t was a scalar.
-
-The POSIX Threading API provides a function named pthread_equal() to
-compare pthread_t thread handles.
-
-Other pthreads implementations, such as Sun's, use an int as the handle
-but do guarantee uniqueness within the process scope. Win32 scalar typed
-thread handles also guarantee uniqueness in system scope. It wasn't clear
-how well the internal management of these handles would scale as the
-number of threads and the fragmentation of the sequence numbering
-increased for applications where thousands or millions of threads are
-created and detached over time. The current management of threads within
-pthreads-win32 using structs for pthread_t, and reusing without ever
-freeing them, reduces the management time overheads to a constant, which
-could be important given that pthreads-win32 threads are built on top of
-Win32 threads and will therefore include that management overhead on top
-of their own. The cost is that the memory resources used for thread
-handles will remain at the peak level until the process exits.
-
-While it may be inconvenient for developers to be forced away from making
-assumptions about the internals of pthread_t, the advantage for the
-future development of pthread-win32, as well as those applications that
-use it and other pthread implementations, is that the library is free to
-change pthread_t internals and management as better methods arise.
-
diff --git a/deps/w32-pthreads/GNUmakefile b/deps/w32-pthreads/GNUmakefile
deleted file mode 100644
index 9b92462..0000000
--- a/deps/w32-pthreads/GNUmakefile
+++ /dev/null
@@ -1,593 +0,0 @@
-#
-# --------------------------------------------------------------------------
-#
-#      Pthreads-win32 - POSIX Threads Library for Win32
-#      Copyright(C) 1998 John E. Bossom
-#      Copyright(C) 1999,2005 Pthreads-win32 contributors
-# 
-#      Contact Email: rpj at callisto.canberra.edu.au
-# 
-#      The current list of contributors is contained
-#      in the file CONTRIBUTORS included with the source
-#      code distribution. The list can also be seen at the
-#      following World Wide Web location:
-#      http://sources.redhat.com/pthreads-win32/contributors.html
-# 
-#      This library is free software; you can redistribute it and/or
-#      modify it under the terms of the GNU Lesser General Public
-#      License as published by the Free Software Foundation; either
-#      version 2 of the License, or (at your option) any later version.
-# 
-#      This library is distributed in the hope that it will be useful,
-#      but WITHOUT ANY WARRANTY; without even the implied warranty of
-#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#      Lesser General Public License for more details.
-# 
-#      You should have received a copy of the GNU Lesser General Public
-#      License along with this library in the file COPYING.LIB;
-#      if not, write to the Free Software Foundation, Inc.,
-#      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-#
-
-DLL_VER	= 2
-DLL_VERD= $(DLL_VER)d
-
-DEVROOT	= C:\PTHREADS
-
-DLLDEST	= $(DEVROOT)\DLL
-LIBDEST	= $(DEVROOT)\DLL
-
-# If Running MsysDTK
-RM	= rm -f
-MV	= mv -f
-CP	= cp -f
-
-# If not.
-#RM	= erase
-#MV	= rename
-#CP	= copy
-
-# For cross compiling use e.g.
-# make CROSS=x86_64-w64-mingw32- clean GC-inlined
-CROSS	= 
-
-AR	= $(CROSS)ar
-DLLTOOL = $(CROSS)dlltool
-CC      = $(CROSS)gcc
-CXX     = $(CROSS)g++
-RANLIB  = $(CROSS)ranlib
-RC	= $(CROSS)windres
-
-OPT	= $(CLEANUP) -O3 # -finline-functions -findirect-inlining
-XOPT	=
-
-RCFLAGS		= --include-dir=.
-# Uncomment this if config.h defines RETAIN_WSALASTERROR
-#LFLAGS		= -lws2_32
-
-# ----------------------------------------------------------------------
-# The library can be built with some alternative behaviour to
-# facilitate development of applications on Win32 that will be ported
-# to other POSIX systems. Nothing definable here will make the library
-# non-compliant, but applications that make assumptions that POSIX
-# does not garrantee may fail or misbehave under some settings.
-#
-# PTW32_THREAD_ID_REUSE_INCREMENT
-# Purpose:
-# POSIX says that applications should assume that thread IDs can be
-# recycled. However, Solaris and some other systems use a [very large]
-# sequence number as the thread ID, which provides virtual uniqueness.
-# Pthreads-win32 provides pseudo-unique IDs when the default increment
-# (1) is used, but pthread_t is not a scalar type like Solaris's.
-#
-# Usage:
-# Set to any value in the range: 0 <= value <= 2^wordsize
-#
-# Examples:
-# Set to 0 to emulate non recycle-unique behaviour like Linux or *BSD.
-# Set to 1 for recycle-unique thread IDs (this is the default).
-# Set to some other +ve value to emulate smaller word size types
-# (i.e. will wrap sooner).
-#
-#PTW32_FLAGS	= "-DPTW32_THREAD_ID_REUSE_INCREMENT=0"
-#
-# ----------------------------------------------------------------------
-
-GC_CFLAGS	= $(PTW32_FLAGS) 
-GCE_CFLAGS	= $(PTW32_FLAGS) -mthreads
-
-## Mingw
-MAKE		?= make
-CFLAGS	= $(OPT) $(XOPT) -I. -DHAVE_PTW32_CONFIG_H -Wall
-
-DLL_INLINED_OBJS	= \
-		pthread.o \
-		version.o
-
-# Agregate modules for inlinability
-DLL_OBJS	= \
-		attr.o \
-		barrier.o \
-		cancel.o \
-		cleanup.o \
-		condvar.o \
-		create.o \
-		dll.o \
-		errno.o \
-		exit.o \
-		fork.o \
-		global.o \
-		misc.o \
-		mutex.o \
-		nonportable.o \
-		private.o \
-		rwlock.o \
-		sched.o \
-		semaphore.o \
-		signal.o \
-		spin.o \
-		sync.o \
-		tsd.o \
-		version.o
-
-# Separate modules for minimum size statically linked images
-SMALL_STATIC_OBJS	= \
-		pthread_attr_init.o \
-		pthread_attr_destroy.o \
-		pthread_attr_getdetachstate.o \
-		pthread_attr_setdetachstate.o \
-		pthread_attr_getstackaddr.o \
-		pthread_attr_setstackaddr.o \
-		pthread_attr_getstacksize.o \
-		pthread_attr_setstacksize.o \
-		pthread_attr_getscope.o \
-		pthread_attr_setscope.o \
-		pthread_attr_setschedpolicy.o \
-		pthread_attr_getschedpolicy.o \
-		pthread_attr_setschedparam.o \
-		pthread_attr_getschedparam.o \
-		pthread_attr_setinheritsched.o \
-		pthread_attr_getinheritsched.o \
-		pthread_barrier_init.o \
-		pthread_barrier_destroy.o \
-		pthread_barrier_wait.o \
-		pthread_barrierattr_init.o \
-		pthread_barrierattr_destroy.o \
-		pthread_barrierattr_setpshared.o \
-		pthread_barrierattr_getpshared.o \
-		pthread_setcancelstate.o \
-		pthread_setcanceltype.o \
-		pthread_testcancel.o \
-		pthread_cancel.o \
-		cleanup.o \
-		pthread_condattr_destroy.o \
-		pthread_condattr_getpshared.o \
-		pthread_condattr_init.o \
-		pthread_condattr_setpshared.o \
-		pthread_cond_destroy.o \
-		pthread_cond_init.o \
-		pthread_cond_signal.o \
-		pthread_cond_wait.o \
-		create.o \
-		dll.o \
-		autostatic.o \
-		errno.o \
-		pthread_exit.o \
-		fork.o \
-		global.o \
-		pthread_mutex_init.o \
-		pthread_mutex_destroy.o \
-		pthread_mutexattr_init.o \
-		pthread_mutexattr_destroy.o \
-		pthread_mutexattr_getpshared.o \
-		pthread_mutexattr_setpshared.o \
-		pthread_mutexattr_settype.o \
-		pthread_mutexattr_gettype.o \
-		pthread_mutexattr_setrobust.o \
-		pthread_mutexattr_getrobust.o \
-		pthread_mutex_lock.o \
-		pthread_mutex_timedlock.o \
-		pthread_mutex_unlock.o \
-		pthread_mutex_trylock.o \
-		pthread_mutex_consistent.o \
-		pthread_mutexattr_setkind_np.o \
-		pthread_mutexattr_getkind_np.o \
-		pthread_getw32threadhandle_np.o \
-		pthread_getunique_np.o \
-		pthread_delay_np.o \
-		pthread_num_processors_np.o \
-		pthread_win32_attach_detach_np.o \
-		pthread_equal.o \
-		pthread_getconcurrency.o \
-		pthread_once.o \
-		pthread_self.o \
-		pthread_setconcurrency.o \
-		pthread_rwlock_init.o \
-		pthread_rwlock_destroy.o \
-		pthread_rwlockattr_init.o \
-		pthread_rwlockattr_destroy.o \
-		pthread_rwlockattr_getpshared.o \
-		pthread_rwlockattr_setpshared.o \
-		pthread_rwlock_rdlock.o \
-		pthread_rwlock_wrlock.o \
-		pthread_rwlock_unlock.o \
-		pthread_rwlock_tryrdlock.o \
-		pthread_rwlock_trywrlock.o \
-		pthread_setschedparam.o \
-		pthread_getschedparam.o \
-		pthread_timechange_handler_np.o \
-		ptw32_is_attr.o \
-		ptw32_cond_check_need_init.o \
-		ptw32_MCS_lock.o \
-		ptw32_mutex_check_need_init.o \
-		ptw32_processInitialize.o \
-		ptw32_processTerminate.o \
-		ptw32_threadStart.o \
-		ptw32_threadDestroy.o \
-		ptw32_tkAssocCreate.o \
-		ptw32_tkAssocDestroy.o \
-		ptw32_callUserDestroyRoutines.o \
-		ptw32_timespec.o \
-		ptw32_throw.o \
-		ptw32_getprocessors.o \
-		ptw32_calloc.o \
-		ptw32_new.o \
-		ptw32_reuse.o \
-		ptw32_semwait.o \
-		ptw32_relmillisecs.o \
-		ptw32_rwlock_check_need_init.o \
-		sched_get_priority_max.o \
-		sched_get_priority_min.o \
-		sched_setscheduler.o \
-		sched_getscheduler.o \
-		sched_yield.o \
-		sem_init.o \
-		sem_destroy.o \
-		sem_trywait.o \
-		sem_timedwait.o \
-		sem_wait.o \
-		sem_post.o \
-		sem_post_multiple.o \
-		sem_getvalue.o \
-		sem_open.o \
-		sem_close.o \
-		sem_unlink.o \
-		signal.o \
-		pthread_kill.o \
-		ptw32_spinlock_check_need_init.o \
-		pthread_spin_init.o \
-		pthread_spin_destroy.o \
-		pthread_spin_lock.o \
-		pthread_spin_unlock.o \
-		pthread_spin_trylock.o \
-		pthread_detach.o \
-		pthread_join.o \
-		pthread_key_create.o \
-		pthread_key_delete.o \
-		pthread_setspecific.o \
-		pthread_getspecific.o \
-		w32_CancelableWait.o \
-		version.o
-
-INCL	= \
-		config.h \
-		implement.h \
-		semaphore.h \
-		pthread.h \
-		need_errno.h
-
-ATTR_SRCS	= \
-		pthread_attr_init.c \
-		pthread_attr_destroy.c \
-		pthread_attr_getdetachstate.c \
-		pthread_attr_setdetachstate.c \
-		pthread_attr_getstackaddr.c \
-		pthread_attr_setstackaddr.c \
-		pthread_attr_getstacksize.c \
-		pthread_attr_setstacksize.c \
-		pthread_attr_getscope.c \
-		pthread_attr_setscope.c
-
-BARRIER_SRCS = \
-		pthread_barrier_init.c \
-		pthread_barrier_destroy.c \
-		pthread_barrier_wait.c \
-		pthread_barrierattr_init.c \
-		pthread_barrierattr_destroy.c \
-		pthread_barrierattr_setpshared.c \
-		pthread_barrierattr_getpshared.c
-
-CANCEL_SRCS	= \
-		pthread_setcancelstate.c \
-		pthread_setcanceltype.c \
-		pthread_testcancel.c \
-		pthread_cancel.c 
-
-CONDVAR_SRCS	= \
-		ptw32_cond_check_need_init.c \
-		pthread_condattr_destroy.c \
-		pthread_condattr_getpshared.c \
-		pthread_condattr_init.c \
-		pthread_condattr_setpshared.c \
-		pthread_cond_destroy.c \
-		pthread_cond_init.c \
-		pthread_cond_signal.c \
-		pthread_cond_wait.c
-
-EXIT_SRCS	= \
-		pthread_exit.c
-
-MISC_SRCS	= \
-		pthread_equal.c \
-		pthread_getconcurrency.c \
-		pthread_kill.c \
-		pthread_once.c \
-		pthread_self.c \
-		pthread_setconcurrency.c \
-		ptw32_calloc.c \
-		ptw32_MCS_lock.c \
-		ptw32_new.c \
-		ptw32_reuse.c \
-		w32_CancelableWait.c
-
-MUTEX_SRCS	= \
-		ptw32_mutex_check_need_init.c \
-		pthread_mutex_init.c \
-		pthread_mutex_destroy.c \
-		pthread_mutexattr_init.c \
-		pthread_mutexattr_destroy.c \
-		pthread_mutexattr_getpshared.c \
-		pthread_mutexattr_setpshared.c \
-		pthread_mutexattr_settype.c \
-		pthread_mutexattr_gettype.c \
-		pthread_mutexattr_setrobust.c \
-		pthread_mutexattr_getrobust.c \
-		pthread_mutex_lock.c \
-		pthread_mutex_timedlock.c \
-		pthread_mutex_unlock.c \
-		pthread_mutex_trylock.c \
-		pthread_mutex_consistent.c
-
-NONPORTABLE_SRCS = \
-		pthread_mutexattr_setkind_np.c \
-		pthread_mutexattr_getkind_np.c \
-		pthread_getw32threadhandle_np.c \
-                pthread_getunique_np.c \
-		pthread_delay_np.c \
-		pthread_num_processors_np.c \
-		pthread_win32_attach_detach_np.c \
-		pthread_timechange_handler_np.c 
-
-PRIVATE_SRCS	= \
-		ptw32_is_attr.c \
-		ptw32_processInitialize.c \
-		ptw32_processTerminate.c \
-		ptw32_threadStart.c \
-		ptw32_threadDestroy.c \
-		ptw32_tkAssocCreate.c \
-		ptw32_tkAssocDestroy.c \
-		ptw32_callUserDestroyRoutines.c \
-		ptw32_semwait.c \
-		ptw32_relmillisecs.c \
-		ptw32_timespec.c \
-		ptw32_throw.c \
-		ptw32_getprocessors.c
-
-RWLOCK_SRCS	= \
-		ptw32_rwlock_check_need_init.c \
-		ptw32_rwlock_cancelwrwait.c \
-		pthread_rwlock_init.c \
-		pthread_rwlock_destroy.c \
-		pthread_rwlockattr_init.c \
-		pthread_rwlockattr_destroy.c \
-		pthread_rwlockattr_getpshared.c \
-		pthread_rwlockattr_setpshared.c \
-		pthread_rwlock_rdlock.c \
-		pthread_rwlock_timedrdlock.c \
-		pthread_rwlock_wrlock.c \
-		pthread_rwlock_timedwrlock.c \
-		pthread_rwlock_unlock.c \
-		pthread_rwlock_tryrdlock.c \
-		pthread_rwlock_trywrlock.c
-
-SCHED_SRCS	= \
-		pthread_attr_setschedpolicy.c \
-		pthread_attr_getschedpolicy.c \
-		pthread_attr_setschedparam.c \
-		pthread_attr_getschedparam.c \
-		pthread_attr_setinheritsched.c \
-		pthread_attr_getinheritsched.c \
-		pthread_setschedparam.c \
-		pthread_getschedparam.c \
-		sched_get_priority_max.c \
-		sched_get_priority_min.c \
-		sched_setscheduler.c \
-		sched_getscheduler.c \
-		sched_yield.c
-
-SEMAPHORE_SRCS = \
-		sem_init.c \
-		sem_destroy.c \
-		sem_trywait.c \
-		sem_timedwait.c \
-		sem_wait.c \
-		sem_post.c \
-		sem_post_multiple.c \
-		sem_getvalue.c \
-		sem_open.c \
-		sem_close.c \
-		sem_unlink.c
-
-SPIN_SRCS	= \
-		ptw32_spinlock_check_need_init.c \
-		pthread_spin_init.c \
-		pthread_spin_destroy.c \
-		pthread_spin_lock.c \
-		pthread_spin_unlock.c \
-		pthread_spin_trylock.c
-
-SYNC_SRCS	= \
-		pthread_detach.c \
-		pthread_join.c
-
-TSD_SRCS	= \
-		pthread_key_create.c \
-		pthread_key_delete.c \
-		pthread_setspecific.c \
-		pthread_getspecific.c
-
-
-GCE_DLL	= pthreadGCE$(DLL_VER).dll
-GCED_DLL= pthreadGCE$(DLL_VERD).dll
-GCE_LIB	= libpthreadGCE$(DLL_VER).a
-GCED_LIB= libpthreadGCE$(DLL_VERD).a
-GCE_INLINED_STAMP = pthreadGCE$(DLL_VER).stamp
-GCED_INLINED_STAMP = pthreadGCE$(DLL_VERD).stamp
-GCE_STATIC_STAMP = libpthreadGCE$(DLL_VER).stamp
-GCED_STATIC_STAMP = libpthreadGCE$(DLL_VERD).stamp
-
-GC_DLL 	= pthreadGC$(DLL_VER).dll
-GCD_DLL	= pthreadGC$(DLL_VERD).dll
-GC_LIB	= libpthreadGC$(DLL_VER).a
-GCD_LIB	= libpthreadGC$(DLL_VERD).a
-GC_INLINED_STAMP = pthreadGC$(DLL_VER).stamp
-GCD_INLINED_STAMP = pthreadGC$(DLL_VERD).stamp
-GC_STATIC_STAMP = libpthreadGC$(DLL_VER).stamp
-GCD_STATIC_STAMP = libpthreadGC$(DLL_VERD).stamp
-
-PTHREAD_DEF	= pthread.def
-
-help:
-	@ echo "Run one of the following command lines:"
-	@ echo "make clean GC            (to build the GNU C dll with C cleanup code)"
-	@ echo "make clean GCE           (to build the GNU C dll with C++ exception handling)"
-	@ echo "make clean GC-inlined    (to build the GNU C inlined dll with C cleanup code)"
-	@ echo "make clean GCE-inlined   (to build the GNU C inlined dll with C++ exception handling)"
-	@ echo "make clean GC-static     (to build the GNU C inlined static lib with C cleanup code)"
-	@ echo "make clean GC-debug      (to build the GNU C debug dll with C cleanup code)"
-	@ echo "make clean GCE-debug     (to build the GNU C debug dll with C++ exception handling)"
-	@ echo "make clean GC-inlined-debug    (to build the GNU C inlined debug dll with C cleanup code)"
-	@ echo "make clean GCE-inlined-debug   (to build the GNU C inlined debug dll with C++ exception handling)"
-	@ echo "make clean GC-static-debug     (to build the GNU C inlined static debug lib with C cleanup code)"
-
-all:
-	@ $(MAKE) clean GCE
-	@ $(MAKE) clean GC
-
-GC:
-		$(MAKE) CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" $(GC_DLL)
-
-GC-debug:
-		$(MAKE) CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_DLL)
-
-GCE:
-		$(MAKE) CC=$(CXX) CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" $(GCE_DLL)
-
-GCE-debug:
-		$(MAKE) CC=$(CXX) CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_CXX -g -O0" $(GCED_DLL)
-
-GC-inlined:
-		$(MAKE) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_INLINED_STAMP)
-
-GC-inlined-debug:
-		$(MAKE) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_INLINED_STAMP)
-
-GCE-inlined:
-		$(MAKE) CC=$(CXX) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GCE_INLINED_STAMP)
-
-GCE-inlined-debug:
-		$(MAKE) CC=$(CXX) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_CXX -g -O0" $(GCED_INLINED_STAMP)
-
-GC-static:
-		$(MAKE) XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_STATIC_STAMP)
-
-GC-static-debug:
-		$(MAKE) XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_STATIC_STAMP)
-
-tests:
-	@ cd tests
-	@ $(MAKE) auto
-
-%.pre: %.c
-	$(CC) -E -o $@ $(CFLAGS) $^
-
-%.s: %.c
-	$(CC) -c $(CFLAGS) -DPTW32_BUILD_INLINED -Wa,-ahl $^ > $@
-
-%.o: %.rc
-	$(RC) $(RCFLAGS) $(CLEANUP) -o $@ -i $<
-
-.SUFFIXES: .dll .rc .c .o
-
-.c.o:;		 $(CC) -c -o $@ $(CFLAGS) $(XC_FLAGS) $<
-
-
-$(GC_DLL) $(GCD_DLL): $(DLL_OBJS)
-	$(CC) $(OPT) -shared -o $(GC_DLL) $(DLL_OBJS) $(LFLAGS)
-	$(DLLTOOL) -z pthread.def $(DLL_OBJS)
-	$(DLLTOOL) -k --dllname $@ --output-lib $(GC_LIB) --def $(PTHREAD_DEF)
-
-$(GCE_DLL): $(DLL_OBJS)
-	$(CC) $(OPT) -mthreads -shared -o $(GCE_DLL) $(DLL_OBJS) $(LFLAGS)
-	$(DLLTOOL) -z pthread.def $(DLL_OBJS)
-	$(DLLTOOL) -k --dllname $@ --output-lib $(GCE_LIB) --def $(PTHREAD_DEF)
-
-$(GC_INLINED_STAMP) $(GCD_INLINED_STAMP): $(DLL_INLINED_OBJS)
-	$(CC) $(OPT) $(XOPT) -shared -o $(GC_DLL) $(DLL_INLINED_OBJS) $(LFLAGS)
-	$(DLLTOOL) -z pthread.def $(DLL_INLINED_OBJS)
-	$(DLLTOOL) -k --dllname $(GC_DLL) --output-lib $(GC_LIB) --def $(PTHREAD_DEF)
-	echo touched > $(GC_INLINED_STAMP)
-
-$(GCE_INLINED_STAMP) $(GCED_INLINED_STAMP): $(DLL_INLINED_OBJS)
-	$(CC) $(OPT) $(XOPT) -mthreads -shared -o $(GCE_DLL) $(DLL_INLINED_OBJS)  $(LFLAGS)
-	$(DLLTOOL) -z pthread.def $(DLL_INLINED_OBJS)
-	$(DLLTOOL) -k --dllname $(GCE_DLL) --output-lib $(GCE_LIB) --def $(PTHREAD_DEF)
-	echo touched > $(GCE_INLINED_STAMP)
-
-$(GC_STATIC_STAMP) $(GCD_STATIC_STAMP): $(DLL_INLINED_OBJS)
-	$(RM) $(GC_LIB)
-	$(AR) -rv $(GC_LIB) $(DLL_INLINED_OBJS)
-	$(RANLIB) $(GC_LIB)
-	echo touched > $(GC_STATIC_STAMP)
-
-clean:
-	-$(RM) *~
-	-$(RM) *.i
-	-$(RM) *.s
-	-$(RM) *.o
-	-$(RM) *.obj
-	-$(RM) *.exe
-	-$(RM) $(PTHREAD_DEF)
-
-realclean: clean
-	-$(RM) $(GC_LIB)
-	-$(RM) $(GCE_LIB)
-	-$(RM) $(GC_DLL)
-	-$(RM) $(GCE_DLL)
-	-$(RM) $(GC_INLINED_STAMP)
-	-$(RM) $(GCE_INLINED_STAMP)
-	-$(RM) $(GC_STATIC_STAMP)
-	-$(RM) $(GCD_LIB)
-	-$(RM) $(GCED_LIB)
-	-$(RM) $(GCD_DLL)
-	-$(RM) $(GCED_DLL)
-	-$(RM) $(GCD_INLINED_STAMP)
-	-$(RM) $(GCED_INLINED_STAMP)
-	-$(RM) $(GCD_STATIC_STAMP)
-
-attr.o:		attr.c $(ATTR_SRCS) $(INCL)
-barrier.o:	barrier.c $(BARRIER_SRCS) $(INCL)
-cancel.o:	cancel.c $(CANCEL_SRCS) $(INCL)
-condvar.o:	condvar.c $(CONDVAR_SRCS) $(INCL)
-exit.o:		exit.c $(EXIT_SRCS) $(INCL)
-misc.o:		misc.c $(MISC_SRCS) $(INCL)
-mutex.o:	mutex.c $(MUTEX_SRCS) $(INCL)
-nonportable.o:	nonportable.c $(NONPORTABLE_SRCS) $(INCL)
-private.o:	private.c $(PRIVATE_SRCS) $(INCL)
-rwlock.o:	rwlock.c $(RWLOCK_SRCS) $(INCL)
-sched.o:	sched.c $(SCHED_SRCS) $(INCL)
-semaphore.o:	semaphore.c $(SEMAPHORE_SRCS) $(INCL)
-spin.o:		spin.c $(SPIN_SRCS) $(INCL)
-sync.o:		sync.c $(SYNC_SRCS) $(INCL)
-tsd.o:		tsd.c $(TSD_SRCS) $(INCL)
-version.o:	version.rc $(INCL)
diff --git a/deps/w32-pthreads/MAINTAINERS b/deps/w32-pthreads/MAINTAINERS
deleted file mode 100644
index d253c1f..0000000
--- a/deps/w32-pthreads/MAINTAINERS
+++ /dev/null
@@ -1,4 +0,0 @@
-CVS Repository maintainers
-
-Ross Johnson		rpj at ise.canberra.edu.au
-Ben Elliston		bje at cygnus.com
diff --git a/deps/w32-pthreads/Makefile b/deps/w32-pthreads/Makefile
deleted file mode 100644
index 472969c..0000000
--- a/deps/w32-pthreads/Makefile
+++ /dev/null
@@ -1,514 +0,0 @@
-# This makefile is compatible with MS nmake and can be used as a
-# replacement for buildlib.bat. I've changed the target from an ordinary dll
-# (/LD) to a debugging dll (/LDd).
-# 
-# The variables $DLLDEST and $LIBDEST hold the destination directories for the
-# dll and the lib, respectively. Probably all that needs to change is $DEVROOT.
-
-
-# DLL_VER:
-# See pthread.h and README - This number is computed as 'current - age'
-DLL_VER	= 2
-DLL_VERD= $(DLL_VER)d
-
-DEVROOT	= C:\pthreads
-
-DLLDEST	= $(DEVROOT)\dll
-LIBDEST	= $(DEVROOT)\lib
-HDRDEST	= $(DEVROOT)\include
-
-DLLS	= pthreadVCE$(DLL_VER).dll pthreadVSE$(DLL_VER).dll pthreadVC$(DLL_VER).dll \
-		  pthreadVCE$(DLL_VERD).dll pthreadVSE$(DLL_VERD).dll pthreadVC$(DLL_VERD).dll
-INLINED_STAMPS	= pthreadVCE$(DLL_VER).stamp pthreadVSE$(DLL_VER).stamp pthreadVC$(DLL_VER).stamp \
-				  pthreadVCE$(DLL_VERD).stamp pthreadVSE$(DLL_VERD).stamp pthreadVC$(DLL_VERD).stamp
-STATIC_STAMPS	= pthreadVCE$(DLL_VER).static pthreadVSE$(DLL_VER).static pthreadVC$(DLL_VER).static \
-				  pthreadVCE$(DLL_VERD).static pthreadVSE$(DLL_VERD).static pthreadVC$(DLL_VERD).static
-
-CC	= cl
-CPPFLAGS = /I. /DHAVE_PTW32_CONFIG_H
-XCFLAGS = /W3 /MD /nologo
-CFLAGS	= /O2 /Ob2 $(XCFLAGS)
-CFLAGSD	= /Z7 $(XCFLAGS)
-
-# Uncomment this if config.h defines RETAIN_WSALASTERROR
-#XLIBS = wsock32.lib
-
-# Default cleanup style
-CLEANUP	= __CLEANUP_C
-
-# C++ Exceptions
-VCEFLAGS	= /EHsc /TP $(CPPFLAGS) $(CFLAGS)
-VCEFLAGSD	= /EHsc /TP $(CPPFLAGS) $(CFLAGSD)
-#Structured Exceptions
-VSEFLAGS	= $(CPPFLAGS) $(CFLAGS)
-VSEFLAGSD	= $(CPPFLAGS) $(CFLAGSD)
-#C cleanup code
-VCFLAGS		= $(CPPFLAGS) $(CFLAGS)
-VCFLAGSD	= $(CPPFLAGS) $(CFLAGSD)
-
-DLL_INLINED_OBJS = \
-		pthread.obj \
-		version.res
-
-# Aggregate modules for inlinability
-DLL_OBJS	= \
-		attr.obj \
-		barrier.obj \
-		cancel.obj \
-		cleanup.obj \
-		condvar.obj \
-		create.obj \
-		dll.obj \
-		autostatic.obj \
-		errno.obj \
-		exit.obj \
-		fork.obj \
-		global.obj \
-		misc.obj \
-		mutex.obj \
-		nonportable.obj \
-		private.obj \
-		rwlock.obj \
-		sched.obj \
-		semaphore.obj \
-		signal.obj \
-		spin.obj \
-		sync.obj \
-		tsd.obj \
-		version.res
-
-# Separate modules for minimising the size of statically linked images
-SMALL_STATIC_OBJS	= \
-		pthread_attr_init.obj \
-		pthread_attr_destroy.obj \
-		pthread_attr_getdetachstate.obj \
-		pthread_attr_setdetachstate.obj \
-		pthread_attr_getstackaddr.obj \
-		pthread_attr_setstackaddr.obj \
-		pthread_attr_getstacksize.obj \
-		pthread_attr_setstacksize.obj \
-		pthread_attr_getscope.obj \
-		pthread_attr_setscope.obj \
-		pthread_attr_setschedpolicy.obj \
-		pthread_attr_getschedpolicy.obj \
-		pthread_attr_setschedparam.obj \
-		pthread_attr_getschedparam.obj \
-		pthread_attr_setinheritsched.obj \
-		pthread_attr_getinheritsched.obj \
-		pthread_barrier_init.obj \
-		pthread_barrier_destroy.obj \
-		pthread_barrier_wait.obj \
-		pthread_barrierattr_init.obj \
-		pthread_barrierattr_destroy.obj \
-		pthread_barrierattr_setpshared.obj \
-		pthread_barrierattr_getpshared.obj \
-		pthread_setcancelstate.obj \
-		pthread_setcanceltype.obj \
-		pthread_testcancel.obj \
-		pthread_cancel.obj \
-		cleanup.obj \
-		pthread_condattr_destroy.obj \
-		pthread_condattr_getpshared.obj \
-		pthread_condattr_init.obj \
-		pthread_condattr_setpshared.obj \
-		pthread_cond_destroy.obj \
-		pthread_cond_init.obj \
-		pthread_cond_signal.obj \
-		pthread_cond_wait.obj \
-		create.obj \
-		dll.obj \
-		autostatic.obj \
-		errno.obj \
-		pthread_exit.obj \
-		fork.obj \
-		global.obj \
-		pthread_mutex_init.obj \
-		pthread_mutex_destroy.obj \
-		pthread_mutexattr_init.obj \
-		pthread_mutexattr_destroy.obj \
-		pthread_mutexattr_getpshared.obj \
-		pthread_mutexattr_setpshared.obj \
-		pthread_mutexattr_settype.obj \
-		pthread_mutexattr_gettype.obj \
-		pthread_mutexattr_setrobust.obj \
-		pthread_mutexattr_getrobust.obj \
-		pthread_mutex_lock.obj \
-		pthread_mutex_timedlock.obj \
-		pthread_mutex_unlock.obj \
-		pthread_mutex_trylock.obj \
-		pthread_mutex_consistent.obj \
-		pthread_mutexattr_setkind_np.obj \
-		pthread_mutexattr_getkind_np.obj \
-		pthread_getw32threadhandle_np.obj \
-		pthread_getunique_np.obj \
-		pthread_delay_np.obj \
-		pthread_num_processors_np.obj \
-		pthread_win32_attach_detach_np.obj \
-		pthread_equal.obj \
-		pthread_getconcurrency.obj \
-		pthread_once.obj \
-		pthread_self.obj \
-		pthread_setconcurrency.obj \
-		pthread_rwlock_init.obj \
-		pthread_rwlock_destroy.obj \
-		pthread_rwlockattr_init.obj \
-		pthread_rwlockattr_destroy.obj \
-		pthread_rwlockattr_getpshared.obj \
-		pthread_rwlockattr_setpshared.obj \
-		pthread_rwlock_rdlock.obj \
-		pthread_rwlock_wrlock.obj \
-		pthread_rwlock_unlock.obj \
-		pthread_rwlock_tryrdlock.obj \
-		pthread_rwlock_trywrlock.obj \
-		pthread_setschedparam.obj \
-		pthread_getschedparam.obj \
-		pthread_timechange_handler_np.obj \
-		ptw32_is_attr.obj \
-		ptw32_processInitialize.obj \
-		ptw32_processTerminate.obj \
-		ptw32_threadStart.obj \
-		ptw32_threadDestroy.obj \
-		ptw32_tkAssocCreate.obj \
-		ptw32_tkAssocDestroy.obj \
-		ptw32_callUserDestroyRoutines.obj \
-		ptw32_timespec.obj \
-		ptw32_throw.obj \
-		ptw32_getprocessors.obj \
-		ptw32_calloc.obj \
-		ptw32_new.obj \
-		ptw32_reuse.obj \
-		ptw32_rwlock_check_need_init.obj \
-		ptw32_cond_check_need_init.obj \
-		ptw32_mutex_check_need_init.obj \
-		ptw32_semwait.obj \
-		ptw32_relmillisecs.obj \
-		ptw32_MCS_lock.obj \
-		sched_get_priority_max.obj \
-		sched_get_priority_min.obj \
-		sched_setscheduler.obj \
-		sched_getscheduler.obj \
-		sched_yield.obj \
-		sem_init.obj \
-		sem_destroy.obj \
-		sem_trywait.obj \
-		sem_timedwait.obj \
-		sem_wait.obj \
-		sem_post.obj \
-		sem_post_multiple.obj \
-		sem_getvalue.obj \
-		sem_open.obj \
-		sem_close.obj \
-		sem_unlink.obj \
-		signal.obj \
-		pthread_kill.obj \
-		ptw32_spinlock_check_need_init.obj \
-		pthread_spin_init.obj \
-		pthread_spin_destroy.obj \
-		pthread_spin_lock.obj \
-		pthread_spin_unlock.obj \
-		pthread_spin_trylock.obj \
-		pthread_detach.obj \
-		pthread_join.obj \
-		pthread_key_create.obj \
-		pthread_key_delete.obj \
-		pthread_setspecific.obj \
-		pthread_getspecific.obj \
-		w32_CancelableWait.obj \
-		version.res
-
-INCL	= config.h implement.h semaphore.h pthread.h need_errno.h
-
-ATTR_SRCS	= \
-		pthread_attr_init.c \
-		pthread_attr_destroy.c \
-		pthread_attr_getdetachstate.c \
-		pthread_attr_setdetachstate.c \
-		pthread_attr_getstackaddr.c \
-		pthread_attr_setstackaddr.c \
-		pthread_attr_getstacksize.c \
-		pthread_attr_setstacksize.c \
-		pthread_attr_getscope.c \
-		pthread_attr_setscope.c
-
-BARRIER_SRCS = \
-		pthread_barrier_init.c \
-		pthread_barrier_destroy.c \
-		pthread_barrier_wait.c \
-		pthread_barrierattr_init.c \
-		pthread_barrierattr_destroy.c \
-		pthread_barrierattr_setpshared.c \
-		pthread_barrierattr_getpshared.c
-
-CANCEL_SRCS	= \
-		pthread_setcancelstate.c \
-		pthread_setcanceltype.c \
-		pthread_testcancel.c \
-		pthread_cancel.c 
-
-CONDVAR_SRCS	= \
-		ptw32_cond_check_need_init.c \
-		pthread_condattr_destroy.c \
-		pthread_condattr_getpshared.c \
-		pthread_condattr_init.c \
-		pthread_condattr_setpshared.c \
-		pthread_cond_destroy.c \
-		pthread_cond_init.c \
-		pthread_cond_signal.c \
-		pthread_cond_wait.c
-
-EXIT_SRCS	= \
-		pthread_exit.c
-
-MISC_SRCS	= \
-		pthread_equal.c \
-		pthread_getconcurrency.c \
-		pthread_kill.c \
-		pthread_once.c \
-		pthread_self.c \
-		pthread_setconcurrency.c \
-		ptw32_calloc.c \
-		ptw32_MCS_lock.c \
-		ptw32_new.c \
-		ptw32_reuse.c \
-		ptw32_relmillisecs.c \
-		w32_CancelableWait.c
-
-MUTEX_SRCS	= \
-		ptw32_mutex_check_need_init.c \
-		pthread_mutex_init.c \
-		pthread_mutex_destroy.c \
-		pthread_mutexattr_init.c \
-		pthread_mutexattr_destroy.c \
-		pthread_mutexattr_getpshared.c \
-		pthread_mutexattr_setpshared.c \
-		pthread_mutexattr_settype.c \
-		pthread_mutexattr_gettype.c \
-		pthread_mutexattr_setrobust.c \
-		pthread_mutexattr_getrobust.c \
-		pthread_mutex_lock.c \
-		pthread_mutex_timedlock.c \
-		pthread_mutex_unlock.c \
-		pthread_mutex_trylock.c \
-		pthread_mutex_consistent.c
-
-NONPORTABLE_SRCS = \
-		pthread_mutexattr_setkind_np.c \
-		pthread_mutexattr_getkind_np.c \
-		pthread_getw32threadhandle_np.c \
-		pthread_getunique_np.c \
-		pthread_delay_np.c \
-		pthread_num_processors_np.c \
-		pthread_win32_attach_detach_np.c \
-		pthread_timechange_handler_np.c 
-
-PRIVATE_SRCS	= \
-		ptw32_is_attr.c \
-		ptw32_processInitialize.c \
-		ptw32_processTerminate.c \
-		ptw32_threadStart.c \
-		ptw32_threadDestroy.c \
-		ptw32_tkAssocCreate.c \
-		ptw32_tkAssocDestroy.c \
-		ptw32_callUserDestroyRoutines.c \
-		ptw32_semwait.c \
-		ptw32_timespec.c \
-		ptw32_throw.c \
-		ptw32_getprocessors.c
-
-RWLOCK_SRCS	= \
-		ptw32_rwlock_check_need_init.c \
-		ptw32_rwlock_cancelwrwait.c \
-		pthread_rwlock_init.c \
-		pthread_rwlock_destroy.c \
-		pthread_rwlockattr_init.c \
-		pthread_rwlockattr_destroy.c \
-		pthread_rwlockattr_getpshared.c \
-		pthread_rwlockattr_setpshared.c \
-		pthread_rwlock_rdlock.c \
-		pthread_rwlock_timedrdlock.c \
-		pthread_rwlock_wrlock.c \
-		pthread_rwlock_timedwrlock.c \
-		pthread_rwlock_unlock.c \
-		pthread_rwlock_tryrdlock.c \
-		pthread_rwlock_trywrlock.c
-
-SCHED_SRCS	= \
-		pthread_attr_setschedpolicy.c \
-		pthread_attr_getschedpolicy.c \
-		pthread_attr_setschedparam.c \
-		pthread_attr_getschedparam.c \
-		pthread_attr_setinheritsched.c \
-		pthread_attr_getinheritsched.c \
-		pthread_setschedparam.c \
-		pthread_getschedparam.c \
-		sched_get_priority_max.c \
-		sched_get_priority_min.c \
-		sched_setscheduler.c \
-		sched_getscheduler.c \
-		sched_yield.c
-
-SEMAPHORE_SRCS = \
-		sem_init.c \
-		sem_destroy.c \
-		sem_trywait.c \
-		sem_timedwait.c \
-		sem_wait.c \
-		sem_post.c \
-		sem_post_multiple.c \
-		sem_getvalue.c \
-		sem_open.c \
-		sem_close.c \
-		sem_unlink.c
-
-SPIN_SRCS	= \
-		ptw32_spinlock_check_need_init.c \
-		pthread_spin_init.c \
-		pthread_spin_destroy.c \
-		pthread_spin_lock.c \
-		pthread_spin_unlock.c \
-		pthread_spin_trylock.c
-
-SYNC_SRCS	= \
-		pthread_detach.c \
-		pthread_join.c
-
-TSD_SRCS	= \
-		pthread_key_create.c \
-		pthread_key_delete.c \
-		pthread_setspecific.c \
-		pthread_getspecific.c
-
-
-help:
-	@ echo Run one of the following command lines:
-	@ echo nmake clean VCE   (to build the MSVC dll with C++ exception handling)
-	@ echo nmake clean VSE   (to build the MSVC dll with structured exception handling)
-	@ echo nmake clean VC    (to build the MSVC dll with C cleanup code)
-	@ echo nmake clean VCE-inlined   (to build the MSVC inlined dll with C++ exception handling)
-	@ echo nmake clean VSE-inlined   (to build the MSVC inlined dll with structured exception handling)
-	@ echo nmake clean VC-inlined    (to build the MSVC inlined dll with C cleanup code)
-	@ echo nmake clean VC-static     (to build the MSVC static lib with C cleanup code)
-	@ echo nmake clean VCE-debug   (to build the debug MSVC dll with C++ exception handling)
-	@ echo nmake clean VSE-debug   (to build the debug MSVC dll with structured exception handling)
-	@ echo nmake clean VC-debug    (to build the debug MSVC dll with C cleanup code)
-	@ echo nmake clean VCE-inlined-debug   (to build the debug MSVC inlined dll with C++ exception handling)
-	@ echo nmake clean VSE-inlined-debug   (to build the debug MSVC inlined dll with structured exception handling)
-	@ echo nmake clean VC-inlined-debug    (to build the debug MSVC inlined dll with C cleanup code)
-	@ echo nmake clean VC-static-debug     (to build the debug MSVC static lib with C cleanup code)
-
-all:
-	@ $(MAKE) /E clean VCE-inlined
-	@ $(MAKE) /E clean VSE-inlined
-	@ $(MAKE) /E clean VC-inlined
-	@ $(MAKE) /E clean VCE-inlined-debug
-	@ $(MAKE) /E clean VSE-inlined-debug
-	@ $(MAKE) /E clean VC-inlined-debug
-
-VCE:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGS)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).dll
-
-VCE-debug:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGSD)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).dll
-
-VSE:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGS)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).dll
-
-VSE-debug:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGSD)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).dll
-
-VC:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS)" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).dll
-
-VC-debug:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGSD)" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).dll
-
-#
-# The so-called inlined DLL is just a single translation unit with
-# inlining optimisation turned on.
-#
-VCE-inlined:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).stamp
-
-VCE-inlined-debug:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).stamp
-
-VSE-inlined:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).stamp
-
-VSE-inlined-debug:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).stamp
-
-VC-inlined:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).stamp
-
-VC-inlined-debug:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).stamp
-
-VC-static:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS) /DPTW32_BUILD_INLINED /DPTW32_STATIC_LIB" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).static
-
-VC-static-debug:
-	@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGSD) /DPTW32_BUILD_INLINED /DPTW32_STATIC_LIB" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).static
-
-realclean: clean
-	if exist pthread*.dll del pthread*.dll
-	if exist pthread*.lib del pthread*.lib
-	if exist *.manifest del *.manifest
-	if exist *.stamp del *.stamp
-
-clean:
-	if exist *.obj del *.obj
-	if exist *.def del *.def
-	if exist *.ilk del *.ilk
-	if exist *.pdb del *.pdb
-	if exist *.exp del *.exp
-	if exist *.map del *.map
-	if exist *.o del *.o
-	if exist *.i del *.i
-	if exist *.res del *.res
-
-
-install:
-	copy pthread*.dll $(DLLDEST)
-	copy pthread*.lib $(LIBDEST)
-	copy pthread.h $(HDRDEST)
-	copy sched.h $(HDRDEST)
-	copy semaphore.h $(HDRDEST)
-
-$(DLLS): $(DLL_OBJS)
-	$(CC) /LDd /Zi /nologo $(DLL_OBJS) /link /implib:$*.lib $(XLIBS) /out:$@
-
-$(INLINED_STAMPS): $(DLL_INLINED_OBJS)
-	$(CC) /LDd /Zi /nologo $(DLL_INLINED_OBJS) /link /implib:$*.lib $(XLIBS) /out:$*.dll
-
-$(STATIC_STAMPS): $(DLL_INLINED_OBJS)
-	if exist $*.lib del $*.lib
-	lib $(DLL_INLINED_OBJS) /out:$*.lib
-
-.c.obj:
-	$(CC) $(EHFLAGS) /D$(CLEANUP) -c $<
-
-# TARGET_CPU is an environment variable set by Visual Studio Command Prompt
-# as provided by the SDK
-.rc.res:
-	rc /dPTW32_ARCH$(TARGET_CPU) /dPTW32_RC_MSC /d$(CLEANUP) $<
-
-.c.i:
-	$(CC) /P /O2 /Ob1 $(VCFLAGS) $<
-
-attr.obj:	attr.c $(ATTR_SRCS) $(INCL)
-barrier.obj:	barrier.c $(BARRIER_SRCS) $(INCL)
-cancel.obj:	cancel.c $(CANCEL_SRCS) $(INCL)
-condvar.obj:	condvar.c $(CONDVAR_SRCS) $(INCL)
-exit.obj:	exit.c $(EXIT_SRCS) $(INCL)
-misc.obj:	misc.c $(MISC_SRCS) $(INCL)
-mutex.obj:	mutex.c $(MUTEX_SRCS) $(INCL)
-nonportable.obj:	nonportable.c $(NONPORTABLE_SRCS) $(INCL)
-private.obj:	private.c $(PRIVATE_SRCS) $(INCL)
-rwlock.obj:	rwlock.c $(RWLOCK_SRCS) $(INCL)
-sched.obj:	sched.c $(SCHED_SRCS) $(INCL)
-semaphore.obj:	semaphore.c $(SEMAPHORE_SRCS) $(INCL)
-spin.obj:	spin.c $(SPIN_SRCS) $(INCL)
-sync.obj:	sync.c $(SYNC_SRCS) $(INCL)
-tsd.obj:	tsd.c $(TSD_SRCS) $(INCL)
-version.res:	version.rc $(INCL)
diff --git a/deps/w32-pthreads/NEWS b/deps/w32-pthreads/NEWS
deleted file mode 100644
index d1b7896..0000000
--- a/deps/w32-pthreads/NEWS
+++ /dev/null
@@ -1,1241 +0,0 @@
-RELEASE 2.9.0
--------------
-(2012-05-25)
-
-General
--------
-New bug fixes in this release since 2.8.0 have NOT been applied to the
-1.x.x series.
-
-Some changes post 2011-02-26 in CVS may not be compatible with pre
-Windows 2000 systems.
-
-Use of other than the "C" version of the library is now discouraged.
-That is, the "C++" version fails some tests and does not provide any
-additional functionality.
-
-Testing and verification
-------------------------
-This version has been tested on SMP architecture (Intel x64 Hex Core)
-by completing the included test suite, stress and bench tests.
-
-New Features
-------------
-DLL properties now properly includes the target architecture, i.e.
-right-click on the file pthreadVC2.dll in explorer and choose the Detail
-tab will show the compiler and architecture in the description field, e.g.
-"MS C x64" or "MS C x86".
-- Ross Johnson
-
-(MSC and GNU builds) The statically linked library now automatically
-initialises and cleans up on program start/exit, i.e. statically linked
-applications need not call the routines pthread_win32_process_attach_np()
-and pthread_win32_process_detach_np() explicitly. The per-thread routine
-pthread_win32_thread_detach_np() is also called at program exit to cleanup
-POSIX resources acquired by the primary Windows native thread, if I (RJ)
-understand the process correctly. Other Windows native threads that call
-POSIX API routines may need to call the thread detach routine on thread
-exit if the application depends on reclaimed POSIX resources or running
-POSIX TSD (TLS) destructors.
-See README.NONPORTABLE for descriptions of these routines.
-- Ramiro Polla
-
-Robust mutexes are implemented within the PROCESS_PRIVATE scope. NOTE that
-pthread_mutex_* functions may return different error codes for robust
-mutexes than they otherwise do in normal usage, e.g.  pthread_mutex_unlock
-is required to check ownership for all mutex types when the mutex is
-robust, whereas this does not occur for the "normal" non-robust mutex type.
-- Ross Johnson
-
-pthread_getunique_np is implemented for source level compatibility
-with some other implementations. This routine returns a 64 bit
-sequence number that is uniquely associated with a thread. It can be
-used by applications to order or hash POSIX thread handles.
-- Ross Johnson
-
-Bug fixes
----------
-Many more changes for 64 bit systems.
-- Kai Tietz
-
-Various modifications and fixes to build and test for WinCE.
-- Marcel Ruff, Sinan Kaya
-
-Fix pthread_cond_destroy() - should not be a cancellation point. Other
-minor build problems fixed.
-- Romano Paolo Tenca
-
-Remove potential deadlock condition from pthread_cond_destroy().
-- Eric Berge
-
-Various modifications to build and test for Win64.
-- Kip Streithorst
-
-Various fixes to the QueueUserAPCEx async cancellation helper DLL
-(this is a separate download) and pthreads code cleanups.
-- Sebastian Gottschalk
-
-Removed potential NULL pointer reference.
-- Robert Kindred
-
-Removed the requirement that applications restrict the number of threads
-calling pthread_barrier_wait to just the barrier count. Also reduced the
-contention between barrier_wait and barrier_destroy. This change will have
-slowed barriers down slightly but halves the number of semaphores consumed
-per barrier to one.
-- Ross Johnson
-
-Fixed a handle leak in sched_[gs]etscheduler.
-- Mark Pizzolato
-
-Removed all of the POSIX re-entrant function compatibility macros from pthread.h.
-Some were simply not semanticly correct.
-- Igor Lubashev
-
-Threads no longer attempt to pass uncaught exceptions out of thread scope (C++
-and SEH builds only). Uncaught exceptions now cause the thread to exit with
-the return code PTHREAD_CANCELED.
-- Ross Johnson
-
-Lots of casting fixes particularly for x64, Interlocked fixes and reworking
-for x64.
-- Daniel Richard G., John Kamp
-
-Other changes
--------------
-Dependence on the winsock library is now discretionary via
-#define RETAIN_WSALASTERROR in config.h. It is undefined by default unless
-WINCE is defined (because RJ is unsure of the dependency there).
-- Ramiro Polla
-
-Several static POSIX mutexes used for internal management were replaced by
-MCS queue-based locks to reduce resource consumption, in particular use of Win32
-objects.
-- Ross Johnson
-
-For security, the QuserEx.dll if used must now be installed in the Windows System
-folder.
-- Ross Johnson
-
-New tests
----------
-robust[1-5].c - Robust mutexes
-sequence1.c - per-thread unique sequence numbers
-
-Modified tests and benchtests
------------------------------
-All mutex*.c tests wherever appropriate have been modified to also test
-robust mutexes under the same conditions.
-Added robust mutex benchtests to benchtest*.c wherever appropriate.
-
-
-RELEASE 2.8.0
--------------
-(2006-12-22)
-
-General
--------
-New bug fixes in this release since 2.7.0 have not been applied to the
-version 1.x.x series. It is probably time to drop version 1.
-
-Testing and verification
-------------------------
-This release has not yet been tested on SMP architechtures. All tests pass
-on a uni-processor system.
-
-Bug fixes
----------
-Sem_destroy could return EBUSY even though no threads were waiting on the 
-semaphore. Other races around invalidating semaphore structs (internally)
-have been removed as well.
-
-New tests
----------
-semaphore5.c - tests the bug fix referred to above.
-
-
-RELEASE 2.7.0
--------------
-(2005-06-04)
-
-General
--------
-All new features in this release have been back-ported in release 1.11.0,
-including the incorporation of MCS locks in pthread_once, however, versions
-1 and 2 remain incompatible even though they are now identical in
-performance and functionality.
-
-Testing and verification
-------------------------
-This release has been tested (passed the test suite) on both uni-processor
-and multi-processor systems.
-- Tim Theisen
-
-Bug fixes
----------
-Pthread_once has been re-implemented to remove priority boosting and other
-complexity to improve robustness. Races for Win32 handles that are not
-recycle-unique have been removed. The general form of pthread_once is now
-the same as that suggested earlier by Alexander Terekhov, but instead of the
-'named mutex', a queue-based lock has been implemented which has the required
-properties of dynamic self initialisation and destruction. This lock is also
-efficient. The ABI is unaffected in as much as the size of pthread_once_t has
-not changed and PTHREAD_ONCE_INIT has not changed, however, applications that
-peek inside pthread_once_t, which is supposed to be opaque, will break.
-- Vladimir Kliatchko
-
-New features
-------------
-* Support for Mingw cross development tools added to GNUmakefile.
-Mingw cross tools allow building the libraries on Linux.
-- Mikael Magnusson
-
-
-RELEASE 2.6.0
--------------
-(2005-05-19)
-
-General
--------
-All of the bug fixes and new features in this release have been
-back-ported in release 1.10.0.
-
-Testing and verification
-------------------------
-This release has been tested (passed the test suite) on both uni-processor
-and multi-processor systems. Thanks to Tim Theisen at TomoTherapy for
-exhaustively running the MP tests and for providing crutial observations
-and data when faults are detected.
-
-Bugs fixed
-----------
-
-* pthread_detach() now reclaims remaining thread resources if called after
-the target thread has terminated. Previously, this routine did nothing in
-this case.
-
-New tests
----------
-
-* detach1.c - tests that pthread_detach properly invalidates the target
-thread, which indicates that the thread resources have been reclaimed.
-
-
-RELEASE 2.5.0
--------------
-(2005-05-09)
-
-General
--------
-
-The package now includes a reference documentation set consisting of
-HTML formatted Unix-style manual pages that have been edited for
-consistency with Pthreads-w32. The set can also be read online at:
-http://sources.redhat.com/pthreads-win32/manual/index.html
-
-Thanks again to Tim Theisen for running the test suite pre-release
-on an MP system.
-
-All of the bug fixes and new features in this release have been
-back-ported in release 1.9.0.
-
-Bugs fixed
-----------
-
-* Thread Specific Data (TSD) key management has been ammended to
-eliminate a source of (what was effectively) resource leakage (a HANDLE
-plus memory for each key destruct routine/thread association). This was
-not a true leak because these resources were eventually reclaimed when
-pthread_key_delete was run AND each thread referencing the key had exited.
-The problem was that these two conditions are often not met until very
-late, and often not until the process is about to exit.
-
-The ammended implementation avoids the need for the problematic HANDLE
-and reclaims the memory as soon as either the key is deleted OR the
-thread exits, whichever is first.
-
-Thanks to Richard Hughes at Aculab for identifying and locating the leak.
-
-* TSD key destructors are now processed up to PTHREAD_DESTRUCTOR_ITERATIONS
-times instead of just once. PTHREAD_DESTRUCTOR_ITERATIONS has been
-defined in pthread.h for some time but not used.
-
-* Fix a semaphore accounting race between sem_post/sem_post_multiple
-and sem_wait cancellation. This is the same issue as with
-sem_timedwait that was fixed in the last release.
-
-* sem_init, sem_post, and sem_post_multiple now check that the
-semaphore count never exceeds _POSIX_SEM_VALUE_MAX.
-
-* Although sigwait() is nothing more than a no-op, it should at least
-be a cancellation point to be consistent with the standard.
-
-New tests
----------
-
-* stress1.c - attempts to expose problems in condition variable
-and semaphore timed wait logic. This test was inspired by Stephan
-Mueller's sample test code used to identify the sem_timedwait bug
-from the last release. It's not a part of the regular test suite
-because it can take awhile to run. To run it:
-nmake clean VC-stress
-
-* tsd2.c - tests that key destructors are re-run if the tsd key value is
-not NULL after the destructor routine has run. Also tests that
-pthread_setspecific() and pthread_getspecific() are callable from
-destructors.
-
-
-RELEASE 2.4.0
--------------
-(2005-04-26)
-
-General
--------
-
-There is now no plan to release a version 3.0.0 to fix problems in
-pthread_once(). Other possible implementations of pthread_once
-will still be investigated for a possible future release in an attempt
-to reduce the current implementation's complexity.
-
-All of the bug fixes and new features in this release have been
-back-ported for release 1.8.0.
-
-Bugs fixed
-----------
-
-* Fixed pthread_once race (failures on an MP system). Thanks to
-Tim Theisen for running exhaustive pre-release testing on his MP system
-using a range of compilers:
-  VC++ 6
-  VC++ 7.1
-  Intel C++ version 8.0
-All tests passed.
-Some minor speed improvements were also done.
-
-* Fix integer overrun error in pthread_mutex_timedlock() - missed when
-sem_timedwait() was fixed in release 2.2.0. This routine no longer returns
-ENOTSUP when NEED_SEM is defined - it is supported (NEED_SEM is only
-required for WinCE versions prior to 3.0).
-
-* Fix timeout bug in sem_timedwait().
-- Thanks to Stephan Mueller for reporting, providing diagnostic output
-and test code.
-
-* Fix several problems in the NEED_SEM conditionally included code.
-NEED_SEM included code is provided for systems that don't implement W32
-semaphores, such as WinCE prior to version 3.0. An alternate implementation
-of POSIX semaphores is built using W32 events for these systems when
-NEED_SEM is defined. This code has been completely rewritten in this
-release to reuse most of the default POSIX semaphore code, and particularly,
-to implement all of the sem_* routines supported by pthreads-win32. Tim
-Theisen also run the test suite over the NEED_SEM code on his MP system. All
-tests passed.
-
-* The library now builds without errors for the Borland Builder 5.5 compiler.
-
-New features
-------------
-
-* pthread_mutex_timedlock() and all sem_* routines provided by
-pthreads-win32 are now implemented for WinCE versions prior to 3.0. Those
-versions did not implement W32 semaphores. Define NEED_SEM in config.h when
-building the library for these systems.
-
-Known issues in this release
-----------------------------
-
-* pthread_once is too complicated - but it works as far as testing can
-determine..
-
-* The Borland version of the dll fails some of the tests with a memory read
-exception. The cause is not yet known but a compiler bug has not been ruled
-out.
-
-
-RELEASE 2.3.0
--------------
-(2005-04-12)
-
-General
--------
-
-Release 1.7.0 is a backport of features and bug fixes new in
-this release. See earlier notes under Release 2.0.0/General.
-
-Bugs fixed
-----------
-
-* Fixed pthread_once potential for post once_routine cancellation
-hanging due to starvation. See comments in pthread_once.c.
-Momentary priority boosting is used to ensure that, after a
-once_routine is cancelled, the thread that will run the
-once_routine is not starved by higher priority waiting threads at
-critical times. Priority boosting occurs only AFTER a once_routine 
-cancellation, and is applied only to that once_control. The
-once_routine is run at the thread's normal base priority.
-
-New tests
----------
-
-* once4.c: Aggressively tests pthread_once() under realtime
-conditions using threads with varying priorities. Windows'
-random priority boosting does not occur for threads with realtime
-priority levels.
-
-
-RELEASE 2.2.0
--------------
-(2005-04-04)
-
-General
--------
-
-* Added makefile targets to build static link versions of the library.
-Both MinGW and MSVC. Please note that this does not imply any change
-to the LGPL licensing, which still imposes psecific conditions on
-distributing software that has been statically linked with this library.
-
-* There is a known bug in pthread_once(). Cancellation of the init_routine
-exposes a potential starvation (i.e. deadlock) problem if a waiting thread
-has a higher priority than the initting thread. This problem will be fixed
-in version 3.0.0 of the library.
-
-Bugs fixed
-----------
-
-* Fix integer overrun error in sem_timedwait().
-Kevin Lussier
-
-* Fix preprocessor directives for static linking.
-Dimitar Panayotov
-
-
-RELEASE 2.1.0
--------------
-(2005-03-16)
-
-Bugs fixed
-----------
-
-* Reverse change to pthread_setcancelstate() in 2.0.0.
-
-
-RELEASE 2.0.0
--------------
-(2005-03-16)
-
-General
--------
-
-This release represents an ABI change and the DLL version naming has
-incremented from 1 to 2, e.g. pthreadVC2.dll.
-
-Version 1.4.0 back-ports the new functionality included in this
-release. Please distribute DLLs built from that version with updates
-to applications built on pthreads-win32 version 1.x.x.
-
-The package naming has changed, replacing the snapshot date with 
-the version number + descriptive information. E.g. this
-release is "pthreads-w32-2-0-0-release".
-
-Bugs fixed
-----------
-
-* pthread_setcancelstate() no longer checks for a pending
-async cancel event if the library is using alertable async
-cancel. See the README file (Prerequisites section) for info
-on adding alertable async cancelation.
-
-New features
-------------
-
-* pthread_once() now supports init_routine cancellability.
-
-New tests
----------
-
-* Agressively test pthread_once() init_routine cancellability.
-
-
-SNAPSHOT 2005-03-08
--------------------
-Version 1.3.0
-
-Bug reports (fixed)
--------------------
-
-* Implicitly created threads leave Win32 handles behind after exiting.
-- Dmitrii Semii
-
-* pthread_once() starvation problem.
-- Gottlob Frege
-
-New tests
----------
-
-* More intense testing of pthread_once().
-
-
-SNAPSHOT 2005-01-25
--------------------
-Version 1.2.0
-
-Bug fixes
----------
-
-* Attempted acquisition of a recursive mutex could cause waiting threads
-to not be woken when the mutex was released.
-- Ralf Kubis  <RKubis at mc.com>
-
-* Various package omissions have been fixed.
-
-
-SNAPSHOT 2005-01-03
--------------------
-Version 1.1.0
-
-Bug fixes
----------
-
-* Unlocking recursive or errorcheck mutexes would sometimes
-unexpectedly return an EPERM error (bug introduced in
-snapshot-2004-11-03).
-- Konstantin Voronkov  <beowinkle at yahoo.com>
-
-
-SNAPSHOT 2004-11-22
--------------------
-Version 1.0.0
-
-This snapshot primarily fixes the condvar bug introduced in
-snapshot-2004-11-03. DLL versioning has also been included to allow
-applications to runtime check the Microsoft compatible DLL version
-information, and to extend the DLL naming system for ABI and major
-(non-backward compatible) API changes. See the README file for details.
-
-Bug fixes
----------
-
-* Condition variables no longer deadlock (bug introduced in
-snapshot-2004-11-03).
-- Alexander Kotliarov and Nicolas at saintmac
-
-* DLL naming extended to avoid 'DLL hell' in the future, and to
-accommodate the ABI change introduced in snapshot-2004-11-03. Snapshot
-2004-11-03 will be removed from FTP sites.
-
-New features
-------------
-
-* A Microsoft-style version resource has been added to the DLL for
-applications that wish to check DLL compatibility at runtime.
-
-* Pthreads-win32 DLL naming has been extended to allow incompatible DLL
-versions to co-exist in the same filesystem. See the README file for details,
-but briefly: while the version information inside the DLL will change with
-each release from now on, the DLL version names will only change if the new
-DLL is not backward compatible with older applications.
-
-The versioning scheme has been borrowed from GNU Libtool, and the DLL
-naming scheme is from Cygwin. Provided the Libtool-style numbering rules are
-honoured, the Cygwin DLL naming scheme automatcally ensures that DLL name
-changes are minimal and that applications will not load an incompatible
-pthreads-win32 DLL.
-
-Those who use the pre-built DLLs will find that the DLL/LIB names have a new
-suffix (1) in this snapshot. E.g. pthreadVC1.dll etc.
-
-* The POSIX thread ID reuse uniqueness feature introduced in the last snapshot
-has been kept as default, but the behaviour can now be controlled when the DLL
-is built to effectively switch it off. This makes the library much more
-sensitive to applications that assume that POSIX thread IDs are unique, i.e.
-are not strictly compliant with POSIX. See the PTW32_THREAD_ID_REUSE_INCREMENT
-macro comments in config.h for details.
-
-Other changes
--------------
-Certain POSIX macros have changed.
-
-These changes are intended to conform to the Single Unix Specification version 3,
-which states that, if set to 0 (zero) or not defined, then applications may use
-sysconf() to determine their values at runtime. Pthreads-win32 does not
-implement sysconf().
-
-The following macros are no longer undefined, but defined and set to -1
-(not implemented):
-
-      _POSIX_THREAD_ATTR_STACKADDR
-      _POSIX_THREAD_PRIO_INHERIT
-      _POSIX_THREAD_PRIO_PROTECT
-      _POSIX_THREAD_PROCESS_SHARED
-
-The following macros are defined and set to 200112L (implemented):
-
-      _POSIX_THREADS
-      _POSIX_THREAD_SAFE_FUNCTIONS
-      _POSIX_THREAD_ATTR_STACKSIZE
-      _POSIX_THREAD_PRIORITY_SCHEDULING
-      _POSIX_SEMAPHORES
-      _POSIX_READER_WRITER_LOCKS
-      _POSIX_SPIN_LOCKS
-      _POSIX_BARRIERS
-
-The following macros are defined and set to appropriate values:
-
-      _POSIX_THREAD_THREADS_MAX
-      _POSIX_SEM_VALUE_MAX
-      _POSIX_SEM_NSEMS_MAX
-      PTHREAD_DESTRUCTOR_ITERATIONS
-      PTHREAD_KEYS_MAX
-      PTHREAD_STACK_MIN
-      PTHREAD_THREADS_MAX
-
-
-SNAPSHOT 2004-11-03
--------------------
-
-DLLs produced from this snapshot cannot be used with older applications without
-recompiling the application, due to a change to pthread_t to provide unique POSIX
-thread IDs.
-
-Although this snapshot passes the extended test suite, many of the changes are
-fairly major, and some applications may show different behaviour than previously,
-so adopt with care. Hopefully, any changed behaviour will be due to the library
-being better at it's job, not worse.
-
-Bug fixes
----------
-
-* pthread_create() no longer accepts NULL as the thread reference arg.
-A segfault (memory access fault) will result, and no thread will be
-created.
-
-* pthread_barrier_wait() no longer acts as a cancelation point.
-
-* Fix potential race condition in pthread_once()
-- Tristan Savatier  <tristan at mpegtv.com>
-
-* Changes to pthread_cond_destroy() exposed some coding weaknesses in several
-test suite mini-apps because pthread_cond_destroy() now returns EBUSY if the CV
-is still in use.
-
-New features
-------------
-
-* Added for compatibility:
-PTHREAD_RECURSIVE_MUTEX_INITIALIZER,
-PTHREAD_ERRORCHECK_MUTEX_INITIALIZER,
-PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
-PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-
-* Initial support for Digital Mars compiler
-- Anuj Goyal  <anuj.goyal at gmail.com>
-
-* Faster Mutexes. These have been been rewritten following a model provided by
-Alexander Terekhov that reduces kernel space checks, and eliminates some additional
-critical sections used to manage a race between timedlock expiration and unlock.
-Please be aware that the new mutexes do not enforce strict absolute FIFO scheduling
-of mutexes, however any out-of-order lock acquisition should be very rare.
-
-* Faster semaphores. Following a similar model to mutexes above, these have been
-rewritten to use preliminary users space checks.
-
-* sem_getvalue() now returns the number of waiters.
-
-* The POSIX thread ID now has much stronger uniqueness characteristics. The library
-garrantees not to reuse the same thread ID for at least 2^(wordsize) thread
-destruction/creation cycles.
-
-New tests
----------
-
-* semaphore4.c: Tests cancelation of the new sem_wait().
-
-* semaphore4t.c: Likewise for sem_timedwait().
-
-* rwlock8.c: Tests and times the slow execution paths of r/w locks, and the CVs,
-mutexes, and semaphores that they're built on.
-
-
-SNAPSHOT 2004-05-16
--------------------
-
-Attempt to add Watcom to the list of compilers that can build the library.
-This failed in the end due to it's non-thread-aware errno. The library
-builds but the test suite fails. See README.Watcom for more details.
-
-Bug fixes
----------
-* Bug and memory leak in sem_init()
-- Alex Blanco  <Alex.Blanco at motorola.com>
-
-* ptw32_getprocessors() now returns CPU count of 1 for WinCE.
-- James Ewing  <james.ewing at sveasoft.com>
-
-* pthread_cond_wait() could be canceled at a point where it should not
-be cancelable. Fixed.
-- Alexander Terekhov  <TEREKHOV at de.ibm.com>
-
-* sem_timedwait() had an incorrect timeout calculation.
-- Philippe Di Cristo  <philipped at voicebox.com>
-
-* Fix a memory leak left behind after threads are destroyed.
-- P. van Bruggen  <pietvb at newbridges.nl>
-
-New features
-------------
-* Ported to AMD64.
-- Makoto Kato  <raven at oldskool.jp>
-
-* True pre-emptive asynchronous cancelation of threads. This is optional
-and requires that Panagiotis E. Hadjidoukas's QueueUserAPCEx package be
-installed. This package is included in the pthreads-win32 self-unpacking
-Zip archive starting from this snapshot. See the README.txt file inside
-the package for installation details.
-
-Note: If you don't use async cancelation in your application, or don't need
-to cancel threads that are blocked on system resources such as network I/O,
-then the default non-preemptive async cancelation is probably good enough.
-However, pthreads-win32 auto-detects the availability of these components
-at run-time, so you don't need to rebuild the library from source if you
-change your mind later.
-
-All of the advice available in books and elsewhere on the undesirability
-of using async cancelation in any application still stands, but this
-feature is a welcome addition with respect to the library's conformance to
-the POSIX standard.
-
-SNAPSHOT 2003-09-18
--------------------
-
-Cleanup of thread priority management. In particular, setting of thread
-priority now attempts to map invalid Win32 values within the range returned
-by sched_get_priority_min/max() to useful values. See README.NONPORTABLE
-under "Thread priority".
-
-Bug fixes
----------
-* pthread_getschedparam() now returns the priority given by the most recent
-call to pthread_setschedparam() or established by pthread_create(), as
-required by the standard. Previously, pthread_getschedparam() incorrectly
-returned the running thread priority at the time of the call, which may have
-been adjusted or temporarily promoted/demoted.
-
-* sched_get_priority_min() and sched_get_priority_max() now return -1 on error
-and set errno. Previously, they incorrectly returned the error value directly.
-
-
-SNAPSHOT 2003-09-04
--------------------
-
-Bug fixes
----------
-* ptw32_cancelableWait() now allows cancelation of waiting implicit POSIX
-threads.
-
-New test
---------
-* cancel8.c tests cancelation of Win32 threads waiting at a POSIX cancelation
-point.
-
-
-SNAPSHOT 2003-09-03
--------------------
-
-Bug fixes
----------
-* pthread_self() would free the newly created implicit POSIX thread handle if
-DuplicateHandle failed instead of recycle it (very unlikely).
-
-* pthread_exit() was neither freeing nor recycling the POSIX thread struct
-for implicit POSIX threads.
-
-New feature - Cancelation of/by Win32 (non-POSIX) threads
----------------------------------------------------------
-Since John Bossom's original implementation, the library has allowed non-POSIX
-initialised threads (Win32 threads) to call pthreads-win32 routines and
-therefore interact with POSIX threads. This is done by creating an on-the-fly
-POSIX thread ID for the Win32 thread that, once created, allows fully
-reciprical interaction. This did not extend to thread cancelation (async or
-deferred). Now it does.
-
-Any thread can be canceled by any other thread (Win32 or POSIX) if the former
-thread's POSIX pthread_t value is known. It's TSD destructors and POSIX
-cleanup handlers will be run before the thread exits with an exit code of
-PTHREAD_CANCELED (retrieved with GetExitCodeThread()).
-
-This allows a Win32 thread to, for example, call POSIX CV routines in the same way
-that POSIX threads would/should, with pthread_cond_wait() cancelability and
-cleanup handlers (pthread_cond_wait() is a POSIX cancelation point).
-
-By adding cancelation, Win32 threads should now be able to call all POSIX
-threads routines that make sense including semaphores, mutexes, condition
-variables, read/write locks, barriers, spinlocks, tsd, cleanup push/pop,
-cancelation, pthread_exit, scheduling, etc.
-
-Note that these on-the-fly 'implicit' POSIX thread IDs are initialised as detached
-(not joinable) with deferred cancelation type. The POSIX thread ID will be created
-automatically by any POSIX routines that need a POSIX handle (unless the routine
-needs a pthread_t as a parameter of course). A Win32 thread can discover it's own
-POSIX thread ID by calling pthread_self(), which will create the handle if
-necessary and return the pthread_t value.
-
-New tests
----------
-Test the above new feature.
-
-
-SNAPSHOT 2003-08-19
--------------------
-
-This snapshot fixes some accidental corruption to new test case sources.
-There are no changes to the library source code.
-
-
-SNAPSHOT 2003-08-15
--------------------
-
-Bug fixes
----------
-
-* pthread.dsp now uses correct compile flags (/MD).
-- Viv  <vcotirlea at hotmail.com>
-
-* pthread_win32_process_detach_np() fixed memory leak.
-- Steven Reddie  <Steven.Reddie at ca.com>
-
-* pthread_mutex_destroy() fixed incorrect return code.
-- Nicolas Barry  <boozai at yahoo.com>
-
-* pthread_spin_destroy() fixed memory leak.
-- Piet van Bruggen  <pietvb at newbridges.nl>
-
-* Various changes to tighten arg checking, and to work with later versions of
-MinGW32 and MsysDTK.
-
-* pthread_getschedparam() etc, fixed dangerous thread validity checking.
-- Nicolas Barry  <boozai at yahoo.com>
-
-* POSIX thread handles are now reused and their memory is not freed on thread exit.
-This allows for stronger thread validity checking.
-
-New standard routine
---------------------
-
-* pthread_kill() added to provide thread validity checking to applications.
-It does not accept any non zero values for the signal arg.
-
-New test cases
---------------
-
-* New test cases to confirm validity checking, pthread_kill(), and thread reuse.
-
-
-SNAPSHOT 2003-05-10
--------------------
-
-Bug fixes
----------
-
-* pthread_mutex_trylock() now returns correct error values.
-pthread_mutex_destroy() will no longer destroy a recursively locked mutex.
-pthread_mutex_lock() is no longer inadvertantly behaving as a cancelation point.
-- Thomas Pfaff  <tpfaff at gmx.net>
-
-* pthread_mutex_timedlock() no longer occasionally sets incorrect mutex
-ownership, causing deadlocks in some applications.
-- Robert Strycek <strycek at posam.sk> and Alexander Terekhov  <TEREKHOV at de.ibm.com>
-
-
-SNAPSHOT 2002-11-04
--------------------
-
-Bug fixes
----------
-
-* sem_getvalue() now returns the correct value under Win NT and WinCE.
-- Rob Fanner  <rfanner at stonethree.com>
-
-* sem_timedwait() now uses tighter checks for unreasonable
-abstime values - that would result in unexpected timeout values.
-
-* ptw32_cond_wait_cleanup() no longer mysteriously consumes
-CV signals but may produce more spurious wakeups. It is believed
-that the sem_timedwait() call is consuming a CV signal that it
-shouldn't.
-- Alexander Terekhov  <TEREKHOV at de.ibm.com>
-
-* Fixed a memory leak in ptw32_threadDestroy() for implicit threads.
-
-* Fixed potential for deadlock in pthread_cond_destroy().
-A deadlock could occur for statically declared CVs (PTHREAD_COND_INITIALIZER),
-when one thread is attempting to destroy the condition variable while another
-is attempting to dynamically initialize it.
-- Michael Johnson  <michaelj at maine.rr.com>
-
-
-SNAPSHOT 2002-03-02
--------------------
-
-Cleanup code default style. (IMPORTANT)
-----------------------------------------------------------------------
-Previously, if not defined, the cleanup style was determined automatically
-from the compiler/language, and one of the following was defined accordingly:
-
-        __CLEANUP_SEH   MSVC only
-        __CLEANUP_CXX   C++, including MSVC++, GNU G++
-        __CLEANUP_C             C, including GNU GCC, not MSVC
-
-These defines determine the style of cleanup (see pthread.h) and,
-most importantly, the way that cancelation and thread exit (via
-pthread_exit) is performed (see the routine ptw32_throw() in private.c).
-
-In short, the exceptions versions of the library throw an exception
-when a thread is canceled or exits (via pthread_exit()), which is
-caught by a handler in the thread startup routine, so that the
-the correct stack unwinding occurs regardless of where the thread
-is when it's canceled or exits via pthread_exit().
-
-In this and future snapshots, unless the build explicitly defines (e.g.
-via a compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
-the build NOW always defaults to __CLEANUP_C style cleanup. This style
-uses setjmp/longjmp in the cancelation and pthread_exit implementations,
-and therefore won't do stack unwinding even when linked to applications
-that have it (e.g. C++ apps). This is for consistency with most
-current commercial Unix POSIX threads implementations. Compaq's TRU64
-may be an exception (no pun intended) and possible future trend.
-
-Although it was not clearly documented before, it is still necessary to
-build your application using the same __CLEANUP_* define as was
-used for the version of the library that you link with, so that the
-correct parts of pthread.h are included. That is, the possible
-defines require the following library versions:
-
-        __CLEANUP_SEH   pthreadVSE.dll
-        __CLEANUP_CXX   pthreadVCE.dll or pthreadGCE.dll
-        __CLEANUP_C     pthreadVC.dll or pthreadGC.dll
-
-E.g. regardless of whether your app is C or C++, if you link with
-pthreadVC.lib or libpthreadGC.a, then you must define __CLEANUP_C.
-
-
-THE POINT OF ALL THIS IS: if you have not been defining one of these
-explicitly, then the defaults as described at the top of this
-section were being used.
-
-THIS NOW CHANGES, as has been explained above, but to try to make this
-clearer here's an example:
-
-If you were building your application with MSVC++ i.e. using C++
-exceptions and not explicitly defining one of __CLEANUP_*, then
-__CLEANUP_C++ was automatically defined for you in pthread.h.
-You should have been linking with pthreadVCE.dll, which does
-stack unwinding.
-
-If you now build your application as you had before, pthread.h will now
-automatically set __CLEANUP_C as the default style, and you will need to
-link with pthreadVC.dll. Stack unwinding will now NOT occur when a thread
-is canceled, or the thread calls pthread_exit().
-
-Your application will now most likely behave differently to previous
-versions, and in non-obvious ways. Most likely is that locally
-instantiated objects may not be destroyed or cleaned up after a thread
-is canceled.
-
-If you want the same behaviour as before, then you must now define
-__CLEANUP_C++ explicitly using a compiler option and link with
-pthreadVCE.dll as you did before.
-
-
-WHY ARE WE MAKING THE DEFAULT STYLE LESS EXCEPTION-FRIENDLY?
-Because no commercial Unix POSIX threads implementation allows you to
-choose to have stack unwinding. Therefore, providing it in pthread-win32
-as a default is dangerous. We still provide the choice but unless
-you consciously choose to do otherwise, your pthreads applications will
-now run or crash in similar ways irrespective of the threads platform
-you use. Or at least this is the hope.
-
-
-WHY NOT REMOVE THE EXCEPTIONS VERSIONS OF THE LIBRARY ALTOGETHER?
-There are a few reasons:
-- because there are well respected POSIX threads people who believe
-  that POSIX threads implementations should be exceptions aware and
-  do the expected thing in that context. (There are equally respected
-  people who believe it should not be easily accessible, if it's there
-  at all, for unconditional conformity to other implementations.)
-- because pthreads-win32 is one of the few implementations that has
-  the choice, perhaps the only freely available one, and so offers
-  a laboratory to people who may want to explore the effects;
-- although the code will always be around somewhere for anyone who
-  wants it, once it's removed from the current version it will not be
-  nearly as visible to people who may have a use for it.
-
-
-Source module splitting
------------------------
-In order to enable smaller image sizes to be generated
-for applications that link statically with the library,
-most routines have been separated out into individual
-source code files.
-
-This is being done in such a way as to be backward compatible.
-The old source files are reused to congregate the individual
-routine files into larger translation units (via a bunch of
-# includes) so that the compiler can still optimise wherever
-possible, e.g. through inlining, which can only be done
-within the same translation unit.
-
-It is also possible to build the entire library by compiling
-the single file named "pthread.c", which just #includes all
-the secondary congregation source files. The compiler
-may be able to use this to do more inlining of routines.
-
-Although the GNU compiler is able to produce libraries with
-the necessary separation (the -ffunction-segments switch),
-AFAIK, the MSVC and other compilers don't have this feature.
-
-Finally, since I use makefiles and command-line compilation,
-I don't know what havoc this reorganisation may wreak amongst
-IDE project file users. You should be able to continue
-using your existing project files without modification.
-
-
-New non-portable functions
---------------------------
-pthread_num_processors_np():
-  Returns the number of processors in the system that are
-  available to the process, as determined from the processor
-  affinity mask.
-
-pthread_timechange_handler_np():
-  To improve tolerance against operator or time service initiated
-  system clock changes.
-
-  This routine can be called by an application when it
-  receives a WM_TIMECHANGE message from the system. At present
-  it broadcasts all condition variables so that waiting threads
-  can wake up and re-evaluate their conditions and restart
-  their timed waits if required.
-  - Suggested by Alexander Terekhov
-
-
-Platform dependence
--------------------
-As Win95 doesn't provide one, the library now contains
-it's own InterlockedCompareExchange() routine, which is used
-whenever Windows doesn't provide it. InterlockedCompareExchange()
-is used to implement spinlocks and barriers, and also in mutexes.
-This routine relies on the CMPXCHG machine instruction which
-is not available on i386 CPUs. This library (from snapshot
-20010712 onwards) is therefore no longer supported on i386
-processor platforms.
-
-
-New standard routines
----------------------
-For source code portability only - rwlocks cannot be process shared yet.
-
-        pthread_rwlockattr_init()
-        pthread_rwlockattr_destroy()
-        pthread_rwlockattr_setpshared()
-        pthread_rwlockattr_getpshared()
-
-As defined in the new POSIX standard, and the Single Unix Spec version 3:
-
-        sem_timedwait()
-        pthread_mutex_timedlock()    - Alexander Terekhov and Thomas Pfaff
-        pthread_rwlock_timedrdlock() - adapted from pthread_rwlock_rdlock()
-        pthread_rwlock_timedwrlock() - adapted from pthread_rwlock_wrlock()
-
-
-pthread.h no longer includes windows.h
---------------------------------------
-[Not yet for G++]
-
-This was done to prevent conflicts.
-
-HANDLE, DWORD, and NULL are temporarily defined within pthread.h if
-they are not already.
-
-
-pthread.h, sched.h and semaphore.h now use dllexport/dllimport
---------------------------------------------------------------
-Not only to avoid the need for the pthread.def file, but to
-improve performance. Apparently, declaring functions with dllimport
-generates a direct call to the function and avoids the overhead
-of a stub function call.
-
-Bug fixes
----------
-* Fixed potential NULL pointer dereferences in pthread_mutexattr_init,
-pthread_mutexattr_getpshared, pthread_barrierattr_init,
-pthread_barrierattr_getpshared, and pthread_condattr_getpshared.
-- Scott McCaskill <scott at magruder.org>
-
-* Removed potential race condition in pthread_mutex_trylock and
-pthread_mutex_lock;
-- Alexander Terekhov <TEREKHOV at de.ibm.com>
-
-* The behaviour of pthread_mutex_trylock in relation to
-recursive mutexes was inconsistent with commercial implementations.
-Trylock would return EBUSY if the lock was owned already by the
-calling thread regardless of mutex type. Trylock now increments the
-recursion count and returns 0 for RECURSIVE mutexes, and will
-return EDEADLK rather than EBUSY for ERRORCHECK mutexes. This is
-consistent with Solaris.
-- Thomas Pfaff <tpfaff at gmx.net>
-
-* Found a fix for the library and workaround for applications for
-the known bug #2, i.e. where __CLEANUP_CXX or __CLEANUP_SEH is defined.
-See the "Known Bugs in this snapshot" section below.
-
-This could be made transparent to applications by replacing the macros that
-define the current C++ and SEH versions of pthread_cleanup_push/pop
-with the C version, but AFAIK cleanup handlers would not then run in the
-correct sequence with destructors and exception cleanup handlers when
-an exception occurs.
-
-* Cancelation once started in a thread cannot now be inadvertantly
-double canceled. That is, once a thread begins it's cancelation run,
-cancelation is disabled and a subsequent cancel request will
-return an error (ESRCH).
-
-* errno: An incorrect compiler directive caused a local version
-of errno to be used instead of the Win32 errno. Both instances are
-thread-safe but applications checking errno after a pthreads-win32
-call would be wrong. Fixing this also fixed a bad compiler
-option in the testsuite (/MT should have been /MD) which is
-needed to link with the correct library MSVCRT.LIB.
-
-
-SNAPSHOT 2001-07-12
--------------------
-
-To be added
-
-
-SNAPSHOT 2001-07-03
--------------------
-
-To be added
-
-
-SNAPSHOT 2000-08-13
--------------------
-
-New:
--       Renamed DLL and LIB files:
-                pthreadVSE.dll  (MS VC++/Structured EH)
-                pthreadVSE.lib
-                pthreadVCE.dll  (MS VC++/C++ EH)
-                pthreadVCE.lib
-                pthreadGCE.dll  (GNU G++/C++ EH)
-                libpthreadw32.a
-
-        Both your application and the pthread dll should use the
-        same exception handling scheme.
-
-Bugs fixed:
--       MSVC++ C++ exception handling.
-
-Some new tests have been added.
-
-
-SNAPSHOT 2000-08-10
--------------------
-
-New:
--       asynchronous cancelation on X86 (Jason Nye)
--       Makefile compatible with MS nmake to replace
-        buildlib.bat
--       GNUmakefile for Mingw32
--       tests/Makefile for MS nmake replaces runall.bat
--       tests/GNUmakefile for Mingw32
-
-Bugs fixed:
--       kernel32 load/free problem
--       attempt to hide internel exceptions from application
-        exception handlers (__try/__except and try/catch blocks)
--       Win32 thread handle leakage bug
-        (David Baggett/Paul Redondo/Eyal Lebedinsky)
-
-Some new tests have been added.
-
-
-SNAPSHOT 1999-11-02
--------------------
-
-Bugs fixed:
--       ctime_r macro had an incorrect argument (Erik Hensema),
--       threads were not being created 
-        PTHREAD_CANCEL_DEFERRED. This should have
-        had little effect as deferred is the only
-        supported type. (Ross Johnson).
-
-Some compatibility improvements added, eg.
--       pthread_setcancelstate accepts NULL pointer
-        for the previous value argument. Ditto for
-        pthread_setcanceltype. This is compatible
-        with Solaris but should not affect
-        standard applications (Erik Hensema)
-
-Some new tests have been added.
-
-
-SNAPSHOT 1999-10-17
--------------------
-
-Bug fix - Cancelation of threads waiting on condition variables
-now works properly (Lorin Hochstein and Peter Slacik)
-
-
-SNAPSHOT 1999-08-12
--------------------
-
-Fixed exception stack cleanup if calling pthread_exit()
-- (Lorin Hochstein and John Bossom).
-
-Fixed bugs in condition variables - (Peter Slacik):
-        - additional contention checks
-        - properly adjust number of waiting threads after timed
-          condvar timeout.
-
-
-SNAPSHOT 1999-05-30
--------------------
-
-Some minor bugs have been fixed. See the ChangeLog file for details.
-
-Some more POSIX 1b functions are now included but ony return an
-error (ENOSYS) if called. They are:
-
-        sem_open
-        sem_close
-        sem_unlink
-        sem_getvalue
-
-
-SNAPSHOT 1999-04-07
--------------------
-
-Some POSIX 1b functions which were internally supported are now
-available as exported functions:
-
-        sem_init
-        sem_destroy
-        sem_wait
-        sem_trywait
-        sem_post
-        sched_yield
-        sched_get_priority_min
-        sched_get_priority_max
-
-Some minor bugs have been fixed. See the ChangeLog file for details.
-
-
-SNAPSHOT 1999-03-16
--------------------
-
-Initial release.
-
diff --git a/deps/w32-pthreads/Nmakefile b/deps/w32-pthreads/Nmakefile
deleted file mode 100644
index d9e5bf1..0000000
--- a/deps/w32-pthreads/Nmakefile
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * nmake file for uwin pthread library
- */
-
-VERSION 		= -
-CCFLAGS 		= -V -g $(CC.DLL)
-HAVE_PTW32_CONFIG_H	== 1
-_MT			== 1
-_timeb		== timeb
-_ftime		== ftime
-_errno		== _ast_errno
-
-$(INCLUDEDIR)	:INSTALLDIR:	pthread.h sched.h
-
-pthread $(VERSION) :LIBRARY: attr.c barrier.c cancel.c cleanup.c condvar.c \
-	create.c dll.c exit.c fork.c global.c misc.c mutex.c private.c \
-	rwlock.c sched.c semaphore.c spin.c sync.c tsd.c nonportable.c
-
-:: ANNOUNCE CONTRIBUTORS COPYING.LIB ChangeLog FAQ GNUmakefile MAINTAINERS \
-	Makefile Makefile.in Makefile.vc NEWS PROGRESS README README.WinCE \
-	TODO WinCE-PORT install-sh errno.c tests tests.mk acconfig.h \
-	config.guess config.h.in config.sub configure configure.in signal.c \
-	README.CV README.NONPORTABLE pthread.dsp pthread.dsw
-
diff --git a/deps/w32-pthreads/Nmakefile.tests b/deps/w32-pthreads/Nmakefile.tests
deleted file mode 100644
index 203560b..0000000
--- a/deps/w32-pthreads/Nmakefile.tests
+++ /dev/null
@@ -1,260 +0,0 @@
-/* for running tests */
-CCFLAGS 	= -g 
-_MT		== 1
-_timeb	== timeb
-_ftime	== ftime 
-
-.SOURCE:	tests
-/*
-:PACKAGE:	pthread
-*/
-
-set keepgoing
-
-":test:" : .MAKE .OPERATOR
-	local I
-	$(<:D:B:S=.pass) : .IMPLICIT $(>:D:B:S=.pass)
-	for I $(<) $(>)
-		$(I:D:B:S=.pass) : .VIRTUAL .FORCE $(I)
-			$(>)
-	end
-sizes::		sizes.c
-loadfree::	loadfree.c
-mutex1::	mutex1.c
-mutex1e::	mutex1e.c
-mutex1n::	mutex1n.c
-mutex1r::	mutex1r.c
-mutex2::	mutex2.c
-mutex2r::	mutex2r.c
-mutex2e::	mutex2e.c
-exit1::	exit1.c
-condvar1::	condvar1.c
-condvar1_1::	condvar1_1.c
-condvar1_2::	condvar1_2.c
-self1::		self1.c
-condvar2::	condvar2.c
-condvar2_1::	condvar2_1.c
-condvar3_1::	condvar3_1.c
-condvar3_2::	condvar3_2.c
-condvar3_3::	condvar3_3.c
-create1.::	create1.c
-create2.::	create2.c
-cancel1::	cancel1.c
-cancel2::	cancel2.c
-mutex3::	mutex3.c
-mutex3r::	mutex3r.c
-mutex3e::	mutex3e.c
-mutex4::	mutex4.c
-mutex5::	mutex5.c
-mutex6::	mutex6.c
-mutex6e::	mutex6e.c
-mutex6n::	mutex6n.c
-mutex6r::	mutex6r.c
-mutex7::	mutex7.c
-mutex6s::	mutex6s.c
-mutex6rs::	mutex6rs.c
-mutex6es::	mutex6es.c
-mutex7e::	mutex7e.c
-mutex7n::	mutex7n.c
-mutex7r::	mutex7r.c
-mutex8::	mutex8.c
-mutex8e::	mutex8e.c
-mutex8n::	mutex8n.c
-mutex8r::	mutex8r.c
-equal1::	equal1.c
-exit2::		exit2.c
-exit3::		exit3.c
-exit4::		exit4.c
-exit5::		exit5.c
-join0::		join0.c
-join1::		join1.c
-join2::		join2.c
-join3::		join3.c
-kill1::		kill1.c
-count1::	count1.c
-once1::		once1.c
-tsd1::		tsd1.c
-self2::		self2.c
-eyal1::		eyal1.c
-condvar3::	condvar3.c
-condvar4::	condvar4.c
-condvar5::	condvar5.c
-condvar6::	condvar6.c
-condvar7::	condvar7.c
-condvar8::	condvar8.c
-condvar9::	condvar9.c
-errno1::	errno1.c
-reuse1.::	reuse1.c
-reuse2.::	reuse2.c
-rwlock1::	rwlock1.c
-rwlock2::	rwlock2.c
-rwlock3::	rwlock3.c
-rwlock4::	rwlock4.c
-rwlock5::	rwlock5.c
-rwlock6::	rwlock6.c
-rwlock7::	rwlock7.c
-rwlock8::	rwlock8.c
-rwlock2_t::	rwlock2_t.c
-rwlock3_t::	rwlock3_t.c
-rwlock4_t::	rwlock4_t.c
-rwlock5_t::	rwlock5_t.c
-rwlock6_t::	rwlock6_t.c
-rwlock6_t2::	rwlock6_t2.c
-semaphore1::	semaphore1.c
-semaphore2::	semaphore2.c
-semaphore3::	semaphore3.c
-context1::	context1.c
-cancel3::	cancel3.c
-cancel4::	cancel4.c
-cancel5::	cancel5.c
-cancel6a::	cancel6a.c
-cancel6d::	cancel6d.c
-cancel7::	cancel7.c
-cleanup0::	cleanup0.c
-cleanup1::	cleanup1.c
-cleanup2::	cleanup2.c
-cleanup3::	cleanup3.c
-priority1::     priority1.c
-priority2::     priority2.c
-inherit1::      inherit1.c
-spin1::         spin1.c
-spin2::         spin2.c
-spin3::         spin3.c
-spin4::         spin4.c
-barrier1::      barrier1.c
-barrier2::      barrier2.c
-barrier3::      barrier3.c
-barrier4::      barrier4.c
-barrier5::      barrier5.c
-exception1::	exception1.c
-exception2::	exception2.c
-exception3::	exception3.c
-benchtest1::    benchtest1.c
-benchtest2::    benchtest2.c
-benchtest3::    benchtest3.c
-benchtest4::    benchtest4.c
-benchtest5::    benchtest5.c
-valid1::	valid1.c
-valid2::	valid2.c
-cancel9::	cancel9.c
-
-sizes:		:test:	sizes
-loadfree:	:test:
-mutex5		:test:	loadfree
-mutex1		:test:	loadfree
-mutex1n		:test:	loadfree
-mutex1r		:test:	loadfree
-mutex1e		:test:	loadfree
-semaphore1	:test:	loadfree
-semaphore2	:test:	loadfree
-semaphore3	:test:	loadfree
-mutex2		:test:	loadfree
-mutex2r		:test:	loadfree
-mutex2e		:test:	loadfree
-exit1		:test:	loadfree
-condvar1	:test:	loadfree
-kill1		:test:	loadfree
-condvar1_1	:test:	condvar1
-condvar1_2	:test:	join2
-self1		:test:	loadfree
-condvar2	:test:	condvar1
-condvar2_1	:test:	condvar2
-create1 	:test:	mutex2
-create2 	:test:	create1
-reuse1 		:test:	create2
-reuse2 		:test:	reuse1
-cancel1		:test:	create1
-cancel2		:test:	cancel1
-mutex3		:test:	create1
-mutex3r		:test:	create1
-mutex3e		:test:	create1
-mutex4		:test:	mutex3
-mutex6		:test:	mutex4
-mutex6n		:test:	mutex4
-mutex6e		:test:	mutex4
-mutex6r		:test:	mutex4
-mutex6s		:test:	mutex6
-mutex6rs	:test:	mutex6r
-mutex6es	:test:	mutex6e
-mutex7		:test:	mutex6
-mutex7n		:test:	mutex6n
-mutex7e		:test:	mutex6e
-mutex7r		:test:	mutex6r
-mutex8		:test:	mutex7
-mutex8n		:test:	mutex7n
-mutex8e		:test:	mutex7e
-mutex8r		:test:	mutex7r
-equal1		:test:	create1
-exit2		:test:	create1
-exit3		:test:	create1
-exit4		:test:	kill1
-exit5		:test:	exit4
-join0		:test:	create1
-join1		:test:	create1
-join2		:test:	create1
-join3		:test:	join2
-count1		:test:	join1
-once1		:test:	create1
-tsd1		:test:	join1
-self2		:test:	create1
-eyal1		:test:	tsd1
-condvar3	:test:	create1
-condvar3_1	:test:	condvar3
-condvar3_2	:test:	condvar3_1
-condvar3_3	:test:	condvar3_2
-condvar4	:test:	create1
-condvar5	:test:	condvar4
-condvar6	:test:	condvar5
-condvar7	:test:	condvar6	cleanup1
-condvar8	:test:	condvar7
-condvar9	:test:	condvar8
-errno1		:test:	mutex3
-rwlock1		:test:	condvar6
-rwlock2		:test:	rwlock1
-rwlock3		:test:	rwlock2
-rwlock4		:test:	rwlock3
-rwlock5		:test:	rwlock4
-rwlock6		:test:	rwlock5
-rwlock7		:test:	rwlock6
-rwlock8		:test:	rwlock7
-rwlock2_t	:test:	rwlock2
-rwlock3_t	:test:	rwlock2_t
-rwlock4_t	:test:	rwlock3_t
-rwlock5_t	:test:	rwlock4_t
-rwlock6_t	:test:	rwlock5_t
-rwlock6_t2	:test:	rwlock6_t
-context1	:test:	cancel2
-cancel3		:test:	context1
-cancel4		:test:	cancel3
-cancel5		:test:	cancel3
-cancel6a	:test:	cancel3
-cancel6d	:test:	cancel3
-cancel7		:test:	kill1
-cleanup0	:test:	cancel5
-cleanup1	:test:	cleanup0
-cleanup2	:test:	cleanup1
-cleanup3	:test:	cleanup2
-priority1       :test:  join1
-priority2       :test:  priority1
-inherit1        :test:  join1
-spin1           :test:
-spin2           :test:  spin1.c
-spin3           :test:  spin2.c
-spin4           :test:  spin3.c
-barrier1        :test:
-barrier2        :test:  barrier1.c
-barrier3        :test:  barrier2.c
-barrier4        :test:  barrier3.c
-barrier5        :test:  barrier4.c
-benchtest1      :test:  mutex3
-benchtest2      :test:  benchtest1
-benchtest3      :test:  benchtest2
-benchtest4      :test:  benchtest3
-benchtest5      :test:  benchtest4
-exception1	:test:	cancel4
-exception2	:test:	exception1
-exception3	:test:	exception2
-exit4		:test:	exit3
-valid1		:test:	join1
-valid2		:test:	valid1
-cancel9		:test:	cancel8
diff --git a/deps/w32-pthreads/PROGRESS b/deps/w32-pthreads/PROGRESS
deleted file mode 100644
index 9abf0bc..0000000
--- a/deps/w32-pthreads/PROGRESS
+++ /dev/null
@@ -1,4 +0,0 @@
-Please see the ANNOUNCE file "Level of Standards Conformance"
-or the web page:
-
-http://sources.redhat.com/pthreads-win32/conformance.html
diff --git a/deps/w32-pthreads/README b/deps/w32-pthreads/README
deleted file mode 100644
index 545360b..0000000
--- a/deps/w32-pthreads/README
+++ /dev/null
@@ -1,601 +0,0 @@
-PTHREADS-WIN32
-==============
-
-Pthreads-win32 is free software, distributed under the GNU Lesser
-General Public License (LGPL). See the file 'COPYING.LIB' for terms
-and conditions. Also see the file 'COPYING' for information
-specific to pthreads-win32, copyrights and the LGPL.
-
-
-What is it?
------------
-
-Pthreads-win32 is an Open Source Software implementation of the
-Threads component of the POSIX 1003.1c 1995 Standard (or later)
-for Microsoft's Win32 environment. Some functions from POSIX
-1003.1b are also supported including semaphores. Other related
-functions include the set of read-write lock functions. The
-library also supports some of the functionality of the Open
-Group's Single Unix specification, version 2, namely mutex types,
-plus some common and pthreads-win32 specific non-portable
-routines (see README.NONPORTABLE).
-
-See the file "ANNOUNCE" for more information including standards
-conformance details and the list of supported and unsupported
-routines.
-
-
-Prerequisites
--------------
-MSVC or GNU C (MinGW32 MSys development kit)
-	To build from source.
-
-QueueUserAPCEx by Panagiotis E. Hadjidoukas
-	To support any thread cancelation in C++ library builds or
-	to support cancelation of blocked threads in any build.
-	This library is not required otherwise.
-
-	For true async cancelation of threads (including blocked threads).
-	This is a DLL and Windows driver that provides pre-emptive APC
-	by forcing threads into an alertable state when the APC is queued.
-	Both the DLL and driver are provided with the pthreads-win32.exe
-	self-unpacking ZIP, and on the pthreads-win32 FTP site  (in source
-	and pre-built forms). Currently this is a separate LGPL package to
-	pthreads-win32. See the README in the QueueUserAPCEx folder for
-	installation instructions.
-
-	Pthreads-win32 will automatically detect if the QueueUserAPCEx DLL
-	QuserEx.DLL is available and whether the driver AlertDrv.sys is
-	loaded. If it is not available, pthreads-win32 will simulate async
-	cancelation, which means that it can async cancel only threads that
-	are runnable. The simulated async cancellation cannot cancel blocked
-	threads.
-
-        [FOR SECURITY] To be found Quserex.dll MUST be installed in the
-	Windows System Folder. This is not an unreasonable constraint given a
-	driver must also be installed and loaded at system startup.
-
-
-Library naming
---------------
-
-Because the library is being built using various exception
-handling schemes and compilers - and because the library
-may not work reliably if these are mixed in an application,
-each different version of the library has it's own name.
-
-Note 1: the incompatibility is really between EH implementations
-of the different compilers. It should be possible to use the
-standard C version from either compiler with C++ applications
-built with a different compiler. If you use an EH version of
-the library, then you must use the same compiler for the
-application. This is another complication and dependency that
-can be avoided by using only the standard C library version.
-
-Note 2: if you use a standard C pthread*.dll with a C++
-application, then any functions that you define that are
-intended to be called via pthread_cleanup_push() must be
-__cdecl.
-
-Note 3: the intention was to also name either the VC or GC
-version (it should be arbitrary) as pthread.dll, including
-pthread.lib and libpthread.a as appropriate. This is no longer
-likely to happen.
-
-Note 4: the compatibility number was added so that applications
-can differentiate between binary incompatible versions of the
-libs and dlls.
-
-In general:
-	pthread[VG]{SE,CE,C}[c].dll
-	pthread[VG]{SE,CE,C}[c].lib
-
-where:
-	[VG] indicates the compiler
-	V	- MS VC, or
-	G	- GNU C
-
-	{SE,CE,C} indicates the exception handling scheme
-	SE	- Structured EH, or
-	CE	- C++ EH, or
-	C	- no exceptions - uses setjmp/longjmp
-
-	c	- DLL compatibility number indicating ABI and API
-		  compatibility with applications built against
-		  a snapshot with the same compatibility number.
-		  See 'Version numbering' below.
-
-The name may also be suffixed by a 'd' to indicate a debugging version
-of the library. E.g. pthreadVC2d.lib. Debugging versions contain
-additional information for debugging (symbols etc) and are often not
-optimised in any way (compiled with optimisation turned off).
-
-Examples:
-	pthreadVSE.dll	(MSVC/SEH)
-	pthreadGCE.dll	(GNUC/C++ EH)
-	pthreadGC.dll	(GNUC/not dependent on exceptions)
-	pthreadVC1.dll	(MSVC/not dependent on exceptions - not binary
-			compatible with pthreadVC.dll)
-	pthreadVC2.dll	(MSVC/not dependent on exceptions - not binary
-			compatible with pthreadVC1.dll or pthreadVC.dll)
-
-The GNU library archive file names have correspondingly changed to:
-
-	libpthreadGCEc.a
-	libpthreadGCc.a
-
-
-Versioning numbering
---------------------
-
-Version numbering is separate from the snapshot dating system, and
-is the canonical version identification system embedded within the
-DLL using the Microsoft version resource system. The versioning
-system chosen follows the GNU Libtool system. See
-http://www.gnu.org/software/libtool/manual.html section 6.2.
-
-See the resource file 'version.rc'.
-
-Microsoft version numbers use 4 integers:
-
-	0.0.0.0
-
-Pthreads-win32 uses the first 3 following the Libtool convention.
-The fourth is commonly used for the build number, but will be reserved
-for future use.
-
-	current.revision.age.0
-
-The numbers are changed as follows:
-
-1. If the library source code has changed at all since the last update,
-   then increment revision (`c:r:a' becomes `c:r+1:a').
-2. If any interfaces have been added, removed, or changed since the last
-   update, increment current, and set revision to 0.
-3. If any interfaces have been added since the last public release, then
-   increment age.
-4. If any interfaces have been removed or changed since the last public
-   release, then set age to 0.
-
-
-DLL compatibility numbering is an attempt to ensure that applications
-always load a compatible pthreads-win32 DLL by using a DLL naming system
-that is consistent with the version numbering system. It also allows
-older and newer DLLs to coexist in the same filesystem so that older
-applications can continue to be used. For pre .NET Windows systems,
-this inevitably requires incompatible versions of the same DLLs to have
-different names.
-
-Pthreads-win32 has adopted the Cygwin convention of appending a single
-integer number to the DLL name. The number used is based on the library
-version number and is computed as 'current' - 'age'.
-
-(See http://home.att.net/~perlspinr/libversioning.html for a nicely
-detailed explanation.)
-
-Using this method, DLL name/s will only change when the DLL's
-backwards compatibility changes. Note that the addition of new
-'interfaces' will not of itself change the DLL's compatibility for older
-applications.
-
-
-Which of the several dll versions to use?
------------------------------------------
-or,
----
-What are all these pthread*.dll and pthread*.lib files?
--------------------------------------------------------
-
-Simple, use either pthreadGCv.* if you use GCC, or pthreadVCv.* if you
-use MSVC - where 'v' is the DLL versioning (compatibility) number.
-
-Otherwise, you need to choose carefully and know WHY.
-
-The most important choice you need to make is whether to use a
-version that uses exceptions internally, or not. There are versions
-of the library that use exceptions as part of the thread
-cancelation and exit implementation. The default version uses
-setjmp/longjmp.
-
-There is some contension amongst POSIX threads experts as
-to how POSIX threads cancelation and exit should work
-with languages that use exceptions, e.g. C++ and even C
-(Microsoft's Structured Exceptions).
-
-The issue is: should cancelation of a thread in, say,
-a C++ application cause object destructors and C++ exception
-handlers to be invoked as the stack unwinds during thread
-exit, or not?
-
-There seems to be more opinion in favour of using the
-standard C version of the library (no EH) with C++ applications
-for the reason that this appears to be the assumption commercial
-pthreads implementations make. Therefore, if you use an EH version
-of pthreads-win32 then you may be under the illusion that
-your application will be portable, when in fact it is likely to
-behave differently when linked with other pthreads libraries.
-
-Now you may be asking: then why have you kept the EH versions of
-the library?
-
-There are a couple of reasons:
-- there is division amongst the experts and so the code may
-  be needed in the future. Yes, it's in the repository and we
-  can get it out anytime in the future, but it would be difficult
-  to find.
-- pthreads-win32 is one of the few implementations, and possibly
-  the only freely available one, that has EH versions. It may be
-  useful to people who want to play with or study application
-  behaviour under these conditions.
-
-Notes:
-
-[If you use either pthreadVCE or pthreadGCE]
-
-1. [See also the discussion in the FAQ file - Q2, Q4, and Q5]
-
-If your application contains catch(...) blocks in your POSIX
-threads then you will need to replace the "catch(...)" with the macro
-"PtW32Catch", eg.
-
-	#ifdef PtW32Catch
-		PtW32Catch {
-			...
-		}
-	#else
-		catch(...) {
-			...
-		}
-	#endif
-
-Otherwise neither pthreads cancelation nor pthread_exit() will work
-reliably when using versions of the library that use C++ exceptions
-for cancelation and thread exit.
-
-This is due to what is believed to be a C++ compliance error in VC++
-whereby you may not have multiple handlers for the same exception in
-the same try/catch block. GNU G++ doesn't have this restriction.
-
-
-Other name changes
-------------------
-
-All snapshots prior to and including snapshot 2000-08-13
-used "_pthread_" as the prefix to library internal
-functions, and "_PTHREAD_" to many library internal
-macros. These have now been changed to "ptw32_" and "PTW32_"
-respectively so as to not conflict with the ANSI standard's
-reservation of identifiers beginning with "_" and "__" for
-use by compiler implementations only.
-
-If you have written any applications and you are linking
-statically with the pthreads-win32 library then you may have
-included a call to _pthread_processInitialize. You will
-now have to change that to ptw32_processInitialize.
-
-
-Cleanup code default style
---------------------------
-
-Previously, if not defined, the cleanup style was determined automatically
-from the compiler used, and one of the following was defined accordingly:
-
-	__CLEANUP_SEH	MSVC only
-	__CLEANUP_CXX	C++, including MSVC++, GNU G++
-	__CLEANUP_C	C, including GNU GCC, not MSVC
-
-These defines determine the style of cleanup (see pthread.h) and,
-most importantly, the way that cancelation and thread exit (via
-pthread_exit) is performed (see the routine ptw32_throw()).
-
-In short, the exceptions versions of the library throw an exception
-when a thread is canceled, or exits via pthread_exit(). This exception is
-caught by a handler in the thread startup routine, so that the
-the correct stack unwinding occurs regardless of where the thread
-is when it's canceled or exits via pthread_exit().
-
-In this snapshot, unless the build explicitly defines (e.g. via a
-compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
-the build NOW always defaults to __CLEANUP_C style cleanup. This style
-uses setjmp/longjmp in the cancelation and pthread_exit implementations,
-and therefore won't do stack unwinding even when linked to applications
-that have it (e.g. C++ apps). This is for consistency with most/all
-commercial Unix POSIX threads implementations.
-
-Although it was not clearly documented before, it is still necessary to
-build your application using the same __CLEANUP_* define as was
-used for the version of the library that you link with, so that the
-correct parts of pthread.h are included. That is, the possible
-defines require the following library versions:
-
-	__CLEANUP_SEH	pthreadVSE.dll
-	__CLEANUP_CXX	pthreadVCE.dll or pthreadGCE.dll
-	__CLEANUP_C	pthreadVC.dll or pthreadGC.dll
-
-It is recommended that you let pthread.h use it's default __CLEANUP_C
-for both library and application builds. That is, don't define any of
-the above, and then link with pthreadVC.lib (MSVC or MSVC++) and
-libpthreadGC.a (MinGW GCC or G++). The reason is explained below, but
-another reason is that the prebuilt pthreadVCE.dll is currently broken.
-Versions built with MSVC++ later than version 6 may not be broken, but I
-can't verify this yet.
-
-WHY ARE WE MAKING THE DEFAULT STYLE LESS EXCEPTION-FRIENDLY?
-Because no commercial Unix POSIX threads implementation allows you to
-choose to have stack unwinding. Therefore, providing it in pthread-win32
-as a default is dangerous. We still provide the choice but unless
-you consciously choose to do otherwise, your pthreads applications will
-now run or crash in similar ways irrespective of the pthreads platform
-you use. Or at least this is the hope.
-
-
-Building under VC++ using C++ EH, Structured EH, or just C
-----------------------------------------------------------
-
-From the source directory run nmake without any arguments to list
-help information. E.g.
-
-$ nmake
-
-Microsoft (R) Program Maintenance Utility   Version 6.00.8168.0
-Copyright (C) Microsoft Corp 1988-1998. All rights reserved.
-
-Run one of the following command lines:
-nmake clean VCE (to build the MSVC dll with C++ exception handling)
-nmake clean VSE (to build the MSVC dll with structured exception handling)
-nmake clean VC (to build the MSVC dll with C cleanup code)
-nmake clean VCE-inlined (to build the MSVC inlined dll with C++ exception handling)
-nmake clean VSE-inlined (to build the MSVC inlined dll with structured exception handling)
-nmake clean VC-inlined (to build the MSVC inlined dll with C cleanup code)
-nmake clean VC-static (to build the MSVC static lib with C cleanup code)
-nmake clean VCE-debug (to build the debug MSVC dll with C++ exception handling)
-nmake clean VSE-debug (to build the debug MSVC dll with structured exception handling)
-nmake clean VC-debug (to build the debug MSVC dll with C cleanup code)
-nmake clean VCE-inlined-debug (to build the debug MSVC inlined dll with C++ exception handling)
-nmake clean VSE-inlined-debug (to build the debug MSVC inlined dll with structured exception handling)
-nmake clean VC-inlined-debug (to build the debug MSVC inlined dll with C cleanup code)
-nmake clean VC-static-debug (to build the debug MSVC static lib with C cleanup code)
-
-
-The pre-built dlls are normally built using the *-inlined targets.
-
-You can run the testsuite by changing to the "tests" directory and
-running nmake. E.g.:
-
-$ cd tests
-$ nmake
-
-Microsoft (R) Program Maintenance Utility   Version 6.00.8168.0
-Copyright (C) Microsoft Corp 1988-1998. All rights reserved.
-
-Run one of the following command lines:
-nmake clean VC (to test using VC dll with VC (no EH) applications)
-nmake clean VCX (to test using VC dll with VC++ (EH) applications)
-nmake clean VCE (to test using the VCE dll with VC++ EH applications)
-nmake clean VSE (to test using VSE dll with VC (SEH) applications)
-nmake clean VC-bench (to benchtest using VC dll with C bench app)
-nmake clean VCX-bench (to benchtest using VC dll with C++ bench app)
-nmake clean VCE-bench (to benchtest using VCE dll with C++ bench app)
-nmake clean VSE-bench (to benchtest using VSE dll with SEH bench app)
-nmake clean VC-static (to test using VC static lib with VC (no EH) applications)
-
-
-Building under Mingw32
-----------------------
-
-The dll can be built easily with recent versions of Mingw32.
-(The distributed versions are built using Mingw32 and MsysDTK
-from www.mingw32.org.)
-
-From the source directory, run make for help information. E.g.:
-
-$ make
-Run one of the following command lines:
-make clean GC            (to build the GNU C dll with C cleanup code)
-make clean GCE           (to build the GNU C dll with C++ exception handling)
-make clean GC-inlined    (to build the GNU C inlined dll with C cleanup code)
-make clean GCE-inlined   (to build the GNU C inlined dll with C++ exception handling)
-make clean GC-static     (to build the GNU C inlined static lib with C cleanup code)
-make clean GC-debug      (to build the GNU C debug dll with C cleanup code)
-make clean GCE-debug     (to build the GNU C debug dll with C++ exception handling)
-make clean GC-inlined-debug    (to build the GNU C inlined debug dll with C cleanup code)
-make clean GCE-inlined-debug   (to build the GNU C inlined debug dll with C++ exception handling)
-make clean GC-static-debug     (to build the GNU C inlined static debug lib with C cleanup code)
-
-
-The pre-built dlls are normally built using the *-inlined targets.
-
-You can run the testsuite by changing to the "tests" directory and
-running make for help information. E.g.:
-
-$ cd tests
-$ make
-Run one of the following command lines:
-make clean GC    (to test using GC dll with C (no EH) applications)
-make clean GCX   (to test using GC dll with C++ (EH) applications)
-make clean GCE   (to test using GCE dll with C++ (EH) applications)
-make clean GC-bench       (to benchtest using GNU C dll with C cleanup code)
-make clean GCE-bench   (to benchtest using GNU C dll with C++ exception handling)
-make clean GC-static   (to test using GC static lib with C (no EH) applications)
-
-
-Building under Linux using the Mingw32 cross development tools
---------------------------------------------------------------
-
-You can build the library without leaving Linux by using the Mingw32 cross
-development toolchain. See http://www.libsdl.org/extras/win32/cross/ for
-tools and info. The GNUmakefile contains some support for this, for example:
-
-make CROSS=i386-mingw32msvc- clean GC-inlined
-
-will build pthreadGCn.dll and libpthreadGCn.a (n=version#), provided your
-cross-tools/bin directory is in your PATH (or use the cross-make.sh script
-at the URL above).
-
-
-Building the library as a statically linkable library
------------------------------------------------------
-
-General: PTW32_STATIC_LIB must be defined for both the library build and the
-application build. The makefiles supplied and used by the following 'make'
-command lines will define this for you.
-
-MSVC (creates pthreadVCn.lib as a static link lib):
-
-nmake clean VC-static
-
-
-MinGW32 (creates libpthreadGCn.a as a static link lib):
-
-make clean GC-static
-
-
-Define PTW32_STATIC_LIB when building your application. Also, your
-application must call a two non-portable routines to initialise the
-some state on startup and cleanup before exit. One other routine needs
-to be called to cleanup after any Win32 threads have called POSIX API
-routines. See README.NONPORTABLE or the html reference manual pages for
-details on these routines:
-
-BOOL pthread_win32_process_attach_np (void);
-BOOL pthread_win32_process_detach_np (void);
-BOOL pthread_win32_thread_attach_np (void); // Currently a no-op
-BOOL pthread_win32_thread_detach_np (void);
-
-
-The tests makefiles have the same targets but only check that the
-static library is statically linkable. They don't run the full
-testsuite. To run the full testsuite, build the dlls and run the
-dll test targets.
-
-
-Building the library under Cygwin
----------------------------------
-
-Cygwin is implementing it's own POSIX threads routines and these
-will be the ones to use if you develop using Cygwin.
-
-
-Ready to run binaries
----------------------
-
-For convenience, the following ready-to-run files can be downloaded
-from the FTP site (see under "Availability" below):
-
-	pthread.h
-	semaphore.h
-	sched.h
-	pthreadVC.dll	- built with MSVC compiler using C setjmp/longjmp
-	pthreadVC.lib
-	pthreadVCE.dll	- built with MSVC++ compiler using C++ EH
-	pthreadVCE.lib
-	pthreadVSE.dll	- built with MSVC compiler using SEH
-	pthreadVSE.lib
-	pthreadGC.dll	- built with Mingw32 GCC
-	libpthreadGC.a	- derived from pthreadGC.dll
-	pthreadGCE.dll	- built with Mingw32 G++
-	libpthreadGCE.a	- derived from pthreadGCE.dll
-
-As of August 2003 pthreads-win32 pthreadG* versions are built and tested
-using the MinGW + MsysDTK environment current as of that date or later.
-The following file MAY be needed for older MinGW environments.
-
-	gcc.dll 	- needed to build and run applications that use
-			  pthreadGCE.dll.
-
-
-Building applications with GNU compilers
-----------------------------------------
-
-If you're using pthreadGC.dll:
-
-With the three header files, pthreadGC.dll and libpthreadGC.a in the
-same directory as your application myapp.c, you could compile, link
-and run myapp.c under Mingw32 as follows:
-
-	gcc -o myapp.exe myapp.c -I. -L. -lpthreadGC
-	myapp
-
-Or put pthreadGC.dll in an appropriate directory in your PATH,
-put libpthreadGC.a in your system lib directory, and
-put the three header files in your system include directory,
-then use:
-
-	gcc -o myapp.exe myapp.c -lpthreadGC
-	myapp
-
-
-If you're using pthreadGCE.dll:
-
-With the three header files, pthreadGCE.dll, gcc.dll and libpthreadGCE.a
-in the same directory as your application myapp.c, you could compile,
-link and run myapp.c under Mingw32 as follows:
-
-	gcc -x c++ -o myapp.exe myapp.c -I. -L. -lpthreadGCE
-	myapp
-
-Or put pthreadGCE.dll and gcc.dll in an appropriate directory in
-your PATH, put libpthreadGCE.a in your system lib directory, and
-put the three header files in your system include directory,
-then use:
-
-	gcc -x c++ -o myapp.exe myapp.c -lpthreadGCE
-	myapp
-
-
-Availability
-------------
-
-The complete source code in either unbundled, self-extracting
-Zip file, or tar/gzipped format can be found at:
-
-	ftp://sources.redhat.com/pub/pthreads-win32
-
-The pre-built DLL, export libraries and matching pthread.h can
-be found at:
-
-	ftp://sources.redhat.com/pub/pthreads-win32/dll-latest
-
-Home page:
-
-	http://sources.redhat.com/pthreads-win32/
-
-
-Mailing list
-------------
-
-There is a mailing list for discussing pthreads on Win32.
-To join, send email to:
-
-	pthreads-win32-subscribe at sources.redhat.com
-
-Unsubscribe by sending mail to:
-
-	pthreads-win32-unsubscribe at sources.redhat.com
-
-
-Acknowledgements
-----------------
-
-See the ANNOUNCE file for acknowledgements.
-See the 'CONTRIBUTORS' file for the list of contributors.
-
-As much as possible, the ChangeLog file attributes
-contributions and patches that have been incorporated
-in the library to the individuals responsible.
-
-Finally, thanks to all those who work on and contribute to the
-POSIX and Single Unix Specification standards. The maturity of an
-industry can be measured by it's open standards.
-
-----
-Ross Johnson
-<rpj at callisto.canberra.edu.au>
-
-
-
-
-
-
-
-
diff --git a/deps/w32-pthreads/README.Borland b/deps/w32-pthreads/README.Borland
deleted file mode 100644
index a130d2b..0000000
--- a/deps/w32-pthreads/README.Borland
+++ /dev/null
@@ -1,57 +0,0 @@
-In ptw32_InterlockedCompareExchange.c, I've added a section for
-Borland's compiler; it's identical to that for the MS compiler except
-that it uses /* ... */ comments instead of ; comments.
-
-[RPJ: need to define HAVE_TASM32 in config.h to use the above.]
-
-
-The other file is a makefile suitable for use with Borland's compiler
-(run "make -fBmakefile" in the directory).  It builds a single version
-of the library, pthreadBC.dll and the corresponding pthreadBC.lib
-import library, which is comparable to the pthreadVC version; I can't
-personally see any demand for the versions that include structured or
-C++ exception cancellation handling so I haven't attempted to build
-those versions of the library.  (I imagine a static version might be
-of use to some, but we can't legally use that on my commercial
-projects so I can't try that out, unfortunately.)
-
-[RPJ: Added tests\Bmakefile as well.]
-
-Borland C++ doesn't define the ENOSYS constant used by pthreads-win32;
-rather than make more extensive patches to the pthreads-win32 source I
-have a mostly-arbitrary constant for it in the makefile.  However this
-doesn't make it visible to the application using the library, so if
-anyone actually wants to use this constant in their apps (why?)
-someone might like to make a seperate NEED_BCC_something define to add
-this stuff.
-
-The makefile also #defines EDEADLK as EDEADLOCK, _timeb as timeb, and
-_ftime as ftime, to deal with the minor differences between the two
-RTLs' naming conventions, and sets the compiler flags as required to
-get a normal compile of the library.
-
-[RPJ: Moved errno values and _timeb etc to pthread.h, so apps will also
-use them.]
-
-(While I'm on the subject, the reason Borland users should recompile
-the library, rather than using the impdef/implib technique suggested
-previously on the mailing list, is that a) the errno constants are
-different, so the results returned by the pthread_* functions can be
-meaningless, and b) the errno variable/pseudo-variable itself is
-different in the MS & BCC runtimes, so you can't access the
-pthreadVC's errno from a Borland C++-compiled host application
-correctly - I imagine there are other potential problems from the RTL
-mismatch too.)
-
-[RPJ: Make sure you use the same RTL in both dll and application builds.
-The dll and tests Bmakefiles use cw32mti.lib. Having some trouble with
-memory read exceptions running the test suite using BCC55.]
-
-Best regards,
-Will
-
--- 
-Will Bryant
-Systems Architect, eCOSM Limited
-Cell +64 21 655 443, office +64 3 365 4176
-http://www.ecosm.com/
diff --git a/deps/w32-pthreads/README.CV b/deps/w32-pthreads/README.CV
deleted file mode 100644
index 698728b..0000000
--- a/deps/w32-pthreads/README.CV
+++ /dev/null
@@ -1,3036 +0,0 @@
-README.CV -- Condition Variables
---------------------------------
-
-The original implementation of condition variables in
-pthreads-win32 was based on a discussion paper:
-
-"Strategies for Implementing POSIX Condition Variables
-on Win32": http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
-
-The changes suggested below were made on Feb 6 2001. This
-file is included in the package for the benefit of anyone
-interested in understanding the pthreads-win32 implementation
-of condition variables and the (sometimes subtle) issues that
-it attempts to resolve.
-
-Thanks go to the individuals whose names appear throughout
-the following text.
-
-Ross Johnson
-
---------------------------------------------------------------------
-
-fyi.. (more detailed problem description/demos + possible fix/patch)
-
-regards,
-alexander.
-
-
-Alexander Terekhov
-31.01.2001 17:43
-
-To:   ace-bugs at cs.wustl.edu
-cc:
-From: Alexander Terekhov/Germany/IBM at IBMDE
-Subject:  Implementation of POSIX CVs: spur.wakeups/lost
-      signals/deadlocks/unfairness
-
-
-
-    ACE VERSION:
-
-        5.1.12 (pthread-win32 snapshot 2000-12-29)
-
-    HOST MACHINE and OPERATING SYSTEM:
-
-        IBM IntelliStation Z Pro, 2 x XEON 1GHz, Win2K
-
-    TARGET MACHINE and OPERATING SYSTEM, if different from HOST:
-    COMPILER NAME AND VERSION (AND PATCHLEVEL):
-
-        Microsoft Visual C++ 6.0
-
-    AREA/CLASS/EXAMPLE AFFECTED:
-
-        Implementation of POSIX condition variables - OS.cpp/.h
-
-    DOES THE PROBLEM AFFECT:
-
-        EXECUTION? YES!
-
-    SYNOPSIS:
-
-        a) spurious wakeups (minor problem)
-        b) lost signals
-        c) broadcast deadlock
-        d) unfairness (minor problem)
-
-    DESCRIPTION:
-
-        Please see attached copy of discussion thread
-        from comp.programming.threads for more details on
-        some reported problems. (i've also posted a "fyi"
-        message to ace-users a week or two ago but
-        unfortunately did not get any response so far).
-
-        It seems that current implementation suffers from
-        two essential problems:
-
-        1) cond.waiters_count does not accurately reflect
-           number of waiters blocked on semaphore - w/o
-           proper synchronisation that could result (in the
-           time window when counter is not accurate)
-           in spurious wakeups organised by subsequent
-           _signals  and _broadcasts.
-
-        2) Always having (with no e.g. copy_and_clear/..)
-           the same queue in use (semaphore+counter)
-           neither signal nor broadcast provide 'atomic'
-           behaviour with respect to other threads/subsequent
-           calls to signal/broadcast/wait.
-
-        Each problem and combination of both could produce
-        various nasty things:
-
-        a) spurious wakeups (minor problem)
-
-             it is possible that waiter(s) which was already
-             unblocked even so is still counted as blocked
-             waiter. signal and broadcast will release
-             semaphore which will produce a spurious wakeup
-             for a 'real' waiter coming later.
-
-        b) lost signals
-
-             signalling thread ends up consuming its own
-             signal. please see demo/discussion below.
-
-        c) broadcast deadlock
-
-             last_waiter processing code does not correctly
-             handle the case with multiple threads
-             waiting for the end of broadcast.
-             please see demo/discussion below.
-
-        d) unfairness (minor problem)
-
-             without SignalObjectAndWait some waiter(s)
-             may end up consuming broadcasted signals
-             multiple times (spurious wakeups) because waiter
-             thread(s) can be preempted before they call
-             semaphore wait (but after count++ and mtx.unlock).
-
-    REPEAT BY:
-
-        See below... run problem demos programs (tennis.cpp and
-        tennisb.cpp) number of times concurrently (on multiprocessor)
-        and in multiple sessions or just add a couple of "Sleep"s
-        as described in the attached copy of discussion thread
-        from comp.programming.threads
-
-    SAMPLE FIX/WORKAROUND:
-
-        See attached patch to pthread-win32.. well, I can not
-        claim that it is completely bug free but at least my
-        test and tests provided by pthreads-win32 seem to work.
-        Perhaps that will help.
-
-        regards,
-        alexander.
-
-
->> Forum: comp.programming.threads
->> Thread: pthread_cond_* implementation questions
-.
-.
-.
-David Schwartz <davids at webmaster.com> wrote:
-
-> terekhov at my-deja.com wrote:
->
->> BTW, could you please also share your view on other perceived
->> "problems" such as nested broadcast deadlock, spurious wakeups
->> and (the latest one) lost signals??
->
->I'm not sure what you mean. The standard allows an implementation
->to do almost whatever it likes. In fact, you could implement
->pthread_cond_wait by releasing the mutex, sleeping a random
->amount of time, and then reacquiring the mutex. Of course,
->this would be a pretty poor implementation, but any code that
->didn't work under that implementation wouldn't be strictly
->compliant.
-
-The implementation you suggested is indeed correct
-one (yes, now I see it :). However it requires from
-signal/broadcast nothing more than to "{ return 0; }"
-That is not the case for pthread-win32 and ACE
-implementations. I do think that these implementations
-(basically the same implementation) have some serious
-problems with wait/signal/broadcast calls. I am looking
-for help to clarify whether these problems are real
-or not. I think that I can demonstrate what I mean
-using one or two small sample programs.
-.
-.
-.
-==========
-tennis.cpp
-==========
-
-#include "ace/Synch.h"
-#include "ace/Thread.h"
-
-enum GAME_STATE {
-
-  START_GAME,
-  PLAYER_A,     // Player A playes the ball
-  PLAYER_B,     // Player B playes the ball
-  GAME_OVER,
-  ONE_PLAYER_GONE,
-  BOTH_PLAYERS_GONE
-
-};
-
-enum GAME_STATE             eGameState;
-ACE_Mutex*                  pmtxGameStateLock;
-ACE_Condition< ACE_Mutex >* pcndGameStateChange;
-
-void*
-  playerA(
-    void* pParm
-  )
-{
-
-  // For access to game state variable
-  pmtxGameStateLock->acquire();
-
-  // Play loop
-  while ( eGameState < GAME_OVER ) {
-
-    // Play the ball
-    cout << endl << "PLAYER-A" << endl;
-
-    // Now its PLAYER-B's turn
-    eGameState = PLAYER_B;
-
-    // Signal to PLAYER-B that now it is his turn
-    pcndGameStateChange->signal();
-
-    // Wait until PLAYER-B finishes playing the ball
-    do {
-
-      pcndGameStateChange->wait();
-
-      if ( PLAYER_B == eGameState )
-        cout << endl << "----PLAYER-A: SPURIOUS WAKEUP!!!" << endl;
-
-    } while ( PLAYER_B == eGameState );
-
-  }
-
-  // PLAYER-A gone
-  eGameState = (GAME_STATE)(eGameState+1);
-  cout << endl << "PLAYER-A GONE" << endl;
-
-  // No more access to state variable needed
-  pmtxGameStateLock->release();
-
-  // Signal PLAYER-A gone event
-  pcndGameStateChange->broadcast();
-
-  return 0;
-
-}
-
-void*
-  playerB(
-    void* pParm
-  )
-{
-
-  // For access to game state variable
-  pmtxGameStateLock->acquire();
-
-  // Play loop
-  while ( eGameState < GAME_OVER ) {
-
-    // Play the ball
-    cout << endl << "PLAYER-B" << endl;
-
-    // Now its PLAYER-A's turn
-    eGameState = PLAYER_A;
-
-    // Signal to PLAYER-A that now it is his turn
-    pcndGameStateChange->signal();
-
-    // Wait until PLAYER-A finishes playing the ball
-    do {
-
-      pcndGameStateChange->wait();
-
-      if ( PLAYER_A == eGameState )
-        cout << endl << "----PLAYER-B: SPURIOUS WAKEUP!!!" << endl;
-
-    } while ( PLAYER_A == eGameState );
-
-  }
-
-  // PLAYER-B gone
-  eGameState = (GAME_STATE)(eGameState+1);
-  cout << endl << "PLAYER-B GONE" << endl;
-
-  // No more access to state variable needed
-  pmtxGameStateLock->release();
-
-  // Signal PLAYER-B gone event
-  pcndGameStateChange->broadcast();
-
-  return 0;
-
-}
-
-
-int
-main (int, ACE_TCHAR *[])
-{
-
-  pmtxGameStateLock   = new ACE_Mutex();
-  pcndGameStateChange = new ACE_Condition< ACE_Mutex >( *pmtxGameStateLock
-);
-
-  // Set initial state
-  eGameState = START_GAME;
-
-  // Create players
-  ACE_Thread::spawn( playerA );
-  ACE_Thread::spawn( playerB );
-
-  // Give them 5 sec. to play
-  Sleep( 5000 );//sleep( 5 );
-
-  // Set game over state
-  pmtxGameStateLock->acquire();
-  eGameState = GAME_OVER;
-
-  // Let them know
-  pcndGameStateChange->broadcast();
-
-  // Wait for players to stop
-  do {
-
-    pcndGameStateChange->wait();
-
-  } while ( eGameState < BOTH_PLAYERS_GONE );
-
-  // Cleanup
-  cout << endl << "GAME OVER" << endl;
-  pmtxGameStateLock->release();
-  delete pcndGameStateChange;
-  delete pmtxGameStateLock;
-
-  return 0;
-
-}
-
-===========
-tennisb.cpp
-===========
-#include "ace/Synch.h"
-#include "ace/Thread.h"
-
-enum GAME_STATE {
-
-  START_GAME,
-  PLAYER_A,     // Player A playes the ball
-  PLAYER_B,     // Player B playes the ball
-  GAME_OVER,
-  ONE_PLAYER_GONE,
-  BOTH_PLAYERS_GONE
-
-};
-
-enum GAME_STATE             eGameState;
-ACE_Mutex*                  pmtxGameStateLock;
-ACE_Condition< ACE_Mutex >* pcndGameStateChange;
-
-void*
-  playerA(
-    void* pParm
-  )
-{
-
-  // For access to game state variable
-  pmtxGameStateLock->acquire();
-
-  // Play loop
-  while ( eGameState < GAME_OVER ) {
-
-    // Play the ball
-    cout << endl << "PLAYER-A" << endl;
-
-    // Now its PLAYER-B's turn
-    eGameState = PLAYER_B;
-
-    // Signal to PLAYER-B that now it is his turn
-    pcndGameStateChange->broadcast();
-
-    // Wait until PLAYER-B finishes playing the ball
-    do {
-
-      pcndGameStateChange->wait();
-
-      if ( PLAYER_B == eGameState )
-        cout << endl << "----PLAYER-A: SPURIOUS WAKEUP!!!" << endl;
-
-    } while ( PLAYER_B == eGameState );
-
-  }
-
-  // PLAYER-A gone
-  eGameState = (GAME_STATE)(eGameState+1);
-  cout << endl << "PLAYER-A GONE" << endl;
-
-  // No more access to state variable needed
-  pmtxGameStateLock->release();
-
-  // Signal PLAYER-A gone event
-  pcndGameStateChange->broadcast();
-
-  return 0;
-
-}
-
-void*
-  playerB(
-    void* pParm
-  )
-{
-
-  // For access to game state variable
-  pmtxGameStateLock->acquire();
-
-  // Play loop
-  while ( eGameState < GAME_OVER ) {
-
-    // Play the ball
-    cout << endl << "PLAYER-B" << endl;
-
-    // Now its PLAYER-A's turn
-    eGameState = PLAYER_A;
-
-    // Signal to PLAYER-A that now it is his turn
-    pcndGameStateChange->broadcast();
-
-    // Wait until PLAYER-A finishes playing the ball
-    do {
-
-      pcndGameStateChange->wait();
-
-      if ( PLAYER_A == eGameState )
-        cout << endl << "----PLAYER-B: SPURIOUS WAKEUP!!!" << endl;
-
-    } while ( PLAYER_A == eGameState );
-
-  }
-
-  // PLAYER-B gone
-  eGameState = (GAME_STATE)(eGameState+1);
-  cout << endl << "PLAYER-B GONE" << endl;
-
-  // No more access to state variable needed
-  pmtxGameStateLock->release();
-
-  // Signal PLAYER-B gone event
-  pcndGameStateChange->broadcast();
-
-  return 0;
-
-}
-
-
-int
-main (int, ACE_TCHAR *[])
-{
-
-  pmtxGameStateLock   = new ACE_Mutex();
-  pcndGameStateChange = new ACE_Condition< ACE_Mutex >( *pmtxGameStateLock
-);
-
-  // Set initial state
-  eGameState = START_GAME;
-
-  // Create players
-  ACE_Thread::spawn( playerA );
-  ACE_Thread::spawn( playerB );
-
-  // Give them 5 sec. to play
-  Sleep( 5000 );//sleep( 5 );
-
-  // Make some noise
-  pmtxGameStateLock->acquire();
-  cout << endl << "---Noise ON..." << endl;
-  pmtxGameStateLock->release();
-  for ( int i = 0; i < 100000; i++ )
-    pcndGameStateChange->broadcast();
-  cout << endl << "---Noise OFF" << endl;
-
-  // Set game over state
-  pmtxGameStateLock->acquire();
-  eGameState = GAME_OVER;
-  cout << endl << "---Stopping the game..." << endl;
-
-  // Let them know
-  pcndGameStateChange->broadcast();
-
-  // Wait for players to stop
-  do {
-
-    pcndGameStateChange->wait();
-
-  } while ( eGameState < BOTH_PLAYERS_GONE );
-
-  // Cleanup
-  cout << endl << "GAME OVER" << endl;
-  pmtxGameStateLock->release();
-  delete pcndGameStateChange;
-  delete pmtxGameStateLock;
-
-  return 0;
-
-}
-.
-.
-.
-David Schwartz <davids at webmaster.com> wrote:
->> > It's compliant
->>
->> That is really good.
->
->> Tomorrow (I have to go urgently now) I will try to
->> demonstrate the lost-signal "problem" of current
->> pthread-win32 and ACE-(variant w/o SingleObjectAndWait)
->> implementations: players start suddenly drop their balls :-)
->> (with no change in source code).
->
->Signals aren't lost, they're going to the main thread,
->which isn't coded correctly to handle them. Try this:
->
->  // Wait for players to stop
->  do {
->
->    pthread_cond_wait( &cndGameStateChange,&mtxGameStateLock );
->printf("Main thread stole a signal\n");
->
->  } while ( eGameState < BOTH_PLAYERS_GONE );
->
->I bet everytime you thing a signal is lost, you'll see that printf.
->The signal isn't lost, it was stolen by another thread.
-
-well, you can probably loose your bet.. it was indeed stolen
-by "another" thread but not the one you seem to think of.
-
-I think that what actually happens is the following:
-
-H:\SA\UXX\pt\PTHREADS\TESTS>tennis3.exe
-
-PLAYER-A
-
-PLAYER-B
-
-----PLAYER-B: SPURIOUS WAKEUP!!!
-
-PLAYER-A GONE
-
-PLAYER-B GONE
-
-GAME OVER
-
-H:\SA\UXX\pt\PTHREADS\TESTS>
-
-here you can see that PLAYER-B after playing his first
-ball (which came via signal from PLAYER-A) just dropped
-it down. What happened is that his signal to player A
-was consumed as spurious wakeup by himself (player B).
-
-The implementation has a problem:
-
-================
-waiting threads:
-================
-
-{ /** Critical Section
-
-  inc cond.waiters_count
-
-}
-
-  /*
-  /* Atomic only if using Win32 SignalObjectAndWait
-  /*
-  cond.mtx.release
-
-  /*** ^^-- A THREAD WHICH DID SIGNAL MAY ACQUIRE THE MUTEX,
-  /***      GO INTO WAIT ON THE SAME CONDITION AND OVERTAKE
-  /***      ORIGINAL WAITER(S) CONSUMING ITS OWN SIGNAL!
-
-  cond.sem.wait
-
-Player-A after playing game's initial ball went into
-wait (called _wait) but was pre-empted before reaching
-wait semaphore. He was counted as waiter but was not
-actually waiting/blocked yet.
-
-===============
-signal threads:
-===============
-
-{ /** Critical Section
-
-  waiters_count = cond.waiters_count
-
-}
-
-  if ( waiters_count != 0 )
-
-    sem.post 1
-
-  endif
-
-Player-B after he received signal/ball from Player A
-called _signal. The _signal did see that there was
-one waiter blocked on the condition (Player-A) and
-released the semaphore.. (but it did not unblock
-Player-A because he was not actually blocked).
-Player-B thread continued its execution, called _wait,
-was counted as second waiter BUT was allowed to slip
-through opened semaphore gate (which was opened for
-Player-B) and received his own signal. Player B remained
-blocked followed by Player A. Deadlock happened which
-lasted until main thread came in and said game over.
-
-It seems to me that the implementation fails to
-correctly implement the following statement
-from specification:
-
-http://www.opengroup.org/
-onlinepubs/007908799/xsh/pthread_cond_wait.html
-
-"These functions atomically release mutex and cause
-the calling thread to block on the condition variable
-cond; atomically here means "atomically with respect
-to access by another thread to the mutex and then the
-condition variable". That is, if another thread is
-able to acquire the mutex after the about-to-block
-thread has released it, then a subsequent call to
-pthread_cond_signal() or pthread_cond_broadcast()
-in that thread behaves as if it were issued after
-the about-to-block thread has blocked."
-
-Question: Am I right?
-
-(I produced the program output above by simply
-adding ?Sleep( 1 )?:
-
-================
-waiting threads:
-================
-
-{ /** Critical Section
-
-  inc cond.waiters_count
-
-}
-
-  /*
-  /* Atomic only if using Win32 SignalObjectAndWait
-  /*
-  cond.mtx.release
-
-Sleep( 1 ); // Win32
-
-  /*** ^^-- A THREAD WHICH DID SIGNAL MAY ACQUIRE THE MUTEX,
-  /***      GO INTO WAIT ON THE SAME CONDITION AND OVERTAKE
-  /***      ORIGINAL WAITER(S) CONSUMING ITS OWN SIGNAL!
-
-  cond.sem.wait
-
-to the source code of pthread-win32 implementation:
-
-http://sources.redhat.com/cgi-bin/cvsweb.cgi/pthreads/
-condvar.c?rev=1.36&content-type=text/
-x-cvsweb-markup&cvsroot=pthreads-win32
-
-
-  /*
-  * We keep the lock held just long enough to increment the count of
-  * waiters by one (above).
-  * Note that we can't keep it held across the
-  * call to sem_wait since that will deadlock other calls
-  * to pthread_cond_signal
-  */
-  cleanup_args.mutexPtr = mutex;
-  cleanup_args.cv = cv;
-  cleanup_args.resultPtr = &result;
-
-  pthread_cleanup_push (ptw32_cond_wait_cleanup, (void *)
-&cleanup_args);
-
-  if ((result = pthread_mutex_unlock (mutex)) == 0)
-    {((result
-Sleep( 1 ); // @AT
-
-      /*
-      * Wait to be awakened by
-      *              pthread_cond_signal, or
-      *              pthread_cond_broadcast, or
-      *              a timeout
-      *
-      * Note:
-      *      ptw32_sem_timedwait is a cancelation point,
-      *      hence providing the
-      *      mechanism for making pthread_cond_wait a cancelation
-      *      point. We use the cleanup mechanism to ensure we
-      *      re-lock the mutex and decrement the waiters count
-      *      if we are canceled.
-      */
-      if (ptw32_sem_timedwait (&(cv->sema), abstime) == -1)         {
-          result = errno;
-        }
-    }
-
-  pthread_cleanup_pop (1);  /* Always cleanup */
-
-
-BTW, on my system (2 CPUs) I can manage to get
-signals lost even without any source code modification
-if I run the tennis program many times in different
-shell sessions.
-.
-.
-.
-David Schwartz <davids at webmaster.com> wrote:
->terekhov at my-deja.com wrote:
->
->> well, it might be that the program is in fact buggy.
->> but you did not show me any bug.
->
->You're right. I was close but not dead on. I was correct, however,
->that the code is buggy because it uses 'pthread_cond_signal' even
->though not any thread waiting on the condition variable can do the
->job. I was wrong in which thread could be waiting on the cv but
->unable to do the job.
-
-Okay, lets change 'pthread_cond_signal' to 'pthread_cond_broadcast'
-but also add some noise from main() right before declaring the game
-to be over (I need it in order to demonstrate another problem of
-pthread-win32/ACE implementations - broadcast deadlock)...
-.
-.
-.
-It is my understanding of POSIX conditions,
-that on correct implementation added noise
-in form of unnecessary broadcasts from main,
-should not break the tennis program. The
-only 'side effect' of added noise on correct
-implementation would be 'spurious wakeups' of
-players (in fact they are not spurious,
-players just see them as spurious) unblocked,
-not by another player but by main before
-another player had a chance to acquire the
-mutex and change the game state variable:
-.
-.
-.
-
-PLAYER-B
-
-PLAYER-A
-
----Noise ON...
-
-PLAYER-B
-
-PLAYER-A
-
-.
-.
-.
-
-PLAYER-B
-
-PLAYER-A
-
-----PLAYER-A: SPURIOUS WAKEUP!!!
-
-PLAYER-B
-
-PLAYER-A
-
----Noise OFF
-
-PLAYER-B
-
----Stopping the game...
-
-PLAYER-A GONE
-
-PLAYER-B GONE
-
-GAME OVER
-
-H:\SA\UXX\pt\PTHREADS\TESTS>
-
-On pthread-win32/ACE implementations the
-program could stall:
-
-.
-.
-.
-
-PLAYER-A
-
-PLAYER-B
-
-PLAYER-A
-
-PLAYER-B
-
-PLAYER-A
-
-PLAYER-B
-
-PLAYER-A
-
-PLAYER-B
-
----Noise ON...
-
-PLAYER-A
-
----Noise OFF
-^C
-H:\SA\UXX\pt\PTHREADS\TESTS>
-
-
-The implementation has problems:
-
-================
-waiting threads:
-================
-
-{ /** Critical Section
-
-  inc cond.waiters_count
-
-}
-
-  /*
-  /* Atomic only if using Win32 SignalObjectAndWait
-  /*
-  cond.mtx.release
-  cond.sem.wait
-
-  /*** ^^-- WAITER CAN BE PREEMPTED AFTER BEING UNBLOCKED...
-
-{ /** Critical Section
-
-  dec cond.waiters_count
-
-  /*** ^^- ...AND BEFORE DECREMENTING THE COUNT (1)
-
-  last_waiter = ( cond.was_broadcast &&
-                    cond.waiters_count == 0 )
-
-  if ( last_waiter )
-
-    cond.was_broadcast = FALSE
-
-  endif
-
-}
-
-  if ( last_waiter )
-
-    /*
-    /* Atomic only if using Win32 SignalObjectAndWait
-    /*
-    cond.auto_reset_event_or_sem.post /* Event for Win32
-    cond.mtx.acquire
-
-  /*** ^^-- ...AND BEFORE CALL TO mtx.acquire (2)
-
-  /*** ^^-- NESTED BROADCASTS RESULT IN A DEADLOCK
-
-
-  else
-
-    cond.mtx.acquire
-
-  /*** ^^-- ...AND BEFORE CALL TO mtx.acquire (3)
-
-  endif
-
-
-==================
-broadcast threads:
-==================
-
-{ /** Critical Section
-
-  waiters_count = cond.waiters_count
-
-  if ( waiters_count != 0 )
-
-    cond.was_broadcast = TRUE
-
-  endif
-
-}
-
-if ( waiters_count != 0 )
-
-  cond.sem.post waiters_count
-
-  /*** ^^^^^--- SPURIOUS WAKEUPS DUE TO (1)
-
-  cond.auto_reset_event_or_sem.wait /* Event for Win32
-
-  /*** ^^^^^--- DEADLOCK FOR FURTHER BROADCASTS IF THEY
-                HAPPEN TO GO INTO WAIT WHILE PREVIOUS
-                BROADCAST IS STILL IN PROGRESS/WAITING
-
-endif
-
-a) cond.waiters_count does not accurately reflect
-number of waiters blocked on semaphore - that could
-result (in the time window when counter is not accurate)
-in spurios wakeups organised by subsequent _signals
-and _broadcasts. From standard compliance point of view
-that is OK but that could be a real problem from
-performance/efficiency point of view.
-
-b) If subsequent broadcast happen to go into wait on
-cond.auto_reset_event_or_sem before previous
-broadcast was unblocked from cond.auto_reset_event_or_sem
-by its last waiter, one of two blocked threads will
-remain blocked because last_waiter processing code
-fails to unblock both threads.
-
-In the situation with tennisb.c the Player-B was put
-in a deadlock by noise (broadcast) coming from main
-thread. And since Player-B holds the game state
-mutex when it calls broadcast, the whole program
-stalled: Player-A was deadlocked on mutex and
-main thread after finishing with producing the noise
-was deadlocked on mutex too (needed to declare the
-game over)
-
-(I produced the program output above by simply
-adding ?Sleep( 1 )?:
-
-==================
-broadcast threads:
-==================
-
-{ /** Critical Section
-
-  waiters_count = cond.waiters_count
-
-  if ( waiters_count != 0 )
-
-    cond.was_broadcast = TRUE
-
-  endif
-
-}
-
-if ( waiters_count != 0 )
-
-Sleep( 1 ); //Win32
-
-  cond.sem.post waiters_count
-
-  /*** ^^^^^--- SPURIOUS WAKEUPS DUE TO (1)
-
-  cond.auto_reset_event_or_sem.wait /* Event for Win32
-
-  /*** ^^^^^--- DEADLOCK FOR FURTHER BROADCASTS IF THEY
-                HAPPEN TO GO INTO WAIT WHILE PREVIOUS
-                BROADCAST IS STILL IN PROGRESS/WAITING
-
-endif
-
-to the source code of pthread-win32 implementation:
-
-http://sources.redhat.com/cgi-bin/cvsweb.cgi/pthreads/
-condvar.c?rev=1.36&content-type=text/
-x-cvsweb-markup&cvsroot=pthreads-win32
-
-  if (wereWaiters)
-    {(wereWaiters)sroot=pthreads-win32eb.cgi/pthreads/Yem...m
-      /*
-      * Wake up all waiters
-      */
-
-Sleep( 1 ); //@AT
-
-#ifdef NEED_SEM
-
-      result = (ptw32_increase_semaphore( &cv->sema, cv->waiters )
-                 ? 0
-                : EINVAL);
-
-#else /* NEED_SEM */
-
-      result = (ReleaseSemaphore( cv->sema, cv->waiters, NULL )
-                 ? 0
-                : EINVAL);
-
-#endif /* NEED_SEM */
-
-    }
-
-  (void) pthread_mutex_unlock(&(cv->waitersLock));
-
-  if (wereWaiters && result == 0)
-    {(wereWaiters
-      /*
-       * Wait for all the awakened threads to acquire their part of
-       * the counting semaphore
-       */
-
-      if (WaitForSingleObject (cv->waitersDone, INFINITE)
-          == WAIT_OBJECT_0)
-        {
-          result = 0;
-        }
-      else
-        {
-          result = EINVAL;
-        }
-
-    }
-
-  return (result);
-
-}
-
-BTW, on my system (2 CPUs) I can manage to get
-the program stalled even without any source code
-modification if I run the tennisb program many
-times in different shell sessions.
-
-===================
-pthread-win32 patch
-===================
-struct pthread_cond_t_ {
-  long            nWaitersBlocked;   /* Number of threads blocked
-*/
-  long            nWaitersUnblocked; /* Number of threads unblocked
-*/
-  long            nWaitersToUnblock; /* Number of threads to unblock
-*/
-  sem_t           semBlockQueue;     /* Queue up threads waiting for the
-*/
-                                     /*   condition to become signalled
-*/
-  sem_t           semBlockLock;      /* Semaphore that guards access to
-*/
-                                     /* | waiters blocked count/block queue
-*/
-                                     /* +-> Mandatory Sync.LEVEL-1
-*/
-  pthread_mutex_t mtxUnblockLock;    /* Mutex that guards access to
-*/
-                                     /* | waiters (to)unblock(ed) counts
-*/
-                                     /* +-> Optional* Sync.LEVEL-2
-*/
-};                                   /* Opt*) for _timedwait and
-cancellation*/
-
-int
-pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr)
-  int result = EAGAIN;
-  pthread_cond_t cv = NULL;
-
-  if (cond == NULL)
-    {(cond
-      return EINVAL;
-    }
-
-  if ((attr != NULL && *attr != NULL) &&
-      ((*attr)->pshared == PTHREAD_PROCESS_SHARED))
-    {
-      /*
-       * Creating condition variable that can be shared between
-       * processes.
-       */
-      result = ENOSYS;
-
-      goto FAIL0;
-    }
-
-  cv = (pthread_cond_t) calloc (1, sizeof (*cv));
-
-  if (cv == NULL)
-    {(cv
-      result = ENOMEM;
-      goto FAIL0;
-    }
-
-  cv->nWaitersBlocked   = 0;
-  cv->nWaitersUnblocked = 0;
-  cv->nWaitersToUnblock = 0;
-
-  if (sem_init (&(cv->semBlockLock), 0, 1) != 0)
-    {(sem_init
-      goto FAIL0;
-    }
-
-  if (sem_init (&(cv->semBlockQueue), 0, 0) != 0)
-    {(sem_init
-      goto FAIL1;
-    }
-
-  if (pthread_mutex_init (&(cv->mtxUnblockLock), 0) != 0)
-    {(pthread_mutex_init
-      goto FAIL2;
-    }
-
-
-  result = 0;
-
-  goto DONE;
-
-  /*
-   * -------------
-   * Failed...
-   * -------------
-   */
-FAIL2:
-  (void) sem_destroy (&(cv->semBlockQueue));
-
-FAIL1:
-  (void) sem_destroy (&(cv->semBlockLock));
-
-FAIL0:
-DONE:
-  *cond = cv;
-
-  return (result);
-
-}                               /* pthread_cond_init */
-
-int
-pthread_cond_destroy (pthread_cond_t * cond)
-{
-  int result = 0;
-  pthread_cond_t cv;
-
-  /*
-   * Assuming any race condition here is harmless.
-   */
-  if (cond == NULL
-      || *cond == NULL)
-    {
-      return EINVAL;
-    }
-
-  if (*cond != (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
-    {(*cond
-      cv = *cond;
-
-      /*
-       * Synchronize access to waiters blocked count (LEVEL-1)
-       */
-      if (sem_wait(&(cv->semBlockLock)) != 0)
-        {(sem_wait(&(cv->semBlockLock))
-          return errno;
-        }
-
-      /*
-       * Synchronize access to waiters (to)unblock(ed) counts (LEVEL-2)
-       */
-      if ((result = pthread_mutex_lock(&(cv->mtxUnblockLock))) != 0)
-        {((result
-          (void) sem_post(&(cv->semBlockLock));
-          return result;
-        }
-
-      /*
-       * Check whether cv is still busy (still has waiters blocked)
-       */
-      if (cv->nWaitersBlocked - cv->nWaitersUnblocked > 0)
-        {(cv->nWaitersBlocked
-          (void) sem_post(&(cv->semBlockLock));
-          (void) pthread_mutex_unlock(&(cv->mtxUnblockLock));
-          return EBUSY;
-        }
-
-      /*
-       * Now it is safe to destroy
-       */
-      (void) sem_destroy (&(cv->semBlockLock));
-      (void) sem_destroy (&(cv->semBlockQueue));
-      (void) pthread_mutex_unlock (&(cv->mtxUnblockLock));
-      (void) pthread_mutex_destroy (&(cv->mtxUnblockLock));
-
-      free(cv);
-      *cond = NULL;
-    }
-  else
-    {
-      /*
-       * See notes in ptw32_cond_check_need_init() above also.
-       */
-      EnterCriticalSection(&ptw32_cond_test_init_lock);
-
-      /*
-       * Check again.
-       */
-      if (*cond == (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
-        {(*cond
-          /*
-           * This is all we need to do to destroy a statically
-           * initialised cond that has not yet been used (initialised).
-           * If we get to here, another thread
-           * waiting to initialise this cond will get an EINVAL.
-           */
-          *cond = NULL;
-        }
-      else
-        {
-          /*
-           * The cv has been initialised while we were waiting
-           * so assume it's in use.
-           */
-          result = EBUSY;
-        }
-
-      LeaveCriticalSection(&ptw32_cond_test_init_lock);
-    }
-
-  return (result);
-}
-
-/*
- * Arguments for cond_wait_cleanup, since we can only pass a
- * single void * to it.
- */
-typedef struct {
-  pthread_mutex_t * mutexPtr;
-  pthread_cond_t cv;
-  int * resultPtr;
-} ptw32_cond_wait_cleanup_args_t;
-
-static void
-ptw32_cond_wait_cleanup(void * args)
-{
-  ptw32_cond_wait_cleanup_args_t * cleanup_args =
-(ptw32_cond_wait_cleanup_args_t *) args;
-  pthread_cond_t cv = cleanup_args->cv;
-  int * resultPtr = cleanup_args->resultPtr;
-  int eLastSignal; /* enum: 1=yes 0=no -1=cancelled/timedout w/o signal(s)
-*/
-  int result;
-
-  /*
-   * Whether we got here as a result of signal/broadcast or because of
-   * timeout on wait or thread cancellation we indicate that we are no
-   * longer waiting. The waiter is responsible for adjusting waiters
-   * (to)unblock(ed) counts (protected by unblock lock).
-   * Unblock lock/Sync.LEVEL-2 supports _timedwait and cancellation.
-   */
-  if ((result = pthread_mutex_lock(&(cv->mtxUnblockLock))) != 0)
-    {((result
-      *resultPtr = result;
-      return;
-    }
-
-  cv->nWaitersUnblocked++;
-
-  eLastSignal = (cv->nWaitersToUnblock == 0) ?
-                   -1 : (--cv->nWaitersToUnblock == 0);
-
-  /*
-   * No more LEVEL-2 access to waiters (to)unblock(ed) counts needed
-   */
-  if ((result = pthread_mutex_unlock(&(cv->mtxUnblockLock))) != 0)
-    {((result
-      *resultPtr = result;
-      return;
-    }
-
-  /*
-   * If last signal...
-   */
-  if (eLastSignal == 1)
-    {(eLastSignal
-     /*
-      * ...it means that we have end of 'atomic' signal/broadcast
-      */
-      if (sem_post(&(cv->semBlockLock)) != 0)
-        {(sem_post(&(cv->semBlockLock))
-          *resultPtr = errno;
-          return;
-        }
-    }
-  /*
-   * If not last signal and not timed out/cancelled wait w/o signal...
-   */
-  else if (eLastSignal == 0)
-    {
-     /*
-      * ...it means that next waiter can go through semaphore
-      */
-      if (sem_post(&(cv->semBlockQueue)) != 0)
-        {(sem_post(&(cv->semBlockQueue))
-          *resultPtr = errno;
-          return;
-        }
-    }
-
-  /*
-   * XSH: Upon successful return, the mutex has been locked and is owned
-   * by the calling thread
-   */
-  if ((result = pthread_mutex_lock(cleanup_args->mutexPtr)) != 0)
-    {((result
-      *resultPtr = result;
-    }
-
-}                               /* ptw32_cond_wait_cleanup */
-
-static int
-ptw32_cond_timedwait (pthread_cond_t * cond,
-                      pthread_mutex_t * mutex,
-                      const struct timespec *abstime)
-{
-  int result = 0;
-  pthread_cond_t cv;
-  ptw32_cond_wait_cleanup_args_t cleanup_args;
-
-  if (cond == NULL || *cond == NULL)
-    {(cond
-      return EINVAL;
-    }
-
-  /*
-   * We do a quick check to see if we need to do more work
-   * to initialise a static condition variable. We check
-   * again inside the guarded section of ptw32_cond_check_need_init()
-   * to avoid race conditions.
-   */
-  if (*cond == (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
-    {(*cond
-      result = ptw32_cond_check_need_init(cond);
-    }
-
-  if (result != 0 && result != EBUSY)
-    {(result
-      return result;
-    }
-
-  cv = *cond;
-
-  /*
-   * Synchronize access to waiters blocked count (LEVEL-1)
-   */
-  if (sem_wait(&(cv->semBlockLock)) != 0)
-    {(sem_wait(&(cv->semBlockLock))
-      return errno;
-    }
-
-  cv->nWaitersBlocked++;
-
-  /*
-   * Thats it. Counted means waiting, no more access needed
-   */
-  if (sem_post(&(cv->semBlockLock)) != 0)
-    {(sem_post(&(cv->semBlockLock))
-      return errno;
-    }
-
-  /*
-   * Setup this waiter cleanup handler
-   */
-  cleanup_args.mutexPtr = mutex;
-  cleanup_args.cv = cv;
-  cleanup_args.resultPtr = &result;
-
-  pthread_cleanup_push (ptw32_cond_wait_cleanup, (void *) &cleanup_args);
-
-  /*
-   * Now we can release 'mutex' and...
-   */
-  if ((result = pthread_mutex_unlock (mutex)) == 0)
-    {((result
-
-      /*
-       * ...wait to be awakened by
-       *              pthread_cond_signal, or
-       *              pthread_cond_broadcast, or
-       *              timeout, or
-       *              thread cancellation
-       *
-       * Note:
-       *
-       *      ptw32_sem_timedwait is a cancellation point,
-       *      hence providing the mechanism for making
-       *      pthread_cond_wait a cancellation point.
-       *      We use the cleanup mechanism to ensure we
-       *      re-lock the mutex and adjust (to)unblock(ed) waiters
-       *      counts if we are cancelled, timed out or signalled.
-       */
-      if (ptw32_sem_timedwait (&(cv->semBlockQueue), abstime) != 0)
-        {(ptw32_sem_timedwait
-          result = errno;
-        }
-    }
-
-  /*
-   * Always cleanup
-   */
-  pthread_cleanup_pop (1);
-
-
-  /*
-   * "result" can be modified by the cleanup handler.
-   */
-  return (result);
-
-}                               /* ptw32_cond_timedwait */
-
-
-static int
-ptw32_cond_unblock (pthread_cond_t * cond,
-                    int unblockAll)
-{
-  int result;
-  pthread_cond_t cv;
-
-  if (cond == NULL || *cond == NULL)
-    {(cond
-      return EINVAL;
-    }
-
-  cv = *cond;
-
-  /*
-   * No-op if the CV is static and hasn't been initialised yet.
-   * Assuming that any race condition is harmless.
-   */
-  if (cv == (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
-    {(cv
-      return 0;
-    }
-
-  /*
-   * Synchronize access to waiters blocked count (LEVEL-1)
-   */
-  if (sem_wait(&(cv->semBlockLock)) != 0)
-    {(sem_wait(&(cv->semBlockLock))
-      return errno;
-    }
-
-  /*
-   * Synchronize access to waiters (to)unblock(ed) counts (LEVEL-2)
-   * This sync.level supports _timedwait and cancellation
-   */
-  if ((result = pthread_mutex_lock(&(cv->mtxUnblockLock))) != 0)
-    {((result
-      return result;
-    }
-
-  /*
-   * Adjust waiters blocked and unblocked counts (collect garbage)
-   */
-  if (cv->nWaitersUnblocked != 0)
-    {(cv->nWaitersUnblocked
-      cv->nWaitersBlocked  -= cv->nWaitersUnblocked;
-      cv->nWaitersUnblocked = 0;
-    }
-
-  /*
-   * If (after adjustment) there are still some waiters blocked counted...
-   */
-  if ( cv->nWaitersBlocked > 0)
-    {(
-      /*
-       * We will unblock first waiter and leave semBlockLock/LEVEL-1 locked
-       * LEVEL-1 access is left disabled until last signal/unblock
-completes
-       */
-      cv->nWaitersToUnblock = (unblockAll) ? cv->nWaitersBlocked : 1;
-
-      /*
-       * No more LEVEL-2 access to waiters (to)unblock(ed) counts needed
-       * This sync.level supports _timedwait and cancellation
-       */
-      if ((result = pthread_mutex_unlock(&(cv->mtxUnblockLock))) != 0)
-        {((result
-          return result;
-        }
-
-
-      /*
-       * Now, with LEVEL-2 lock released let first waiter go through
-semaphore
-       */
-      if (sem_post(&(cv->semBlockQueue)) != 0)
-        {(sem_post(&(cv->semBlockQueue))
-          return errno;
-        }
-    }
-  /*
-   * No waiter blocked - no more LEVEL-1 access to blocked count needed...
-   */
-  else if (sem_post(&(cv->semBlockLock)) != 0)
-    {
-      return errno;
-    }
-  /*
-   * ...and no more LEVEL-2 access to waiters (to)unblock(ed) counts needed
-too
-   * This sync.level supports _timedwait and cancellation
-   */
-  else
-    {
-      result = pthread_mutex_unlock(&(cv->mtxUnblockLock));
-    }
-
-  return(result);
-
-}                               /* ptw32_cond_unblock */
-
-int
-pthread_cond_wait (pthread_cond_t * cond,
-                   pthread_mutex_t * mutex)
-{
-  /* The NULL abstime arg means INFINITE waiting. */
-  return(ptw32_cond_timedwait(cond, mutex, NULL));
-}                               /* pthread_cond_wait */
-
-
-int
-pthread_cond_timedwait (pthread_cond_t * cond,
-                        pthread_mutex_t * mutex,
-                        const struct timespec *abstime)
-{
-  if (abstime == NULL)
-    {(abstime
-      return EINVAL;
-    }
-
-  return(ptw32_cond_timedwait(cond, mutex, abstime));
-}                               /* pthread_cond_timedwait */
-
-
-int
-pthread_cond_signal (pthread_cond_t * cond)
-{
-  /* The '0'(FALSE) unblockAll arg means unblock ONE waiter. */
-  return(ptw32_cond_unblock(cond, 0));
-}                               /* pthread_cond_signal */
-
-int
-pthread_cond_broadcast (pthread_cond_t * cond)
-{
-  /* The '1'(TRUE) unblockAll arg means unblock ALL waiters. */
-  return(ptw32_cond_unblock(cond, 1));
-}                               /* pthread_cond_broadcast */
-
-
-
-
-TEREKHOV at de.ibm.com on 17.01.2001 01:00:57
-
-Please respond to TEREKHOV at de.ibm.com
-
-To:   pthreads-win32 at sourceware.cygnus.com
-cc:   schmidt at uci.edu
-Subject:  win32 conditions: sem+counter+event = broadcast_deadlock +
-      spur.wakeup/unfairness/incorrectness ??
-
-
-
-
-
-
-
-Hi,
-
-Problem 1: broadcast_deadlock
-
-It seems that current implementation does not provide "atomic"
-broadcasts. That may lead to "nested" broadcasts... and it seems
-that nested case is not handled correctly -> producing a broadcast
-DEADLOCK as a result.
-
-Scenario:
-
-N (>1) waiting threads W1..N are blocked (in _wait) on condition's
-semaphore.
-
-Thread B1 calls pthread_cond_broadcast, which results in "releasing" N
-W threads via incrementing semaphore counter by N (stored in
-cv->waiters) BUT cv->waiters counter does not change!! The caller
-thread B1 remains blocked on cv->waitersDone event (auto-reset!!) BUT
-condition is not protected from starting another broadcast (when called
-on another thread) while still waiting for the "old" broadcast to
-complete on thread B1.
-
-M (>=0, <N) W threads are fast enough to go thru their _wait call and
-decrement cv->waiters counter.
-
-L (N-M) "late" waiter W threads are a) still blocked/not returned from
-their semaphore wait call or b) were preempted after sem_wait but before
-lock( &cv->waitersLock ) or c) are blocked on cv->waitersLock.
-
-cv->waiters is still > 0 (= L).
-
-Another thread B2 (or some W thread from M group) calls
-pthread_cond_broadcast and gains access to counter... neither a) nor b)
-prevent thread B2 in pthread_cond_broadcast from gaining access to
-counter and starting another broadcast ( for c) - it depends on
-cv->waitersLock scheduling rules: FIFO=OK, PRTY=PROBLEM,... )
-
-That call to pthread_cond_broadcast (on thread B2) will result in
-incrementing semaphore by cv->waiters (=L) which is INCORRECT (all
-W1..N were in fact already released by thread B1) and waiting on
-_auto-reset_ event cv->waitersDone which is DEADLY WRONG (produces a
-deadlock)...
-
-All late W1..L threads now have a chance to complete their _wait call.
-Last W_L thread sets an auto-reselt event cv->waitersDone which will
-release either B1 or B2 leaving one of B threads in a deadlock.
-
-Problem 2: spur.wakeup/unfairness/incorrectness
-
-It seems that:
-
-a) because of the same problem with counter which does not reflect the
-actual number of NOT RELEASED waiters, the signal call may increment
-a semaphore counter w/o having a waiter blocked on it. That will result
-in (best case) spurious wake ups - performance degradation due to
-unnecessary context switches and predicate re-checks and (in worth case)
-unfairness/incorrectness problem - see b)
-
-b) neither signal nor broadcast prevent other threads - "new waiters"
-(and in the case of signal, the caller thread as well) from going into
-_wait and overtaking "old" waiters (already released but still not returned
-from sem_wait on condition's semaphore). Win semaphore just [API DOC]:
-"Maintains a count between zero and some maximum value, limiting the number
-of threads that are simultaneously accessing a shared resource." Calling
-ReleaseSemaphore does not imply (at least not documented) that on return
-from ReleaseSemaphore all waiters will in fact become released (returned
-from their Wait... call) and/or that new waiters calling Wait... afterwards
-will become less importance. It is NOT documented to be an atomic release
-of
-waiters... And even if it would be there is still a problem with a thread
-being preempted after Wait on semaphore and before Wait on cv->waitersLock
-and scheduling rules for cv->waitersLock itself
-(??WaitForMultipleObjects??)
-That may result in unfairness/incorrectness problem as described
-for SetEvent impl. in "Strategies for Implementing POSIX Condition
-Variables
-on Win32": http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
-
-Unfairness -- The semantics of the POSIX pthread_cond_broadcast function is
-to wake up all threads currently blocked in wait calls on the condition
-variable. The awakened threads then compete for the external_mutex. To
-ensure
-fairness, all of these threads should be released from their
-pthread_cond_wait calls and allowed to recheck their condition expressions
-before other threads can successfully complete a wait on the condition
-variable.
-
-Unfortunately, the SetEvent implementation above does not guarantee that
-all
-threads sleeping on the condition variable when cond_broadcast is called
-will
-acquire the external_mutex and check their condition expressions. Although
-the Pthreads specification does not mandate this degree of fairness, the
-lack of fairness can cause starvation.
-
-To illustrate the unfairness problem, imagine there are 2 threads, C1 and
-C2,
-that are blocked in pthread_cond_wait on condition variable not_empty_ that
-is guarding a thread-safe message queue. Another thread, P1 then places two
-messages onto the queue and calls pthread_cond_broadcast. If C1 returns
-from
-pthread_cond_wait, dequeues and processes the message, and immediately
-waits
-again then it and only it may end up acquiring both messages. Thus, C2 will
-never get a chance to dequeue a message and run.
-
-The following illustrates the sequence of events:
-
-1.   Thread C1 attempts to dequeue and waits on CV non_empty_
-2.   Thread C2 attempts to dequeue and waits on CV non_empty_
-3.   Thread P1 enqueues 2 messages and broadcasts to CV not_empty_
-4.   Thread P1 exits
-5.   Thread C1 wakes up from CV not_empty_, dequeues a message and runs
-6.   Thread C1 waits again on CV not_empty_, immediately dequeues the 2nd
-        message and runs
-7.   Thread C1 exits
-8.   Thread C2 is the only thread left and blocks forever since
-        not_empty_ will never be signaled
-
-Depending on the algorithm being implemented, this lack of fairness may
-yield
-concurrent programs that have subtle bugs. Of course, application
-developers
-should not rely on the fairness semantics of pthread_cond_broadcast.
-However,
-there are many cases where fair implementations of condition variables can
-simplify application code.
-
-Incorrectness -- A variation on the unfairness problem described above
-occurs
-when a third consumer thread, C3, is allowed to slip through even though it
-was not waiting on condition variable not_empty_ when a broadcast occurred.
-
-To illustrate this, we will use the same scenario as above: 2 threads, C1
-and
-C2, are blocked dequeuing messages from the message queue. Another thread,
-P1
-then places two messages onto the queue and calls pthread_cond_broadcast.
-C1
-returns from pthread_cond_wait, dequeues and processes the message. At this
-time, C3 acquires the external_mutex, calls pthread_cond_wait and waits on
-the events in WaitForMultipleObjects. Since C2 has not had a chance to run
-yet, the BROADCAST event is still signaled. C3 then returns from
-WaitForMultipleObjects, and dequeues and processes the message in the
-queue.
-Thus, C2 will never get a chance to dequeue a message and run.
-
-The following illustrates the sequence of events:
-
-1.   Thread C1 attempts to dequeue and waits on CV non_empty_
-2.   Thread C2 attempts to dequeue and waits on CV non_empty_
-3.   Thread P1 enqueues 2 messages and broadcasts to CV not_empty_
-4.   Thread P1 exits
-5.   Thread C1 wakes up from CV not_empty_, dequeues a message and runs
-6.   Thread C1 exits
-7.   Thread C3 waits on CV not_empty_, immediately dequeues the 2nd
-        message and runs
-8.   Thread C3 exits
-9.   Thread C2 is the only thread left and blocks forever since
-        not_empty_ will never be signaled
-
-In the above case, a thread that was not waiting on the condition variable
-when a broadcast occurred was allowed to proceed. This leads to incorrect
-semantics for a condition variable.
-
-
-COMMENTS???
-
-regards,
-alexander.
-
------------------------------------------------------------------------------
-
-Subject: RE: FYI/comp.programming.threads/Re: pthread_cond_*
-     implementation questions
-Date: Wed, 21 Feb 2001 11:54:47 +0100
-From: TEREKHOV at de.ibm.com
-To: lthomas at arbitrade.com
-CC: rpj at ise.canberra.edu.au, Thomas Pfaff <tpfaff at gmx.net>,
-     Nanbor Wang <nanbor at cs.wustl.edu>
-
-Hi Louis,
-
-generation number 8..
-
-had some time to revisit timeouts/spurious wakeup problem..
-found some bugs (in 7.b/c/d) and something to improve
-(7a - using IPC semaphores but it should speedup Win32
-version as well).
-
-regards,
-alexander.
-
----------- Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL ------
-given:
-semBlockLock - bin.semaphore
-semBlockQueue - semaphore
-mtxExternal - mutex or CS
-mtxUnblockLock - mutex or CS
-nWaitersGone - int
-nWaitersBlocked - int
-nWaitersToUnblock - int
-
-wait( timeout ) {
-
-  [auto: register int result          ]     // error checking omitted
-  [auto: register int nSignalsWasLeft ]
-  [auto: register int nWaitersWasGone ]
-
-  sem_wait( semBlockLock );
-  nWaitersBlocked++;
-  sem_post( semBlockLock );
-
-  unlock( mtxExternal );
-  bTimedOut = sem_wait( semBlockQueue,timeout );
-
-  lock( mtxUnblockLock );
-  if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
-    if ( bTimeout ) {                       // timeout (or canceled)
-      if ( 0 != nWaitersBlocked ) {
-        nWaitersBlocked--;
-      }
-      else {
-        nWaitersGone++;                     // count spurious wakeups
-      }
-    }
-    if ( 0 == --nWaitersToUnblock ) {
-      if ( 0 != nWaitersBlocked ) {
-        sem_post( semBlockLock );           // open the gate
-        nSignalsWasLeft = 0;                // do not open the gate below
-again
-      }
-      else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
-        nWaitersGone = 0;
-      }
-    }
-  }
-  else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or spurious
-semaphore :-)
-    sem_wait( semBlockLock );
-    nWaitersBlocked -= nWaitersGone;        // something is going on here -
-test of timeouts? :-)
-    sem_post( semBlockLock );
-    nWaitersGone = 0;
-  }
-  unlock( mtxUnblockLock );
-
-  if ( 1 == nSignalsWasLeft ) {
-    if ( 0 != nWaitersWasGone ) {
-      // sem_adjust( -nWaitersWasGone );
-      while ( nWaitersWasGone-- ) {
-        sem_wait( semBlockLock );          // better now than spurious
-later
-      }
-    }
-    sem_post( semBlockLock );              // open the gate
-  }
-
-  lock( mtxExternal );
-
-  return ( bTimedOut ) ? ETIMEOUT : 0;
-}
-
-signal(bAll) {
-
-  [auto: register int result         ]
-  [auto: register int nSignalsToIssue]
-
-  lock( mtxUnblockLock );
-
-  if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
-    if ( 0 == nWaitersBlocked ) { // NO-OP
-      return unlock( mtxUnblockLock );
-    }
-    if (bAll) {
-      nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
-      nWaitersBlocked = 0;
-    }
-    else {
-      nSignalsToIssue = 1;
-      nWaitersToUnblock++;
-      nWaitersBlocked--;
-    }
-  }
-  else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
-    sem_wait( semBlockLock ); // close the gate
-    if ( 0 != nWaitersGone ) {
-      nWaitersBlocked -= nWaitersGone;
-      nWaitersGone = 0;
-    }
-    if (bAll) {
-      nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
-      nWaitersBlocked = 0;
-    }
-    else {
-      nSignalsToIssue = nWaitersToUnblock = 1;
-      nWaitersBlocked--;
-    }
-  }
-  else { // NO-OP
-    return unlock( mtxUnblockLock );
-  }
-
-  unlock( mtxUnblockLock );
-  sem_post( semBlockQueue,nSignalsToIssue );
-  return result;
-}
-
----------- Algorithm 8b / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ONEBYONE
-------
-given:
-semBlockLock - bin.semaphore
-semBlockQueue - bin.semaphore
-mtxExternal - mutex or CS
-mtxUnblockLock - mutex or CS
-nWaitersGone - int
-nWaitersBlocked - int
-nWaitersToUnblock - int
-
-wait( timeout ) {
-
-  [auto: register int result          ]     // error checking omitted
-  [auto: register int nWaitersWasGone ]
-  [auto: register int nSignalsWasLeft ]
-
-  sem_wait( semBlockLock );
-  nWaitersBlocked++;
-  sem_post( semBlockLock );
-
-  unlock( mtxExternal );
-  bTimedOut = sem_wait( semBlockQueue,timeout );
-
-  lock( mtxUnblockLock );
-  if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
-    if ( bTimeout ) {                       // timeout (or canceled)
-      if ( 0 != nWaitersBlocked ) {
-        nWaitersBlocked--;
-        nSignalsWasLeft = 0;                // do not unblock next waiter
-below (already unblocked)
-      }
-      else {
-        nWaitersGone = 1;                   // spurious wakeup pending!!
-      }
-    }
-    if ( 0 == --nWaitersToUnblock &&
-      if ( 0 != nWaitersBlocked ) {
-        sem_post( semBlockLock );           // open the gate
-        nSignalsWasLeft = 0;                // do not open the gate below
-again
-      }
-      else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
-        nWaitersGone = 0;
-      }
-    }
-  }
-  else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or spurious
-semaphore :-)
-    sem_wait( semBlockLock );
-    nWaitersBlocked -= nWaitersGone;        // something is going on here -
-test of timeouts? :-)
-    sem_post( semBlockLock );
-    nWaitersGone = 0;
-  }
-  unlock( mtxUnblockLock );
-
-  if ( 1 == nSignalsWasLeft ) {
-    if ( 0 != nWaitersWasGone ) {
-      // sem_adjust( -1 );
-      sem_wait( semBlockQueue );           // better now than spurious
-later
-    }
-    sem_post( semBlockLock );              // open the gate
-  }
-  else if ( 0 != nSignalsWasLeft ) {
-    sem_post( semBlockQueue );             // unblock next waiter
-  }
-
-  lock( mtxExternal );
-
-  return ( bTimedOut ) ? ETIMEOUT : 0;
-}
-
-signal(bAll) {
-
-  [auto: register int result ]
-
-  lock( mtxUnblockLock );
-
-  if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
-    if ( 0 == nWaitersBlocked ) { // NO-OP
-      return unlock( mtxUnblockLock );
-    }
-    if (bAll) {
-      nWaitersToUnblock += nWaitersBlocked;
-      nWaitersBlocked = 0;
-    }
-    else {
-      nWaitersToUnblock++;
-      nWaitersBlocked--;
-    }
-    unlock( mtxUnblockLock );
-  }
-  else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
-    sem_wait( semBlockLock ); // close the gate
-    if ( 0 != nWaitersGone ) {
-      nWaitersBlocked -= nWaitersGone;
-      nWaitersGone = 0;
-    }
-    if (bAll) {
-      nWaitersToUnblock = nWaitersBlocked;
-      nWaitersBlocked = 0;
-    }
-    else {
-      nWaitersToUnblock = 1;
-      nWaitersBlocked--;
-    }
-    unlock( mtxUnblockLock );
-    sem_post( semBlockQueue );
-  }
-  else { // NO-OP
-    unlock( mtxUnblockLock );
-  }
-
-  return result;
-}
-
----------- Algorithm 8c / IMPL_EVENT,UNBLOCK_STRATEGY == UNBLOCK_ONEBYONE
----------
-given:
-hevBlockLock - auto-reset event
-hevBlockQueue - auto-reset event
-mtxExternal - mutex or CS
-mtxUnblockLock - mutex or CS
-nWaitersGone - int
-nWaitersBlocked - int
-nWaitersToUnblock - int
-
-wait( timeout ) {
-
-  [auto: register int result          ]     // error checking omitted
-  [auto: register int nSignalsWasLeft ]
-  [auto: register int nWaitersWasGone ]
-
-  wait( hevBlockLock,INFINITE );
-  nWaitersBlocked++;
-  set_event( hevBlockLock );
-
-  unlock( mtxExternal );
-  bTimedOut = wait( hevBlockQueue,timeout );
-
-  lock( mtxUnblockLock );
-  if ( 0 != (SignalsWasLeft = nWaitersToUnblock) ) {
-    if ( bTimeout ) {                       // timeout (or canceled)
-      if ( 0 != nWaitersBlocked ) {
-        nWaitersBlocked--;
-        nSignalsWasLeft = 0;                // do not unblock next waiter
-below (already unblocked)
-      }
-      else {
-        nWaitersGone = 1;                   // spurious wakeup pending!!
-      }
-    }
-    if ( 0 == --nWaitersToUnblock )
-      if ( 0 != nWaitersBlocked ) {
-        set_event( hevBlockLock );          // open the gate
-        nSignalsWasLeft = 0;                // do not open the gate below
-again
-      }
-      else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
-        nWaitersGone = 0;
-      }
-    }
-  }
-  else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or spurious
-event :-)
-    wait( hevBlockLock,INFINITE );
-    nWaitersBlocked -= nWaitersGone;        // something is going on here -
-test of timeouts? :-)
-    set_event( hevBlockLock );
-    nWaitersGone = 0;
-  }
-  unlock( mtxUnblockLock );
-
-  if ( 1 == nSignalsWasLeft ) {
-    if ( 0 != nWaitersWasGone ) {
-      reset_event( hevBlockQueue );         // better now than spurious
-later
-    }
-    set_event( hevBlockLock );              // open the gate
-  }
-  else if ( 0 != nSignalsWasLeft ) {
-    set_event( hevBlockQueue );             // unblock next waiter
-  }
-
-  lock( mtxExternal );
-
-  return ( bTimedOut ) ? ETIMEOUT : 0;
-}
-
-signal(bAll) {
-
-  [auto: register int result ]
-
-  lock( mtxUnblockLock );
-
-  if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
-    if ( 0 == nWaitersBlocked ) { // NO-OP
-      return unlock( mtxUnblockLock );
-    }
-    if (bAll) {
-      nWaitersToUnblock += nWaitersBlocked;
-      nWaitersBlocked = 0;
-    }
-    else {
-      nWaitersToUnblock++;
-      nWaitersBlocked--;
-    }
-    unlock( mtxUnblockLock );
-  }
-  else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
-    wait( hevBlockLock,INFINITE ); // close the gate
-    if ( 0 != nWaitersGone ) {
-      nWaitersBlocked -= nWaitersGone;
-      nWaitersGone = 0;
-    }
-    if (bAll) {
-      nWaitersToUnblock = nWaitersBlocked;
-      nWaitersBlocked = 0;
-    }
-    else {
-      nWaitersToUnblock = 1;
-      nWaitersBlocked--;
-    }
-    unlock( mtxUnblockLock );
-    set_event( hevBlockQueue );
-  }
-  else { // NO-OP
-    unlock( mtxUnblockLock );
-  }
-
-  return result;
-}
-
----------- Algorithm 8d / IMPL_EVENT,UNBLOCK_STRATEGY == UNBLOCK_ALL ------
-given:
-hevBlockLock - auto-reset event
-hevBlockQueueS - auto-reset event  // for signals
-hevBlockQueueB - manual-reset even // for broadcasts
-mtxExternal - mutex or CS
-mtxUnblockLock - mutex or CS
-eBroadcast - int                   // 0: no broadcast, 1: broadcast, 2:
-broadcast after signal(s)
-nWaitersGone - int
-nWaitersBlocked - int
-nWaitersToUnblock - int
-
-wait( timeout ) {
-
-  [auto: register int result          ]     // error checking omitted
-  [auto: register int eWasBroadcast   ]
-  [auto: register int nSignalsWasLeft ]
-  [auto: register int nWaitersWasGone ]
-
-  wait( hevBlockLock,INFINITE );
-  nWaitersBlocked++;
-  set_event( hevBlockLock );
-
-  unlock( mtxExternal );
-  bTimedOut = waitformultiple( hevBlockQueueS,hevBlockQueueB,timeout,ONE );
-
-  lock( mtxUnblockLock );
-  if ( 0 != (SignalsWasLeft = nWaitersToUnblock) ) {
-    if ( bTimeout ) {                       // timeout (or canceled)
-      if ( 0 != nWaitersBlocked ) {
-        nWaitersBlocked--;
-        nSignalsWasLeft = 0;                // do not unblock next waiter
-below (already unblocked)
-      }
-      else if ( 1 != eBroadcast ) {
-        nWaitersGone = 1;
-      }
-    }
-    if ( 0 == --nWaitersToUnblock ) {
-      if ( 0 != nWaitersBlocked ) {
-        set_event( hevBlockLock );           // open the gate
-        nSignalsWasLeft = 0;                 // do not open the gate below
-again
-      }
-      else {
-        if ( 0 != (eWasBroadcast = eBroadcast) ) {
-          eBroadcast = 0;
-        }
-        if ( 0 != (nWaitersWasGone = nWaitersGone ) {
-          nWaitersGone = 0;
-        }
-      }
-    }
-    else if ( 0 != eBroadcast ) {
-      nSignalsWasLeft = 0;                  // do not unblock next waiter
-below (already unblocked)
-    }
-  }
-  else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or spurious
-event :-)
-    wait( hevBlockLock,INFINITE );
-    nWaitersBlocked -= nWaitersGone;        // something is going on here -
-test of timeouts? :-)
-    set_event( hevBlockLock );
-    nWaitersGone = 0;
-  }
-  unlock( mtxUnblockLock );
-
-  if ( 1 == nSignalsWasLeft ) {
-    if ( 0 != eWasBroadcast ) {
-      reset_event( hevBlockQueueB );
-    }
-    if ( 0 != nWaitersWasGone ) {
-      reset_event( hevBlockQueueS );        // better now than spurious
-later
-    }
-    set_event( hevBlockLock );              // open the gate
-  }
-  else if ( 0 != nSignalsWasLeft ) {
-    set_event( hevBlockQueueS );            // unblock next waiter
-  }
-
-  lock( mtxExternal );
-
-  return ( bTimedOut ) ? ETIMEOUT : 0;
-}
-
-signal(bAll) {
-
-  [auto: register int    result        ]
-  [auto: register HANDLE hevBlockQueue ]
-
-  lock( mtxUnblockLock );
-
-  if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
-    if ( 0 == nWaitersBlocked ) { // NO-OP
-      return unlock( mtxUnblockLock );
-    }
-    if (bAll) {
-      nWaitersToUnblock += nWaitersBlocked;
-      nWaitersBlocked = 0;
-      eBroadcast = 2;
-      hevBlockQueue = hevBlockQueueB;
-    }
-    else {
-      nWaitersToUnblock++;
-      nWaitersBlocked--;
-      return unlock( mtxUnblockLock );
-    }
-  }
-  else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
-    wait( hevBlockLock,INFINITE ); // close the gate
-    if ( 0 != nWaitersGone ) {
-      nWaitersBlocked -= nWaitersGone;
-      nWaitersGone = 0;
-    }
-    if (bAll) {
-      nWaitersToUnblock = nWaitersBlocked;
-      nWaitersBlocked = 0;
-      eBroadcast = 1;
-      hevBlockQueue = hevBlockQueueB;
-    }
-    else {
-      nWaitersToUnblock = 1;
-      nWaitersBlocked--;
-      hevBlockQueue = hevBlockQueueS;
-    }
-  }
-  else { // NO-OP
-    return unlock( mtxUnblockLock );
-  }
-
-  unlock( mtxUnblockLock );
-  set_event( hevBlockQueue );
-  return result;
-}
----------------------- Forwarded by Alexander Terekhov/Germany/IBM on
-02/21/2001 09:13 AM ---------------------------
-
-Alexander Terekhov
-02/20/2001 04:33 PM
-
-To:   Louis Thomas <lthomas at arbitrade.com>
-cc:
-
-From: Alexander Terekhov/Germany/IBM at IBMDE
-Subject:  RE: FYI/comp.programming.threads/Re: pthread_cond_* implementatio
-      n questions
-Importance:    Normal
-
->Sorry, gotta take a break and work on something else for a while.
->Real work
->calls, unfortunately. I'll get back to you in two or three days.
-
-ok. no problem. here is some more stuff for pauses you might have
-in between :)
-
----------- Algorithm 7d / IMPL_EVENT,UNBLOCK_STRATEGY == UNBLOCK_ALL ------
-given:
-hevBlockLock - auto-reset event
-hevBlockQueueS - auto-reset event  // for signals
-hevBlockQueueB - manual-reset even // for broadcasts
-mtxExternal - mutex or CS
-mtxUnblockLock - mutex or CS
-bBroadcast - int
-nWaitersGone - int
-nWaitersBlocked - int
-nWaitersToUnblock - int
-
-wait( timeout ) {
-
-  [auto: register int result          ]     // error checking omitted
-  [auto: register int bWasBroadcast   ]
-  [auto: register int nSignalsWasLeft ]
-
-  wait( hevBlockLock,INFINITE );
-  nWaitersBlocked++;
-  set_event( hevBlockLock );
-
-  unlock( mtxExternal );
-  bTimedOut = waitformultiple( hevBlockQueueS,hevBlockQueueB,timeout,ONE );
-
-  lock( mtxUnblockLock );
-  if ( 0 != (SignalsWasLeft = nWaitersToUnblock) ) {
-    if ( bTimeout ) {                       // timeout (or canceled)
-      if ( 0 != nWaitersBlocked ) {
-        nWaitersBlocked--;
-        nSignalsWasLeft = 0;                // do not unblock next waiter
-below (already unblocked)
-      }
-      else if ( !bBroadcast ) {
-        wait( hevBlockQueueS,INFINITE );    // better now than spurious
-later
-      }
-    }
-    if ( 0 == --nWaitersToUnblock ) {
-      if ( 0 != nWaitersBlocked ) {
-        if ( bBroadcast ) {
-          reset_event( hevBlockQueueB );
-          bBroadcast = false;
-        }
-        set_event( hevBlockLock );           // open the gate
-        nSignalsWasLeft = 0;                 // do not open the gate below
-again
-      }
-      else if ( false != (bWasBroadcast = bBroadcast) ) {
-        bBroadcast = false;
-      }
-    }
-    else {
-      bWasBroadcast = bBroadcast;
-    }
-  }
-  else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or spurious
-event :-)
-    wait( hevBlockLock,INFINITE );
-    nWaitersBlocked -= nWaitersGone;        // something is going on here -
-test of timeouts? :-)
-    set_event( hevBlockLock );
-    nWaitersGone = 0;
-  }
-  unlock( mtxUnblockLock );
-
-  if ( 1 == nSignalsWasLeft ) {
-    if ( bWasBroadcast ) {
-      reset_event( hevBlockQueueB );
-    }
-    set_event( hevBlockLock );              // open the gate
-  }
-  else if ( 0 != nSignalsWasLeft && !bWasBroadcast ) {
-    set_event( hevBlockQueueS );            // unblock next waiter
-  }
-
-  lock( mtxExternal );
-
-  return ( bTimedOut ) ? ETIMEOUT : 0;
-}
-
-signal(bAll) {
-
-  [auto: register int    result        ]
-  [auto: register HANDLE hevBlockQueue ]
-
-  lock( mtxUnblockLock );
-
-  if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
-    if ( 0 == nWaitersBlocked ) { // NO-OP
-      return unlock( mtxUnblockLock );
-    }
-    if (bAll) {
-      nWaitersToUnblock += nWaitersBlocked;
-      nWaitersBlocked = 0;
-      bBroadcast = true;
-      hevBlockQueue = hevBlockQueueB;
-    }
-    else {
-      nWaitersToUnblock++;
-      nWaitersBlocked--;
-      return unlock( mtxUnblockLock );
-    }
-  }
-  else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
-    wait( hevBlockLock,INFINITE ); // close the gate
-    if ( 0 != nWaitersGone ) {
-      nWaitersBlocked -= nWaitersGone;
-      nWaitersGone = 0;
-    }
-    if (bAll) {
-      nWaitersToUnblock = nWaitersBlocked;
-      nWaitersBlocked = 0;
-      bBroadcast = true;
-      hevBlockQueue = hevBlockQueueB;
-    }
-    else {
-      nWaitersToUnblock = 1;
-      nWaitersBlocked--;
-      hevBlockQueue = hevBlockQueueS;
-    }
-  }
-  else { // NO-OP
-    return unlock( mtxUnblockLock );
-  }
-
-  unlock( mtxUnblockLock );
-  set_event( hevBlockQueue );
-  return result;
-}
-
-
-----------------------------------------------------------------------------
-
-Subject: RE: FYI/comp.programming.threads/Re: pthread_cond_* implementatio
-     n questions
-Date: Mon, 26 Feb 2001 22:20:12 -0600
-From: Louis Thomas <lthomas at arbitrade.com>
-To: "'TEREKHOV at de.ibm.com'" <TEREKHOV at de.ibm.com>
-CC: rpj at ise.canberra.edu.au, Thomas Pfaff <tpfaff at gmx.net>,
-     Nanbor Wang
-     <nanbor at cs.wustl.edu>
-
-Sorry all. Busy week.
-
-> this insures the fairness
-> which POSIX does not (e.g. two subsequent broadcasts - the gate does
-insure
-> that first wave waiters will start the race for the mutex before waiters
-> from the second wave - Linux pthreads process/unblock both waves
-> concurrently...)
-
-I'm not sure how we are any more fair about this than Linux. We certainly
-don't guarantee that the threads released by the first broadcast will get
-the external mutex before the threads of the second wave. In fact, it is
-possible that those threads will never get the external mutex if there is
-enough contention for it.
-
-> e.g. i was thinking about implementation with a pool of
-> N semaphores/counters [...]
-
-I considered that too. The problem is as you mentioned in a). You really
-need to assign threads to semaphores once you know how you want to wake them
-up, not when they first begin waiting which is the only time you can assign
-them.
-
-> well, i am not quite sure that i've fully understood your scenario,
-
-Hmm. Well, it think it's an important example, so I'll try again. First, we
-have thread A which we KNOW is waiting on a condition. As soon as it becomes
-unblocked for any reason, we will know because it will set a flag. Since the
-flag is not set, we are 100% confident that thread A is waiting on the
-condition. We have another thread, thread B, which has acquired the mutex
-and is about to wait on the condition. Thus it is pretty clear that at any
-point, either just A is waiting, or A and B are waiting. Now thread C comes
-along. C is about to do a broadcast on the condition. A broadcast is
-guaranteed to unblock all threads currently waiting on a condition, right?
-Again, we said that either just A is waiting, or A and B are both waiting.
-So, when C does its broadcast, depending upon whether B has started waiting
-or not, thread C will unblock A or unblock A and B. Either way, C must
-unblock A, right?
-
-Now, you said anything that happens is correct so long as a) "a signal is
-not lost between unlocking the mutex and waiting on the condition" and b) "a
-thread must not steal a signal it sent", correct? Requirement b) is easy to
-satisfy: in this scenario, thread C will never wait on the condition, so it
-won't steal any signals.  Requirement a) is not hard either. The only way we
-could fail to meet requirement a) in this scenario is if thread B was
-started waiting but didn't wake up because a signal was lost. This will not
-happen.
-
-Now, here is what happens. Assume thread C beats thread B. Thread C looks to
-see how many threads are waiting on the condition. Thread C sees just one
-thread, thread A, waiting. It does a broadcast waking up just one thread
-because just one thread is waiting. Next, before A can become unblocked,
-thread B begins waiting. Now there are two threads waiting, but only one
-will be unblocked. Suppose B wins. B will become unblocked. A will not
-become unblocked, because C only unblocked one thread (sema_post cond, 1).
-So at the end, B finishes and A remains blocked.
-
-We have met both of your requirements, so by your rules, this is an
-acceptable outcome. However, I think that the spec says this is an
-unacceptable outcome! We know for certain that A was waiting and that C did
-a broadcast, but A did not become unblocked! Yet, the spec says that a
-broadcast wakes up all waiting threads. This did not happen. Do you agree
-that this shows your rules are not strict enough?
-
-> and what about N2? :) this one does allow almost everything.
-
-Don't get me started about rule #2. I'll NEVER advocate an algorithm that
-uses rule 2 as an excuse to suck!
-
-> but it is done (decrement)under mutex protection - this is not a subject
-> of a race condition.
-
-You are correct. My mistake.
-
-> i would remove "_bTimedOut=false".. after all, it was a real timeout..
-
-I disagree. A thread that can't successfully retract its waiter status can't
-really have timed out. If a thread can't return without executing extra code
-to deal with the fact that someone tried to unblock it, I think it is a poor
-idea to pretend we
-didn't realize someone was trying to signal us. After all, a signal is more
-important than a time out.
-
-> when nSignaled != 0, it is possible to update nWaiters (--) and do not
-> touch nGone
-
-I realize this, but I was thinking that writing it the other ways saves
-another if statement.
-
-> adjust only if nGone != 0 and save one cache memory write - probably much
-slower than 'if'
-
-Hmm. You are probably right.
-
-> well, in a strange (e.g. timeout test) program you may (theoretically)
-> have an overflow of nWaiters/nGone counters (with waiters repeatedly
-timing
-> out and no signals at all).
-
-Also true. Not only that, but you also have the possibility that one could
-overflow the number of waiters as well! However, considering the limit you
-have chosen for nWaitersGone, I suppose it is unlikely that anyone would be
-able to get INT_MAX/2 threads waiting on a single condition. :)
-
-Analysis of 8a:
-
-It looks correct to me.
-
-What are IPC semaphores?
-
-In the line where you state, "else if ( nWaitersBlocked > nWaitersGone ) {
-// HARMLESS RACE CONDITION!" there is no race condition for nWaitersGone
-because nWaitersGone is never modified without holding mtxUnblockLock. You
-are correct that there is a harmless race on nWaitersBlocked, which can
-increase and make the condition become true just after we check it. If this
-happens, we interpret it as the wait starting after the signal.
-
-I like your optimization of this. You could improve Alg. 6 as follows:
----------- Algorithm 6b ----------
-signal(bAll) {
-  _nSig=0
-  lock counters
-  // this is safe because nWaiting can only be decremented by a thread that
-  // owns counters and nGone can only be changed by a thread that owns
-counters.
-  if (nWaiting>nGone) {
-    if (0==nSignaled) {
-      sema_wait gate // close gate if not already closed
-    }
-    if (nGone>0) {
-      nWaiting-=nGone
-      nGone=0
-    }
-    _nSig=bAll?nWaiting:1
-    nSignaled+=_nSig
-    nWaiting-=_nSig
-  }
-  unlock counters
-  if (0!=_nSig) {
-    sema_post queue, _nSig
-  }
-}
----------- ---------- ----------
-I guess this wouldn't apply to Alg 8a because nWaitersGone changes meanings
-depending upon whether the gate is open or closed.
-
-In the loop "while ( nWaitersWasGone-- ) {" you do a sema_wait on
-semBlockLock. Perhaps waiting on semBlockQueue would be a better idea.
-
-What have you gained by making the last thread to be signaled do the waits
-for all the timed out threads, besides added complexity? It took me a long
-time to figure out what your objective was with this, to realize you were
-using nWaitersGone to mean two different things, and to verify that you
-hadn't introduced any bug by doing this. Even now I'm not 100% sure.
-
-What has all this playing about with nWaitersGone really gained us besides a
-lot of complexity (it is much harder to verify that this solution is
-correct), execution overhead (we now have a lot more if statements to
-evaluate), and space overhead (more space for the extra code, and another
-integer in our data)? We did manage to save a lock/unlock pair in an
-uncommon case (when a time out occurs) at the above mentioned expenses in
-the common cases.
-
-As for 8b, c, and d, they look ok though I haven't studied them thoroughly.
-What would you use them for?
-
-    Later,
-        -Louis! :)
-
------------------------------------------------------------------------------
-
-Subject: RE: FYI/comp.programming.threads/Re: pthread_cond_* implementatio
-     n questions
-Date: Tue, 27 Feb 2001 15:51:28 +0100
-From: TEREKHOV at de.ibm.com
-To: Louis Thomas <lthomas at arbitrade.com>
-CC: rpj at ise.canberra.edu.au, Thomas Pfaff <tpfaff at gmx.net>,
-     Nanbor Wang <nanbor at cs.wustl.edu>
-
-Hi Louis,
-
->> that first wave waiters will start the race for the mutex before waiters
->> from the second wave - Linux pthreads process/unblock both waves
->> concurrently...)
->
->I'm not sure how we are any more fair about this than Linux. We certainly
->don't guarantee that the threads released by the first broadcast will get
->the external mutex before the threads of the second wave. In fact, it is
->possible that those threads will never get the external mutex if there is
->enough contention for it.
-
-correct. but gate is nevertheless more fair than Linux because of the
-barrier it establishes between two races (1st and 2nd wave waiters) for
-the mutex which under 'normal' circumstances (e.g. all threads of equal
-priorities,..) will 'probably' result in fair behaviour with respect to
-mutex ownership.
-
->> well, i am not quite sure that i've fully understood your scenario,
->
->Hmm. Well, it think it's an important example, so I'll try again. ...
-
-ok. now i seem to understand this example. well, now it seems to me
-that the only meaningful rule is just:
-
-a) "a signal is not lost between unlocking the mutex and waiting on the
-condition"
-
-and that the rule
-
-b) "a thread must not steal a signal it sent"
-
-is not needed at all because a thread which violates b) also violates a).
-
-i'll try to explain..
-
-i think that the most important thing is how POSIX defines waiter's
-visibility:
-
-"if another thread is able to acquire the mutex after the about-to-block
-thread
-has released it, then a subsequent call to pthread_cond_signal() or
-pthread_cond_broadcast() in that thread behaves as if it were issued after
-the about-to-block thread has blocked. "
-
-my understanding is the following:
-
-1) there is no guarantees whatsoever with respect to whether
-signal/broadcast
-will actually unblock any 'waiter' if it is done w/o acquiring the mutex
-first
-(note that a thread may release it before signal/broadcast - it does not
-matter).
-
-2) it is guaranteed that waiters become 'visible' - eligible for unblock as
-soon
-as signalling thread acquires the mutex (but not before!!)
-
-so..
-
->So, when C does its broadcast, depending upon whether B has started
-waiting
->or not, thread C will unblock A or unblock A and B. Either way, C must
->unblock A, right?
-
-right. but only if C did acquire the mutex prior to broadcast (it may
-release it before broadcast as well).
-
-implementation will violate waiters visibility rule (signal will become
-lost)
-if C will not unblock A.
-
->Now, here is what happens. Assume thread C beats thread B. Thread C looks
-to
->see how many threads are waiting on the condition. Thread C sees just one
->thread, thread A, waiting. It does a broadcast waking up just one thread
->because just one thread is waiting. Next, before A can become unblocked,
->thread B begins waiting. Now there are two threads waiting, but only one
->will be unblocked. Suppose B wins. B will become unblocked. A will not
->become unblocked, because C only unblocked one thread (sema_post cond, 1).
->So at the end, B finishes and A remains blocked.
-
-thread C did acquire the mutex ("Thread C sees just one thread, thread A,
-waiting"). beginning from that moment it is guaranteed that subsequent
-broadcast will unblock A. Otherwise we will have a lost signal with respect
-to A. I do think that it does not matter whether the signal was physically
-(completely) lost or was just stolen by another thread (B) - in both cases
-it was simply lost with respect to A.
-
->..Do you agree that this shows your rules are not strict enough?
-
-probably the opposite.. :-) i think that it shows that the only meaningful
-rule is
-
-a) "a signal is not lost between unlocking the mutex and waiting on the
-condition"
-
-with clarification of waiters visibility as defined by POSIX above.
-
->> i would remove "_bTimedOut=false".. after all, it was a real timeout..
->
->I disagree. A thread that can't successfully retract its waiter status
-can't
->really have timed out. If a thread can't return without executing extra
-code
->to deal with the fact that someone tried to unblock it, I think it is a
-poor
->idea to pretend we
->didn't realize someone was trying to signal us. After all, a signal is
-more
->important than a time out.
-
-a) POSIX does allow timed out thread to consume a signal (cancelled is
-not).
-b) ETIMEDOUT status just says that: "The time specified by abstime to
-pthread_cond_timedwait() has passed."
-c) it seem to me that hiding timeouts would violate "The
-pthread_cond_timedwait()
-function is the same as pthread_cond_wait() except that an error is
-returned if
-the absolute time specified by abstime passes (that is, system time equals
-or
-exceeds abstime) before the condition cond is signaled or broadcasted"
-because
-the abs. time did really pass before cond was signaled (waiter was
-released via semaphore). however, if it really matters, i could imaging
-that we
-can save an abs. time of signal/broadcast and compare it with timeout after
-unblock to find out whether it was a 'real' timeout or not. absent this
-check
-i do think that hiding timeouts would result in technical violation of
-specification.. but i think that this check is not important and we can
-simply
-trust timeout error code provided by wait since we are not trying to make
-'hard' realtime implementation.
-
->What are IPC semaphores?
-
-<sys/sem.h>
-int   semctl(int, int, int, ...);
-int   semget(key_t, int, int);
-int   semop(int, struct sembuf *, size_t);
-
-they support adjustment of semaphore counter (semvalue)
-in one single call - imaging Win32 ReleaseSemaphore( hsem,-N )
-
->In the line where you state, "else if ( nWaitersBlocked > nWaitersGone ) {
->// HARMLESS RACE CONDITION!" there is no race condition for nWaitersGone
->because nWaitersGone is never modified without holding mtxUnblockLock. You
->are correct that there is a harmless race on nWaitersBlocked, which can
->increase and make the condition become true just after we check it. If
-this
->happens, we interpret it as the wait starting after the signal.
-
-well, the reason why i've asked on comp.programming.threads whether this
-race
-condition is harmless or not is that in order to be harmless it should not
-violate the waiters visibility rule (see above). Fortunately, we increment
-the counter under protection of external mutex.. so that any (signalling)
-thread which will acquire the mutex next, should see the updated counter
-(in signal) according to POSIX memory visibility rules and mutexes
-(memory barriers). But i am not so sure how it actually works on
-Win32/INTEL
-which does not explicitly define any memory visibility rules :(
-
->I like your optimization of this. You could improve Alg. 6 as follows:
->---------- Algorithm 6b ----------
->signal(bAll) {
->  _nSig=0
->  lock counters
->  // this is safe because nWaiting can only be decremented by a thread
-that
->  // owns counters and nGone can only be changed by a thread that owns
->counters.
->  if (nWaiting>nGone) {
->    if (0==nSignaled) {
->      sema_wait gate // close gate if not already closed
->    }
->    if (nGone>0) {
->      nWaiting-=nGone
->      nGone=0
->    }
->    _nSig=bAll?nWaiting:1
->    nSignaled+=_nSig
->    nWaiting-=_nSig
->  }
->  unlock counters
->  if (0!=_nSig) {
->    sema_post queue, _nSig
->  }
->}
->---------- ---------- ----------
->I guess this wouldn't apply to Alg 8a because nWaitersGone changes
-meanings
->depending upon whether the gate is open or closed.
-
-agree.
-
->In the loop "while ( nWaitersWasGone-- ) {" you do a sema_wait on
->semBlockLock. Perhaps waiting on semBlockQueue would be a better idea.
-
-you are correct. my mistake.
-
->What have you gained by making the last thread to be signaled do the waits
->for all the timed out threads, besides added complexity? It took me a long
->time to figure out what your objective was with this, to realize you were
->using nWaitersGone to mean two different things, and to verify that you
->hadn't introduced any bug by doing this. Even now I'm not 100% sure.
->
->What has all this playing about with nWaitersGone really gained us besides
-a
->lot of complexity (it is much harder to verify that this solution is
->correct), execution overhead (we now have a lot more if statements to
->evaluate), and space overhead (more space for the extra code, and another
->integer in our data)? We did manage to save a lock/unlock pair in an
->uncommon case (when a time out occurs) at the above mentioned expenses in
->the common cases.
-
-well, please consider the following:
-
-1) with multiple waiters unblocked (but some timed out) the trick with
-counter
-seem to ensure potentially higher level of concurrency by not delaying
-most of unblocked waiters for semaphore cleanup - only the last one
-will be delayed but all others would already contend/acquire/release
-the external mutex - the critical section protected by mtxUnblockLock is
-made smaller (increment + couple of IFs is faster than system/kernel call)
-which i think is good in general. however, you are right, this is done
-at expense of 'normal' waiters..
-
-2) some semaphore APIs (e.g. POSIX IPC sems) do allow to adjust the
-semaphore counter in one call => less system/kernel calls.. imagine:
-
-if ( 1 == nSignalsWasLeft ) {
-    if ( 0 != nWaitersWasGone ) {
-      ReleaseSemaphore( semBlockQueue,-nWaitersWasGone );  // better now
-than spurious later
-    }
-    sem_post( semBlockLock );              // open the gate
-  }
-
-3) even on win32 a single thread doing multiple cleanup calls (to wait)
-will probably result in faster execution (because of processor caching)
-than multiple threads each doing a single call to wait.
-
->As for 8b, c, and d, they look ok though I haven't studied them
-thoroughly.
->What would you use them for?
-
-8b) for semaphores which do not allow to unblock multiple waiters
-in a single call to post/release (e.g. POSIX realtime semaphores -
-<semaphore.h>)
-
-8c/8d) for WinCE prior to 3.0 (WinCE 3.0 does have semaphores)
-
-ok. so, which one is the 'final' algorithm(s) which we should use in
-pthreads-win32??
-
-regards,
-alexander.
-
-----------------------------------------------------------------------------
-
-Louis Thomas <lthomas at arbitrade.com> on 02/27/2001 05:20:12 AM
-
-Please respond to Louis Thomas <lthomas at arbitrade.com>
-
-To:   Alexander Terekhov/Germany/IBM at IBMDE
-cc:   rpj at ise.canberra.edu.au, Thomas Pfaff <tpfaff at gmx.net>, Nanbor Wang
-      <nanbor at cs.wustl.edu>
-Subject:  RE: FYI/comp.programming.threads/Re: pthread_cond_* implementatio
-      n questions
-
-Sorry all. Busy week.
-
-> this insures the fairness
-> which POSIX does not (e.g. two subsequent broadcasts - the gate does
-insure
-> that first wave waiters will start the race for the mutex before waiters
-> from the second wave - Linux pthreads process/unblock both waves
-> concurrently...)
-
-I'm not sure how we are any more fair about this than Linux. We certainly
-don't guarantee that the threads released by the first broadcast will get
-the external mutex before the threads of the second wave. In fact, it is
-possible that those threads will never get the external mutex if there is
-enough contention for it.
-
-> e.g. i was thinking about implementation with a pool of
-> N semaphores/counters [...]
-
-I considered that too. The problem is as you mentioned in a). You really
-need to assign threads to semaphores once you know how you want to wake
-them
-up, not when they first begin waiting which is the only time you can assign
-them.
-
-> well, i am not quite sure that i've fully understood your scenario,
-
-Hmm. Well, it think it's an important example, so I'll try again. First, we
-have thread A which we KNOW is waiting on a condition. As soon as it
-becomes
-unblocked for any reason, we will know because it will set a flag. Since
-the
-flag is not set, we are 100% confident that thread A is waiting on the
-condition. We have another thread, thread B, which has acquired the mutex
-and is about to wait on the condition. Thus it is pretty clear that at any
-point, either just A is waiting, or A and B are waiting. Now thread C comes
-along. C is about to do a broadcast on the condition. A broadcast is
-guaranteed to unblock all threads currently waiting on a condition, right?
-Again, we said that either just A is waiting, or A and B are both waiting.
-So, when C does its broadcast, depending upon whether B has started waiting
-or not, thread C will unblock A or unblock A and B. Either way, C must
-unblock A, right?
-
-Now, you said anything that happens is correct so long as a) "a signal is
-not lost between unlocking the mutex and waiting on the condition" and b)
-"a
-thread must not steal a signal it sent", correct? Requirement b) is easy to
-satisfy: in this scenario, thread C will never wait on the condition, so it
-won't steal any signals.  Requirement a) is not hard either. The only way
-we
-could fail to meet requirement a) in this scenario is if thread B was
-started waiting but didn't wake up because a signal was lost. This will not
-happen.
-
-Now, here is what happens. Assume thread C beats thread B. Thread C looks
-to
-see how many threads are waiting on the condition. Thread C sees just one
-thread, thread A, waiting. It does a broadcast waking up just one thread
-because just one thread is waiting. Next, before A can become unblocked,
-thread B begins waiting. Now there are two threads waiting, but only one
-will be unblocked. Suppose B wins. B will become unblocked. A will not
-become unblocked, because C only unblocked one thread (sema_post cond, 1).
-So at the end, B finishes and A remains blocked.
-
-We have met both of your requirements, so by your rules, this is an
-acceptable outcome. However, I think that the spec says this is an
-unacceptable outcome! We know for certain that A was waiting and that C did
-a broadcast, but A did not become unblocked! Yet, the spec says that a
-broadcast wakes up all waiting threads. This did not happen. Do you agree
-that this shows your rules are not strict enough?
-
-> and what about N2? :) this one does allow almost everything.
-
-Don't get me started about rule #2. I'll NEVER advocate an algorithm that
-uses rule 2 as an excuse to suck!
-
-> but it is done (decrement)under mutex protection - this is not a subject
-> of a race condition.
-
-You are correct. My mistake.
-
-> i would remove "_bTimedOut=false".. after all, it was a real timeout..
-
-I disagree. A thread that can't successfully retract its waiter status
-can't
-really have timed out. If a thread can't return without executing extra
-code
-to deal with the fact that someone tried to unblock it, I think it is a
-poor
-idea to pretend we
-didn't realize someone was trying to signal us. After all, a signal is more
-important than a time out.
-
-> when nSignaled != 0, it is possible to update nWaiters (--) and do not
-> touch nGone
-
-I realize this, but I was thinking that writing it the other ways saves
-another if statement.
-
-> adjust only if nGone != 0 and save one cache memory write - probably much
-slower than 'if'
-
-Hmm. You are probably right.
-
-> well, in a strange (e.g. timeout test) program you may (theoretically)
-> have an overflow of nWaiters/nGone counters (with waiters repeatedly
-timing
-> out and no signals at all).
-
-Also true. Not only that, but you also have the possibility that one could
-overflow the number of waiters as well! However, considering the limit you
-have chosen for nWaitersGone, I suppose it is unlikely that anyone would be
-able to get INT_MAX/2 threads waiting on a single condition. :)
-
-Analysis of 8a:
-
-It looks correct to me.
-
-What are IPC semaphores?
-
-In the line where you state, "else if ( nWaitersBlocked > nWaitersGone ) {
-// HARMLESS RACE CONDITION!" there is no race condition for nWaitersGone
-because nWaitersGone is never modified without holding mtxUnblockLock. You
-are correct that there is a harmless race on nWaitersBlocked, which can
-increase and make the condition become true just after we check it. If this
-happens, we interpret it as the wait starting after the signal.
-
-I like your optimization of this. You could improve Alg. 6 as follows:
----------- Algorithm 6b ----------
-signal(bAll) {
-  _nSig=0
-  lock counters
-  // this is safe because nWaiting can only be decremented by a thread that
-  // owns counters and nGone can only be changed by a thread that owns
-counters.
-  if (nWaiting>nGone) {
-    if (0==nSignaled) {
-      sema_wait gate // close gate if not already closed
-    }
-    if (nGone>0) {
-      nWaiting-=nGone
-      nGone=0
-    }
-    _nSig=bAll?nWaiting:1
-    nSignaled+=_nSig
-    nWaiting-=_nSig
-  }
-  unlock counters
-  if (0!=_nSig) {
-    sema_post queue, _nSig
-  }
-}
----------- ---------- ----------
-I guess this wouldn't apply to Alg 8a because nWaitersGone changes meanings
-depending upon whether the gate is open or closed.
-
-In the loop "while ( nWaitersWasGone-- ) {" you do a sema_wait on
-semBlockLock. Perhaps waiting on semBlockQueue would be a better idea.
-
-What have you gained by making the last thread to be signaled do the waits
-for all the timed out threads, besides added complexity? It took me a long
-time to figure out what your objective was with this, to realize you were
-using nWaitersGone to mean two different things, and to verify that you
-hadn't introduced any bug by doing this. Even now I'm not 100% sure.
-
-What has all this playing about with nWaitersGone really gained us besides
-a
-lot of complexity (it is much harder to verify that this solution is
-correct), execution overhead (we now have a lot more if statements to
-evaluate), and space overhead (more space for the extra code, and another
-integer in our data)? We did manage to save a lock/unlock pair in an
-uncommon case (when a time out occurs) at the above mentioned expenses in
-the common cases.
-
-As for 8b, c, and d, they look ok though I haven't studied them thoroughly.
-What would you use them for?
-
-    Later,
-        -Louis! :)
-
diff --git a/deps/w32-pthreads/README.NONPORTABLE b/deps/w32-pthreads/README.NONPORTABLE
deleted file mode 100644
index 9bdc445..0000000
--- a/deps/w32-pthreads/README.NONPORTABLE
+++ /dev/null
@@ -1,783 +0,0 @@
-This file documents non-portable functions and other issues.
-
-Non-portable functions included in pthreads-win32
--------------------------------------------------
-
-BOOL
-pthread_win32_test_features_np(int mask)
-
-	This routine allows an application to check which
-	run-time auto-detected features are available within
-	the library.
-
-	The possible features are:
-
-		PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE
-			Return TRUE if the native version of
-			InterlockedCompareExchange() is being used.
-			This feature is not meaningful in recent
-			library versions as MSVC builds only support
-			system implemented ICE. Note that all Mingw
-			builds use inlined asm versions of all the
-			Interlocked routines.
-		PTW32_ALERTABLE_ASYNC_CANCEL
-			Return TRUE is the QueueUserAPCEx package
-			QUSEREX.DLL is available and the AlertDrv.sys
-			driver is loaded into Windows, providing
-			alertable (pre-emptive) asyncronous threads
-			cancelation. If this feature returns FALSE
-			then the default async cancel scheme is in
-			use, which cannot cancel blocked threads.
-
-	Features may be Or'ed into the mask parameter, in which case
-	the routine returns TRUE if any of the Or'ed features would
-	return TRUE. At this stage it doesn't make sense to Or features
-	but it may some day.
-
-
-void *
-pthread_timechange_handler_np(void *)
-
-        To improve tolerance against operator or time service
-        initiated system clock changes.
-
-        This routine can be called by an application when it
-        receives a WM_TIMECHANGE message from the system. At
-        present it broadcasts all condition variables so that
-        waiting threads can wake up and re-evaluate their
-        conditions and restart their timed waits if required.
-
-        It has the same return type and argument type as a
-        thread routine so that it may be called directly
-        through pthread_create(), i.e. as a separate thread.
-
-        Parameters
-
-        Although a parameter must be supplied, it is ignored.
-        The value NULL can be used.
-
-        Return values
-
-        It can return an error EAGAIN to indicate that not
-        all condition variables were broadcast for some reason.
-        Otherwise, 0 is returned.
-
-        If run as a thread, the return value is returned
-        through pthread_join().
-
-        The return value should be cast to an integer.
-
-
-HANDLE
-pthread_getw32threadhandle_np(pthread_t thread);
-
-	Returns the win32 thread handle that the POSIX
-	thread "thread" is running as.
-
-	Applications can use the win32 handle to set
-	win32 specific attributes of the thread.
-
-DWORD
-pthread_getw32threadid_np (pthread_t thread)
-
-	Returns the Windows native thread ID that the POSIX
-	thread "thread" is running as.
-
-        Only valid when the library is built where
-        ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
-        and otherwise returns 0.
-
-
-int
-pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, int kind)
-
-int
-pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, int *kind)
-
-        These two routines are included for Linux compatibility
-        and are direct equivalents to the standard routines
-                pthread_mutexattr_settype
-                pthread_mutexattr_gettype
-
-        pthread_mutexattr_setkind_np accepts the following
-        mutex kinds:
-                PTHREAD_MUTEX_FAST_NP
-                PTHREAD_MUTEX_ERRORCHECK_NP
-                PTHREAD_MUTEX_RECURSIVE_NP
-
-        These are really just equivalent to (respectively):
-                PTHREAD_MUTEX_NORMAL
-                PTHREAD_MUTEX_ERRORCHECK
-                PTHREAD_MUTEX_RECURSIVE
-
-int
-pthread_delay_np (const struct timespec *interval);
-
-        This routine causes a thread to delay execution for a specific period of time.
-        This period ends at the current time plus the specified interval. The routine
-        will not return before the end of the period is reached, but may return an
-        arbitrary amount of time after the period has gone by. This can be due to
-        system load, thread priorities, and system timer granularity.
-
-        Specifying an interval of zero (0) seconds and zero (0) nanoseconds is
-        allowed and can be used to force the thread to give up the processor or to
-        deliver a pending cancelation request.
-
-        This routine is a cancelation point.
-
-        The timespec structure contains the following two fields:
-
-                tv_sec is an integer number of seconds.
-                tv_nsec is an integer number of nanoseconds. 
-
-        Return Values
-
-        If an error condition occurs, this routine returns an integer value
-        indicating the type of error. Possible return values are as follows:
-
-        0          Successful completion. 
-        [EINVAL]   The value specified by interval is invalid. 
-
-int
-pthread_num_processors_np (void)
-
-        This routine (found on HPUX systems) returns the number of processors
-        in the system. This implementation actually returns the number of
-        processors available to the process, which can be a lower number
-        than the system's number, depending on the process's affinity mask.
-
-BOOL
-pthread_win32_process_attach_np (void);
-
-BOOL
-pthread_win32_process_detach_np (void);
-
-BOOL
-pthread_win32_thread_attach_np (void);
-
-BOOL
-pthread_win32_thread_detach_np (void);
-
-	These functions contain the code normally run via dllMain
-	when the library is used as a dll but which need to be
-	called explicitly by an application when the library
-	is statically linked. As of version 2.9.0 of the library, static
-	builds using either MSC or GCC will call pthread_win32_process_*
-	automatically at application startup and exit respectively.
-
-	Otherwise, you will need to call pthread_win32_process_attach_np()
-	before you can call any pthread routines when statically linking.
-	You should call pthread_win32_process_detach_np() before
-	exiting your application to clean up.
-
-	pthread_win32_thread_attach_np() is currently a no-op, but
-	pthread_win32_thread_detach_np() is needed to clean up
-	the implicit pthread handle that is allocated to a Win32 thread if
-	it calls any pthreads routines. Call this routine when the
-	Win32 thread exits.
-
-	Threads created through pthread_create() do not	need to call
-	pthread_win32_thread_detach_np().
-
-	These functions invariably return TRUE except for
-	pthread_win32_process_attach_np() which will return FALSE
-	if pthreads-win32 initialisation fails.
-
-int
-pthreadCancelableWait (HANDLE waitHandle);
-
-int
-pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout);
-
-	These two functions provide hooks into the pthread_cancel
-	mechanism that will allow you to wait on a Windows handle
-	and make it a cancellation point. Both functions block
-	until either the given w32 handle is signaled, or
-	pthread_cancel has been called. It is implemented using
-	WaitForMultipleObjects on 'waitHandle' and a manually
-	reset w32 event used to implement pthread_cancel.
-
-
-Non-portable issues
--------------------
-
-Thread priority
-
-	POSIX defines a single contiguous range of numbers that determine a
-	thread's priority. Win32 defines priority classes and priority
-	levels relative to these classes. Classes are simply priority base
-	levels that the defined priority levels are relative to such that,
-	changing a process's priority class will change the priority of all
-	of it's threads, while the threads retain the same relativity to each
-	other.
-
-	A Win32 system defines a single contiguous monotonic range of values
-	that define system priority levels, just like POSIX. However, Win32
-	restricts individual threads to a subset of this range on a
-	per-process basis.
-
-	The following table shows the base priority levels for combinations
-	of priority class and priority value in Win32.
-	
-	 Process Priority Class               Thread Priority Level
-	 -----------------------------------------------------------------
-	 1 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_IDLE
-	 1 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_IDLE
-	 1 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_IDLE
-	 1 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_IDLE
-	 1 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_IDLE
-	 2 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_LOWEST
-	 3 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_BELOW_NORMAL
-	 4 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_NORMAL
-	 4 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_LOWEST
-	 5 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_ABOVE_NORMAL
-	 5 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_BELOW_NORMAL
-	 5 Background NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_LOWEST
-	 6 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_HIGHEST
-	 6 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_NORMAL
-	 6 Background NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_BELOW_NORMAL
-	 7 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_ABOVE_NORMAL
-	 7 Background NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_NORMAL
-	 7 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_LOWEST
- 	 8 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_HIGHEST
-	 8 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_ABOVE_NORMAL
-	 8 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_BELOW_NORMAL
-	 8 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_LOWEST
-	 9 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_HIGHEST
-	 9 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_NORMAL
-	 9 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_BELOW_NORMAL
-	10 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_ABOVE_NORMAL
-	10 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_NORMAL
-	11 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_HIGHEST
-	11 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_ABOVE_NORMAL
-	11 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_LOWEST
-	12 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_HIGHEST
-	12 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_BELOW_NORMAL
-	13 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_NORMAL
-	14 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_ABOVE_NORMAL
-	15 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_HIGHEST
-	15 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_TIME_CRITICAL
-	15 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_TIME_CRITICAL
-	15 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_TIME_CRITICAL
-	15 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_TIME_CRITICAL
-	15 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_TIME_CRITICAL
-	16 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_IDLE
-	17 REALTIME_PRIORITY_CLASS            -7
-	18 REALTIME_PRIORITY_CLASS            -6
-	19 REALTIME_PRIORITY_CLASS            -5
-	20 REALTIME_PRIORITY_CLASS            -4
-	21 REALTIME_PRIORITY_CLASS            -3
-	22 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_LOWEST
-	23 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_BELOW_NORMAL
-	24 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_NORMAL
-	25 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_ABOVE_NORMAL
-	26 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_HIGHEST
-	27 REALTIME_PRIORITY_CLASS             3
-	28 REALTIME_PRIORITY_CLASS             4
-	29 REALTIME_PRIORITY_CLASS             5
-	30 REALTIME_PRIORITY_CLASS             6
-	31 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_TIME_CRITICAL
-	
-	Windows NT:  Values -7, -6, -5, -4, -3, 3, 4, 5, and 6 are not supported.
-
-
-	As you can see, the real priority levels available to any individual
-	Win32 thread are non-contiguous.
-
-	An application using pthreads-win32 should not make assumptions about
-	the numbers used to represent thread priority levels, except that they
-	are monotonic between the values returned by sched_get_priority_min()
-	and sched_get_priority_max(). E.g. Windows 95, 98, NT, 2000, XP make
-	available a non-contiguous range of numbers between -15 and 15, while
-	at least one version of WinCE (3.0) defines the minimum priority
-	(THREAD_PRIORITY_LOWEST) as 5, and the maximum priority
-	(THREAD_PRIORITY_HIGHEST) as 1.
-
-	Internally, pthreads-win32 maps any priority levels between
-	THREAD_PRIORITY_IDLE and THREAD_PRIORITY_LOWEST to THREAD_PRIORITY_LOWEST,
-	or between THREAD_PRIORITY_TIME_CRITICAL and THREAD_PRIORITY_HIGHEST to
-	THREAD_PRIORITY_HIGHEST. Currently, this also applies to
-	REALTIME_PRIORITY_CLASSi even if levels -7, -6, -5, -4, -3, 3, 4, 5, and 6
-	are supported.
-
-	If it wishes, a Win32 application using pthreads-win32 can use the Win32
-	defined priority macros THREAD_PRIORITY_IDLE through
-	THREAD_PRIORITY_TIME_CRITICAL.
-
-
-The opacity of the pthread_t datatype
--------------------------------------
-and possible solutions for portable null/compare/hash, etc
-----------------------------------------------------------
-
-Because pthread_t is an opague datatype an implementation is permitted to define
-pthread_t in any way it wishes. That includes defining some bits, if it is
-scalar, or members, if it is an aggregate, to store information that may be
-extra to the unique identifying value of the ID. As a result, pthread_t values
-may not be directly comparable.
-
-If you want your code to be portable you must adhere to the following contraints:
-
-1) Don't assume it is a scalar data type, e.g. an integer or pointer value. There
-are several other implementations where pthread_t is also a struct. See our FAQ
-Question 11 for our reasons for defining pthread_t as a struct.
-
-2) You must not compare them using relational or equality operators. You must use
-the API function pthread_equal() to test for equality.
-
-3) Never attempt to reference individual members.
-
-
-The problem
-
-Certain applications would like to be able to access only the 'pure' pthread_t
-id values, primarily to use as keys into data structures to manage threads or
-thread-related data, but this is not possible in a maximally portable and
-standards compliant way for current POSIX threads implementations.
-
-For implementations that define pthread_t as a scalar, programmers often employ
-direct relational and equality operators on pthread_t. This code will break when
-ported to an implementation that defines pthread_t as an aggregate type.
-
-For implementations that define pthread_t as an aggregate, e.g. a struct,
-programmers can use memcmp etc., but then face the prospect that the struct may
-include alignment padding bytes or bits as well as extra implementation-specific
-members that are not part of the unique identifying value.
-
-[While this is not currently the case for pthreads-win32, opacity also
-means that an implementation is free to change the definition, which should
-generally only require that applications be recompiled and relinked, not
-rewritten.]
-
-
-Doesn't the compiler take care of padding?
-
-The C89 and later standards only effectively guarrantee element-by-element
-equivalence following an assignment or pass by value of a struct or union,
-therefore undefined areas of any two otherwise equivalent pthread_t instances
-can still compare differently, e.g. attempting to compare two such pthread_t
-variables byte-by-byte, e.g. memcmp(&t1, &t2, sizeof(pthread_t) may give an
-incorrect result. In practice I'm reasonably confident that compilers routinely
-also copy the padding bytes, mainly because assignment of unions would be far
-too complicated otherwise. But it just isn't guarranteed by the standard.
-
-Illustration:
-
-We have two thread IDs t1 and t2
-
-pthread_t t1, t2;
-
-In an application we create the threads and intend to store the thread IDs in an
-ordered data structure (linked list, tree, etc) so we need to be able to compare
-them in order to insert them initially and also to traverse.
-
-Suppose pthread_t contains undefined padding bits and our compiler copies our
-pthread_t [struct] element-by-element, then for the assignment:
-
-pthread_t temp = t1;
-
-temp and t1 will be equivalent and correct but a byte-for-byte comparison such as
-memcmp(&temp, &t1, sizeof(pthread_t)) == 0 may not return true as we expect because
-the undefined bits may not have the same values in the two variable instances.
-
-Similarly if passing by value under the same conditions.
-
-If, on the other hand, the undefined bits are at least constant through every
-assignment and pass-by-value then the byte-for-byte comparison
-memcmp(&temp, &t1, sizeof(pthread_t)) == 0 will always return the expected result.
-How can we force the behaviour we need?
-
-
-Solutions
-
-Adding new functions to the standard API or as non-portable extentions is
-the only reliable and portable way to provide the necessary operations.
-Remember also that POSIX is not tied to the C language. The most common
-functions that have been suggested are:
-
-pthread_null()
-pthread_compare()
-pthread_hash()
-
-A single more general purpose function could also be defined as a
-basis for at least the last two of the above functions.
-
-First we need to list the freedoms and constraints with restpect
-to pthread_t so that we can be sure our solution is compatible with the
-standard.
-
-What is known or may be deduced from the standard:
-1) pthread_t must be able to be passed by value, so it must be a single object.
-2) from (1) it must be copyable so cannot embed thread-state information, locks
-or other volatile objects required to manage the thread it associates with.
-3) pthread_t may carry additional information, e.g. for debugging or to manage
-itself.
-4) there is an implicit requirement that the size of pthread_t is determinable
-at compile-time and size-invariant, because it must be able to copy the object
-(i.e. through assignment and pass-by-value). Such copies must be genuine
-duplicates, not merely a copy of a pointer to a common instance such as
-would be the case if pthread_t were defined as an array.
-
-
-Suppose we define the following function:
-
-/* This function shall return it's argument */
-pthread_t* pthread_normalize(pthread_t* thread);
-
-For scalar or aggregate pthread_t types this function would simply zero any bits
-within the pthread_t that don't uniquely identify the thread, including padding,
-such that client code can return consistent results from operations done on the
-result. If the additional bits are a pointer to an associate structure then
-this function would ensure that the memory used to store that associate
-structure does not leak. After normalization the following compare would be
-valid and repeatable:
-
-memcmp(pthread_normalize(&t1),pthread_normalize(&t2),sizeof(pthread_t))
-
-Note 1: such comparisons are intended merely to order and sort pthread_t values
-and allow them to index various data structures. They are not intended to reveal
-anything about the relationships between threads, like startup order.
-
-Note 2: the normalized pthread_t is also a valid pthread_t that uniquely
-identifies the same thread.
-
-Advantages:
-1) In most existing implementations this function would reduce to a no-op that
-emits no additional instructions, i.e after in-lining or optimisation, or if
-defined as a macro:
-#define pthread_normalise(tptr) (tptr)
-
-2) This single function allows an application to portably derive
-application-level versions of any of the other required functions.
-
-3) It is a generic function that could enable unanticipated uses.
-
-Disadvantages:
-1) Less efficient than dedicated compare or hash functions for implementations
-that include significant extra non-id elements in pthread_t.
-
-2) Still need to be concerned about padding if copying normalized pthread_t.
-See the later section on defining pthread_t to neutralise padding issues.
-
-Generally a pthread_t may need to be normalized every time it is used,
-which could have a significant impact. However, this is a design decision
-for the implementor in a competitive environment. An implementation is free
-to define a pthread_t in a way that minimises or eliminates padding or
-renders this function a no-op.
-
-Hazards:
-1) Pass-by-reference directly modifies 'thread' so the application must
-synchronise access or ensure that the pointer refers to a copy. The alternative
-of pass-by-value/return-by-value was considered but then this requires two copy
-operations, disadvantaging implementations where this function is not a no-op
-in terms of speed of execution. This function is intended to be used in high
-frequency situations and needs to be efficient, or at least not unnecessarily
-inefficient. The alternative also sits awkwardly with functions like memcmp.
-
-2) [Non-compliant] code that uses relational and equality operators on
-arithmetic or pointer style pthread_t types would need to be rewritten, but it
-should be rewritten anyway.
-
-
-C implementation of null/compare/hash functions using pthread_normalize():
-
-/* In pthread.h */
-pthread_t* pthread_normalize(pthread_t* thread);
-
-/* In user code */
-/* User-level bitclear function - clear bits in loc corresponding to mask */
-void* bitclear (void* loc, void* mask, size_t count);
-
-typedef unsigned int hash_t;
-
-/* User-level hash function */
-hash_t hash(void* ptr, size_t count);
-
-/*
- * User-level pthr_null function - modifies the origin thread handle.
- * The concept of a null pthread_t is highly implementation dependent
- * and this design may be far from the mark. For example, in an
- * implementation "null" may mean setting a special value inside one
- * element of pthread_t to mean "INVALID". However, if that value was zero and
- * formed part of the id component then we may get away with this design.
- */
-pthread_t* pthr_null(pthread_t* tp)
-{
-  /* 
-   * This should have the same effect as memset(tp, 0, sizeof(pthread_t))
-   * We're just showing that we can do it.
-   */
-  void* p = (void*) pthread_normalize(tp);
-  return (pthread_t*) bitclear(p, p, sizeof(pthread_t));
-}
-
-/*
- * Safe user-level pthr_compare function - modifies temporary thread handle copies
- */
-int pthr_compare_safe(pthread_t thread1, pthread_t thread2)
-{
-  return memcmp(pthread_normalize(&thread1), pthread_normalize(&thread2), sizeof(pthread_t));
-}
-
-/*
- * Fast user-level pthr_compare function - modifies origin thread handles
- */
-int pthr_compare_fast(pthread_t* thread1, pthread_t* thread2)
-{
-  return memcmp(pthread_normalize(&thread1), pthread_normalize(&thread2), sizeof(pthread_t));
-}
-
-/*
- * Safe user-level pthr_hash function - modifies temporary thread handle copy
- */
-hash_t pthr_hash_safe(pthread_t thread)
-{
-  return hash((void *) pthread_normalize(&thread), sizeof(pthread_t));
-}
-
-/*
- * Fast user-level pthr_hash function - modifies origin thread handle
- */
-hash_t pthr_hash_fast(pthread_t thread)
-{
-  return hash((void *) pthread_normalize(&thread), sizeof(pthread_t));
-}
-
-/* User-level bitclear function - modifies the origin array */
-void* bitclear(void* loc, void* mask, size_t count)
-{
-  int i;
-  for (i=0; i < count; i++) {
-    (unsigned char) *loc++ &= ~((unsigned char) *mask++);
-  }
-}
-
-/* Donald Knuth hash */
-hash_t hash(void* str, size_t count)
-{
-   hash_t hash = (hash_t) count;
-   unsigned int i = 0;
-
-   for(i = 0; i < len; str++, i++)
-   {
-      hash = ((hash << 5) ^ (hash >> 27)) ^ (*str);
-   }
-   return hash;
-}
-
-/* Example of advantage point (3) - split a thread handle into its id and non-id values */
-pthread_t id = thread, non-id = thread;
-bitclear((void*) &non-id, (void*) pthread_normalize(&id), sizeof(pthread_t));
-
-
-A pthread_t type change proposal to neutralise the effects of padding
-
-Even if pthread_nornalize() is available, padding is still a problem because
-the standard only garrantees element-by-element equivalence through
-copy operations (assignment and pass-by-value). So padding bit values can
-still change randomly after calls to pthread_normalize().
-
-[I suspect that most compilers take the easy path and always byte-copy anyway,
-partly because it becomes too complex to do (e.g. unions that contain sub-aggregates)
-but also because programmers can easily design their aggregates to minimise and
-often eliminate padding].
-
-How can we eliminate the problem of padding bytes in structs? Could
-defining pthread_t as a union rather than a struct provide a solution?
-
-In fact, the Linux pthread.h defines most of it's pthread_*_t objects (but not
-pthread_t itself) as unions, possibly for this and/or other reasons. We'll
-borrow some element naming from there but the ideas themselves are well known
-- the __align element used to force alignment of the union comes from K&R's
-storage allocator example.
-
-/* Essentially our current pthread_t renamed */
-typedef struct {
-  struct thread_state_t * __p;
-  long __x; /* sequence counter */
-} thread_id_t;
-
-Ensuring that the last element in the above struct is a long ensures that the
-overall struct size is a multiple of sizeof(long), so there should be no trailing
-padding in this struct or the union we define below.
-(Later we'll see that we can handle internal but not trailing padding.)
-
-/* New pthread_t */
-typedef union {
-  char __size[sizeof(thread_id_t)]; /* array as the first element */
-  thread_id_t __tid;
-  long __align;  /* Ensure that the union starts on long boundary */
-} pthread_t;
-
-This guarrantees that, during an assignment or pass-by-value, the compiler copies
-every byte in our thread_id_t because the compiler guarrantees that the __size
-array, which we have ensured is the equal-largest element in the union, retains
-equivalence.
-
-This means that pthread_t values stored, assigned and passed by value will at least
-carry the value of any undefined padding bytes along and therefore ensure that
-those values remain consistent. Our comparisons will return consistent results and
-our hashes of [zero initialised] pthread_t values will also return consistent
-results.
-
-We have also removed the need for a pthread_null() function; we can initialise
-at declaration time or easily create our own const pthread_t to use in assignments
-later:
-
-const pthread_t null_tid = {0}; /* braces are required */
-
-pthread_t t;
-...
-t = null_tid;
-
-
-Note that we don't have to explicitly make use of the __size array at all. It's
-there just to force the compiler behaviour we want.
-
-
-Partial solutions without a pthread_normalize function
-
-
-An application-level pthread_null and pthread_compare proposal
-(and pthread_hash proposal by extention)
-
-In order to deal with the problem of scalar/aggregate pthread_t type disparity in
-portable code I suggest using an old-fashioned union, e.g.:
-
-Contraints:
-- there is no padding, or padding values are preserved through assignment and
-  pass-by-value (see above);
-- there are no extra non-id values in the pthread_t.
-
-
-Example 1: A null initialiser for pthread_t variables...
-
-typedef union {
-    unsigned char b[sizeof(pthread_t)];
-    pthread_t t;
-} init_t;
-
-const init_t initial = {0};
-
-pthread_t tid = initial.t; /* init tid to all zeroes */
-
-
-Example 2: A comparison function for pthread_t values
-
-typedef union {
-   unsigned char b[sizeof(pthread_t)];
-   pthread_t t;
-} pthcmp_t;
-
-int pthcmp(pthread_t left, pthread_t right)
-{
-  /*
-  * Compare two pthread handles in a way that imposes a repeatable but arbitrary
-  * ordering on them.
-  * I.e. given the same set of pthread_t handles the ordering should be the same
-  * each time but the order has no particular meaning other than that. E.g.
-  * the ordering does not imply the thread start sequence, or any other
-  * relationship between threads.
-  *
-  * Return values are:
-  * 1 : left is greater than right
-  * 0 : left is equal to right
-  * -1 : left is less than right
-  */
-  int i;
-  pthcmp_t L, R;
-  L.t = left;
-  R.t = right;
-  for (i = 0; i < sizeof(pthread_t); i++)
-  {
-    if (L.b[i] > R.b[i])
-      return 1;
-    else if (L.b[i] < R.b[i])
-      return -1;
-  }
-  return 0;
-}
-
-It has been pointed out that the C99 standard allows for the possibility that
-integer types also may include padding bits, which could invalidate the above
-method. This addition to C99 was specifically included after it was pointed
-out that there was one, presumably not particularly well known, architecture
-that included a padding bit in it's 32 bit integer type. See section 6.2.6.2
-of both the standard and the rationale, specifically the paragraph starting at
-line 16 on page 43 of the rationale.
-
-
-An aside
-
-Certain compilers, e.g. gcc and one of the IBM compilers, include a feature
-extention: provided the union contains a member of the same type as the
-object then the object may be cast to the union itself.
-
-We could use this feature to speed up the pthrcmp() function from example 2
-above by casting rather than assigning the pthread_t arguments to the union, e.g.:
-
-int pthcmp(pthread_t left, pthread_t right)
-{
-  /*
-  * Compare two pthread handles in a way that imposes a repeatable but arbitrary
-  * ordering on them.
-  * I.e. given the same set of pthread_t handles the ordering should be the same
-  * each time but the order has no particular meaning other than that. E.g.
-  * the ordering does not imply the thread start sequence, or any other
-  * relationship between threads.
-  *
-  * Return values are:
-  * 1 : left is greater than right
-  * 0 : left is equal to right
-  * -1 : left is less than right
-  */
-  int i;
-  for (i = 0; i < sizeof(pthread_t); i++)
-  {
-    if (((pthcmp_t)left).b[i] > ((pthcmp_t)right).b[i])
-      return 1;
-    else if (((pthcmp_t)left).b[i] < ((pthcmp_t)right).b[i])
-      return -1;
-  }
-  return 0;
-}
-
-
-Result thus far
-
-We can't remove undefined bits if they are there in pthread_t already, but we have
-attempted to render them inert for comparison and hashing functions by making them
-consistent through assignment, copy and pass-by-value.
-
-Note: Hashing pthread_t values requires that all pthread_t variables be initialised
-to the same value (usually all zeros) before being assigned a proper thread ID, i.e.
-to ensure that any padding bits are zero, or at least the same value for all
-pthread_t. Since all pthread_t values are generated by the library in the first
-instance this need not be an application-level operation.
-
-
-Conclusion
-
-I've attempted to resolve the multiple issues of type opacity and the possible
-presence of undefined bits and bytes in pthread_t values, which prevent
-applications from comparing or hashing pthread handles.
-
-Two complimentary partial solutions have been proposed, one an application-level
-scheme to handle both scalar and aggregate pthread_t types equally, plus a
-definition of pthread_t itself that neutralises padding bits and bytes by
-coercing semantics out of the compiler to eliminate variations in the values of
-padding bits.
-
-I have not provided any solution to the problem of handling extra values embedded
-in pthread_t, e.g. debugging or trap information that an implementation is entitled
-to include. Therefore none of this replaces the portability and flexibility of API
-functions but what functions are needed? The threads standard is unlikely to
-include that can be implemented by a combination of existing features and more
-generic functions (several references in the threads rationale suggest this.
-Therefore I propose that the following function could replace the several functions
-that have been suggested in conversations:
-
-pthread_t * pthread_normalize(pthread_t * handle);
-
-For most existing pthreads implementations this function, or macro, would reduce to
-a no-op with zero call overhead.
diff --git a/deps/w32-pthreads/README.Watcom b/deps/w32-pthreads/README.Watcom
deleted file mode 100644
index 2974928..0000000
--- a/deps/w32-pthreads/README.Watcom
+++ /dev/null
@@ -1,62 +0,0 @@
-Watcom compiler notes
-=====================
-
-Status
-------
-Not yet usable. Although the library builds under Watcom it
-substantially fails the test suite.
-
-There is a working Wmakefile for wmake for the library build.
-
-invoke as any of:
-wmake -f Wmakefile clean WC
-wmake -f Wmakefile clean WC-inlined
-wmake -f Wmakefile clean WCE
-wmake -f Wmakefile clean WCE-inlined
-
-These build pthreadWC.dll and pthreadWCE.dll.
-
-There is a working Wmakefile for wmake for the test suite.
-
-invoke as any of:
-wmake -f Wmakefile clean WC
-wmake -f Wmakefile clean WCX
-wmake -f Wmakefile clean WCE
-wmake -f Wmakefile clean WC-bench
-wmake -f Wmakefile clean WCX-bench
-wmake -f Wmakefile clean WCE-bench
-
-
-Current known problems
-----------------------
-
-Library build:
-The Watcom compiler uses a different default call convention to MS C or GNU C and so
-applications are not compatible with pthreadVC.dll etc using pre 2003-10-14 versions
-of pthread.h, sched.h, or semaphore.h. The cdecl attribute can be used on exposed
-function prototypes to force compatibility with MS C built DLLs.
-
-However, there appear to be other incompatibilities. Errno.h, for example, defines
-different values for the standard C and POSIX errors to those defined by the MS C
-errno.h. It may be that references to Watcom's threads compatible 'errno' do set
-and return translated numbers consistently, but I have not verified this.
-
-Watcom defines errno as a dereferenced pointer returned by the function
-_get_errno_ptr(). This is similar to both the MS and GNU C environments for
-multithreaded use. However, the Watcom version appears to have a number of problems:
-
-- different threads return the same pointer value. Compare with the MS and GNU C
-versions which correctly return different values (since each thread must maintain
-a thread specific errno value).
-
-- an errno value set within the DLL appears as zero in the application even though
-both share the same thread.
-
-Therefore applications built using the Watcom compiler may need to use
-a Watcom built version of the library (pthreadWC.dll). If this is the case, then
-the cdecl function attribute should not be required.
-
-Application builds:
-The test suite fails with the Watcom compiler.
-
-Test semaphore1.c fails for pthreadWC.dll because errno returns 0 instead of EAGAIN.
diff --git a/deps/w32-pthreads/README.WinCE b/deps/w32-pthreads/README.WinCE
deleted file mode 100644
index a2cd8c2..0000000
--- a/deps/w32-pthreads/README.WinCE
+++ /dev/null
@@ -1,6 +0,0 @@
-WinCE port
-----------
-(See the file WinCE-PORT for a detailed explanation.)
-
-Make sure you define "WINCE" amongst your compiler flags (eg. -DWINCE).
-The config.h file will define all the necessary defines for you.
diff --git a/deps/w32-pthreads/TODO b/deps/w32-pthreads/TODO
deleted file mode 100644
index fa9efc4..0000000
--- a/deps/w32-pthreads/TODO
+++ /dev/null
@@ -1,7 +0,0 @@
-                   Things that aren't done yet
-                   ---------------------------
-
-1. Implement PTHREAD_PROCESS_SHARED for semaphores, mutexes,
-   condition variables, read/write locks, barriers.
-
-
diff --git a/deps/w32-pthreads/WinCE-PORT b/deps/w32-pthreads/WinCE-PORT
deleted file mode 100644
index 7bcfdea..0000000
--- a/deps/w32-pthreads/WinCE-PORT
+++ /dev/null
@@ -1,222 +0,0 @@
-NOTE: The comments in this file relate to the original WinCE port
-done by Tristan Savatier. The semaphore routines have been 
-completely rewritten since (2005-04-25), having been progressively
-broken more and more by changes to the library. All of the semaphore
-routines implemented for W9x/WNT/2000 and up should now also work for
-WinCE. Also, pthread_mutex_timedlock should now work.
-
-Additional WinCE updates have been applied since this as well. Check the
-ChangeLog file and search for WINCE for example. (2007-01-07)
-
-[RPJ]
-
-----
-
-Some interesting news:
-
-I have been able to port pthread-win32 to Windows-CE,
-which uses a subset of the WIN32 API.
-
-Since we intend to keep using pthread-win32 for our
-Commercial WinCE developments, I would be very interested
-if WinCE support could be added to the main source tree
-of pthread-win32.  Also, I would like to be credited
-for this port :-)
-
-Now, here is the story...
-
-The port was performed and tested on a Casio "Cassiopeia"
-PalmSize PC, which runs a MIP processor.  The OS in the
-Casio is WinCE version 2.11, but I used VC++ 6.0 with
-the WinCE SDK for version 2.01.
-
-I used pthread-win32 to port a heavily multithreaded
-commercial application (real-time MPEG video player)
-from Linux to WinCE.  I consider the changes that
-I have done to be quite well tested.
-
-Overall the modifications that we had to do are minor.
-
-The WinCE port were based on pthread-win32-snap-1999-05-30,
-but I am certain that they can be integrated very easiely
-to more recent versions of the source.
-
-I have attached the modified source code:
-pthread-win32-snap-1999-05-30-WinCE.
-
-All the changes do not affect the code compiled on non-WinCE
-environment, provided that the macros used for WinCE compilation
-are not used, of course!
-
-Overall description of the WinCE port:
--------------------------------------
-
-Most of the changes had to be made in areas where
-pthread-win32 was relying on some standard-C librairies
-(e.g. _ftime, calloc, errno), which are not available
-on WinCE. We have changed the code to use native Win32
-API instead (or in some cases we made wrappers).
-
-The Win32 Semaphores are not available,
-so we had to re-implement Semaphores using mutexes
-and events.
-
-Limitations / known problems of the WinCE port:
-----------------------------------------------
-
-Not all the semaphore routines have been ported
-(semaphores are defined by Posix but are not part
-pf pthread).  I have just done enough to make
-pthread routines (that rely internally on semaphores)
-work, like signal conditions.
-
-I noticed that the Win32 threads work slightly
-differently on WinCE.  This may have some impact
-on some tricky parts of pthread-win32, but I have
-not really investigated.  For example, on WinCE,
-the process is killed if the main thread falls off
-the bottom (or calls pthread_exit), regardless
-of the existence of any other detached thread.
-Microsoft manual indicates that this behavior is
-deffirent from that of Windows Threads for other
-Win32 platforms.
-
-
-Detailed descriptions of the changes and rationals:
-
-------------------------------------
-- use a new macro NEED_ERRNO.
-
-If defined, the code in errno.c that defines a reentrant errno
-is compiled, regardless of _MT and _REENTRANT.
-
-Rational: On WinCE, there is no support for <stdio.h>, <errno.h> or
-any other standard C library, i.e. even if _MT or _REENTRANT
-is defined, errno is not provided by any library.  NEED_ERRNO
-must be set to compile for WinCE.
-
-------------------------------------
-- In implement.h, change #include <semaphore.h> to #include "semaphore.h".
-
-Rational: semaphore.h is provided in pthread-win32 and should not
-be searched in the systems standard include.  would not compile.
-This change does not seem to create problems on "classic" win32
-(e.g. win95).
-
-------------------------------------
-- use a new macro NEED_CALLOC.
-
-If defined, some code in misc.c will provide a replacement
-for calloc, which is not available on Win32.
-
-
-------------------------------------
-- use a new macro NEED_CREATETHREAD.
-
-If defined, implement.h defines the macro _beginthreadex
-and _endthreadex.
-
-Rational: On WinCE, the wrappers _beginthreadex and _endthreadex
-do not exist. The native Win32 routines must be used.
-
-------------------------------------
-- in misc.c:
-
-#ifdef NEED_DUPLICATEHANDLE
-	  /* DuplicateHandle does not exist on WinCE */
-	  self->threadH = GetCurrentThread();
-#else
-	  if( !DuplicateHandle(
-			       GetCurrentProcess(),
-			       GetCurrentThread(),
-			       GetCurrentProcess(),
-			       &self->threadH,
-			       0,
-			       FALSE,
-			       DUPLICATE_SAME_ACCESS ) )
-	    {
-	      free( self );
-	      return (NULL);
-	    }
-#endif
-
-Rational: On WinCE, DuplicateHandle does not exist.  I could not understand
-why DuplicateHandle must be used.  It seems to me that getting the current
-thread handle with GetCurrentThread() is sufficient, and it seems to work
-perfectly fine, so maybe DuplicateHandle was just plain useless to begin with ?
-
-------------------------------------
-- In private.c, added some code at the beginning of ptw32_processInitialize
-to detect the case of multiple calls to ptw32_processInitialize.
-
-Rational: In order to debug pthread-win32, it is easier to compile
-it as a regular library (it is not possible to debug DLL's on winCE).
-In that case, the application must call ptw32_rocessInitialize()
-explicitely, to initialize pthread-win32.  It is safer in this circumstance
-to handle the case where ptw32_processInitialize() is called on
-an already initialized library:
-
-int
-ptw32_processInitialize (void)
-{
-	if (ptw32_processInitialized) {
-		/* 
-		 * ignore if already initialized. this is useful for 
-		 * programs that uses a non-dll pthread
-		 * library. such programs must call ptw32_processInitialize() explicitely,
-		 * since this initialization routine is automatically called only when
-		 * the dll is loaded.
-		 */
-		return TRUE;
-	}
-    ptw32_processInitialized = TRUE;
-  	[...]
-}
-
-------------------------------------
-- in private.c, if macro NEED_FTIME is defined, add routines to
-convert timespec_to_filetime and filetime_to_timespec, and modified
-code that was using _ftime() to use Win32 API instead.
-
-Rational: _ftime is not available on WinCE.  It is necessary to use
-the native Win32 time API instead.
-
-Note: the routine timespec_to_filetime is provided as a convenience and a mean
-to test that filetime_to_timespec works, but it is not used by the library.
-
-------------------------------------
-- in semaphore.c, if macro NEED_SEM is defined, add code for the routines
-_increase_semaphore and _decrease_semaphore, and modify significantly
-the implementation of the semaphores so that it does not use CreateSemaphore.
-
-Rational: CreateSemaphore is not available on WinCE.  I had to re-implement
-semaphores using mutexes and Events.
-
-Note: Only the semaphore routines that are used by pthread are implemented
-(i.e. signal conditions rely on a subset of the semaphores routines, and
-this subset works). Some other semaphore routines (e.g. sem_trywait) are
-not yet supported on my WinCE port (and since I don't need them, I am not
-planning to do anything about them).
-
-------------------------------------
-- in tsd.c, changed the code that defines TLS_OUT_OF_INDEXES
-
-/* TLS_OUT_OF_INDEXES not defined on WinCE */
-#ifndef TLS_OUT_OF_INDEXES
-#define TLS_OUT_OF_INDEXES 0xffffffff
-#endif
-
-Rational: TLS_OUT_OF_INDEXES is not defined in any standard include file
-on WinCE.
-
-------------------------------------
-- added file need_errno.h
-
-Rational: On WinCE, there is no errno.h file. need_errno.h is just a
-copy of windows version of errno.h, with minor modifications due to the fact
-that some of the error codes are defined by the WinCE socket library.
-In pthread.h, if NEED_ERRNO is defined, the file need_errno.h is
-included (instead of <errno.h>).
-
-
--- eof
diff --git a/deps/w32-pthreads/attr.c b/deps/w32-pthreads/attr.c
deleted file mode 100644
index fa1a1dd..0000000
--- a/deps/w32-pthreads/attr.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * attr.c
- *
- * Description:
- * This translation unit agregates operations on thread attribute objects.
- * It is used for inline optimisation.
- *
- * The included modules are used separately when static executable sizes
- * must be minimised.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-#include "pthread_attr_init.c"
-#include "pthread_attr_destroy.c"
-#include "pthread_attr_getdetachstate.c"
-#include "pthread_attr_setdetachstate.c"
-#include "pthread_attr_getstackaddr.c"
-#include "pthread_attr_setstackaddr.c"
-#include "pthread_attr_getstacksize.c"
-#include "pthread_attr_setstacksize.c"
-#include "pthread_attr_getscope.c"
-#include "pthread_attr_setscope.c"
diff --git a/deps/w32-pthreads/autostatic.c b/deps/w32-pthreads/autostatic.c
deleted file mode 100644
index e8bc3a8..0000000
--- a/deps/w32-pthreads/autostatic.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * autostatic.c
- *
- * Description:
- * This translation unit implements static auto-init and auto-exit logic.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- *
- *      Contact Email: rpj at callisto.canberra.edu.au
- *
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- *
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- *
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- *
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#if defined(PTW32_STATIC_LIB)
-
-#if defined(__MINGW64__) || defined(__MINGW32__) || defined(_MSC_VER)
-
-#include "pthread.h"
-#include "implement.h"
-
-static void on_process_init(void)
-{
-    pthread_win32_process_attach_np ();
-}
-
-static void on_process_exit(void)
-{
-    pthread_win32_thread_detach_np  ();
-    pthread_win32_process_detach_np ();
-}
-
-#if defined(__MINGW64__) || defined(__MINGW32__)
-# define attribute_section(a) __attribute__((section(a)))
-#elif defined(_MSC_VER)
-# define attribute_section(a) __pragma(section(a,long,read)); __declspec(allocate(a))
-#endif
-
-attribute_section(".ctors") void *gcc_ctor = on_process_init;
-attribute_section(".dtors") void *gcc_dtor = on_process_exit;
-
-attribute_section(".CRT$XCU") void *msc_ctor = on_process_init;
-attribute_section(".CRT$XPU") void *msc_dtor = on_process_exit;
-
-#endif /* defined(__MINGW64__) || defined(__MINGW32__) || defined(_MSC_VER) */
-
-#endif /* PTW32_STATIC_LIB */
diff --git a/deps/w32-pthreads/barrier.c b/deps/w32-pthreads/barrier.c
deleted file mode 100644
index c34fd7f..0000000
--- a/deps/w32-pthreads/barrier.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * barrier.c
- *
- * Description:
- * This translation unit implements barrier primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-#include "pthread_barrier_init.c"
-#include "pthread_barrier_destroy.c"
-#include "pthread_barrier_wait.c"
-#include "pthread_barrierattr_init.c"
-#include "pthread_barrierattr_destroy.c"
-#include "pthread_barrierattr_getpshared.c"
-#include "pthread_barrierattr_setpshared.c"
diff --git a/deps/w32-pthreads/builddmc.bat b/deps/w32-pthreads/builddmc.bat
deleted file mode 100644
index bf813d8..0000000
--- a/deps/w32-pthreads/builddmc.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-; Build the pthreads library with the Digital Mars Compiler
-;
-set DMCDIR=c:\dm
-
-;   RELEASE
-%DMCDIR%\bin\dmc -D_WIN32_WINNT -D_MT -DHAVE_PTW32_CONFIG_H -I.;c:\dm\include -o+all -WD pthread.c user32.lib+kernel32.lib+wsock32.lib -L/impl -L/NODEBUG -L/SU:WINDOWS
-
-;   DEBUG
-%DMCDIR%\bin\dmc -g -D_WIN32_WINNT -D_MT -DHAVE_PTW32_CONFIG_H -I.;c:\dm\include -o+all -WD pthread.c user32.lib+kernel32.lib+wsock32.lib -L/impl -L/SU:WINDOWS
diff --git a/deps/w32-pthreads/cancel.c b/deps/w32-pthreads/cancel.c
deleted file mode 100644
index 3a554a0..0000000
--- a/deps/w32-pthreads/cancel.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * cancel.c
- *
- * Description:
- * POSIX thread functions related to thread cancellation.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-#include "pthread_setcancelstate.c"
-#include "pthread_setcanceltype.c"
-#include "pthread_testcancel.c"
-#include "pthread_cancel.c"
diff --git a/deps/w32-pthreads/cleanup.c b/deps/w32-pthreads/cleanup.c
deleted file mode 100644
index fc69ca8..0000000
--- a/deps/w32-pthreads/cleanup.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * cleanup.c
- *
- * Description:
- * This translation unit implements routines associated
- * with cleaning up threads.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-/*
- * The functions ptw32_pop_cleanup and ptw32_push_cleanup
- * are implemented here for applications written in C with no
- * SEH or C++ destructor support. 
- */
-
-ptw32_cleanup_t *
-ptw32_pop_cleanup (int execute)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function pops the most recently pushed cleanup
-      *      handler. If execute is nonzero, then the cleanup handler
-      *      is executed if non-null.
-      *
-      * PARAMETERS
-      *      execute
-      *              if nonzero, execute the cleanup handler
-      *
-      *
-      * DESCRIPTION
-      *      This function pops the most recently pushed cleanup
-      *      handler. If execute is nonzero, then the cleanup handler
-      *      is executed if non-null.
-      *      NOTE: specify 'execute' as nonzero to avoid duplication
-      *                of common cleanup code.
-      *
-      * RESULTS
-      *              N/A
-      *
-      * ------------------------------------------------------
-      */
-{
-  ptw32_cleanup_t *cleanup;
-
-  cleanup = (ptw32_cleanup_t *) pthread_getspecific (ptw32_cleanupKey);
-
-  if (cleanup != NULL)
-    {
-      if (execute && (cleanup->routine != NULL))
-	{
-
-	  (*cleanup->routine) (cleanup->arg);
-
-	}
-
-      pthread_setspecific (ptw32_cleanupKey, (void *) cleanup->prev);
-
-    }
-
-  return (cleanup);
-
-}				/* ptw32_pop_cleanup */
-
-
-void
-ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
-		    ptw32_cleanup_callback_t routine, void *arg)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function pushes a new cleanup handler onto the thread's stack
-      *      of cleanup handlers. Each cleanup handler pushed onto the stack is
-      *      popped and invoked with the argument 'arg' when
-      *              a) the thread exits by calling 'pthread_exit',
-      *              b) when the thread acts on a cancellation request,
-      *              c) or when the thread calls pthread_cleanup_pop with a nonzero
-      *                 'execute' argument
-      *
-      * PARAMETERS
-      *      cleanup
-      *              a pointer to an instance of pthread_cleanup_t,
-      *
-      *      routine
-      *              pointer to a cleanup handler,
-      *
-      *      arg
-      *              parameter to be passed to the cleanup handler
-      *
-      *
-      * DESCRIPTION
-      *      This function pushes a new cleanup handler onto the thread's stack
-      *      of cleanup handlers. Each cleanup handler pushed onto the stack is
-      *      popped and invoked with the argument 'arg' when
-      *              a) the thread exits by calling 'pthread_exit',
-      *              b) when the thread acts on a cancellation request,
-      *              c) or when the thrad calls pthread_cleanup_pop with a nonzero
-      *                 'execute' argument
-      *      NOTE: pthread_push_cleanup, ptw32_pop_cleanup must be paired
-      *                in the same lexical scope.
-      *
-      * RESULTS
-      *              pthread_cleanup_t *
-      *                              pointer to the previous cleanup
-      *
-      * ------------------------------------------------------
-      */
-{
-  cleanup->routine = routine;
-  cleanup->arg = arg;
-
-  cleanup->prev = (ptw32_cleanup_t *) pthread_getspecific (ptw32_cleanupKey);
-
-  pthread_setspecific (ptw32_cleanupKey, (void *) cleanup);
-
-}				/* ptw32_push_cleanup */
diff --git a/deps/w32-pthreads/condvar.c b/deps/w32-pthreads/condvar.c
deleted file mode 100644
index 556596d..0000000
--- a/deps/w32-pthreads/condvar.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * condvar.c
- *
- * Description:
- * This translation unit implements condition variables and their primitives.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-#include "ptw32_cond_check_need_init.c"
-#include "pthread_condattr_init.c"
-#include "pthread_condattr_destroy.c"
-#include "pthread_condattr_getpshared.c"
-#include "pthread_condattr_setpshared.c"
-#include "pthread_cond_init.c"
-#include "pthread_cond_destroy.c"
-#include "pthread_cond_wait.c"
-#include "pthread_cond_signal.c"
diff --git a/deps/w32-pthreads/config.h b/deps/w32-pthreads/config.h
deleted file mode 100644
index e231724..0000000
--- a/deps/w32-pthreads/config.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* config.h  */
-
-#ifndef PTW32_CONFIG_H
-#define PTW32_CONFIG_H
-
-/*********************************************************************
- * Defaults: see target specific redefinitions below.
- *********************************************************************/
-
-/* We're building the pthreads-win32 library */
-#define PTW32_BUILD
-
-/* Do we know about the C type sigset_t? */
-#undef HAVE_SIGSET_T
-
-/* Define if you have the <signal.h> header file.  */
-#undef HAVE_SIGNAL_H
-
-/* Define if you have the Borland TASM32 or compatible assembler.  */
-#undef HAVE_TASM32
-
-/* Define if you don't have Win32 DuplicateHandle. (eg. WinCE) */
-#undef NEED_DUPLICATEHANDLE
-
-/* Define if you don't have Win32 _beginthreadex. (eg. WinCE) */
-#undef NEED_CREATETHREAD
-
-/* Define if you don't have Win32 errno. (eg. WinCE) */
-#undef NEED_ERRNO
-
-/* Define if you don't have Win32 calloc. (eg. WinCE)  */
-#undef NEED_CALLOC
-
-/* Define if you don't have Win32 ftime. (eg. WinCE)  */
-#undef NEED_FTIME
-
-/* Define if you don't have Win32 semaphores. (eg. WinCE 2.1 or earlier)  */
-#undef NEED_SEM
-
-/* Define if you need to convert string parameters to unicode. (eg. WinCE)  */
-#undef NEED_UNICODE_CONSTS
-
-/* Define if your C (not C++) compiler supports "inline" functions. */
-#undef HAVE_C_INLINE
-
-/* Do we know about type mode_t? */
-#undef HAVE_MODE_T
-
-/* 
- * Define if GCC has atomic builtins, i.e. __sync_* intrinsics
- * __sync_lock_* is implemented in mingw32 gcc 4.5.2 at least
- * so this define does not turn those on or off. If you get an
- * error from __sync_lock* then consider upgrading your gcc.
- */
-#undef HAVE_GCC_ATOMIC_BUILTINS
-
-/* Define if you have the timespec struct */
-#undef HAVE_STRUCT_TIMESPEC
-
-/* Define if you don't have the GetProcessAffinityMask() */
-#undef NEED_PROCESS_AFFINITY_MASK
-
-/* Define if your version of Windows TLSGetValue() clears WSALastError
- * and calling SetLastError() isn't enough restore it. You'll also need to
- * link against wsock32.lib (or libwsock32.a for MinGW).
- */
-#undef RETAIN_WSALASTERROR
-
-/*
-# ----------------------------------------------------------------------
-# The library can be built with some alternative behaviour to better
-# facilitate development of applications on Win32 that will be ported
-# to other POSIX systems.
-#
-# Nothing described here will make the library non-compliant and strictly
-# compliant applications will not be affected in any way, but
-# applications that make assumptions that POSIX does not guarantee are
-# not strictly compliant and may fail or misbehave with some settings.
-#
-# PTW32_THREAD_ID_REUSE_INCREMENT
-# Purpose:
-# POSIX says that applications should assume that thread IDs can be
-# recycled. However, Solaris (and some other systems) use a [very large]
-# sequence number as the thread ID, which provides virtual uniqueness.
-# This provides a very high but finite level of safety for applications
-# that are not meticulous in tracking thread lifecycles e.g. applications
-# that call functions which target detached threads without some form of
-# thread exit synchronisation.
-#
-# Usage:
-# Set to any value in the range: 0 <= value < 2^wordsize.
-# Set to 0 to emulate reusable thread ID behaviour like Linux or *BSD.
-# Set to 1 for unique thread IDs like Solaris (this is the default).
-# Set to some factor of 2^wordsize to emulate smaller word size types
-# (i.e. will wrap sooner). This might be useful to emulate some embedded
-# systems.
-#
-# define PTW32_THREAD_ID_REUSE_INCREMENT 0
-#
-# ----------------------------------------------------------------------
- */
-#undef PTW32_THREAD_ID_REUSE_INCREMENT
-
-
-/*********************************************************************
- * Target specific groups
- *
- * If you find that these are incorrect or incomplete please report it
- * to the pthreads-win32 maintainer. Thanks.
- *********************************************************************/
-#if defined(WINCE)
-#define NEED_DUPLICATEHANDLE
-#define NEED_CREATETHREAD
-#define NEED_ERRNO
-#define NEED_CALLOC
-#define NEED_FTIME
-/* #define NEED_SEM */
-#define NEED_UNICODE_CONSTS
-#define NEED_PROCESS_AFFINITY_MASK
-/* This may not be needed */
-#define RETAIN_WSALASTERROR
-#endif
-
-#if defined(_UWIN)
-#define HAVE_MODE_T
-#define HAVE_STRUCT_TIMESPEC
-#endif
-
-#if defined(__GNUC__)
-#define HAVE_C_INLINE
-#endif
-
-#if defined(__MINGW64__)
-#define HAVE_MODE_T
-#define HAVE_STRUCT_TIMESPEC
-#elif defined(__MINGW32__)
-#define HAVE_MODE_T
-#endif
-
-#if defined(__BORLANDC__)
-#endif
-
-#if defined(__WATCOMC__)
-#endif
-
-#if defined(__DMC__)
-#define HAVE_SIGNAL_H
-#define HAVE_C_INLINE
-#endif
-
-
-
-#endif
diff --git a/deps/w32-pthreads/context.h b/deps/w32-pthreads/context.h
deleted file mode 100644
index f55dd73..0000000
--- a/deps/w32-pthreads/context.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * context.h
- *
- * Description:
- * POSIX thread macros related to thread cancellation.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifndef PTW32_CONTEXT_H
-#define PTW32_CONTEXT_H
-
-#undef PTW32_PROGCTR
-
-#if defined(_M_IX86) || (defined(_X86_) && !defined(__amd64__))
-#define PTW32_PROGCTR(Context)  ((Context).Eip)
-#endif
-
-#if defined (_M_IA64) || defined(_IA64)
-#define PTW32_PROGCTR(Context)  ((Context).StIIP)
-#endif
-
-#if defined(_MIPS_) || defined(MIPS)
-#define PTW32_PROGCTR(Context)  ((Context).Fir)
-#endif
-
-#if defined(_ALPHA_)
-#define PTW32_PROGCTR(Context)  ((Context).Fir)
-#endif
-
-#if defined(_PPC_)
-#define PTW32_PROGCTR(Context)  ((Context).Iar)
-#endif
-
-#if defined(_AMD64_) || defined(__amd64__)
-#define PTW32_PROGCTR(Context)  ((Context).Rip)
-#endif
-
-#if defined(_ARM_) || defined(ARM)
-#define PTW32_PROGCTR(Context)  ((Context).Pc)
-#endif
-
-#if !defined(PTW32_PROGCTR)
-#error Module contains CPU-specific code; modify and recompile.
-#endif
-
-#endif
diff --git a/deps/w32-pthreads/create.c b/deps/w32-pthreads/create.c
deleted file mode 100644
index 1927296..0000000
--- a/deps/w32-pthreads/create.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * create.c
- *
- * Description:
- * This translation unit implements routines associated with spawning a new
- * thread.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#if ! defined(_UWIN) && ! defined(WINCE)
-#include <process.h>
-#endif
-
-int
-pthread_create (pthread_t * tid,
-		const pthread_attr_t * attr,
-		void *(PTW32_CDECL *start) (void *), void *arg)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function creates a thread running the start function,
-      *      passing it the parameter value, 'arg'. The 'attr'
-      *      argument specifies optional creation attributes.
-      *      The identity of the new thread is returned
-      *      via 'tid', which should not be NULL.
-      *
-      * PARAMETERS
-      *      tid
-      *              pointer to an instance of pthread_t
-      *
-      *      attr
-      *              optional pointer to an instance of pthread_attr_t
-      *
-      *      start
-      *              pointer to the starting routine for the new thread
-      *
-      *      arg
-      *              optional parameter passed to 'start'
-      *
-      *
-      * DESCRIPTION
-      *      This function creates a thread running the start function,
-      *      passing it the parameter value, 'arg'. The 'attr'
-      *      argument specifies optional creation attributes.
-      *      The identity of the new thread is returned
-      *      via 'tid', which should not be the NULL pointer.
-      *
-      * RESULTS
-      *              0               successfully created thread,
-      *              EINVAL          attr invalid,
-      *              EAGAIN          insufficient resources.
-      *
-      * ------------------------------------------------------
-      */
-{
-  pthread_t thread;
-  ptw32_thread_t * tp;
-  register pthread_attr_t a;
-  HANDLE threadH = 0;
-  int result = EAGAIN;
-  int run = PTW32_TRUE;
-  ThreadParms *parms = NULL;
-  unsigned int stackSize;
-  int priority;
-  pthread_t self;
-
-  /*
-   * Before doing anything, check that tid can be stored through
-   * without invoking a memory protection error (segfault).
-   * Make sure that the assignment below can't be optimised out by the compiler.
-   * This is assured by conditionally assigning *tid again at the end.
-   */
-  tid->x = 0;
-
-  if (attr != NULL)
-    {
-      a = *attr;
-    }
-  else
-    {
-      a = NULL;
-    }
-
-  if ((thread = ptw32_new ()).p == NULL)
-    {
-      goto FAIL0;
-    }
-
-  tp = (ptw32_thread_t *) thread.p;
-
-  priority = tp->sched_priority;
-
-  if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL)
-    {
-      goto FAIL0;
-    }
-
-  parms->tid = thread;
-  parms->start = start;
-  parms->arg = arg;
-
-#if defined(HAVE_SIGSET_T)
-
-  /*
-   * Threads inherit their initial sigmask from their creator thread.
-   */
-  self = pthread_self();
-  tp->sigmask = ((ptw32_thread_t *)self.p)->sigmask;
-
-#endif /* HAVE_SIGSET_T */
-
-
-  if (a != NULL)
-    {
-      stackSize = (unsigned int)a->stacksize;
-      tp->detachState = a->detachstate;
-      priority = a->param.sched_priority;
-
-#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
-      /* WinCE */
-#else
-      /* Everything else */
-
-      /*
-       * Thread priority must be set to a valid system level
-       * without altering the value set by pthread_attr_setschedparam().
-       */
-
-      /*
-       * PTHREAD_EXPLICIT_SCHED is the default because Win32 threads
-       * don't inherit their creator's priority. They are started with
-       * THREAD_PRIORITY_NORMAL (win32 value). The result of not supplying
-       * an 'attr' arg to pthread_create() is equivalent to defaulting to
-       * PTHREAD_EXPLICIT_SCHED and priority THREAD_PRIORITY_NORMAL.
-       */
-      if (PTHREAD_INHERIT_SCHED == a->inheritsched)
-	{
-	  /*
-	   * If the thread that called pthread_create() is a Win32 thread
-	   * then the inherited priority could be the result of a temporary
-	   * system adjustment. This is not the case for POSIX threads.
-	   */
-#if ! defined(HAVE_SIGSET_T)
-	  self = pthread_self ();
-#endif
-	  priority = ((ptw32_thread_t *) self.p)->sched_priority;
-	}
-
-#endif
-
-    }
-  else
-    {
-      /*
-       * Default stackSize
-       */
-      stackSize = PTHREAD_STACK_MIN;
-    }
-
-  tp->state = run ? PThreadStateInitial : PThreadStateSuspended;
-
-  tp->keys = NULL;
-
-  /*
-   * Threads must be started in suspended mode and resumed if necessary
-   * after _beginthreadex returns us the handle. Otherwise we set up a
-   * race condition between the creating and the created threads.
-   * Note that we also retain a local copy of the handle for use
-   * by us in case thread.p->threadH gets NULLed later but before we've
-   * finished with it here.
-   */
-
-#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) 
-
-  tp->threadH =
-    threadH =
-    (HANDLE) _beginthreadex ((void *) NULL,	/* No security info             */
-			     stackSize,		/* default stack size   */
-			     ptw32_threadStart,
-			     parms,
-			     (unsigned)
-			     CREATE_SUSPENDED,
-			     (unsigned *) &(tp->thread));
-
-  if (threadH != 0)
-    {
-      if (a != NULL)
-	{
-	  (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority);
-	}
-
-      if (run)
-	{
-	  ResumeThread (threadH);
-	}
-    }
-
-#else
-
-  {
-    ptw32_mcs_local_node_t stateLock;
-
-    /*
-     * This lock will force pthread_threadStart() to wait until we have
-     * the thread handle and have set the priority.
-     */
-    ptw32_mcs_lock_acquire(&tp->stateLock, &stateLock);
-
-    tp->threadH =
-      threadH =
-      (HANDLE) _beginthread (ptw32_threadStart, stackSize,	/* default stack size   */
-			     parms);
-
-    /*
-     * Make the return code match _beginthreadex's.
-     */
-    if (threadH == (HANDLE) - 1L)
-      {
-        tp->threadH = threadH = 0;
-      }
-    else
-      {
-        if (!run)
-	  {
-	    /* 
-	     * beginthread does not allow for create flags, so we do it now.
-	     * Note that beginthread itself creates the thread in SUSPENDED
-	     * mode, and then calls ResumeThread to start it.
-	     */
-	    SuspendThread (threadH);
-	  }
-  
-        if (a != NULL)
-	  {
-	    (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority);
-	  }
-      }
-
-    ptw32_mcs_lock_release (&stateLock);
-  }
-#endif
-
-  result = (threadH != 0) ? 0 : EAGAIN;
-
-  /*
-   * Fall Through Intentionally
-   */
-
-  /*
-   * ------------
-   * Failure Code
-   * ------------
-   */
-
-FAIL0:
-  if (result != 0)
-    {
-
-      ptw32_threadDestroy (thread);
-      tp = NULL;
-
-      if (parms != NULL)
-	{
-	  free (parms);
-	}
-    }
-  else
-    {
-      *tid = thread;
-    }
-
-#if defined(_UWIN)
-  if (result == 0)
-    pthread_count++;
-#endif
-  return (result);
-
-}				/* pthread_create */
diff --git a/deps/w32-pthreads/dll.c b/deps/w32-pthreads/dll.c
deleted file mode 100644
index 8350cdd..0000000
--- a/deps/w32-pthreads/dll.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * dll.c
- *
- * Description:
- * This translation unit implements DLL initialisation.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#if !defined(PTW32_STATIC_LIB)
-
-#include "pthread.h"
-#include "implement.h"
-
-#if defined(_MSC_VER)
-/* 
- * lpvReserved yields an unreferenced formal parameter;
- * ignore it
- */
-#pragma warning( disable : 4100 )
-#endif
-
-#if defined(__cplusplus)
-/*
- * Dear c++: Please don't mangle this name. -thanks
- */
-extern "C"
-#endif				/* __cplusplus */
-  BOOL WINAPI
-DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
-{
-  BOOL result = PTW32_TRUE;
-
-  switch (fdwReason)
-    {
-
-    case DLL_PROCESS_ATTACH:
-      result = pthread_win32_process_attach_np ();
-      break;
-
-    case DLL_THREAD_ATTACH:
-      /*
-       * A thread is being created
-       */
-      result = pthread_win32_thread_attach_np ();
-      break;
-
-    case DLL_THREAD_DETACH:
-      /*
-       * A thread is exiting cleanly
-       */
-      result = pthread_win32_thread_detach_np ();
-      break;
-
-    case DLL_PROCESS_DETACH:
-      (void) pthread_win32_thread_detach_np ();
-      result = pthread_win32_process_detach_np ();
-      break;
-    }
-
-  return (result);
-
-}				/* DllMain */
-
-#endif /* PTW32_STATIC_LIB */
diff --git a/deps/w32-pthreads/errno.c b/deps/w32-pthreads/errno.c
deleted file mode 100644
index 1f5bfff..0000000
--- a/deps/w32-pthreads/errno.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * errno.c
- *
- * Description:
- * This translation unit implements routines associated with spawning a new
- * thread.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#if defined(NEED_ERRNO)
-
-#include "pthread.h"
-#include "implement.h"
-
-static int reallyBad = ENOMEM;
-
-/*
- * Re-entrant errno.
- *
- * Each thread has it's own errno variable in pthread_t.
- *
- * The benefit of using the pthread_t structure
- * instead of another TSD key is TSD keys are limited
- * on Win32 to 64 per process. Secondly, to implement
- * it properly without using pthread_t you'd need
- * to dynamically allocate an int on starting the thread
- * and store it manually into TLS and then ensure that you free
- * it on thread termination. We get all that for free
- * by simply storing the errno on the pthread_t structure.
- *
- * MSVC and Mingw32 already have their own thread-safe errno.
- *
- * #if defined( _REENTRANT ) || defined( _MT )
- * #define errno *_errno()
- *
- * int *_errno( void );
- * #else
- * extern int errno;
- * #endif
- *
- */
-
-int *
-_errno (void)
-{
-  pthread_t self;
-  int *result;
-
-  if ((self = pthread_self ()).p == NULL)
-    {
-      /*
-       * Yikes! unable to allocate a thread!
-       * Throw an exception? return an error?
-       */
-      result = &reallyBad;
-    }
-  else
-    {
-      result = (int *)(&self.p->exitStatus);
-    }
-
-  return (result);
-
-}				/* _errno */
-
-#endif /* (NEED_ERRNO) */
diff --git a/deps/w32-pthreads/exit.c b/deps/w32-pthreads/exit.c
deleted file mode 100644
index 7645d7a..0000000
--- a/deps/w32-pthreads/exit.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * exit.c
- *
- * Description:
- * This translation unit implements routines associated with exiting from
- * a thread.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#if ! defined(_UWIN) && ! defined(WINCE)
-#   include <process.h>
-#endif
-
-#include "pthread_exit.c"
diff --git a/deps/w32-pthreads/fork.c b/deps/w32-pthreads/fork.c
deleted file mode 100644
index 32acba6..0000000
--- a/deps/w32-pthreads/fork.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * fork.c
- *
- * Description:
- * Implementation of fork() for POSIX threads.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-
-#include "pthread.h"
-#include "implement.h"
diff --git a/deps/w32-pthreads/global.c b/deps/w32-pthreads/global.c
deleted file mode 100644
index 0bdf325..0000000
--- a/deps/w32-pthreads/global.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * global.c
- *
- * Description:
- * This translation unit instantiates data associated with the implementation
- * as a whole.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int ptw32_processInitialized = PTW32_FALSE;
-ptw32_thread_t * ptw32_threadReuseTop = PTW32_THREAD_REUSE_EMPTY;
-ptw32_thread_t * ptw32_threadReuseBottom = PTW32_THREAD_REUSE_EMPTY;
-pthread_key_t ptw32_selfThreadKey = NULL;
-pthread_key_t ptw32_cleanupKey = NULL;
-pthread_cond_t ptw32_cond_list_head = NULL;
-pthread_cond_t ptw32_cond_list_tail = NULL;
-
-int ptw32_concurrency = 0;
-
-/* What features have been auto-detected */
-int ptw32_features = 0;
-
-/*
- * Global [process wide] thread sequence Number
- */
-unsigned __int64 ptw32_threadSeqNumber = 0;
-
-/* 
- * Function pointer to QueueUserAPCEx if it exists, otherwise
- * it will be set at runtime to a substitute routine which cannot unblock
- * blocked threads.
- */
-DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD) = NULL;
-
-/*
- * Global lock for managing pthread_t struct reuse.
- */
-ptw32_mcs_lock_t ptw32_thread_reuse_lock = 0;
-
-/*
- * Global lock for testing internal state of statically declared mutexes.
- */
-ptw32_mcs_lock_t ptw32_mutex_test_init_lock = 0;
-
-/*
- * Global lock for testing internal state of PTHREAD_COND_INITIALIZER
- * created condition variables.
- */
-ptw32_mcs_lock_t ptw32_cond_test_init_lock = 0;
-
-/*
- * Global lock for testing internal state of PTHREAD_RWLOCK_INITIALIZER
- * created read/write locks.
- */
-ptw32_mcs_lock_t ptw32_rwlock_test_init_lock = 0;
-
-/*
- * Global lock for testing internal state of PTHREAD_SPINLOCK_INITIALIZER
- * created spin locks.
- */
-ptw32_mcs_lock_t ptw32_spinlock_test_init_lock = 0;
-
-/*
- * Global lock for condition variable linked list. The list exists
- * to wake up CVs when a WM_TIMECHANGE message arrives. See
- * w32_TimeChangeHandler.c.
- */
-ptw32_mcs_lock_t ptw32_cond_list_lock = 0;
-
-#if defined(_UWIN)
-/*
- * Keep a count of the number of threads.
- */
-int pthread_count = 0;
-#endif
diff --git a/deps/w32-pthreads/implement.h b/deps/w32-pthreads/implement.h
deleted file mode 100644
index db7888b..0000000
--- a/deps/w32-pthreads/implement.h
+++ /dev/null
@@ -1,943 +0,0 @@
-/*
- * implement.h
- *
- * Definitions that don't need to be public.
- *
- * Keeps all the internals out of pthread.h
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: Ross.Johnson at homemail.com.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#if !defined(_IMPLEMENT_H)
-#define _IMPLEMENT_H
-
-#if !defined(_WIN32_WINNT)
-#define _WIN32_WINNT 0x0400
-#endif
-
-#include <windows.h>
-
-/*
- * In case windows.h doesn't define it (e.g. WinCE perhaps)
- */
-#if defined(WINCE)
-typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
-#endif
-
-/*
- * note: ETIMEDOUT is correctly defined in winsock.h
- */
-#include <winsock.h>
-
-/*
- * In case ETIMEDOUT hasn't been defined above somehow.
- */
-#if !defined(ETIMEDOUT)
-#  define ETIMEDOUT 10060	/* This is the value in winsock.h. */
-#endif
-
-#if !defined(malloc)
-#include <malloc.h>
-#endif
-
-#if defined(__CLEANUP_C)
-# include <setjmp.h>
-#endif
-
-#if !defined(INT_MAX)
-#include <limits.h>
-#endif
-
-/* use local include files during development */
-#include "semaphore.h"
-#include "sched.h"
-
-#if defined(HAVE_C_INLINE) || defined(__cplusplus)
-#define INLINE inline
-#else
-#define INLINE
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER < 1300
-/*
- * MSVC 6 does not use the "volatile" qualifier
- */
-#define PTW32_INTERLOCKED_VOLATILE
-#else
-#define PTW32_INTERLOCKED_VOLATILE volatile
-#endif
-#define PTW32_INTERLOCKED_LONG long
-#define PTW32_INTERLOCKED_SIZE size_t
-#define PTW32_INTERLOCKED_PVOID PVOID
-#define PTW32_INTERLOCKED_LONGPTR PTW32_INTERLOCKED_VOLATILE long*
-#define PTW32_INTERLOCKED_SIZEPTR PTW32_INTERLOCKED_VOLATILE size_t*
-#define PTW32_INTERLOCKED_PVOID_PTR PTW32_INTERLOCKED_VOLATILE PVOID*
-
-#if defined(__MINGW64__) || defined(__MINGW32__)
-#  include <stdint.h>
-#elif defined(__BORLANDC__)
-#  define int64_t ULONGLONG
-#else
-#  define int64_t _int64
-#  if defined(_MSC_VER) && _MSC_VER < 1300
-     typedef long intptr_t;
-#  endif
-#endif
-
-typedef enum
-{
-  /*
-   * This enumeration represents the state of the thread;
-   * The thread is still "alive" if the numeric value of the
-   * state is greater or equal "PThreadStateRunning".
-   */
-  PThreadStateInitial = 0,	/* Thread not running                   */
-  PThreadStateRunning,		/* Thread alive & kicking               */
-  PThreadStateSuspended,	/* Thread alive but suspended           */
-  PThreadStateCancelPending,	/* Thread alive but                     */
-                                /* has cancelation pending.             */
-  PThreadStateCanceling,	/* Thread alive but is                  */
-                                /* in the process of terminating        */
-                                /* due to a cancellation request        */
-  PThreadStateExiting,		/* Thread alive but exiting             */
-                                /* due to an exception                  */
-  PThreadStateLast,             /* All handlers have been run and now   */
-                                /* final cleanup can be done.           */
-  PThreadStateReuse             /* In reuse pool.                       */
-}
-PThreadState;
-
-typedef struct ptw32_mcs_node_t_     ptw32_mcs_local_node_t;
-typedef struct ptw32_mcs_node_t_*    ptw32_mcs_lock_t;
-typedef struct ptw32_robust_node_t_  ptw32_robust_node_t;
-typedef struct ptw32_thread_t_       ptw32_thread_t;
-
-
-struct ptw32_thread_t_
-{
-  unsigned __int64 seqNumber;	/* Process-unique thread sequence number */
-  HANDLE threadH;		/* Win32 thread handle - POSIX thread is invalid if threadH == 0 */
-  pthread_t ptHandle;		/* This thread's permanent pthread_t handle */
-  ptw32_thread_t * prevReuse;	/* Links threads on reuse stack */
-  volatile PThreadState state;
-  ptw32_mcs_lock_t threadLock;	/* Used for serialised access to public thread state */
-  ptw32_mcs_lock_t stateLock;	/* Used for async-cancel safety */
-  HANDLE cancelEvent;
-  void *exitStatus;
-  void *parms;
-  void *keys;
-  void *nextAssoc;
-#if defined(__CLEANUP_C)
-  jmp_buf start_mark;		/* Jump buffer follows void* so should be aligned */
-#endif				/* __CLEANUP_C */
-#if defined(HAVE_SIGSET_T)
-  sigset_t sigmask;
-#endif				/* HAVE_SIGSET_T */
-  ptw32_mcs_lock_t
-              robustMxListLock; /* robustMxList lock */
-  ptw32_robust_node_t*
-                  robustMxList; /* List of currenty held robust mutexes */
-  int ptErrno;
-  int detachState;
-  int sched_priority;		/* As set, not as currently is */
-  int cancelState;
-  int cancelType;
-  int implicit:1;
-  DWORD thread;			/* Win32 thread ID */
-#if defined(_UWIN)
-  DWORD dummy[5];
-#endif
-  size_t align;			/* Force alignment if this struct is packed */
-};
-
-
-/* 
- * Special value to mark attribute objects as valid.
- */
-#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE)
-
-struct pthread_attr_t_
-{
-  unsigned long valid;
-  void *stackaddr;
-  size_t stacksize;
-  int detachstate;
-  struct sched_param param;
-  int inheritsched;
-  int contentionscope;
-#if defined(HAVE_SIGSET_T)
-  sigset_t sigmask;
-#endif				/* HAVE_SIGSET_T */
-};
-
-
-/*
- * ====================
- * ====================
- * Semaphores, Mutexes and Condition Variables
- * ====================
- * ====================
- */
-
-struct sem_t_
-{
-  int value;
-  pthread_mutex_t lock;
-  HANDLE sem;
-#if defined(NEED_SEM)
-  int leftToUnblock;
-#endif
-};
-
-#define PTW32_OBJECT_AUTO_INIT ((void *)(size_t) -1)
-#define PTW32_OBJECT_INVALID   NULL
-
-struct pthread_mutex_t_
-{
-  LONG lock_idx;		/* Provides exclusive access to mutex state
-				   via the Interlocked* mechanism.
-				    0: unlocked/free.
-				    1: locked - no other waiters.
-				   -1: locked - with possible other waiters.
-				*/
-  int recursive_count;		/* Number of unlocks a thread needs to perform
-				   before the lock is released (recursive
-				   mutexes only). */
-  int kind;			/* Mutex type. */
-  pthread_t ownerThread;
-  HANDLE event;			/* Mutex release notification to waiting
-				   threads. */
-  ptw32_robust_node_t*
-                    robustNode; /* Extra state for robust mutexes  */
-};
-
-enum ptw32_robust_state_t_
-{
-  PTW32_ROBUST_CONSISTENT,
-  PTW32_ROBUST_INCONSISTENT,
-  PTW32_ROBUST_NOTRECOVERABLE
-};
-
-typedef enum ptw32_robust_state_t_   ptw32_robust_state_t;
-
-/*
- * Node used to manage per-thread lists of currently-held robust mutexes.
- */
-struct ptw32_robust_node_t_
-{
-  pthread_mutex_t mx;
-  ptw32_robust_state_t stateInconsistent;
-  ptw32_robust_node_t* prev;
-  ptw32_robust_node_t* next;
-};
-
-struct pthread_mutexattr_t_
-{
-  int pshared;
-  int kind;
-  int robustness;
-};
-
-/*
- * Possible values, other than PTW32_OBJECT_INVALID,
- * for the "interlock" element in a spinlock.
- *
- * In this implementation, when a spinlock is initialised,
- * the number of cpus available to the process is checked.
- * If there is only one cpu then "interlock" is set equal to
- * PTW32_SPIN_USE_MUTEX and u.mutex is an initialised mutex.
- * If the number of cpus is greater than 1 then "interlock"
- * is set equal to PTW32_SPIN_UNLOCKED and the number is
- * stored in u.cpus. This arrangement allows the spinlock
- * routines to attempt an InterlockedCompareExchange on "interlock"
- * immediately and, if that fails, to try the inferior mutex.
- *
- * "u.cpus" isn't used for anything yet, but could be used at
- * some point to optimise spinlock behaviour.
- */
-#define PTW32_SPIN_INVALID     (0)
-#define PTW32_SPIN_UNLOCKED    (1)
-#define PTW32_SPIN_LOCKED      (2)
-#define PTW32_SPIN_USE_MUTEX   (3)
-
-struct pthread_spinlock_t_
-{
-  long interlock;		/* Locking element for multi-cpus. */
-  union
-  {
-    int cpus;			/* No. of cpus if multi cpus, or   */
-    pthread_mutex_t mutex;	/* mutex if single cpu.            */
-  } u;
-};
-
-/*
- * MCS lock queue node - see ptw32_MCS_lock.c
- */
-struct ptw32_mcs_node_t_
-{
-  struct ptw32_mcs_node_t_ **lock;        /* ptr to tail of queue */
-  struct ptw32_mcs_node_t_  *next;        /* ptr to successor in queue */
-  HANDLE                     readyFlag;   /* set after lock is released by
-                                             predecessor */
-  HANDLE                     nextFlag;    /* set after 'next' ptr is set by
-                                             successor */
-};
-
-
-struct pthread_barrier_t_
-{
-  unsigned int nCurrentBarrierHeight;
-  unsigned int nInitialBarrierHeight;
-  int pshared;
-  sem_t semBarrierBreeched;
-  ptw32_mcs_lock_t lock;
-  ptw32_mcs_local_node_t proxynode;
-};
-
-struct pthread_barrierattr_t_
-{
-  int pshared;
-};
-
-struct pthread_key_t_
-{
-  DWORD key;
-  void (PTW32_CDECL *destructor) (void *);
-  ptw32_mcs_lock_t keyLock;
-  void *threads;
-};
-
-
-typedef struct ThreadParms ThreadParms;
-
-struct ThreadParms
-{
-  pthread_t tid;
-  void *(PTW32_CDECL *start) (void *);
-  void *arg;
-};
-
-
-struct pthread_cond_t_
-{
-  long nWaitersBlocked;		/* Number of threads blocked            */
-  long nWaitersGone;		/* Number of threads timed out          */
-  long nWaitersToUnblock;	/* Number of threads to unblock         */
-  sem_t semBlockQueue;		/* Queue up threads waiting for the     */
-  /*   condition to become signalled      */
-  sem_t semBlockLock;		/* Semaphore that guards access to      */
-  /* | waiters blocked count/block queue  */
-  /* +-> Mandatory Sync.LEVEL-1           */
-  pthread_mutex_t mtxUnblockLock;	/* Mutex that guards access to          */
-  /* | waiters (to)unblock(ed) counts     */
-  /* +-> Optional* Sync.LEVEL-2           */
-  pthread_cond_t next;		/* Doubly linked list                   */
-  pthread_cond_t prev;
-};
-
-
-struct pthread_condattr_t_
-{
-  int pshared;
-};
-
-#define PTW32_RWLOCK_MAGIC 0xfacade2
-
-struct pthread_rwlock_t_
-{
-  pthread_mutex_t mtxExclusiveAccess;
-  pthread_mutex_t mtxSharedAccessCompleted;
-  pthread_cond_t cndSharedAccessCompleted;
-  int nSharedAccessCount;
-  int nExclusiveAccessCount;
-  int nCompletedSharedAccessCount;
-  int nMagic;
-};
-
-struct pthread_rwlockattr_t_
-{
-  int pshared;
-};
-
-typedef struct ThreadKeyAssoc ThreadKeyAssoc;
-
-struct ThreadKeyAssoc
-{
-  /*
-   * Purpose:
-   *      This structure creates an association between a thread and a key.
-   *      It is used to implement the implicit invocation of a user defined
-   *      destroy routine for thread specific data registered by a user upon
-   *      exiting a thread.
-   *
-   *      Graphically, the arrangement is as follows, where:
-   *
-   *         K - Key with destructor
-   *            (head of chain is key->threads)
-   *         T - Thread that has called pthread_setspecific(Kn)
-   *            (head of chain is thread->keys)
-   *         A - Association. Each association is a node at the
-   *             intersection of two doubly-linked lists.
-   *
-   *                 T1    T2    T3
-   *                 |     |     |
-   *                 |     |     |
-   *         K1 -----+-----A-----A----->
-   *                 |     |     |
-   *                 |     |     |
-   *         K2 -----A-----A-----+----->
-   *                 |     |     |
-   *                 |     |     |
-   *         K3 -----A-----+-----A----->
-   *                 |     |     |
-   *                 |     |     |
-   *                 V     V     V
-   *
-   *      Access to the association is guarded by two locks: the key's
-   *      general lock (guarding the row) and the thread's general
-   *      lock (guarding the column). This avoids the need for a
-   *      dedicated lock for each association, which not only consumes
-   *      more handles but requires that the lock resources persist
-   *      until both the key is deleted and the thread has called the
-   *      destructor. The two-lock arrangement allows those resources
-   *      to be freed as soon as either thread or key is concluded.
-   *
-   *      To avoid deadlock, whenever both locks are required both the
-   *      key and thread locks are acquired consistently in the order
-   *      "key lock then thread lock". An exception to this exists
-   *      when a thread calls the destructors, however, this is done
-   *      carefully (but inelegantly) to avoid deadlock.
-   *
-   *      An association is created when a thread first calls
-   *      pthread_setspecific() on a key that has a specified
-   *      destructor.
-   *
-   *      An association is destroyed either immediately after the
-   *      thread calls the key destructor function on thread exit, or
-   *      when the key is deleted.
-   *
-   * Attributes:
-   *      thread
-   *              reference to the thread that owns the
-   *              association. This is actually the pointer to the
-   *              thread struct itself. Since the association is
-   *              destroyed before the thread exits, this can never
-   *              point to a different logical thread to the one that
-   *              created the assoc, i.e. after thread struct reuse.
-   *
-   *      key
-   *              reference to the key that owns the association.
-   *
-   *      nextKey
-   *              The pthread_t->keys attribute is the head of a
-   *              chain of associations that runs through the nextKey
-   *              link. This chain provides the 1 to many relationship
-   *              between a pthread_t and all pthread_key_t on which
-   *              it called pthread_setspecific.
-   *
-   *      prevKey
-   *              Similarly.
-   *
-   *      nextThread
-   *              The pthread_key_t->threads attribute is the head of
-   *              a chain of associations that runs through the
-   *              nextThreads link. This chain provides the 1 to many
-   *              relationship between a pthread_key_t and all the 
-   *              PThreads that have called pthread_setspecific for
-   *              this pthread_key_t.
-   *
-   *      prevThread
-   *              Similarly.
-   *
-   * Notes:
-   *      1)      As soon as either the key or the thread is no longer
-   *              referencing the association, it can be destroyed. The
-   *              association will be removed from both chains.
-   *
-   *      2)      Under WIN32, an association is only created by
-   *              pthread_setspecific if the user provided a
-   *              destroyRoutine when they created the key.
-   *
-   *
-   */
-  ptw32_thread_t * thread;
-  pthread_key_t key;
-  ThreadKeyAssoc *nextKey;
-  ThreadKeyAssoc *nextThread;
-  ThreadKeyAssoc *prevKey;
-  ThreadKeyAssoc *prevThread;
-};
-
-
-#if defined(__CLEANUP_SEH)
-/*
- * --------------------------------------------------------------
- * MAKE_SOFTWARE_EXCEPTION
- *      This macro constructs a software exception code following
- *      the same format as the standard Win32 error codes as defined
- *      in WINERROR.H
- *  Values are 32 bit values laid out as follows:
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +---+-+-+-----------------------+-------------------------------+
- *  |Sev|C|R|     Facility          |               Code            |
- *  +---+-+-+-----------------------+-------------------------------+
- *
- * Severity Values:
- */
-#define SE_SUCCESS              0x00
-#define SE_INFORMATION          0x01
-#define SE_WARNING              0x02
-#define SE_ERROR                0x03
-
-#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \
-( (DWORD) ( ( (_severity) << 30 ) |     /* Severity code        */ \
-            ( 1 << 29 ) |               /* MS=0, User=1         */ \
-            ( 0 << 28 ) |               /* Reserved             */ \
-            ( (_facility) << 16 ) |     /* Facility Code        */ \
-            ( (_exception) <<  0 )      /* Exception Code       */ \
-            ) )
-
-/*
- * We choose one specific Facility/Error code combination to
- * identify our software exceptions vs. WIN32 exceptions.
- * We store our actual component and error code within
- * the optional information array.
- */
-#define EXCEPTION_PTW32_SERVICES        \
-     MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \
-                              PTW32_SERVICES_FACILITY, \
-                              PTW32_SERVICES_ERROR )
-
-#define PTW32_SERVICES_FACILITY         0xBAD
-#define PTW32_SERVICES_ERROR            0xDEED
-
-#endif /* __CLEANUP_SEH */
-
-/*
- * Services available through EXCEPTION_PTW32_SERVICES
- * and also used [as parameters to ptw32_throw()] as
- * generic exception selectors.
- */
-
-#define PTW32_EPS_EXIT                  (1)
-#define PTW32_EPS_CANCEL                (2)
-
-
-/* Useful macros */
-#define PTW32_MAX(a,b)  ((a)<(b)?(b):(a))
-#define PTW32_MIN(a,b)  ((a)>(b)?(b):(a))
-
-
-/* Declared in pthread_cancel.c */
-extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD);
-
-/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */
-#define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *)(size_t) 1)
-
-extern int ptw32_processInitialized;
-extern ptw32_thread_t * ptw32_threadReuseTop;
-extern ptw32_thread_t * ptw32_threadReuseBottom;
-extern pthread_key_t ptw32_selfThreadKey;
-extern pthread_key_t ptw32_cleanupKey;
-extern pthread_cond_t ptw32_cond_list_head;
-extern pthread_cond_t ptw32_cond_list_tail;
-
-extern int ptw32_mutex_default_kind;
-
-extern unsigned __int64 ptw32_threadSeqNumber;
-
-extern int ptw32_concurrency;
-
-extern int ptw32_features;
-
-extern ptw32_mcs_lock_t ptw32_thread_reuse_lock;
-extern ptw32_mcs_lock_t ptw32_mutex_test_init_lock;
-extern ptw32_mcs_lock_t ptw32_cond_list_lock;
-extern ptw32_mcs_lock_t ptw32_cond_test_init_lock;
-extern ptw32_mcs_lock_t ptw32_rwlock_test_init_lock;
-extern ptw32_mcs_lock_t ptw32_spinlock_test_init_lock;
-
-#if defined(_UWIN)
-extern int pthread_count;
-#endif
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif				/* __cplusplus */
-
-/*
- * =====================
- * =====================
- * Forward Declarations
- * =====================
- * =====================
- */
-
-  int ptw32_is_attr (const pthread_attr_t * attr);
-
-  int ptw32_cond_check_need_init (pthread_cond_t * cond);
-  int ptw32_mutex_check_need_init (pthread_mutex_t * mutex);
-  int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock);
-
-  int ptw32_robust_mutex_inherit(pthread_mutex_t * mutex);
-  void ptw32_robust_mutex_add(pthread_mutex_t* mutex, pthread_t self);
-  void ptw32_robust_mutex_remove(pthread_mutex_t* mutex, ptw32_thread_t* otp);
-
-  DWORD
-    ptw32_RegisterCancelation (PAPCFUNC callback,
-			       HANDLE threadH, DWORD callback_arg);
-
-  int ptw32_processInitialize (void);
-
-  void ptw32_processTerminate (void);
-
-  void ptw32_threadDestroy (pthread_t tid);
-
-  void ptw32_pop_cleanup_all (int execute);
-
-  pthread_t ptw32_new (void);
-
-  pthread_t ptw32_threadReusePop (void);
-
-  void ptw32_threadReusePush (pthread_t thread);
-
-  int ptw32_getprocessors (int *count);
-
-  int ptw32_setthreadpriority (pthread_t thread, int policy, int priority);
-
-  void ptw32_rwlock_cancelwrwait (void *arg);
-
-#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || (defined(__MSVCRT__) && ! defined(__DMC__))
-  unsigned __stdcall
-#else
-  void
-#endif
-    ptw32_threadStart (void *vthreadParms);
-
-  void ptw32_callUserDestroyRoutines (pthread_t thread);
-
-  int ptw32_tkAssocCreate (ptw32_thread_t * thread, pthread_key_t key);
-
-  void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc);
-
-  int ptw32_semwait (sem_t * sem);
-
-  DWORD ptw32_relmillisecs (const struct timespec * abstime);
-
-  void ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node);
-
-  int ptw32_mcs_lock_try_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node);
-
-  void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node);
-
-  void ptw32_mcs_node_transfer (ptw32_mcs_local_node_t * new_node, ptw32_mcs_local_node_t * old_node);
-
-#if defined(NEED_FTIME)
-  void ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft);
-  void ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts);
-#endif
-
-/* Declared in misc.c */
-#if defined(NEED_CALLOC)
-#define calloc(n, s) ptw32_calloc(n, s)
-  void *ptw32_calloc (size_t n, size_t s);
-#endif
-
-/* Declared in private.c */
-#if defined(_MSC_VER)
-/*
- * Ignore the warning:
- * "C++ exception specification ignored except to indicate that
- * the function is not __declspec(nothrow)."
- */
-#pragma warning(disable:4290)
-#endif
-  void ptw32_throw (DWORD exception)
-#if defined(__CLEANUP_CXX)
-    throw(ptw32_exception_cancel,ptw32_exception_exit)
-#endif
-;
-
-#if defined(__cplusplus)
-}
-#endif				/* __cplusplus */
-
-
-#if defined(_UWIN_)
-#   if defined(_MT)
-#       if defined(__cplusplus)
-extern "C"
-{
-#       endif
-  _CRTIMP unsigned long __cdecl _beginthread (void (__cdecl *) (void *),
-					      unsigned, void *);
-  _CRTIMP void __cdecl _endthread (void);
-  _CRTIMP unsigned long __cdecl _beginthreadex (void *, unsigned,
-						unsigned (__stdcall *) (void *),
-						void *, unsigned, unsigned *);
-  _CRTIMP void __cdecl _endthreadex (unsigned);
-#       if defined(__cplusplus)
-}
-#       endif
-#   endif
-#else
-#       include <process.h>
-#   endif
-
-
-/*
- * Use intrinsic versions wherever possible. VC will do this
- * automatically where possible and GCC define these if available:
- * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
- * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
- * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
- * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
- * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
- *
- * The full set of Interlocked intrinsics in GCC are (check versions):
- * type __sync_fetch_and_add (type *ptr, type value, ...)
- * type __sync_fetch_and_sub (type *ptr, type value, ...)
- * type __sync_fetch_and_or (type *ptr, type value, ...)
- * type __sync_fetch_and_and (type *ptr, type value, ...)
- * type __sync_fetch_and_xor (type *ptr, type value, ...)
- * type __sync_fetch_and_nand (type *ptr, type value, ...)
- * type __sync_add_and_fetch (type *ptr, type value, ...)
- * type __sync_sub_and_fetch (type *ptr, type value, ...)
- * type __sync_or_and_fetch (type *ptr, type value, ...)
- * type __sync_and_and_fetch (type *ptr, type value, ...)
- * type __sync_xor_and_fetch (type *ptr, type value, ...)
- * type __sync_nand_and_fetch (type *ptr, type value, ...)
- * bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
- * type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)
- * __sync_synchronize (...) // Full memory barrier
- * type __sync_lock_test_and_set (type *ptr, type value, ...) // Acquire barrier
- * void __sync_lock_release (type *ptr, ...) // Release barrier
- *
- * These are all overloaded and take 1,2,4,8 byte scalar or pointer types.
- *
- * The above aren't available in Mingw32 as of gcc 4.5.2 so define our own.
- */
-#if defined(__GNUC__)
-# if defined(_WIN64)
-# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64(location, value, comparand)    \
-    ({                                                                     \
-      __typeof (value) _result;                                            \
-      __asm__ __volatile__                                                 \
-      (                                                                    \
-        "lock\n\t"                                                         \
-        "cmpxchgq      %2,(%1)"                                            \
-        :"=a" (_result)                                                    \
-        :"r"  (location), "r" (value), "a" (comparand)                     \
-        :"memory", "cc");                                                  \
-      _result;                                                             \
-    })
-# define PTW32_INTERLOCKED_EXCHANGE_64(location, value)                    \
-    ({                                                                     \
-      __typeof (value) _result;                                            \
-      __asm__ __volatile__                                                 \
-      (                                                                    \
-        "xchgq	 %0,(%1)"                                                  \
-        :"=r" (_result)                                                    \
-        :"r" (location), "0" (value)                                       \
-        :"memory", "cc");                                                  \
-      _result;                                                             \
-    })
-# define PTW32_INTERLOCKED_EXCHANGE_ADD_64(location, value)                \
-    ({                                                                     \
-      __typeof (value) _result;                                            \
-      __asm__ __volatile__                                                 \
-      (                                                                    \
-        "lock\n\t"                                                         \
-        "xaddq	 %0,(%1)"                                                  \
-        :"=r" (_result)                                                    \
-        :"r" (location), "0" (value)                                       \
-        :"memory", "cc");                                                  \
-      _result;                                                             \
-    })
-# define PTW32_INTERLOCKED_INCREMENT_64(location)                          \
-    ({                                                                     \
-      PTW32_INTERLOCKED_LONG _temp = 1;                                   \
-      __asm__ __volatile__                                                 \
-      (                                                                    \
-        "lock\n\t"                                                         \
-        "xaddq	 %0,(%1)"                                                  \
-        :"+r" (_temp)                                                      \
-        :"r" (location)                                                    \
-        :"memory", "cc");                                                  \
-      ++_temp;                                                             \
-    })
-# define PTW32_INTERLOCKED_DECREMENT_64(location)                          \
-    ({                                                                     \
-      PTW32_INTERLOCKED_LONG _temp = -1;                                  \
-      __asm__ __volatile__                                                 \
-      (                                                                    \
-        "lock\n\t"                                                         \
-        "xaddq	 %2,(%1)"                                                  \
-        :"+r" (_temp)                                                      \
-        :"r" (location)                                                    \
-        :"memory", "cc");                                                  \
-      --_temp;                                                             \
-    })
-#endif
-# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand)    \
-    ({                                                                     \
-      __typeof (value) _result;                                            \
-      __asm__ __volatile__                                                 \
-      (                                                                    \
-        "lock\n\t"                                                         \
-        "cmpxchgl       %2,(%1)"                                           \
-        :"=a" (_result)                                                    \
-        :"r"  (location), "r" (value), "a" (comparand)                     \
-        :"memory", "cc");                                                  \
-      _result;                                                             \
-    })
-# define PTW32_INTERLOCKED_EXCHANGE_LONG(location, value)                  \
-    ({                                                                     \
-      __typeof (value) _result;                                            \
-      __asm__ __volatile__                                                 \
-      (                                                                    \
-        "xchgl	 %0,(%1)"                                                  \
-        :"=r" (_result)                                                    \
-        :"r" (location), "0" (value)                                       \
-        :"memory", "cc");                                                  \
-      _result;                                                             \
-    })
-# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(location, value)              \
-    ({                                                                     \
-      __typeof (value) _result;                                            \
-      __asm__ __volatile__                                                 \
-      (                                                                    \
-        "lock\n\t"                                                         \
-        "xaddl	 %0,(%1)"                                                  \
-        :"=r" (_result)                                                    \
-        :"r" (location), "0" (value)                                       \
-        :"memory", "cc");                                                  \
-      _result;                                                             \
-    })
-# define PTW32_INTERLOCKED_INCREMENT_LONG(location)                        \
-    ({                                                                     \
-      PTW32_INTERLOCKED_LONG _temp = 1;                                   \
-      __asm__ __volatile__                                                 \
-      (                                                                    \
-        "lock\n\t"                                                         \
-        "xaddl	 %0,(%1)"                                                  \
-        :"+r" (_temp)                                                      \
-        :"r" (location)                                                    \
-        :"memory", "cc");                                                  \
-      ++_temp;                                                             \
-    })
-# define PTW32_INTERLOCKED_DECREMENT_LONG(location)                        \
-    ({                                                                     \
-      PTW32_INTERLOCKED_LONG _temp = -1;                                  \
-      __asm__ __volatile__                                                 \
-      (                                                                    \
-        "lock\n\t"                                                         \
-        "xaddl	 %0,(%1)"                                                  \
-        :"+r" (_temp)                                                      \
-        :"r" (location)                                                    \
-        :"memory", "cc");                                                  \
-      --_temp;                                                             \
-    })
-# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(location, value, comparand) \
-    PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE((PTW32_INTERLOCKED_SIZEPTR)location, \
-                                            (PTW32_INTERLOCKED_SIZE)value, \
-                                            (PTW32_INTERLOCKED_SIZE)comparand)
-# define PTW32_INTERLOCKED_EXCHANGE_PTR(location, value) \
-    PTW32_INTERLOCKED_EXCHANGE_SIZE((PTW32_INTERLOCKED_SIZEPTR)location, \
-                                    (PTW32_INTERLOCKED_SIZE)value)
-#else
-# if defined(_WIN64)
-#   define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64 InterlockedCompareExchange64
-#   define PTW32_INTERLOCKED_EXCHANGE_64 InterlockedExchange64
-#   define PTW32_INTERLOCKED_EXCHANGE_ADD_64 InterlockedExchangeAdd64
-#   define PTW32_INTERLOCKED_INCREMENT_64 InterlockedIncrement64
-#   define PTW32_INTERLOCKED_DECREMENT_64 InterlockedDecrement64
-# endif
-# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */
-#  define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand) \
-      ((LONG)InterlockedCompareExchange((PVOID *)(location), (PVOID)(value), (PVOID)(comparand)))
-# else
-#  define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG InterlockedCompareExchange
-# endif
-# define PTW32_INTERLOCKED_EXCHANGE_LONG InterlockedExchange
-# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG InterlockedExchangeAdd
-# define PTW32_INTERLOCKED_INCREMENT_LONG InterlockedIncrement
-# define PTW32_INTERLOCKED_DECREMENT_LONG InterlockedDecrement
-# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */
-#  define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchange
-#  define PTW32_INTERLOCKED_EXCHANGE_PTR(location, value) \
-    ((PVOID)InterlockedExchange((LPLONG)(location), (LONG)(value)))
-# else
-#  define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchangePointer
-#  define PTW32_INTERLOCKED_EXCHANGE_PTR InterlockedExchangePointer
-# endif
-#endif
-#if defined(_WIN64)
-#   define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE PTW32_INTERLOCKED_COMPARE_EXCHANGE_64
-#   define PTW32_INTERLOCKED_EXCHANGE_SIZE PTW32_INTERLOCKED_EXCHANGE_64
-#   define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE PTW32_INTERLOCKED_EXCHANGE_ADD_64
-#   define PTW32_INTERLOCKED_INCREMENT_SIZE PTW32_INTERLOCKED_INCREMENT_64
-#   define PTW32_INTERLOCKED_DECREMENT_SIZE PTW32_INTERLOCKED_DECREMENT_64
-#else
-#   define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG
-#   define PTW32_INTERLOCKED_EXCHANGE_SIZE PTW32_INTERLOCKED_EXCHANGE_LONG
-#   define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE PTW32_INTERLOCKED_EXCHANGE_ADD_LONG
-#   define PTW32_INTERLOCKED_INCREMENT_SIZE PTW32_INTERLOCKED_INCREMENT_LONG
-#   define PTW32_INTERLOCKED_DECREMENT_SIZE PTW32_INTERLOCKED_DECREMENT_LONG
-#endif
-
-#if defined(NEED_CREATETHREAD)
-
-/* 
- * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE
- * in order to avoid warnings because of return type
- */
-
-#define _beginthreadex(security, \
-                       stack_size, \
-                       start_proc, \
-                       arg, \
-                       flags, \
-                       pid) \
-        CreateThread(security, \
-                     stack_size, \
-                     (LPTHREAD_START_ROUTINE) start_proc, \
-                     arg, \
-                     flags, \
-                     pid)
-
-#define _endthreadex ExitThread
-
-#endif				/* NEED_CREATETHREAD */
-
-
-#endif				/* _IMPLEMENT_H */
diff --git a/deps/w32-pthreads/libpthreadGC2.a b/deps/w32-pthreads/libpthreadGC2.a
deleted file mode 100644
index 43ff77e..0000000
Binary files a/deps/w32-pthreads/libpthreadGC2.a and /dev/null differ
diff --git a/deps/w32-pthreads/libpthreadGC2.stamp b/deps/w32-pthreads/libpthreadGC2.stamp
deleted file mode 100644
index 16225d0..0000000
--- a/deps/w32-pthreads/libpthreadGC2.stamp
+++ /dev/null
@@ -1 +0,0 @@
-touched
diff --git a/deps/w32-pthreads/manual/ChangeLog b/deps/w32-pthreads/manual/ChangeLog
deleted file mode 100644
index 071b847..0000000
--- a/deps/w32-pthreads/manual/ChangeLog
+++ /dev/null
@@ -1,74 +0,0 @@
-2011-03-26  Ross Johnson  <ross at homemail dot com dot au>
-
-	* pthread_nutex_init.html (robust mutexes): Added
-	descriptions for newly implemented interface.
-	* pthread_mutexattr_init.html (robust mutexes): Likewise.
-	* pthread_getsequence_np.html: New.
-	* index.html: Updated.
-
-2008-06-30  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* pthread_setschedparam.html: Fix "see also" links.
-
-2005-05-06  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* PortabilityIssues.html: Was nonPortableIssues.html.
-	* index.html: Updated; add table of contents at top.
-	* *.html: Add Pthreads-win32 header info; add link back to the
-	index page 'index.html'.
-
-2005-05-06  Ross Johnson  <ross at callisto.canberra.edu.au>
-
-	* index.html: New.
-	* nonPortableIssues.html: New.
-	* pthread_attr_init.html: New.
-	* pthread_attr_setstackaddr.html: New.
-	* pthread_attr_setstacksize.html: New.
-	* pthread_barrierattr_init.html: New.
-	* pthread_barrierattr_setpshared.html: New.
-	* pthread_barrier_init.html: New.
-	* pthread_barrier_wait.html: New.
-	* pthreadCancelableWait.html: New.
-	* pthread_cancel.html: New.
-	* pthread_cleanup_push.html: New.
-	* pthread_condattr_init.html: New.
-	* pthread_condattr_setpshared.html: New.
-	* pthread_cond_init.html: New.
-	* pthread_create.html: New.
-	* pthread_delay_np.html: New.
-	* pthread_detach.html: New.
-	* pthread_equal.html: New.
-	* pthread_exit.html: New.
-	* pthread_getw32threadhandle_np.html: New.
-	* pthread_join.html: New.
-	* pthread_key_create.html: New.
-	* pthread_kill.html: New.
-	* pthread_mutexattr_init.html: New.
-	* pthread_mutexattr_setpshared.html: New.
-	* pthread_mutex_init.html: New.
-	* pthread_num_processors_np.html: New.
-	* pthread_once.html: New.
-	* pthread_rwlockattr_init.html: New.
-	* pthread_rwlockattr_setpshared.html: New.
-	* pthread_rwlock_init.html: New.
-	* pthread_rwlock_rdlock.html: New.
-	* pthread_rwlock_timedrdlock.html: New.
-	* pthread_rwlock_timedwrlock.html: New.
-	* pthread_rwlock_unlock.html: New.
-	* pthread_rwlock_wrlock.html: New.
-	* pthread_self.html: New.
-	* pthread_setcancelstate.html: New.
-	* pthread_setcanceltype.html: New.
-	* pthread_setconcurrency.html: New.
-	* pthread_setschedparam.html: New.
-	* pthread_spin_init.html: New.
-	* pthread_spin_lock.html: New.
-	* pthread_spin_unlock.html: New.
-	* pthread_timechange_handler_np.html: New.
-	* pthread_win32_attach_detach_np.html: New.
-	* pthread_win32_test_features_np.html: New.
-	* sched_get_priority_max.html: New.
-	* sched_getscheduler.html: New.
-	* sched_setscheduler.html: New.
-	* sched_yield.html: New.
-	* sem_init.html: New.
diff --git a/deps/w32-pthreads/manual/PortabilityIssues.html b/deps/w32-pthreads/manual/PortabilityIssues.html
deleted file mode 100644
index 376a5f0..0000000
--- a/deps/w32-pthreads/manual/PortabilityIssues.html
+++ /dev/null
@@ -1,718 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PORTABILITYISSUES manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;322600">
-	<META NAME="CHANGED" CONTENT="20050506;11580000">
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<H4><A HREF="#toc">Table of Contents</A></H4>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P STYLE="font-weight: medium">Portability issues</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>Thread priority</B></P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<H3>Thread priority</H3>
-<P STYLE="margin-left: 2cm">POSIX defines a single contiguous range
-of numbers that determine a thread's priority. Win32 defines priority
-classes - and priority levels relative to these classes. Classes are
-simply priority base levels that the defined priority levels are
-relative to such that, changing a process's priority class will
-change the priority of all of it's threads, while the threads retain
-the same relativity to each other.</P>
-<P STYLE="margin-left: 2cm">A Win32 system defines a single
-contiguous monotonic range of values that define system priority
-levels, just like POSIX. However, Win32 restricts individual threads
-to a subset of this range on a per-process basis.</P>
-<P STYLE="margin-left: 2cm">The following table shows the base
-priority levels for combinations of priority class and priority value
-in Win32.</P>
-<DL>
-	<DL>
-		<DD>
-		<TABLE WIDTH=742 BORDER=0 CELLPADDING=0 CELLSPACING=0 STYLE="page-break-inside: avoid">
-			<COL WIDTH=50>
-			<COL WIDTH=356>
-			<COL WIDTH=336>
-			<THEAD>
-				<TR VALIGN=TOP>
-					<TD WIDTH=50>
-						<P ALIGN=CENTER><BR>
-						</P>
-					</TD>
-					<TD WIDTH=356>
-						<P ALIGN=LEFT><B>Process Priority Class</B></P>
-					</TD>
-					<TD WIDTH=336>
-						<P ALIGN=LEFT><B>Thread Priority Level</B></P>
-					</TD>
-				</TR>
-			</THEAD>
-			<TBODY>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="1" SDNUM="3081;">
-						<P ALIGN=CENTER>1</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="1" SDNUM="3081;">
-						<P ALIGN=CENTER>1</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="1" SDNUM="3081;">
-						<P ALIGN=CENTER>1</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="1" SDNUM="3081;">
-						<P ALIGN=CENTER>1</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="1" SDNUM="3081;">
-						<P ALIGN=CENTER>1</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="2" SDNUM="3081;">
-						<P ALIGN=CENTER>2</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="3" SDNUM="3081;">
-						<P ALIGN=CENTER>3</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="4" SDNUM="3081;">
-						<P ALIGN=CENTER>4</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="4" SDNUM="3081;">
-						<P ALIGN=CENTER>4</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="5" SDNUM="3081;">
-						<P ALIGN=CENTER>5</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="5" SDNUM="3081;">
-						<P ALIGN=CENTER>5</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="5" SDNUM="3081;">
-						<P ALIGN=CENTER>5</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>Background NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="6" SDNUM="3081;">
-						<P ALIGN=CENTER>6</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="6" SDNUM="3081;">
-						<P ALIGN=CENTER>6</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="6" SDNUM="3081;">
-						<P ALIGN=CENTER>6</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>Background NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="7" SDNUM="3081;">
-						<P ALIGN=CENTER>7</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="7" SDNUM="3081;">
-						<P ALIGN=CENTER>7</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>Background NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="7" SDNUM="3081;">
-						<P ALIGN=CENTER>7</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>Foreground NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="8" SDNUM="3081;">
-						<P ALIGN=CENTER>8</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="8" SDNUM="3081;">
-						<P ALIGN=CENTER>8</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="8" SDNUM="3081;">
-						<P ALIGN=CENTER>8</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>Foreground NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="8" SDNUM="3081;">
-						<P ALIGN=CENTER>8</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="9" SDNUM="3081;">
-						<P ALIGN=CENTER>9</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="9" SDNUM="3081;">
-						<P ALIGN=CENTER>9</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>Foreground NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="9" SDNUM="3081;">
-						<P ALIGN=CENTER>9</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="10" SDNUM="3081;">
-						<P ALIGN=CENTER>10</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>Foreground NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="10" SDNUM="3081;">
-						<P ALIGN=CENTER>10</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="11" SDNUM="3081;">
-						<P ALIGN=CENTER>11</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>Foreground NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="11" SDNUM="3081;">
-						<P ALIGN=CENTER>11</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="11" SDNUM="3081;">
-						<P ALIGN=CENTER>11</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="12" SDNUM="3081;">
-						<P ALIGN=CENTER>12</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="12" SDNUM="3081;">
-						<P ALIGN=CENTER>12</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="13" SDNUM="3081;">
-						<P ALIGN=CENTER>13</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="14" SDNUM="3081;">
-						<P ALIGN=CENTER>14</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
-						<P ALIGN=CENTER>15</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
-						<P ALIGN=CENTER>15</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
-						<P ALIGN=CENTER>15</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
-						<P ALIGN=CENTER>15</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
-						<P ALIGN=CENTER>15</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
-						<P ALIGN=CENTER>15</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="16" SDNUM="3081;">
-						<P ALIGN=CENTER>16</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="17" SDNUM="3081;">
-						<P ALIGN=CENTER>17</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=BOTTOM SDVAL="-7" SDNUM="3081;">
-						<P ALIGN=LEFT>-7</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="18" SDNUM="3081;">
-						<P ALIGN=CENTER>18</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=BOTTOM SDVAL="-6" SDNUM="3081;">
-						<P ALIGN=LEFT>-6</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="19" SDNUM="3081;">
-						<P ALIGN=CENTER>19</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=BOTTOM SDVAL="-5" SDNUM="3081;">
-						<P ALIGN=LEFT>-5</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="20" SDNUM="3081;">
-						<P ALIGN=CENTER>20</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=BOTTOM SDVAL="-4" SDNUM="3081;">
-						<P ALIGN=LEFT>-4</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="21" SDNUM="3081;">
-						<P ALIGN=CENTER>21</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=BOTTOM SDVAL="-3" SDNUM="3081;">
-						<P ALIGN=LEFT>-3</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="22" SDNUM="3081;">
-						<P ALIGN=CENTER>22</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="23" SDNUM="3081;">
-						<P ALIGN=CENTER>23</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="24" SDNUM="3081;">
-						<P ALIGN=CENTER>24</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="25" SDNUM="3081;">
-						<P ALIGN=CENTER>25</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="26" SDNUM="3081;">
-						<P ALIGN=CENTER>26</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="27" SDNUM="3081;">
-						<P ALIGN=CENTER>27</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=BOTTOM SDVAL="3" SDNUM="3081;">
-						<P ALIGN=LEFT>3</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="28" SDNUM="3081;">
-						<P ALIGN=CENTER>28</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=BOTTOM SDVAL="4" SDNUM="3081;">
-						<P ALIGN=LEFT>4</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="29" SDNUM="3081;">
-						<P ALIGN=CENTER>29</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=BOTTOM SDVAL="5" SDNUM="3081;">
-						<P ALIGN=LEFT>5</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="30" SDNUM="3081;">
-						<P ALIGN=CENTER>30</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=BOTTOM SDVAL="6" SDNUM="3081;">
-						<P ALIGN=LEFT>6</P>
-					</TD>
-				</TR>
-				<TR>
-					<TD WIDTH=50 VALIGN=BOTTOM SDVAL="31" SDNUM="3081;">
-						<P ALIGN=CENTER>31</P>
-					</TD>
-					<TD WIDTH=356 VALIGN=TOP>
-						<P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
-					</TD>
-					<TD WIDTH=336 VALIGN=TOP>
-						<P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
-					</TD>
-				</TR>
-			</TBODY>
-		</TABLE>
-	</DL>
-</DL>
-<P STYLE="margin-left: 2cm">Windows NT: Values -7, -6, -5, -4, -3, 3,
-4, 5, and 6 are not supported.</P>
-<P STYLE="margin-left: 2cm">As you can see, the real priority levels
-available to any individual Win32 thread are non-contiguous.</P>
-<P STYLE="margin-left: 2cm">An application using Pthreads-w32 should
-not make assumptions about the numbers used to represent thread
-priority levels, except that they are monotonic between the values
-returned by sched_get_priority_min() and sched_get_priority_max().
-E.g. Windows 95, 98, NT, 2000, XP make available a non-contiguous
-range of numbers between -15 and 15, while at least one version of
-WinCE (3.0) defines the minimum priority (THREAD_PRIORITY_LOWEST) as
-5, and the maximum priority (THREAD_PRIORITY_HIGHEST) as 1.</P>
-<P STYLE="margin-left: 2cm">Internally, pthreads-win32 maps any
-priority levels between THREAD_PRIORITY_IDLE and
-THREAD_PRIORITY_LOWEST to THREAD_PRIORITY_LOWEST, or between
-THREAD_PRIORITY_TIME_CRITICAL and THREAD_PRIORITY_HIGHEST to
-THREAD_PRIORITY_HIGHEST. Currently, this also applies to
-REALTIME_PRIORITY_CLASS even if levels -7, -6, -5, -4, -3, 3, 4, 5,
-and 6 are supported.</P>
-<P STYLE="margin-left: 2cm">If it wishes, a Win32 application using
-pthreads-w32 can use the Win32 defined priority macros
-THREAD_PRIORITY_IDLE through THREAD_PRIORITY_TIME_CRITICAL.</P>
-<H2><A HREF="#toc3" NAME="sect3">Author</A></H2>
-<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc4" NAME="sect4">See also</A></H2>
-<P><BR><BR>
-</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Author</A>
-		</P>
-	<LI><P><A HREF="#sect4" NAME="toc4">See also</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/index.html b/deps/w32-pthreads/manual/index.html
deleted file mode 100644
index f7b5bc9..0000000
--- a/deps/w32-pthreads/manual/index.html
+++ /dev/null
@@ -1,158 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE></TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;17350500">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<META NAME="CHANGED" CONTENT="20110326;18352700">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<STYLE TYPE="text/css">
-	<!--
-		H4.cjk { font-family: "AR PL UMing CN" }
-		H4.ctl { font-family: "Lohit Devanagari" }
-		H3.cjk { font-family: "AR PL UMing CN" }
-		H3.ctl { font-family: "Lohit Devanagari" }
-		H2.cjk { font-family: "AR PL UMing CN" }
-		H2.ctl { font-family: "Lohit Devanagari" }
-	-->
-	</STYLE>
-</HEAD>
-<BODY LANG="en-GB" DIR="LTR">
-<H4 CLASS="western">POSIX Threads for Windows – REFERENCE -
-<A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<H3 CLASS="western">Table of Contents</H3>
-<P STYLE="margin-left: 0.79in"><A HREF="#sect1" NAME="toc1">POSIX
-threads API reference</A><BR><A HREF="#sect2" NAME="toc2">Miscellaneous
-POSIX thread safe routines provided by Pthreads-w32</A><BR><A HREF="#sect3" NAME="toc3">Non-portable
-Pthreads-w32 routines</A><BR><A HREF="#sect4" NAME="toc4">Other</A></P>
-<H2 CLASS="western"><A HREF="#toc1" NAME="sect1">POSIX threads API
-reference</A></H2>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_destroy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_getdetachstate</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_getinheritsched</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_getschedparam</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_getschedpolicy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_getscope</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_setstackaddr.html"><B>pthread_attr_getstackaddr</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_setstacksize.html"><B>pthread_attr_getstacksize</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_init</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_setdetachstate</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_setinheritsched</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_setschedparam</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_setschedpolicy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_init.html"><B>pthread_attr_setscope</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_setstackaddr.html"><B>pthread_attr_setstackaddr</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_attr_setstacksize.html"><B>pthread_attr_setstacksize</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_barrierattr_init.html"><B>pthread_barrierattr_destroy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_barrierattr_setpshared.html"><B>pthread_barrierattr_getpshared</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_barrierattr_init.html"><B>pthread_barrierattr_init</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_barrierattr_setpshared.html"><B>pthread_barrierattr_setpshared</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_barrier_init.html"><B>pthread_barrier_destroy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_barrier_init.html"><B>pthread_barrier_init</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cancel.html"><B>pthread_cancel</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_pop</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_push</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_condattr_init.html"><B>pthread_condattr_destroy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_condattr_setpshared.html"><B>pthread_condattr_getpshared</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_condattr_init.html"><B>pthread_condattr_init</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_condattr_setpshared.html"><B>pthread_condattr_setpshared</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cond_init.html"><B>pthread_cond_broadcast</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cond_init.html"><B>pthread_cond_destroy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cond_init.html"><B>pthread_cond_init</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cond_init.html"><B>pthread_cond_signal</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cond_init.html"><B>pthread_cond_timedwait</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cond_init.html"><B>pthread_cond_wait</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_create.html"><B>pthread_create</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_detach.html"><B>pthread_detach</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_equal.html"><B>pthread_equal</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_exit.html"><B>pthread_exit</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_setconcurrency.html"><B>pthread_getconcurrency</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_setschedparam.html"><B>pthread_getschedparam</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_getunique_np.html"><B>pthread_getunique_np</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_key_create.html"><B>pthread_getspecific</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_join.html"><B>pthread_join</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_key_create.html"><B>pthread_key_create</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_key_create.html"><B>pthread_key_delete</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_kill.html"><B>pthread_kill</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_destroy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_getkind_np</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutexattr_setpshared.html"><B>pthread_mutexattr_getpshared</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_getrobust</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_gettype</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_init</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_setkind_np</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutexattr_setpshared.html"><B>pthread_mutexattr_setpshared</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_setrobust</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_settype</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_consistent</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_destroy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_init</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_lock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_timedlock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_trylock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_unlock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_once.html"><B>pthread_once</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlockattr_init.html"><B>pthread_rwlockattr_destroy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlockattr_setpshared.html"><B>pthread_rwlockattr_getpshared</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlockattr_init.html"><B>pthread_rwlockattr_init</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlockattr_setpshared.html"><B>pthread_rwlockattr_setpshared</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_init</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_self.html"><B>pthread_self</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cancel.html"><B>pthread_setcancelstate</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cancel.html"><B>pthread_setcanceltype</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_setconcurrency.html"><B>pthread_setconcurrency</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_setschedparam.html"><B>pthread_setschedparam</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_key_create.html"><B>pthread_setspecific</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_kill.html"><B>pthread_sigmask</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_spin_init.html"><B>pthread_spin_destroy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_spin_init.html"><B>pthread_spin_init</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_spin_lock.html"><B>pthread_spin_trylock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_spin_unlock.html"><B>pthread_spin_unlock</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_cancel.html"><B>pthread_testcancel</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sched_get_priority_max.html"><B>sched_get_priority_max</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sched_get_priority_max.html"><B>sched_get_priority_min</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sched_getscheduler.html"><B>sched_getscheduler</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sched_setscheduler.html"><B>sched_setscheduler</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sched_yield.html"><B>sched_yield</B></A></P>
-<P STYLE="margin-left: 0.79in"><B>sem_close</B></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sem_init.html"><B>sem_destroy</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sem_init.html"><B>sem_getvalue</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sem_init.html"><B>sem_init</B></A></P>
-<P STYLE="margin-left: 0.79in"><B>sem_open</B></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sem_init.html"><B>sem_post</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sem_init.html"><B>sem_post_multiple</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sem_init.html"><B>sem_timedwait</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sem_init.html"><B>sem_trywait</B></A></P>
-<P STYLE="margin-left: 0.79in"><B>sem_unlink</B></P>
-<P STYLE="margin-left: 0.79in"><A HREF="sem_init.html"><B>sem_wait</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_kill.html"><B>sigwait</B></A></P>
-<H2 CLASS="western"><A HREF="#toc3" NAME="sect3">Non-portable
-Pthreads-w32 routines</A></H2>
-<P STYLE="margin-left: 0.79in"><A HREF="pthreadCancelableWait.html"><B>pthreadCancelableTimedWait</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthreadCancelableWait.html"><B>pthreadCancelableWait</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_delay_np.html"><B>pthread_delay_np</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_getw32threadhandle_np.html"><B>pthread_getw32threadhandle_np</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_num_processors_np.html"><B>pthread_num_processors_np</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_win32_test_features_np.html"><B>pthread_win32_test_features_np</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_timechange_handler_np.html"><B>pthread_timechange_handler_np</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_win32_attach_detach_np.html"><B>pthread_win32_process_attach_np</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_win32_attach_detach_np.html"><B>pthread_win32_process_detach_np</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_win32_attach_detach_np.html"><B>pthread_win32_thread_attach_np</B></A></P>
-<P STYLE="margin-left: 0.79in"><A HREF="pthread_win32_attach_detach_np.html"><B>pthread_win32_thread_detach_np</B></A></P>
-<H2 CLASS="western"><A HREF="#toc4" NAME="sect4">Other</A></H2>
-<P STYLE="margin-left: 0.79in"><A HREF="PortabilityIssues.html"><B>Portability
-issues</B></A></P>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/pthreadCancelableWait.html b/deps/w32-pthreads/manual/pthreadCancelableWait.html
deleted file mode 100644
index 9d7c1a4..0000000
--- a/deps/w32-pthreads/manual/pthreadCancelableWait.html
+++ /dev/null
@@ -1,86 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREADCANCELLABLEWAIT manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;322600">
-	<META NAME="CHANGED" CONTENT="20050505;23242300">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P STYLE="font-weight: medium">pthreadCancelableTimedWait,
-pthreadCancelableWait – provide cancellation hooks for user Win32
-routines</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthreadCancelableTimedWait (HANDLE </B><I>waitHandle</I><B>,
-DWORD </B><I>timeout</I><B>);</B></P>
-<P><B>int pthreadCancelableWait (HANDLE </B><I>waitHandle</I><B>);</B></P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>These two functions provide hooks into the <A HREF="pthread_cancel.html"><B>pthread_cancel</B></A>()
-mechanism that will allow you to wait on a Windows handle and make it
-a cancellation point. Both functions block until either the given
-Win32 <B>HANDLE</B> is signalled, or <A HREF="pthread_cancel.html"><B>pthread_cancel</B></A>()
-has been called. They are implemented using <B>WaitForMultipleObjects</B>
-on <I>waitHandle</I> and the manually reset Win32 event handle that
-is the target of <A HREF="pthread_cancel.html"><B>pthread_cancel</B></A>().
-These routines may be called from Win32 native threads but
-<A HREF="pthread_cancel.html"><B>pthread_cancel</B></A>() will
-require that thread's POSIX thread ID that the thread must retrieve
-using <A HREF="pthread_self.html"><B>pthread_self</B></A>().</P>
-<P><B>pthreadCancelableTimedWait</B> is the timed version that will
-return with the code <B>ETIMEDOUT</B> if the interval <I>timeout</I>
-milliseconds elapses before <I>waitHandle</I> is signalled.</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P>These routines allow routines that block on Win32 HANDLEs to be
-cancellable via <A HREF="pthread_cancel.html"><B>pthread_cancel</B></A>().</P>
-<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
-<P><BR><BR>
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
-<P>The <B>pthreadCancelableTimedWait</B> function returns the
-following error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ETIMEDOUT</B>
-				</DT></DL>
-</DL>
-<P STYLE="margin-left: 2cm">
-The interval <I>timeout</I> milliseconds elapsed before <I>waitHandle</I>
-was signalled.</P>
-<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
-<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc7" NAME="sect7">See also</A></H2>
-<P><A HREF="pthread_cancel.html"><B>pthread_cancel()</B></A>,
-<A HREF="pthread_self.html"><B>pthread_self()</B></A></P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4"></A><A HREF="#sect4" NAME="toc4">Return
-	Value</A><A HREF="#sect4" NAME="toc4"></A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Author</A>
-		</P>
-	<LI><P><A HREF="#sect7" NAME="toc7">See also</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_attr_init.html b/deps/w32-pthreads/manual/pthread_attr_init.html
deleted file mode 100644
index fa5ab58..0000000
--- a/deps/w32-pthreads/manual/pthread_attr_init.html
+++ /dev/null
@@ -1,280 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_ATTR_INIT(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;10092900">
-	<META NAME="CHANGED" CONTENT="20050505;16540200">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_attr_init, pthread_attr_destroy,
-pthread_attr_setdetachstate, pthread_attr_getdetachstate,
-pthread_attr_setschedparam, pthread_attr_getschedparam,
-pthread_attr_setschedpolicy, pthread_attr_getschedpolicy,
-pthread_attr_setinheritsched, pthread_attr_getinheritsched,
-pthread_attr_setscope, pthread_attr_getscope - thread creation
-attributes 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_attr_init(pthread_attr_t *</B><I>attr</I><B>);</B> 
-</P>
-<P><B>int pthread_attr_destroy(pthread_attr_t *</B><I>attr</I><B>);</B>
-</P>
-<P><B>int pthread_attr_setdetachstate(pthread_attr_t *</B><I>attr</I><B>,
-int </B><I>detachstate</I><B>);</B> 
-</P>
-<P><B>int pthread_attr_getdetachstate(const pthread_attr_t *</B><I>attr</I><B>,
-int *</B><I>detachstate</I><B>);</B> 
-</P>
-<P><B>int pthread_attr_setschedpolicy(pthread_attr_t *</B><I>attr</I><B>,
-int </B><I>policy</I><B>);</B> 
-</P>
-<P><B>int pthread_attr_getschedpolicy(const pthread_attr_t *</B><I>attr</I><B>,
-int *</B><I>policy</I><B>);</B> 
-</P>
-<P><B>int pthread_attr_setschedparam(pthread_attr_t *</B><I>attr</I><B>,
-const struct sched_param *</B><I>param</I><B>);</B> 
-</P>
-<P><B>int pthread_attr_getschedparam(const pthread_attr_t *</B><I>attr</I><B>,
-struct sched_param *</B><I>param</I><B>);</B> 
-</P>
-<P><B>int pthread_attr_setinheritsched(pthread_attr_t *</B><I>attr</I><B>,
-int </B><I>inherit</I><B>);</B> 
-</P>
-<P><B>int pthread_attr_getinheritsched(const pthread_attr_t *</B><I>attr</I><B>,
-int *</B><I>inherit</I><B>);</B> 
-</P>
-<P><B>int pthread_attr_setscope(pthread_attr_t *</B><I>attr</I><B>,
-int </B><I>scope</I><B>);</B> 
-</P>
-<P><B>int pthread_attr_getscope(const pthread_attr_t *</B><I>attr</I><B>,
-int *</B><I>scope</I><B>);</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Setting attributes for threads is achieved by filling a thread
-attribute object <I>attr</I> of type <B>pthread_attr_t</B>, then
-passing it as second argument to <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
-. Passing <B>NULL</B> is equivalent to passing a thread attribute
-object with all attributes set to their default values. 
-</P>
-<P><B>pthread_attr_init</B> initializes the thread attribute object
-<I>attr</I> and fills it with default values for the attributes. (The
-default values are listed below for each attribute.) 
-</P>
-<P>Each attribute <I>attrname</I> (see below for a list of all
-attributes) can be individually set using the function
-<B>pthread_attr_set</B><I>attrname</I> and retrieved using the
-function <B>pthread_attr_get</B><I>attrname.</I> 
-</P>
-<P><B>pthread_attr_destroy</B> destroys a thread attribute object,
-which must not then be reused until it is reinitialized. 
-</P>
-<P>Attribute objects are consulted only when creating a new thread.
-The same attribute object can be used for creating several threads.
-Modifying an attribute object after a call to <B>pthread_create</B>
-does not change the attributes of the thread previously created. 
-</P>
-<P>The following thread attributes are supported: 
-</P>
-<H3><A HREF="#toc3" NAME="sect3">detachstate</A></H3>
-<P>Control whether the thread is created in the joinable state (value
-<B>PTHREAD_CREATE_JOINABLE</B>) or in the detached state (
-<B>PTHREAD_CREATE_DETACHED</B>). 
-</P>
-<P>Default value: <B>PTHREAD_CREATE_JOINABLE</B>. 
-</P>
-<P>In the joinable state, another thread can synchronize on the
-thread termination and recover its termination code using
-<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> . When a
-joinable thread terminates, some of the thread resources are kept
-allocated, and released only when another thread performs
-<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> on that
-thread. 
-</P>
-<P>In the detached state, the thread's resources are released
-immediately when it terminates. <A HREF="pthread_join.html"><B>pthread_join</B>(3)</A>
-cannot be used to synchronize on the thread termination. 
-</P>
-<P>A thread created in the joinable state can later be put in the
-detached thread using <A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A>
-. 
-</P>
-<H3><A HREF="#toc4" NAME="sect4">schedpolicy</A></H3>
-<P>Select the scheduling policy for the thread: one of <B>SCHED_OTHER</B>
-(regular, non-real-time scheduling), <B>SCHED_RR</B> (real-time,
-round-robin) or <B>SCHED_FIFO</B> (real-time, first-in first-out). 
-</P>
-<P><B>Pthreads-w32</B> only supports <B>SCHED_OTHER</B> - attempting
-to set one of the other policies will return an error ENOTSUP.</P>
-<P>Default value: <B>SCHED_OTHER</B>. 
-</P>
-<P><B>Pthreads-w32</B> only supports <B>SCHED_OTHER</B> - attempting
-to set one of the other policies will return an error ENOTSUP.</P>
-<P>The scheduling policy of a thread can be changed after creation
-with <A HREF="pthread_setschedparam.html"><B>pthread_setschedparam</B>(3)</A>
-. 
-</P>
-<H3><A HREF="#toc5" NAME="sect5">schedparam</A></H3>
-<P>Contain the scheduling parameters (essentially, the scheduling
-priority) for the thread.</P>
-<P><B>Pthreads-w32</B> supports the priority levels defined by the
-Windows system it is running on. Under Windows, thread priorities are
-relative to the process priority class, which must be set via the
-Windows W32 API.</P>
-<P>Default value: priority is 0 (Win32 level <B>THREAD_PRIORITY_NORMAL</B>).
-</P>
-<P>The scheduling priority of a thread can be changed after creation
-with <A HREF="pthread_setschedparam.html"><B>pthread_setschedparam</B>(3)</A>
-. 
-</P>
-<H3><A HREF="#toc6" NAME="sect6">inheritsched</A></H3>
-<P>Indicate whether the scheduling policy and scheduling parameters
-for the newly created thread are determined by the values of the
-<I>schedpolicy</I> and <I>schedparam</I> attributes (value
-<B>PTHREAD_EXPLICIT_SCHED</B>) or are inherited from the parent
-thread (value <B>PTHREAD_INHERIT_SCHED</B>). 
-</P>
-<P>Default value: <B>PTHREAD_EXPLICIT_SCHED</B>. 
-</P>
-<H3><A HREF="#toc7" NAME="sect7">scope</A></H3>
-<P>Define the scheduling contention scope for the created thread. The
-only value supported in the <B>Pthreads-w32</B> implementation is
-<B>PTHREAD_SCOPE_SYSTEM</B>, meaning that the threads contend for CPU
-time with all processes running on the machine. The other value
-specified by the standard, <B>PTHREAD_SCOPE_PROCESS</B>, means that
-scheduling contention occurs only between the threads of the running
-process.</P>
-<P><B>Pthreads-w32</B> only supports <B>PTHREAD_SCOPE_SYSTEM</B>.</P>
-<P>Default value: <B>PTHREAD_SCOPE_SYSTEM</B>. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Return Value</A></H2>
-<P>All functions return 0 on success and a non-zero error code on
-error. On success, the <B>pthread_attr_get</B><I>attrname</I>
-functions also store the current value of the attribute <I>attrname</I>
-in the location pointed to by their second argument. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">Errors</A></H2>
-<P>The <B>pthread_attr_setdetachstate</B> function returns the
-following error codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the specified <I>detachstate</I> is not one of
-		<B>PTHREAD_CREATE_JOINABLE</B> or <B>PTHREAD_CREATE_DETACHED</B>. 
-		</DD></DL>
-</DL>
-<P>
-The <B>pthread_attr_setschedparam</B> function returns the following
-error codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the priority specified in <I>param</I> is outside the range of
-		allowed priorities for the scheduling policy currently in <I>attr</I>
-		(1 to 99 for <B>SCHED_FIFO</B> and <B>SCHED_RR</B>; 0 for
-		<B>SCHED_OTHER</B>). 
-		</DD></DL>
-</DL>
-<P>
-The <B>pthread_attr_setschedpolicy</B> function returns the following
-error codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the specified <I>policy</I> is not one of <B>SCHED_OTHER</B>,
-		<B>SCHED_FIFO</B>, or <B>SCHED_RR</B>. 
-		</DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<B>ENOTSUP</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<I>policy</I> is not <B>SCHED_OTHER</B>, the only value supported
-		by <B>Pthreads-w32</B>.</DD></DL>
-</DL>
-<P>
-The <B>pthread_attr_setinheritsched</B> function returns the
-following error codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the specified <I>inherit</I> is not one of <B>PTHREAD_INHERIT_SCHED</B>
-		or <B>PTHREAD_EXPLICIT_SCHED</B>. 
-		</DD></DL>
-</DL>
-<P>
-The <B>pthread_attr_setscope</B> function returns the following error
-codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the specified <I>scope</I> is not one of <B>PTHREAD_SCOPE_SYSTEM</B>
-		or <B>PTHREAD_SCOPE_PROCESS</B>. 
-		</DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<B>ENOTSUP</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the specified <I>scope</I> is <B>PTHREAD_SCOPE_PROCESS</B> (not
-		supported by <B>Pthreads-w32</B>). 
-		</DD></DL>
-</DL>
-<H2>
-<A HREF="#toc10" NAME="sect10">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc11" NAME="sect11">See Also</A></H2>
-<P><A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> ,
-<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> ,
-<A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A> ,
-<A HREF="pthread_setschedparam.html"><B>pthread_setschedparam</B>(3)</A>
-. 
-</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<UL>
-		<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">detachstate</A>
-				</P>
-		<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">schedpolicy</A>
-				</P>
-		<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">schedparam</A>
-				</P>
-		<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">inheritsched</A>
-				</P>
-		<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">scope</A>
-				</P>
-	</UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect10" NAME="toc10">Author</A>
-		</P>
-	<LI><P><A HREF="#sect11" NAME="toc11">See Also</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_attr_setstackaddr.html b/deps/w32-pthreads/manual/pthread_attr_setstackaddr.html
deleted file mode 100644
index 868832c..0000000
--- a/deps/w32-pthreads/manual/pthread_attr_setstackaddr.html
+++ /dev/null
@@ -1,158 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_ATTR_GETSTACKADDR"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;11025500">
-	<META NAME="CHANGED" CONTENT="20050505;17571400">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_attr_getstackaddr, pthread_attr_setstackaddr - get and set
-the stackaddr attribute 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_attr_getstackaddr(const pthread_attr_t *restrict</B>
-<I>attr</I><B>, void **restrict</B> <I>stackaddr</I><B>); <BR>int
-pthread_attr_setstackaddr(pthread_attr_t *</B><I>attr</I><B>, void
-*</B><I>stackaddr</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_attr_getstackaddr</B> and <B>pthread_attr_setstackaddr</B>
-functions, respectively, shall get and set the thread creation
-<I>stackaddr</I> attribute in the <I>attr</I> object. 
-</P>
-<P>The <I>stackaddr</I> attribute specifies the location of storage
-to be used for the created thread’s stack. The size of the storage
-shall be at least {PTHREAD_STACK_MIN}. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_ATTR_STACKADDR</B> in
-pthread.h as -1 to indicate that these routines are implemented but
-cannot used to set or get the stack address. These routines always
-return the error ENOSYS when called.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>Upon successful completion, <B>pthread_attr_getstackaddr</B> and
-<B>pthread_attr_setstackaddr</B> shall return a value of 0;
-otherwise, an error number shall be returned to indicate the error. 
-</P>
-<P>The <B>pthread_attr_getstackaddr</B> function stores the <I>stackaddr</I>
-attribute value in <I>stackaddr</I> if successful. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_attr_setstackaddr</B> function always returns the
-following error code: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ENOSYS</B></DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		The function is not supported. 
-		</DD></DL>
-</DL>
-<P>
-The <B>pthread_attr_getstackaddr</B> function always returns the
-following error code: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ENOSYS</B></DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		The function is not supported. 
-		</DD></DL>
-</DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>The specification of the <I>stackaddr</I> attribute presents
-several ambiguities that make portable use of these interfaces
-impossible. The description of the single address parameter as a
-"stack" does not specify a particular relationship between
-the address and the "stack" implied by that address. For
-example, the address may be taken as the low memory address of a
-buffer intended for use as a stack, or it may be taken as the address
-to be used as the initial stack pointer register value for the new
-thread. These two are not the same except for a machine on which the
-stack grows "up" from low memory to high, and on which a
-"push" operation first stores the value in memory and then
-increments the stack pointer register. Further, on a machine where
-the stack grows "down" from high memory to low,
-interpretation of the address as the "low memory" address
-requires a determination of the intended size of the stack.
-IEEE Std 1003.1-2001 has introduced the new interfaces
-<A HREF="pthread_attr_setstack.html"><B>pthread_attr_setstack</B>(3)</A>
-and <A HREF="pthread_attr_getstack.html"><B>pthread_attr_getstack</B>(3)</A>
-to resolve these ambiguities. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_attr_init.html"><B>pthread_attr_destroy</B>(3)</A>
-, <A HREF="pthread_attr_init.html"><B>pthread_attr_getdetachstate</B>(3)</A>
-, <A HREF="pthread_attr_getstack.html"><B>pthread_attr_getstack</B>(3)</A>
-, <A HREF="pthread_attr_getstacksize.html"><B>pthread_attr_getstacksize</B>(3)</A>
-, <A HREF="pthread_attr_setstack.html"><B>pthread_attr_setstack</B>(3)</A>
-, <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> , the
-Base Definitions volume of IEEE Std 1003.1-2001,
-<I><limits.h></I>, <I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_attr_setstacksize.html b/deps/w32-pthreads/manual/pthread_attr_setstacksize.html
deleted file mode 100644
index ae9d031..0000000
--- a/deps/w32-pthreads/manual/pthread_attr_setstacksize.html
+++ /dev/null
@@ -1,127 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_ATTR_GETSTACKSIZE"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;11224900">
-	<META NAME="CHANGED" CONTENT="20050505;18003200">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_attr_getstacksize, pthread_attr_setstacksize - get and set
-the stacksize attribute 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_attr_getstacksize(const pthread_attr_t *restrict</B>
-<I>attr</I><B>, size_t *restrict</B> <I>stacksize</I><B>); <BR>int
-pthread_attr_setstacksize(pthread_attr_t *</B><I>attr</I><B>, size_t</B>
-<I>stacksize</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_attr_getstacksize</B> and <B>pthread_attr_setstacksize</B>
-functions, respectively, shall get and set the thread creation
-<I>stacksize</I> attribute in the <I>attr</I> object. 
-</P>
-<P>The <I>stacksize</I> attribute shall define the minimum stack size
-(in bytes) allocated for the created threads stack. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_ATTR_STACKSIZE</B> in
-pthread.h to indicate that these routines are implemented and may be
-used to set or get the stack size.</P>
-<P>Default value: 0 (in Pthreads-w32 a value of 0 means the stack
-will grow as required)</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>Upon successful completion, <B>pthread_attr_getstacksize</B> and
-<B>pthread_attr_setstacksize</B> shall return a value of 0;
-otherwise, an error number shall be returned to indicate the error. 
-</P>
-<P>The <B>pthread_attr_getstacksize</B> function stores the <I>stacksize</I>
-attribute value in <I>stacksize</I> if successful. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_attr_setstacksize</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value of <I>stacksize</I> is less than {PTHREAD_STACK_MIN} or
-	exceeds a system-imposed limit. 
-	</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_attr_init.html"><B>pthread_attr_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_attr_setstackaddr.html"><B>pthread_attr_getstackaddr</B>(3)</A>
-<B>,</B> <A HREF="pthread_attr_init.html"><B>pthread_attr_getdetachstate</B>(3)</A>
-<B>,</B> <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> <B>,</B>
-the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><limits.h></I>, <I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_barrier_init.html b/deps/w32-pthreads/manual/pthread_barrier_init.html
deleted file mode 100644
index f581358..0000000
--- a/deps/w32-pthreads/manual/pthread_barrier_init.html
+++ /dev/null
@@ -1,197 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_BARRIER_DESTROY"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 2.0  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;11372800">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<META NAME="CHANGED" CONTENT="20060408;9450100">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_barrier_destroy, pthread_barrier_init - destroy and
-initialize a barrier object (<B>ADVANCED REALTIME THREADS</B>) 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_barrier_destroy(pthread_barrier_t *</B><I>barrier</I><B>);
-<BR>int pthread_barrier_init(pthread_barrier_t *restrict</B> <I>barrier</I><B>,
-const pthread_barrierattr_t *restrict</B> <I>attr</I><B>, unsigned</B>
-<I>count</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_barrier_destroy</B> function shall destroy the
-barrier referenced by <I>barrier</I> and release any resources used
-by the barrier. The effect of subsequent use of the barrier is
-undefined until the barrier is reinitialized by another call to
-<B>pthread_barrier_init</B> . An implementation may use this function
-to set <I>barrier</I> to an invalid value. An error code is returned if <B>pthread_barrier_destroy</B> is called when any thread is
-blocked on the barrier, or if this function is called with an
-uninitialized barrier. 
-</P>
-<P>The <B>pthread_barrier_init</B> function shall allocate any
-resources required to use the barrier referenced by <I>barrier</I>
-and shall initialize the barrier with attributes referenced by <I>attr</I>.
-If <I>attr</I> is NULL, the default barrier attributes shall be used;
-the effect is the same as passing the address of a default barrier
-attributes object. The results are undefined if <B>pthread_barrier_init</B>
-is called when any thread is blocked on the barrier (that is, has not
-returned from the <A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
-call). The results are undefined if a barrier is used without first
-being initialized. The results are undefined if <B>pthread_barrier_init</B>
-is called specifying an already initialized barrier. 
-</P>
-<P>The <I>count</I> argument specifies the number of threads that
-must call <A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
-before any of them successfully return from the call. The value
-specified by <I>count</I> must be greater than zero. 
-</P>
-<P>If the <B>pthread_barrier_init</B> function fails, the barrier
-shall not be initialized and the contents of <I>barrier</I> are
-undefined. 
-</P>
-<P>Only the object referenced by <I>barrier</I> may be used for
-performing synchronization. The result of referring to copies of that
-object in calls to <B>pthread_barrier_destroy</B> <B>or</B>
-<A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
-is undefined.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>Upon successful completion, these functions shall return zero;
-otherwise, an error number shall be returned to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_barrier_destroy</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EBUSY</B> 
-	</DT><DD>
-	The implementation has detected an attempt to destroy a barrier
-	while it is in use (for example, while being used in a
-	<A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
-	call) by another thread. 
-	</DD><DT>
-	<B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>barrier</I> is invalid. 
-	</DD></DL>
-<P>
-The <B>pthread_barrier_init</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>EAGAIN</B> 
-	</DT><DD>
-	The system lacks the necessary resources to initialize another
-	barrier. 
-	</DD><DT>
-	<B>EINVAL</B> 
-	</DT><DD>
-	The value specified by <I>count</I> is equal to zero. 
-	</DD><DT>
-	<B>ENOMEM</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	Insufficient memory exists to initialize the barrier. 
-	</DD></DL>
-<P>
-The <B>pthread_barrier_init</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EBUSY</B> 
-	</DT><DD>
-	The implementation has detected an attempt to reinitialize a barrier
-	while it is in use (for example, while being used in a
-	<A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
-	call) by another thread. 
-	</DD><DT>
-	<B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>attr</I> is invalid. 
-	</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>The <B>pthread_barrier_destroy</B> and <B>pthread_barrier_init</B>
-functions are part of the Barriers option and need not be provided on
-all implementations. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_BARRIERS</B> to indicate
-that these routines are implemented and may be used.</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc11" NAME="sect11">Known Bugs</A></H2>
-<DL>
-	<DD STYLE="margin-left: 0cm; margin-bottom: 0.5cm">In
-	<B><SPAN LANG="en-GB"><SPAN LANG="en-GB">pthreads-win32</SPAN></SPAN></B>,
-	the behaviour of threads which enter <A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
-	while the barrier is being destroyed is undefined. 
-	</DD></DL>
-<H2>
-<A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect11" NAME="toc11">Known
-	Bugs</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/pthread_barrier_wait.html b/deps/w32-pthreads/manual/pthread_barrier_wait.html
deleted file mode 100644
index f407aa5..0000000
--- a/deps/w32-pthreads/manual/pthread_barrier_wait.html
+++ /dev/null
@@ -1,161 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_BARRIER_WAIT"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 2.0  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;11484200">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<META NAME="CHANGED" CONTENT="20060408;9504600">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_barrier_wait - synchronize at a barrier (<B>ADVANCED
-REALTIME THREADS</B>) 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_barrier_wait(pthread_barrier_t *</B><I>barrier</I><B>);
-</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_barrier_wait</B> function shall synchronize
-participating threads at the barrier referenced by <I>barrier</I>.
-The calling thread shall block until the required number of threads
-have called <B>pthread_barrier_wait</B> specifying the barrier. 
-</P>
-<P>When the required number of threads have called
-<B>pthread_barrier_wait</B> specifying the barrier, the constant
-<B>PTHREAD_BARRIER_SERIAL_THREAD</B> shall be returned to one
-unspecified thread and zero shall be returned to each of the
-remaining threads. At this point, the barrier shall be reset to the
-state it had as a result of the most recent <A HREF="pthread_barrier_init.html"><B>pthread_barrier_init</B>(3)</A>
-function that referenced it. 
-</P>
-<P>The constant <B>PTHREAD_BARRIER_SERIAL_THREAD</B> is defined in
-<I><pthread.h></I> and its value shall be distinct from any
-other value returned by <B>pthread_barrier_wait</B> . 
-</P>
-<P>The results are undefined if this function is called with an
-uninitialized barrier. 
-</P>
-<P>If a signal is delivered to a thread blocked on a barrier, upon
-return from the signal handler the thread shall resume waiting at the
-barrier if the barrier wait has not completed (that is, if the
-required number of threads have not arrived at the barrier during the
-execution of the signal handler); otherwise, the thread shall
-continue as normal from the completed barrier wait. Until the thread
-in the signal handler returns from it, it is unspecified whether
-other threads may proceed past the barrier once they have all reached
-it. 
-</P>
-<P>A thread that has blocked on a barrier shall not prevent any
-unblocked thread that is eligible to use the same processing
-resources from eventually making forward progress in its execution.
-Eligibility for processing resources shall be determined by the
-scheduling policy. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>Upon successful completion, the <B>pthread_barrier_wait</B>
-function shall return <B>PTHREAD_BARRIER_SERIAL_THREAD</B> for a
-single (arbitrary) thread synchronized at the barrier and zero for
-each of the other threads. Otherwise, an error number shall be
-returned to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_barrier_wait</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>barrier</I> does not refer to an
-	initialized barrier object. 
-	</DD></DL>
-<P>
-This function shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>Applications using this function may be subject to priority
-inversion, as discussed in the Base Definitions volume of
-IEEE Std 1003.1-2001, Section 3.285, Priority Inversion. 
-</P>
-<P>The <B>pthread_barrier_wait</B> function is part of the Barriers
-option and need not be provided on all implementations. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_BARRIERS</B> to indicate
-that this routine is implemented and may be used.</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc11" NAME="sect11">Known Bugs</A></H2>
-<DL>
-	None.</DL>
-<H2>
-<A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_barrier_init.html"><B>pthread_barrier_destroy</B>(3)</A>,
-<A HREF="pthread_barrier_init.html"><B>pthread_barrier_init(3)</B></A>,
-the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect11" NAME="toc11">Known
-	Bugs</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/pthread_barrierattr_init.html b/deps/w32-pthreads/manual/pthread_barrierattr_init.html
deleted file mode 100644
index a7c8027..0000000
--- a/deps/w32-pthreads/manual/pthread_barrierattr_init.html
+++ /dev/null
@@ -1,142 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_BARRIERATTR_DESTROY"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;11502600">
-	<META NAME="CHANGED" CONTENT="20050505;18032300">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_barrierattr_destroy, pthread_barrierattr_init - destroy
-and initialize the barrier attributes object (<B>ADVANCED REALTIME
-THREADS</B>) 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P>i<B>nt pthread_barrierattr_destroy(pthread_barrierattr_t *</B><I>attr</I><B>);
-<BR>int pthread_barrierattr_init(pthread_barrierattr_t *</B><I>attr</I><B>);
-</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_barrierattr_destroy</B> function shall destroy a
-barrier attributes object. A destroyed <I>attr</I> attributes object
-can be reinitialized using <B>pthread_barrierattr_init</B> ; the
-results of otherwise referencing the object after it has been
-destroyed are undefined. An implementation may cause
-<B>pthread_barrierattr_destroy</B> to set the object referenced by
-<I>attr</I> to an invalid value. 
-</P>
-<P>The <B>pthread_barrierattr_init</B> function shall initialize a
-barrier attributes object <I>attr</I> with the default value for all
-of the attributes defined by the implementation. 
-</P>
-<P>Results are undefined if <B>pthread_barrierattr_init</B> is called
-specifying an already initialized <I>attr</I> attributes object. 
-</P>
-<P>After a barrier attributes object has been used to initialize one
-or more barriers, any function affecting the attributes object
-(including destruction) shall not affect any previously initialized
-barrier. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>If successful, the <B>pthread_barrierattr_destroy</B> and
-<B>pthread_barrierattr_init</B> functions shall return zero;
-otherwise, an error number shall be returned to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_barrierattr_destroy</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>attr</I> is invalid. 
-	</DD></DL>
-<P>
-The <B>pthread_barrierattr_init</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>ENOMEM</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	Insufficient memory exists to initialize the barrier attributes
-	object. 
-	</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>The <B>pthread_barrierattr_destroy</B> and
-<B>pthread_barrierattr_init</B> functions are part of the Barriers
-option and need not be provided on all implementations. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_BARRIERS</B> to indicate
-that these routines are implemented and may be used.</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_barrierattr_setpshared.html"><B>pthread_barrierattr_getpshared</B>(3)</A>
-<B>,</B> <A HREF="pthread_barrierattr_setpshared.html"><B>pthread_barrierattr_setpshared</B>(3)</A>
-, the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I>. 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_barrierattr_setpshared.html b/deps/w32-pthreads/manual/pthread_barrierattr_setpshared.html
deleted file mode 100644
index 2c62d3d..0000000
--- a/deps/w32-pthreads/manual/pthread_barrierattr_setpshared.html
+++ /dev/null
@@ -1,159 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_BARRIERATTR_GETPSHARED"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;11552100">
-	<META NAME="CHANGED" CONTENT="20050505;18080400">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_barrierattr_getpshared, pthread_barrierattr_setpshared -
-get and set the process-shared attribute of the barrier attributes
-object (<B>ADVANCED REALTIME THREADS</B>) 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_barrierattr_getpshared(const pthread_barrierattr_t
-* restrict</B> <I>attr</I><B>, int *restrict</B> <I>pshared</I><B>);
-<BR>int pthread_barrierattr_setpshared(pthread_barrierattr_t *</B><I>attr</I><B>,
-int</B> <I>pshared</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_barrierattr_getpshared</B> function shall obtain
-the value of the <I>process-shared</I> attribute from the attributes
-object referenced by <I>attr</I>. The <B>pthread_barrierattr_setpshared</B>
-function shall set the <I>process-shared</I> attribute in an
-initialized attributes object referenced by <I>attr</I>. 
-</P>
-<P>The <I>process-shared</I> attribute is set to
-PTHREAD_PROCESS_SHARED to permit a barrier to be operated upon by any
-thread that has access to the memory where the barrier is allocated.
-If the <I>process-shared</I> attribute is PTHREAD_PROCESS_PRIVATE,
-the barrier shall only be operated upon by threads created within the
-same process as the thread that initialized the barrier; if threads
-of different processes attempt to operate on such a barrier, the
-behavior is undefined. The default value of the attribute shall be
-PTHREAD_PROCESS_PRIVATE. Both constants PTHREAD_PROCESS_SHARED and
-PTHREAD_PROCESS_PRIVATE are defined in <I><pthread.h></I>. 
-</P>
-<P><B>Pthreads-w32</B> defines _<B>POSIX_THREAD_PROCESS_SHARED</B> in
-pthread.h as -1 to indicate that these routines are implemented but
-that the process shared attribute is not supported.</P>
-<P>Additional attributes, their default values, and the names of the
-associated functions to get and set those attribute values are
-implementation-defined. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>If successful, the <B>pthread_barrierattr_getpshared</B> function
-shall return zero and store the value of the <I>process-shared</I>
-attribute of <I>attr</I> into the object referenced by the <I>pshared</I>
-parameter. Otherwise, an error number shall be returned to indicate
-the error. 
-</P>
-<P>If successful, the <B>pthread_barrierattr_setpshared</B> function
-shall return zero; otherwise, an error number shall be returned to
-indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>These functions may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>attr</I> is invalid. 
-	</DD><DT>
-	The <B>pthread_barrierattr_setpshared</B> function may fail if: 
-	</DT><DT>
-	<B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The new value specified for the <I>process-shared</I> attribute is
-	not one of the legal values <B>PTHREAD_PROCESS_SHARED</B> or
-	<B>PTHREAD_PROCESS_PRIVATE</B>. 
-	</DD><DT>
-	<B>ENOSYS</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>attr</I> was <B>PTHREAD_PROCESS_SHARED</B>
-	(Pthreads-w32).</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>The <B>pthread_barrierattr_getpshared</B> and
-<B>pthread_barrierattr_setpshared</B> functions are part of the
-Barriers option and need not be provided on all implementations. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_BARRIERS</B> and
-<B>_POSIX_THREAD_PROCESS_SHARED</B> in pthread.h as -1 to indicate
-that these routines are implemented and may be used, but do not
-support the process shared option.</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_barrier_init.html"><B>pthread_barrier_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_barrierattr_init.html"><B>pthread_barrierattr_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_barrierattr_init.html"><B>pthread_barrierattr_init</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_cancel.html b/deps/w32-pthreads/manual/pthread_cancel.html
deleted file mode 100644
index d9acd77..0000000
--- a/deps/w32-pthreads/manual/pthread_cancel.html
+++ /dev/null
@@ -1,205 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_CANCEL(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;12090500">
-	<META NAME="CHANGED" CONTENT="20050505;18220000">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_cancel, pthread_setcancelstate, pthread_setcanceltype,
-pthread_testcancel - thread cancellation 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_cancel(pthread_t </B><I>thread</I><B>);</B> 
-</P>
-<P><B>int pthread_setcancelstate(int </B><I>state</I><B>, int
-*</B><I>oldstate</I><B>);</B> 
-</P>
-<P><B>int pthread_setcanceltype(int </B><I>type</I><B>, int
-*</B><I>oldtype</I><B>);</B> 
-</P>
-<P><B>void pthread_testcancel(void);</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Cancellation is the mechanism by which a thread can terminate the
-execution of another thread. More precisely, a thread can send a
-cancellation request to another thread. Depending on its settings,
-the target thread can then either ignore the request, honor it
-immediately, or defer it until it reaches a cancellation point. 
-</P>
-<P>When a thread eventually honors a cancellation request, it
-performs as if <B>pthread_exit(PTHREAD_CANCELED)</B> has been called
-at that point: all cleanup handlers are executed in reverse order,
-destructor functions for thread-specific data are called, and finally
-the thread stops executing with the return value <B>PTHREAD_CANCELED</B>.
-See <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> for more
-information. 
-</P>
-<P><B>pthread_cancel</B> sends a cancellation request to the thread
-denoted by the <I>thread</I> argument. 
-</P>
-<P><B>pthread_setcancelstate</B> changes the cancellation state for
-the calling thread -- that is, whether cancellation requests are
-ignored or not. The <I>state</I> argument is the new cancellation
-state: either <B>PTHREAD_CANCEL_ENABLE</B> to enable cancellation, or
-<B>PTHREAD_CANCEL_DISABLE</B> to disable cancellation (cancellation
-requests are ignored). If <I>oldstate</I> is not <B>NULL</B>, the
-previous cancellation state is stored in the location pointed to by
-<I>oldstate</I>, and can thus be restored later by another call to
-<B>pthread_setcancelstate</B>. 
-</P>
-<P><B>pthread_setcanceltype</B> changes the type of responses to
-cancellation requests for the calling thread: asynchronous
-(immediate) or deferred. The <I>type</I> argument is the new
-cancellation type: either <B>PTHREAD_CANCEL_ASYNCHRONOUS</B> to
-cancel the calling thread as soon as the cancellation request is
-received, or <B>PTHREAD_CANCEL_DEFERRED</B> to keep the cancellation
-request pending until the next cancellation point. If <I>oldtype</I>
-is not <B>NULL</B>, the previous cancellation state is stored in the
-location pointed to by <I>oldtype</I>, and can thus be restored later
-by another call to <B>pthread_setcanceltype</B>. 
-</P>
-<P><B>Pthreads-w32</B> provides two levels of support for
-<B>PTHREAD_CANCEL_ASYNCHRONOUS</B>: full and partial. Full support
-requires an additional DLL and driver be installed on the Windows
-system (see the See Also section below) that allows blocked threads
-to be cancelled immediately. Partial support means that the target
-thread will not cancel until it resumes execution naturally. Partial
-support is provided if either the DLL or the driver are not
-automatically detected by the pthreads-w32 library at run-time.</P>
-<P>Threads are always created by <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
-with cancellation enabled and deferred. That is, the initial
-cancellation state is <B>PTHREAD_CANCEL_ENABLE</B> and the initial
-type is <B>PTHREAD_CANCEL_DEFERRED</B>. 
-</P>
-<P>Cancellation points are those points in the program execution
-where a test for pending cancellation requests is performed and
-cancellation is executed if positive. The following POSIX threads
-functions are cancellation points: 
-</P>
-<P><A HREF="pthread_join.html"><B>pthread_join</B>(3)</A>
-<BR><A HREF="pthread_cond_init.html"><B>pthread_cond_wait</B>(3)</A>
-<BR><A HREF="pthread_cond_init.html"><B>pthread_cond_timedwait</B>(3)</A>
-<BR><A HREF=""><B>pthread_testcancel</B>(3)</A> <BR><A HREF="sem_init.html"><B>sem_wait</B>(3)</A>
-<BR><A HREF="sem_init.html"><B>sem_timedwait</B>(3)</A> <BR><A HREF="pthread_kill.html"><B>sigwait</B>(3)</A></P>
-<P><B>Pthreads-w32</B> provides two functions to enable additional
-cancellation points to be created in user functions that block on
-Win32 HANDLEs:</P>
-<P><A HREF="pthreadCancelableWait.html">pthreadCancelableWait()</A>
-<BR><A HREF="pthreadCancelableTimedWait.html">pthreadCancelableTimedWait()</A></P>
-<P>All other POSIX threads functions are guaranteed not to be
-cancellation points. That is, they never perform cancellation in
-deferred cancellation mode. 
-</P>
-<P><B>pthread_testcancel</B> does nothing except testing for pending
-cancellation and executing it. Its purpose is to introduce explicit
-checks for cancellation in long sequences of code that do not call
-cancellation point functions otherwise. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P><B>pthread_cancel</B>, <B>pthread_setcancelstate</B> and
-<B>pthread_setcanceltype</B> return 0 on success and a non-zero error
-code on error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P><B>pthread_cancel</B> returns the following error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ESRCH</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		no thread could be found corresponding to that specified by the
-		<I>thread</I> ID. 
-		</DD></DL>
-</DL>
-<P>
-<B>pthread_setcancelstate</B> returns the following error code on
-error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the <I>state</I> argument is not 
-		</DD></DL>
-</DL>
-<BLOCKQUOTE>
-<B>PTHREAD_CANCEL_ENABLE</B> nor <B>PTHREAD_CANCEL_DISABLE</B> 
-</BLOCKQUOTE>
-<P><B>pthread_setcanceltype</B> returns the following error code on
-error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the <I>type</I> argument is not 
-		</DD></DL>
-</DL>
-<BLOCKQUOTE>
-<B>PTHREAD_CANCEL_DEFERRED</B> nor <B>PTHREAD_CANCEL_ASYNCHRONOUS</B>
-</BLOCKQUOTE>
-<H2><A HREF="#toc5" NAME="sect5">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
-<P><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> ,
-<A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_push</B>(3)</A>
-, <A HREF="pthread_cleanup_pop.html"><B>pthread_cleanup_pop</B>(3)</A>
-, Pthreads-w32 package README file 'Prerequisites' section. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Bugs</A></H2>
-<P>POSIX specifies that a number of system calls (basically, all
-system calls that may block, such as <A HREF="read.html"><B>read</B>(2)</A>
-, <A HREF="write.html"><B>write</B>(2)</A> , <A HREF="wait.html"><B>wait</B>(2)</A>
-, etc.) and library functions that may call these system calls (e.g.
-<A HREF="fprintf.html"><B>fprintf</B>(3)</A> ) are cancellation
-points. <B>Pthreads-win32</B> is not integrated enough with the C
-library to implement this, and thus none of the C library functions
-is a cancellation point. 
-</P>
-<P>A workaround for these calls is to temporarily switch to
-asynchronous cancellation (assuming full asynchronous cancellation
-support is installed). So, checking for cancellation during a <B>read</B>
-system call, for instance, can be achieved as follows: 
-</P>
-<BLOCKQUOTE><BR><BR>
-</BLOCKQUOTE>
-<PRE STYLE="margin-left: 1cm; margin-right: 1cm">pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldCancelType);
-read(fd, buffer, length);
-pthread_setcanceltype(oldCancelType, NULL);</PRE>
-<HR>
-<BLOCKQUOTE><A NAME="toc"></A><B>Table of Contents</B></BLOCKQUOTE>
-<UL>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">See
-	Also</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE><A HREF="#sect7" NAME="toc7">Bugs</A> 
-	</BLOCKQUOTE>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_cleanup_push.html b/deps/w32-pthreads/manual/pthread_cleanup_push.html
deleted file mode 100644
index 0fc071e..0000000
--- a/deps/w32-pthreads/manual/pthread_cleanup_push.html
+++ /dev/null
@@ -1,140 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_CLEANUP(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;20152200">
-	<META NAME="CHANGED" CONTENT="20050505;18252600">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_cleanup_push, pthread_cleanup_pop - install and remove
-cleanup handlers 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>void pthread_cleanup_push(void (*</B><I>routine</I><B>) (void
-*), void *</B><I>arg</I><B>);</B> 
-</P>
-<P><B>void pthread_cleanup_pop(int </B><I>execute</I><B>);</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Cleanup handlers are functions that get called when a thread
-terminates, either by calling <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A>
-or because of cancellation. Cleanup handlers are installed and
-removed following a stack-like discipline. 
-</P>
-<P>The purpose of cleanup handlers is to free the resources that a
-thread may hold at the time it terminates. In particular, if a thread
-exits or is cancelled while it owns a locked mutex, the mutex will
-remain locked forever and prevent other threads from executing
-normally. The best way to avoid this is, just before locking the
-mutex, to install a cleanup handler whose effect is to unlock the
-mutex. Cleanup handlers can be used similarly to free blocks
-allocated with <A HREF="malloc.html"><B>malloc</B>(3)</A> or close
-file descriptors on thread termination. 
-</P>
-<P><B>pthread_cleanup_push</B> installs the <I>routine</I> function
-with argument <I>arg</I> as a cleanup handler. From this point on to
-the matching <B>pthread_cleanup_pop</B>, the function <I>routine</I>
-will be called with arguments <I>arg</I> when the thread terminates,
-either through <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A>
-or by cancellation. If several cleanup handlers are active at that
-point, they are called in LIFO order: the most recently installed
-handler is called first. 
-</P>
-<P><B>pthread_cleanup_pop</B> removes the most recently installed
-cleanup handler. If the <I>execute</I> argument is not 0, it also
-executes the handler, by calling the <I>routine</I> function with
-arguments <I>arg</I>. If the <I>execute</I> argument is 0, the
-handler is only removed but not executed. 
-</P>
-<P>Matching pairs of <B>pthread_cleanup_push</B> and
-<B>pthread_cleanup_pop</B> must occur in the same function, at the
-same level of block nesting. Actually, <B>pthread_cleanup_push</B>
-and <B>pthread_cleanup_pop</B> are macros, and the expansion of
-<B>pthread_cleanup_push</B> introduces an open brace <B>{</B> with
-the matching closing brace <B>}</B> being introduced by the expansion
-of the matching <B>pthread_cleanup_pop</B>. 
-</P>
-<H2 STYLE="margin-top: 0cm"><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">None. 
-</BLOCKQUOTE>
-<H2 STYLE="margin-top: 0cm"><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">None. 
-</BLOCKQUOTE>
-<H2 STYLE="margin-top: 0cm"><A HREF="#toc5" NAME="sect5">Author</A></H2>
-<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">Xavier Leroy
-<Xavier.Leroy at inria.fr> 
-</BLOCKQUOTE>
-<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">Modified by
-Ross Johnson for use with Pthreads-w32.</BLOCKQUOTE>
-<H2 STYLE="margin-top: 0cm"><A HREF="#toc6" NAME="sect6">See Also</A></H2>
-<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm"><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A>
-, <A HREF="pthread_cancel.html"><B>pthread_cancel</B>(3)</A> ,
-<A HREF="pthread_cancel.html"><B>pthread_setcanceltype</B>(3)</A> . 
-</BLOCKQUOTE>
-<H2 STYLE="margin-top: 0cm"><A HREF="#toc7" NAME="sect7">Example</A></H2>
-<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">Here is how
-to lock a mutex <I>mut</I> in such a way that it will be unlocked if
-the thread is canceled while <I>mut</I> is locked: 
-</BLOCKQUOTE>
-<PRE>pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
-pthread_mutex_lock(&mut);
-/* do some work */
-pthread_mutex_unlock(&mut);
-pthread_cleanup_pop(0);</PRE><BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">
-Equivalently, the last two lines can be replaced by 
-</BLOCKQUOTE>
-<PRE STYLE="margin-bottom: 0.5cm">pthread_cleanup_pop(1);</PRE><BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">
-Notice that the code above is safe only in deferred cancellation mode
-(see <A HREF="pthread_cancel.html"><B>pthread_setcanceltype</B>(3)</A>
-). In asynchronous cancellation mode, a cancellation can occur
-between <B>pthread_cleanup_push</B> and <B>pthread_mutex_lock</B>, or
-between <B>pthread_mutex_unlock</B> and <B>pthread_cleanup_pop</B>,
-resulting in both cases in the thread trying to unlock a mutex not
-locked by the current thread. This is the main reason why
-asynchronous cancellation is difficult to use. 
-</BLOCKQUOTE>
-<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">If the code
-above must also work in asynchronous cancellation mode, then it must
-switch to deferred mode for locking and unlocking the mutex: 
-</BLOCKQUOTE>
-<PRE>pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
-pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
-pthread_mutex_lock(&mut);
-/* do some work */
-pthread_cleanup_pop(1);
-pthread_setcanceltype(oldtype, NULL);</PRE>
-<HR>
-<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm"><A NAME="toc"></A>
-<B>Table of Contents</B></BLOCKQUOTE>
-<UL>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">See
-	Also</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm"><A HREF="#sect7" NAME="toc7">Example</A>
-		</BLOCKQUOTE>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_cond_init.html b/deps/w32-pthreads/manual/pthread_cond_init.html
deleted file mode 100644
index 937e490..0000000
--- a/deps/w32-pthreads/manual/pthread_cond_init.html
+++ /dev/null
@@ -1,313 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_COND(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;16454400">
-	<META NAME="CHANGED" CONTENT="20050505;19004700">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_cond_init, pthread_cond_destroy, pthread_cond_signal,
-pthread_cond_broadcast, pthread_cond_wait, pthread_cond_timedwait -
-operations on conditions 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>pthread_cond_t </B><I>cond</I> <B>= PTHREAD_COND_INITIALIZER;</B>
-</P>
-<P><B>int pthread_cond_init(pthread_cond_t *</B><I>cond</I><B>,
-pthread_condattr_t *</B><I>cond_attr</I><B>);</B> 
-</P>
-<P><B>int pthread_cond_signal(pthread_cond_t *</B><I>cond</I><B>);</B>
-</P>
-<P><B>int pthread_cond_broadcast(pthread_cond_t *</B><I>cond</I><B>);</B>
-</P>
-<P><B>int pthread_cond_wait(pthread_cond_t *</B><I>cond</I><B>,
-pthread_mutex_t *</B><I>mutex</I><B>);</B> 
-</P>
-<P><B>int pthread_cond_timedwait(pthread_cond_t *</B><I>cond</I><B>,
-pthread_mutex_t *</B><I>mutex</I><B>, const struct timespec
-*</B><I>abstime</I><B>);</B> 
-</P>
-<P><B>int pthread_cond_destroy(pthread_cond_t *</B><I>cond</I><B>);</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>A condition (short for ‘‘condition variable’’) is a
-synchronization device that allows threads to suspend execution and
-relinquish the processors until some predicate on shared data is
-satisfied. The basic operations on conditions are: signal the
-condition (when the predicate becomes true), and wait for the
-condition, suspending the thread execution until another thread
-signals the condition. 
-</P>
-<P>A condition variable must always be associated with a mutex, to
-avoid the race condition where a thread prepares to wait on a
-condition variable and another thread signals the condition just
-before the first thread actually waits on it. 
-</P>
-<P><B>pthread_cond_init</B> initializes the condition variable <I>cond</I>,
-using the condition attributes specified in <I>cond_attr</I>, or
-default attributes if <I>cond_attr</I> is <B>NULL</B>. 
-</P>
-<P>Variables of type <B>pthread_cond_t</B> can also be initialized
-statically, using the constant <B>PTHREAD_COND_INITIALIZER</B>. In
-the <B>Pthreads-w32</B> implementation, an application should still
-call <B>pthread_cond_destroy</B> at some point to ensure that any
-resources consumed by the condition variable are released.</P>
-<P><B>pthread_cond_signal</B> restarts one of the threads that are
-waiting on the condition variable <I>cond</I>. If no threads are
-waiting on <I>cond</I>, nothing happens. If several threads are
-waiting on <I>cond</I>, exactly one is restarted, but it is not
-specified which. 
-</P>
-<P><B>pthread_cond_broadcast</B> restarts all the threads that are
-waiting on the condition variable <I>cond</I>. Nothing happens if no
-threads are waiting on <I>cond</I>. 
-</P>
-<P><B>pthread_cond_wait</B> atomically unlocks the <I>mutex</I> (as
-per <B>pthread_unlock_mutex</B>) and waits for the condition variable
-<I>cond</I> to be signalled. The thread execution is suspended and
-does not consume any CPU time until the condition variable is
-signalled. The <I>mutex</I> must be locked by the calling thread on
-entrance to <B>pthread_cond_wait</B>. Before returning to the calling
-thread, <B>pthread_cond_wait</B> re-acquires <I>mutex</I> (as per
-<B>pthread_lock_mutex</B>). 
-</P>
-<P>Unlocking the mutex and suspending on the condition variable is
-done atomically. Thus, if all threads always acquire the mutex before
-signalling the condition, this guarantees that the condition cannot
-be signalled (and thus ignored) between the time a thread locks the
-mutex and the time it waits on the condition variable. 
-</P>
-<P><B>pthread_cond_timedwait</B> atomically unlocks <I>mutex</I> and
-waits on <I>cond</I>, as <B>pthread_cond_wait</B> does, but it also
-bounds the duration of the wait. If <I>cond</I> has not been
-signalled within the amount of time specified by <I>abstime</I>, the
-mutex <I>mutex</I> is re-acquired and <B>pthread_cond_timedwait</B>
-returns the error <B>ETIMEDOUT</B>. The <I>abstime</I> parameter
-specifies an absolute time, with the same origin as <A HREF="time.html"><B>time</B>(2)</A>
-and <A HREF="gettimeofday.html"><B>gettimeofday</B>(2)</A>. 
-</P>
-<P><B>pthread_cond_destroy</B> destroys a condition variable, freeing
-the resources it might hold. No threads must be waiting on the
-condition variable on entrance to <B>pthread_cond_destroy</B>.</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P><B>pthread_cond_wait</B> and <B>pthread_cond_timedwait</B> are
-cancellation points. If a thread is cancelled while suspended in one
-of these functions, the thread immediately resumes execution, then
-locks again the <I>mutex</I> argument to <B>pthread_cond_wait</B> and
-<B>pthread_cond_timedwait</B>, and finally executes the cancellation.
-Consequently, cleanup handlers are assured that <I>mutex</I> is
-locked when they are called. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Async-signal Safety</A></H2>
-<P>The condition functions are not async-signal safe, and should not
-be called from a signal handler. In particular, calling
-<B>pthread_cond_signal</B> or <B>pthread_cond_broadcast</B> from a
-signal handler may deadlock the calling thread. 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Return Value</A></H2>
-<P>All condition variable functions return 0 on success and a
-non-zero error code on error. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Errors</A></H2>
-<P><B>pthread_cond_init</B>, <B>pthread_cond_signal</B>,
-<B>pthread_cond_broadcast</B>, and <B>pthread_cond_wait</B> never
-return an error code. 
-</P>
-<P>The <B>pthread_cond_init</B> function returns the following error
-codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		The <I>cond</I> argument is invalid. 
-		</DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<B>ENOMEM</B> 
-		</DT></DL>
-</DL>
-<BLOCKQUOTE STYLE="margin-left: 4cm">
-There was not enough memory to allocate the condition variable. 
-</BLOCKQUOTE>
-<P>The <B>pthread_cond_signal</B> function returns the following
-error codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		The <I>cond</I> argument is invalid. 
-		</DD></DL>
-</DL>
-<P>
-The <B>pthread_cond_broadcast</B> function returns the following
-error codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		The <I>cond</I> argument is invalid. 
-		</DD></DL>
-</DL>
-<P>
-The <B>pthread_cond_wait</B> function returns the following error
-codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		The <I>cond</I> argument is invalid. 
-		</DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<B>ENOMEM</B> 
-		</DT></DL>
-</DL>
-<BLOCKQUOTE STYLE="margin-left: 4cm">
-There was not enough memory to allocate the statically initialised
-condition variable. Statically initialised condition variables are
-dynamically allocated by the first thread to wait on them.</BLOCKQUOTE>
-<P>The <B>pthread_cond_timedwait</B> function returns the following
-error codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT></DL>
-</DL>
-<P STYLE="margin-left: 2cm">
-The <I>cond</I> argument is invalid. 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ETIMEDOUT</B>
-				</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		The condition variable was not signalled before the timeout
-		specified by <I>abstime</I> 
-		</DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<B>ENOMEM</B> 
-		</DT></DL>
-</DL>
-<BLOCKQUOTE STYLE="margin-left: 4cm">
-There was not enough memory to allocate the statically initialised
-condition variable. Statically initialised condition variables are
-dynamically allocated by the first thread to wait on them. 
-</BLOCKQUOTE>
-<P>The <B>pthread_cond_destroy</B> function returns the following
-error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT></DL>
-</DL>
-<P STYLE="margin-left: 2cm; margin-right: 1cm">
-The <I>cond</I> argument is invalid. 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EBUSY</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		Some threads are currently waiting on <I>cond</I>. 
-		</DD></DL>
-</DL>
-<H2>
-<A HREF="#toc7" NAME="sect7">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc8" NAME="sect8">See Also</A></H2>
-<P><A HREF="pthread_condattr_init.html"><B>pthread_condattr_init</B>(3)</A>
-, <A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
-, <A HREF="pthread_mutex_unlock.html"><B>pthread_mutex_unlock</B>(3)</A>
-, <A HREF="pthread_cancel.html"><B>pthread_cancel(3)</B></A>. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">Example</A></H2>
-<P>Consider two shared variables <I>x</I> and <I>y</I>, protected by
-the mutex <I>mut</I>, and a condition variable <I>cond</I> that is to
-be signaled whenever <I>x</I> becomes greater than <I>y</I>. 
-</P>
-<PRE STYLE="margin-left: 1cm; margin-right: 1cm">int x,y;
-pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t cond = PTHREAD_COND_INITIALIZER;</PRE><BLOCKQUOTE>
-Waiting until <I>x</I> is greater than <I>y</I> is performed as
-follows: 
-</BLOCKQUOTE>
-<PRE STYLE="margin-left: 1.01cm">pthread_mutex_lock(&mut);
-while (x <= y) {
-        pthread_cond_wait(&cond, &mut);
-}
-/* operate on x and y */
-pthread_mutex_unlock(&mut);</PRE><BLOCKQUOTE STYLE="margin-left: 3.01cm">
-Modifications on <I>x</I> and <I>y</I> that may cause <I>x</I> to
-become greater than <I>y</I> should signal the condition if needed: 
-</BLOCKQUOTE>
-<PRE STYLE="margin-left: 1.01cm">pthread_mutex_lock(&mut);
-/* modify x and y */
-if (x > y) pthread_cond_broadcast(&cond);
-pthread_mutex_unlock(&mut);</PRE><BLOCKQUOTE STYLE="margin-left: 3.01cm">
-If it can be proved that at most one waiting thread needs to be waken
-up (for instance, if there are only two threads communicating through
-<I>x</I> and <I>y</I>), <B>pthread_cond_signal</B> can be used as a
-slightly more efficient alternative to <B>pthread_cond_broadcast</B>.
-If in doubt, use <B>pthread_cond_broadcast</B>. 
-</BLOCKQUOTE>
-<BLOCKQUOTE STYLE="margin-left: 3.01cm">To wait for <I>x</I> to
-become greater than <I>y</I> with a timeout of 5 seconds, do: 
-</BLOCKQUOTE>
-<PRE STYLE="margin-left: 1.01cm">struct timeval now;
-struct timespec timeout;
-int retcode;
-pthread_mutex_lock(&mut);
-gettimeofday(&now);
-timeout.tv_sec = now.tv_sec + 5;
-timeout.tv_nsec = now.tv_usec * 1000;
-retcode = 0;
-while (x <= y && retcode != ETIMEDOUT) {
-        retcode = pthread_cond_timedwait(&cond, &mut, &timeout);
-}
-if (retcode == ETIMEDOUT) {
-        /* timeout occurred */
-} else {
-        /* operate on x and y */
-}
-pthread_mutex_unlock(&mut);</PRE>
-<HR>
-<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm"><A NAME="toc"></A>
-<B>Table of Contents</B></BLOCKQUOTE>
-<UL>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Async-signal
-	Safety</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Return
-	Value</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Errors</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Author</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">See
-	Also</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 0cm"><A HREF="#sect9" NAME="toc9">Example</A>
-		</BLOCKQUOTE>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_condattr_init.html b/deps/w32-pthreads/manual/pthread_condattr_init.html
deleted file mode 100644
index 8b8b2f2..0000000
--- a/deps/w32-pthreads/manual/pthread_condattr_init.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_CONDATTR(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;16375600">
-	<META NAME="CHANGED" CONTENT="20050504;16570300">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_condattr_init, pthread_condattr_destroy - condition
-creation 
-</P>
-<P>attributes 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_condattr_init(pthread_condattr_t *</B><I>attr</I><B>);</B>
-</P>
-<P><B>int pthread_condattr_destroy(pthread_condattr_t *</B><I>attr</I><B>);</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Condition attributes can be specified at condition creation time,
-by passing a condition attribute object as second argument to
-<A HREF="pthread_cond_init.html"><B>pthread_cond_init</B>(3)</A> .
-Passing <B>NULL</B> is equivalent to passing a condition attribute
-object with all attributes set to their default values. 
-</P>
-<P><B>pthread_condattr_init</B> initializes the condition attribute
-object <I>attr</I> and fills it with default values for the
-attributes. <B>pthread_condattr_destroy</B> destroys a condition
-attribute object, which must not be reused until it is reinitialized.</P>
-<P><B>Pthreads-w32</B> defines _<B>POSIX_THREAD_PROCESS_SHARED</B> in
-pthread.h as -1 to indicate that the attribute routines are
-implemented but that the process shared attribute is not supported.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>All condition variable functions return 0 on success and a
-non-zero error code on error.</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_condattr_init</B> function returns the following
-error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ENOMEM</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		The was insufficient memory to create the attribute.<SPAN STYLE="font-weight: medium">
-		</SPAN>
-		</DD></DL>
-</DL>
-<P>
-The <B>pthread_condattr_destroy</B> function returns the following
-error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		The <I>attr</I> argument is not valid.<SPAN STYLE="font-weight: medium">
-		</SPAN>
-		</DD></DL>
-</DL>
-<H2>
-<A HREF="#toc5" NAME="sect5">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
-<P><A HREF="pthread_cond_init.html"><B>pthread_cond_init</B>(3)</A> .
-</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">See Also</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_condattr_setpshared.html b/deps/w32-pthreads/manual/pthread_condattr_setpshared.html
deleted file mode 100644
index eda357e..0000000
--- a/deps/w32-pthreads/manual/pthread_condattr_setpshared.html
+++ /dev/null
@@ -1,153 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_CONDATTR_GETPSHARED"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;17542300">
-	<META NAME="CHANGED" CONTENT="20050505;18293100">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_condattr_getpshared, pthread_condattr_setpshared - get and
-set the process-shared condition variable attributes 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_condattr_getpshared(const pthread_condattr_t
-*restrict</B> <I>attr</I><B>, int *restrict</B> <I>pshared</I><B>);
-<BR>int pthread_condattr_setpshared(pthread_condattr_t *</B><I>attr</I><B>,
-int</B> <I>pshared</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_condattr_getpshared</B> function shall obtain the
-value of the <I>process-shared</I> attribute from the attributes
-object referenced by <I>attr</I>. The <B>pthread_condattr_setpshared</B>
-function shall set the <I>process-shared</I> attribute in an
-initialized attributes object referenced by <I>attr</I>. 
-</P>
-<P>The <I>process-shared</I> attribute is set to
-<B>PTHREAD_PROCESS_SHARED</B> to permit a condition variable to be
-operated upon by any thread that has access to the memory where the
-condition variable is allocated, even if the condition variable is
-allocated in memory that is shared by multiple processes. If the
-<I>process-shared</I> attribute is <B>PTHREAD_PROCESS_PRIVATE</B>,
-the condition variable shall only be operated upon by threads created
-within the same process as the thread that initialized the condition
-variable; if threads of differing processes attempt to operate on
-such a condition variable, the behavior is undefined. The default
-value of the attribute is <B>PTHREAD_PROCESS_PRIVATE</B>. 
-</P>
-<P><B>Pthreads-w32</B> defines _<B>POSIX_THREAD_PROCESS_SHARED</B> in
-pthread.h as -1 to indicate that these routines are implemented but
-that the process shared attribute is not supported.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>If successful, the <B>pthread_condattr_setpshared</B> function
-shall return zero; otherwise, an error number shall be returned to
-indicate the error. 
-</P>
-<P>If successful, the <B>pthread_condattr_getpshared</B> function
-shall return zero and store the value of the <I>process-shared</I>
-attribute of <I>attr</I> into the object referenced by the <I>pshared</I>
-parameter. Otherwise, an error number shall be returned to indicate
-the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_condattr_getpshared</B> and
-<B>pthread_condattr_setpshared</B> functions may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>attr</I> is invalid. 
-	</DD></DL>
-<P>
-The <B>pthread_condattr_setpshared</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The new value specified for the attribute is outside the range of
-	legal values for that attribute. 
-	</DD><DT>
-	<B>ENOSYS</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>attr</I> was <B>PTHREAD_PROCESS_SHARED</B>
-	(Pthreads-w32).</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_PROCESS_SHARED</B> in
-pthread.h as -1 to indicate that these routines are implemented and
-may be used, but do not support the process shared option.</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> <B>,</B>
-<A HREF="pthread_cond_init.html"><B>pthread_cond_destroy</B>(3)</A> <B>,</B>
-<A HREF="pthread_condattr_init.html"><B>pthread_condattr_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_mutex_init.html"><B>pthread_mutex_destroy</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_create.html b/deps/w32-pthreads/manual/pthread_create.html
deleted file mode 100644
index d1ebbc3..0000000
--- a/deps/w32-pthreads/manual/pthread_create.html
+++ /dev/null
@@ -1,94 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_CREATE(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;19394700">
-	<META NAME="CHANGED" CONTENT="20050504;20140200">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_create - create a new thread 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_create(pthread_t * </B><I>thread</I><B>,
-pthread_attr_t * </B><I>attr</I><B>, void * (*</B><I>start_routine</I><B>)(void
-*), void * </B><I>arg</I><B>);</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P><B>pthread_create</B> creates a new thread of control that
-executes concurrently with the calling thread. The new thread applies
-the function <I>start_routine</I> passing it <I>arg</I> as first
-argument. The new thread terminates either explicitly, by calling
-<A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> , or
-implicitly, by returning from the <I>start_routine</I> function. The
-latter case is equivalent to calling <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A>
-with the result returned by <I>start_routine</I> as exit code. 
-</P>
-<P>The initial signal state of the new thread is inherited from it's
-creating thread and there are no pending signals. <B>Pthreads-w32</B>
-does not yet implement signals.</P>
-<P>The <I>attr</I> argument specifies thread attributes to be applied
-to the new thread. See <A HREF="pthread_attr_init.html"><B>pthread_attr_init</B>(3)</A>
-for a complete list of thread attributes. The <I>attr</I> argument
-can also be <B>NULL</B>, in which case default attributes are used:
-the created thread is joinable (not detached) and has default (non
-real-time) scheduling policy. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>On success, the identifier of the newly created thread is stored
-in the location pointed by the <I>thread</I> argument, and a 0 is
-returned. On error, a non-zero error code is returned. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<DL>
-	<DT><B>EAGAIN</B> 
-	</DT><DL>
-		<DL>
-			<DT>
-			Not enough system resources to create a process for the new
-			thread, or<BR>more than <B>PTHREAD_THREADS_MAX</B> threads are
-			already active. 
-			</DT></DL>
-	</DL>
-</DL>
-<H2>
-<A HREF="#toc5" NAME="sect5">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
-<P><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> ,
-<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> ,
-<A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A> ,
-<A HREF="pthread_attr_init.html"><B>pthread_attr_init</B>(3)</A> . 
-</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">See Also</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_delay_np.html b/deps/w32-pthreads/manual/pthread_delay_np.html
deleted file mode 100644
index ce533e2..0000000
--- a/deps/w32-pthreads/manual/pthread_delay_np.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_DELAY_NP manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;322600">
-	<META NAME="CHANGED" CONTENT="20050505;21371500">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P STYLE="font-weight: medium">pthread_delay_np – suspend the
-thread for a specified period</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_delay_np (const struct timespec *</B>interval<B>);</B></P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P><B>pthread_delay_np</B> causes a thread to delay execution for a
-specific period of time. This period ends at the current time plus
-the specified interval. The routine will not return before the end of
-the period is reached, but may return an arbitrary amount of time
-after the period has gone by. This can be due to system load, thread
-priorities, and system timer granularity.</P>
-<P>Specifying an interval of zero (0) seconds and zero (0)
-nanoseconds is allowed and can be used to force the thread to give up
-the processor or to deliver a pending cancellation request.</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P><B>pthread_delay_np </B>is a cancellation point.</P>
-<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
-<P>If an error condition occurs, <B>pthread_delay_np</B> returns an
-integer value indicating the type of error.</P>
-<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
-<P>The <B>pthread_delay_np</B> function returns the following error
-code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT></DL>
-</DL>
-<P STYLE="margin-left: 2cm">
-The value specified by interval is invalid.</P>
-<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
-<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">Author</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_detach.html b/deps/w32-pthreads/manual/pthread_detach.html
deleted file mode 100644
index 252adb8..0000000
--- a/deps/w32-pthreads/manual/pthread_detach.html
+++ /dev/null
@@ -1,90 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_DETACH(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 2.0  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;18010700">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<META NAME="CHANGED" CONTENT="20060408;9255600">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_detach - put a running thread in the detached state 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_detach(pthread_t </B><I>th</I><B>);</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P><B>pthread_detach</B> puts the thread <I>th</I> in the detached
-state. This guarantees that the resources consumed by <I>th</I> will
-be freed immediately when <I>th</I> terminates. However, this
-prevents other threads from synchronizing on the termination of <I>th</I>
-using <B>pthread_join</B>. If, when <B>pthread_detach</B> is called,
-<I>th</I> has already terminated, all of <I>th</I>'s remaining
-resources will be freed.</P>
-<P>A thread can be created initially in the detached state, using the
-<B>detachstate</B> attribute to <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
-. In contrast, <B>pthread_detach</B> applies to threads created in
-the joinable state, and which need to be put in the detached state
-later. 
-</P>
-<P>After <B>pthread_detach</B> completes, subsequent attempts to
-perform <B>pthread_join</B> on <I>th</I> will fail. If another thread
-is already joining the thread <I>th</I> at the time <B>pthread_detach</B>
-is called, <I>th</I> will be detached and <B>pthread_join</B> will
-eventually return when <I>th</I> terminates but may not return with
-<I>th</I>'s correct return code. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>On success, 0 is returned. On error, a non-zero error code is
-returned. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<DL>
-	<DT><B>ESRCH</B> 
-	</DT><DD>
-	No thread could be found corresponding to that specified by <I>th</I>
-		</DD><DT>
-	<B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	the thread <I>th</I> is already in the detached state 
-	</DD></DL>
-<H2>
-<A HREF="#toc5" NAME="sect5">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with Pthreads-w32.</P>
-<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
-<P><A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> ,
-<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> ,
-<A HREF="pthread_attr_init.html"><B>pthread_attr_setdetachstate</B>(3)</A>
-</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">See Also</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/pthread_equal.html b/deps/w32-pthreads/manual/pthread_equal.html
deleted file mode 100644
index 6f61063..0000000
--- a/deps/w32-pthreads/manual/pthread_equal.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!-- manual page source format generated by PolyglotMan v3.2, -->
-<!-- available at http://polyglotman.sourceforge.net/ -->
-
-<html>
-<head>
-<title>PTHREAD_EQUAL(3) manual page</title>
-</head>
-<body bgcolor='white'>
-<a href='#toc'>Table of Contents</a><p>
-
-<p> 
-<h2><a name='sect0' href='#toc0'>Name</a></h2>
-pthread_equal - compare two thread identifiers 
-<p> 
-<h2><a name='sect1' href='#toc1'>Synopsis</a></h2>
-<b>#include <pthread.h></b>
-
-<p> <b>int pthread_equal(pthread_t </b><i>thread1</i><b>, pthread_t </b><i>thread2</i><b>);</b> 
-<p> 
-<h2><a name='sect2' href='#toc2'>Description</a></h2>
-<b>pthread_equal</b>
-determines if two thread identifiers refer to the same thread. 
-<p> 
-<h2><a name='sect3' href='#toc3'>Return Value</a></h2>
-A
-non-zero value is returned if  <i>thread1</i> and  <i>thread2</i> refer to the same thread.
-Otherwise, 0 is returned. 
-<p> 
-<h2><a name='sect4' href='#toc4'>Author</a></h2>
-Xavier Leroy <Xavier.Leroy at inria.fr> 
-<p> 
-<h2><a name='sect5' href='#toc5'>See Also</a></h2>
-<a href='file:pthread_self.html'><b>pthread_self</b>(3)</a>
-.
-<p>
-
-<hr><p>
-<a name='toc'><b>Table of Contents</b></a><p>
-<ul>
-<li><a name='toc0' href='#sect0'>Name</a></li>
-<li><a name='toc1' href='#sect1'>Synopsis</a></li>
-<li><a name='toc2' href='#sect2'>Description</a></li>
-<li><a name='toc3' href='#sect3'>Return Value</a></li>
-<li><a name='toc4' href='#sect4'>Author</a></li>
-<li><a name='toc5' href='#sect5'>See Also</a></li>
-</ul>
-</body>
-</html>
diff --git a/deps/w32-pthreads/manual/pthread_exit.html b/deps/w32-pthreads/manual/pthread_exit.html
deleted file mode 100644
index e97318f..0000000
--- a/deps/w32-pthreads/manual/pthread_exit.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!-- manual page source format generated by PolyglotMan v3.2, -->
-<!-- available at http://polyglotman.sourceforge.net/ -->
-
-<html>
-<head>
-<title>PTHREAD_EXIT(3) manual page</title>
-</head>
-<body bgcolor='white'>
-<a href='#toc'>Table of Contents</a><p>
-
-<p> 
-<h2><a name='sect0' href='#toc0'>Name</a></h2>
-pthread_exit - terminate the calling thread 
-<p> 
-<h2><a name='sect1' href='#toc1'>Synopsis</a></h2>
-<b>#include <pthread.h></b>
-
-<p> <b>void pthread_exit(void *</b><i>retval</i><b>);</b> 
-<p> 
-<h2><a name='sect2' href='#toc2'>Description</a></h2>
-<b>pthread_exit</b> terminates the
-execution of the calling thread. All cleanup handlers that have been set
-for the calling thread with <a href='file:pthread_cleanup_push.html'><b>pthread_cleanup_push</b>(3)</a>
- are executed in reverse
-order (the most recently pushed handler is executed first). Finalization
-functions for thread-specific data are then called for all keys that have
-non- <b>NULL</b> values associated with them in the calling thread (see <a href='file:pthread_key_create.html'><b>pthread_key_create</b>(3)</a>
-).
-Finally, execution of the calling thread is stopped. 
-<p> The  <i>retval</i> argument
-is the return value of the thread. It can be consulted from another thread
-using  <a href='file:pthread_join.html'><b>pthread_join</b>(3)</a>
-. 
-<p> 
-<h2><a name='sect3' href='#toc3'>Return Value</a></h2>
-The  <b>pthread_exit</b> function never returns.
-
-<p> 
-<h2><a name='sect4' href='#toc4'>Author</a></h2>
-Xavier Leroy <Xavier.Leroy at inria.fr> 
-<p> 
-<h2><a name='sect5' href='#toc5'>See Also</a></h2>
-<a href='file:pthread_create.html'><b>pthread_create</b>(3)</a>
-, <a href='file:pthread_join.html'><b>pthread_join</b>(3)</a>
-.
-<p>
-
-<hr><p>
-<a name='toc'><b>Table of Contents</b></a><p>
-<ul>
-<li><a name='toc0' href='#sect0'>Name</a></li>
-<li><a name='toc1' href='#sect1'>Synopsis</a></li>
-<li><a name='toc2' href='#sect2'>Description</a></li>
-<li><a name='toc3' href='#sect3'>Return Value</a></li>
-<li><a name='toc4' href='#sect4'>Author</a></li>
-<li><a name='toc5' href='#sect5'>See Also</a></li>
-</ul>
-</body>
-</html>
diff --git a/deps/w32-pthreads/manual/pthread_getunique_np.html b/deps/w32-pthreads/manual/pthread_getunique_np.html
deleted file mode 100644
index 182ce73..0000000
--- a/deps/w32-pthreads/manual/pthread_getunique_np.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_GETW32THREADHANDLE_NP manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;322600">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<META NAME="CHANGED" CONTENT="20110326;18290500">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-	<STYLE TYPE="text/css">
-	<!--
-		H4.cjk { font-family: "AR PL UMing CN" }
-		H4.ctl { font-family: "Lohit Devanagari" }
-		H2.cjk { font-family: "AR PL UMing CN" }
-		H2.ctl { font-family: "Lohit Devanagari" }
-	-->
-	</STYLE>
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4 CLASS="western">POSIX Threads for Windows – REFERENCE -
-<A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2 CLASS="western"><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P STYLE="font-weight: normal">pthread_getunique_np – get the
-unique sequence number associated with a thread</P>
-<H2 CLASS="western"><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>unsigned long long pthread_getunique_np(pthread_t</B> <I>thread</I><B>);</B></P>
-<H2 CLASS="western"><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Returns the <B>unique </B><SPAN STYLE="font-weight: normal">64 bit
-sequence number</SPAN> assigned to <I>thread</I>.</P>
-<P>In <B>Pthreads-win32:</B></P>
-<UL>
-	<LI><P>the value returned is not reused after the thread terminates
-	so it is unique for the life of the process</P>
-	<LI><P>Windows native threads may obtain their own POSIX thread
-	sequence number by first retrieving their <B>pthread_t</B> handle
-	via <B>pthread_self</B> to use as the <I>thread</I> argument.</P>
-</UL>
-<P>This function was added for source code compatibility with some
-other POSIX threads implementations.</P>
-<H2 CLASS="western"><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P>None.</P>
-<H2 CLASS="western"><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
-<P><B>pthread_getunique_np</B> returns the unique sequence number for
-<I>thread</I>.</P>
-<H2 CLASS="western"><A HREF="#toc5" NAME="sect5">Errors</A></H2>
-<P>None.</P>
-<H2 CLASS="western"><A HREF="#toc6" NAME="sect6">Author</A></H2>
-<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect4" NAME="toc4">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect5" NAME="toc5">Errors</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">Author</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/pthread_getw32threadhandle_np.html b/deps/w32-pthreads/manual/pthread_getw32threadhandle_np.html
deleted file mode 100644
index 7e8de64..0000000
--- a/deps/w32-pthreads/manual/pthread_getw32threadhandle_np.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_GETW32THREADHANDLE_NP manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;322600">
-	<META NAME="CHANGED" CONTENT="20050505;21523500">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P STYLE="font-weight: medium">pthread_getw32threadhandle_np – get
-the Win32 thread handle associated with a thread</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>HANDLE pthread_getw32threadhandle_np(pthread_t</B> <I>thread</I><B>);</B></P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Returns the Win32 native thread <B>HANDLE</B> that the POSIX
-thread <I>thread</I> is running as.</P>
-<P>Applications can use the Win32 handle to set Win32 specific
-attributes of the thread.</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P>None.</P>
-<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
-<P><B>pthread_getw32threadhandle_np</B> returns the Win32 native
-thread <B>HANDLE</B> for the specified POSIX thread <I>thread</I>.</P>
-<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
-<P>None.</P>
-<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
-<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">Author</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_join.html b/deps/w32-pthreads/manual/pthread_join.html
deleted file mode 100644
index 3e3f3b9..0000000
--- a/deps/w32-pthreads/manual/pthread_join.html
+++ /dev/null
@@ -1,118 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_JOIN(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;18232700">
-	<META NAME="CHANGED" CONTENT="20050504;18421400">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_join - wait for termination of another thread 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_join(pthread_t </B><I>th</I><B>, void
-**</B><I>thread_return</I><B>);</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P><B>pthread_join</B> suspends the execution of the calling thread
-until the thread identified by <I>th</I> terminates, either by
-calling <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> or by
-being cancelled. 
-</P>
-<P>If <I>thread_return</I> is not <B>NULL</B>, the return value of <I>th</I>
-is stored in the location pointed to by <I>thread_return</I>. The
-return value of <I>th</I> is either the argument it gave to
-<A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> , or
-<B>PTHREAD_CANCELED</B> if <I>th</I> was cancelled. 
-</P>
-<P>The joined thread <B>th</B> must be in the joinable state: it must
-not have been detached using <A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A>
-or the <B>PTHREAD_CREATE_DETACHED</B> attribute to <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
-. 
-</P>
-<P>When a joinable thread terminates, its memory resources (thread
-descriptor and stack) are not deallocated until another thread
-performs <B>pthread_join</B> on it. Therefore, <B>pthread_join</B>
-must be called once for each joinable thread created to avoid memory
-leaks. 
-</P>
-<P>At most one thread can wait for the termination of a given thread.
-Calling <B>pthread_join</B> on a thread <I>th</I> on which another
-thread is already waiting for termination returns an error. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P><B>pthread_join</B> is a cancellation point. If a thread is
-cancelled while suspended in <B>pthread_join</B>, the thread
-execution resumes immediately and the cancellation is executed
-without waiting for the <I>th</I> thread to terminate. If
-cancellation occurs during <B>pthread_join</B>, the <I>th</I> thread
-remains not joined. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
-<P>On success, the return value of <I>th</I> is stored in the
-location pointed to by <I>thread_return</I>, and 0 is returned. On
-error, a non-zero error code is returned. 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
-<DL>
-	<DT><B>ESRCH</B> 
-	</DT><DD>
-	No thread could be found corresponding to that specified by <I>th</I>.
-		</DD><DT>
-	<B>EINVAL</B> 
-	</DT><DD>
-	The <I>th</I> thread has been detached. 
-	</DD><DT>
-	<B>EINVAL</B> 
-	</DT><DD>
-	Another thread is already waiting on termination of <I>th</I>. 
-	</DD><DT>
-	<B>EDEADLK</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The <I>th</I> argument refers to the calling thread. 
-	</DD></DL>
-<H2>
-<A HREF="#toc6" NAME="sect6">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">See Also</A></H2>
-<P><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> ,
-<A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A> ,
-<A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> ,
-<A HREF="pthread_attr_setdetachstate.html"><B>pthread_attr_setdetachstate</B>(3)</A>
-, <A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_push</B>(3)</A>
-, <A HREF="pthread_key_create.html"><B>pthread_key_create</B>(3)</A>
-. 
-</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Author</A>
-		</P>
-	<LI><P><A HREF="#sect7" NAME="toc7">See Also</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_key_create.html b/deps/w32-pthreads/manual/pthread_key_create.html
deleted file mode 100644
index 5ecca69..0000000
--- a/deps/w32-pthreads/manual/pthread_key_create.html
+++ /dev/null
@@ -1,211 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_SPECIFIC(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;18425400">
-	<META NAME="CHANGED" CONTENT="20050509;18220200">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_key_create, pthread_key_delete, pthread_setspecific,
-pthread_getspecific - management of thread-specific data 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_key_create(pthread_key_t *</B><I>key</I><B>, void
-(*</B><I>destr_function</I><B>) (void *));</B> 
-</P>
-<P><B>int pthread_key_delete(pthread_key_t </B><I>key</I><B>);</B> 
-</P>
-<P><B>int pthread_setspecific(pthread_key_t </B><I>key</I><B>, const
-void *</B><I>pointer</I><B>);</B> 
-</P>
-<P><B>void * pthread_getspecific(pthread_key_t </B><I>key</I><B>);</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Programs often need global or static variables that have different
-values in different threads. Since threads share one memory space,
-this cannot be achieved with regular variables. Thread-specific data
-is the POSIX threads answer to this need. 
-</P>
-<P>Each thread possesses a private memory block, the thread-specific
-data area, or TSD area for short. This area is indexed by TSD keys.
-The TSD area associates values of type <B>void *</B> to TSD keys. TSD
-keys are common to all threads, but the value associated with a given
-TSD key can be different in each thread. 
-</P>
-<P>For concreteness, the TSD areas can be viewed as arrays of <B>void
-*</B> pointers, TSD keys as integer indices into these arrays, and
-the value of a TSD key as the value of the corresponding array
-element in the calling thread. 
-</P>
-<P>When a thread is created, its TSD area initially associates <B>NULL</B>
-with all keys. 
-</P>
-<P><B>pthread_key_create</B> allocates a new TSD key. The key is
-stored in the location pointed to by <I>key</I>. There is a limit of
-<B>PTHREAD_KEYS_MAX</B> on the number of keys allocated at a given
-time. The value initially associated with the returned key is <B>NULL</B>
-in all currently executing threads. 
-</P>
-<P>The <I>destr_function</I> argument, if not <B>NULL</B>, specifies
-a destructor function associated with the key. When a thread
-terminates via <B>pthread_exit</B> or by cancellation, <I>destr_function</I>
-is called with arguments the value associated with the key in that
-thread. The <I>destr_function</I> is not called if that value is <B>NULL</B><SPAN STYLE="font-weight: medium">
-or the key has been deleted</SPAN>. The order in which destructor
-functions are called at thread termination time is unspecified. 
-</P>
-<P>Before the destructor function is called, the <B>NULL</B> value is
-associated with the key in the current thread. A destructor function
-might, however, re-associate non- <B>NULL</B> values to that key or
-some other key. To deal with this, if after all the destructors have
-been called for all non- <B>NULL</B> values, there are still some
-non- <B>NULL</B> values with associated destructors, then the process
-is repeated.</P>
-<P><B>pthread_key_delete</B> deallocates a TSD key. It does not check
-whether non- <B>NULL</B> values are associated with that key in the
-currently executing threads, nor call the destructor function
-associated with the key. 
-</P>
-<P><B>pthread_setspecific</B> changes the value associated with <I>key</I>
-in the calling thread, storing the given <I>pointer</I> instead. 
-</P>
-<P><B>pthread_getspecific</B> returns the value currently associated
-with <I>key</I> in the calling thread. 
-</P>
-<P>The routines <B>pthread_setspecific</B>, <B>pthread_getspecific</B>,
-and <B>pthread_key_delete</B> can be called from <I>destr_function</I>
-targeting any valid key including the key on which <I>destr_function</I>
-is currently operating. If <B>pthread_getspecific</B> is called on
-the key whose thread specific data is being destroyed, the value NULL
-is returned, unless <B>pthread_setspecific</B> was called previously
-on that key from within <I>destr_function</I> to set the value to
-non-NULL. For some implementations the effect of calling
-<B>pthread_setspecific</B> from within <I>destr_function</I> can be
-either memory leakage or infinite loops if <I>destr_function</I> has
-already been called at least <B>PTHREAD_DESTRUCTOR_ITERATIONS</B>
-times.</P>
-<P STYLE="font-weight: medium"><B>Pthreads-w32</B> stops running key
-<I>destr_function</I> routines after <B>PTHREAD_DESTRUCTOR_ITERATIONS</B>
-iterations, even if some non- <B>NULL</B> values with associated
-descriptors remain. If memory is allocated and associated with a key
-from within <I>destr_function</I>, that memory may not be reclaimed
-because that key's <I>destr_function</I>, may not run again.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P><B>pthread_key_create</B>, <B>pthread_key_delete</B>, and
-<B>pthread_setspecific</B> return 0 on success and a non-zero error
-code on failure. If successful, <B>pthread_key_create</B> stores the
-newly allocated key in the location pointed to by its <I>key</I>
-argument. 
-</P>
-<P><B>pthread_getspecific</B> returns the value associated with <I>key</I>
-on success, and <B>NULL</B> on error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P><B>pthread_key_create</B> returns the following error code on
-error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EAGAIN</B> 
-		</DT></DL>
-</DL>
-<BLOCKQUOTE STYLE="margin-left: 5cm">
-<B>PTHREAD_KEYS_MAX</B> keys are already allocated 
-</BLOCKQUOTE>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ENOMEM</B> 
-		</DT></DL>
-</DL>
-<BLOCKQUOTE STYLE="margin-left: 5cm">
-Insufficient memory to allocate the key. 
-</BLOCKQUOTE>
-<P><B>pthread_key_delete</B> and <B>pthread_setspecific</B> return
-the following error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<I>key</I> is not a valid, allocated TSD key 
-		</DD></DL>
-</DL>
-<P>
-<B>pthread_getspecific</B> returns <B>NULL</B> if <I>key</I> is not a
-valid, allocated TSD key. 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
-<P><A HREF="pthread_create.html">pthread_create(3)</A> ,
-<A HREF="pthread_exit.html">pthread_exit(3)</A> ,
-<A HREF="pthread_cancel.html">pthread_testcancel(3)</A> . 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Example</A></H2>
-<P>The following code fragment allocates a thread-specific array of
-100 characters, with automatic reclamation at thread exit: 
-</P>
-<BLOCKQUOTE><BR><BR>
-</BLOCKQUOTE>
-<PRE STYLE="margin-left: 1cm; margin-right: 1cm">/* Key for the thread-specific buffer */
-static pthread_key_t buffer_key;
-/* Once-only initialisation of the key */
-static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
-/* Allocate the thread-specific buffer */
-void buffer_alloc(void)
-{
-  pthread_once(&buffer_key_once, buffer_key_alloc);
-  pthread_setspecific(buffer_key, malloc(100));
-}
-/* Return the thread-specific buffer */
-char * get_buffer(void)
-{
-  return (char *) pthread_getspecific(buffer_key);
-}
-/* Allocate the key */
-static void buffer_key_alloc()
-{
-  pthread_key_create(&buffer_key, buffer_destroy);
-}
-/* Free the thread-specific buffer */
-static void buffer_destroy(void * buf)
-{
-  free(buf);
-}</PRE>
-<HR>
-<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm"><A NAME="toc"></A>
-<B>Table of Contents</B></BLOCKQUOTE>
-<UL>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">See
-	Also</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE><A HREF="#sect7" NAME="toc7">Example</A> 
-	</BLOCKQUOTE>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/pthread_kill.html b/deps/w32-pthreads/manual/pthread_kill.html
deleted file mode 100644
index 33d61b2..0000000
--- a/deps/w32-pthreads/manual/pthread_kill.html
+++ /dev/null
@@ -1,152 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_SIGNAL(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;18500100">
-	<META NAME="CHANGED" CONTENT="20050504;23005800">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_sigmask, pthread_kill, sigwait - handling of signals in
-threads 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> <BR><B>#include <signal.h></B>
-</P>
-<P><B>int pthread_sigmask(int </B><I>how</I><B>, const sigset_t
-*</B><I>newmask</I><B>, sigset_t *</B><I>oldmask</I><B>);</B> 
-</P>
-<P><B>int pthread_kill(pthread_t </B><I>thread</I><B>, int </B><I>signo</I><B>);</B>
-</P>
-<P><B>int sigwait(const sigset_t *</B>set, <B>int</B> *sig);</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P><B>pthread_sigmask</B> changes the signal mask for the calling
-thread as described by the <I>how</I> and <I>newmask</I> arguments.
-If <I>oldmask</I> is not <B>NULL</B>, the previous signal mask is
-stored in the location pointed to by <I>oldmask</I>. <B>Pthreads-w32</B>
-implements this function but no other function uses the signal mask
-yet.</P>
-<P>The meaning of the <I>how</I> and <I>newmask</I> arguments is the
-same as for <B><SPAN STYLE="font-style: normal">sigprocmask</SPAN></B>(2).
-If <I>how</I> is <B>SIG_SETMASK</B>, the signal mask is set to
-<I>newmask</I>. If <I>how</I> is <B>SIG_BLOCK</B>, the signals
-specified to <I>newmask</I> are added to the current signal mask. If
-<I>how</I> is <B>SIG_UNBLOCK</B>, the signals specified to <I>newmask</I>
-are removed from the current signal mask. 
-</P>
-<P>Recall that signal masks are set on a per-thread basis, but signal
-actions and signal handlers, as set with <B>sigaction</B>(2), are
-shared between all threads. 
-</P>
-<P><B>pthread_kill</B> send signal number <I>signo</I> to the thread
-<I>thread</I>. <B>Pthreads-w32</B> only supports signal number 0,
-which does not send any signal but causes <B>pthread_kill</B> to
-return an error if <I>thread</I> is not valid.</P>
-<P><B>sigwait</B> suspends the calling thread until one of the
-signals in <I>set</I> is delivered to the calling thread. It then
-stores the number of the signal received in the location pointed to
-by <I>sig</I> and returns. The signals in <I>set</I> must be blocked
-and not ignored on entrance to <B>sigwait</B>. If the delivered
-signal has a signal handler function attached, that function is <I>not</I>
-called. <B>Pthreads-w32</B> implements this function as a
-cancellation point only - it does not wait for any signals and does
-not change the location pointed to by <I>sig</I>.</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P><B>sigwait</B> is a cancellation point. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
-<P>On success, 0 is returned. On failure, a non-zero error code is
-returned. 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
-<P>The <B>pthread_sigmask</B> function returns the following error
-codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<I>how</I> is not one of <B>SIG_SETMASK</B>, <B>SIG_BLOCK</B>, or
-		<B>SIG_UNBLOCK</B> 
-		</DD></DL>
-</DL>
-<P>
-The <B>pthread_kill</B> function returns the following error codes on
-error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<I>signo</I> is not a valid signal number or is unsupported.</DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<B>ESRCH</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the thread <I>thread</I> does not exist (e.g. it has already
-		terminated) 
-		</DD></DL>
-</DL>
-<P>
-The <B>sigwait</B> function never returns an error. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc7" NAME="sect7">See Also</A></H2>
-<P> 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Notes</A></H2>
-<P>In any implementation, for <B>sigwait</B> to work reliably, the
-signals being waited for must be blocked in all threads, not only in
-the calling thread, since otherwise the POSIX semantics for signal
-delivery do not guarantee that it’s the thread doing the <B>sigwait</B>
-that will receive the signal. The best way to achieve this is to
-block those signals before any threads are created, and never unblock
-them in the program other than by calling <B>sigwait</B>. This works
-because all threads inherit their initial sigmask from their creating
-thread.</P>
-<H2><A HREF="#toc9" NAME="sect9">Bugs</A></H2>
-<P><B>Pthreads-w32</B> does not implement signals yet and so these
-routines have almost no use except to prevent the compiler or linker
-from complaining. <B>pthread_kill</B> is useful in determining if the
-thread is a valid thread, but since many threads implementations
-reuse thread IDs, the valid thread may no longer be the thread you
-think it is, and so this method of determining thread validity is not
-portable, and very risky. <B>Pthreads-w32</B> from version 1.0.0
-onwards implements pseudo-unique thread IDs, so applications that use
-this technique (but really shouldn't) have some protection.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Author</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">See
-	Also</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Notes</A>
-		</P>
-	<LI><P><A HREF="#sect9" NAME="toc9">Bugs</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_mutex_init.html b/deps/w32-pthreads/manual/pthread_mutex_init.html
deleted file mode 100644
index cdb333e..0000000
--- a/deps/w32-pthreads/manual/pthread_mutex_init.html
+++ /dev/null
@@ -1,356 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_MUTEX(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;5000">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<META NAME="CHANGED" CONTENT="20110326;15072100">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-	<STYLE TYPE="text/css">
-	<!--
-		H4.cjk { font-family: "AR PL UMing CN" }
-		H4.ctl { font-family: "Lohit Devanagari" }
-		H2.cjk { font-family: "AR PL UMing CN" }
-		H2.ctl { font-family: "Lohit Devanagari" }
-		PRE.cjk { font-family: "AR PL UMing CN", monospace }
-		PRE.ctl { font-family: "Lohit Devanagari", monospace }
-	-->
-	</STYLE>
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4 CLASS="western">POSIX Threads for Windows – REFERENCE -
-<A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2 CLASS="western"><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_mutex_init, pthread_mutex_lock, pthread_mutex_trylock,
-pthread_mutex_timedlock, pthread_mutex_unlock,
-pthread_mutex_consistent, pthread_mutex_destroy - operations on
-mutexes 
-</P>
-<H2 CLASS="western"><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>#include <time.h></B></P>
-<P><B>pthread_mutex_t </B><I>fastmutex</I> <B>=
-PTHREAD_MUTEX_INITIALIZER;</B> 
-</P>
-<P><B>pthread_mutex_t </B><I>recmutex</I> <B>=
-PTHREAD_RECURSIVE_MUTEX_INITIALIZER;</B> 
-</P>
-<P><B>pthread_mutex_t </B><I>errchkmutex</I> <B>=
-PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;</B> 
-</P>
-<P><B>pthread_mutex_t </B><I>recmutex</I> <B>=
-PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;</B> 
-</P>
-<P><B>pthread_mutex_t </B><I>errchkmutex</I> <B>=
-PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;</B> 
-</P>
-<P><B>int pthread_mutex_init(pthread_mutex_t *</B><I>mutex</I><B>,
-const pthread_mutexattr_t *</B><I>mutexattr</I><B>);</B> 
-</P>
-<P><B>int pthread_mutex_lock(pthread_mutex_t *</B><I>mutex</I><B>);</B>
-</P>
-<P><B>int pthread_mutex_trylock(pthread_mutex_t *</B><I>mutex</I><B>);</B>
-</P>
-<P><B>int pthread_mutex_timedlock(pthread_mutex_t *</B><I>mutex,
-</I><B>const struct timespec *</B><I>abs_timeout</I><B>);</B> 
-</P>
-<P><B>int pthread_mutex_unlock(pthread_mutex_t *</B><I>mutex</I><B>);</B>
-</P>
-<P><B>int pthread_mutex_consistent(pthread_mutex_t *</B><I>mutex</I><B>);</B>
-</P>
-<P><B>int pthread_mutex_destroy(pthread_mutex_t *</B><I>mutex</I><B>);</B>
-</P>
-<H2 CLASS="western"><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>A mutex is a MUTual EXclusion device, and is useful for protecting
-shared data structures from concurrent modifications, and
-implementing critical sections and monitors. 
-</P>
-<P>A mutex has two possible states: unlocked (not owned by any
-thread), and locked (owned by one thread). A mutex can never be owned
-by two different threads simultaneously. A thread attempting to lock
-a mutex that is already locked by another thread is suspended until
-the owning thread unlocks the mutex first. 
-</P>
-<P><B>pthread_mutex_init</B> initializes the mutex object pointed to
-by <I>mutex</I> according to the mutex attributes specified in
-<I>mutexattr</I>. If <I>mutexattr</I> is <B>NULL</B>, default
-attributes are used instead. 
-</P>
-<P>The type of a mutex determines whether it can be locked again by a
-thread that already owns it. The default type is “normal”. See
-<A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_init</B>(3)</A>
-for more information on mutex attributes. 
-</P>
-<P>Variables of type <B>pthread_mutex_t</B> can also be initialized
-statically, using the constants <B>PTHREAD_MUTEX_INITIALIZER</B> (for
-normal “fast” mutexes), <B>PTHREAD_RECURSIVE_MUTEX_INITIALIZER</B>
-(for recursive mutexes), and <B>PTHREAD_ERRORCHECK_MUTEX_INITIALIZER</B>
-(for error checking mutexes). <SPAN STYLE="font-weight: normal">In
-the </SPAN><B>Pthreads-w32</B> <SPAN STYLE="font-weight: normal">implementation,
-an application should still call </SPAN><B>pthread_mutex_destroy</B>
-<SPAN STYLE="font-weight: normal">at some point to ensure that any
-resources consumed by the mutex are released.</SPAN></P>
-<P><SPAN STYLE="font-weight: normal">Any mutex type can be
-initialized as a </SPAN><B>robust mutex</B><SPAN STYLE="font-weight: normal">.
-See </SPAN><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_init</B><SPAN STYLE="font-weight: normal">(3)</SPAN></A>
-<SPAN STYLE="font-weight: normal">for more information as well as the
-section </SPAN><I><U><SPAN STYLE="font-weight: normal">Robust Mutexes</SPAN></U></I>
-<SPAN STYLE="font-weight: normal">below.</SPAN></P>
-<P><B>pthread_mutex_lock</B> locks the given mutex. If the mutex is
-currently unlocked, it becomes locked and owned by the calling
-thread, and <B>pthread_mutex_lock</B> returns immediately. If the
-mutex is already locked by another thread, <B>pthread_mutex_lock</B>
-suspends the calling thread until the mutex is unlocked.</P>
-<P>If the mutex is already locked by the calling thread, the behavior
-of <B>pthread_mutex_lock</B> depends on the type of the mutex. If the
-mutex is of the “normal” type, the calling thread is suspended
-until the mutex is unlocked, thus effectively causing the calling
-thread to deadlock. If the mutex is of the ‘‘error checking’’
-type, <B>pthread_mutex_lock</B> returns immediately with the error
-code <B>EDEADLK</B>. If the mutex is of the ‘‘recursive’’
-type, <B>pthread_mutex_lock</B> succeeds and returns immediately,
-recording the number of times the calling thread has locked the
-mutex. An equal number of <B>pthread_mutex_unlock</B> operations must
-be performed before the mutex returns to the unlocked state. 
-</P>
-<P><B>pthread_mutex_trylock</B> behaves identically to
-<B>pthread_mutex_lock</B>, except that it does not block the calling
-thread if the mutex is already locked by another thread (or by the
-calling thread in the case of a “normal” or “<SPAN STYLE="font-style: normal">errorcheck</SPAN>”
-mutex). Instead, <B>pthread_mutex_trylock</B> returns immediately
-with the error code <B>EBUSY</B>. 
-</P>
-<P><B>pthread_mutex_timedlock</B> behaves identically to
-<B>pthread_mutex_lock</B>, except that if it cannot acquire the lock
-before the <I>abs_timeout</I> time, the call returns with the error
-code <B>ETIMEDOUT</B>. If the mutex can be locked immediately it is,
-and the <B>abs_timeout</B> parameter is ignored.</P>
-<P><B>pthread_mutex_consistent</B> may only be called for
-<B>PTHREAD_MUTEX_ROBUST</B> mutexes. It simply marks the mutex as
-consistent. See <I><U>Robust Mutexes</U></I> below.</P>
-<P><B>pthread_mutex_unlock</B> unlocks the given mutex. The mutex is
-assumed to be locked and owned by the calling thread on entrance to
-<B>pthread_mutex_unlock</B>. If the mutex is of the “normal”
-type, <B>pthread_mutex_unlock</B> always returns it to the unlocked
-state. If it is of the ‘‘recursive’’ type, it decrements the
-locking count of the mutex (number of <B>pthread_mutex_lock</B>
-operations performed on it by the calling thread), and only when this
-count reaches zero is the mutex actually unlocked. In <B>Pthreads-win32</B>,
-non-robust normal or default mutex types do not check the owner of
-the mutex. For all types of robust mutexes the owner is checked and
-an error code is returned if the calling thread does not own the
-mutex.</P>
-<P>On ‘‘error checking’’ mutexes, <B>pthread_mutex_unlock</B>
-actually checks at run-time that the mutex is locked on entrance, and
-that it was locked by the same thread that is now calling
-<B>pthread_mutex_unlock</B>. If these conditions are not met, an
-error code is returned and the mutex remains unchanged. ‘‘Normal’’
-[non-robust] mutexes perform no such checks, thus allowing a locked
-mutex to be unlocked by a thread other than its owner. This is
-non-portable behavior and is not meant to be used as a feature.</P>
-<P><B>pthread_mutex_destroy</B> destroys a mutex object, freeing the
-resources it might hold. The mutex must be unlocked on entrance.</P>
-<H2 CLASS="western"><A HREF="#toc10" NAME="sect10">Robust Mutexes</A></H2>
-<P>If the mutex is <B>PTHREAD_MUTEX_ROBUST</B> and the owning thread
-terminates without unlocking the mutex the implementation will wake
-one waiting thread, if any. The next thread to acquire the mutex will
-receive the error code <B>EOWNERDEAD</B><SPAN STYLE="font-weight: normal">,
-in which case that thread should if possible ensure that the state
-protected by the mutex is consistent and then call
-</SPAN><B>pthread_mutex_consistent</B> <SPAN STYLE="font-weight: normal">before
-unlocking. The mutex may then be used normally from then on.</SPAN></P>
-<P><SPAN STYLE="font-weight: normal">If the thread cannot recover the
-state then it must call </SPAN><B>pthread_mutex_unlock</B><SPAN STYLE="font-weight: normal">
-without calling </SPAN><B>pthread_mutex_consistent</B><SPAN STYLE="font-weight: normal">.
-This will mark the mutex as unusable and wake all currently waiting
-threads with the return code </SPAN><B>ENOTRECOVERABLE</B><SPAN STYLE="font-weight: normal">.
-The error indicates that the mutex is no longer usable and any
-threads that receive this error code from any lock operation have not
-acquired the mutex. The mutex can be made consistent by calling
-</SPAN><B>pthread_mutex_destroy</B> <SPAN STYLE="font-weight: normal">to
-uninitialize the mutex, and calling </SPAN><B>pthread_mutex_int</B>
-<SPAN STYLE="font-weight: normal">to reinitialize the mutex. However,
-the state that was protected by the mutex remains inconsistent and
-some form of application recovery is required.</SPAN></P>
-<P><SPAN STYLE="font-weight: normal">If a thread that receives the
-</SPAN><B>EOWNERDEAD</B> <SPAN STYLE="font-weight: normal">error code
-itself terminates without unlocking the mutex then this behaviour
-repeats for the next acquiring thread.</SPAN></P>
-<P><SPAN STYLE="font-weight: normal">Applications must ensure that
-they check the return values from all calls targeting robust mutexes.</SPAN></P>
-<P STYLE="font-weight: normal">Robust mutexes are slower because they
-require some additional overhead, however they are not very much
-slower than the non-robust recursive type.</P>
-<H2 CLASS="western"><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P>None of the mutex functions is a cancellation point, not even
-<B>pthread_mutex_lock</B>, in spite of the fact that it can suspend a
-thread for arbitrary durations. This way, the status of mutexes at
-cancellation points is predictable, allowing cancellation handlers to
-unlock precisely those mutexes that need to be unlocked before the
-thread stops executing. Consequently, threads using deferred
-cancellation should never hold a mutex for extended periods of time. 
-</P>
-<H2 CLASS="western"><A HREF="#toc4" NAME="sect4">Async-signal Safety</A></H2>
-<P>The mutex functions are not async-signal safe. What this means is
-that they should not be called from a signal handler. In particular,
-calling <B>pthread_mutex_lock</B> or <B>pthread_mutex_unlock</B> from
-a signal handler may deadlock the calling thread. 
-</P>
-<H2 CLASS="western"><A HREF="#toc5" NAME="sect5">Return Value</A></H2>
-<P><B>pthread_mutex_init</B> always returns 0. The other mutex
-functions return 0 on success and a non-zero error code on error. 
-</P>
-<H2 CLASS="western"><A HREF="#toc6" NAME="sect6">Errors</A></H2>
-<P>The <B>pthread_mutex_lock</B> function returns the following error
-code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in"><B>EINVAL</B></DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the mutex has not been properly initialized. 
-		</DD><DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		<B>EDEADLK</B></DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the mutex is already locked by the calling thread (‘‘error
-		checking’’ mutexes only). 
-		</DD><DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		<B>EOWNERDEAD</B></DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the robust mutex is now locked by the calling thread after the
-		previous owner terminated without unlocking it.</DD><DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		<B>ENOTRECOVERABLE</B></DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the robust mutex is not locked and is no longer usable after the
-		previous owner unlocked it without calling
-		pthread_mutex_consistent.</DD></DL>
-	<DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-	The <B>pthread_mutex_trylock</B> function returns the following
-	error codes on error: 
-	</DD><DL>
-		<DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		<B>EBUSY</B> 
-		</DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the mutex could not be acquired because it was currently locked. 
-		</DD><DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		<B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the mutex has not been properly initialized. 
-		</DD><DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		<B>EOWNERDEAD</B></DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the robust mutex is now locked by the calling thread after the
-		previous owner terminated without unlocking it.</DD><DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		<B>ENOTRECOVERABLE</B></DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the robust mutex is not locked and is no longer usable after the
-		previous owner unlocked it without calling
-		pthread_mutex_consistent.</DD></DL>
-</DL>
-<P>
-The <B>pthread_mutex_timedlock</B> function returns the following
-error codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in"><B>ETIMEDOUT</B>
-				</DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the mutex could not be acquired before the <I>abs_timeout</I> time
-		arrived. 
-		</DD><DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		<B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the mutex has not been properly initialized. 
-		</DD><DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		<B>EOWNERDEAD</B></DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the robust mutex is now locked by the calling thread after the
-		previous owner terminated without unlocking it.</DD><DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		<B>ENOTRECOVERABLE</B></DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the robust mutex is not locked and is no longer usable after the
-		previous owner unlocked it without calling
-		pthread_mutex_consistent.</DD></DL>
-</DL>
-<P>
-The <B>pthread_mutex_unlock</B> function returns the following error
-code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in"><B>EINVAL</B>
-				</DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the mutex has not been properly initialized. 
-		</DD><DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		<B>EPERM</B> 
-		</DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the calling thread does not own the mutex (‘‘error checking’’
-		mutexes only). 
-		</DD></DL>
-</DL>
-<P>
-The <B>pthread_mutex_destroy</B> function returns the following error
-code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 0.39in; margin-bottom: 0.2in"><B>EBUSY</B>
-				</DT><DD STYLE="margin-right: 0.39in; margin-bottom: 0.2in">
-		the mutex is currently locked. 
-		</DD></DL>
-</DL>
-<H2 CLASS="western">
-<A HREF="#toc7" NAME="sect7">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2 CLASS="western"><A HREF="#toc8" NAME="sect8">See Also</A></H2>
-<P><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_init</B>(3)</A>
-, <A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_settype</B>(3)</A>
-, <A HREF="pthread_cancel.html"><B>pthread_cancel</B>(3)</A> . 
-</P>
-<H2 CLASS="western"><A HREF="#toc9" NAME="sect9">Example</A></H2>
-<P>A shared global variable <I>x</I> can be protected by a mutex as
-follows: 
-</P>
-<PRE CLASS="western" STYLE="margin-left: 0.39in; margin-right: 0.39in">int x;
-pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;</PRE><BLOCKQUOTE STYLE="margin-left: 0in; margin-right: 0in">
-All accesses and modifications to <I>x</I> should be bracketed by
-calls to <B>pthread_mutex_lock</B> and <B>pthread_mutex_unlock</B> as
-follows: 
-</BLOCKQUOTE>
-<PRE CLASS="western" STYLE="margin-left: 0.41in; margin-right: 0.79in">pthread_mutex_lock(&mut);
-/* operate on x */
-pthread_mutex_unlock(&mut);</PRE>
-<HR>
-<BLOCKQUOTE STYLE="margin-right: 2.75in"><A NAME="toc"></A><B>Table
-of Contents</B></BLOCKQUOTE>
-<UL>
-	<LI><BLOCKQUOTE STYLE="margin-right: 2.75in; margin-bottom: 0in"><A HREF="#sect0" NAME="toc0">Name</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 2.75in; margin-bottom: 0in"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 2.75in; margin-bottom: 0in"><A HREF="#sect2" NAME="toc2">Description</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 2.75in; margin-bottom: 0in"><A HREF="#sect10" NAME="toc10">Robust
-	Mutexes</A></BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 2.75in; margin-bottom: 0in"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 2.75in; margin-bottom: 0in"><A HREF="#sect4" NAME="toc4">Async-signal
-	Safety</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 2.75in; margin-bottom: 0in"><A HREF="#sect5" NAME="toc5">Return
-	Value</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 2.75in; margin-bottom: 0in"><A HREF="#sect6" NAME="toc6">Errors</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 2.75in; margin-bottom: 0in"><A HREF="#sect7" NAME="toc7">Author</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 2.75in; margin-bottom: 0in"><A HREF="#sect8" NAME="toc8">See
-	Also</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-right: 2.75in"><A HREF="#sect9" NAME="toc9">Example</A>
-		</BLOCKQUOTE>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/pthread_mutexattr_init.html b/deps/w32-pthreads/manual/pthread_mutexattr_init.html
deleted file mode 100644
index 760521f..0000000
--- a/deps/w32-pthreads/manual/pthread_mutexattr_init.html
+++ /dev/null
@@ -1,207 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_MUTEXATTR(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;23040500">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<META NAME="CHANGED" CONTENT="20110326;13190500">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-	<STYLE TYPE="text/css">
-	<!--
-		H4.cjk { font-family: "AR PL UMing CN" }
-		H4.ctl { font-family: "Lohit Devanagari" }
-		H2.cjk { font-family: "AR PL UMing CN" }
-		H2.ctl { font-family: "Lohit Devanagari" }
-	-->
-	</STYLE>
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4 CLASS="western">POSIX Threads for Windows – REFERENCE -
-<A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2 CLASS="western"><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_mutexattr_init, pthread_mutexattr_destroy,
-pthread_mutexattr_settype, pthread_mutexattr_gettype - mutex creation
-attributes 
-</P>
-<H2 CLASS="western"><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_mutexattr_init(pthread_mutexattr_t *</B><I>attr</I><B>);</B>
-</P>
-<P><B>int pthread_mutexattr_destroy(pthread_mutexattr_t *</B><I>attr</I><B>);</B>
-</P>
-<P><B>int pthread_mutexattr_settype(pthread_mutexattr_t *</B><I>attr</I><B>,
-int </B><I>type</I><B>);</B> 
-</P>
-<P><B>int pthread_mutexattr_gettype(const pthread_mutexattr_t *</B><I>attr</I><B>,
-int *</B><I>type</I><B>);</B> 
-</P>
-<P><B>int pthread_mutexattr_setkind_np(pthread_mutexattr_t *</B><I>attr</I><B>,
-int </B><I>type</I><B>);</B> 
-</P>
-<P><B>int pthread_mutexattr_getkind_np(const pthread_mutexattr_t
-*</B><I>attr</I><B>, int *</B><I>type</I><B>);</B> 
-</P>
-<P><B>int pthread_mutexattr_setrobust(pthread_mutexattr_t *</B><I>attr</I><B>,
-int</B><SPAN STYLE="font-weight: normal"> </SPAN><I><SPAN STYLE="font-weight: normal">robust</SPAN></I><B>);</B>
-</P>
-<P><B>int pthread_mutexattr_getrobust(pthread_mutexattr_t *</B><I>attr</I><B>,
-int</B><SPAN STYLE="font-weight: normal"> </SPAN><B>*</B><I><SPAN STYLE="font-weight: normal">robust</SPAN></I><B>);</B>
-</P>
-<H2 CLASS="western"><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Mutex attributes can be specified at mutex creation time, by
-passing a mutex attribute object as second argument to
-<A HREF="pthread_mutex_init.html"><B>pthread_mutex_init</B>(3)</A> .
-Passing <B>NULL</B> is equivalent to passing a mutex attribute object
-with all attributes set to their default values. 
-</P>
-<P><B>pthread_mutexattr_init</B> initializes the mutex attribute
-object <I>attr</I> and fills it with default values for the
-attributes. 
-</P>
-<P><B>pthread_mutexattr_destroy</B> destroys a mutex attribute
-object, which must not be reused until it is reinitialized.</P>
-<P><B>pthread_mutexattr_settype</B> sets the mutex type attribute in
-<I>attr</I> to the value specified by <I>type</I>. 
-</P>
-<P><B>pthread_mutexattr_gettype</B> retrieves the current value of
-the mutex kind attribute in <I>attr</I> and stores it in the location
-pointed to by <I>type</I>. 
-</P>
-<P><B>Pthreads-w32</B> also recognises the following equivalent
-functions that are used in Linux:</P>
-<P><B>pthread_mutexattr_setkind_np</B> is an alias for
-<B>pthread_mutexattr_settype</B>. 
-</P>
-<P STYLE="font-weight: normal"><B>pthread_mutexattr_getkind_np</B> is
-an alias for <B>pthread_mutexattr_gettype</B>. 
-</P>
-<P>The following mutex types are supported:</P>
-<P STYLE="margin-left: 0.79in"><B>PTHREAD_MUTEX_NORMAL</B> - for
-‘‘fast’’ mutexes.</P>
-<P STYLE="margin-left: 0.79in"><B>PTHREAD_MUTEX_RECURSIVE</B> - for
-‘‘recursive’’ mutexes.</P>
-<P STYLE="margin-left: 0.79in"><B>PTHREAD_MUTEX_ERRORCHECK</B> - for
-‘‘error checking’’ mutexes.</P>
-<P>The mutex type determines what happens if a thread attempts to
-lock a mutex it already owns with <A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
-. If the mutex is of the “normal” or “fast” type,
-<A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
-simply suspends the calling thread forever. If the mutex is of the
-‘‘error checking’’ type, <A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
-returns immediately with the error code <B>EDEADLK</B>. If the mutex
-is of the ‘‘recursive’’ type, the call to
-<A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
-returns immediately with a success return code. The number of times
-the thread owning the mutex has locked it is recorded in the mutex.
-The owning thread must call <A HREF="pthread_mutex_unlock.html"><B>pthread_mutex_unlock</B>(3)</A>
-the same number of times before the mutex returns to the unlocked
-state. 
-</P>
-<P>The default mutex type is <B>PTHREAD_MUTEX_NORMAL</B></P>
-<P><B>Pthreads-w32</B> also recognises the following equivalent types
-that are used by Linux:</P>
-<P STYLE="margin-left: 0.79in; font-weight: normal"><B>PTHREAD_MUTEX_FAST_NP</B>
-– equivalent to <B>PTHREAD_MUTEX_NORMAL</B></P>
-<P STYLE="margin-left: 0.79in"><B>PTHREAD_MUTEX_RECURSIVE_NP</B></P>
-<P STYLE="margin-left: 0.79in"><B>PTHREAD_MUTEX_ERRORCHECK_NP</B></P>
-<P><B>pthread_mutexattr_setrobust</B><SPAN STYLE="font-weight: normal">
-sets the robustness attribute to the value given by </SPAN><I><SPAN STYLE="font-weight: normal">robust</SPAN></I><SPAN STYLE="font-weight: normal">.</SPAN></P>
-<P><B>pthread_mutexattr_getrobust</B><SPAN STYLE="font-weight: normal">
-returns the current robustness value to the location given by
-*</SPAN><I><SPAN STYLE="font-weight: normal">robust</SPAN></I><SPAN STYLE="font-weight: normal">.</SPAN></P>
-<P><SPAN STYLE="font-weight: normal">The possible values for </SPAN><I><SPAN STYLE="font-weight: normal">robust</SPAN></I><SPAN STYLE="font-weight: normal">
-are:</SPAN></P>
-<P STYLE="margin-left: 0.79in"><B>PTHREAD_MUTEX_STALLED</B><SPAN STYLE="font-weight: normal">
-- when the owner of the mutex terminates without unlocking the mutex,
-all subsequent calls
 to pthread_mutex_*lock() are blocked from
-progress in an unspecified manner.</SPAN></P>
-<P STYLE="margin-left: 0.79in"><B>PTHREAD_MUTEX_ROBUST</B><SPAN STYLE="font-weight: normal">
-- when the owner of the mutex terminates without unlocking the mutex,
-the mutex is
 unlocked. The next owner of this mutex acquires the
-mutex with an error return of
EOWNERDEAD.</SPAN></P>
-<H2 CLASS="western"><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P><SPAN STYLE="font-weight: normal">On success all functions return
-0, otherwise they return an error code as follows:</SPAN></P>
-<P><B>pthread_mutexattr_init</B></P>
-<P STYLE="margin-left: 0.79in"><B>ENOMEM</B><SPAN STYLE="font-weight: normal">
-- insufficient memory for </SPAN><I><SPAN STYLE="font-weight: normal">attr</SPAN></I><SPAN STYLE="font-weight: normal">.</SPAN></P>
-<P><B>pthread_mutexattr_destroy</B></P>
-<P STYLE="margin-left: 0.79in"><B>EINVAL</B><SPAN STYLE="font-weight: normal">
-- </SPAN><I><SPAN STYLE="font-weight: normal">attr</SPAN></I><SPAN STYLE="font-weight: normal">
-is invalid.</SPAN></P>
-<P><B>pthread_mutexattr_gettype</B></P>
-<P STYLE="margin-left: 0.79in"><B>EINVAL</B><SPAN STYLE="font-weight: normal">
-- </SPAN><I><SPAN STYLE="font-weight: normal">attr</SPAN></I><SPAN STYLE="font-weight: normal">
-is invalid.</SPAN></P>
-<P><B>pthread_mutexattr_settype</B></P>
-<DL>
-	<DL>
-		<DL>
-			<DT><B>EINVAL</B><SPAN STYLE="font-weight: normal"> - </SPAN><I><SPAN STYLE="font-weight: normal">attr</SPAN></I><SPAN STYLE="font-weight: normal">
-			is invalid or </SPAN><I><SPAN STYLE="font-weight: normal">type</SPAN></I><SPAN STYLE="font-weight: normal">
-			is none of:</SPAN></DT><DL>
-				<DL>
-					<DT>
-					<B>PTHREAD_MUTEX_NORMAL<BR>PTHREAD_MUTEX_FAST_NP<BR>PTHREAD_MUTEX_RECURSIVE<BR>PTHREAD_MUTEX_RECURSIVE_NP<BR>PTHREAD_MUTEX_ERRORCHECK<BR>PTHREAD_MUTEX_ERRORCHECK_NP</B></DT></DL>
-			</DL>
-		</DL>
-	</DL>
-	<DD STYLE="margin-left: 0in">
-	<BR>
-	</DD></DL>
-<P>
-<B>pthread_mutexattr_getrobust</B></P>
-<P STYLE="margin-left: 0.79in"><B>EINVAL</B><SPAN STYLE="font-weight: normal">
-– </SPAN><I><SPAN STYLE="font-weight: normal">attr</SPAN></I><SPAN STYLE="font-weight: normal">
-or </SPAN><I><SPAN STYLE="font-weight: normal">robust</SPAN></I><SPAN STYLE="font-weight: normal">
-is invalid.</SPAN></P>
-<P><B>pthread_mutexattr_setrobust</B></P>
-<P STYLE="margin-left: 0.79in"><B>EINVAL</B><SPAN STYLE="font-weight: normal">
-– </SPAN><I><SPAN STYLE="font-weight: normal">attr</SPAN></I><SPAN STYLE="font-weight: normal">
-or </SPAN><I><SPAN STYLE="font-weight: normal">robust</SPAN></I><SPAN STYLE="font-weight: normal">
-is invalid.</SPAN></P>
-<H2 CLASS="western"><A HREF="#toc5" NAME="sect5">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2 CLASS="western"><A HREF="#toc6" NAME="sect6">See Also</A></H2>
-<P><A HREF="pthread_mutex_init.html"><B>pthread_mutex_init</B>(3)</A>
-, <A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
-, <A HREF="pthread_mutex_unlock.html"><B>pthread_mutex_unlock</B>(3)</A>
-. 
-</P>
-<H2 CLASS="western"><A HREF="#toc7" NAME="sect7"><FONT COLOR="#000080"><U>Notes</U></FONT></A></H2>
-<P>For speed, <B>Pthreads-w32</B> never checks the thread ownership
-of non-robust mutexes of type <B>PTHREAD_MUTEX_NORMAL</B> (or
-<B>PTHREAD_MUTEX_FAST_NP</B>) when performing operations on the
-mutex. It is therefore possible for one thread to lock such a mutex
-and another to unlock it.</P>
-<P STYLE="font-weight: normal">When developing code, it is a common
-precaution to substitute the error checking type, then drop in the
-normal type for release if the extra performance is required.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect5" NAME="toc5">Author</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0in"><A HREF="#sect6" NAME="toc6">See
-	Also</A></P>
-	<LI><P><A HREF="#sect7" NAME="toc7">Notes</A></P>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/pthread_mutexattr_setpshared.html b/deps/w32-pthreads/manual/pthread_mutexattr_setpshared.html
deleted file mode 100644
index 25bf9f6..0000000
--- a/deps/w32-pthreads/manual/pthread_mutexattr_setpshared.html
+++ /dev/null
@@ -1,151 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_MUTEXATTR_GETPSHARED"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;23480600">
-	<META NAME="CHANGED" CONTENT="20050505;18381800">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_mutexattr_getpshared, pthread_mutexattr_setpshared - get
-and set the process-shared attribute 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_mutexattr_getpshared(const pthread_mutexattr_t *
-restrict</B> <I>attr</I><B>, int *restrict</B> <I>pshared</I><B>);
-<BR>int pthread_mutexattr_setpshared(pthread_mutexattr_t *</B><I>attr</I><B>,
-int</B> <I>pshared</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_mutexattr_getpshared</B> function shall obtain the
-value of the <I>process-shared</I> attribute from the attributes
-object referenced by <I>attr</I>. The <B>pthread_mutexattr_setpshared</B>
-function shall set the <I>process-shared</I> attribute in an
-initialized attributes object referenced by <I>attr</I>. 
-</P>
-<P>The <I>process-shared</I> attribute is set to
-<B>PTHREAD_PROCESS_SHARED</B> to permit a mutex to be operated upon
-by any thread that has access to the memory where the mutex is
-allocated, even if the mutex is allocated in memory that is shared by
-multiple processes. If the <I>process-shared</I> attribute is
-<B>PTHREAD_PROCESS_PRIVATE</B>, the mutex shall only be operated upon
-by threads created within the same process as the thread that
-initialized the mutex; if threads of differing processes attempt to
-operate on such a mutex, the behavior is undefined. The default value
-of the attribute shall be <B>PTHREAD_PROCESS_PRIVATE</B>. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_PROCESS_SHARED</B> in
-pthread.h as -1 to indicate that these routines are implemented but
-the process shared option is not supported.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>Upon successful completion, <B>pthread_mutexattr_setpshared</B>
-shall return zero; otherwise, an error number shall be returned to
-indicate the error. 
-</P>
-<P>Upon successful completion, <B>pthread_mutexattr_getpshared</B>
-shall return zero and store the value of the <I>process-shared</I>
-attribute of <I>attr</I> into the object referenced by the <I>pshared</I>
-parameter. Otherwise, an error number shall be returned to indicate
-the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_mutexattr_getpshared</B> and
-<B>pthread_mutexattr_setpshared</B> functions may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>attr</I> is invalid. 
-	</DD></DL>
-<P>
-The <B>pthread_mutexattr_setpshared</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The new value specified for the attribute is outside the range of
-	legal values for that attribute. 
-	</DD><DT>
-	<B>ENOTSUP</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The new value specified for the attribute is PTHREAD_PROCESS_SHARED.
-		</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_cond_init.html"><B>pthread_cond_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> <B>,</B>
-<A HREF="pthread_mutex_init.html"><B>pthread_mutex_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_destroy</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_num_processors_np.html b/deps/w32-pthreads/manual/pthread_num_processors_np.html
deleted file mode 100644
index 0509410..0000000
--- a/deps/w32-pthreads/manual/pthread_num_processors_np.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_NUM_PROCESSORS_NP manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;322600">
-	<META NAME="CHANGED" CONTENT="20050505;21514100">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P STYLE="font-weight: medium">pthread_num_processors_np – get the
-number of processors (CPUs) in use by the process</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_num_processors_np(void);</B></P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P><B>pthread_num_processors_np </B>returns the number of processors
-in the system. This implementation actually returns the number of
-processors available to the process, which can be a lower number than
-the system's number, depending on the process's affinity mask.</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P>None.</P>
-<H2><A HREF="#toc4" NAME="sect4"><FONT COLOR="#000080">Return Value</FONT></A></H2>
-<P><B>pthread_num_processors_np</B> returns the number of processors
-currently available to the process.</P>
-<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
-<P>None.</P>
-<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
-<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">Author</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_once.html b/deps/w32-pthreads/manual/pthread_once.html
deleted file mode 100644
index 856fb86..0000000
--- a/deps/w32-pthreads/manual/pthread_once.html
+++ /dev/null
@@ -1,83 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_ONCE(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;322600">
-	<META NAME="CHANGED" CONTENT="20050603;463100">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_once - once-only initialization 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>pthread_once_t </B><I>once_control</I> <B>= PTHREAD_ONCE_INIT;</B>
-</P>
-<P><B>int pthread_once(pthread_once_t *</B><I>once_control</I><B>,
-void (*</B><I>init_routine</I><B>) (void));</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The purpose of <B>pthread_once</B> is to ensure that a piece of
-initialization code is executed at most once. The <I>once_control</I>
-argument points to a static or extern variable statically initialized
-to <B>PTHREAD_ONCE_INIT</B>. 
-</P>
-<P>The first time <B>pthread_once</B> is called with a given
-<I>once_control</I> argument, it calls <I>init_routine</I> with no
-argument and changes the value of the <I>once_control</I> variable to
-record that initialization has been performed. Subsequent calls to
-<B>pthread_once</B> with the same <B>once_control</B> argument do
-nothing. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P>While <B>pthread_once</B> is not a cancellation point,
-<I>init_routine</I> can be. The effect on <I>once_control</I> of a
-cancellation inside the <I>init_routine</I> is to leave it as if
-<B>pthread_once</B> had not been called by the cancelled thread.</P>
-<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
-<P STYLE="text-decoration: none"><FONT COLOR="#000000"><B>pthread_once</B>
-returns 0 on success, or an error code on failure.</FONT></P>
-<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
-<P>The <B>pthread_once</B> function returns the following error code
-on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT></DL>
-</DL>
-<P STYLE="margin-left: 2cm">
-The once_control or init_routine parameter is NULL.</P>
-<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">Author</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/pthread_rwlock_init.html b/deps/w32-pthreads/manual/pthread_rwlock_init.html
deleted file mode 100644
index 530df93..0000000
--- a/deps/w32-pthreads/manual/pthread_rwlock_init.html
+++ /dev/null
@@ -1,193 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_RWLOCK_DESTROY"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;10211800">
-	<META NAME="CHANGED" CONTENT="20050505;18563400">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_rwlock_destroy, pthread_rwlock_init - destroy and
-initialize a read-write lock object 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>pthread_wrlock_t </B><I>rwlock</I> <B>=
-PTHREAD_RWLOCK_INITIALIZER;</B></P>
-<P><B>int pthread_rwlock_destroy(pthread_rwlock_t *</B><I>rwlock</I><B>);
-<BR>int pthread_rwlock_init(pthread_rwlock_t *restrict</B> <I>rwlock</I><B>,
-const pthread_rwlockattr_t *restrict</B> <I>attr</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_rwlock_destroy</B> function shall destroy the
-read-write lock object referenced by <I>rwlock</I> and release any
-resources used by the lock. The effect of subsequent use of the lock
-is undefined until the lock is reinitialized by another call to
-<B>pthread_rwlock_init</B>. An implementation may cause
-<B>pthread_rwlock_destroy</B> to set the object referenced by <I>rwlock</I>
-to an invalid value. Results are undefined if <B>pthread_rwlock_destroy</B>
-is called when any thread holds <I>rwlock</I>. Attempting to destroy
-an uninitialized read-write lock results in undefined behavior. 
-</P>
-<P>The <B>pthread_rwlock_init</B> function shall allocate any
-resources required to use the read-write lock referenced by <I>rwlock</I>
-and initializes the lock to an unlocked state with attributes
-referenced by <I>attr</I>. If <I>attr</I> is NULL, the default
-read-write lock attributes shall be used; the effect is the same as
-passing the address of a default read-write lock attributes object.
-Once initialized, the lock can be used any number of times without
-being reinitialized. Results are undefined if <B>pthread_rwlock_init</B>
-is called specifying an already initialized read-write lock. Results
-are undefined if a read-write lock is used without first being
-initialized. 
-</P>
-<P>If the <B>pthread_rwlock_init</B> function fails, <I>rwlock</I>
-shall not be initialized and the contents of <I>rwlock</I> are
-undefined. 
-</P>
-<P><B>Pthreads-w32</B> supports statically initialized <I>rwlock</I>
-objects using <B>PTHREAD_RWLOCK_INITIALIZER</B>. <SPAN STYLE="font-weight: medium">
-An application should still call <B>pthread_rwlock_destroy</B> at
-some point to ensure that any resources consumed by the read/write
-lock are released.</SPAN></P>
-<P>Only the object referenced by <I>rwlock</I> may be used for
-performing synchronization. The result of referring to copies of that
-object in calls to <B>pthread_rwlock_destroy</B> ,
-<B>pthread_rwlock_rdlock</B> , <B>pthread_rwlock_timedrdlock</B> ,
-<B>pthread_rwlock_timedwrlock</B> , <B>pthread_rwlock_tryrdlock</B> ,
-<B>pthread_rwlock_trywrlock</B> , <B>pthread_rwlock_unlock</B> , or
-<B>pthread_rwlock_wrlock</B> is undefined. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
-pthread.h as 200112L to indicate that the reader/writer routines are
-implemented and may be used.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>If successful, the <B>pthread_rwlock_destroy</B> and
-<B>pthread_rwlock_init</B> functions shall return zero; otherwise, an
-error number shall be returned to indicate the error. 
-</P>
-<P>The [EBUSY] and [EINVAL] error checks, if implemented, act as if
-they were performed immediately at the beginning of processing for
-the function and caused an error return prior to modifying the state
-of the read-write lock specified by <I>rwlock</I>. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_rwlock_destroy</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EBUSY</B> 
-	</DT><DD>
-	The implementation has detected an attempt to destroy the object
-	referenced by <I>rwlock</I> while it is locked. 
-	</DD><DT>
-	<B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>rwlock</I> is invalid. 
-	</DD></DL>
-<P>
-The <B>pthread_rwlock_init</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>EAGAIN</B> 
-	</DT><DD>
-	The system lacked the necessary resources (other than memory) to
-	initialize another read-write lock. 
-	</DD><DT>
-	<B>ENOMEM</B> 
-	</DT><DD>
-	Insufficient memory exists to initialize the read-write lock. 
-	</DD><DD STYLE="margin-left: 0cm; margin-bottom: 0.5cm">
-	<BR><BR>
-	</DD></DL>
-<P>
-The <B>pthread_rwlock_init</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>attr</I> is invalid. 
-	</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>Applications using these and related read-write lock functions may
-be subject to priority inversion, as discussed in the Base
-Definitions volume of IEEE Std 1003.1-2001, Section 3.285,
-Priority Inversion. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_rwlock_rdlock.html b/deps/w32-pthreads/manual/pthread_rwlock_rdlock.html
deleted file mode 100644
index 3b63f25..0000000
--- a/deps/w32-pthreads/manual/pthread_rwlock_rdlock.html
+++ /dev/null
@@ -1,168 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_RWLOCK_RDLOCK"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;10352600">
-	<META NAME="CHANGED" CONTENT="20050505;12554200">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_rwlock_rdlock, pthread_rwlock_tryrdlock - lock a
-read-write lock object for reading 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_rwlock_rdlock(pthread_rwlock_t <I>*</I></B><I>rwlock</I><B>);
-<BR></B>i<B>nt pthread_rwlock_tryrdlock(pthread_rwlock_t <I>*</I></B><I>rwlock</I><B>);
-</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_rwlock_rdlock</B> function shall apply a read lock
-to the read-write lock referenced by <I>rwlock</I>. The calling
-thread acquires the read lock if a writer does not hold the lock and
-there are no writers blocked on the lock. 
-</P>
-<P><B>Pthreads-win32</B> does not prefer either writers or readers in
-acquiring the lock – all threads enter a single prioritised FIFO
-queue. While this may not be optimally efficient for some
-applications, it does ensure that one type does not starve the other.</P>
-<P>A thread may hold multiple concurrent read locks on <I>rwlock</I>
-(that is, successfully call the <B>pthread_rwlock_rdlock</B> function
-<I>n</I> times). If so, the application shall ensure that the thread
-performs matching unlocks (that is, it calls the
-<A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
-function <I>n</I> times). 
-</P>
-<P>The <B>pthread_rwlock_tryrdlock</B> function shall apply a read
-lock as in the <B>pthread_rwlock_rdlock</B> function, with the
-exception that the function shall fail if the equivalent
-<B>pthread_rwlock_rdlock</B> call would have blocked the calling
-thread. In no case shall the <B>pthread_rwlock_tryrdlock</B> function
-ever block; it always either acquires the lock or fails and returns
-immediately. 
-</P>
-<P>Results are undefined if any of these functions are called with an
-uninitialized read-write lock. 
-</P>
-<P><B>Pthreads-w32</B> does not detect deadlock if the thread already
-owns the lock for writing.</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
-pthread.h as  200112L to indicate that the reader/writer routines are
-implemented and may be used.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>If successful, the <B>pthread_rwlock_rdlock</B> function shall
-return zero; otherwise, an error number shall be returned to indicate
-the error. 
-</P>
-<P>The <B>pthread_rwlock_tryrdlock</B> function shall return zero if
-the lock for reading on the read-write lock object referenced by
-<I>rwlock</I> is acquired. Otherwise, an error number shall be
-returned to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_rwlock_tryrdlock</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>EBUSY</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The read-write lock could not be acquired for reading because a
-	writer holds the lock or a writer with the appropriate priority was
-	blocked on it. 
-	</DD></DL>
-<P>
-The <B>pthread_rwlock_rdlock</B> and <B>pthread_rwlock_tryrdlock</B>
-functions may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD>
-	The value specified by <I>rwlock</I> does not refer to an
-	initialized read-write lock object. 
-	</DD><DT>
-	<B>EAGAIN</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The read lock could not be acquired because the maximum number of
-	read locks for <I>rwlock</I> has been exceeded. 
-	</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>Applications using these functions may be subject to priority
-inversion, as discussed in the Base Definitions volume of
-IEEE Std 1003.1-2001, Section 3.285, Priority Inversion. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_rwlock_timedrdlock.html b/deps/w32-pthreads/manual/pthread_rwlock_timedrdlock.html
deleted file mode 100644
index 1b9ca63..0000000
--- a/deps/w32-pthreads/manual/pthread_rwlock_timedrdlock.html
+++ /dev/null
@@ -1,156 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_RWLOCK_TIMEDRDLOCK"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;11101700">
-	<META NAME="CHANGED" CONTENT="20050505;12560000">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_rwlock_timedrdlock - lock a read-write lock for reading 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> <BR></B>#include <time.h> 
-</P>
-<P><B>int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict</B>
-<I>rwlock</I><B>, const struct timespec *restrict</B> <I>abs_timeout</I><B>);
-</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_rwlock_timedrdlock</B> function shall apply a read
-lock to the read-write lock referenced by <I>rwlock</I> as in the
-<A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
-function. However, if the lock cannot be acquired without waiting for
-other threads to unlock the lock, this wait shall be terminated when
-the specified timeout expires. The timeout shall expire when the
-absolute time specified by <I>abs_timeout</I> passes, as measured by
-the clock on which timeouts are based (that is, when the value of
-that clock equals or exceeds <I>abs_timeout</I>), or if the absolute
-time specified by <I>abs_timeout</I> has already been passed at the
-time of the call. 
-</P>
-<P>The <B>timespec</B> data type is defined in the <I><time.h></I>
-header. Under no circumstances shall the function fail with a timeout
-if the lock can be acquired immediately. The validity of the
-<I>abs_timeout</I> parameter need not be checked if the lock can be
-immediately acquired. 
-</P>
-<P>The calling thread may deadlock if at the time the call is made it
-holds a write lock on <I>rwlock</I>. The results are undefined if
-this function is called with an uninitialized read-write lock. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
-pthread.h as  200112L to indicate that the reader/writer routines are
-implemented and may be used.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>The <B>pthread_rwlock_timedrdlock</B> function shall return zero
-if the lock for reading on the read-write lock object referenced by
-<I>rwlock</I> is acquired. Otherwise, an error number shall be
-returned to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_rwlock_timedrdlock</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>ETIMEDOUT</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The lock could not be acquired before the specified timeout expired.
-		</DD></DL>
-<P>
-The <B>pthread_rwlock_timedrdlock</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EAGAIN</B> 
-	</DT><DD>
-	The read lock could not be acquired because the maximum number of
-	read locks for lock would be exceeded. 
-	</DD><DT>
-	<B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>rwlock</I> does not refer to an
-	initialized read-write lock object, or the <I>abs_timeout</I>
-	nanosecond value is less than zero or greater than or equal to 1000
-	million. 
-	</DD></DL>
-<P>
-This function shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>Applications using this function may be subject to priority
-inversion, as discussed in the Base Definitions volume of
-IEEE Std 1003.1-2001, Section 3.285, Priority Inversion. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I>, <I><time.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_rwlock_timedwrlock.html b/deps/w32-pthreads/manual/pthread_rwlock_timedwrlock.html
deleted file mode 100644
index 0213bab..0000000
--- a/deps/w32-pthreads/manual/pthread_rwlock_timedwrlock.html
+++ /dev/null
@@ -1,150 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_RWLOCK_TIMEDWRLOCK"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;11172800">
-	<META NAME="CHANGED" CONTENT="20050505;12561600">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_rwlock_timedwrlock - lock a read-write lock for writing 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> <BR></B>#include <time.h> 
-</P>
-<P><B>int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict</B>
-<I>rwlock</I><B>, const struct timespec *restrict</B> <I>abs_timeout</I><B>);
-</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_rwlock_timedwrlock</B> function shall apply a write
-lock to the read-write lock referenced by <I>rwlock</I> as in the
-<A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
-function. However, if the lock cannot be acquired without waiting for
-other threads to unlock the lock, this wait shall be terminated when
-the specified timeout expires. The timeout shall expire when the
-absolute time specified by <I>abs_timeout</I> passes, as measured by
-the clock on which timeouts are based (that is, when the value of
-that clock equals or exceeds <I>abs_timeout</I>), or if the absolute
-time specified by <I>abs_timeout</I> has already been passed at the
-time of the call. 
-</P>
-<P>The <B>timespec</B> data type is defined in the <I><time.h></I>
-header. Under no circumstances shall the function fail with a timeout
-if the lock can be acquired immediately. The validity of the
-<I>abs_timeout</I> parameter need not be checked if the lock can be
-immediately acquired. 
-</P>
-<P>The calling thread may deadlock if at the time the call is made it
-holds the read-write lock. The results are undefined if this function
-is called with an uninitialized read-write lock. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
-pthread.h as  200112L to indicate that the reader/writer routines are
-implemented and may be used.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>The <B>pthread_rwlock_timedwrlock</B> function shall return zero
-if the lock for writing on the read-write lock object referenced by
-<I>rwlock</I> is acquired. Otherwise, an error number shall be
-returned to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_rwlock_timedwrlock</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>ETIMEDOUT</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The lock could not be acquired before the specified timeout expired.
-		</DD></DL>
-<P>
-The <B>pthread_rwlock_timedwrlock</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by rwlock does not refer to an initialized
-	read-write lock object, or the <I>abs_timeout</I> nanosecond value
-	is less than zero or greater than or equal to 1000 million. 
-	</DD></DL>
-<P>
-This function shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>Applications using this function may be subject to priority
-inversion, as discussed in the Base Definitions volume of
-IEEE Std 1003.1-2001, Section 3.285, Priority Inversion. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I>, <I><time.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_rwlock_unlock.html b/deps/w32-pthreads/manual/pthread_rwlock_unlock.html
deleted file mode 100644
index 09725cc..0000000
--- a/deps/w32-pthreads/manual/pthread_rwlock_unlock.html
+++ /dev/null
@@ -1,141 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_RWLOCK_UNLOCK"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;11291100">
-	<META NAME="CHANGED" CONTENT="20050505;12562700">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_rwlock_unlock - unlock a read-write lock object 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P>in<B>t pthread_rwlock_unlock(pthread_rwlock_t <I>*</I></B><I>rwlock</I><B>);
-</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_rwlock_unlock</B> function shall release a lock
-held on the read-write lock object referenced by <I>rwlock</I>.
-Results are undefined if the read-write lock <I>rwlock</I> is not
-held by the calling thread. 
-</P>
-<P>If this function is called to release a read lock from the
-read-write lock object and there are other read locks currently held
-on this read-write lock object, the read-write lock object remains in
-the read locked state. If this function releases the last read lock
-for this read-write lock object, the read-write lock object shall be
-put in the unlocked state with no owners. 
-</P>
-<P>If this function is called to release a write lock for this
-read-write lock object, the read-write lock object shall be put in
-the unlocked state. 
-</P>
-<P><B>Pthreads-win32</B> does not prefer either writers or readers in
-acquiring the lock – all threads enter a single prioritised FIFO
-queue. While this may not be optimally efficient for some
-applications, it does ensure that one type does not starve the other.</P>
-<P>Results are undefined if any of these functions are called with an
-uninitialized read-write lock. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
-pthread.h as  200112L to indicate that the reader/writer routines are
-implemented and may be used.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>If successful, the <B>pthread_rwlock_unlock</B> function shall
-return zero; otherwise, an error number shall be returned to indicate
-the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_rwlock_unlock</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD>
-	The value specified by <I>rwlock</I> does not refer to an
-	initialized read-write lock object. 
-	</DD><DD STYLE="margin-left: 0cm; margin-bottom: 0.5cm">
-	<BR><BR>
-	</DD></DL>
-<P>
-The <B>pthread_rwlock_unlock</B> function shall not return an error
-code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
-, the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_rwlock_wrlock.html b/deps/w32-pthreads/manual/pthread_rwlock_wrlock.html
deleted file mode 100644
index 02b3a19..0000000
--- a/deps/w32-pthreads/manual/pthread_rwlock_wrlock.html
+++ /dev/null
@@ -1,153 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_RWLOCK_TRYWRLOCK"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;11221900">
-	<META NAME="CHANGED" CONTENT="20050505;12563800">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_rwlock_trywrlock, pthread_rwlock_wrlock - lock a
-read-write lock object for writing 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_rwlock_trywrlock(pthread_rwlock_t <I>*</I></B><I>rwlock</I><B>);
-<BR>int pthread_rwlock_wrlock(pthread_rwlock_t <I>*</I></B><I>rwlock</I><B>);
-</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_rwlock_trywrlock</B> function shall apply a write
-lock like the <B>pthread_rwlock_wrlock</B> function, with the
-exception that the function shall fail if any thread currently holds
-<I>rwlock</I> (for reading or writing). 
-</P>
-<P>The <B>pthread_rwlock_wrlock</B> function shall apply a write lock
-to the read-write lock referenced by <I>rwlock</I>. The calling
-thread acquires the write lock if no other thread (reader or writer)
-holds the read-write lock <I>rwlock</I>. Otherwise, the thread shall
-block until it can acquire the lock. The calling thread may deadlock
-if at the time the call is made it holds the read-write lock (whether
-a read or write lock). 
-</P>
-<P><B>Pthreads-win32</B> does not prefer either writers or readers in
-acquiring the lock – all threads enter a single prioritised FIFO
-queue. While this may not be optimally efficient for some
-applications, it does ensure that one type does not starve the other.</P>
-<P>Results are undefined if any of these functions are called with an
-uninitialized read-write lock. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
-pthread.h as  200112L to indicate that the reader/writer routines are
-implemented and may be used.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>The <B>pthread_rwlock_trywrlock</B> function shall return zero if
-the lock for writing on the read-write lock object referenced by
-<I>rwlock</I> is acquired. Otherwise, an error number shall be
-returned to indicate the error. 
-</P>
-<P>If successful, the <B>pthread_rwlock_wrlock</B> function shall
-return zero; otherwise, an error number shall be returned to indicate
-the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_rwlock_trywrlock</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>EBUSY</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The read-write lock could not be acquired for writing because it was
-	already locked for reading or writing. 
-	</DD></DL>
-<P>
-The <B>pthread_rwlock_trywrlock</B> and <B>pthread_rwlock_wrlock</B>
-functions may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>rwlock</I> does not refer to an
-	initialized read-write lock object. 
-	</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>Applications using these functions may be subject to priority
-inversion, as discussed in the Base Definitions volume of
-IEEE Std 1003.1-2001, Section 3.285, Priority Inversion. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_rwlockattr_init.html b/deps/w32-pthreads/manual/pthread_rwlockattr_init.html
deleted file mode 100644
index 67da876..0000000
--- a/deps/w32-pthreads/manual/pthread_rwlockattr_init.html
+++ /dev/null
@@ -1,141 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_RWLOCKATTR_DESTROY"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;504000">
-	<META NAME="CHANGED" CONTENT="20050505;18474200">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_rwlockattr_destroy, pthread_rwlockattr_init - destroy and
-initialize the read-write lock attributes object 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_rwlockattr_destroy(pthread_rwlockattr_t <I>*</I></B><I>attr</I><B>);
-<BR>int pthread_rwlockattr_init(pthread_rwlockattr_t <I>*</I></B><I>attr</I><B>);
-</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_rwlockattr_destroy</B> function shall destroy a
-read-write lock attributes object. A destroyed <I>attr</I> attributes
-object can be reinitialized using <B>pthread_rwlockattr_init</B> ;
-the results of otherwise referencing the object after it has been
-destroyed are undefined. An implementation may cause
-<B>pthread_rwlockattr_destroy</B> to set the object referenced by
-<I>attr</I> to an invalid value. 
-</P>
-<P>The <B>pthread_rwlockattr_init</B> function shall initialize a
-read-write lock attributes object <I>attr</I> with the default value
-for all of the attributes defined by the implementation. 
-</P>
-<P>Results are undefined if <B>pthread_rwlockattr_init</B> is called
-specifying an already initialized <I>attr</I> attributes object. 
-</P>
-<P>After a read-write lock attributes object has been used to
-initialize one or more read-write locks, any function affecting the
-attributes object (including destruction) shall not affect any
-previously initialized read-write locks. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
-pthread.h as 200112L to indicate that the reader/writer routines are
-implemented and may be used.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>If successful, the <B>pthread_rwlockattr_destroy</B> and
-<B>pthread_rwlockattr_init</B> functions shall return zero;
-otherwise, an error number shall be returned to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_rwlockattr_destroy</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>attr</I> is invalid. 
-	</DD></DL>
-<P>
-The <B>pthread_rwlockattr_init</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>ENOMEM</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	Insufficient memory exists to initialize the read-write lock
-	attributes object. 
-	</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlockattr_setpshared.html"><B>pthread_rwlockattr_getpshared</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlockattr_setpshared.html"><B>pthread_rwlockattr_setpshared</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_rwlockattr_setpshared.html b/deps/w32-pthreads/manual/pthread_rwlockattr_setpshared.html
deleted file mode 100644
index 9db6f4c..0000000
--- a/deps/w32-pthreads/manual/pthread_rwlockattr_setpshared.html
+++ /dev/null
@@ -1,160 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_RWLOCKATTR_GETPSHARED"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;10124400">
-	<META NAME="CHANGED" CONTENT="20050505;12572100">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_rwlockattr_getpshared, pthread_rwlockattr_setpshared - get
-and set the process-shared attribute of the read-write lock
-attributes object 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *
-restrict </B><I>attr</I><B>, int *restrict</B> <I>pshared</I><B>);
-<BR>int pthread_rwlockattr_setpshared(pthread_rwlockattr_t <I>*</I></B><I>attr</I><B>,
-int</B> <I>pshared</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_rwlockattr_getpshared</B> function shall obtain the
-value of the <I>process-shared</I> attribute from the initialized
-attributes object referenced by <I>attr</I>. The
-<B>pthread_rwlockattr_setpshared</B> function shall set the
-<I>process-shared</I> attribute in an initialized attributes object
-referenced by <I>attr</I>. 
-</P>
-<P>The <I>process-shared</I> attribute shall be set to
-<B>PTHREAD_PROCESS_SHARED</B> to permit a read-write lock to be
-operated upon by any thread that has access to the memory where the
-read-write lock is allocated, even if the read-write lock is
-allocated in memory that is shared by multiple processes. If the
-<I>process-shared</I> attribute is <B>PTHREAD_PROCESS_PRIVATE</B>,
-the read-write lock shall only be operated upon by threads created
-within the same process as the thread that initialized the read-write
-lock; if threads of differing processes attempt to operate on such a
-read-write lock, the behavior is undefined. The default value of the
-<I>process-shared</I> attribute shall be <B>PTHREAD_PROCESS_PRIVATE</B>.
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_PROCESS_SHARED</B> in
-pthread.h as -1 to indicate that these routines are implemented but
-they do not support the process shared option.</P>
-<P>Additional attributes, their default values, and the names of the
-associated functions to get and set those attribute values are
-implementation-defined. 
-</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
-pthread.h as  200112L to indicate that the reader/writer routines are
-implemented and may be used.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>Upon successful completion, the <B>pthread_rwlockattr_getpshared</B>
-function shall return zero and store the value of the <I>process-shared</I>
-attribute of <I>attr</I> into the object referenced by the <I>pshared</I>
-parameter. Otherwise, an error number shall be returned to indicate
-the error. 
-</P>
-<P>If successful, the <B>pthread_rwlockattr_setpshared</B> function
-shall return zero; otherwise, an error number shall be returned to
-indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_rwlockattr_getpshared</B> and
-<B>pthread_rwlockattr_setpshared</B> functions may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>attr</I> is invalid. 
-	</DD></DL>
-<P>
-The <B>pthread_rwlockattr_setpshared</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The new value specified for the attribute is outside the range of
-	legal values for that attribute. 
-	</DD><DT>
-	<B>ENOTSUP</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The new value specified for the attribute is <B>PTHREAD_PROCESS_SHARED</B>.
-		</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlockattr_init.html"><B>pthread_rwlockattr_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_rwlockattr_init.html"><B>pthread_rwlockattr_init</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_self.html b/deps/w32-pthreads/manual/pthread_self.html
deleted file mode 100644
index 82e16ea..0000000
--- a/deps/w32-pthreads/manual/pthread_self.html
+++ /dev/null
@@ -1,70 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_SELF(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;11361600">
-	<META NAME="CHANGED" CONTENT="20050505;11575700">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_self - return identifier of current thread 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>pthread_t pthread_self(void);</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P><B>pthread_self</B> return the thread identifier for the calling
-thread. 
-</P>
-<P><B>Pthreads-w32</B> also provides support for <B>Win32</B> native
-threads to interact with POSIX threads through the pthreads API.
-Whereas all threads created via a call to pthread_create have a POSIX
-thread ID and thread state, the library ensures that any Win32 native
-threads that interact through the Pthreads API also generate a POSIX
-thread ID and thread state when and if necessary. This provides full
-<SPAN LANG="en-GB">reciprocity</SPAN> between Win32 and POSIX
-threads. Win32 native threads that generate a POSIX thread ID and
-state are treated by the library as having been created with the
-<B>PTHREAD_CREATE_DETACHED</B> attribute.</P>
-<P>Any Win32 native thread may call <B>pthread_self</B> directly to
-return it's POSIX thread identifier. The ID and state will be
-generated if it does not already exist. Win32 native threads do not
-need to call <B>pthread_self</B> before calling Pthreads-w32 routines
-unless that routine requires a pthread_t parameter.</P>
-<H2><A HREF="#toc3" NAME="sect3">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc4" NAME="sect4">See Also</A></H2>
-<P><A HREF="pthread_equal.html"><B>pthread_equal</B>(3)</A> ,
-<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> ,
-<A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A> ,
-<A HREF="pthread_setschedparam.html"><B>pthread_setschedparam</B>(3)</A>
-, <A HREF="pthread_setschedparam.html"><B>pthread_getschedparam</B>(3)</A>
-. 
-</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Author</A>
-		</P>
-	<LI><P><A HREF="#sect4" NAME="toc4">See Also</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_setcancelstate.html b/deps/w32-pthreads/manual/pthread_setcancelstate.html
deleted file mode 100644
index 3ce65c4..0000000
--- a/deps/w32-pthreads/manual/pthread_setcancelstate.html
+++ /dev/null
@@ -1,207 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_CANCEL(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;12090500">
-	<META NAME="CHANGED" CONTENT="20050504;16361300">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_cancel, pthread_setcancelstate, pthread_setcanceltype,
-pthread_testcancel - thread cancellation 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_cancel(pthread_t </B><I>thread</I><B>);</B> 
-</P>
-<P><B>int pthread_setcancelstate(int </B><I>state</I><B>, int
-*</B><I>oldstate</I><B>);</B> 
-</P>
-<P><B>int pthread_setcanceltype(int </B><I>type</I><B>, int
-*</B><I>oldtype</I><B>);</B> 
-</P>
-<P><B>void pthread_testcancel(void);</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Cancellation is the mechanism by which a thread can terminate the
-execution of another thread. More precisely, a thread can send a
-cancellation request to another thread. Depending on its settings,
-the target thread can then either ignore the request, honor it
-immediately, or defer it until it reaches a cancellation point. 
-</P>
-<P>When a thread eventually honors a cancellation request, it
-performs as if <B>pthread_exit(PTHREAD_CANCELED)</B> has been called
-at that point: all cleanup handlers are executed in reverse order,
-destructor functions for thread-specific data are called, and finally
-the thread stops executing with the return value <B>PTHREAD_CANCELED</B>.
-See <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> for more
-information. 
-</P>
-<P><B>pthread_cancel</B> sends a cancellation request to the thread
-denoted by the <I>thread</I> argument. 
-</P>
-<P><B>pthread_setcancelstate</B> changes the cancellation state for
-the calling thread -- that is, whether cancellation requests are
-ignored or not. The <I>state</I> argument is the new cancellation
-state: either <B>PTHREAD_CANCEL_ENABLE</B> to enable cancellation, or
-<B>PTHREAD_CANCEL_DISABLE</B> to disable cancellation (cancellation
-requests are ignored). If <I>oldstate</I> is not <B>NULL</B>, the
-previous cancellation state is stored in the location pointed to by
-<I>oldstate</I>, and can thus be restored later by another call to
-<B>pthread_setcancelstate</B>. 
-</P>
-<P><B>pthread_setcanceltype</B> changes the type of responses to
-cancellation requests for the calling thread: asynchronous
-(immediate) or deferred. The <I>type</I> argument is the new
-cancellation type: either <B>PTHREAD_CANCEL_ASYNCHRONOUS</B> to
-cancel the calling thread as soon as the cancellation request is
-received, or <B>PTHREAD_CANCEL_DEFERRED</B> to keep the cancellation
-request pending until the next cancellation point. If <I>oldtype</I>
-is not <B>NULL</B>, the previous cancellation state is stored in the
-location pointed to by <I>oldtype</I>, and can thus be restored later
-by another call to <B>pthread_setcanceltype</B>. 
-</P>
-<P><B>Pthreads-w32</B> provides two levels of support for
-<B>PTHREAD_CANCEL_ASYNCHRONOUS</B>: full and partial. Full support
-requires an additional DLL and driver be installed on the Windows
-system (see the See Also section below) that allows blocked threads
-to be cancelled immediately. Partial support means that the target
-thread will not cancel until it resumes execution naturally. Partial
-support is provided if either the DLL or the driver are not
-automatically detected by the pthreads-w32 library at run-time.</P>
-<P>Threads are always created by <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
-with cancellation enabled and deferred. That is, the initial
-cancellation state is <B>PTHREAD_CANCEL_ENABLE</B> and the initial
-type is <B>PTHREAD_CANCEL_DEFERRED</B>. 
-</P>
-<P>Cancellation points are those points in the program execution
-where a test for pending cancellation requests is performed and
-cancellation is executed if positive. The following POSIX threads
-functions are cancellation points: 
-</P>
-<P><A HREF="pthread_join.html"><B>pthread_join</B>(3)</A>
-<BR><A HREF="pthread_cond_wait.html"><B>pthread_cond_wait</B>(3)</A>
-<BR><A HREF="pthread_cond_timedwait.html"><B>pthread_cond_timedwait</B>(3)</A>
-<BR><A HREF="pthread_testcancel.html"><B>pthread_testcancel</B>(3)</A>
-<BR><A HREF="sem_wait.html"><B>sem_wait</B>(3)</A> <BR><A HREF="sem_timedwait.html"><B>sem_timedwait</B>(3)</A>
-<BR><A HREF="sigwait.html"><B>sigwait</B>(3)</A> (not supported under
-<B>Pthreads-w32</B>)</P>
-<P><B>Pthreads-w32</B> provides two functions to enable additional
-cancellation points to be created in user functions that block on
-Win32 HANDLEs:</P>
-<P><A HREF="pthreadCancelableWait.html">pthreadCancelableWait()</A>
-<BR><A HREF="pthreadCancelableTimedWait.html">pthreadCancelableTimedWait()</A></P>
-<P>All other POSIX threads functions are guaranteed not to be
-cancellation points. That is, they never perform cancellation in
-deferred cancellation mode. 
-</P>
-<P><B>pthread_testcancel</B> does nothing except testing for pending
-cancellation and executing it. Its purpose is to introduce explicit
-checks for cancellation in long sequences of code that do not call
-cancellation point functions otherwise. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P><B>pthread_cancel</B>, <B>pthread_setcancelstate</B> and
-<B>pthread_setcanceltype</B> return 0 on success and a non-zero error
-code on error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P><B>pthread_cancel</B> returns the following error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ESRCH</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		no thread could be found corresponding to that specified by the
-		<I>thread</I> ID. 
-		</DD></DL>
-</DL>
-<P>
-<B>pthread_setcancelstate</B> returns the following error code on
-error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the <I>state</I> argument is not 
-		</DD></DL>
-</DL>
-<BLOCKQUOTE>
-<B>PTHREAD_CANCEL_ENABLE</B> nor <B>PTHREAD_CANCEL_DISABLE</B> 
-</BLOCKQUOTE>
-<P><B>pthread_setcanceltype</B> returns the following error code on
-error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the <I>type</I> argument is not 
-		</DD></DL>
-</DL>
-<BLOCKQUOTE>
-<B>PTHREAD_CANCEL_DEFERRED</B> nor <B>PTHREAD_CANCEL_ASYNCHRONOUS</B>
-</BLOCKQUOTE>
-<H2><A HREF="#toc5" NAME="sect5">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
-<P><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> ,
-<A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_push</B>(3)</A>
-, <A HREF="pthread_cleanup_pop.html"><B>pthread_cleanup_pop</B>(3)</A>
-, Pthreads-w32 package README file 'Prerequisites' section. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Bugs</A></H2>
-<P>POSIX specifies that a number of system calls (basically, all
-system calls that may block, such as <A HREF="read.html"><B>read</B>(2)</A>
-, <A HREF="write.html"><B>write</B>(2)</A> , <A HREF="wait.html"><B>wait</B>(2)</A>
-, etc.) and library functions that may call these system calls (e.g.
-<A HREF="fprintf.html"><B>fprintf</B>(3)</A> ) are cancellation
-points. <B>Pthreads-win32</B> is not integrated enough with the C
-library to implement this, and thus none of the C library functions
-is a cancellation point. 
-</P>
-<P>A workaround for these calls is to temporarily switch to
-asynchronous cancellation (assuming full asynchronous cancellation
-support is installed). So, checking for cancellation during a <B>read</B>
-system call, for instance, can be achieved as follows: 
-</P>
-<BLOCKQUOTE><BR><BR>
-</BLOCKQUOTE>
-<PRE STYLE="margin-left: 1cm; margin-right: 1cm">pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldCancelType);
-read(fd, buffer, length);
-pthread_setcanceltype(oldCancelType, NULL);</PRE>
-<HR>
-<BLOCKQUOTE><A NAME="toc"></A><B>Table of Contents</B></BLOCKQUOTE>
-<UL>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">See
-	Also</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE><A HREF="#sect7" NAME="toc7">Bugs</A> 
-	</BLOCKQUOTE>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_setcanceltype.html b/deps/w32-pthreads/manual/pthread_setcanceltype.html
deleted file mode 100644
index 935ed82..0000000
--- a/deps/w32-pthreads/manual/pthread_setcanceltype.html
+++ /dev/null
@@ -1,207 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_CANCEL(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;12090500">
-	<META NAME="CHANGED" CONTENT="20050504;16362800">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_cancel, pthread_setcancelstate, pthread_setcanceltype,
-pthread_testcancel - thread cancellation 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_cancel(pthread_t </B><I>thread</I><B>);</B> 
-</P>
-<P><B>int pthread_setcancelstate(int </B><I>state</I><B>, int
-*</B><I>oldstate</I><B>);</B> 
-</P>
-<P><B>int pthread_setcanceltype(int </B><I>type</I><B>, int
-*</B><I>oldtype</I><B>);</B> 
-</P>
-<P><B>void pthread_testcancel(void);</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Cancellation is the mechanism by which a thread can terminate the
-execution of another thread. More precisely, a thread can send a
-cancellation request to another thread. Depending on its settings,
-the target thread can then either ignore the request, honor it
-immediately, or defer it until it reaches a cancellation point. 
-</P>
-<P>When a thread eventually honors a cancellation request, it
-performs as if <B>pthread_exit(PTHREAD_CANCELED)</B> has been called
-at that point: all cleanup handlers are executed in reverse order,
-destructor functions for thread-specific data are called, and finally
-the thread stops executing with the return value <B>PTHREAD_CANCELED</B>.
-See <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> for more
-information. 
-</P>
-<P><B>pthread_cancel</B> sends a cancellation request to the thread
-denoted by the <I>thread</I> argument. 
-</P>
-<P><B>pthread_setcancelstate</B> changes the cancellation state for
-the calling thread -- that is, whether cancellation requests are
-ignored or not. The <I>state</I> argument is the new cancellation
-state: either <B>PTHREAD_CANCEL_ENABLE</B> to enable cancellation, or
-<B>PTHREAD_CANCEL_DISABLE</B> to disable cancellation (cancellation
-requests are ignored). If <I>oldstate</I> is not <B>NULL</B>, the
-previous cancellation state is stored in the location pointed to by
-<I>oldstate</I>, and can thus be restored later by another call to
-<B>pthread_setcancelstate</B>. 
-</P>
-<P><B>pthread_setcanceltype</B> changes the type of responses to
-cancellation requests for the calling thread: asynchronous
-(immediate) or deferred. The <I>type</I> argument is the new
-cancellation type: either <B>PTHREAD_CANCEL_ASYNCHRONOUS</B> to
-cancel the calling thread as soon as the cancellation request is
-received, or <B>PTHREAD_CANCEL_DEFERRED</B> to keep the cancellation
-request pending until the next cancellation point. If <I>oldtype</I>
-is not <B>NULL</B>, the previous cancellation state is stored in the
-location pointed to by <I>oldtype</I>, and can thus be restored later
-by another call to <B>pthread_setcanceltype</B>. 
-</P>
-<P><B>Pthreads-w32</B> provides two levels of support for
-<B>PTHREAD_CANCEL_ASYNCHRONOUS</B>: full and partial. Full support
-requires an additional DLL and driver be installed on the Windows
-system (see the See Also section below) that allows blocked threads
-to be cancelled immediately. Partial support means that the target
-thread will not cancel until it resumes execution naturally. Partial
-support is provided if either the DLL or the driver are not
-automatically detected by the pthreads-w32 library at run-time.</P>
-<P>Threads are always created by <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
-with cancellation enabled and deferred. That is, the initial
-cancellation state is <B>PTHREAD_CANCEL_ENABLE</B> and the initial
-type is <B>PTHREAD_CANCEL_DEFERRED</B>. 
-</P>
-<P>Cancellation points are those points in the program execution
-where a test for pending cancellation requests is performed and
-cancellation is executed if positive. The following POSIX threads
-functions are cancellation points: 
-</P>
-<P><A HREF="pthread_join.html"><B>pthread_join</B>(3)</A>
-<BR><A HREF="pthread_cond_wait.html"><B>pthread_cond_wait</B>(3)</A>
-<BR><A HREF="pthread_cond_timedwait.html"><B>pthread_cond_timedwait</B>(3)</A>
-<BR><A HREF="pthread_testcancel.html"><B>pthread_testcancel</B>(3)</A>
-<BR><A HREF="sem_wait.html"><B>sem_wait</B>(3)</A> <BR><A HREF="sem_timedwait.html"><B>sem_timedwait</B>(3)</A>
-<BR><A HREF="sigwait.html"><B>sigwait</B>(3)</A> (not supported under
-<B>Pthreads-w32</B>)</P>
-<P><B>Pthreads-w32</B> provides two functions to enable additional
-cancellation points to be created in user functions that block on
-Win32 HANDLEs:</P>
-<P><A HREF="pthreadCancelableWait.html">pthreadCancelableWait()</A>
-<BR><A HREF="pthreadCancelableTimedWait.html">pthreadCancelableTimedWait()</A></P>
-<P>All other POSIX threads functions are guaranteed not to be
-cancellation points. That is, they never perform cancellation in
-deferred cancellation mode. 
-</P>
-<P><B>pthread_testcancel</B> does nothing except testing for pending
-cancellation and executing it. Its purpose is to introduce explicit
-checks for cancellation in long sequences of code that do not call
-cancellation point functions otherwise. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P><B>pthread_cancel</B>, <B>pthread_setcancelstate</B> and
-<B>pthread_setcanceltype</B> return 0 on success and a non-zero error
-code on error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P><B>pthread_cancel</B> returns the following error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ESRCH</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		no thread could be found corresponding to that specified by the
-		<I>thread</I> ID. 
-		</DD></DL>
-</DL>
-<P>
-<B>pthread_setcancelstate</B> returns the following error code on
-error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the <I>state</I> argument is not 
-		</DD></DL>
-</DL>
-<BLOCKQUOTE>
-<B>PTHREAD_CANCEL_ENABLE</B> nor <B>PTHREAD_CANCEL_DISABLE</B> 
-</BLOCKQUOTE>
-<P><B>pthread_setcanceltype</B> returns the following error code on
-error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the <I>type</I> argument is not 
-		</DD></DL>
-</DL>
-<BLOCKQUOTE>
-<B>PTHREAD_CANCEL_DEFERRED</B> nor <B>PTHREAD_CANCEL_ASYNCHRONOUS</B>
-</BLOCKQUOTE>
-<H2><A HREF="#toc5" NAME="sect5">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
-<P><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> ,
-<A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_push</B>(3)</A>
-, <A HREF="pthread_cleanup_pop.html"><B>pthread_cleanup_pop</B>(3)</A>
-, Pthreads-w32 package README file 'Prerequisites' section. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Bugs</A></H2>
-<P>POSIX specifies that a number of system calls (basically, all
-system calls that may block, such as <A HREF="read.html"><B>read</B>(2)</A>
-, <A HREF="write.html"><B>write</B>(2)</A> , <A HREF="wait.html"><B>wait</B>(2)</A>
-, etc.) and library functions that may call these system calls (e.g.
-<A HREF="fprintf.html"><B>fprintf</B>(3)</A> ) are cancellation
-points. <B>Pthreads-win32</B> is not integrated enough with the C
-library to implement this, and thus none of the C library functions
-is a cancellation point. 
-</P>
-<P>A workaround for these calls is to temporarily switch to
-asynchronous cancellation (assuming full asynchronous cancellation
-support is installed). So, checking for cancellation during a <B>read</B>
-system call, for instance, can be achieved as follows: 
-</P>
-<BLOCKQUOTE><BR><BR>
-</BLOCKQUOTE>
-<PRE STYLE="margin-left: 1cm; margin-right: 1cm">pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldCancelType);
-read(fd, buffer, length);
-pthread_setcanceltype(oldCancelType, NULL);</PRE>
-<HR>
-<BLOCKQUOTE><A NAME="toc"></A><B>Table of Contents</B></BLOCKQUOTE>
-<UL>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
-		</BLOCKQUOTE>
-	<LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">See
-	Also</A> 
-	</BLOCKQUOTE>
-	<LI><BLOCKQUOTE><A HREF="#sect7" NAME="toc7">Bugs</A> 
-	</BLOCKQUOTE>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_setconcurrency.html b/deps/w32-pthreads/manual/pthread_setconcurrency.html
deleted file mode 100644
index cdd4f58..0000000
--- a/deps/w32-pthreads/manual/pthread_setconcurrency.html
+++ /dev/null
@@ -1,155 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_GETCONCURRENCY"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;19162600">
-	<META NAME="CHANGED" CONTENT="20050505;19223800">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_getconcurrency, pthread_setconcurrency - get and set the
-level of concurrency 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_getconcurrency(void);</B> <BR><B>int
-pthread_setconcurrency(int</B> <I>new_level</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Unbound threads in a process may or may not be required to be
-simultaneously active. By default, the threads implementation ensures
-that a sufficient number of threads are active so that the process
-can continue to make progress. While this conserves system resources,
-it may not produce the most effective level of concurrency. 
-</P>
-<P>The <B>pthread_setconcurrency</B> function allows an application
-to inform the threads implementation of its desired concurrency
-level, <I>new_level</I>. The actual level of concurrency provided by
-the implementation as a result of this function call is unspecified. 
-</P>
-<P>If <I>new_level</I> is zero, it causes the implementation to
-maintain the concurrency level at its discretion as if
-<B>pthread_setconcurrency</B> had never been called. 
-</P>
-<P>The <B>pthread_getconcurrency</B> function shall return the value
-set by a previous call to the <B>pthread_setconcurrency</B> function.
-If the <B>pthread_setconcurrency</B> function was not previously
-called, this function shall return zero to indicate that the
-implementation is maintaining the concurrency level. 
-</P>
-<P>A call to <B>pthread_setconcurrency</B> shall inform the
-implementation of its desired concurrency level. The implementation
-shall use this as a hint, not a requirement. 
-</P>
-<P>If an implementation does not support multiplexing of user threads
-on top of several kernel-scheduled entities, the
-<B>pthread_setconcurrency</B> and <B>pthread_getconcurrency</B>
-functions are provided for source code compatibility but they shall
-have no effect when called. To maintain the function semantics, the
-<I>new_level</I> parameter is saved when <B>pthread_setconcurrency</B>
-is called so that a subsequent call to <B>pthread_getconcurrency</B>
-shall return the same value. 
-</P>
-<P><B>Pthreads-w32</B> provides these routines for source code
-compatibility only, as described in the previous paragraph.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>If successful, the <B>pthread_setconcurrency</B> function shall
-return zero; otherwise, an error number shall be returned to indicate
-the error. 
-</P>
-<P>The <B>pthread_getconcurrency</B> function shall always return the
-concurrency level set by a previous call to <B>pthread_setconcurrency</B>
-. If the <B>pthread_setconcurrency</B> function has never been
-called, <B>pthread_getconcurrency</B> shall return zero. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_setconcurrency</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD>
-	The value specified by <I>new_level</I> is negative. 
-	</DD><DT>
-	<B>EAGAIN</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specific by <I>new_level</I> would cause a system resource
-	to be exceeded. 
-	</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>Use of these functions changes the state of the underlying
-concurrency upon which the application depends. Library developers
-are advised to not use the <B>pthread_getconcurrency</B> and
-<B>pthread_setconcurrency</B> functions since their use may conflict
-with an applications use of these functions. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P>The Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_setschedparam.html b/deps/w32-pthreads/manual/pthread_setschedparam.html
deleted file mode 100644
index 8dbb9c4..0000000
--- a/deps/w32-pthreads/manual/pthread_setschedparam.html
+++ /dev/null
@@ -1,114 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_SETSCHEDPARAM(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 2.4  (Linux)">
-	<META NAME="CREATED" CONTENT="20050504;18110100">
-	<META NAME="CHANGEDBY" CONTENT="Ross Johnson">
-	<META NAME="CHANGED" CONTENT="20080630;22330400">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_setschedparam, pthread_getschedparam - control thread
-scheduling 
-</P>
-<P>parameters 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>int pthread_setschedparam(pthread_t </B><I>target_thread</I><B>,
-int </B><I>policy</I><B>, const struct sched_param *</B><I>param</I><B>);</B>
-</P>
-<P><B>int pthread_getschedparam(pthread_t </B><I>target_thread</I><B>,
-int *</B><I>policy</I><B>, struct sched_param *</B><I>param</I><B>);</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P><B>pthread_setschedparam</B> sets the scheduling parameters for
-the thread <I>target_thread</I> as indicated by <I>policy</I> and
-<I>param</I>. <I>policy</I> can be either <B>SCHED_OTHER</B>
-(regular, non-real-time scheduling), <B>SCHED_RR</B> (real-time,
-round-robin) or <B>SCHED_FIFO</B> (real-time, first-in first-out).
-<I>param</I> specifies the scheduling priority for the two real-time
-policies.</P>
-<P><B>Pthreads-w32</B> only supports SCHED_OTHER and does not support
-the real-time scheduling policies <B>SCHED_RR</B> and <B>SCHED_FIFO.</B>
-</P>
-<P><B>pthread_getschedparam</B> retrieves the scheduling policy and
-scheduling parameters for the thread <I>target_thread</I> and stores
-them in the locations pointed to by <I>policy</I> and <I>param</I>,
-respectively. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P><B>pthread_setschedparam</B> and <B>pthread_getschedparam</B>
-return 0 on success and a non-zero error code on error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>On error, <B>pthread_setschedparam</B> returns the following error
-codes: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ENOTSUP</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<I>policy</I> is not <B>SCHED_OTHER.</B></DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		One of the arguments is invalid, or the priority value specified by
-		<I>param</I> is not valid for the specified policy.</DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<B>ESRCH</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		The <I>target_thread</I> is invalid or has already terminated 
-		</DD></DL>
-</DL>
-<P>
-On error, <B>pthread_getschedparam</B> returns the following error
-codes: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ESRCH</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		the <I>target_thread</I> is invalid or has already terminated 
-		</DD></DL>
-</DL>
-<H2>
-<A HREF="#toc5" NAME="sect5">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
-<P><A HREF="sched_setscheduler.html"><B>sched_setscheduler</B>(2)</A>
-, <A HREF="sched_getscheduler.html"><B>sched_getscheduler</B>(2)</A>
-, <A HREF="sched_getparam.html"><B>sched_getparam</B>(2)</A> ,
-<A HREF="pthread_attr_init.html"><B>pthread_attr_setschedpolicy</B>(3)</A>
-, <A HREF="pthread_attr_init.html"><B>pthread_attr_setschedparam</B>(3)</A>
-. 
-</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">See Also</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/pthread_spin_init.html b/deps/w32-pthreads/manual/pthread_spin_init.html
deleted file mode 100644
index 35e657b..0000000
--- a/deps/w32-pthreads/manual/pthread_spin_init.html
+++ /dev/null
@@ -1,176 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_SPIN_DESTROY"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;12074100">
-	<META NAME="CHANGED" CONTENT="20050505;19014200">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_spin_destroy, pthread_spin_init - destroy or initialize a
-spin lock object (<B>ADVANCED REALTIME THREADS</B>) 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>pthread_spinlock_t</B> <I>lock</I> <B>=
-PTHREAD_SPINLOCK_INITIALIZER;</B></P>
-<P><B>int pthread_spin_destroy(pthread_spinlock_t *</B><I>lock</I><B>);
-<BR>int pthread_spin_init(pthread_spinlock_t *</B><I>lock</I><B>, int</B>
-<I>pshared</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_spin_destroy</B> function shall destroy the spin
-lock referenced by <I>lock</I> and release any resources used by the
-lock. The effect of subsequent use of the lock is undefined until the
-lock is reinitialized by another call to <B>pthread_spin_init</B> .
-The results are undefined if <B>pthread_spin_destroy</B> is called
-when a thread holds the lock, or if this function is called with an
-uninitialized thread spin lock. 
-</P>
-<P>The <B>pthread_spin_init</B> function shall allocate any resources
-required to use the spin lock referenced by <I>lock</I> and
-initialize the lock to an unlocked state. 
-</P>
-<P><B>Pthreads-w32</B> supports single and multiple processor systems
-as well as process CPU affinity masking by checking the mask when the
-spin lock is initialized. If the process is using only a single
-processor at the time <B>pthread_spin_init</B> is called then the
-spin lock is initialized as a PTHREAD_MUTEX_NORMAL mutex object. A
-thread that calls <A HREF="pthread_spin_lock.html"><B>pthread_spin_lock(3)</B></A>
-will block rather than spin in this case. If the process CPU affinity
-mask is altered after the spin lock has been initialised, the spin
-lock is not modified, and may no longer be optimal for the number of
-CPUs available.</P>
-<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_PROCESS_SHARED</B> in
-pthread.h as -1 to indicate that these routines do not support the
-<B>PTHREAD_PROCESS_SHARED</B> attribute. <B>pthread_spin_init</B>
-will return the error <B>ENOTSUP</B> if the value of <I>pshared</I>
-is not <B>PTHREAD_PROCESS_PRIVATE</B>.</P>
-<P>The results are undefined if <B>pthread_spin_init</B> is called
-specifying an already initialized spin lock. The results are
-undefined if a spin lock is used without first being initialized. 
-</P>
-<P>If the <B>pthread_spin_init</B> function fails, the lock is not
-initialized and the contents of <I>lock</I> are undefined. 
-</P>
-<P>Only the object referenced by <I>lock</I> may be used for
-performing synchronization. 
-</P>
-<P>The result of referring to copies of that object in calls to
-<B>pthread_spin_destroy</B> , <A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B>(3)</A>
-, <A HREF="pthread_spin_lock.html"><B>pthread_spin_trylock</B>(3)</A>,
-or <A HREF="pthread_spin_unlock.html"><B>pthread_spin_unlock</B>(3)</A>
-is undefined. 
-</P>
-<P><B>Pthreads-w32</B> supports statically initialized spin locks
-using <B>PTHREAD_SPINLOCK_INITIALIZER</B>. An application should
-still call <B>pthread_spin_destroy</B> at some point to ensure that
-any resources consumed by the spin lock are released.</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>Upon successful completion, these functions shall return zero;
-otherwise, an error number shall be returned to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>These functions may fail if: 
-</P>
-<DL>
-	<DT><B>EBUSY</B> 
-	</DT><DD>
-	The implementation has detected an attempt to initialize or destroy
-	a spin lock while it is in use (for example, while being used in a
-	<A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B>(3)</A>
-	call) by another thread. 
-	</DD><DT>
-	<B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>lock</I> is invalid. 
-	</DD></DL>
-<P>
-The <B>pthread_spin_init</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>ENOTSUP</B> 
-	</DT><DD>
-	The value of <I>pshared</I> is not <B>PTHREAD_PROCESS_PRIVATE</B>.</DD><DT>
-	<B>ENOMEM</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	Insufficient memory exists to initialize the lock. 
-	</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>The <B>pthread_spin_destroy</B> and <B>pthread_spin_init</B>
-functions are part of the Spin Locks option and need not be provided
-on all implementations. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B>(3)</A> <B>,</B>
-<A HREF="pthread_spin_unlock.html"><B>pthread_spin_unlock</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_spin_lock.html b/deps/w32-pthreads/manual/pthread_spin_lock.html
deleted file mode 100644
index dd180ae..0000000
--- a/deps/w32-pthreads/manual/pthread_spin_lock.html
+++ /dev/null
@@ -1,141 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_SPIN_LOCK"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;12202300">
-	<META NAME="CHANGED" CONTENT="20050505;19302300">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_spin_lock, pthread_spin_trylock - lock a spin lock object
-(<B>ADVANCED REALTIME THREADS</B>) 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_spin_lock(pthread_spinlock_t *</B><I>lock</I><B>);
-<BR>int pthread_spin_trylock(pthread_spinlock_t *</B><I>lock</I><B>);
-</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_spin_lock</B> function shall lock the spin lock
-referenced by <I>lock</I>. The calling thread shall acquire the lock
-if it is not held by another thread. Otherwise, the thread shall spin
-(that is, shall not return from the <B>pthread_spin_lock</B> call)
-until the lock becomes available. The results are undefined if the
-calling thread holds the lock at the time the call is made.</P>
-<P><B>Pthreads-w32</B> supports single and multiple processor systems
-as well as process CPU affinity masking by checking the mask when the
-spin lock is initialized. If the process is using only a single
-processor at the time <A HREF="pthread_spin_init.html"><B>pthread_spin_init</B>(3)</A>
-is called then the spin lock is initialized as a PTHREAD_MUTEX_NORMAL
-mutex object. A thread that calls <B>pthread_spin_lock</B> will block
-rather than spin in this case. If the process CPU affinity mask is
-altered after the spin lock has been initialised, the spin lock is
-not modified, and may no longer be optimal for the number of CPUs
-available.</P>
-<P>The <B>pthread_spin_trylock</B> function shall lock the spin lock
-referenced by <I>lock</I> if it is not held by any thread. Otherwise,
-the function shall fail. 
-</P>
-<P>The results are undefined if any of these functions is called with
-an uninitialized spin lock. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>Upon successful completion, these functions shall return zero;
-otherwise, an error number shall be returned to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>These functions may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value specified by <I>lock</I> does not refer to an initialized
-	spin lock object. 
-	</DD></DL>
-<P>
-The <B>pthread_spin_trylock</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>EBUSY</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	A thread currently holds the lock. 
-	</DD></DL>
-<P>
-These functions shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>Applications using this function may be subject to priority
-inversion, as discussed in the Base Definitions volume of
-IEEE Std 1003.1-2001, Section 3.285, Priority Inversion. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_spin_init.html"><B>pthread_spin_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_spin_unlock.html"><B>pthread_spin_unlock</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_spin_unlock.html b/deps/w32-pthreads/manual/pthread_spin_unlock.html
deleted file mode 100644
index 2215700..0000000
--- a/deps/w32-pthreads/manual/pthread_spin_unlock.html
+++ /dev/null
@@ -1,124 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"PTHREAD_SPIN_UNLOCK"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;12401400">
-	<META NAME="CHANGED" CONTENT="20050505;12462400">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>pthread_spin_unlock - unlock a spin lock object (<B>ADVANCED
-REALTIME THREADS</B>) 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h> </B>
-</P>
-<P><B>int pthread_spin_unlock(pthread_spinlock_t *</B><I>lock</I><B>);
-</B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>pthread_spin_unlock</B> function shall release the spin
-lock referenced by <I>lock</I> which was locked via the
-<A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B>(3)</A> or
-<A HREF="pthread_spin_lock.html"><B>pthread_spin_trylock</B>(3)</A>
-functions. If there are threads spinning on the lock when
-<B>pthread_spin_unlock</B> is called, the lock becomes available and
-an unspecified spinning thread shall acquire the lock. 
-</P>
-<P><B>Pthreads-w32</B> does not check ownership of the lock and it is
-therefore possible for a thread other than the locker to unlock the
-spin lock. This is not a feature that should be exploited.</P>
-<P>The results are undefined if this function is called with an
-uninitialized thread spin lock. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>Upon successful completion, the <B>pthread_spin_unlock</B>
-function shall return zero; otherwise, an error number shall be
-returned to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>pthread_spin_unlock</B> function may fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD>
-	An invalid argument was specified. 
-	</DD><DD STYLE="margin-left: -2cm">
-	<BR>
-	</DD></DL>
-<P>
-This function shall not return an error code of [EINTR]. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P><B>Pthreads-w32</B> does not check ownership of the lock and it is
-therefore possible for a thread other than the locker to unlock the
-spin lock. This is not a feature that should be exploited.</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="pthread_spin_init.html"><B>pthread_spin_destroy</B>(3)</A>
-<B>,</B> <A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><pthread.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_timechange_handler_np.html b/deps/w32-pthreads/manual/pthread_timechange_handler_np.html
deleted file mode 100644
index 54226da..0000000
--- a/deps/w32-pthreads/manual/pthread_timechange_handler_np.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_TIMECHANGE_HANDLER_NP manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;322600">
-	<META NAME="CHANGED" CONTENT="20050505;22110600">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P STYLE="font-weight: medium">pthread_timechange_handler_np –
-alert timed waiting condition variables to system time changes.</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>void * pthread_timechange_handler_np(void * </B><I>dummy</I><B>);</B></P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>To improve tolerance against operator or time service initiated
-system clock changes.</P>
-<P><B>pthread_timechange_handler_np </B>can be called by an
-application when it receives a WM_TIMECHANGE message from the system.
-At present it broadcasts all condition variables so that waiting
-threads can wake up and re-evaluate their conditions and restart
-their timed waits if required.</P>
-<P><B>pthread_timechange_handler_np </B>has the same return type and
-argument type as a thread routine so that it may be called directly
-through pthread_create(), i.e. as a separate thread. If run as a
-thread, the return code must be retrieved through <A HREF="pthread_join.html"><B>pthread_join</B>()</A>.</P>
-<P>Although the <I>dummy</I> parameter is required it is not used and
-any value including NULL can be given.</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P>None.</P>
-<H2><A HREF="#toc4" NAME="sect4"><FONT COLOR="#000080">Return Value</FONT></A></H2>
-<P><B>pthread_timechange_handler_np</B> returns 0 on success, or an
-error code.</P>
-<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
-<P>The <B>pthread_timechange_handler_np</B> function returns the
-following error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EAGAIN</B> 
-		</DT></DL>
-</DL>
-<P STYLE="margin-left: 2cm; margin-bottom: 0cm">
-To indicate that not all condition variables were signalled for some
-reason.</P>
-<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
-<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">Author</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_win32_attach_detach_np.html b/deps/w32-pthreads/manual/pthread_win32_attach_detach_np.html
deleted file mode 100644
index f8cfc36..0000000
--- a/deps/w32-pthreads/manual/pthread_win32_attach_detach_np.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_WIN32_ATTACH_DETACH_NP manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;322600">
-	<META NAME="CHANGED" CONTENT="20050505;22415600">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P STYLE="font-weight: medium">pthread_win32_process_attach_np,
-pthread_win32_process_detach_np, pthread_win32_thread_attach_np,
-pthread_win32_thread_detach_np – exposed versions of the
-pthreads-w32 DLL dllMain() switch functionality for use when
-statically linking the library.</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>BOOL pthread_win32_process_attach_np (void);</B></P>
-<P><B>BOOL pthread_win32_process_detach_np (void);</B></P>
-<P><B>BOOL pthread_win32_thread_attach_np (void);</B></P>
-<P><B>BOOL pthread_win32_thread_detach_np (void);</B></P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>These functions contain the code normally run via <b>dllMain</b>
-when the library is used as a dll but which need to be called
-explicitly by an application when the library is statically linked. As of version 2.9.0,  the  static library built using either MSC or GCC includes RT hooks which will call the pthread_win32_process_*_np routines automatically on  start/exit of the application.</P>
-<P>You will need to call <B>pthread_win32_process_attach_np</B>
-before you can call any pthread routines when statically linking. You
-should call <B>pthread_win32_process_detach_np</B> before exiting
-your application to clean up.</P>
-<P><B>pthread_win32_thread_attach_np</B> is currently a no-op, but
-<B>pthread_win32_thread_detach_np</B> is needed to clean up the
-implicit  pthread handle that is allocated to a Win32 thread if it
-calls certain pthreads routines. Call this routine when the Win32
-thread exits.</P>
-<P>These functions invariably return TRUE except for
-<B>pthread_win32_process_attach_np</B> which will return FALSE if
-pthreads-w32 initialisation fails.</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P>None.</P>
-<H2><A HREF="#toc4" NAME="sect4"><FONT COLOR="#000080">Return Value</FONT></A></H2>
-<P>These routines return TRUE (non-zero) on success, or FALSE (0) if
-they fail.</P>
-<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
-<P>None.</P>
-<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
-<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">Author</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/pthread_win32_test_features_np.html b/deps/w32-pthreads/manual/pthread_win32_test_features_np.html
deleted file mode 100644
index 1d8e112..0000000
--- a/deps/w32-pthreads/manual/pthread_win32_test_features_np.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>PTHREAD_WIN32_TEST_FEATURES_NP manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;322600">
-	<META NAME="CHANGED" CONTENT="20050510;17405600">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P STYLE="font-weight: medium">pthread_win32_test_features_np –
-find out what features were detected at process attach time.</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <pthread.h></B> 
-</P>
-<P><B>BOOL pthread_win32_test_features_np(int</B> <I>mask</I><B>);</B></P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P><B>pthread_win32_test_features_np</B> allows an application to
-check which run-time auto-detected features are available within the
-library.</P>
-<P>The possible features are:</P>
-<P><B>PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE</B></P>
-<P STYLE="margin-left: 2cm">Return TRUE if the Win32 version of
-InterlockedCompareExchange() is being used. On IA32 systems the
-library can use optimised and inlinable assembler versions of
-InterlockedExchange() and InterlockedCompareExchange().</P>
-<P><B>PTW32_ALERTABLE_ASYNC_CANCEL</B></P>
-<P STYLE="margin-left: 2cm">Return TRUE if the QueueUserAPCEx package
-QUSEREX.DLL and the AlertDrv.sys driver was detected. This package
-provides alertable (pre-emptive) asynchronous threads cancellation.
-If this feature returns FALSE then the default async cancel scheme is
-in use, which cannot cancel blocked threads.</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P>None.</P>
-<H2><A HREF="#toc4" NAME="sect4"><FONT COLOR="#000080">Return Value</FONT></A></H2>
-<P><B>pthread_win32_test_features_np</B> returns TRUE (non-zero) if
-the specified feature is present, and FALSE (0) otherwise.</P>
-<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
-<P>None.</P>
-<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
-<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
-		</P>
-	<LI><P><A HREF="#sect6" NAME="toc6">Author</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/sched_get_priority_max.html b/deps/w32-pthreads/manual/sched_get_priority_max.html
deleted file mode 100644
index 5486902..0000000
--- a/deps/w32-pthreads/manual/sched_get_priority_max.html
+++ /dev/null
@@ -1,115 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"SCHED_GET_PRIORITY_MAX"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;12575100">
-	<META NAME="CHANGED" CONTENT="20050510;12533300">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>sched_get_priority_max, sched_get_priority_min - get priority
-limits (<B>REALTIME</B>) 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <sched.h> </B>
-</P>
-<P><B>int sched_get_priority_max(int</B> <I>policy</I><B>); <BR>int
-sched_get_priority_min(int</B> <I>policy</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>sched_get_priority_max</B> and <B>sched_get_priority_min</B>
-functions shall return the appropriate maximum or minimum,
-respectively, for the scheduling policy specified by <I>policy</I>. 
-</P>
-<P>The value of <I>policy</I> shall be one of the scheduling policy
-values defined in <I><sched.h></I>. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>If successful, the <B>sched_get_priority_max</B> and
-<B>sched_get_priority_min</B> functions shall return the appropriate
-maximum or minimum values, respectively. If unsuccessful, they shall
-return a value of -1 and set <I>errno</I> to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>sched_get_priority_max</B> and <B>sched_get_priority_min</B>
-functions shall fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	The value of the <I>policy</I> parameter does not represent a
-	defined scheduling policy. 
-	</DD></DL>
-<P>
-<I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="sched_getscheduler.html"><B>sched_getscheduler</B>(3)</A>
-<B>,</B> <A HREF="sched_setscheduler.html"><B>sched_setscheduler</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><sched.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/manual/sched_getscheduler.html b/deps/w32-pthreads/manual/sched_getscheduler.html
deleted file mode 100644
index 0089e24..0000000
--- a/deps/w32-pthreads/manual/sched_getscheduler.html
+++ /dev/null
@@ -1,127 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"SCHED_GETSCHEDULER"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;13153500">
-	<META NAME="CHANGED" CONTENT="20050505;13202000">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>sched_getscheduler - get scheduling policy (<B>REALTIME</B>) 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <sched.h> </B>
-</P>
-<P><B>int sched_getscheduler(pid_t</B> <I>pid</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>sched_getscheduler</B> function shall return the scheduling
-policy of the process specified by <I>pid</I>. If the value of <I>pid</I>
-is negative, the behavior of the <B>sched_getscheduler</B> function
-is unspecified. 
-</P>
-<P>The values that can be returned by <B>sched_getscheduler</B> are
-defined in the <I><sched.h></I> header. 
-</P>
-<P><B>Pthreads-w32</B> only supports the <B>SCHED_OTHER</B> policy,
-which is the only value that can be returned. However, checks on <I>pid</I>
-and permissions are performed first so that the other useful side
-effects of this routine are retained.</P>
-<P>If a process specified by <I>pid</I> exists, and if the calling
-process has permission, the scheduling policy shall be returned for
-the process whose process ID is equal to <I>pid</I>. 
-</P>
-<P>If <I>pid</I> is zero, the scheduling policy shall be returned for
-the calling process. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>Upon successful completion, the <B>sched_getscheduler</B> function
-shall return the scheduling policy of the specified process. If
-unsuccessful, the function shall return -1 and set <I>errno</I> to
-indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>sched_getscheduler</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>EPERM</B> 
-	</DT><DD>
-	The requesting process does not have permission to determine the
-	scheduling policy of the specified process. 
-	</DD><DT>
-	<B>ESRCH</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	No process can be found corresponding to that specified by <I>pid</I>.
-		</DD></DL>
-<P>
-<I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="sched_setscheduler.html"><B>sched_setscheduler</B>(3)</A>
-, the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><sched.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/sched_setscheduler.html b/deps/w32-pthreads/manual/sched_setscheduler.html
deleted file mode 100644
index c6e62ae..0000000
--- a/deps/w32-pthreads/manual/sched_setscheduler.html
+++ /dev/null
@@ -1,181 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"SCHED_SETSCHEDULER"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;13012200">
-	<META NAME="CHANGED" CONTENT="20050505;13193700">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>sched_setscheduler - set scheduling policy and parameters
-(<B>REALTIME</B>) 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <sched.h> </B>
-</P>
-<P><B>int sched_setscheduler(pid_t</B> <I>pid</I><B>, int</B> <I>policy</I><B>,
-const struct sched_param *</B><I>param</I><B>); </B>
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>sched_setscheduler</B> function shall set the scheduling
-policy and scheduling parameters of the process specified by <I>pid</I>
-to <I>policy</I> and the parameters specified in the <B>sched_param</B>
-structure pointed to by <I>param</I>, respectively. The value of the
-<I>sched_priority</I> member in the <B>sched_param</B> structure
-shall be any integer within the inclusive priority range for the
-scheduling policy specified by <I>policy</I>. If the value of <I>pid</I>
-is negative, the behavior of the <B>sched_setscheduler</B> function
-is unspecified. 
-</P>
-<P>The possible values for the <I>policy</I> parameter are defined in
-the <I><sched.h></I> header. 
-</P>
-<P><B>Pthreads-w32</B> only supports the <B>SCHED_OTHER</B> policy.
-Any other value for <I>policy</I> will return failure with errno set
-to <B>ENOSYS</B>. However, checks on <I>pid</I> and permissions are
-performed first so that the other useful side effects of this routine
-are retained.</P>
-<P>If a process specified by <I>pid</I> exists, and if the calling
-process has permission, the scheduling policy and scheduling
-parameters shall be set for the process whose process ID is equal to
-<I>pid</I>. 
-</P>
-<P>If <I>pid</I> is zero, the scheduling policy and scheduling
-parameters shall be set for the calling process. 
-</P>
-<P>Implementations may require that the requesting process have
-permission to set its own scheduling parameters or those of another
-process. Additionally, implementation-defined restrictions may apply
-as to the appropriate privileges required to set a process’ own
-scheduling policy, or another process’ scheduling policy, to a
-particular value. 
-</P>
-<P>The <B>sched_setscheduler</B> function shall be considered
-successful if it succeeds in setting the scheduling policy and
-scheduling parameters of the process specified by <I>pid</I> to the
-values specified by <I>policy</I> and the structure pointed to by
-<I>param</I>, respectively. 
-</P>
-<P>The effect of this function on individual threads is dependent on
-the scheduling contention scope of the threads: 
-</P>
-<DL>
-	<DT>* 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	For threads with system scheduling contention scope, these functions
-	shall have no effect on their scheduling. 
-	</DD><DT>
-	* 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	For threads with process scheduling contention scope, the threads’
-	scheduling policy and associated parameters shall not be affected.
-	However, the scheduling of these threads with respect to threads in
-	other processes may be dependent on the scheduling parameters of
-	their process, which are governed using these functions. 
-	</DD></DL>
-<P>
-This function is not atomic with respect to other threads in the
-process. Threads may continue to execute while this function call is
-in the process of changing the scheduling policy and associated
-scheduling parameters for the underlying kernel-scheduled entities
-used by the process contention scope threads. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>Upon successful completion, the function shall return the former
-scheduling policy of the specified process. If the <B>sched_setscheduler</B>
-function fails to complete successfully, the policy and scheduling
-parameters shall remain unchanged, and the function shall return a
-value of -1 and set <I>errno</I> to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>The <B>sched_setscheduler</B> function shall fail if: 
-</P>
-<DL>
-	<DT><B>EINVAL</B> 
-	</DT><DD>
-	The value of the <I>policy</I> parameter is invalid, or one or more
-	of the parameters contained in <I>param</I> is outside the valid
-	range for the specified scheduling policy. 
-	</DD><DT>
-	<B>EPERM</B> 
-	</DT><DD>
-	The requesting process does not have permission to set either or
-	both of the scheduling parameters or the scheduling policy of the
-	specified process. 
-	</DD><DT>
-	<B>ESRCH</B> 
-	</DT><DD STYLE="margin-bottom: 0.5cm">
-	No process can be found corresponding to that specified by <I>pid</I>.
-		</DD></DL>
-<P>
-<I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P><A HREF="sched_getscheduler.html"><B>sched_getscheduler</B>(3)</A>
-<B>,</B> the Base Definitions volume of IEEE Std 1003.1-2001,
-<I><sched.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/sched_yield.html b/deps/w32-pthreads/manual/sched_yield.html
deleted file mode 100644
index fa5ed04..0000000
--- a/deps/w32-pthreads/manual/sched_yield.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>"SCHED_YIELD"(P) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;14034600">
-	<META NAME="CHANGED" CONTENT="20050505;14050300">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>sched_yield - yield the processor 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <sched.h> </B>
-</P>
-<P><B>int sched_yield(void);</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>The <B>sched_yield</B> function shall force the running thread to
-relinquish the processor until it again becomes the head of its
-thread list. It takes no arguments. 
-</P>
-<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
-<P>The <B>sched_yield</B> function shall return 0 if it completes
-successfully; otherwise, it shall return a value of -1 and set <I>errno</I>
-to indicate the error. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
-<P>No errors are defined. 
-</P>
-<P><I>The following sections are informative.</I> 
-</P>
-<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
-<P>None. 
-</P>
-<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
-<P>The Base Definitions volume of IEEE Std 1003.1-2001,
-<I><sched.h></I> 
-</P>
-<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
-<P>Portions of this text are reprinted and reproduced in electronic
-form from IEEE Std 1003.1, 2003 Edition, Standard for Information
-Technology -- Portable Operating System Interface (POSIX), The Open
-Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
-Institute of Electrical and Electronics Engineers, Inc and The Open
-Group. In the event of any discrepancy between this version and the
-original IEEE and The Open Group Standard, the original IEEE and The
-Open Group Standard is the referee document. The original Standard
-can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
-. 
-</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
-	Usage</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
-	Directions</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
-	Also</A> 
-	</P>
-	<LI><P><A HREF="#sect10" NAME="toc10">Copyright</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
diff --git a/deps/w32-pthreads/manual/sem_init.html b/deps/w32-pthreads/manual/sem_init.html
deleted file mode 100644
index 80e0580..0000000
--- a/deps/w32-pthreads/manual/sem_init.html
+++ /dev/null
@@ -1,200 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
-	<TITLE>SEMAPHORES(3) manual page</TITLE>
-	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3  (Linux)">
-	<META NAME="CREATED" CONTENT="20050505;14061900">
-	<META NAME="CHANGED" CONTENT="20050514;195200">
-	<!-- manual page source format generated by PolyglotMan v3.2, -->
-	<!-- available at http://polyglotman.sourceforge.net/ -->
-</HEAD>
-<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
-<H4>POSIX Threads for Windows – REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
-<P><A HREF="index.html">Reference Index</A></P>
-<P><A HREF="#toc">Table of Contents</A></P>
-<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
-<P>sem_init, sem_wait, sem_trywait, sem_post, sem_getvalue,
-sem_destroy - operations on semaphores 
-</P>
-<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
-<P><B>#include <semaphore.h></B> 
-</P>
-<P><B>int sem_init(sem_t *</B><I>sem</I><B>, int </B><I>pshared</I><B>,
-unsigned int </B><I>value</I><B>);</B> 
-</P>
-<P><B>int sem_wait(sem_t * </B><I>sem</I><B>);</B> 
-</P>
-<P><B>int sem_timedwait(sem_t * </B><I>sem</I>, <B>const struct
-timespec *</B><I>abstime</I><B>);</B> 
-</P>
-<P><B>int sem_trywait(sem_t * </B><I>sem</I><B>);</B> 
-</P>
-<P><B>int sem_post(sem_t * </B><I>sem</I><B>);</B> 
-</P>
-<P><B>int sem_post_multiple(sem_t * </B><I>sem, </I><B>int</B>
-<I>number</I><B>);</B> 
-</P>
-<P><B>int sem_getvalue(sem_t * </B><I>sem</I><B>, int * </B><I>sval</I><B>);</B>
-</P>
-<P><B>int sem_destroy(sem_t * </B><I>sem</I><B>);</B> 
-</P>
-<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
-<P>Semaphores are counters for resources shared between threads. The
-basic operations on semaphores are: increment the counter atomically,
-and wait until the counter is non-null and decrement it atomically. 
-</P>
-<P><B>sem_init</B> initializes the semaphore object pointed to by
-<I>sem</I>. The count associated with the semaphore is set initially
-to <I>value</I>. The <I>pshared</I> argument indicates whether the
-semaphore is local to the current process ( <I>pshared</I> is zero)
-or is to be shared between several processes ( <I>pshared</I> is not
-zero).</P>
-<P><B>Pthreads-w32</B> currently does not support process-shared
-semaphores, thus <B>sem_init</B> always returns with error <B>EPERM</B>
-if <I>pshared</I> is not zero. 
-</P>
-<P><B>sem_wait</B> atomically decrements <I>sem</I>'s count if it is
-greater than 0 and returns immediately or it suspends the calling
-thread until it can resume following a call to <B>sem_post</B> or
-<B>sem_post_multiple</B>.</P>
-<P><B>sem_timedwait</B> atomically decrements <I>sem</I>'s count if
-it is greater than 0 and returns immediately, or it suspends the
-calling thread. If <I>abstime</I> time arrives before the thread can
-resume following a call to <B>sem_post</B> or <B>sem_post_multiple</B>,
-then <B>sem_timedwait</B> returns with a return code of -1 after
-having set <B>errno</B> to <B>ETIMEDOUT</B>. If the call can return
-without suspending then <I>abstime</I> is not checked.</P>
-<P><B>sem_trywait</B> atomically decrements <I>sem</I>'s count if it
-is greater than 0 and returns immediately, or it returns immediately
-with a return code of -1 after having set <B>errno</B> to <B>EAGAIN</B>.
-<B>sem_trywait</B> never blocks.</P>
-<P><B>sem_post</B> either releases one thread if there are any
-waiting on <I>sem</I>, or it atomically increments <I>sem</I>'s
-count.</P>
-<P><B>sem_post_multiple</B> either releases multiple threads if there
-are any waiting on <I>sem</I> and/or it atomically increases <I>sem</I>'s
-count. If there are currently <I>n</I> waiters, where <I>n</I> the
-largest number less than or equal to <I>number</I>, then <I>n</I>
-waiters are released and <I>sem</I>'s count is incremented by <I>number</I>
-minus <I>n</I>.</P>
-<P><B>sem_getvalue</B> stores in the location pointed to by <I>sval</I>
-the current count of the semaphore <I>sem</I>. In the <B>Pthreads-w32</B>
-implementation: if the value returned in <I>sval</I> is greater than
-or equal to 0 it was the <I>sem</I>'s count at some point during the
-call to <B>sem_getvalue</B>. If the value returned in <I>sval</I> is
-less than 0 then it's absolute value represents the number of threads
-waiting on <I>sem</I> at some point during the call to <B>sem_getvalue.
-</B>POSIX does not require an implementation of <B>sem_getvalue</B>
-to return a value in <I>sval</I> that is less than 0, but if it does
-then it's absolute value must represent the number of waiters.</P>
-<P><B>sem_destroy</B> destroys a semaphore object, freeing the
-resources it might hold. No threads should be waiting on the
-semaphore at the time <B>sem_destroy</B> is called.</P>
-<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
-<P><B>sem_wait</B> and <B>sem_timedwait</B> are cancellation points. 
-</P>
-<H2><A HREF="#toc4" NAME="sect4">Async-signal Safety</A></H2>
-<P>These routines are not async-cancel safe.</P>
-<H2><A HREF="#toc5" NAME="sect5">Return Value</A></H2>
-<P>All semaphore functions return 0 on success, or -1 on error in
-which case they write an error code in <B>errno</B>. 
-</P>
-<H2><A HREF="#toc6" NAME="sect6">Errors</A></H2>
-<P>The <B>sem_init</B> function sets <B>errno</B> to the following
-codes on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<I>value</I> exceeds the maximal counter value <B>SEM_VALUE_MAX</B>
-				</DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		<B>ENOSYS</B> 
-		</DT></DL>
-</DL>
-<BLOCKQUOTE STYLE="margin-left: 3cm">
-<I>pshared</I> is not zero 
-</BLOCKQUOTE>
-<P>The <B>sem_timedwait</B> function sets <B>errno</B> to the
-following error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ETIMEDOUT</B>
-				</DT></DL>
-</DL>
-<BLOCKQUOTE STYLE="margin-left: 3cm">
-if <I>abstime</I> arrives before the waiting thread can resume
-following a call to <B>sem_post</B> or <B>sem_post_multiple</B>. 
-</BLOCKQUOTE>
-<P>The <B>sem_trywait</B> function sets <B>errno</B> to the following
-error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EAGAIN</B> 
-		</DT></DL>
-</DL>
-<BLOCKQUOTE STYLE="margin-left: 3cm">
-if the semaphore count is currently 0 
-</BLOCKQUOTE>
-<P>The <B>sem_post</B> and <B>sem_post_multiple</B> functions set
-<B>errno</B> to the following error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ERANGE</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		if after incrementing, the semaphore count would exceed
-		<B>SEM_VALUE_MAX</B> (the semaphore count is left unchanged in this
-		case) 
-		</DD></DL>
-</DL>
-<P>
-The <B>sem_destroy</B> function sets <B>errno</B> to the following
-error code on error: 
-</P>
-<DL>
-	<DL>
-		<DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EBUSY</B> 
-		</DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
-		if some threads are currently blocked waiting on the semaphore. 
-		</DD></DL>
-</DL>
-<H2>
-<A HREF="#toc7" NAME="sect7">Author</A></H2>
-<P>Xavier Leroy <Xavier.Leroy at inria.fr> 
-</P>
-<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
-<H2><A HREF="#toc8" NAME="sect8">See Also</A></H2>
-<P><A HREF="pthread_mutex_init.html"><B>pthread_mutex_init</B>(3)</A>
-, <A HREF="pthread_cond_init.html"><B>pthread_cond_init</B>(3)</A> ,
-<A HREF="pthread_cancel.html"><B>pthread_cancel</B>(3)</A> . 
-</P>
-<HR>
-<P><A NAME="toc"></A><B>Table of Contents</B></P>
-<UL>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Async-signal
-	Safety</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Return
-	Value</A> 
-	</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Errors</A>
-		</P>
-	<LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Author</A>
-		</P>
-	<LI><P><A HREF="#sect8" NAME="toc8">See Also</A> 
-	</P>
-</UL>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/deps/w32-pthreads/misc.c b/deps/w32-pthreads/misc.c
deleted file mode 100644
index cf0e4ec..0000000
--- a/deps/w32-pthreads/misc.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * misc.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-#include "pthread_kill.c"
-#include "pthread_once.c"
-#include "pthread_self.c"
-#include "pthread_equal.c"
-#include "pthread_setconcurrency.c"
-#include "pthread_getconcurrency.c"
-#include "ptw32_new.c"
-#include "ptw32_calloc.c"
-#include "ptw32_reuse.c"
-#include "w32_CancelableWait.c"
diff --git a/deps/w32-pthreads/mutex.c b/deps/w32-pthreads/mutex.c
deleted file mode 100644
index 78bc6d2..0000000
--- a/deps/w32-pthreads/mutex.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * mutex.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#if ! defined(_UWIN) && ! defined(WINCE)
-#   include <process.h>
-#endif
-#if !defined(NEED_FTIME)
-#include <sys/timeb.h>
-#endif
-#include "pthread.h"
-#include "implement.h"
-
-
-#include "ptw32_mutex_check_need_init.c"
-#include "pthread_mutex_init.c"
-#include "pthread_mutex_destroy.c"
-#include "pthread_mutexattr_init.c"
-#include "pthread_mutexattr_destroy.c"
-#include "pthread_mutexattr_getpshared.c"
-#include "pthread_mutexattr_setpshared.c"
-#include "pthread_mutexattr_settype.c"
-#include "pthread_mutexattr_gettype.c"
-#include "pthread_mutexattr_setrobust.c"
-#include "pthread_mutexattr_getrobust.c"
-#include "pthread_mutex_lock.c"
-#include "pthread_mutex_timedlock.c"
-#include "pthread_mutex_unlock.c"
-#include "pthread_mutex_trylock.c"
-#include "pthread_mutex_consistent.c"
diff --git a/deps/w32-pthreads/nonportable.c b/deps/w32-pthreads/nonportable.c
deleted file mode 100644
index b9ff9bf..0000000
--- a/deps/w32-pthreads/nonportable.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * nonportable.c
- *
- * Description:
- * This translation unit implements non-portable thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-#include "pthread_mutexattr_setkind_np.c"
-#include "pthread_mutexattr_getkind_np.c"
-#include "pthread_getw32threadhandle_np.c"
-#include "pthread_getunique_np.c"
-#include "pthread_delay_np.c"
-#include "pthread_num_processors_np.c"
-#include "pthread_win32_attach_detach_np.c"
-#include "pthread_timechange_handler_np.c"
diff --git a/deps/w32-pthreads/private.c b/deps/w32-pthreads/private.c
deleted file mode 100644
index 52d73b7..0000000
--- a/deps/w32-pthreads/private.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * private.c
- *
- * Description:
- * This translation unit implements routines which are private to
- * the implementation and may be used throughout it.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-#include "ptw32_MCS_lock.c"
-#include "ptw32_is_attr.c"
-#include "ptw32_processInitialize.c"
-#include "ptw32_processTerminate.c"
-#include "ptw32_threadStart.c"
-#include "ptw32_threadDestroy.c"
-#include "ptw32_tkAssocCreate.c"
-#include "ptw32_tkAssocDestroy.c"
-#include "ptw32_callUserDestroyRoutines.c"
-#include "ptw32_semwait.c"
-#include "ptw32_timespec.c"
-#include "ptw32_relmillisecs.c"
-#include "ptw32_throw.c"
-#include "ptw32_getprocessors.c"
diff --git a/deps/w32-pthreads/pthread.c b/deps/w32-pthreads/pthread.c
deleted file mode 100644
index a061c8c..0000000
--- a/deps/w32-pthreads/pthread.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * pthread.c
- *
- * Description:
- * This translation unit agregates pthreads-win32 translation units.
- * It is used for inline optimisation of the library,
- * maximising for speed at the expense of size.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/* The following are ordered for inlining */
-
-#include "private.c"
-#include "attr.c"
-#include "barrier.c"
-#include "cancel.c"
-#include "cleanup.c"
-#include "condvar.c"
-#include "create.c"
-#include "dll.c"
-#include "autostatic.c"
-#include "errno.c"
-#include "exit.c"
-#include "fork.c"
-#include "global.c"
-#include "misc.c"
-#include "mutex.c"
-#include "nonportable.c"
-#include "rwlock.c"
-#include "sched.c"
-#include "semaphore.c"
-#include "signal.c"
-#include "spin.c"
-#include "sync.c"
-#include "tsd.c"
diff --git a/deps/w32-pthreads/pthread.dsp b/deps/w32-pthreads/pthread.dsp
deleted file mode 100644
index 112bff7..0000000
--- a/deps/w32-pthreads/pthread.dsp
+++ /dev/null
@@ -1,142 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pthread" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=pthread - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "pthread.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "pthread.mak" CFG="pthread - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "pthread - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "pthread - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "pthread - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "."
-# PROP Intermediate_Dir "."
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "__CLEANUP_C" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /c
-# SUBTRACT CPP /u
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x809 /d "NDEBUG"
-# ADD RSC /l 0x409 /i "." /d "NDEBUG" /d "PTW32_RC_MSC"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib ws2_32.lib /nologo /dll /pdb:none /machine:I386 /out:".\pthreadVC2.dll"
-
-!ELSEIF  "$(CFG)" == "pthread - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "."
-# PROP Intermediate_Dir "."
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "__CLEANUP_C" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x809 /d "_DEBUG"
-# ADD RSC /l 0x409 /i "." /d "_DEBUG" /d "PTW32_RC_MSC"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib ws2_32.lib /nologo /dll /map /debug /machine:I386 /out:".\pthreadVC2.dll" /pdbtype:sept
-# SUBTRACT LINK32 /pdb:none
-
-!ENDIF 
-
-# Begin Target
-
-# Name "pthread - Win32 Release"
-# Name "pthread - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\pthread.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\implement.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\pthread.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\sched.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\semaphore.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# Begin Source File
-
-SOURCE=.\version.rc
-
-!IF  "$(CFG)" == "pthread - Win32 Release"
-
-# ADD BASE RSC /l 0xc09
-# ADD RSC /l 0x409 /i "." /d "PTW32_RC_MSC"
-
-!ELSEIF  "$(CFG)" == "pthread - Win32 Debug"
-
-# ADD BASE RSC /l 0xc09
-# ADD RSC /l 0x409 /i "." /d "PTW32_RC_MSC"
-
-!ENDIF 
-
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/deps/w32-pthreads/pthread.dsw b/deps/w32-pthreads/pthread.dsw
deleted file mode 100644
index 815a678..0000000
--- a/deps/w32-pthreads/pthread.dsw
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "pthread"=.\pthread.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/deps/w32-pthreads/pthread.h b/deps/w32-pthreads/pthread.h
deleted file mode 100644
index d4fc589..0000000
--- a/deps/w32-pthreads/pthread.h
+++ /dev/null
@@ -1,1372 +0,0 @@
-/* This is an implementation of the threads API of POSIX 1003.1-2001.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#if !defined( PTHREAD_H )
-#define PTHREAD_H
-
-/*
- * See the README file for an explanation of the pthreads-win32 version
- * numbering scheme and how the DLL is named etc.
- */
-#define PTW32_VERSION 2,9,1,0
-#define PTW32_VERSION_STRING "2, 9, 1, 0\0"
-
-/* There are three implementations of cancel cleanup.
- * Note that pthread.h is included in both application
- * compilation units and also internally for the library.
- * The code here and within the library aims to work
- * for all reasonable combinations of environments.
- *
- * The three implementations are:
- *
- *   WIN32 SEH
- *   C
- *   C++
- *
- * Please note that exiting a push/pop block via
- * "return", "exit", "break", or "continue" will
- * lead to different behaviour amongst applications
- * depending upon whether the library was built
- * using SEH, C++, or C. For example, a library built
- * with SEH will call the cleanup routine, while both
- * C++ and C built versions will not.
- */
-
-/*
- * Define defaults for cleanup code.
- * Note: Unless the build explicitly defines one of the following, then
- * we default to standard C style cleanup. This style uses setjmp/longjmp
- * in the cancelation and thread exit implementations and therefore won't
- * do stack unwinding if linked to applications that have it (e.g.
- * C++ apps). This is currently consistent with most/all commercial Unix
- * POSIX threads implementations.
- */
-#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )
-# define __CLEANUP_C
-#endif
-
-#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC))
-#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler.
-#endif
-
-/*
- * Stop here if we are being included by the resource compiler.
- */
-#if !defined(RC_INVOKED)
-
-#undef PTW32_LEVEL
-
-#if defined(_POSIX_SOURCE)
-#define PTW32_LEVEL 0
-/* Early POSIX */
-#endif
-
-#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
-#undef PTW32_LEVEL
-#define PTW32_LEVEL 1
-/* Include 1b, 1c and 1d */
-#endif
-
-#if defined(INCLUDE_NP)
-#undef PTW32_LEVEL
-#define PTW32_LEVEL 2
-/* Include Non-Portable extensions */
-#endif
-
-#define PTW32_LEVEL_MAX 3
-
-#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 )  || !defined(PTW32_LEVEL)
-#define PTW32_LEVEL PTW32_LEVEL_MAX
-/* Include everything */
-#endif
-
-#if defined(_UWIN)
-#   define HAVE_STRUCT_TIMESPEC 1
-#   define HAVE_SIGNAL_H        1
-#   undef HAVE_PTW32_CONFIG_H
-#   pragma comment(lib, "pthread")
-#endif
-
-/*
- * -------------------------------------------------------------
- *
- *
- * Module: pthread.h
- *
- * Purpose:
- *      Provides an implementation of PThreads based upon the
- *      standard:
- *
- *              POSIX 1003.1-2001
- *  and
- *    The Single Unix Specification version 3
- *
- *    (these two are equivalent)
- *
- *      in order to enhance code portability between Windows,
- *  various commercial Unix implementations, and Linux.
- *
- *      See the ANNOUNCE file for a full list of conforming
- *      routines and defined constants, and a list of missing
- *      routines and constants not defined in this implementation.
- *
- * Authors:
- *      There have been many contributors to this library.
- *      The initial implementation was contributed by
- *      John Bossom, and several others have provided major
- *      sections or revisions of parts of the implementation.
- *      Often significant effort has been contributed to
- *      find and fix important bugs and other problems to
- *      improve the reliability of the library, which sometimes
- *      is not reflected in the amount of code which changed as
- *      result.
- *      As much as possible, the contributors are acknowledged
- *      in the ChangeLog file in the source code distribution
- *      where their changes are noted in detail.
- *
- *      Contributors are listed in the CONTRIBUTORS file.
- *
- *      As usual, all bouquets go to the contributors, and all
- *      brickbats go to the project maintainer.
- *
- * Maintainer:
- *      The code base for this project is coordinated and
- *      eventually pre-tested, packaged, and made available by
- *
- *              Ross Johnson <rpj at callisto.canberra.edu.au>
- *
- * QA Testers:
- *      Ultimately, the library is tested in the real world by
- *      a host of competent and demanding scientists and
- *      engineers who report bugs and/or provide solutions
- *      which are then fixed or incorporated into subsequent
- *      versions of the library. Each time a bug is fixed, a
- *      test case is written to prove the fix and ensure
- *      that later changes to the code don't reintroduce the
- *      same error. The number of test cases is slowly growing
- *      and therefore so is the code reliability.
- *
- * Compliance:
- *      See the file ANNOUNCE for the list of implemented
- *      and not-implemented routines and defined options.
- *      Of course, these are all defined is this file as well.
- *
- * Web site:
- *      The source code and other information about this library
- *      are available from
- *
- *              http://sources.redhat.com/pthreads-win32/
- *
- * -------------------------------------------------------------
- */
-
-/* Try to avoid including windows.h */
-#if (defined(__MINGW64__) || defined(__MINGW32__)) && defined(__cplusplus)
-#define PTW32_INCLUDE_WINDOWS_H
-#endif
-
-#if defined(PTW32_INCLUDE_WINDOWS_H)
-#include <windows.h>
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__)
-/*
- * VC++6.0 or early compiler's header has no DWORD_PTR type.
- */
-typedef unsigned long DWORD_PTR;
-typedef unsigned long ULONG_PTR;
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1900
-#define HAVE_STRUCT_TIMESPEC
-#endif
-/*
- * -----------------
- * autoconf switches
- * -----------------
- */
-
-#if defined(HAVE_PTW32_CONFIG_H)
-#include "config.h"
-#endif /* HAVE_PTW32_CONFIG_H */
-
-#if !defined(NEED_FTIME)
-#include <time.h>
-#else /* NEED_FTIME */
-/* use native WIN32 time API */
-#endif /* NEED_FTIME */
-
-#if defined(HAVE_SIGNAL_H)
-#include <signal.h>
-#endif /* HAVE_SIGNAL_H */
-
-#include <limits.h>
-
-/*
- * Boolean values to make us independent of system includes.
- */
-enum {
-  PTW32_FALSE = 0,
-  PTW32_TRUE = (! PTW32_FALSE)
-};
-
-/*
- * This is a duplicate of what is in the autoconf config.h,
- * which is only used when building the pthread-win32 libraries.
- */
-
-#if !defined(PTW32_CONFIG_H)
-#  if defined(WINCE)
-#    define NEED_ERRNO
-#    define NEED_SEM
-#  endif
-#  if defined(__MINGW64__)
-#    define HAVE_STRUCT_TIMESPEC
-#    define HAVE_MODE_T
-#  elif defined(_UWIN) || defined(__MINGW32__)
-#    define HAVE_MODE_T
-#  endif
-#endif
-
-/*
- *
- */
-
-#if PTW32_LEVEL >= PTW32_LEVEL_MAX
-#if defined(NEED_ERRNO)
-#include "need_errno.h"
-#else
-#include <errno.h>
-#endif
-#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
-
-/*
- * Several systems don't define some error numbers.
- */
-#if !defined(ENOTSUP)
-#  define ENOTSUP 48   /* This is the value in Solaris. */
-#endif
-
-#if !defined(ETIMEDOUT)
-#  define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */
-#endif
-
-#if !defined(ENOSYS)
-#  define ENOSYS 140     /* Semi-arbitrary value */
-#endif
-
-#if !defined(EDEADLK)
-#  if defined(EDEADLOCK)
-#    define EDEADLK EDEADLOCK
-#  else
-#    define EDEADLK 36     /* This is the value in MSVC. */
-#  endif
-#endif
-
-/* POSIX 2008 - related to robust mutexes */
-#if !defined(EOWNERDEAD)
-#  define EOWNERDEAD 43
-#endif
-#if !defined(ENOTRECOVERABLE)
-#  define ENOTRECOVERABLE 44
-#endif
-
-#include "sched.h"
-
-/*
- * To avoid including windows.h we define only those things that we
- * actually need from it.
- */
-#if !defined(PTW32_INCLUDE_WINDOWS_H)
-#if !defined(HANDLE)
-# define PTW32__HANDLE_DEF
-# define HANDLE void *
-#endif
-#if !defined(DWORD)
-# define PTW32__DWORD_DEF
-# define DWORD unsigned long
-#endif
-#endif
-
-#if !defined(HAVE_STRUCT_TIMESPEC)
-#define HAVE_STRUCT_TIMESPEC
-#if !defined(_TIMESPEC_DEFINED)
-#define _TIMESPEC_DEFINED
-struct timespec {
-        time_t tv_sec;
-        long tv_nsec;
-};
-#endif /* _TIMESPEC_DEFINED */
-#endif /* HAVE_STRUCT_TIMESPEC */
-
-#if !defined(SIG_BLOCK)
-#define SIG_BLOCK 0
-#endif /* SIG_BLOCK */
-
-#if !defined(SIG_UNBLOCK)
-#define SIG_UNBLOCK 1
-#endif /* SIG_UNBLOCK */
-
-#if !defined(SIG_SETMASK)
-#define SIG_SETMASK 2
-#endif /* SIG_SETMASK */
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif                          /* __cplusplus */
-
-/*
- * -------------------------------------------------------------
- *
- * POSIX 1003.1-2001 Options
- * =========================
- *
- * Options are normally set in <unistd.h>, which is not provided
- * with pthreads-win32.
- *
- * For conformance with the Single Unix Specification (version 3), all of the
- * options below are defined, and have a value of either -1 (not supported)
- * or 200112L (supported).
- *
- * These options can neither be left undefined nor have a value of 0, because
- * either indicates that sysconf(), which is not implemented, may be used at
- * runtime to check the status of the option.
- *
- * _POSIX_THREADS (== 200112L)
- *                      If == 200112L, you can use threads
- *
- * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)
- *                      If == 200112L, you can control the size of a thread's
- *                      stack
- *                              pthread_attr_getstacksize
- *                              pthread_attr_setstacksize
- *
- * _POSIX_THREAD_ATTR_STACKADDR (== -1)
- *                      If == 200112L, you can allocate and control a thread's
- *                      stack. If not supported, the following functions
- *                      will return ENOSYS, indicating they are not
- *                      supported:
- *                              pthread_attr_getstackaddr
- *                              pthread_attr_setstackaddr
- *
- * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)
- *                      If == 200112L, you can use realtime scheduling.
- *                      This option indicates that the behaviour of some
- *                      implemented functions conforms to the additional TPS
- *                      requirements in the standard. E.g. rwlocks favour
- *                      writers over readers when threads have equal priority.
- *
- * _POSIX_THREAD_PRIO_INHERIT (== -1)
- *                      If == 200112L, you can create priority inheritance
- *                      mutexes.
- *                              pthread_mutexattr_getprotocol +
- *                              pthread_mutexattr_setprotocol +
- *
- * _POSIX_THREAD_PRIO_PROTECT (== -1)
- *                      If == 200112L, you can create priority ceiling mutexes
- *                      Indicates the availability of:
- *                              pthread_mutex_getprioceiling
- *                              pthread_mutex_setprioceiling
- *                              pthread_mutexattr_getprioceiling
- *                              pthread_mutexattr_getprotocol     +
- *                              pthread_mutexattr_setprioceiling
- *                              pthread_mutexattr_setprotocol     +
- *
- * _POSIX_THREAD_PROCESS_SHARED (== -1)
- *                      If set, you can create mutexes and condition
- *                      variables that can be shared with another
- *                      process.If set, indicates the availability
- *                      of:
- *                              pthread_mutexattr_getpshared
- *                              pthread_mutexattr_setpshared
- *                              pthread_condattr_getpshared
- *                              pthread_condattr_setpshared
- *
- * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)
- *                      If == 200112L you can use the special *_r library
- *                      functions that provide thread-safe behaviour
- *
- * _POSIX_READER_WRITER_LOCKS (== 200112L)
- *                      If == 200112L, you can use read/write locks
- *
- * _POSIX_SPIN_LOCKS (== 200112L)
- *                      If == 200112L, you can use spin locks
- *
- * _POSIX_BARRIERS (== 200112L)
- *                      If == 200112L, you can use barriers
- *
- *      + These functions provide both 'inherit' and/or
- *        'protect' protocol, based upon these macro
- *        settings.
- *
- * -------------------------------------------------------------
- */
-
-/*
- * POSIX Options
- */
-#undef _POSIX_THREADS
-#define _POSIX_THREADS 200809L
-
-#undef _POSIX_READER_WRITER_LOCKS
-#define _POSIX_READER_WRITER_LOCKS 200809L
-
-#undef _POSIX_SPIN_LOCKS
-#define _POSIX_SPIN_LOCKS 200809L
-
-#undef _POSIX_BARRIERS
-#define _POSIX_BARRIERS 200809L
-
-#undef _POSIX_THREAD_SAFE_FUNCTIONS
-#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L
-
-#undef _POSIX_THREAD_ATTR_STACKSIZE
-#define _POSIX_THREAD_ATTR_STACKSIZE 200809L
-
-/*
- * The following options are not supported
- */
-#undef _POSIX_THREAD_ATTR_STACKADDR
-#define _POSIX_THREAD_ATTR_STACKADDR -1
-
-#undef _POSIX_THREAD_PRIO_INHERIT
-#define _POSIX_THREAD_PRIO_INHERIT -1
-
-#undef _POSIX_THREAD_PRIO_PROTECT
-#define _POSIX_THREAD_PRIO_PROTECT -1
-
-/* TPS is not fully supported.  */
-#undef _POSIX_THREAD_PRIORITY_SCHEDULING
-#define _POSIX_THREAD_PRIORITY_SCHEDULING -1
-
-#undef _POSIX_THREAD_PROCESS_SHARED
-#define _POSIX_THREAD_PROCESS_SHARED -1
-
-
-/*
- * POSIX 1003.1-2001 Limits
- * ===========================
- *
- * These limits are normally set in <limits.h>, which is not provided with
- * pthreads-win32.
- *
- * PTHREAD_DESTRUCTOR_ITERATIONS
- *                      Maximum number of attempts to destroy
- *                      a thread's thread-specific data on
- *                      termination (must be at least 4)
- *
- * PTHREAD_KEYS_MAX
- *                      Maximum number of thread-specific data keys
- *                      available per process (must be at least 128)
- *
- * PTHREAD_STACK_MIN
- *                      Minimum supported stack size for a thread
- *
- * PTHREAD_THREADS_MAX
- *                      Maximum number of threads supported per
- *                      process (must be at least 64).
- *
- * SEM_NSEMS_MAX
- *                      The maximum number of semaphores a process can have.
- *                      (must be at least 256)
- *
- * SEM_VALUE_MAX
- *                      The maximum value a semaphore can have.
- *                      (must be at least 32767)
- *
- */
-#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS
-#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS     4
-
-#undef PTHREAD_DESTRUCTOR_ITERATIONS
-#define PTHREAD_DESTRUCTOR_ITERATIONS           _POSIX_THREAD_DESTRUCTOR_ITERATIONS
-
-#undef _POSIX_THREAD_KEYS_MAX
-#define _POSIX_THREAD_KEYS_MAX                  128
-
-#undef PTHREAD_KEYS_MAX
-#define PTHREAD_KEYS_MAX                        _POSIX_THREAD_KEYS_MAX
-
-#undef PTHREAD_STACK_MIN
-#define PTHREAD_STACK_MIN                       0
-
-#undef _POSIX_THREAD_THREADS_MAX
-#define _POSIX_THREAD_THREADS_MAX               64
-
-  /* Arbitrary value */
-#undef PTHREAD_THREADS_MAX
-#define PTHREAD_THREADS_MAX                     2019
-
-#undef _POSIX_SEM_NSEMS_MAX
-#define _POSIX_SEM_NSEMS_MAX                    256
-
-  /* Arbitrary value */
-#undef SEM_NSEMS_MAX
-#define SEM_NSEMS_MAX                           1024
-
-#undef _POSIX_SEM_VALUE_MAX
-#define _POSIX_SEM_VALUE_MAX                    32767
-
-#undef SEM_VALUE_MAX
-#define SEM_VALUE_MAX                           INT_MAX
-
-
-#if defined(__GNUC__) && !defined(__declspec)
-# error Please upgrade your GNU compiler to one that supports __declspec.
-#endif
-
-/*
- * When building the library, you should define PTW32_BUILD so that
- * the variables/functions are exported correctly. When using the library,
- * do NOT define PTW32_BUILD, and then the variables/functions will
- * be imported correctly.
- */
-#if !defined(PTW32_STATIC_LIB)
-#  if defined(PTW32_BUILD)
-#    define PTW32_DLLPORT __declspec (dllexport)
-#  else
-#    define PTW32_DLLPORT
-#  endif
-#else
-#  define PTW32_DLLPORT
-#endif
-
-/*
- * The Open Watcom C/C++ compiler uses a non-standard calling convention
- * that passes function args in registers unless __cdecl is explicitly specified
- * in exposed function prototypes.
- *
- * We force all calls to cdecl even though this could slow Watcom code down
- * slightly. If you know that the Watcom compiler will be used to build both
- * the DLL and application, then you can probably define this as a null string.
- * Remember that pthread.h (this file) is used for both the DLL and application builds.
- */
-#define PTW32_CDECL __cdecl
-
-#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX
-#   include     <sys/types.h>
-#else
-/*
- * Generic handle type - intended to extend uniqueness beyond
- * that available with a simple pointer. It should scale for either
- * IA-32 or IA-64.
- */
-typedef struct {
-    void * p;                   /* Pointer to actual object */
-    unsigned int x;             /* Extra information - reuse count etc */
-} ptw32_handle_t;
-
-typedef ptw32_handle_t pthread_t;
-typedef struct pthread_attr_t_ * pthread_attr_t;
-typedef struct pthread_once_t_ pthread_once_t;
-typedef struct pthread_key_t_ * pthread_key_t;
-typedef struct pthread_mutex_t_ * pthread_mutex_t;
-typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t;
-typedef struct pthread_cond_t_ * pthread_cond_t;
-typedef struct pthread_condattr_t_ * pthread_condattr_t;
-#endif
-typedef struct pthread_rwlock_t_ * pthread_rwlock_t;
-typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t;
-typedef struct pthread_spinlock_t_ * pthread_spinlock_t;
-typedef struct pthread_barrier_t_ * pthread_barrier_t;
-typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t;
-
-/*
- * ====================
- * ====================
- * POSIX Threads
- * ====================
- * ====================
- */
-
-enum {
-/*
- * pthread_attr_{get,set}detachstate
- */
-  PTHREAD_CREATE_JOINABLE       = 0,  /* Default */
-  PTHREAD_CREATE_DETACHED       = 1,
-
-/*
- * pthread_attr_{get,set}inheritsched
- */
-  PTHREAD_INHERIT_SCHED         = 0,
-  PTHREAD_EXPLICIT_SCHED        = 1,  /* Default */
-
-/*
- * pthread_{get,set}scope
- */
-  PTHREAD_SCOPE_PROCESS         = 0,
-  PTHREAD_SCOPE_SYSTEM          = 1,  /* Default */
-
-/*
- * pthread_setcancelstate paramters
- */
-  PTHREAD_CANCEL_ENABLE         = 0,  /* Default */
-  PTHREAD_CANCEL_DISABLE        = 1,
-
-/*
- * pthread_setcanceltype parameters
- */
-  PTHREAD_CANCEL_ASYNCHRONOUS   = 0,
-  PTHREAD_CANCEL_DEFERRED       = 1,  /* Default */
-
-/*
- * pthread_mutexattr_{get,set}pshared
- * pthread_condattr_{get,set}pshared
- */
-  PTHREAD_PROCESS_PRIVATE       = 0,
-  PTHREAD_PROCESS_SHARED        = 1,
-
-/*
- * pthread_mutexattr_{get,set}robust
- */
-  PTHREAD_MUTEX_STALLED         = 0,  /* Default */
-  PTHREAD_MUTEX_ROBUST          = 1,
-
-/*
- * pthread_barrier_wait
- */
-  PTHREAD_BARRIER_SERIAL_THREAD = -1
-};
-
-/*
- * ====================
- * ====================
- * Cancelation
- * ====================
- * ====================
- */
-#define PTHREAD_CANCELED       ((void *)(size_t) -1)
-
-
-/*
- * ====================
- * ====================
- * Once Key
- * ====================
- * ====================
- */
-#define PTHREAD_ONCE_INIT       { PTW32_FALSE, 0, 0, 0}
-
-struct pthread_once_t_
-{
-  int          done;        /* indicates if user function has been executed */
-  void *       lock;
-  int          reserved1;
-  int          reserved2;
-};
-
-
-/*
- * ====================
- * ====================
- * Object initialisers
- * ====================
- * ====================
- */
-#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1)
-#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2)
-#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -3)
-
-/*
- * Compatibility with LinuxThreads
- */
-#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
-#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
-
-#define PTHREAD_COND_INITIALIZER ((pthread_cond_t)(size_t) -1)
-
-#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1)
-
-#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_t) -1)
-
-
-/*
- * Mutex types.
- */
-enum
-{
-  /* Compatibility with LinuxThreads */
-  PTHREAD_MUTEX_FAST_NP,
-  PTHREAD_MUTEX_RECURSIVE_NP,
-  PTHREAD_MUTEX_ERRORCHECK_NP,
-  PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,
-  PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,
-  /* For compatibility with POSIX */
-  PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
-  PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
-  PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
-  PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
-};
-
-
-typedef struct ptw32_cleanup_t ptw32_cleanup_t;
-
-#if defined(_MSC_VER)
-/* Disable MSVC 'anachronism used' warning */
-#pragma warning( disable : 4229 )
-#endif
-
-typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *);
-
-#if defined(_MSC_VER)
-#pragma warning( default : 4229 )
-#endif
-
-struct ptw32_cleanup_t
-{
-  ptw32_cleanup_callback_t routine;
-  void *arg;
-  struct ptw32_cleanup_t *prev;
-};
-
-#if defined(__CLEANUP_SEH)
-        /*
-         * WIN32 SEH version of cancel cleanup.
-         */
-
-#define pthread_cleanup_push( _rout, _arg ) \
-        { \
-            ptw32_cleanup_t     _cleanup; \
-            \
-        _cleanup.routine        = (ptw32_cleanup_callback_t)(_rout); \
-            _cleanup.arg        = (_arg); \
-            __try \
-              { \
-
-#define pthread_cleanup_pop( _execute ) \
-              } \
-            __finally \
-                { \
-                    if( _execute || AbnormalTermination()) \
-                      { \
-                          (*(_cleanup.routine))( _cleanup.arg ); \
-                      } \
-                } \
-        }
-
-#else /* __CLEANUP_SEH */
-
-#if defined(__CLEANUP_C)
-
-        /*
-         * C implementation of PThreads cancel cleanup
-         */
-
-#define pthread_cleanup_push( _rout, _arg ) \
-        { \
-            ptw32_cleanup_t     _cleanup; \
-            \
-            ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \
-
-#define pthread_cleanup_pop( _execute ) \
-            (void) ptw32_pop_cleanup( _execute ); \
-        }
-
-#else /* __CLEANUP_C */
-
-#if defined(__CLEANUP_CXX)
-
-        /*
-         * C++ version of cancel cleanup.
-         * - John E. Bossom.
-         */
-
-        class PThreadCleanup {
-          /*
-           * PThreadCleanup
-           *
-           * Purpose
-           *      This class is a C++ helper class that is
-           *      used to implement pthread_cleanup_push/
-           *      pthread_cleanup_pop.
-           *      The destructor of this class automatically
-           *      pops the pushed cleanup routine regardless
-           *      of how the code exits the scope
-           *      (i.e. such as by an exception)
-           */
-      ptw32_cleanup_callback_t cleanUpRout;
-          void    *       obj;
-          int             executeIt;
-
-        public:
-          PThreadCleanup() :
-            cleanUpRout( 0 ),
-            obj( 0 ),
-            executeIt( 0 )
-            /*
-             * No cleanup performed
-             */
-            {
-            }
-
-          PThreadCleanup(
-             ptw32_cleanup_callback_t routine,
-                         void    *       arg ) :
-            cleanUpRout( routine ),
-            obj( arg ),
-            executeIt( 1 )
-            /*
-             * Registers a cleanup routine for 'arg'
-             */
-            {
-            }
-
-          ~PThreadCleanup()
-            {
-              if ( executeIt && ((void *) cleanUpRout != (void *) 0) )
-                {
-                  (void) (*cleanUpRout)( obj );
-                }
-            }
-
-          void execute( int exec )
-            {
-              executeIt = exec;
-            }
-        };
-
-        /*
-         * C++ implementation of PThreads cancel cleanup;
-         * This implementation takes advantage of a helper
-         * class who's destructor automatically calls the
-         * cleanup routine if we exit our scope weirdly
-         */
-#define pthread_cleanup_push( _rout, _arg ) \
-        { \
-            PThreadCleanup  cleanup((ptw32_cleanup_callback_t)(_rout), \
-                                    (void *) (_arg) );
-
-#define pthread_cleanup_pop( _execute ) \
-            cleanup.execute( _execute ); \
-        }
-
-#else
-
-#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
-
-#endif /* __CLEANUP_CXX */
-
-#endif /* __CLEANUP_C */
-
-#endif /* __CLEANUP_SEH */
-
-/*
- * ===============
- * ===============
- * Methods
- * ===============
- * ===============
- */
-
-/*
- * PThread Attribute Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr,
-                                         int *detachstate);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr,
-                                       void **stackaddr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr,
-                                       size_t * stacksize);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr,
-                                         int detachstate);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr,
-                                       void *stackaddr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr,
-                                       size_t stacksize);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr,
-                                        struct sched_param *param);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr,
-                                        const struct sched_param *param);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *,
-                                         int);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (const pthread_attr_t *,
-                                         int *);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr,
-                                         int inheritsched);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(const pthread_attr_t * attr,
-                                         int * inheritsched);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *,
-                                   int);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *,
-                                   int *);
-
-/*
- * PThread Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,
-                            const pthread_attr_t * attr,
-                            void *(PTW32_CDECL *start) (void *),
-                            void *arg);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1,
-                           pthread_t t2);
-
-PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread,
-                          void **value_ptr);
-
-PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state,
-                                    int *oldstate);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type,
-                                   int *oldtype);
-
-PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control,
-                          void (PTW32_CDECL *init_routine) (void));
-
-#if PTW32_LEVEL >= PTW32_LEVEL_MAX
-PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute);
-
-PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
-                                 ptw32_cleanup_callback_t routine,
-                                 void *arg);
-#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
-
-/*
- * Thread Specific Data Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key,
-                                void (PTW32_CDECL *destructor) (void *));
-
-PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key,
-                                 const void *value);
-
-PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key);
-
-
-/*
- * Mutex Attribute Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t
-                                          * attr,
-                                          int *pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
-                                          int pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust(
-                                           pthread_mutexattr_t *attr,
-                                           int robust);
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust(
-                                           const pthread_mutexattr_t * attr,
-                                           int * robust);
-
-/*
- * Barrier Attribute Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t
-                                            * attr,
-                                            int *pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,
-                                            int pshared);
-
-/*
- * Mutex Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex,
-                                const pthread_mutexattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t * mutex,
-                                    const struct timespec *abstime);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (pthread_mutex_t * mutex);
-
-/*
- * Spinlock Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock);
-
-/*
- * Barrier Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier,
-                                  const pthread_barrierattr_t * attr,
-                                  unsigned int count);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier);
-
-/*
- * Condition Variable Attribute Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr,
-                                         int *pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr,
-                                         int pshared);
-
-/*
- * Condition Variable Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond,
-                               const pthread_condattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond,
-                               pthread_mutex_t * mutex);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond,
-                                    pthread_mutex_t * mutex,
-                                    const struct timespec *abstime);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond);
-
-/*
- * Scheduling
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread,
-                                   int policy,
-                                   const struct sched_param *param);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread,
-                                   int *policy,
-                                   struct sched_param *param);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int);
- 
-PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void);
-
-/*
- * Read-Write Lock Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock,
-                                const pthread_rwlockattr_t *attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
-                                       const struct timespec *abstime);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
-                                       const struct timespec *abstime);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
-                                           int *pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
-                                           int pshared);
-
-#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1
-
-/*
- * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32
- * already have signal.h that don't define these.
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig);
-
-/*
- * Non-portable functions
- */
-
-/*
- * Compatibility with Linux.
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
-                                         int kind);
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
-                                         int *kind);
-
-/*
- * Possibly supported by other POSIX threads implementations
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval);
-PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void);
-PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread);
-
-/*
- * Useful if an application wants to statically link
- * the lib rather than load the DLL at run-time.
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void);
-PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void);
-PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void);
-PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void);
-
-/*
- * Features that are auto-detected at load/run time.
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int);
-enum ptw32_features {
-  PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */
-  PTW32_ALERTABLE_ASYNC_CANCEL              = 0x0002  /* Can cancel blocked threads. */
-};
-
-/*
- * Register a system time change with the library.
- * Causes the library to perform various functions
- * in response to the change. Should be called whenever
- * the application's top level window receives a
- * WM_TIMECHANGE message. It can be passed directly to
- * pthread_create() as a new thread if desired.
- */
-PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *);
-
-#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */
-
-#if PTW32_LEVEL >= PTW32_LEVEL_MAX
-
-/*
- * Returns the Win32 HANDLE for the POSIX thread.
- */
-PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread);
-/*
- * Returns the win32 thread ID for POSIX thread.
- */
-PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np (pthread_t thread);
-
-
-/*
- * Protected Methods
- *
- * This function blocks until the given WIN32 handle
- * is signaled or pthread_cancel had been called.
- * This function allows the caller to hook into the
- * PThreads cancel mechanism. It is implemented using
- *
- *              WaitForMultipleObjects
- *
- * on 'waitHandle' and a manually reset WIN32 Event
- * used to implement pthread_cancel. The 'timeout'
- * argument to TimedWait is simply passed to
- * WaitForMultipleObjects.
- */
-PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle);
-PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle,
-                                        DWORD timeout);
-
-#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
-
-/*
- * Thread-Safe C Runtime Library Mappings.
- */
-#if !defined(_UWIN)
-#  if defined(NEED_ERRNO)
-     PTW32_DLLPORT int * PTW32_CDECL _errno( void );
-#  else
-#    if !defined(errno)
-#      if (defined(_MT) || defined(_DLL))
-         __declspec(dllimport) extern int * __cdecl _errno(void);
-#        define errno   (*_errno())
-#      endif
-#    endif
-#  endif
-#endif
-
-/*
- * Some compiler environments don't define some things.
- */
-#if defined(__BORLANDC__)
-#  define _ftime ftime
-#  define _timeb timeb
-#endif
-
-#if defined(__cplusplus)
-
-/*
- * Internal exceptions
- */
-class ptw32_exception {};
-class ptw32_exception_cancel : public ptw32_exception {};
-class ptw32_exception_exit   : public ptw32_exception {};
-
-#endif
-
-#if PTW32_LEVEL >= PTW32_LEVEL_MAX
-
-/* FIXME: This is only required if the library was built using SEH */
-/*
- * Get internal SEH tag
- */
-PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void);
-
-#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
-
-#if !defined(PTW32_BUILD)
-
-#if defined(__CLEANUP_SEH)
-
-/*
- * Redefine the SEH __except keyword to ensure that applications
- * propagate our internal exceptions up to the library's internal handlers.
- */
-#define __except( E ) \
-        __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
-                 ? EXCEPTION_CONTINUE_SEARCH : ( E ) )
-
-#endif /* __CLEANUP_SEH */
-
-#if defined(__CLEANUP_CXX)
-
-/*
- * Redefine the C++ catch keyword to ensure that applications
- * propagate our internal exceptions up to the library's internal handlers.
- */
-#if defined(_MSC_VER)
-        /*
-         * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
-         * if you want Pthread-Win32 cancelation and pthread_exit to work.
-         */
-
-#if !defined(PtW32NoCatchWarn)
-
-#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.")
-#pragma message("------------------------------------------------------------------")
-#pragma message("When compiling applications with MSVC++ and C++ exception handling:")
-#pragma message("  Replace any 'catch( ... )' in routines called from POSIX threads")
-#pragma message("  with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread")
-#pragma message("  cancelation and pthread_exit to work. For example:")
-#pragma message("")
-#pragma message("    #if defined(PtW32CatchAll)")
-#pragma message("      PtW32CatchAll")
-#pragma message("    #else")
-#pragma message("      catch(...)")
-#pragma message("    #endif")
-#pragma message("        {")
-#pragma message("          /* Catchall block processing */")
-#pragma message("        }")
-#pragma message("------------------------------------------------------------------")
-
-#endif
-
-#define PtW32CatchAll \
-        catch( ptw32_exception & ) { throw; } \
-        catch( ... )
-
-#else /* _MSC_VER */
-
-#define catch( E ) \
-        catch( ptw32_exception & ) { throw; } \
-        catch( E )
-
-#endif /* _MSC_VER */
-
-#endif /* __CLEANUP_CXX */
-
-#endif /* ! PTW32_BUILD */
-
-#if defined(__cplusplus)
-}                               /* End of extern "C" */
-#endif                          /* __cplusplus */
-
-#if defined(PTW32__HANDLE_DEF)
-# undef HANDLE
-#endif
-#if defined(PTW32__DWORD_DEF)
-# undef DWORD
-#endif
-
-#undef PTW32_LEVEL
-#undef PTW32_LEVEL_MAX
-
-#endif /* ! RC_INVOKED */
-
-#endif /* PTHREAD_H */
diff --git a/deps/w32-pthreads/pthread.lastbuildstate b/deps/w32-pthreads/pthread.lastbuildstate
deleted file mode 100644
index 71ee68a..0000000
--- a/deps/w32-pthreads/pthread.lastbuildstate
+++ /dev/null
@@ -1,2 +0,0 @@
-#v4.0:v100:false
-Release-Static|x64|D:\OBS2\liboms-util\w32-pthreads\|
diff --git a/deps/w32-pthreads/pthread.sln b/deps/w32-pthreads/pthread.sln
deleted file mode 100644
index fbf5991..0000000
--- a/deps/w32-pthreads/pthread.sln
+++ /dev/null
@@ -1,38 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pthread", "pthread.vcxproj", "{969D9298-8CEF-14A3-8EEF-E3C596896C8D}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
-		Debug-Static|Win32 = Debug-Static|Win32
-		Debug-Static|x64 = Debug-Static|x64
-		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
-		Release-Static|Win32 = Release-Static|Win32
-		Release-Static|x64 = Release-Static|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Debug|Win32.ActiveCfg = Debug|Win32
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Debug|Win32.Build.0 = Debug|Win32
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Debug|x64.ActiveCfg = Debug|x64
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Debug|x64.Build.0 = Debug|x64
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Debug-Static|Win32.Build.0 = Debug-Static|Win32
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Debug-Static|x64.ActiveCfg = Debug-Static|x64
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Debug-Static|x64.Build.0 = Debug-Static|x64
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Release|Win32.ActiveCfg = Release|Win32
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Release|Win32.Build.0 = Release|Win32
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Release|x64.ActiveCfg = Release|x64
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Release|x64.Build.0 = Release|x64
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Release-Static|Win32.ActiveCfg = Release-Static|Win32
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Release-Static|Win32.Build.0 = Release-Static|Win32
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Release-Static|x64.ActiveCfg = Release-Static|x64
-		{969D9298-8CEF-14A3-8EEF-E3C596896C8D}.Release-Static|x64.Build.0 = Release-Static|x64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/deps/w32-pthreads/pthread.vcxproj b/deps/w32-pthreads/pthread.vcxproj
deleted file mode 100644
index 8a17fed..0000000
--- a/deps/w32-pthreads/pthread.vcxproj
+++ /dev/null
@@ -1,514 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug-Static|Win32">
-      <Configuration>Debug-Static</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug-Static|x64">
-      <Configuration>Debug-Static</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release-Static|Win32">
-      <Configuration>Release-Static</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release-Static|x64">
-      <Configuration>Release-Static</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <SccProjectName />
-    <SccLocalPath />
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <OutDir>.\.\</OutDir>
-    <IntDir>.\.\</IntDir>
-    <LinkIncremental>false</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|Win32'">
-    <OutDir>.\.\</OutDir>
-    <IntDir>.\.\</IntDir>
-    <LinkIncremental>false</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <OutDir>.\.\</OutDir>
-    <IntDir>.\.\</IntDir>
-    <LinkIncremental>false</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|x64'">
-    <OutDir>.\.\</OutDir>
-    <IntDir>.\.\</IntDir>
-    <LinkIncremental>false</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <OutDir>.\.\</OutDir>
-    <IntDir>.\.\</IntDir>
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|Win32'">
-    <OutDir>.\.\</OutDir>
-    <IntDir>.\.\</IntDir>
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <OutDir>.\.\</OutDir>
-    <IntDir>.\.\</IntDir>
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|x64'">
-    <OutDir>.\.\</OutDir>
-    <IntDir>.\.\</IntDir>
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
-      <StringPooling>true</StringPooling>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <Optimization>MaxSpeed</Optimization>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <WarningLevel>Level3</WarningLevel>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <UndefineAllPreprocessorDefinitions>false</UndefineAllPreprocessorDefinitions>
-      <PreprocessorDefinitions>__CLEANUP_C;WIN32;NDEBUG;_WINDOWS;_USRDLL;PTW32_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AssemblerListingLocation>.\.\</AssemblerListingLocation>
-      <PrecompiledHeaderOutputFile>.\.\pthread.pch</PrecompiledHeaderOutputFile>
-      <ObjectFileName>.\.\</ObjectFileName>
-      <ProgramDataBaseFileName>.\.\</ProgramDataBaseFileName>
-    </ClCompile>
-    <Midl>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <TypeLibraryName>.\.\pthread.tlb</TypeLibraryName>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-      <TargetEnvironment>Win32</TargetEnvironment>
-    </Midl>
-    <ResourceCompile>
-      <Culture>0x0409</Culture>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>NDEBUG;PTW32_RC_MSC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <Bscmake>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>.\.\pthread.bsc</OutputFile>
-    </Bscmake>
-    <Link>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <LinkDLL>true</LinkDLL>
-      <SubSystem>Console</SubSystem>
-      <OutputFile>.\pthreadVC2.dll</OutputFile>
-      <ImportLibrary>.\.\pthreadVC2.lib</ImportLibrary>
-      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|Win32'">
-    <ClCompile>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
-      <StringPooling>true</StringPooling>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <Optimization>MaxSpeed</Optimization>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <WarningLevel>Level3</WarningLevel>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <UndefineAllPreprocessorDefinitions>false</UndefineAllPreprocessorDefinitions>
-      <PreprocessorDefinitions>__CLEANUP_C;WIN32;NDEBUG;_WINDOWS;_USRDLL;PTW32_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AssemblerListingLocation>.\.\</AssemblerListingLocation>
-      <PrecompiledHeaderOutputFile>.\.\pthread.pch</PrecompiledHeaderOutputFile>
-      <ObjectFileName>.\.\</ObjectFileName>
-      <ProgramDataBaseFileName>.\.\</ProgramDataBaseFileName>
-    </ClCompile>
-    <Midl>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <TypeLibraryName>.\.\pthread.tlb</TypeLibraryName>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-      <TargetEnvironment>Win32</TargetEnvironment>
-    </Midl>
-    <ResourceCompile>
-      <Culture>0x0409</Culture>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>NDEBUG;PTW32_RC_MSC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <Bscmake>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>.\.\pthread.bsc</OutputFile>
-    </Bscmake>
-    <Link>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <LinkDLL>true</LinkDLL>
-      <SubSystem>Console</SubSystem>
-      <OutputFile>.\pthreadVC2.dll</OutputFile>
-      <ImportLibrary>.\.\pthreadVC2.lib</ImportLibrary>
-      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
-      <StringPooling>true</StringPooling>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <Optimization>MaxSpeed</Optimization>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <WarningLevel>Level3</WarningLevel>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <UndefineAllPreprocessorDefinitions>false</UndefineAllPreprocessorDefinitions>
-      <PreprocessorDefinitions>__CLEANUP_C;WIN32;NDEBUG;_WINDOWS;_USRDLL;PTW32_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AssemblerListingLocation>.\.\</AssemblerListingLocation>
-      <PrecompiledHeaderOutputFile>.\.\pthread.pch</PrecompiledHeaderOutputFile>
-      <ObjectFileName>.\.\</ObjectFileName>
-      <ProgramDataBaseFileName>.\.\</ProgramDataBaseFileName>
-    </ClCompile>
-    <Midl>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <TypeLibraryName>.\.\pthread.tlb</TypeLibraryName>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-    </Midl>
-    <ResourceCompile>
-      <Culture>0x0409</Culture>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>NDEBUG;PTW32_RC_MSC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <Bscmake>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>.\.\pthread.bsc</OutputFile>
-    </Bscmake>
-    <Link>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <LinkDLL>true</LinkDLL>
-      <SubSystem>Console</SubSystem>
-      <OutputFile>.\pthreadVC2.dll</OutputFile>
-      <ImportLibrary>.\.\pthreadVC2.lib</ImportLibrary>
-      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|x64'">
-    <ClCompile>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
-      <StringPooling>true</StringPooling>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <Optimization>MaxSpeed</Optimization>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <WarningLevel>Level3</WarningLevel>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <UndefineAllPreprocessorDefinitions>false</UndefineAllPreprocessorDefinitions>
-      <PreprocessorDefinitions>__CLEANUP_C;WIN32;NDEBUG;_WINDOWS;_USRDLL;PTW32_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AssemblerListingLocation>.\.\</AssemblerListingLocation>
-      <PrecompiledHeaderOutputFile>.\.\pthread.pch</PrecompiledHeaderOutputFile>
-      <ObjectFileName>.\.\</ObjectFileName>
-      <ProgramDataBaseFileName>.\.\</ProgramDataBaseFileName>
-    </ClCompile>
-    <Midl>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <TypeLibraryName>.\.\pthread.tlb</TypeLibraryName>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-    </Midl>
-    <ResourceCompile>
-      <Culture>0x0409</Culture>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>NDEBUG;PTW32_RC_MSC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <Bscmake>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>.\.\pthread.bsc</OutputFile>
-    </Bscmake>
-    <Link>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <LinkDLL>true</LinkDLL>
-      <SubSystem>Console</SubSystem>
-      <OutputFile>.\pthreadVC2.dll</OutputFile>
-      <ImportLibrary>.\.\pthreadVC2.lib</ImportLibrary>
-      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-    <Lib>
-      <OutputFile>.\pthreadVC2.lib</OutputFile>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <Optimization>Disabled</Optimization>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <WarningLevel>Level3</WarningLevel>
-      <MinimalRebuild>true</MinimalRebuild>
-      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>__CLEANUP_C;WIN32;_DEBUG;_WINDOWS;_USRDLL;PTW32_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AssemblerListingLocation>.\.\</AssemblerListingLocation>
-      <PrecompiledHeaderOutputFile>.\.\pthread.pch</PrecompiledHeaderOutputFile>
-      <ObjectFileName>.\.\</ObjectFileName>
-      <ProgramDataBaseFileName>.\.\</ProgramDataBaseFileName>
-      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
-    </ClCompile>
-    <Midl>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <TypeLibraryName>.\.\pthread.tlb</TypeLibraryName>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-      <TargetEnvironment>Win32</TargetEnvironment>
-    </Midl>
-    <ResourceCompile>
-      <Culture>0x0409</Culture>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_DEBUG;PTW32_RC_MSC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <Bscmake>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>.\.\pthread.bsc</OutputFile>
-    </Bscmake>
-    <Link>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <LinkDLL>true</LinkDLL>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <OutputFile>.\pthreadVC2.dll</OutputFile>
-      <ImportLibrary>.\.\pthreadVC2.lib</ImportLibrary>
-      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|Win32'">
-    <ClCompile>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <Optimization>Disabled</Optimization>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <WarningLevel>Level3</WarningLevel>
-      <MinimalRebuild>true</MinimalRebuild>
-      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>__CLEANUP_C;WIN32;_DEBUG;_WINDOWS;_USRDLL;PTW32_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AssemblerListingLocation>.\.\</AssemblerListingLocation>
-      <PrecompiledHeaderOutputFile>.\.\pthread.pch</PrecompiledHeaderOutputFile>
-      <ObjectFileName>.\.\</ObjectFileName>
-      <ProgramDataBaseFileName>.\.\</ProgramDataBaseFileName>
-      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
-    </ClCompile>
-    <Midl>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <TypeLibraryName>.\.\pthread.tlb</TypeLibraryName>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-      <TargetEnvironment>Win32</TargetEnvironment>
-    </Midl>
-    <ResourceCompile>
-      <Culture>0x0409</Culture>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_DEBUG;PTW32_RC_MSC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <Bscmake>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>.\.\pthread.bsc</OutputFile>
-    </Bscmake>
-    <Link>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <LinkDLL>true</LinkDLL>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <OutputFile>.\pthreadVC2.dll</OutputFile>
-      <ImportLibrary>.\.\pthreadVC2.lib</ImportLibrary>
-      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <Optimization>Disabled</Optimization>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>__CLEANUP_C;WIN32;_DEBUG;_WINDOWS;_USRDLL;PTW32_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AssemblerListingLocation>.\.\</AssemblerListingLocation>
-      <PrecompiledHeaderOutputFile>.\.\pthread.pch</PrecompiledHeaderOutputFile>
-      <ObjectFileName>.\.\</ObjectFileName>
-      <ProgramDataBaseFileName>.\.\</ProgramDataBaseFileName>
-      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
-    </ClCompile>
-    <Midl>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <TypeLibraryName>.\.\pthread.tlb</TypeLibraryName>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-    </Midl>
-    <ResourceCompile>
-      <Culture>0x0409</Culture>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_DEBUG;PTW32_RC_MSC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <Bscmake>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>.\.\pthread.bsc</OutputFile>
-    </Bscmake>
-    <Link>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <LinkDLL>true</LinkDLL>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <OutputFile>.\pthreadVC2.dll</OutputFile>
-      <ImportLibrary>.\.\pthreadVC2.lib</ImportLibrary>
-      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|x64'">
-    <ClCompile>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <Optimization>Disabled</Optimization>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>__CLEANUP_C;WIN32;_DEBUG;_WINDOWS;_USRDLL;PTW32_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AssemblerListingLocation>.\.\</AssemblerListingLocation>
-      <PrecompiledHeaderOutputFile>.\.\pthread.pch</PrecompiledHeaderOutputFile>
-      <ObjectFileName>.\.\</ObjectFileName>
-      <ProgramDataBaseFileName>.\.\</ProgramDataBaseFileName>
-      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
-    </ClCompile>
-    <Midl>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <TypeLibraryName>.\.\pthread.tlb</TypeLibraryName>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-    </Midl>
-    <ResourceCompile>
-      <Culture>0x0409</Culture>
-      <AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_DEBUG;PTW32_RC_MSC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ResourceCompile>
-    <Bscmake>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>.\.\pthread.bsc</OutputFile>
-    </Bscmake>
-    <Link>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <LinkDLL>true</LinkDLL>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <OutputFile>.\pthreadVC2.dll</OutputFile>
-      <ImportLibrary>.\.\pthreadVC2.lib</ImportLibrary>
-      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-    <Lib>
-      <OutputFile>.\pthreadVC2.lib</OutputFile>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="pthread.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="implement.h" />
-    <ClInclude Include="pthread.h" />
-    <ClInclude Include="sched.h" />
-    <ClInclude Include="semaphore.h" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/deps/w32-pthreads/pthread.vcxproj.filters b/deps/w32-pthreads/pthread.vcxproj.filters
deleted file mode 100644
index fc5c64a..0000000
--- a/deps/w32-pthreads/pthread.vcxproj.filters
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{ed014216-ffe7-4e4f-b783-9812a5e778d7}</UniqueIdentifier>
-      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{a9cc5beb-e838-4849-9cbd-ee1de4bda860}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{636c1d95-8104-45b5-aa12-6e8e3c5ebcee}</UniqueIdentifier>
-      <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="pthread.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="implement.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="pthread.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="sched.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="semaphore.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/deps/w32-pthreads/pthread_attr_destroy.c b/deps/w32-pthreads/pthread_attr_destroy.c
deleted file mode 100644
index 1489e4c..0000000
--- a/deps/w32-pthreads/pthread_attr_destroy.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * pthread_attr_destroy.c
- *
- * Description:
- * This translation unit implements operations on thread attribute objects.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_attr_destroy (pthread_attr_t * attr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Destroys a thread attributes object.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_attr_t
-      *
-      *
-      * DESCRIPTION
-      *      Destroys a thread attributes object.
-      *
-      *      NOTES:
-      *              1)      Does not affect threads created with 'attr'.
-      *
-      * RESULTS
-      *              0               successfully destroyed attr,
-      *              EINVAL          'attr' is invalid.
-      *
-      * ------------------------------------------------------
-      */
-{
-  if (ptw32_is_attr (attr) != 0)
-    {
-      return EINVAL;
-    }
-
-  /*
-   * Set the attribute object to a specific invalid value.
-   */
-  (*attr)->valid = 0;
-  free (*attr);
-  *attr = NULL;
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/pthread_attr_getdetachstate.c b/deps/w32-pthreads/pthread_attr_getdetachstate.c
deleted file mode 100644
index e5050ab..0000000
--- a/deps/w32-pthreads/pthread_attr_getdetachstate.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * pthread_attr_getdetachstate.c
- *
- * Description:
- * This translation unit implements operations on thread attribute objects.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_attr_getdetachstate (const pthread_attr_t * attr, int *detachstate)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function determines whether threads created with
-      *      'attr' will run detached.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_attr_t
-      *
-      *      detachstate
-      *              pointer to an integer into which is returned one
-      *              of:
-      *
-      *              PTHREAD_CREATE_JOINABLE
-      *                              Thread ID is valid, must be joined
-      *
-      *              PTHREAD_CREATE_DETACHED
-      *                              Thread ID is invalid, cannot be joined,
-      *                              canceled, or modified
-      *
-      *
-      * DESCRIPTION
-      *      This function determines whether threads created with
-      *      'attr' will run detached.
-      *
-      *      NOTES:
-      *              1)      You cannot join or cancel detached threads.
-      *
-      * RESULTS
-      *              0               successfully retrieved detach state,
-      *              EINVAL          'attr' is invalid
-      *
-      * ------------------------------------------------------
-      */
-{
-  if (ptw32_is_attr (attr) != 0 || detachstate == NULL)
-    {
-      return EINVAL;
-    }
-
-  *detachstate = (*attr)->detachstate;
-  return 0;
-}
diff --git a/deps/w32-pthreads/pthread_attr_getinheritsched.c b/deps/w32-pthreads/pthread_attr_getinheritsched.c
deleted file mode 100644
index a7d59f6..0000000
--- a/deps/w32-pthreads/pthread_attr_getinheritsched.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * pthread_attr_getinheritsched.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-int
-pthread_attr_getinheritsched (const pthread_attr_t * attr, int *inheritsched)
-{
-  if (ptw32_is_attr (attr) != 0 || inheritsched == NULL)
-    {
-      return EINVAL;
-    }
-
-  *inheritsched = (*attr)->inheritsched;
-  return 0;
-}
diff --git a/deps/w32-pthreads/pthread_attr_getschedparam.c b/deps/w32-pthreads/pthread_attr_getschedparam.c
deleted file mode 100644
index 0cecde3..0000000
--- a/deps/w32-pthreads/pthread_attr_getschedparam.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * pthread_attr_getschedparam.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-int
-pthread_attr_getschedparam (const pthread_attr_t * attr,
-			    struct sched_param *param)
-{
-  if (ptw32_is_attr (attr) != 0 || param == NULL)
-    {
-      return EINVAL;
-    }
-
-  memcpy (param, &(*attr)->param, sizeof (*param));
-  return 0;
-}
diff --git a/deps/w32-pthreads/pthread_attr_getschedpolicy.c b/deps/w32-pthreads/pthread_attr_getschedpolicy.c
deleted file mode 100644
index 73c9081..0000000
--- a/deps/w32-pthreads/pthread_attr_getschedpolicy.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * pthread_attr_getschedpolicy.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-int
-pthread_attr_getschedpolicy (const pthread_attr_t * attr, int *policy)
-{
-  if (ptw32_is_attr (attr) != 0 || policy == NULL)
-    {
-      return EINVAL;
-    }
-
-  /*
-   * Validate the policy arg.
-   * Check that a policy constant wasn't passed rather than &policy.
-   */
-  if (policy <= (int *) SCHED_MAX)
-    {
-      return EINVAL;
-    }
-
-  *policy = SCHED_OTHER;
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/pthread_attr_getscope.c b/deps/w32-pthreads/pthread_attr_getscope.c
deleted file mode 100644
index ac644e4..0000000
--- a/deps/w32-pthreads/pthread_attr_getscope.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * pthread_attr_getscope.c
- *
- * Description:
- * This translation unit implements operations on thread attribute objects.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/* ignore warning "unreferenced formal parameter" */
-#if defined(_MSC_VER)
-#pragma warning( disable : 4100 )
-#endif
-
-int
-pthread_attr_getscope (const pthread_attr_t * attr, int *contentionscope)
-{
-#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
-  *contentionscope = (*attr)->contentionscope;
-  return 0;
-#else
-  return ENOSYS;
-#endif
-}
diff --git a/deps/w32-pthreads/pthread_attr_getstackaddr.c b/deps/w32-pthreads/pthread_attr_getstackaddr.c
deleted file mode 100644
index 15a3f00..0000000
--- a/deps/w32-pthreads/pthread_attr_getstackaddr.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * pthread_attr_getstackaddr.c
- *
- * Description:
- * This translation unit implements operations on thread attribute objects.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/* ignore warning "unreferenced formal parameter" */
-#if defined(_MSC_VER)
-#pragma warning( disable : 4100 )
-#endif
-
-int
-pthread_attr_getstackaddr (const pthread_attr_t * attr, void **stackaddr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function determines the address of the stack
-      *      on which threads created with 'attr' will run.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_attr_t
-      *
-      *      stackaddr
-      *              pointer into which is returned the stack address.
-      *
-      *
-      * DESCRIPTION
-      *      This function determines the address of the stack
-      *      on which threads created with 'attr' will run.
-      *
-      *      NOTES:
-      *              1)      Function supported only if this macro is
-      *                      defined:
-      *
-      *                              _POSIX_THREAD_ATTR_STACKADDR
-      *
-      *              2)      Create only one thread for each stack
-      *                      address..
-      *
-      * RESULTS
-      *              0               successfully retreived stack address,
-      *              EINVAL          'attr' is invalid
-      *              ENOSYS          function not supported
-      *
-      * ------------------------------------------------------
-      */
-{
-#if defined( _POSIX_THREAD_ATTR_STACKADDR )
-
-  if (ptw32_is_attr (attr) != 0)
-    {
-      return EINVAL;
-    }
-
-  *stackaddr = (*attr)->stackaddr;
-  return 0;
-
-#else
-
-  return ENOSYS;
-
-#endif /* _POSIX_THREAD_ATTR_STACKADDR */
-}
diff --git a/deps/w32-pthreads/pthread_attr_getstacksize.c b/deps/w32-pthreads/pthread_attr_getstacksize.c
deleted file mode 100644
index 948a12f..0000000
--- a/deps/w32-pthreads/pthread_attr_getstacksize.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * pthread_attr_getstacksize.c
- *
- * Description:
- * This translation unit implements operations on thread attribute objects.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/* ignore warning "unreferenced formal parameter" */
-#if defined(_MSC_VER)
-#pragma warning( disable : 4100 )
-#endif
-
-int
-pthread_attr_getstacksize (const pthread_attr_t * attr, size_t * stacksize)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function determines the size of the stack on
-      *      which threads created with 'attr' will run.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_attr_t
-      *
-      *      stacksize
-      *              pointer to size_t into which is returned the
-      *              stack size, in bytes.
-      *
-      *
-      * DESCRIPTION
-      *      This function determines the size of the stack on
-      *      which threads created with 'attr' will run.
-      *
-      *      NOTES:
-      *              1)      Function supported only if this macro is
-      *                      defined:
-      *
-      *                              _POSIX_THREAD_ATTR_STACKSIZE
-      *
-      *              2)      Use on newly created attributes object to
-      *                      find the default stack size.
-      *
-      * RESULTS
-      *              0               successfully retrieved stack size,
-      *              EINVAL          'attr' is invalid
-      *              ENOSYS          function not supported
-      *
-      * ------------------------------------------------------
-      */
-{
-#if defined(_POSIX_THREAD_ATTR_STACKSIZE)
-
-  if (ptw32_is_attr (attr) != 0)
-    {
-      return EINVAL;
-    }
-
-  /* Everything is okay. */
-  *stacksize = (*attr)->stacksize;
-  return 0;
-
-#else
-
-  return ENOSYS;
-
-#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
-
-}
diff --git a/deps/w32-pthreads/pthread_attr_init.c b/deps/w32-pthreads/pthread_attr_init.c
deleted file mode 100644
index 4eff84f..0000000
--- a/deps/w32-pthreads/pthread_attr_init.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * pthread_attr_init.c
- *
- * Description:
- * This translation unit implements operations on thread attribute objects.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_attr_init (pthread_attr_t * attr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Initializes a thread attributes object with default
-      *      attributes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_attr_t
-      *
-      *
-      * DESCRIPTION
-      *      Initializes a thread attributes object with default
-      *      attributes.
-      *
-      *      NOTES:
-      *              1)      Used to define thread attributes
-      *
-      * RESULTS
-      *              0               successfully initialized attr,
-      *              ENOMEM          insufficient memory for attr.
-      *
-      * ------------------------------------------------------
-      */
-{
-  pthread_attr_t attr_result;
-
-  if (attr == NULL)
-    {
-      /* This is disallowed. */
-      return EINVAL;
-    }
-
-  attr_result = (pthread_attr_t) malloc (sizeof (*attr_result));
-
-  if (attr_result == NULL)
-    {
-      return ENOMEM;
-    }
-
-#if defined(_POSIX_THREAD_ATTR_STACKSIZE)
-  /*
-   * Default to zero size. Unless changed explicitly this
-   * will allow Win32 to set the size to that of the
-   * main thread.
-   */
-  attr_result->stacksize = 0;
-#endif
-
-#if defined(_POSIX_THREAD_ATTR_STACKADDR)
-  /* FIXME: Set this to something sensible when we support it. */
-  attr_result->stackaddr = NULL;
-#endif
-
-  attr_result->detachstate = PTHREAD_CREATE_JOINABLE;
-
-#if defined(HAVE_SIGSET_T)
-  memset (&(attr_result->sigmask), 0, sizeof (sigset_t));
-#endif /* HAVE_SIGSET_T */
-
-  /*
-   * Win32 sets new threads to THREAD_PRIORITY_NORMAL and
-   * not to that of the parent thread. We choose to default to
-   * this arrangement.
-   */
-  attr_result->param.sched_priority = THREAD_PRIORITY_NORMAL;
-  attr_result->inheritsched = PTHREAD_EXPLICIT_SCHED;
-  attr_result->contentionscope = PTHREAD_SCOPE_SYSTEM;
-
-  attr_result->valid = PTW32_ATTR_VALID;
-
-  *attr = attr_result;
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/pthread_attr_setdetachstate.c b/deps/w32-pthreads/pthread_attr_setdetachstate.c
deleted file mode 100644
index c20926a..0000000
--- a/deps/w32-pthreads/pthread_attr_setdetachstate.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * pthread_attr_setdetachstate.c
- *
- * Description:
- * This translation unit implements operations on thread attribute objects.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_attr_setdetachstate (pthread_attr_t * attr, int detachstate)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function specifies whether threads created with
-      *      'attr' will run detached.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_attr_t
-      *
-      *      detachstate
-      *              an integer containing one of:
-      *
-      *              PTHREAD_CREATE_JOINABLE
-      *                              Thread ID is valid, must be joined
-      *
-      *              PTHREAD_CREATE_DETACHED
-      *                              Thread ID is invalid, cannot be joined,
-      *                              canceled, or modified
-      *
-      *
-      * DESCRIPTION
-      *      This function specifies whether threads created with
-      *      'attr' will run detached.
-      *
-      *      NOTES:
-      *              1)      You cannot join or cancel detached threads.
-      *
-      * RESULTS
-      *              0               successfully set detach state,
-      *              EINVAL          'attr' or 'detachstate' is invalid
-      *
-      * ------------------------------------------------------
-      */
-{
-  if (ptw32_is_attr (attr) != 0)
-    {
-      return EINVAL;
-    }
-
-  if (detachstate != PTHREAD_CREATE_JOINABLE &&
-      detachstate != PTHREAD_CREATE_DETACHED)
-    {
-      return EINVAL;
-    }
-
-  (*attr)->detachstate = detachstate;
-  return 0;
-}
diff --git a/deps/w32-pthreads/pthread_attr_setinheritsched.c b/deps/w32-pthreads/pthread_attr_setinheritsched.c
deleted file mode 100644
index 2f921fc..0000000
--- a/deps/w32-pthreads/pthread_attr_setinheritsched.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * pthread_attr_setinheritsched.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-int
-pthread_attr_setinheritsched (pthread_attr_t * attr, int inheritsched)
-{
-  if (ptw32_is_attr (attr) != 0)
-    {
-      return EINVAL;
-    }
-
-  if (PTHREAD_INHERIT_SCHED != inheritsched
-      && PTHREAD_EXPLICIT_SCHED != inheritsched)
-    {
-      return EINVAL;
-    }
-
-  (*attr)->inheritsched = inheritsched;
-  return 0;
-}
diff --git a/deps/w32-pthreads/pthread_attr_setschedparam.c b/deps/w32-pthreads/pthread_attr_setschedparam.c
deleted file mode 100644
index 969fe7c..0000000
--- a/deps/w32-pthreads/pthread_attr_setschedparam.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * pthread_attr_setschedparam.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-int
-pthread_attr_setschedparam (pthread_attr_t * attr,
-			    const struct sched_param *param)
-{
-  int priority;
-
-  if (ptw32_is_attr (attr) != 0 || param == NULL)
-    {
-      return EINVAL;
-    }
-
-  priority = param->sched_priority;
-
-  /* Validate priority level. */
-  if (priority < sched_get_priority_min (SCHED_OTHER) ||
-      priority > sched_get_priority_max (SCHED_OTHER))
-    {
-      return EINVAL;
-    }
-
-  memcpy (&(*attr)->param, param, sizeof (*param));
-  return 0;
-}
diff --git a/deps/w32-pthreads/pthread_attr_setschedpolicy.c b/deps/w32-pthreads/pthread_attr_setschedpolicy.c
deleted file mode 100644
index d8873ae..0000000
--- a/deps/w32-pthreads/pthread_attr_setschedpolicy.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * pthread_attr_setschedpolicy.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-int
-pthread_attr_setschedpolicy (pthread_attr_t * attr, int policy)
-{
-  if (ptw32_is_attr (attr) != 0)
-    {
-      return EINVAL;
-    }
-
-  if (policy != SCHED_OTHER)
-    {
-      return ENOTSUP;
-    }
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/pthread_attr_setscope.c b/deps/w32-pthreads/pthread_attr_setscope.c
deleted file mode 100644
index 2cdffe8..0000000
--- a/deps/w32-pthreads/pthread_attr_setscope.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * pthread_attr_setscope.c
- *
- * Description:
- * This translation unit implements operations on thread attribute objects.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/* ignore warning "unreferenced formal parameter" */
-#if defined(_MSC_VER)
-#pragma warning( disable : 4100 )
-#endif
-
-int
-pthread_attr_setscope (pthread_attr_t * attr, int contentionscope)
-{
-#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
-  switch (contentionscope)
-    {
-    case PTHREAD_SCOPE_SYSTEM:
-      (*attr)->contentionscope = contentionscope;
-      return 0;
-    case PTHREAD_SCOPE_PROCESS:
-      return ENOTSUP;
-    default:
-      return EINVAL;
-    }
-#else
-  return ENOSYS;
-#endif
-}
diff --git a/deps/w32-pthreads/pthread_attr_setstackaddr.c b/deps/w32-pthreads/pthread_attr_setstackaddr.c
deleted file mode 100644
index 5eb2b61..0000000
--- a/deps/w32-pthreads/pthread_attr_setstackaddr.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * pthread_attr_setstackaddr.c
- *
- * Description:
- * This translation unit implements operations on thread attribute objects.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_attr_setstackaddr (pthread_attr_t * attr, void *stackaddr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Threads created with 'attr' will run on the stack
-      *      starting at 'stackaddr'.
-      *      Stack must be at least PTHREAD_STACK_MIN bytes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_attr_t
-      *
-      *      stackaddr
-      *              the address of the stack to use
-      *
-      *
-      * DESCRIPTION
-      *      Threads created with 'attr' will run on the stack
-      *      starting at 'stackaddr'.
-      *      Stack must be at least PTHREAD_STACK_MIN bytes.
-      *
-      *      NOTES:
-      *              1)      Function supported only if this macro is
-      *                      defined:
-      *
-      *                              _POSIX_THREAD_ATTR_STACKADDR
-      *
-      *              2)      Create only one thread for each stack
-      *                      address..
-      *
-      *              3)      Ensure that stackaddr is aligned.
-      *
-      * RESULTS
-      *              0               successfully set stack address,
-      *              EINVAL          'attr' is invalid
-      *              ENOSYS          function not supported
-      *
-      * ------------------------------------------------------
-      */
-{
-#if defined( _POSIX_THREAD_ATTR_STACKADDR )
-
-  if (ptw32_is_attr (attr) != 0)
-    {
-      return EINVAL;
-    }
-
-  (*attr)->stackaddr = stackaddr;
-  return 0;
-
-#else
-
-  return ENOSYS;
-
-#endif /* _POSIX_THREAD_ATTR_STACKADDR */
-}
diff --git a/deps/w32-pthreads/pthread_attr_setstacksize.c b/deps/w32-pthreads/pthread_attr_setstacksize.c
deleted file mode 100644
index cd8f702..0000000
--- a/deps/w32-pthreads/pthread_attr_setstacksize.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * pthread_attr_setstacksize.c
- *
- * Description:
- * This translation unit implements operations on thread attribute objects.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_attr_setstacksize (pthread_attr_t * attr, size_t stacksize)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function specifies the size of the stack on
-      *      which threads created with 'attr' will run.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_attr_t
-      *
-      *      stacksize
-      *              stack size, in bytes.
-      *
-      *
-      * DESCRIPTION
-      *      This function specifies the size of the stack on
-      *      which threads created with 'attr' will run.
-      *
-      *      NOTES:
-      *              1)      Function supported only if this macro is
-      *                      defined:
-      *
-      *                              _POSIX_THREAD_ATTR_STACKSIZE
-      *
-      *              2)      Find the default first (using
-      *                      pthread_attr_getstacksize), then increase
-      *                      by multiplying.
-      *
-      *              3)      Only use if thread needs more than the
-      *                      default.
-      *
-      * RESULTS
-      *              0               successfully set stack size,
-      *              EINVAL          'attr' is invalid or stacksize too
-      *                              small or too big.
-      *              ENOSYS          function not supported
-      *
-      * ------------------------------------------------------
-      */
-{
-#if defined(_POSIX_THREAD_ATTR_STACKSIZE)
-
-#if PTHREAD_STACK_MIN > 0
-
-  /*  Verify that the stack size is within range. */
-  if (stacksize < PTHREAD_STACK_MIN)
-    {
-      return EINVAL;
-    }
-
-#endif
-
-  if (ptw32_is_attr (attr) != 0)
-    {
-      return EINVAL;
-    }
-
-  /* Everything is okay. */
-  (*attr)->stacksize = stacksize;
-  return 0;
-
-#else
-
-  return ENOSYS;
-
-#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
-
-}
diff --git a/deps/w32-pthreads/pthread_barrier_destroy.c b/deps/w32-pthreads/pthread_barrier_destroy.c
deleted file mode 100644
index 48e2423..0000000
--- a/deps/w32-pthreads/pthread_barrier_destroy.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * pthread_barrier_destroy.c
- *
- * Description:
- * This translation unit implements barrier primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_barrier_destroy (pthread_barrier_t * barrier)
-{
-  int result = 0;
-  pthread_barrier_t b;
-  ptw32_mcs_local_node_t node;
-
-  if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID)
-    {
-      return EINVAL;
-    }
-
-  if (0 != ptw32_mcs_lock_try_acquire(&(*barrier)->lock, &node))
-    {
-      return EBUSY;
-    }
-
-  b = *barrier;
-
-  if (b->nCurrentBarrierHeight < b->nInitialBarrierHeight)
-    {
-      result = EBUSY;
-    }
-  else
-	{
-      if (0 == (result = sem_destroy (&(b->semBarrierBreeched))))
-        {
-          *barrier = (pthread_barrier_t) PTW32_OBJECT_INVALID;
-          /*
-           * Release the lock before freeing b.
-           *
-           * FIXME: There may be successors which, when we release the lock,
-           * will be linked into b->lock, which will be corrupted at some
-           * point with undefined results for the application. To fix this
-           * will require changing pthread_barrier_t from a pointer to
-           * pthread_barrier_t_ to an instance. This is a change to the ABI
-           * and will require a major version number increment.
-           */
-          ptw32_mcs_lock_release(&node);
-	  (void) free (b);
-	  return 0;
-	}
-      else
-        {
-          /*
-           * This should not ever be reached.
-           * Restore the barrier to working condition before returning.
-           */
-          (void) sem_init (&(b->semBarrierBreeched), b->pshared, 0);
-        }
-
-      if (result != 0)
-        {
-          /*
-           * The barrier still exists and is valid
-           * in the event of any error above.
-           */
-          result = EBUSY;
-        }
-    }
-
-  ptw32_mcs_lock_release(&node);
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_barrier_init.c b/deps/w32-pthreads/pthread_barrier_init.c
deleted file mode 100644
index 8bb9894..0000000
--- a/deps/w32-pthreads/pthread_barrier_init.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * pthread_barrier_init.c
- *
- * Description:
- * This translation unit implements barrier primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_barrier_init (pthread_barrier_t * barrier,
-		      const pthread_barrierattr_t * attr, unsigned int count)
-{
-  pthread_barrier_t b;
-
-  if (barrier == NULL || count == 0)
-    {
-      return EINVAL;
-    }
-
-  if (NULL != (b = (pthread_barrier_t) calloc (1, sizeof (*b))))
-    {
-      b->pshared = (attr != NULL && *attr != NULL
-		    ? (*attr)->pshared : PTHREAD_PROCESS_PRIVATE);
-
-      b->nCurrentBarrierHeight = b->nInitialBarrierHeight = count;
-      b->lock = 0;
-
-      if (0 == sem_init (&(b->semBarrierBreeched), b->pshared, 0))
-	    {
-	      *barrier = b;
-	      return 0;
-	    }
-      (void) free (b);
-    }
-
-  return ENOMEM;
-}
diff --git a/deps/w32-pthreads/pthread_barrier_wait.c b/deps/w32-pthreads/pthread_barrier_wait.c
deleted file mode 100644
index 9fe987e..0000000
--- a/deps/w32-pthreads/pthread_barrier_wait.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * pthread_barrier_wait.c
- *
- * Description:
- * This translation unit implements barrier primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_barrier_wait (pthread_barrier_t * barrier)
-{
-  int result;
-  pthread_barrier_t b;
-
-  ptw32_mcs_local_node_t node;
-
-  if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID)
-    {
-      return EINVAL;
-    }
-
-  ptw32_mcs_lock_acquire(&(*barrier)->lock, &node);
-
-  b = *barrier;
-  if (--b->nCurrentBarrierHeight == 0)
-    {
-      /*
-       * We are the last thread to arrive at the barrier before it releases us.
-       * Move our MCS local node to the global scope barrier handle so that the
-       * last thread out (not necessarily us) can release the lock.
-       */
-      ptw32_mcs_node_transfer(&b->proxynode, &node);
-
-      /*
-       * Any threads that have not quite entered sem_wait below when the
-       * multiple_post has completed will nevertheless continue through
-       * the semaphore (barrier).
-       */
-      result = (b->nInitialBarrierHeight > 1
-                ? sem_post_multiple (&(b->semBarrierBreeched),
-				     b->nInitialBarrierHeight - 1) : 0);
-    }
-  else
-    {
-      ptw32_mcs_lock_release(&node);
-      /*
-       * Use the non-cancelable version of sem_wait().
-       *
-       * It is possible that all nInitialBarrierHeight-1 threads are
-       * at this point when the last thread enters the barrier, resets
-       * nCurrentBarrierHeight = nInitialBarrierHeight and leaves.
-       * If pthread_barrier_destroy is called at that moment then the
-       * barrier will be destroyed along with the semas.
-       */
-      result = ptw32_semwait (&(b->semBarrierBreeched));
-    }
-
-  if ((PTW32_INTERLOCKED_LONG)PTW32_INTERLOCKED_INCREMENT_LONG((PTW32_INTERLOCKED_LONGPTR)&b->nCurrentBarrierHeight)
-		  == (PTW32_INTERLOCKED_LONG)b->nInitialBarrierHeight)
-    {
-      /*
-       * We are the last thread to cross this barrier
-       */
-      ptw32_mcs_lock_release(&b->proxynode);
-      if (0 == result)
-        {
-          result = PTHREAD_BARRIER_SERIAL_THREAD;
-        }
-    }
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_barrierattr_destroy.c b/deps/w32-pthreads/pthread_barrierattr_destroy.c
deleted file mode 100644
index 59853db..0000000
--- a/deps/w32-pthreads/pthread_barrierattr_destroy.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * pthread_barrier_attr_destroy.c
- *
- * Description:
- * This translation unit implements barrier primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_barrierattr_destroy (pthread_barrierattr_t * attr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Destroys a barrier attributes object. The object can
-      *      no longer be used.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_barrierattr_t
-      *
-      *
-      * DESCRIPTION
-      *      Destroys a barrier attributes object. The object can
-      *      no longer be used.
-      *
-      *      NOTES:
-      *              1)      Does not affect barrieres created using 'attr'
-      *
-      * RESULTS
-      *              0               successfully released attr,
-      *              EINVAL          'attr' is invalid.
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-
-  if (attr == NULL || *attr == NULL)
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      pthread_barrierattr_t ba = *attr;
-
-      *attr = NULL;
-      free (ba);
-    }
-
-  return (result);
-}				/* pthread_barrierattr_destroy */
diff --git a/deps/w32-pthreads/pthread_barrierattr_getpshared.c b/deps/w32-pthreads/pthread_barrierattr_getpshared.c
deleted file mode 100644
index e2529da..0000000
--- a/deps/w32-pthreads/pthread_barrierattr_getpshared.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * pthread_barrier_attr_getpshared.c
- *
- * Description:
- * This translation unit implements barrier primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_barrierattr_getpshared (const pthread_barrierattr_t * attr,
-				int *pshared)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Determine whether barriers created with 'attr' can be
-      *      shared between processes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_barrierattr_t
-      *
-      *      pshared
-      *              will be set to one of:
-      *
-      *                      PTHREAD_PROCESS_SHARED
-      *                              May be shared if in shared memory
-      *
-      *                      PTHREAD_PROCESS_PRIVATE
-      *                              Cannot be shared.
-      *
-      *
-      * DESCRIPTION
-      *      Mutexes creatd with 'attr' can be shared between
-      *      processes if pthread_barrier_t variable is allocated
-      *      in memory shared by these processes.
-      *      NOTES:
-      *              1)      pshared barriers MUST be allocated in shared
-      *                      memory.
-      *              2)      The following macro is defined if shared barriers
-      *                      are supported:
-      *                              _POSIX_THREAD_PROCESS_SHARED
-      *
-      * RESULTS
-      *              0               successfully retrieved attribute,
-      *              EINVAL          'attr' is invalid,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-
-  if ((attr != NULL && *attr != NULL) && (pshared != NULL))
-    {
-      *pshared = (*attr)->pshared;
-      result = 0;
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  return (result);
-}				/* pthread_barrierattr_getpshared */
diff --git a/deps/w32-pthreads/pthread_barrierattr_init.c b/deps/w32-pthreads/pthread_barrierattr_init.c
deleted file mode 100644
index 7e7b13e..0000000
--- a/deps/w32-pthreads/pthread_barrierattr_init.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * pthread_barrier_attr_init.c
- *
- * Description:
- * This translation unit implements barrier primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_barrierattr_init (pthread_barrierattr_t * attr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Initializes a barrier attributes object with default
-      *      attributes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_barrierattr_t
-      *
-      *
-      * DESCRIPTION
-      *      Initializes a barrier attributes object with default
-      *      attributes.
-      *
-      *      NOTES:
-      *              1)      Used to define barrier types
-      *
-      * RESULTS
-      *              0               successfully initialized attr,
-      *              ENOMEM          insufficient memory for attr.
-      *
-      * ------------------------------------------------------
-      */
-{
-  pthread_barrierattr_t ba;
-  int result = 0;
-
-  ba = (pthread_barrierattr_t) calloc (1, sizeof (*ba));
-
-  if (ba == NULL)
-    {
-      result = ENOMEM;
-    }
-  else
-    {
-      ba->pshared = PTHREAD_PROCESS_PRIVATE;
-    }
-
-  *attr = ba;
-
-  return (result);
-}				/* pthread_barrierattr_init */
diff --git a/deps/w32-pthreads/pthread_barrierattr_setpshared.c b/deps/w32-pthreads/pthread_barrierattr_setpshared.c
deleted file mode 100644
index 2612c07..0000000
--- a/deps/w32-pthreads/pthread_barrierattr_setpshared.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * pthread_barrier_attr_setpshared.c
- *
- * Description:
- * This translation unit implements barrier primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, int pshared)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Barriers created with 'attr' can be shared between
-      *      processes if pthread_barrier_t variable is allocated
-      *      in memory shared by these processes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_barrierattr_t
-      *
-      *      pshared
-      *              must be one of:
-      *
-      *                      PTHREAD_PROCESS_SHARED
-      *                              May be shared if in shared memory
-      *
-      *                      PTHREAD_PROCESS_PRIVATE
-      *                              Cannot be shared.
-      *
-      * DESCRIPTION
-      *      Mutexes creatd with 'attr' can be shared between
-      *      processes if pthread_barrier_t variable is allocated
-      *      in memory shared by these processes.
-      *
-      *      NOTES:
-      *              1)      pshared barriers MUST be allocated in shared
-      *                      memory.
-      *
-      *              2)      The following macro is defined if shared barriers
-      *                      are supported:
-      *                              _POSIX_THREAD_PROCESS_SHARED
-      *
-      * RESULTS
-      *              0               successfully set attribute,
-      *              EINVAL          'attr' or pshared is invalid,
-      *              ENOSYS          PTHREAD_PROCESS_SHARED not supported,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-
-  if ((attr != NULL && *attr != NULL) &&
-      ((pshared == PTHREAD_PROCESS_SHARED) ||
-       (pshared == PTHREAD_PROCESS_PRIVATE)))
-    {
-      if (pshared == PTHREAD_PROCESS_SHARED)
-	{
-
-#if !defined( _POSIX_THREAD_PROCESS_SHARED )
-
-	  result = ENOSYS;
-	  pshared = PTHREAD_PROCESS_PRIVATE;
-
-#else
-
-	  result = 0;
-
-#endif /* _POSIX_THREAD_PROCESS_SHARED */
-
-	}
-      else
-	{
-	  result = 0;
-	}
-
-      (*attr)->pshared = pshared;
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  return (result);
-
-}				/* pthread_barrierattr_setpshared */
diff --git a/deps/w32-pthreads/pthread_cancel.c b/deps/w32-pthreads/pthread_cancel.c
deleted file mode 100644
index 4af0c6e..0000000
--- a/deps/w32-pthreads/pthread_cancel.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * pthread_cancel.c
- *
- * Description:
- * POSIX thread functions related to thread cancellation.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "context.h"
-
-static void
-ptw32_cancel_self (void)
-{
-  ptw32_throw (PTW32_EPS_CANCEL);
-
-  /* Never reached */
-}
-
-static void CALLBACK
-ptw32_cancel_callback (ULONG_PTR unused)
-{
-  ptw32_throw (PTW32_EPS_CANCEL);
-
-  /* Never reached */
-}
-
-/*
- * ptw32_RegisterCancelation() -
- * Must have args of same type as QueueUserAPCEx because this function
- * is a substitute for QueueUserAPCEx if it's not available.
- */
-DWORD
-ptw32_RegisterCancelation (PAPCFUNC unused1, HANDLE threadH, DWORD unused2)
-{
-  CONTEXT context;
-
-  context.ContextFlags = CONTEXT_CONTROL;
-  GetThreadContext (threadH, &context);
-  PTW32_PROGCTR (context) = (DWORD_PTR) ptw32_cancel_self;
-  SetThreadContext (threadH, &context);
-  return 0;
-}
-
-int
-pthread_cancel (pthread_t thread)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function requests cancellation of 'thread'.
-      *
-      * PARAMETERS
-      *      thread
-      *              reference to an instance of pthread_t
-      *
-      *
-      * DESCRIPTION
-      *      This function requests cancellation of 'thread'.
-      *      NOTE: cancellation is asynchronous; use pthread_join to
-      *                wait for termination of 'thread' if necessary.
-      *
-      * RESULTS
-      *              0               successfully requested cancellation,
-      *              ESRCH           no thread found corresponding to 'thread',
-      *              ENOMEM          implicit self thread create failed.
-      * ------------------------------------------------------
-      */
-{
-  int result;
-  int cancel_self;
-  pthread_t self;
-  ptw32_thread_t * tp;
-  ptw32_mcs_local_node_t stateLock;
-
-  result = pthread_kill (thread, 0);
-
-  if (0 != result)
-    {
-      return result;
-    }
-
-  if ((self = pthread_self ()).p == NULL)
-    {
-      return ENOMEM;
-    };
-
-  /*
-   * For self cancellation we need to ensure that a thread can't
-   * deadlock itself trying to cancel itself asynchronously
-   * (pthread_cancel is required to be an async-cancel
-   * safe function).
-   */
-  cancel_self = pthread_equal (thread, self);
-
-  tp = (ptw32_thread_t *) thread.p;
-
-  /*
-   * Lock for async-cancel safety.
-   */
-  ptw32_mcs_lock_acquire (&tp->stateLock, &stateLock);
-
-  if (tp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS
-      && tp->cancelState == PTHREAD_CANCEL_ENABLE
-      && tp->state < PThreadStateCanceling)
-    {
-      if (cancel_self)
-	{
-	  tp->state = PThreadStateCanceling;
-	  tp->cancelState = PTHREAD_CANCEL_DISABLE;
-
-	  ptw32_mcs_lock_release (&stateLock);
-	  ptw32_throw (PTW32_EPS_CANCEL);
-
-	  /* Never reached */
-	}
-      else
-	{
-	  HANDLE threadH = tp->threadH;
-
-	  SuspendThread (threadH);
-
-	  if (WaitForSingleObject (threadH, 0) == WAIT_TIMEOUT)
-	    {
-	      tp->state = PThreadStateCanceling;
-	      tp->cancelState = PTHREAD_CANCEL_DISABLE;
-	      /*
-	       * If alertdrv and QueueUserAPCEx is available then the following
-	       * will result in a call to QueueUserAPCEx with the args given, otherwise
-	       * this will result in a call to ptw32_RegisterCancelation and only
-	       * the threadH arg will be used.
-	       */
-	      ptw32_register_cancelation ((PAPCFUNC)ptw32_cancel_callback, threadH, 0);
-	      ptw32_mcs_lock_release (&stateLock);
-	      ResumeThread (threadH);
-	    }
-	}
-    }
-  else
-    {
-      /*
-       * Set for deferred cancellation.
-       */
-      if (tp->state < PThreadStateCancelPending)
-	{
-	  tp->state = PThreadStateCancelPending;
-	  if (!SetEvent (tp->cancelEvent))
-	    {
-	      result = ESRCH;
-	    }
-	}
-      else if (tp->state >= PThreadStateCanceling)
-	{
-	  result = ESRCH;
-	}
-
-      ptw32_mcs_lock_release (&stateLock);
-    }
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_cond_destroy.c b/deps/w32-pthreads/pthread_cond_destroy.c
deleted file mode 100644
index d960172..0000000
--- a/deps/w32-pthreads/pthread_cond_destroy.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * pthread_cond_destroy.c
- *
- * Description:
- * This translation unit implements condition variables and their primitives.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_cond_destroy (pthread_cond_t * cond)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function destroys a condition variable
-      *
-      *
-      * PARAMETERS
-      *      cond
-      *              pointer to an instance of pthread_cond_t
-      *
-      *
-      * DESCRIPTION
-      *      This function destroys a condition variable.
-      *
-      *      NOTES:
-      *              1)      A condition variable can be destroyed
-      *                      immediately after all the threads that
-      *                      are blocked on it are awakened. e.g.
-      *
-      *                      struct list {
-      *                        pthread_mutex_t lm;
-      *                        ...
-      *                      }
-      *
-      *                      struct elt {
-      *                        key k;
-      *                        int busy;
-      *                        pthread_cond_t notbusy;
-      *                        ...
-      *                      }
-      *
-      *                      
-      *                      struct elt *
-      *                      list_find(struct list *lp, key k)
-      *                      {
-      *                        struct elt *ep;
-      *
-      *                        pthread_mutex_lock(&lp->lm);
-      *                        while ((ep = find_elt(l,k) != NULL) && ep->busy)
-      *                          pthread_cond_wait(&ep->notbusy, &lp->lm);
-      *                        if (ep != NULL)
-      *                          ep->busy = 1;
-      *                        pthread_mutex_unlock(&lp->lm);
-      *                        return(ep);
-      *                      }
-      *
-      *                      delete_elt(struct list *lp, struct elt *ep)
-      *                      {
-      *                        pthread_mutex_lock(&lp->lm);
-      *                        assert(ep->busy);
-      *                        ... remove ep from list ...
-      *                        ep->busy = 0;
-      *                    (A) pthread_cond_broadcast(&ep->notbusy);
-      *                        pthread_mutex_unlock(&lp->lm);
-      *                    (B) pthread_cond_destroy(&rp->notbusy);
-      *                        free(ep);
-      *                      }
-      *
-      *                      In this example, the condition variable
-      *                      and its list element may be freed (line B)
-      *                      immediately after all threads waiting for
-      *                      it are awakened (line A), since the mutex
-      *                      and the code ensure that no other thread
-      *                      can touch the element to be deleted.
-      *
-      * RESULTS
-      *              0               successfully released condition variable,
-      *              EINVAL          'cond' is invalid,
-      *              EBUSY           'cond' is in use,
-      *
-      * ------------------------------------------------------
-      */
-{
-  pthread_cond_t cv;
-  int result = 0, result1 = 0, result2 = 0;
-
-  /*
-   * Assuming any race condition here is harmless.
-   */
-  if (cond == NULL || *cond == NULL)
-    {
-      return EINVAL;
-    }
-
-  if (*cond != PTHREAD_COND_INITIALIZER)
-    {
-      ptw32_mcs_local_node_t node;
-      ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node);
-
-      cv = *cond;
-
-      /*
-       * Close the gate; this will synchronize this thread with
-       * all already signaled waiters to let them retract their
-       * waiter status - SEE NOTE 1 ABOVE!!!
-       */
-      if (ptw32_semwait (&(cv->semBlockLock)) != 0) /* Non-cancelable */
-	{
-	  result = errno;
-	}
-      else
-        {
-          /*
-           * !TRY! lock mtxUnblockLock; try will detect busy condition
-           * and will not cause a deadlock with respect to concurrent
-           * signal/broadcast.
-           */
-          if ((result = pthread_mutex_trylock (&(cv->mtxUnblockLock))) != 0)
-	    {
-	      (void) sem_post (&(cv->semBlockLock));
-	    }
-	}
-	
-      if (result != 0)
-        {
-          ptw32_mcs_lock_release(&node);
-          return result;
-        }
-
-      /*
-       * Check whether cv is still busy (still has waiters)
-       */
-      if (cv->nWaitersBlocked > cv->nWaitersGone)
-	{
-	  if (sem_post (&(cv->semBlockLock)) != 0)
-	    {
-	      result = errno;
-	    }
-	  result1 = pthread_mutex_unlock (&(cv->mtxUnblockLock));
-	  result2 = EBUSY;
-	}
-      else
-	{
-	  /*
-	   * Now it is safe to destroy
-	   */
-	  *cond = NULL;
-
-	  if (sem_destroy (&(cv->semBlockLock)) != 0)
-	    {
-	      result = errno;
-	    }
-	  if (sem_destroy (&(cv->semBlockQueue)) != 0)
-	    {
-	      result1 = errno;
-	    }
-	  if ((result2 = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0)
-	    {
-	      result2 = pthread_mutex_destroy (&(cv->mtxUnblockLock));
-	    }
-
-	  /* Unlink the CV from the list */
-
-	  if (ptw32_cond_list_head == cv)
-	    {
-	      ptw32_cond_list_head = cv->next;
-	    }
-	  else
-	    {
-	      cv->prev->next = cv->next;
-	    }
-
-	  if (ptw32_cond_list_tail == cv)
-	    {
-	      ptw32_cond_list_tail = cv->prev;
-	    }
-	  else
-	    {
-	      cv->next->prev = cv->prev;
-	    }
-
-	  (void) free (cv);
-	}
-
-      ptw32_mcs_lock_release(&node);
-    }
-  else
-    {
-      ptw32_mcs_local_node_t node;
-      /*
-       * See notes in ptw32_cond_check_need_init() above also.
-       */
-      ptw32_mcs_lock_acquire(&ptw32_cond_test_init_lock, &node);
-
-      /*
-       * Check again.
-       */
-      if (*cond == PTHREAD_COND_INITIALIZER)
-	{
-	  /*
-	   * This is all we need to do to destroy a statically
-	   * initialised cond that has not yet been used (initialised).
-	   * If we get to here, another thread waiting to initialise
-	   * this cond will get an EINVAL. That's OK.
-	   */
-	  *cond = NULL;
-	}
-      else
-	{
-	  /*
-	   * The cv has been initialised while we were waiting
-	   * so assume it's in use.
-	   */
-	  result = EBUSY;
-	}
-
-      ptw32_mcs_lock_release(&node);
-    }
-
-  return ((result != 0) ? result : ((result1 != 0) ? result1 : result2));
-}
diff --git a/deps/w32-pthreads/pthread_cond_init.c b/deps/w32-pthreads/pthread_cond_init.c
deleted file mode 100644
index c2d2526..0000000
--- a/deps/w32-pthreads/pthread_cond_init.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * pthread_cond_init.c
- *
- * Description:
- * This translation unit implements condition variables and their primitives.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function initializes a condition variable.
-      *
-      * PARAMETERS
-      *      cond
-      *              pointer to an instance of pthread_cond_t
-      *
-      *      attr
-      *              specifies optional creation attributes.
-      *
-      *
-      * DESCRIPTION
-      *      This function initializes a condition variable.
-      *
-      * RESULTS
-      *              0               successfully created condition variable,
-      *              EINVAL          'attr' is invalid,
-      *              EAGAIN          insufficient resources (other than
-      *                              memory,
-      *              ENOMEM          insufficient memory,
-      *              EBUSY           'cond' is already initialized,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-  pthread_cond_t cv = NULL;
-
-  if (cond == NULL)
-    {
-      return EINVAL;
-    }
-
-  if ((attr != NULL && *attr != NULL) &&
-      ((*attr)->pshared == PTHREAD_PROCESS_SHARED))
-    {
-      /*
-       * Creating condition variable that can be shared between
-       * processes.
-       */
-      result = ENOSYS;
-      goto DONE;
-    }
-
-  cv = (pthread_cond_t) calloc (1, sizeof (*cv));
-
-  if (cv == NULL)
-    {
-      result = ENOMEM;
-      goto DONE;
-    }
-
-  cv->nWaitersBlocked = 0;
-  cv->nWaitersToUnblock = 0;
-  cv->nWaitersGone = 0;
-
-  if (sem_init (&(cv->semBlockLock), 0, 1) != 0)
-    {
-      result = errno;
-      goto FAIL0;
-    }
-
-  if (sem_init (&(cv->semBlockQueue), 0, 0) != 0)
-    {
-      result = errno;
-      goto FAIL1;
-    }
-
-  if ((result = pthread_mutex_init (&(cv->mtxUnblockLock), 0)) != 0)
-    {
-      goto FAIL2;
-    }
-
-  result = 0;
-
-  goto DONE;
-
-  /*
-   * -------------
-   * Failed...
-   * -------------
-   */
-FAIL2:
-  (void) sem_destroy (&(cv->semBlockQueue));
-
-FAIL1:
-  (void) sem_destroy (&(cv->semBlockLock));
-
-FAIL0:
-  (void) free (cv);
-  cv = NULL;
-
-DONE:
-  if (0 == result)
-    {
-      ptw32_mcs_local_node_t node;
-
-      ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node);
-
-      cv->next = NULL;
-      cv->prev = ptw32_cond_list_tail;
-
-      if (ptw32_cond_list_tail != NULL)
-	{
-	  ptw32_cond_list_tail->next = cv;
-	}
-
-      ptw32_cond_list_tail = cv;
-
-      if (ptw32_cond_list_head == NULL)
-	{
-	  ptw32_cond_list_head = cv;
-	}
-
-      ptw32_mcs_lock_release(&node);
-    }
-
-  *cond = cv;
-
-  return result;
-
-}				/* pthread_cond_init */
diff --git a/deps/w32-pthreads/pthread_cond_signal.c b/deps/w32-pthreads/pthread_cond_signal.c
deleted file mode 100644
index f3d384a..0000000
--- a/deps/w32-pthreads/pthread_cond_signal.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * pthread_cond_signal.c
- *
- * Description:
- * This translation unit implements condition variables and their primitives.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * -------------------------------------------------------------
- * Algorithm:
- * See the comments at the top of pthread_cond_wait.c.
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-static INLINE int
-ptw32_cond_unblock (pthread_cond_t * cond, int unblockAll)
-     /*
-      * Notes.
-      *
-      * Does not use the external mutex for synchronisation,
-      * therefore semBlockLock is needed.
-      * mtxUnblockLock is for LEVEL-2 synch. LEVEL-2 is the
-      * state where the external mutex is not necessarily locked by
-      * any thread, ie. between cond_wait unlocking and re-acquiring
-      * the lock after having been signaled or a timeout or
-      * cancellation.
-      *
-      * Uses the following CV elements:
-      *   nWaitersBlocked
-      *   nWaitersToUnblock
-      *   nWaitersGone
-      *   mtxUnblockLock
-      *   semBlockLock
-      *   semBlockQueue
-      */
-{
-  int result;
-  pthread_cond_t cv;
-  int nSignalsToIssue;
-
-  if (cond == NULL || *cond == NULL)
-    {
-      return EINVAL;
-    }
-
-  cv = *cond;
-
-  /*
-   * No-op if the CV is static and hasn't been initialised yet.
-   * Assuming that any race condition is harmless.
-   */
-  if (cv == PTHREAD_COND_INITIALIZER)
-    {
-      return 0;
-    }
-
-  if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0)
-    {
-      return result;
-    }
-
-  if (0 != cv->nWaitersToUnblock)
-    {
-      if (0 == cv->nWaitersBlocked)
-	{
-	  return pthread_mutex_unlock (&(cv->mtxUnblockLock));
-	}
-      if (unblockAll)
-	{
-	  cv->nWaitersToUnblock += (nSignalsToIssue = cv->nWaitersBlocked);
-	  cv->nWaitersBlocked = 0;
-	}
-      else
-	{
-	  nSignalsToIssue = 1;
-	  cv->nWaitersToUnblock++;
-	  cv->nWaitersBlocked--;
-	}
-    }
-  else if (cv->nWaitersBlocked > cv->nWaitersGone)
-    {
-      /* Use the non-cancellable version of sem_wait() */
-      if (ptw32_semwait (&(cv->semBlockLock)) != 0)
-	{
-	  result = errno;
-	  (void) pthread_mutex_unlock (&(cv->mtxUnblockLock));
-	  return result;
-	}
-      if (0 != cv->nWaitersGone)
-	{
-	  cv->nWaitersBlocked -= cv->nWaitersGone;
-	  cv->nWaitersGone = 0;
-	}
-      if (unblockAll)
-	{
-	  nSignalsToIssue = cv->nWaitersToUnblock = cv->nWaitersBlocked;
-	  cv->nWaitersBlocked = 0;
-	}
-      else
-	{
-	  nSignalsToIssue = cv->nWaitersToUnblock = 1;
-	  cv->nWaitersBlocked--;
-	}
-    }
-  else
-    {
-      return pthread_mutex_unlock (&(cv->mtxUnblockLock));
-    }
-
-  if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0)
-    {
-      if (sem_post_multiple (&(cv->semBlockQueue), nSignalsToIssue) != 0)
-	{
-	  result = errno;
-	}
-    }
-
-  return result;
-
-}				/* ptw32_cond_unblock */
-
-int
-pthread_cond_signal (pthread_cond_t * cond)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function signals a condition variable, waking
-      *      one waiting thread.
-      *      If SCHED_FIFO or SCHED_RR policy threads are waiting
-      *      the highest priority waiter is awakened; otherwise,
-      *      an unspecified waiter is awakened.
-      *
-      * PARAMETERS
-      *      cond
-      *              pointer to an instance of pthread_cond_t
-      *
-      *
-      * DESCRIPTION
-      *      This function signals a condition variable, waking
-      *      one waiting thread.
-      *      If SCHED_FIFO or SCHED_RR policy threads are waiting
-      *      the highest priority waiter is awakened; otherwise,
-      *      an unspecified waiter is awakened.
-      *
-      *      NOTES:
-      *
-      *      1)      Use when any waiter can respond and only one need
-      *              respond (all waiters being equal).
-      *
-      * RESULTS
-      *              0               successfully signaled condition,
-      *              EINVAL          'cond' is invalid,
-      *
-      * ------------------------------------------------------
-      */
-{
-  /*
-   * The '0'(FALSE) unblockAll arg means unblock ONE waiter.
-   */
-  return (ptw32_cond_unblock (cond, 0));
-
-}				/* pthread_cond_signal */
-
-int
-pthread_cond_broadcast (pthread_cond_t * cond)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function broadcasts the condition variable,
-      *      waking all current waiters.
-      *
-      * PARAMETERS
-      *      cond
-      *              pointer to an instance of pthread_cond_t
-      *
-      *
-      * DESCRIPTION
-      *      This function signals a condition variable, waking
-      *      all waiting threads.
-      *
-      *      NOTES:
-      *
-      *      1)      Use when more than one waiter may respond to
-      *              predicate change or if any waiting thread may
-      *              not be able to respond
-      *
-      * RESULTS
-      *              0               successfully signalled condition to all
-      *                              waiting threads,
-      *              EINVAL          'cond' is invalid
-      *              ENOSPC          a required resource has been exhausted,
-      *
-      * ------------------------------------------------------
-      */
-{
-  /*
-   * The TRUE unblockAll arg means unblock ALL waiters.
-   */
-  return (ptw32_cond_unblock (cond, PTW32_TRUE));
-
-}				/* pthread_cond_broadcast */
diff --git a/deps/w32-pthreads/pthread_cond_wait.c b/deps/w32-pthreads/pthread_cond_wait.c
deleted file mode 100644
index 8248407..0000000
--- a/deps/w32-pthreads/pthread_cond_wait.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * pthread_cond_wait.c
- *
- * Description:
- * This translation unit implements condition variables and their primitives.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * -------------------------------------------------------------
- * Algorithm:
- * The algorithm used in this implementation is that developed by
- * Alexander Terekhov in colaboration with Louis Thomas. The bulk
- * of the discussion is recorded in the file README.CV, which contains
- * several generations of both colaborators original algorithms. The final
- * algorithm used here is the one referred to as
- *
- *     Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
- * 
- * presented below in pseudo-code as it appeared:
- *
- *
- * given:
- * semBlockLock - bin.semaphore
- * semBlockQueue - semaphore
- * mtxExternal - mutex or CS
- * mtxUnblockLock - mutex or CS
- * nWaitersGone - int
- * nWaitersBlocked - int
- * nWaitersToUnblock - int
- * 
- * wait( timeout ) {
- * 
- *   [auto: register int result          ]     // error checking omitted
- *   [auto: register int nSignalsWasLeft ]
- *   [auto: register int nWaitersWasGone ]
- * 
- *   sem_wait( semBlockLock );
- *   nWaitersBlocked++;
- *   sem_post( semBlockLock );
- * 
- *   unlock( mtxExternal );
- *   bTimedOut = sem_wait( semBlockQueue,timeout );
- * 
- *   lock( mtxUnblockLock );
- *   if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
- *     if ( bTimeout ) {                       // timeout (or canceled)
- *       if ( 0 != nWaitersBlocked ) {
- *         nWaitersBlocked--;
- *       }
- *       else {
- *         nWaitersGone++;                     // count spurious wakeups.
- *       }
- *     }
- *     if ( 0 == --nWaitersToUnblock ) {
- *       if ( 0 != nWaitersBlocked ) {
- *         sem_post( semBlockLock );           // open the gate.
- *         nSignalsWasLeft = 0;                // do not open the gate
- *                                             // below again.
- *       }
- *       else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
- *         nWaitersGone = 0;
- *       }
- *     }
- *   }
- *   else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
- *                                             // spurious semaphore :-)
- *     sem_wait( semBlockLock );
- *     nWaitersBlocked -= nWaitersGone;     // something is going on here
- *                                          //  - test of timeouts? :-)
- *     sem_post( semBlockLock );
- *     nWaitersGone = 0;
- *   }
- *   unlock( mtxUnblockLock );
- * 
- *   if ( 1 == nSignalsWasLeft ) {
- *     if ( 0 != nWaitersWasGone ) {
- *       // sem_adjust( semBlockQueue,-nWaitersWasGone );
- *       while ( nWaitersWasGone-- ) {
- *         sem_wait( semBlockQueue );       // better now than spurious later
- *       }
- *     } sem_post( semBlockLock );          // open the gate
- *   }
- * 
- *   lock( mtxExternal );
- * 
- *   return ( bTimedOut ) ? ETIMEOUT : 0;
- * }
- * 
- * signal(bAll) {
- * 
- *   [auto: register int result         ]
- *   [auto: register int nSignalsToIssue]
- * 
- *   lock( mtxUnblockLock );
- * 
- *   if ( 0 != nWaitersToUnblock ) {        // the gate is closed!!!
- *     if ( 0 == nWaitersBlocked ) {        // NO-OP
- *       return unlock( mtxUnblockLock );
- *     }
- *     if (bAll) {
- *       nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
- *       nWaitersBlocked = 0;
- *     }
- *     else {
- *       nSignalsToIssue = 1;
- *       nWaitersToUnblock++;
- *       nWaitersBlocked--;
- *     }
- *   }
- *   else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
- *     sem_wait( semBlockLock );                  // close the gate
- *     if ( 0 != nWaitersGone ) {
- *       nWaitersBlocked -= nWaitersGone;
- *       nWaitersGone = 0;
- *     }
- *     if (bAll) {
- *       nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
- *       nWaitersBlocked = 0;
- *     }
- *     else {
- *       nSignalsToIssue = nWaitersToUnblock = 1;
- *       nWaitersBlocked--;
- *     }
- *   }
- *   else { // NO-OP
- *     return unlock( mtxUnblockLock );
- *   }
- * 
- *   unlock( mtxUnblockLock );
- *   sem_post( semBlockQueue,nSignalsToIssue );
- *   return result;
- * }
- * -------------------------------------------------------------
- *
- *     Algorithm 9 / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
- * 
- * presented below in pseudo-code; basically 8a...
- *                                      ...BUT W/O "spurious wakes" prevention:
- *
- *
- * given:
- * semBlockLock - bin.semaphore
- * semBlockQueue - semaphore
- * mtxExternal - mutex or CS
- * mtxUnblockLock - mutex or CS
- * nWaitersGone - int
- * nWaitersBlocked - int
- * nWaitersToUnblock - int
- * 
- * wait( timeout ) {
- * 
- *   [auto: register int result          ]     // error checking omitted
- *   [auto: register int nSignalsWasLeft ]
- * 
- *   sem_wait( semBlockLock );
- *   ++nWaitersBlocked;
- *   sem_post( semBlockLock );
- * 
- *   unlock( mtxExternal );
- *   bTimedOut = sem_wait( semBlockQueue,timeout );
- * 
- *   lock( mtxUnblockLock );
- *   if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
- *     --nWaitersToUnblock;
- *   }
- *   else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
- *                                             // spurious semaphore :-)
- *     sem_wait( semBlockLock );
- *     nWaitersBlocked -= nWaitersGone;        // something is going on here
- *                                             //  - test of timeouts? :-)
- *     sem_post( semBlockLock );
- *     nWaitersGone = 0;
- *   }
- *   unlock( mtxUnblockLock );
- * 
- *   if ( 1 == nSignalsWasLeft ) {
- *     sem_post( semBlockLock );               // open the gate
- *   }
- * 
- *   lock( mtxExternal );
- * 
- *   return ( bTimedOut ) ? ETIMEOUT : 0;
- * }
- * 
- * signal(bAll) {
- * 
- *   [auto: register int result         ]
- *   [auto: register int nSignalsToIssue]
- * 
- *   lock( mtxUnblockLock );
- * 
- *   if ( 0 != nWaitersToUnblock ) {        // the gate is closed!!!
- *     if ( 0 == nWaitersBlocked ) {        // NO-OP
- *       return unlock( mtxUnblockLock );
- *     }
- *     if (bAll) {
- *       nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
- *       nWaitersBlocked = 0;
- *     }
- *     else {
- *       nSignalsToIssue = 1;
- *       ++nWaitersToUnblock;
- *       --nWaitersBlocked;
- *     }
- *   }
- *   else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
- *     sem_wait( semBlockLock );                  // close the gate
- *     if ( 0 != nWaitersGone ) {
- *       nWaitersBlocked -= nWaitersGone;
- *       nWaitersGone = 0;
- *     }
- *     if (bAll) {
- *       nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
- *       nWaitersBlocked = 0;
- *     }
- *     else {
- *       nSignalsToIssue = nWaitersToUnblock = 1;
- *       --nWaitersBlocked;
- *     }
- *   }
- *   else { // NO-OP
- *     return unlock( mtxUnblockLock );
- *   }
- *
- *   unlock( mtxUnblockLock );
- *   sem_post( semBlockQueue,nSignalsToIssue );
- *   return result;
- * }
- * -------------------------------------------------------------
- *
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/*
- * Arguments for cond_wait_cleanup, since we can only pass a
- * single void * to it.
- */
-typedef struct
-{
-  pthread_mutex_t *mutexPtr;
-  pthread_cond_t cv;
-  int *resultPtr;
-} ptw32_cond_wait_cleanup_args_t;
-
-static void PTW32_CDECL
-ptw32_cond_wait_cleanup (void *args)
-{
-  ptw32_cond_wait_cleanup_args_t *cleanup_args =
-    (ptw32_cond_wait_cleanup_args_t *) args;
-  pthread_cond_t cv = cleanup_args->cv;
-  int *resultPtr = cleanup_args->resultPtr;
-  int nSignalsWasLeft;
-  int result;
-
-  /*
-   * Whether we got here as a result of signal/broadcast or because of
-   * timeout on wait or thread cancellation we indicate that we are no
-   * longer waiting. The waiter is responsible for adjusting waiters
-   * (to)unblock(ed) counts (protected by unblock lock).
-   */
-  if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0)
-    {
-      *resultPtr = result;
-      return;
-    }
-
-  if (0 != (nSignalsWasLeft = cv->nWaitersToUnblock))
-    {
-      --(cv->nWaitersToUnblock);
-    }
-  else if (INT_MAX / 2 == ++(cv->nWaitersGone))
-    {
-      /* Use the non-cancellable version of sem_wait() */
-      if (ptw32_semwait (&(cv->semBlockLock)) != 0)
-	{
-	  *resultPtr = errno;
-	  /*
-	   * This is a fatal error for this CV,
-	   * so we deliberately don't unlock
-	   * cv->mtxUnblockLock before returning.
-	   */
-	  return;
-	}
-      cv->nWaitersBlocked -= cv->nWaitersGone;
-      if (sem_post (&(cv->semBlockLock)) != 0)
-	{
-	  *resultPtr = errno;
-	  /*
-	   * This is a fatal error for this CV,
-	   * so we deliberately don't unlock
-	   * cv->mtxUnblockLock before returning.
-	   */
-	  return;
-	}
-      cv->nWaitersGone = 0;
-    }
-
-  if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) != 0)
-    {
-      *resultPtr = result;
-      return;
-    }
-
-  if (1 == nSignalsWasLeft)
-    {
-      if (sem_post (&(cv->semBlockLock)) != 0)
-	{
-	  *resultPtr = errno;
-	  return;
-	}
-    }
-
-  /*
-   * XSH: Upon successful return, the mutex has been locked and is owned
-   * by the calling thread.
-   */
-  if ((result = pthread_mutex_lock (cleanup_args->mutexPtr)) != 0)
-    {
-      *resultPtr = result;
-    }
-}				/* ptw32_cond_wait_cleanup */
-
-static INLINE int
-ptw32_cond_timedwait (pthread_cond_t * cond,
-		      pthread_mutex_t * mutex, const struct timespec *abstime)
-{
-  int result = 0;
-  pthread_cond_t cv;
-  ptw32_cond_wait_cleanup_args_t cleanup_args;
-
-  if (cond == NULL || *cond == NULL)
-    {
-      return EINVAL;
-    }
-
-  /*
-   * We do a quick check to see if we need to do more work
-   * to initialise a static condition variable. We check
-   * again inside the guarded section of ptw32_cond_check_need_init()
-   * to avoid race conditions.
-   */
-  if (*cond == PTHREAD_COND_INITIALIZER)
-    {
-      result = ptw32_cond_check_need_init (cond);
-    }
-
-  if (result != 0 && result != EBUSY)
-    {
-      return result;
-    }
-
-  cv = *cond;
-
-  /* Thread can be cancelled in sem_wait() but this is OK */
-  if (sem_wait (&(cv->semBlockLock)) != 0)
-    {
-      return errno;
-    }
-
-  ++(cv->nWaitersBlocked);
-
-  if (sem_post (&(cv->semBlockLock)) != 0)
-    {
-      return errno;
-    }
-
-  /*
-   * Setup this waiter cleanup handler
-   */
-  cleanup_args.mutexPtr = mutex;
-  cleanup_args.cv = cv;
-  cleanup_args.resultPtr = &result;
-
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth(0)
-#endif
-  pthread_cleanup_push (ptw32_cond_wait_cleanup, (void *) &cleanup_args);
-
-  /*
-   * Now we can release 'mutex' and...
-   */
-  if ((result = pthread_mutex_unlock (mutex)) == 0)
-    {
-
-      /*
-       * ...wait to be awakened by
-       *              pthread_cond_signal, or
-       *              pthread_cond_broadcast, or
-       *              timeout, or
-       *              thread cancellation
-       *
-       * Note:
-       *
-       *      sem_timedwait is a cancellation point,
-       *      hence providing the mechanism for making
-       *      pthread_cond_wait a cancellation point.
-       *      We use the cleanup mechanism to ensure we
-       *      re-lock the mutex and adjust (to)unblock(ed) waiters
-       *      counts if we are cancelled, timed out or signalled.
-       */
-      if (sem_timedwait (&(cv->semBlockQueue), abstime) != 0)
-	{
-	  result = errno;
-	}
-    }
-
-  /*
-   * Always cleanup
-   */
-  pthread_cleanup_pop (1);
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth()
-#endif
-
-  /*
-   * "result" can be modified by the cleanup handler.
-   */
-  return result;
-
-}				/* ptw32_cond_timedwait */
-
-
-int
-pthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function waits on a condition variable until
-      *      awakened by a signal or broadcast.
-      *
-      *      Caller MUST be holding the mutex lock; the
-      *      lock is released and the caller is blocked waiting
-      *      on 'cond'. When 'cond' is signaled, the mutex
-      *      is re-acquired before returning to the caller.
-      *
-      * PARAMETERS
-      *      cond
-      *              pointer to an instance of pthread_cond_t
-      *
-      *      mutex
-      *              pointer to an instance of pthread_mutex_t
-      *
-      *
-      * DESCRIPTION
-      *      This function waits on a condition variable until
-      *      awakened by a signal or broadcast.
-      *
-      *      NOTES:
-      *
-      *      1)      The function must be called with 'mutex' LOCKED
-      *              by the calling thread, or undefined behaviour
-      *              will result.
-      *
-      *      2)      This routine atomically releases 'mutex' and causes
-      *              the calling thread to block on the condition variable.
-      *              The blocked thread may be awakened by 
-      *                      pthread_cond_signal or 
-      *                      pthread_cond_broadcast.
-      *
-      * Upon successful completion, the 'mutex' has been locked and 
-      * is owned by the calling thread.
-      *
-      *
-      * RESULTS
-      *              0               caught condition; mutex released,
-      *              EINVAL          'cond' or 'mutex' is invalid,
-      *              EINVAL          different mutexes for concurrent waits,
-      *              EINVAL          mutex is not held by the calling thread,
-      *
-      * ------------------------------------------------------
-      */
-{
-  /*
-   * The NULL abstime arg means INFINITE waiting.
-   */
-  return (ptw32_cond_timedwait (cond, mutex, NULL));
-
-}				/* pthread_cond_wait */
-
-
-int
-pthread_cond_timedwait (pthread_cond_t * cond,
-			pthread_mutex_t * mutex,
-			const struct timespec *abstime)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function waits on a condition variable either until
-      *      awakened by a signal or broadcast; or until the time
-      *      specified by abstime passes.
-      *
-      * PARAMETERS
-      *      cond
-      *              pointer to an instance of pthread_cond_t
-      *
-      *      mutex
-      *              pointer to an instance of pthread_mutex_t
-      *
-      *      abstime
-      *              pointer to an instance of (const struct timespec)
-      *
-      *
-      * DESCRIPTION
-      *      This function waits on a condition variable either until
-      *      awakened by a signal or broadcast; or until the time
-      *      specified by abstime passes.
-      *
-      *      NOTES:
-      *      1)      The function must be called with 'mutex' LOCKED
-      *              by the calling thread, or undefined behaviour
-      *              will result.
-      *
-      *      2)      This routine atomically releases 'mutex' and causes
-      *              the calling thread to block on the condition variable.
-      *              The blocked thread may be awakened by 
-      *                      pthread_cond_signal or 
-      *                      pthread_cond_broadcast.
-      *
-      *
-      * RESULTS
-      *              0               caught condition; mutex released,
-      *              EINVAL          'cond', 'mutex', or abstime is invalid,
-      *              EINVAL          different mutexes for concurrent waits,
-      *              EINVAL          mutex is not held by the calling thread,
-      *              ETIMEDOUT       abstime ellapsed before cond was signaled.
-      *
-      * ------------------------------------------------------
-      */
-{
-  if (abstime == NULL)
-    {
-      return EINVAL;
-    }
-
-  return (ptw32_cond_timedwait (cond, mutex, abstime));
-
-}				/* pthread_cond_timedwait */
diff --git a/deps/w32-pthreads/pthread_condattr_destroy.c b/deps/w32-pthreads/pthread_condattr_destroy.c
deleted file mode 100644
index d401cee..0000000
--- a/deps/w32-pthreads/pthread_condattr_destroy.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * condvar_attr_destroy.c
- *
- * Description:
- * This translation unit implements condition variables and their primitives.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_condattr_destroy (pthread_condattr_t * attr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Destroys a condition variable attributes object.
-      *      The object can no longer be used.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_condattr_t
-      *
-      *
-      * DESCRIPTION
-      *      Destroys a condition variable attributes object.
-      *      The object can no longer be used.
-      *
-      *      NOTES:
-      *      1)      Does not affect condition variables created
-      *              using 'attr'
-      *
-      * RESULTS
-      *              0               successfully released attr,
-      *              EINVAL          'attr' is invalid.
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-
-  if (attr == NULL || *attr == NULL)
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      (void) free (*attr);
-
-      *attr = NULL;
-      result = 0;
-    }
-
-  return result;
-
-}				/* pthread_condattr_destroy */
diff --git a/deps/w32-pthreads/pthread_condattr_getpshared.c b/deps/w32-pthreads/pthread_condattr_getpshared.c
deleted file mode 100644
index 7b508e3..0000000
--- a/deps/w32-pthreads/pthread_condattr_getpshared.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * pthread_condattr_getpshared.c
- *
- * Description:
- * This translation unit implements condition variables and their primitives.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_condattr_getpshared (const pthread_condattr_t * attr, int *pshared)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Determine whether condition variables created with 'attr'
-      *      can be shared between processes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_condattr_t
-      *
-      *      pshared
-      *              will be set to one of:
-      *
-      *                      PTHREAD_PROCESS_SHARED
-      *                              May be shared if in shared memory
-      *
-      *                      PTHREAD_PROCESS_PRIVATE
-      *                              Cannot be shared.
-      *
-      *
-      * DESCRIPTION
-      *      Condition Variables created with 'attr' can be shared
-      *      between processes if pthread_cond_t variable is allocated
-      *      in memory shared by these processes.
-      *      NOTES:
-      *      1)      pshared condition variables MUST be allocated in
-      *              shared memory.
-      *
-      *      2)      The following macro is defined if shared mutexes
-      *              are supported:
-      *                      _POSIX_THREAD_PROCESS_SHARED
-      *
-      * RESULTS
-      *              0               successfully retrieved attribute,
-      *              EINVAL          'attr' or 'pshared' is invalid,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-
-  if ((attr != NULL && *attr != NULL) && (pshared != NULL))
-    {
-      *pshared = (*attr)->pshared;
-      result = 0;
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  return result;
-
-}				/* pthread_condattr_getpshared */
diff --git a/deps/w32-pthreads/pthread_condattr_init.c b/deps/w32-pthreads/pthread_condattr_init.c
deleted file mode 100644
index fd59642..0000000
--- a/deps/w32-pthreads/pthread_condattr_init.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * pthread_condattr_init.c
- *
- * Description:
- * This translation unit implements condition variables and their primitives.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_condattr_init (pthread_condattr_t * attr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Initializes a condition variable attributes object
-      *      with default attributes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_condattr_t
-      *
-      *
-      * DESCRIPTION
-      *      Initializes a condition variable attributes object
-      *      with default attributes.
-      *
-      *      NOTES:
-      *              1)      Use to define condition variable types
-      *              2)      It is up to the application to ensure
-      *                      that it doesn't re-init an attribute
-      *                      without destroying it first. Otherwise
-      *                      a memory leak is created.
-      *
-      * RESULTS
-      *              0               successfully initialized attr,
-      *              ENOMEM          insufficient memory for attr.
-      *
-      * ------------------------------------------------------
-      */
-{
-  pthread_condattr_t attr_result;
-  int result = 0;
-
-  attr_result = (pthread_condattr_t) calloc (1, sizeof (*attr_result));
-
-  if (attr_result == NULL)
-    {
-      result = ENOMEM;
-    }
-
-  *attr = attr_result;
-
-  return result;
-
-}				/* pthread_condattr_init */
diff --git a/deps/w32-pthreads/pthread_condattr_setpshared.c b/deps/w32-pthreads/pthread_condattr_setpshared.c
deleted file mode 100644
index f624207..0000000
--- a/deps/w32-pthreads/pthread_condattr_setpshared.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * pthread_condattr_setpshared.c
- *
- * Description:
- * This translation unit implements condition variables and their primitives.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_condattr_setpshared (pthread_condattr_t * attr, int pshared)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Mutexes created with 'attr' can be shared between
-      *      processes if pthread_mutex_t variable is allocated
-      *      in memory shared by these processes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_mutexattr_t
-      *
-      *      pshared
-      *              must be one of:
-      *
-      *                      PTHREAD_PROCESS_SHARED
-      *                              May be shared if in shared memory
-      *
-      *                      PTHREAD_PROCESS_PRIVATE
-      *                              Cannot be shared.
-      *
-      * DESCRIPTION
-      *      Mutexes creatd with 'attr' can be shared between
-      *      processes if pthread_mutex_t variable is allocated
-      *      in memory shared by these processes.
-      *
-      *      NOTES:
-      *              1)      pshared mutexes MUST be allocated in shared
-      *                      memory.
-      *
-      *              2)      The following macro is defined if shared mutexes
-      *                      are supported:
-      *                              _POSIX_THREAD_PROCESS_SHARED
-      *
-      * RESULTS
-      *              0               successfully set attribute,
-      *              EINVAL          'attr' or pshared is invalid,
-      *              ENOSYS          PTHREAD_PROCESS_SHARED not supported,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-
-  if ((attr != NULL && *attr != NULL)
-      && ((pshared == PTHREAD_PROCESS_SHARED)
-	  || (pshared == PTHREAD_PROCESS_PRIVATE)))
-    {
-      if (pshared == PTHREAD_PROCESS_SHARED)
-	{
-
-#if !defined( _POSIX_THREAD_PROCESS_SHARED )
-	  result = ENOSYS;
-	  pshared = PTHREAD_PROCESS_PRIVATE;
-#else
-	  result = 0;
-
-#endif /* _POSIX_THREAD_PROCESS_SHARED */
-
-	}
-      else
-	{
-	  result = 0;
-	}
-
-      (*attr)->pshared = pshared;
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  return result;
-
-}				/* pthread_condattr_setpshared */
diff --git a/deps/w32-pthreads/pthread_delay_np.c b/deps/w32-pthreads/pthread_delay_np.c
deleted file mode 100644
index 8d681e9..0000000
--- a/deps/w32-pthreads/pthread_delay_np.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * pthreads_delay_np.c
- *
- * Description:
- * This translation unit implements non-portable thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/*
- * pthread_delay_np
- *
- * DESCRIPTION
- *
- *       This routine causes a thread to delay execution for a specific period of time.
- *       This period ends at the current time plus the specified interval. The routine
- *       will not return before the end of the period is reached, but may return an
- *       arbitrary amount of time after the period has gone by. This can be due to
- *       system load, thread priorities, and system timer granularity. 
- *
- *       Specifying an interval of zero (0) seconds and zero (0) nanoseconds is
- *       allowed and can be used to force the thread to give up the processor or to
- *       deliver a pending cancelation request. 
- *
- *       The timespec structure contains the following two fields: 
- *
- *            tv_sec is an integer number of seconds. 
- *            tv_nsec is an integer number of nanoseconds. 
- *
- *  Return Values
- *
- *  If an error condition occurs, this routine returns an integer value indicating
- *  the type of error. Possible return values are as follows: 
- *
- *  0 
- *           Successful completion.
- *  [EINVAL] 
- *           The value specified by interval is invalid. 
- *
- * Example
- *
- * The following code segment would wait for 5 and 1/2 seconds
- *
- *  struct timespec tsWait;
- *  int      intRC;
- *
- *  tsWait.tv_sec  = 5;
- *  tsWait.tv_nsec = 500000000L;
- *  intRC = pthread_delay_np(&tsWait);
- */
-int
-pthread_delay_np (struct timespec *interval)
-{
-  DWORD wait_time;
-  DWORD secs_in_millisecs;
-  DWORD millisecs;
-  DWORD status;
-  pthread_t self;
-  ptw32_thread_t * sp;
-
-  if (interval == NULL)
-    {
-      return EINVAL;
-    }
-
-  if (interval->tv_sec == 0L && interval->tv_nsec == 0L)
-    {
-      pthread_testcancel ();
-      Sleep (0);
-      pthread_testcancel ();
-      return (0);
-    }
-
-  /* convert secs to millisecs */
-  secs_in_millisecs = (DWORD)interval->tv_sec * 1000L;
-
-  /* convert nanosecs to millisecs (rounding up) */
-  millisecs = (interval->tv_nsec + 999999L) / 1000000L;
-
-#if defined(__WATCOMC__)
-#pragma disable_message (124)
-#endif
-
-  /*
-   * Most compilers will issue a warning 'comparison always 0'
-   * because the variable type is unsigned, but we need to keep this
-   * for some reason I can't recall now.
-   */
-  if (0 > (wait_time = secs_in_millisecs + millisecs))
-    {
-      return EINVAL;
-    }
-
-#if defined(__WATCOMC__)
-#pragma enable_message (124)
-#endif
-
-  if (NULL == (self = pthread_self ()).p)
-    {
-      return ENOMEM;
-    }
-
-  sp = (ptw32_thread_t *) self.p;
-
-  if (sp->cancelState == PTHREAD_CANCEL_ENABLE)
-    {
-      /*
-       * Async cancelation won't catch us until wait_time is up.
-       * Deferred cancelation will cancel us immediately.
-       */
-      if (WAIT_OBJECT_0 ==
-	  (status = WaitForSingleObject (sp->cancelEvent, wait_time)))
-	{
-          ptw32_mcs_local_node_t stateLock;
-	  /*
-	   * Canceling!
-	   */
-	  ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
-	  if (sp->state < PThreadStateCanceling)
-	    {
-	      sp->state = PThreadStateCanceling;
-	      sp->cancelState = PTHREAD_CANCEL_DISABLE;
-	      ptw32_mcs_lock_release (&stateLock);
-
-	      ptw32_throw (PTW32_EPS_CANCEL);
-	    }
-
-	  ptw32_mcs_lock_release (&stateLock);
-	  return ESRCH;
-	}
-      else if (status != WAIT_TIMEOUT)
-	{
-	  return EINVAL;
-	}
-    }
-  else
-    {
-      Sleep (wait_time);
-    }
-
-  return (0);
-}
diff --git a/deps/w32-pthreads/pthread_detach.c b/deps/w32-pthreads/pthread_detach.c
deleted file mode 100644
index 10f79d8..0000000
--- a/deps/w32-pthreads/pthread_detach.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * pthread_detach.c
- *
- * Description:
- * This translation unit implements functions related to thread
- * synchronisation.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/*
- * Not needed yet, but defining it should indicate clashes with build target
- * environment that should be fixed.
- */
-#if !defined(WINCE)
-#  include <signal.h>
-#endif
-
-
-int
-pthread_detach (pthread_t thread)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function detaches the given thread.
-      *
-      * PARAMETERS
-      *      thread
-      *              an instance of a pthread_t
-      *
-      *
-      * DESCRIPTION
-      *      This function detaches the given thread. You may use it to
-      *      detach the main thread or to detach a joinable thread.
-      *      NOTE:   detached threads cannot be joined;
-      *              storage is freed immediately on termination.
-      *
-      * RESULTS
-      *              0               successfully detached the thread,
-      *              EINVAL          thread is not a joinable thread,
-      *              ENOSPC          a required resource has been exhausted,
-      *              ESRCH           no thread could be found for 'thread',
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-  BOOL destroyIt = PTW32_FALSE;
-  ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
-  ptw32_mcs_local_node_t node;
-
-  ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
-
-  if (NULL == tp
-      || thread.x != tp->ptHandle.x)
-    {
-      result = ESRCH;
-    }
-  else if (PTHREAD_CREATE_DETACHED == tp->detachState)
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      ptw32_mcs_local_node_t stateLock;
-      /*
-       * Joinable ptw32_thread_t structs are not scavenged until
-       * a join or detach is done. The thread may have exited already,
-       * but all of the state and locks etc are still there.
-       */
-      result = 0;
-
-      ptw32_mcs_lock_acquire (&tp->stateLock, &stateLock);
-      if (tp->state != PThreadStateLast)
-        {
-          tp->detachState = PTHREAD_CREATE_DETACHED;
-        }
-      else if (tp->detachState != PTHREAD_CREATE_DETACHED)
-        {
-          /*
-           * Thread is joinable and has exited or is exiting.
-           */
-          destroyIt = PTW32_TRUE;
-        }
-      ptw32_mcs_lock_release (&stateLock);
-    }
-
-  ptw32_mcs_lock_release(&node);
-
-  if (result == 0)
-    {
-      /* Thread is joinable */
-
-      if (destroyIt)
-	{
-	  /* The thread has exited or is exiting but has not been joined or
-	   * detached. Need to wait in case it's still exiting.
-	   */
-	  (void) WaitForSingleObject(tp->threadH, INFINITE);
-	  ptw32_threadDestroy (thread);
-	}
-    }
-
-  return (result);
-
-}				/* pthread_detach */
diff --git a/deps/w32-pthreads/pthread_equal.c b/deps/w32-pthreads/pthread_equal.c
deleted file mode 100644
index aae0085..0000000
--- a/deps/w32-pthreads/pthread_equal.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * pthread_equal.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_equal (pthread_t t1, pthread_t t2)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function returns nonzero if t1 and t2 are equal, else
-      *      returns zero
-      *
-      * PARAMETERS
-      *      t1,
-      *      t2
-      *              thread IDs
-      *
-      *
-      * DESCRIPTION
-      *      This function returns nonzero if t1 and t2 are equal, else
-      *      returns zero.
-      *
-      * RESULTS
-      *              non-zero        if t1 and t2 refer to the same thread,
-      *              0               t1 and t2 do not refer to the same thread
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-
-  /*
-   * We also accept NULL == NULL - treating NULL as a thread
-   * for this special case, because there is no error that we can return.
-   */
-  result = ( t1.p == t2.p && t1.x == t2.x );
-
-  return (result);
-
-}				/* pthread_equal */
diff --git a/deps/w32-pthreads/pthread_exit.c b/deps/w32-pthreads/pthread_exit.c
deleted file mode 100644
index 30ae5f4..0000000
--- a/deps/w32-pthreads/pthread_exit.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * pthread_exit.c
- *
- * Description:
- * This translation unit implements routines associated with exiting from
- * a thread.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#if !defined(_UWIN)
-/*#   include <process.h> */
-#endif
-
-void
-pthread_exit (void *value_ptr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function terminates the calling thread, returning
-      *      the value 'value_ptr' to any joining thread.
-      *
-      * PARAMETERS
-      *      value_ptr
-      *              a generic data value (i.e. not the address of a value)
-      *
-      *
-      * DESCRIPTION
-      *      This function terminates the calling thread, returning
-      *      the value 'value_ptr' to any joining thread.
-      *      NOTE: thread should be joinable.
-      *
-      * RESULTS
-      *              N/A
-      *
-      * ------------------------------------------------------
-      */
-{
-  ptw32_thread_t * sp;
-
-  /*
-   * Don't use pthread_self() to avoid creating an implicit POSIX thread handle
-   * unnecessarily.
-   */
-  sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
-
-#if defined(_UWIN)
-  if (--pthread_count <= 0)
-    exit ((int) value_ptr);
-#endif
-
-  if (NULL == sp)
-    {
-      /*
-       * A POSIX thread handle was never created. I.e. this is a
-       * Win32 thread that has never called a pthreads-win32 routine that
-       * required a POSIX handle.
-       *
-       * Implicit POSIX handles are cleaned up in ptw32_throw() now.
-       */
-
-#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__)  || defined (__DMC__)
-      _endthreadex ((unsigned) (size_t) value_ptr);
-#else
-      _endthread ();
-#endif
-
-      /* Never reached */
-    }
-
-  sp->exitStatus = value_ptr;
-
-  ptw32_throw (PTW32_EPS_EXIT);
-
-  /* Never reached. */
-
-}
diff --git a/deps/w32-pthreads/pthread_getconcurrency.c b/deps/w32-pthreads/pthread_getconcurrency.c
deleted file mode 100644
index 5c9856c..0000000
--- a/deps/w32-pthreads/pthread_getconcurrency.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * pthread_getconcurrency.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_getconcurrency (void)
-{
-  return ptw32_concurrency;
-}
diff --git a/deps/w32-pthreads/pthread_getschedparam.c b/deps/w32-pthreads/pthread_getschedparam.c
deleted file mode 100644
index bef6efe..0000000
--- a/deps/w32-pthreads/pthread_getschedparam.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * sched_getschedparam.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-int
-pthread_getschedparam (pthread_t thread, int *policy,
-		       struct sched_param *param)
-{
-  int result;
-
-  /* Validate the thread id. */
-  result = pthread_kill (thread, 0);
-  if (0 != result)
-    {
-      return result;
-    }
-
-  /*
-   * Validate the policy and param args.
-   * Check that a policy constant wasn't passed rather than &policy.
-   */
-  if (policy <= (int *) SCHED_MAX || param == NULL)
-    {
-      return EINVAL;
-    }
-
-  /* Fill out the policy. */
-  *policy = SCHED_OTHER;
-
-  /*
-   * This function must return the priority value set by
-   * the most recent pthread_setschedparam() or pthread_create()
-   * for the target thread. It must not return the actual thread
-   * priority as altered by any system priority adjustments etc.
-   */
-  param->sched_priority = ((ptw32_thread_t *)thread.p)->sched_priority;
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/pthread_getspecific.c b/deps/w32-pthreads/pthread_getspecific.c
deleted file mode 100644
index f3e8af7..0000000
--- a/deps/w32-pthreads/pthread_getspecific.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * pthread_getspecific.c
- *
- * Description:
- * POSIX thread functions which implement thread-specific data (TSD).
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-void *
-pthread_getspecific (pthread_key_t key)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function returns the current value of key in the
-      *      calling thread. If no value has been set for 'key' in 
-      *      the thread, NULL is returned.
-      *
-      * PARAMETERS
-      *      key
-      *              an instance of pthread_key_t
-      *
-      *
-      * DESCRIPTION
-      *      This function returns the current value of key in the
-      *      calling thread. If no value has been set for 'key' in 
-      *      the thread, NULL is returned.
-      *
-      * RESULTS
-      *              key value or NULL on failure
-      *
-      * ------------------------------------------------------
-      */
-{
-  void * ptr;
-
-  if (key == NULL)
-    {
-      ptr = NULL;
-    }
-  else
-    {
-      int lasterror = GetLastError ();
-#if defined(RETAIN_WSALASTERROR)
-      int lastWSAerror = WSAGetLastError ();
-#endif
-      ptr = TlsGetValue (key->key);
-
-      SetLastError (lasterror);
-#if defined(RETAIN_WSALASTERROR)
-      WSASetLastError (lastWSAerror);
-#endif
-    }
-
-  return ptr;
-}
diff --git a/deps/w32-pthreads/pthread_getunique_np.c b/deps/w32-pthreads/pthread_getunique_np.c
deleted file mode 100644
index 9ab1c5b..0000000
--- a/deps/w32-pthreads/pthread_getunique_np.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * pthread_getunique_np.c
- *
- * Description:
- * This translation unit implements non-portable thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/*
- *
- */
-unsigned __int64
-pthread_getunique_np (pthread_t thread)
-{
-  return ((ptw32_thread_t*)thread.p)->seqNumber;
-}
diff --git a/deps/w32-pthreads/pthread_getw32threadhandle_np.c b/deps/w32-pthreads/pthread_getw32threadhandle_np.c
deleted file mode 100644
index 23ed746..0000000
--- a/deps/w32-pthreads/pthread_getw32threadhandle_np.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * pthread_getw32threadhandle_np.c
- *
- * Description:
- * This translation unit implements non-portable thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/*
- * pthread_getw32threadhandle_np()
- *
- * Returns the win32 thread handle that the POSIX
- * thread "thread" is running as.
- *
- * Applications can use the win32 handle to set
- * win32 specific attributes of the thread.
- */
-HANDLE
-pthread_getw32threadhandle_np (pthread_t thread)
-{
-  return ((ptw32_thread_t *)thread.p)->threadH;
-}
-
-/*
- * pthread_getw32threadid_np()
- *
- * Returns the win32 thread id that the POSIX
- * thread "thread" is running as.
- */
-DWORD
-pthread_getw32threadid_np (pthread_t thread)
-{
-  return ((ptw32_thread_t *)thread.p)->thread;
-}
diff --git a/deps/w32-pthreads/pthread_join.c b/deps/w32-pthreads/pthread_join.c
deleted file mode 100644
index 86318b7..0000000
--- a/deps/w32-pthreads/pthread_join.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * pthread_join.c
- *
- * Description:
- * This translation unit implements functions related to thread
- * synchronisation.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/*
- * Not needed yet, but defining it should indicate clashes with build target
- * environment that should be fixed.
- */
-#if !defined(WINCE)
-#  include <signal.h>
-#endif
-
-
-int
-pthread_join (pthread_t thread, void **value_ptr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function waits for 'thread' to terminate and
-      *      returns the thread's exit value if 'value_ptr' is not
-      *      NULL. This also detaches the thread on successful
-      *      completion.
-      *
-      * PARAMETERS
-      *      thread
-      *              an instance of pthread_t
-      *
-      *      value_ptr
-      *              pointer to an instance of pointer to void
-      *
-      *
-      * DESCRIPTION
-      *      This function waits for 'thread' to terminate and
-      *      returns the thread's exit value if 'value_ptr' is not
-      *      NULL. This also detaches the thread on successful
-      *      completion.
-      *      NOTE:   detached threads cannot be joined or canceled
-      *
-      * RESULTS
-      *              0               'thread' has completed
-      *              EINVAL          thread is not a joinable thread,
-      *              ESRCH           no thread could be found with ID 'thread',
-      *              ENOENT          thread couldn't find it's own valid handle,
-      *              EDEADLK         attempt to join thread with self
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-  pthread_t self;
-  ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
-  ptw32_mcs_local_node_t node;
-
-  ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
-
-  if (NULL == tp
-      || thread.x != tp->ptHandle.x)
-    {
-      result = ESRCH;
-    }
-  else if (PTHREAD_CREATE_DETACHED == tp->detachState)
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      result = 0;
-    }
-
-  ptw32_mcs_lock_release(&node);
-
-  if (result == 0)
-    {
-      /* 
-       * The target thread is joinable and can't be reused before we join it.
-       */
-      self = pthread_self();
-
-      if (NULL == self.p)
-	{
-	  result = ENOENT;
-	}
-      else if (pthread_equal (self, thread))
-	{
-	  result = EDEADLK;
-	}
-      else
-	{
-	  /*
-	   * Pthread_join is a cancelation point.
-	   * If we are canceled then our target thread must not be
-	   * detached (destroyed). This is guarranteed because
-	   * pthreadCancelableWait will not return if we
-	   * are canceled.
-	   */
-	  result = pthreadCancelableWait (tp->threadH);
-
-	  if (0 == result)
-	    {
-	      if (value_ptr != NULL)
-		{
-		  *value_ptr = tp->exitStatus;
-		}
-
-	      /*
-	       * The result of making multiple simultaneous calls to
-	       * pthread_join() or pthread_detach() specifying the same
-	       * target is undefined.
-	       */
-	      result = pthread_detach (thread);
-	    }
-	  else
-	    {
-	      result = ESRCH;
-	    }
-	}
-    }
-
-  return (result);
-
-}				/* pthread_join */
diff --git a/deps/w32-pthreads/pthread_key_create.c b/deps/w32-pthreads/pthread_key_create.c
deleted file mode 100644
index ff69c90..0000000
--- a/deps/w32-pthreads/pthread_key_create.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * pthread_key_create.c
- *
- * Description:
- * POSIX thread functions which implement thread-specific data (TSD).
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-/* TLS_OUT_OF_INDEXES not defined on WinCE */
-#if !defined(TLS_OUT_OF_INDEXES)
-#define TLS_OUT_OF_INDEXES 0xffffffff
-#endif
-
-int
-pthread_key_create (pthread_key_t * key, void (PTW32_CDECL *destructor) (void *))
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function creates a thread-specific data key visible
-      *      to all threads. All existing and new threads have a value
-      *      NULL for key until set using pthread_setspecific. When any
-      *      thread with a non-NULL value for key terminates, 'destructor'
-      *      is called with key's current value for that thread.
-      *
-      * PARAMETERS
-      *      key
-      *              pointer to an instance of pthread_key_t
-      *
-      *
-      * DESCRIPTION
-      *      This function creates a thread-specific data key visible
-      *      to all threads. All existing and new threads have a value
-      *      NULL for key until set using pthread_setspecific. When any
-      *      thread with a non-NULL value for key terminates, 'destructor'
-      *      is called with key's current value for that thread.
-      *
-      * RESULTS
-      *              0               successfully created semaphore,
-      *              EAGAIN          insufficient resources or PTHREAD_KEYS_MAX
-      *                              exceeded,
-      *              ENOMEM          insufficient memory to create the key,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  pthread_key_t newkey;
-
-  if ((newkey = (pthread_key_t) calloc (1, sizeof (*newkey))) == NULL)
-    {
-      result = ENOMEM;
-    }
-  else if ((newkey->key = TlsAlloc ()) == TLS_OUT_OF_INDEXES)
-    {
-      result = EAGAIN;
-
-      free (newkey);
-      newkey = NULL;
-    }
-  else if (destructor != NULL)
-    {
-      /*
-       * Have to manage associations between thread and key;
-       * Therefore, need a lock that allows competing threads
-       * to gain exclusive access to the key->threads list.
-       *
-       * The mutex will only be created when it is first locked.
-       */
-      newkey->keyLock = 0;
-      newkey->destructor = destructor;
-    }
-
-  *key = newkey;
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_key_delete.c b/deps/w32-pthreads/pthread_key_delete.c
deleted file mode 100644
index 165276e..0000000
--- a/deps/w32-pthreads/pthread_key_delete.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * pthread_key_delete.c
- *
- * Description:
- * POSIX thread functions which implement thread-specific data (TSD).
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_key_delete (pthread_key_t key)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function deletes a thread-specific data key. This
-      *      does not change the value of the thread specific data key
-      *      for any thread and does not run the key's destructor
-      *      in any thread so it should be used with caution.
-      *
-      * PARAMETERS
-      *      key
-      *              pointer to an instance of pthread_key_t
-      *
-      *
-      * DESCRIPTION
-      *      This function deletes a thread-specific data key. This
-      *      does not change the value of the thread specific data key
-      *      for any thread and does not run the key's destructor
-      *      in any thread so it should be used with caution.
-      *
-      * RESULTS
-      *              0               successfully deleted the key,
-      *              EINVAL          key is invalid,
-      *
-      * ------------------------------------------------------
-      */
-{
-  ptw32_mcs_local_node_t keyLock;
-  int result = 0;
-
-  if (key != NULL)
-    {
-      if (key->threads != NULL && key->destructor != NULL)
-	{
-	  ThreadKeyAssoc *assoc;
-	  ptw32_mcs_lock_acquire (&(key->keyLock), &keyLock);
-	  /*
-	   * Run through all Thread<-->Key associations
-	   * for this key.
-	   *
-	   * While we hold at least one of the locks guarding
-	   * the assoc, we know that the assoc pointed to by
-	   * key->threads is valid.
-	   */
-	  while ((assoc = (ThreadKeyAssoc *) key->threads) != NULL)
-	    {
-              ptw32_mcs_local_node_t threadLock;
-	      ptw32_thread_t * thread = assoc->thread;
-
-	      if (assoc == NULL)
-		{
-		  /* Finished */
-		  break;
-		}
-
-	      ptw32_mcs_lock_acquire (&(thread->threadLock), &threadLock);
-	      /*
-	       * Since we are starting at the head of the key's threads
-	       * chain, this will also point key->threads at the next assoc.
-	       * While we hold key->keyLock, no other thread can insert
-	       * a new assoc via pthread_setspecific.
-	       */
-	      ptw32_tkAssocDestroy (assoc);
-	      ptw32_mcs_lock_release (&threadLock);
-	      ptw32_mcs_lock_release (&keyLock);
-	    }
-	}
-
-      TlsFree (key->key);
-      if (key->destructor != NULL)
-	{
-	  /* A thread could be holding the keyLock */
-	  ptw32_mcs_lock_acquire (&(key->keyLock), &keyLock);
-	  ptw32_mcs_lock_release (&keyLock);
-	}
-
-#if defined( _DEBUG )
-      memset ((char *) key, 0, sizeof (*key));
-#endif
-      free (key);
-    }
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_kill.c b/deps/w32-pthreads/pthread_kill.c
deleted file mode 100644
index 1c3af53..0000000
--- a/deps/w32-pthreads/pthread_kill.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * pthread_kill.c
- *
- * Description:
- * This translation unit implements the pthread_kill routine.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/*
- * Not needed yet, but defining it should indicate clashes with build target
- * environment that should be fixed.
- */
-#if !defined(WINCE)
-#  include <signal.h>
-#endif
-
-int
-pthread_kill (pthread_t thread, int sig)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function requests that a signal be delivered to the
-      *      specified thread. If sig is zero, error checking is
-      *      performed but no signal is actually sent such that this
-      *      function can be used to check for a valid thread ID.
-      *
-      * PARAMETERS
-      *      thread  reference to an instances of pthread_t
-      *      sig     signal. Currently only a value of 0 is supported.
-      *
-      *
-      * DESCRIPTION
-      *      This function requests that a signal be delivered to the
-      *      specified thread. If sig is zero, error checking is
-      *      performed but no signal is actually sent such that this
-      *      function can be used to check for a valid thread ID.
-      *
-      * RESULTS
-      *              ESRCH           the thread is not a valid thread ID,
-      *              EINVAL          the value of the signal is invalid
-      *                              or unsupported.
-      *              0               the signal was successfully sent.
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  ptw32_thread_t * tp;
-  ptw32_mcs_local_node_t node;
-
-  ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
-
-  tp = (ptw32_thread_t *) thread.p;
-
-  if (NULL == tp
-      || thread.x != tp->ptHandle.x
-      || NULL == tp->threadH)
-    {
-      result = ESRCH;
-    }
-
-  ptw32_mcs_lock_release(&node);
-
-  if (0 == result && 0 != sig)
-    {
-      /*
-       * Currently does not support any signals.
-       */
-      result = EINVAL;
-    }
-
-  return result;
-
-}				/* pthread_kill */
diff --git a/deps/w32-pthreads/pthread_mutex_consistent.c b/deps/w32-pthreads/pthread_mutex_consistent.c
deleted file mode 100644
index e0bd3a3..0000000
--- a/deps/w32-pthreads/pthread_mutex_consistent.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * pthread_mutex_consistent.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-#if !defined(_UWIN)
-/*#   include <process.h> */
-#endif
-#include "pthread.h"
-#include "implement.h"
-
-INLINE
-int
-ptw32_robust_mutex_inherit(pthread_mutex_t * mutex)
-{
-  int result;
-  pthread_mutex_t mx = *mutex;
-  ptw32_robust_node_t* robust = mx->robustNode;
-
-  switch ((LONG)PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
-            (PTW32_INTERLOCKED_LONGPTR)&robust->stateInconsistent,
-            (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT,
-            (PTW32_INTERLOCKED_LONG)-1 /* The terminating thread sets this */))
-    {
-      case -1L:
-          result = EOWNERDEAD;
-          break;
-      case (LONG)PTW32_ROBUST_NOTRECOVERABLE:
-          result = ENOTRECOVERABLE;
-          break;
-      default:
-          result = 0;
-          break;
-    }
-
-  return result;
-}
-
-/*
- * The next two internal support functions depend on only being
- * called by the thread that owns the robust mutex. This enables
- * us to avoid additional locks.
- * Any mutex currently in the thread's robust mutex list is held
- * by the thread, again eliminating the need for locks.
- * The forward/backward links allow the thread to unlock mutexes
- * in any order, not necessarily the reverse locking order.
- * This is all possible because it is an error if a thread that
- * does not own the [robust] mutex attempts to unlock it.
- */
-
-INLINE
-void
-ptw32_robust_mutex_add(pthread_mutex_t* mutex, pthread_t self)
-{
-  ptw32_robust_node_t** list;
-  pthread_mutex_t mx = *mutex;
-  ptw32_thread_t* tp = (ptw32_thread_t*)self.p;
-  ptw32_robust_node_t* robust = mx->robustNode;
-
-  list = &tp->robustMxList;
-  mx->ownerThread = self;
-  if (NULL == *list)
-    {
-      robust->prev = NULL;
-      robust->next = NULL;
-      *list = robust;
-    }
-  else
-    {
-      robust->prev = NULL;
-      robust->next = *list;
-      (*list)->prev = robust;
-      *list = robust;
-    }
-}
-
-INLINE
-void
-ptw32_robust_mutex_remove(pthread_mutex_t* mutex, ptw32_thread_t* otp)
-{
-  ptw32_robust_node_t** list;
-  pthread_mutex_t mx = *mutex;
-  ptw32_robust_node_t* robust = mx->robustNode;
-
-  list = &(((ptw32_thread_t*)mx->ownerThread.p)->robustMxList);
-  mx->ownerThread.p = otp;
-  if (robust->next != NULL)
-    {
-      robust->next->prev = robust->prev;
-    }
-  if (robust->prev != NULL)
-    {
-      robust->prev->next = robust->next;
-    }
-  if (*list == robust)
-    {
-      *list = robust->next;
-    }
-}
-
-
-int
-pthread_mutex_consistent (pthread_mutex_t* mutex)
-{
-  pthread_mutex_t mx = *mutex;
-  int result = 0;
-
-  /*
-   * Let the system deal with invalid pointers.
-   */
-  if (mx == NULL)
-    {
-      return EINVAL;
-    }
-
-  if (mx->kind >= 0
-        || (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT != PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
-                                                (PTW32_INTERLOCKED_LONGPTR)&mx->robustNode->stateInconsistent,
-                                                (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_CONSISTENT,
-                                                (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT))
-    {
-      result = EINVAL;
-    }
-
-  return (result);
-}
-
diff --git a/deps/w32-pthreads/pthread_mutex_destroy.c b/deps/w32-pthreads/pthread_mutex_destroy.c
deleted file mode 100644
index 93588ed..0000000
--- a/deps/w32-pthreads/pthread_mutex_destroy.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * pthread_mutex_destroy.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutex_destroy (pthread_mutex_t * mutex)
-{
-  int result = 0;
-  pthread_mutex_t mx;
-
-  /*
-   * Let the system deal with invalid pointers.
-   */
-
-  /*
-   * Check to see if we have something to delete.
-   */
-  if (*mutex < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
-    {
-      mx = *mutex;
-
-      result = pthread_mutex_trylock (&mx);
-
-      /*
-       * If trylock succeeded and the mutex is not recursively locked it
-       * can be destroyed.
-       */
-      if (0 == result || ENOTRECOVERABLE == result)
-	{
-	  if (mx->kind != PTHREAD_MUTEX_RECURSIVE || 1 == mx->recursive_count)
-	    {
-	      /*
-	       * FIXME!!!
-	       * The mutex isn't held by another thread but we could still
-	       * be too late invalidating the mutex below since another thread
-	       * may already have entered mutex_lock and the check for a valid
-	       * *mutex != NULL.
-	       */
-	      *mutex = NULL;
-
-	      result = (0 == result)?pthread_mutex_unlock(&mx):0;
-
-	      if (0 == result)
-		{
-                  if (mx->robustNode != NULL)
-                    {
-                      free(mx->robustNode);
-                    }
-		  if (!CloseHandle (mx->event))
-		    {
-		      *mutex = mx;
-		      result = EINVAL;
-		    }
-		  else
-		    {
-		      free (mx);
-		    }
-		}
-	      else
-		{
-		  /*
-		   * Restore the mutex before we return the error.
-		   */
-		  *mutex = mx;
-		}
-	    }
-	  else			/* mx->recursive_count > 1 */
-	    {
-	      /*
-	       * The mutex must be recursive and already locked by us (this thread).
-	       */
-	      mx->recursive_count--;	/* Undo effect of pthread_mutex_trylock() above */
-	      result = EBUSY;
-	    }
-	}
-    }
-  else
-    {
-      ptw32_mcs_local_node_t node;
-
-      /*
-       * See notes in ptw32_mutex_check_need_init() above also.
-       */
-
-      ptw32_mcs_lock_acquire(&ptw32_mutex_test_init_lock, &node);
-
-      /*
-       * Check again.
-       */
-      if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
-	{
-	  /*
-	   * This is all we need to do to destroy a statically
-	   * initialised mutex that has not yet been used (initialised).
-	   * If we get to here, another thread
-	   * waiting to initialise this mutex will get an EINVAL.
-	   */
-	  *mutex = NULL;
-	}
-      else
-	{
-	  /*
-	   * The mutex has been initialised while we were waiting
-	   * so assume it's in use.
-	   */
-	  result = EBUSY;
-	}
-      ptw32_mcs_lock_release(&node);
-    }
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_mutex_init.c b/deps/w32-pthreads/pthread_mutex_init.c
deleted file mode 100644
index 52ea956..0000000
--- a/deps/w32-pthreads/pthread_mutex_init.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * pthread_mutex_init.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr)
-{
-  int result = 0;
-  pthread_mutex_t mx;
-
-  if (mutex == NULL)
-    {
-      return EINVAL;
-    }
-
-  if (attr != NULL && *attr != NULL)
-    {
-      if ((*attr)->pshared == PTHREAD_PROCESS_SHARED)
-        {
-          /*
-           * Creating mutex that can be shared between
-           * processes.
-           */
-#if _POSIX_THREAD_PROCESS_SHARED >= 0
-
-          /*
-           * Not implemented yet.
-           */
-
-#error ERROR [__FILE__, line __LINE__]: Process shared mutexes are not supported yet.
-
-#else
-
-          return ENOSYS;
-
-#endif /* _POSIX_THREAD_PROCESS_SHARED */
-        }
-    }
-
-  mx = (pthread_mutex_t) calloc (1, sizeof (*mx));
-
-  if (mx == NULL)
-    {
-      result = ENOMEM;
-    }
-  else
-    {
-      mx->lock_idx = 0;
-      mx->recursive_count = 0;
-      mx->robustNode = NULL;
-      if (attr == NULL || *attr == NULL)
-        {
-          mx->kind = PTHREAD_MUTEX_DEFAULT;
-        }
-      else
-        {
-          mx->kind = (*attr)->kind;
-          if ((*attr)->robustness == PTHREAD_MUTEX_ROBUST)
-            {
-              /*
-               * Use the negative range to represent robust types.
-               * Replaces a memory fetch with a register negate and incr
-               * in pthread_mutex_lock etc.
-               *
-               * Map 0,1,..,n to -1,-2,..,(-n)-1
-               */
-              mx->kind = -mx->kind - 1;
-
-              mx->robustNode = (ptw32_robust_node_t*) malloc(sizeof(ptw32_robust_node_t));
-              mx->robustNode->stateInconsistent = PTW32_ROBUST_CONSISTENT;
-              mx->robustNode->mx = mx;
-              mx->robustNode->next = NULL;
-              mx->robustNode->prev = NULL;
-            }
-        }
-
-      mx->ownerThread.p = NULL;
-
-      mx->event = CreateEvent (NULL, PTW32_FALSE,    /* manual reset = No */
-                              PTW32_FALSE,           /* initial state = not signaled */
-                              NULL);                 /* event name */
-
-      if (0 == mx->event)
-        {
-          result = ENOSPC;
-          free (mx);
-          mx = NULL;
-        }
-    }
-
-  *mutex = mx;
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_mutex_lock.c b/deps/w32-pthreads/pthread_mutex_lock.c
deleted file mode 100644
index a222172..0000000
--- a/deps/w32-pthreads/pthread_mutex_lock.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * pthread_mutex_lock.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#if !defined(_UWIN)
-/*#   include <process.h> */
-#endif
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_mutex_lock (pthread_mutex_t * mutex)
-{
-  int kind;
-  pthread_mutex_t mx;
-  int result = 0;
-
-  /*
-   * Let the system deal with invalid pointers.
-   */
-  if (*mutex == NULL)
-    {
-      return EINVAL;
-    }
-
-  /*
-   * We do a quick check to see if we need to do more work
-   * to initialise a static mutex. We check
-   * again inside the guarded section of ptw32_mutex_check_need_init()
-   * to avoid race conditions.
-   */
-  if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
-    {
-      if ((result = ptw32_mutex_check_need_init (mutex)) != 0)
-	{
-	  return (result);
-	}
-    }
-
-  mx = *mutex;
-  kind = mx->kind;
-
-  if (kind >= 0)
-    {
-      /* Non-robust */
-      if (PTHREAD_MUTEX_NORMAL == kind)
-        {
-          if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-		       (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-		       (PTW32_INTERLOCKED_LONG) 1) != 0)
-	    {
-	      while ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-                              (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-			      (PTW32_INTERLOCKED_LONG) -1) != 0)
-	        {
-	          if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
-	            {
-	              result = EINVAL;
-		      break;
-	            }
-	        }
-	    }
-        }
-      else
-        {
-          pthread_t self = pthread_self();
-
-          if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
-                       (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-		       (PTW32_INTERLOCKED_LONG) 1,
-		       (PTW32_INTERLOCKED_LONG) 0) == 0)
-	    {
-	      mx->recursive_count = 1;
-	      mx->ownerThread = self;
-	    }
-          else
-	    {
-	      if (pthread_equal (mx->ownerThread, self))
-	        {
-	          if (kind == PTHREAD_MUTEX_RECURSIVE)
-		    {
-		      mx->recursive_count++;
-		    }
-	          else
-		    {
-		      result = EDEADLK;
-		    }
-	        }
-	      else
-	        {
-	          while ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-                                  (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-			          (PTW32_INTERLOCKED_LONG) -1) != 0)
-		    {
-	              if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
-		        {
-	                  result = EINVAL;
-		          break;
-		        }
-		    }
-
-	          if (0 == result)
-		    {
-		      mx->recursive_count = 1;
-		      mx->ownerThread = self;
-		    }
-	        }
-	    }
-        }
-    }
-  else
-    {
-      /*
-       * Robust types
-       * All types record the current owner thread.
-       * The mutex is added to a per thread list when ownership is acquired.
-       */
-      ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent;
-
-      if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
-                                                 (PTW32_INTERLOCKED_LONGPTR)statePtr,
-                                                 (PTW32_INTERLOCKED_LONG)0))
-        {
-          result = ENOTRECOVERABLE;
-        }
-      else
-        {
-          pthread_t self = pthread_self();
-
-          kind = -kind - 1; /* Convert to non-robust range */
-    
-          if (PTHREAD_MUTEX_NORMAL == kind)
-            {
-              if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-                           (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-                           (PTW32_INTERLOCKED_LONG) 1) != 0)
-                {
-                  while (0 == (result = ptw32_robust_mutex_inherit(mutex))
-                           && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-                                       (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-                                       (PTW32_INTERLOCKED_LONG) -1) != 0)
-                    {
-                      if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
-                        {
-                          result = EINVAL;
-                          break;
-                        }
-                      if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE ==
-                                  PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
-                                    (PTW32_INTERLOCKED_LONGPTR)statePtr,
-                                    (PTW32_INTERLOCKED_LONG)0))
-                        {
-                          /* Unblock the next thread */
-                          SetEvent(mx->event);
-                          result = ENOTRECOVERABLE;
-                          break;
-                        }
-                    }
-                }
-              if (0 == result || EOWNERDEAD == result)
-                {
-                  /*
-                   * Add mutex to the per-thread robust mutex currently-held list.
-                   * If the thread terminates, all mutexes in this list will be unlocked.
-                   */
-                  ptw32_robust_mutex_add(mutex, self);
-                }
-            }
-          else
-            {
-              if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
-                           (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-                           (PTW32_INTERLOCKED_LONG) 1,
-                           (PTW32_INTERLOCKED_LONG) 0) == 0)
-                {
-                  mx->recursive_count = 1;
-                  /*
-                   * Add mutex to the per-thread robust mutex currently-held list.
-                   * If the thread terminates, all mutexes in this list will be unlocked.
-                   */
-                  ptw32_robust_mutex_add(mutex, self);
-                }
-              else
-                {
-                  if (pthread_equal (mx->ownerThread, self))
-                    {
-                      if (PTHREAD_MUTEX_RECURSIVE == kind)
-                        {
-                          mx->recursive_count++;
-                        }
-                      else
-                        {
-                          result = EDEADLK;
-                        }
-                    }
-                  else
-                    {
-                      while (0 == (result = ptw32_robust_mutex_inherit(mutex))
-                               && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-                                           (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-                                           (PTW32_INTERLOCKED_LONG) -1) != 0)
-                        {
-                          if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
-                            {
-                              result = EINVAL;
-                              break;
-                            }
-                          if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE ==
-                                      PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
-                                        (PTW32_INTERLOCKED_LONGPTR)statePtr,
-                                        (PTW32_INTERLOCKED_LONG)0))
-                            {
-                              /* Unblock the next thread */
-                              SetEvent(mx->event);
-                              result = ENOTRECOVERABLE;
-                              break;
-                            }
-                        }
-
-                      if (0 == result || EOWNERDEAD == result)
-                        {
-                          mx->recursive_count = 1;
-                          /*
-                           * Add mutex to the per-thread robust mutex currently-held list.
-                           * If the thread terminates, all mutexes in this list will be unlocked.
-                           */
-                          ptw32_robust_mutex_add(mutex, self);
-                        }
-                    }
-	        }
-            }
-        }
-    }
-
-  return (result);
-}
-
diff --git a/deps/w32-pthreads/pthread_mutex_timedlock.c b/deps/w32-pthreads/pthread_mutex_timedlock.c
deleted file mode 100644
index 398ced8..0000000
--- a/deps/w32-pthreads/pthread_mutex_timedlock.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * pthread_mutex_timedlock.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-static INLINE int
-ptw32_timed_eventwait (HANDLE event, const struct timespec *abstime)
-     /*
-      * ------------------------------------------------------
-      * DESCRIPTION
-      *      This function waits on an event until signaled or until
-      *      abstime passes.
-      *      If abstime has passed when this routine is called then
-      *      it returns a result to indicate this.
-      *
-      *      If 'abstime' is a NULL pointer then this function will
-      *      block until it can successfully decrease the value or
-      *      until interrupted by a signal.
-      *
-      *      This routine is not a cancelation point.
-      *
-      * RESULTS
-      *              0               successfully signaled,
-      *              ETIMEDOUT       abstime passed
-      *              EINVAL          'event' is not a valid event,
-      *
-      * ------------------------------------------------------
-      */
-{
-
-  DWORD milliseconds;
-  DWORD status;
-
-  if (event == NULL)
-    {
-      return EINVAL;
-    }
-  else
-    {
-      if (abstime == NULL)
-	{
-	  milliseconds = INFINITE;
-	}
-      else
-	{
-	  /* 
-	   * Calculate timeout as milliseconds from current system time. 
-	   */
-	  milliseconds = ptw32_relmillisecs (abstime);
-	}
-
-      status = WaitForSingleObject (event, milliseconds);
-
-      if (status == WAIT_OBJECT_0)
-	{
-	  return 0;
-	}
-      else if (status == WAIT_TIMEOUT)
-	{
-	  return ETIMEDOUT;
-	}
-      else
-	{
-	  return EINVAL;
-	}
-    }
-
-  return 0;
-
-}				/* ptw32_timed_semwait */
-
-
-int
-pthread_mutex_timedlock (pthread_mutex_t * mutex,
-			 const struct timespec *abstime)
-{
-  pthread_mutex_t mx;
-  int kind;
-  int result = 0;
-
-  /*
-   * Let the system deal with invalid pointers.
-   */
-
-  /*
-   * We do a quick check to see if we need to do more work
-   * to initialise a static mutex. We check
-   * again inside the guarded section of ptw32_mutex_check_need_init()
-   * to avoid race conditions.
-   */
-  if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
-    {
-      if ((result = ptw32_mutex_check_need_init (mutex)) != 0)
-	{
-	  return (result);
-	}
-    }
-
-  mx = *mutex;
-  kind = mx->kind;
-
-  if (kind >= 0)
-    {
-      if (mx->kind == PTHREAD_MUTEX_NORMAL)
-        {
-          if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-		       (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-		       (PTW32_INTERLOCKED_LONG) 1) != 0)
-	    {
-              while ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-                              (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-			      (PTW32_INTERLOCKED_LONG) -1) != 0)
-                {
-	          if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
-		    {
-		      return result;
-		    }
-	        }
-	    }
-        }
-      else
-        {
-          pthread_t self = pthread_self();
-
-          if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
-                       (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-		       (PTW32_INTERLOCKED_LONG) 1,
-		       (PTW32_INTERLOCKED_LONG) 0) == 0)
-	    {
-	      mx->recursive_count = 1;
-	      mx->ownerThread = self;
-	    }
-          else
-	    {
-	      if (pthread_equal (mx->ownerThread, self))
-	        {
-	          if (mx->kind == PTHREAD_MUTEX_RECURSIVE)
-		    {
-		      mx->recursive_count++;
-		    }
-	          else
-		    {
-		      return EDEADLK;
-		    }
-	        }
-	      else
-	        {
-                  while ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-                                  (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-			          (PTW32_INTERLOCKED_LONG) -1) != 0)
-                    {
-		      if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
-		        {
-		          return result;
-		        }
-		    }
-
-	          mx->recursive_count = 1;
-	          mx->ownerThread = self;
-	        }
-	    }
-        }
-    }
-  else
-    {
-      /*
-       * Robust types
-       * All types record the current owner thread.
-       * The mutex is added to a per thread list when ownership is acquired.
-       */
-      ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent;
-
-      if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
-                                                 (PTW32_INTERLOCKED_LONGPTR)statePtr,
-                                                 (PTW32_INTERLOCKED_LONG)0))
-        {
-          result = ENOTRECOVERABLE;
-        }
-      else
-        {
-          pthread_t self = pthread_self();
-
-          kind = -kind - 1; /* Convert to non-robust range */
-
-          if (PTHREAD_MUTEX_NORMAL == kind)
-            {
-              if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-		           (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-		           (PTW32_INTERLOCKED_LONG) 1) != 0)
-	        {
-                  while (0 == (result = ptw32_robust_mutex_inherit(mutex))
-                           && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-                                  (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-			          (PTW32_INTERLOCKED_LONG) -1) != 0)
-                    {
-	              if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
-		        {
-		          return result;
-		        }
-                      if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE ==
-                                  PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
-                                    (PTW32_INTERLOCKED_LONGPTR)statePtr,
-                                    (PTW32_INTERLOCKED_LONG)0))
-                        {
-                          /* Unblock the next thread */
-                          SetEvent(mx->event);
-                          result = ENOTRECOVERABLE;
-                          break;
-                        }
-	            }
-
-                  if (0 == result || EOWNERDEAD == result)
-                    {
-                      /*
-                       * Add mutex to the per-thread robust mutex currently-held list.
-                       * If the thread terminates, all mutexes in this list will be unlocked.
-                       */
-                      ptw32_robust_mutex_add(mutex, self);
-                    }
-	        }
-            }
-          else
-            {
-              pthread_t self = pthread_self();
-
-              if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
-                           (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-		           (PTW32_INTERLOCKED_LONG) 1,
-		           (PTW32_INTERLOCKED_LONG) 0))
-	        {
-	          mx->recursive_count = 1;
-                  /*
-                   * Add mutex to the per-thread robust mutex currently-held list.
-                   * If the thread terminates, all mutexes in this list will be unlocked.
-                   */
-                  ptw32_robust_mutex_add(mutex, self);
-	        }
-              else
-	        {
-	          if (pthread_equal (mx->ownerThread, self))
-	            {
-	              if (PTHREAD_MUTEX_RECURSIVE == kind)
-		        {
-		          mx->recursive_count++;
-		        }
-	              else
-		        {
-		          return EDEADLK;
-		        }
-	            }
-	          else
-	            {
-                      while (0 == (result = ptw32_robust_mutex_inherit(mutex))
-                               && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
-                                          (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-			                  (PTW32_INTERLOCKED_LONG) -1) != 0)
-                        {
-		          if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
-		            {
-		              return result;
-		            }
-		        }
-
-                      if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE ==
-                                  PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
-                                    (PTW32_INTERLOCKED_LONGPTR)statePtr,
-                                    (PTW32_INTERLOCKED_LONG)0))
-                        {
-                          /* Unblock the next thread */
-                          SetEvent(mx->event);
-                          result = ENOTRECOVERABLE;
-                        }
-                      else if (0 == result || EOWNERDEAD == result)
-                        {
-                          mx->recursive_count = 1;
-                          /*
-                           * Add mutex to the per-thread robust mutex currently-held list.
-                           * If the thread terminates, all mutexes in this list will be unlocked.
-                           */
-                          ptw32_robust_mutex_add(mutex, self);
-                        }
-	            }
-	        }
-            }
-        }
-    }
-
-  return result;
-}
diff --git a/deps/w32-pthreads/pthread_mutex_trylock.c b/deps/w32-pthreads/pthread_mutex_trylock.c
deleted file mode 100644
index 7dd9c3f..0000000
--- a/deps/w32-pthreads/pthread_mutex_trylock.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * pthread_mutex_trylock.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutex_trylock (pthread_mutex_t * mutex)
-{
-  pthread_mutex_t mx;
-  int kind;
-  int result = 0;
-
-  /*
-   * Let the system deal with invalid pointers.
-   */
-
-  /*
-   * We do a quick check to see if we need to do more work
-   * to initialise a static mutex. We check
-   * again inside the guarded section of ptw32_mutex_check_need_init()
-   * to avoid race conditions.
-   */
-  if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
-    {
-      if ((result = ptw32_mutex_check_need_init (mutex)) != 0)
-	{
-	  return (result);
-	}
-    }
-
-  mx = *mutex;
-  kind = mx->kind;
-
-  if (kind >= 0)
-    {
-      /* Non-robust */
-      if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG (
-		         (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-		         (PTW32_INTERLOCKED_LONG) 1,
-		         (PTW32_INTERLOCKED_LONG) 0))
-        {
-          if (kind != PTHREAD_MUTEX_NORMAL)
-	    {
-	      mx->recursive_count = 1;
-	      mx->ownerThread = pthread_self ();
-	    }
-        }
-      else
-        {
-          if (kind == PTHREAD_MUTEX_RECURSIVE &&
-	      pthread_equal (mx->ownerThread, pthread_self ()))
-	    {
-	      mx->recursive_count++;
-	    }
-          else
-	    {
-	      result = EBUSY;
-	    }
-        }
-    }
-  else
-    {
-      /*
-       * Robust types
-       * All types record the current owner thread.
-       * The mutex is added to a per thread list when ownership is acquired.
-       */
-      pthread_t self;
-      ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent;
-
-      if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE ==
-                  PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
-                    (PTW32_INTERLOCKED_LONGPTR)statePtr,
-                    (PTW32_INTERLOCKED_LONG)0))
-        {
-          return ENOTRECOVERABLE;
-        }
-
-      self = pthread_self();
-      kind = -kind - 1; /* Convert to non-robust range */
-
-      if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG (
-        	         (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-        	         (PTW32_INTERLOCKED_LONG) 1,
-        	         (PTW32_INTERLOCKED_LONG) 0))
-        {
-          if (kind != PTHREAD_MUTEX_NORMAL)
-            {
-              mx->recursive_count = 1;
-            }
-          ptw32_robust_mutex_add(mutex, self);
-        }
-      else
-        {
-          if (PTHREAD_MUTEX_RECURSIVE == kind &&
-              pthread_equal (mx->ownerThread, pthread_self ()))
-            {
-              mx->recursive_count++;
-            }
-          else
-            {
-              if (EOWNERDEAD == (result = ptw32_robust_mutex_inherit(mutex)))
-                {
-                  mx->recursive_count = 1;
-                  ptw32_robust_mutex_add(mutex, self);
-                }
-              else
-                {
-                  if (0 == result)
-                    { 
-	              result = EBUSY;
-                    }
-                }
-	    }
-        }
-    }
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_mutex_unlock.c b/deps/w32-pthreads/pthread_mutex_unlock.c
deleted file mode 100644
index 66b375a..0000000
--- a/deps/w32-pthreads/pthread_mutex_unlock.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * pthread_mutex_unlock.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutex_unlock (pthread_mutex_t * mutex)
-{
-  int result = 0;
-  int kind;
-  pthread_mutex_t mx;
-
-  /*
-   * Let the system deal with invalid pointers.
-   */
-
-  mx = *mutex;
-
-  /*
-   * If the thread calling us holds the mutex then there is no
-   * race condition. If another thread holds the
-   * lock then we shouldn't be in here.
-   */
-  if (mx < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
-    {
-      kind = mx->kind;
-
-      if (kind >= 0)
-        {
-          if (kind == PTHREAD_MUTEX_NORMAL)
-	    {
-	      LONG idx;
-
-	      idx = (LONG) PTW32_INTERLOCKED_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR)&mx->lock_idx,
-							    (PTW32_INTERLOCKED_LONG)0);
-	      if (idx != 0)
-	        {
-	          if (idx < 0)
-		    {
-		      /*
-		       * Someone may be waiting on that mutex.
-		       */
-		      if (SetEvent (mx->event) == 0)
-		        {
-		          result = EINVAL;
-		        }
-		    }
-	        }
-	    }
-          else
-	    {
-	      if (pthread_equal (mx->ownerThread, pthread_self()))
-	        {
-	          if (kind != PTHREAD_MUTEX_RECURSIVE
-		      || 0 == --mx->recursive_count)
-		    {
-		      mx->ownerThread.p = NULL;
-
-		      if ((LONG) PTW32_INTERLOCKED_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR)&mx->lock_idx,
-							          (PTW32_INTERLOCKED_LONG)0) < 0L)
-		        {
-		          /* Someone may be waiting on that mutex */
-		          if (SetEvent (mx->event) == 0)
-			    {
-			      result = EINVAL;
-			    }
-		        }
-		    }
-	        }
-	      else
-	        {
-	          result = EPERM;
-	        }
-	    }
-        }
-      else
-        {
-          /* Robust types */
-          pthread_t self = pthread_self();
-          kind = -kind - 1; /* Convert to non-robust range */
-
-          /*
-           * The thread must own the lock regardless of type if the mutex
-           * is robust.
-           */
-          if (pthread_equal (mx->ownerThread, self))
-            {
-              PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG((PTW32_INTERLOCKED_LONGPTR) &mx->robustNode->stateInconsistent,
-                                                      (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE,
-                                                      (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT);
-              if (PTHREAD_MUTEX_NORMAL == kind)
-                {
-                  ptw32_robust_mutex_remove(mutex, NULL);
-
-                  if ((LONG) PTW32_INTERLOCKED_EXCHANGE_LONG((PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-                                                             (PTW32_INTERLOCKED_LONG) 0) < 0)
-                    {
-                      /*
-                       * Someone may be waiting on that mutex.
-                       */
-                      if (SetEvent (mx->event) == 0)
-                        {
-                          result = EINVAL;
-                        }
-                    }
-                }
-              else
-                {
-                  if (kind != PTHREAD_MUTEX_RECURSIVE
-                      || 0 == --mx->recursive_count)
-                    {
-                      ptw32_robust_mutex_remove(mutex, NULL);
-
-                      if ((LONG) PTW32_INTERLOCKED_EXCHANGE_LONG((PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
-                                                                 (PTW32_INTERLOCKED_LONG) 0) < 0)
-                        {
-                          /*
-                           * Someone may be waiting on that mutex.
-                           */
-                          if (SetEvent (mx->event) == 0)
-                            {
-                              result = EINVAL;
-                            }
-                        }
-                    }
-                }
-            }
-          else
-            {
-              result = EPERM;
-            }
-        }
-    }
-  else if (mx != PTHREAD_MUTEX_INITIALIZER)
-    {
-      result = EINVAL;
-    }
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_mutexattr_destroy.c b/deps/w32-pthreads/pthread_mutexattr_destroy.c
deleted file mode 100644
index 0cdec0f..0000000
--- a/deps/w32-pthreads/pthread_mutexattr_destroy.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * pthread_mutexattr_destroy.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutexattr_destroy (pthread_mutexattr_t * attr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Destroys a mutex attributes object. The object can
-      *      no longer be used.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_mutexattr_t
-      *
-      *
-      * DESCRIPTION
-      *      Destroys a mutex attributes object. The object can
-      *      no longer be used.
-      *
-      *      NOTES:
-      *              1)      Does not affect mutexes created using 'attr'
-      *
-      * RESULTS
-      *              0               successfully released attr,
-      *              EINVAL          'attr' is invalid.
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-
-  if (attr == NULL || *attr == NULL)
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      pthread_mutexattr_t ma = *attr;
-
-      *attr = NULL;
-      free (ma);
-    }
-
-  return (result);
-}				/* pthread_mutexattr_destroy */
diff --git a/deps/w32-pthreads/pthread_mutexattr_getkind_np.c b/deps/w32-pthreads/pthread_mutexattr_getkind_np.c
deleted file mode 100644
index 753b36f..0000000
--- a/deps/w32-pthreads/pthread_mutexattr_getkind_np.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * pthread_mutexattr_getkind_np.c
- *
- * Description:
- * This translation unit implements non-portable thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_mutexattr_getkind_np (pthread_mutexattr_t * attr, int *kind)
-{
-  return pthread_mutexattr_gettype (attr, kind);
-}
diff --git a/deps/w32-pthreads/pthread_mutexattr_getpshared.c b/deps/w32-pthreads/pthread_mutexattr_getpshared.c
deleted file mode 100644
index 4752110..0000000
--- a/deps/w32-pthreads/pthread_mutexattr_getpshared.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * pthread_mutexattr_getpshared.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutexattr_getpshared (const pthread_mutexattr_t * attr, int *pshared)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Determine whether mutexes created with 'attr' can be
-      *      shared between processes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_mutexattr_t
-      *
-      *      pshared
-      *              will be set to one of:
-      *
-      *                      PTHREAD_PROCESS_SHARED
-      *                              May be shared if in shared memory
-      *
-      *                      PTHREAD_PROCESS_PRIVATE
-      *                              Cannot be shared.
-      *
-      *
-      * DESCRIPTION
-      *      Mutexes creatd with 'attr' can be shared between
-      *      processes if pthread_mutex_t variable is allocated
-      *      in memory shared by these processes.
-      *      NOTES:
-      *              1)      pshared mutexes MUST be allocated in shared
-      *                      memory.
-      *              2)      The following macro is defined if shared mutexes
-      *                      are supported:
-      *                              _POSIX_THREAD_PROCESS_SHARED
-      *
-      * RESULTS
-      *              0               successfully retrieved attribute,
-      *              EINVAL          'attr' is invalid,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-
-  if ((attr != NULL && *attr != NULL) && (pshared != NULL))
-    {
-      *pshared = (*attr)->pshared;
-      result = 0;
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  return (result);
-
-}				/* pthread_mutexattr_getpshared */
diff --git a/deps/w32-pthreads/pthread_mutexattr_getrobust.c b/deps/w32-pthreads/pthread_mutexattr_getrobust.c
deleted file mode 100644
index a4b7550..0000000
--- a/deps/w32-pthreads/pthread_mutexattr_getrobust.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * pthread_mutexattr_getrobust.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutexattr_getrobust (const pthread_mutexattr_t * attr, int * robust)
-     /*
-      * ------------------------------------------------------
-      *
-      * DOCPUBLIC
-      * The pthread_mutexattr_setrobust() and
-      * pthread_mutexattr_getrobust() functions  respectively set and
-      * get the mutex robust  attribute. This attribute is set in  the
-      * robust parameter to these functions.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_mutexattr_t
-      *
-      *     robust 
-      *              must be one of:
-      *
-      *                      PTHREAD_MUTEX_STALLED
-      *
-      *                      PTHREAD_MUTEX_ROBUST
-      *
-      * DESCRIPTION
-      * The pthread_mutexattr_setrobust() and
-      * pthread_mutexattr_getrobust() functions  respectively set and
-      * get the mutex robust  attribute. This attribute is set in  the
-      * robust  parameter to these functions. The default value of the
-      * robust  attribute is  PTHREAD_MUTEX_STALLED.
-      * 
-      * The robustness of mutex is contained in the robustness attribute
-      * of the mutex attributes. Valid mutex robustness values are:
-      *
-      * PTHREAD_MUTEX_STALLED
-      * No special actions are taken if the owner of the mutex is
-      * terminated while holding the mutex lock. This can lead to
-      * deadlocks if no other thread can unlock the mutex.
-      * This is the default value.
-      * 
-      * PTHREAD_MUTEX_ROBUST
-      * If the process containing the owning thread of a robust mutex
-      * terminates while holding the mutex lock, the next thread that
-      * acquires the mutex shall be notified about the termination by
-      * the return value [EOWNERDEAD] from the locking function. If the
-      * owning thread of a robust mutex terminates while holding the mutex
-      * lock, the next thread that acquires the mutex may be notified
-      * about the termination by the return value [EOWNERDEAD]. The
-      * notified thread can then attempt to mark the state protected by
-      * the mutex as consistent again by a call to
-      * pthread_mutex_consistent(). After a subsequent successful call to
-      * pthread_mutex_unlock(), the mutex lock shall be released and can
-      * be used normally by other threads. If the mutex is unlocked without
-      * a call to pthread_mutex_consistent(), it shall be in a permanently
-      * unusable state and all attempts to lock the mutex shall fail with
-      * the error [ENOTRECOVERABLE]. The only permissible operation on such
-      * a mutex is pthread_mutex_destroy().
-      *
-      * RESULTS
-      *              0               successfully set attribute,
-      *              EINVAL          'attr' or 'robust' is invalid,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = EINVAL;
-
-  if ((attr != NULL && *attr != NULL && robust != NULL))
-    {
-      *robust = (*attr)->robustness;
-      result = 0;
-    }
-
-  return (result);
-}				/* pthread_mutexattr_getrobust */
diff --git a/deps/w32-pthreads/pthread_mutexattr_gettype.c b/deps/w32-pthreads/pthread_mutexattr_gettype.c
deleted file mode 100644
index 817ab69..0000000
--- a/deps/w32-pthreads/pthread_mutexattr_gettype.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * pthread_mutexattr_gettype.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind)
-{
-  int result = 0;
-
-  if (attr != NULL && *attr != NULL && kind != NULL)
-    {
-      *kind = (*attr)->kind;
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_mutexattr_init.c b/deps/w32-pthreads/pthread_mutexattr_init.c
deleted file mode 100644
index f6960f4..0000000
--- a/deps/w32-pthreads/pthread_mutexattr_init.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * pthread_mutexattr_init.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutexattr_init (pthread_mutexattr_t * attr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Initializes a mutex attributes object with default
-      *      attributes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_mutexattr_t
-      *
-      *
-      * DESCRIPTION
-      *      Initializes a mutex attributes object with default
-      *      attributes.
-      *
-      *      NOTES:
-      *              1)      Used to define mutex types
-      *
-      * RESULTS
-      *              0               successfully initialized attr,
-      *              ENOMEM          insufficient memory for attr.
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  pthread_mutexattr_t ma;
-
-  ma = (pthread_mutexattr_t) calloc (1, sizeof (*ma));
-
-  if (ma == NULL)
-    {
-      result = ENOMEM;
-    }
-  else
-    {
-      ma->pshared = PTHREAD_PROCESS_PRIVATE;
-      ma->kind = PTHREAD_MUTEX_DEFAULT;
-    }
-
-  *attr = ma;
-
-  return (result);
-}				/* pthread_mutexattr_init */
diff --git a/deps/w32-pthreads/pthread_mutexattr_setkind_np.c b/deps/w32-pthreads/pthread_mutexattr_setkind_np.c
deleted file mode 100644
index 06bb92d..0000000
--- a/deps/w32-pthreads/pthread_mutexattr_setkind_np.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * pthread_mutexattr_setkind_np.c
- *
- * Description:
- * This translation unit implements non-portable thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_mutexattr_setkind_np (pthread_mutexattr_t * attr, int kind)
-{
-  return pthread_mutexattr_settype (attr, kind);
-}
diff --git a/deps/w32-pthreads/pthread_mutexattr_setpshared.c b/deps/w32-pthreads/pthread_mutexattr_setpshared.c
deleted file mode 100644
index 09e750b..0000000
--- a/deps/w32-pthreads/pthread_mutexattr_setpshared.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * pthread_mutexattr_setpshared.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, int pshared)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Mutexes created with 'attr' can be shared between
-      *      processes if pthread_mutex_t variable is allocated
-      *      in memory shared by these processes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_mutexattr_t
-      *
-      *      pshared
-      *              must be one of:
-      *
-      *                      PTHREAD_PROCESS_SHARED
-      *                              May be shared if in shared memory
-      *
-      *                      PTHREAD_PROCESS_PRIVATE
-      *                              Cannot be shared.
-      *
-      * DESCRIPTION
-      *      Mutexes creatd with 'attr' can be shared between
-      *      processes if pthread_mutex_t variable is allocated
-      *      in memory shared by these processes.
-      *
-      *      NOTES:
-      *              1)      pshared mutexes MUST be allocated in shared
-      *                      memory.
-      *
-      *              2)      The following macro is defined if shared mutexes
-      *                      are supported:
-      *                              _POSIX_THREAD_PROCESS_SHARED
-      *
-      * RESULTS
-      *              0               successfully set attribute,
-      *              EINVAL          'attr' or pshared is invalid,
-      *              ENOSYS          PTHREAD_PROCESS_SHARED not supported,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-
-  if ((attr != NULL && *attr != NULL) &&
-      ((pshared == PTHREAD_PROCESS_SHARED) ||
-       (pshared == PTHREAD_PROCESS_PRIVATE)))
-    {
-      if (pshared == PTHREAD_PROCESS_SHARED)
-	{
-
-#if !defined( _POSIX_THREAD_PROCESS_SHARED )
-
-	  result = ENOSYS;
-	  pshared = PTHREAD_PROCESS_PRIVATE;
-
-#else
-
-	  result = 0;
-
-#endif /* _POSIX_THREAD_PROCESS_SHARED */
-
-	}
-      else
-	{
-	  result = 0;
-	}
-
-      (*attr)->pshared = pshared;
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  return (result);
-
-}				/* pthread_mutexattr_setpshared */
diff --git a/deps/w32-pthreads/pthread_mutexattr_setrobust.c b/deps/w32-pthreads/pthread_mutexattr_setrobust.c
deleted file mode 100644
index f55a333..0000000
--- a/deps/w32-pthreads/pthread_mutexattr_setrobust.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * pthread_mutexattr_setrobust.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutexattr_setrobust (pthread_mutexattr_t * attr, int robust)
-     /*
-      * ------------------------------------------------------
-      *
-      * DOCPUBLIC
-      * The pthread_mutexattr_setrobust() and
-      * pthread_mutexattr_getrobust() functions  respectively set and
-      * get the mutex robust  attribute. This attribute is set in  the
-      * robust parameter to these functions.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_mutexattr_t
-      *
-      *     robust 
-      *              must be one of:
-      *
-      *                      PTHREAD_MUTEX_STALLED
-      *
-      *                      PTHREAD_MUTEX_ROBUST
-      *
-      * DESCRIPTION
-      * The pthread_mutexattr_setrobust() and
-      * pthread_mutexattr_getrobust() functions  respectively set and
-      * get the mutex robust  attribute. This attribute is set in  the
-      * robust  parameter to these functions. The default value of the
-      * robust  attribute is  PTHREAD_MUTEX_STALLED.
-      * 
-      * The robustness of mutex is contained in the robustness attribute
-      * of the mutex attributes. Valid mutex robustness values are:
-      *
-      * PTHREAD_MUTEX_STALLED
-      * No special actions are taken if the owner of the mutex is
-      * terminated while holding the mutex lock. This can lead to
-      * deadlocks if no other thread can unlock the mutex.
-      * This is the default value.
-      * 
-      * PTHREAD_MUTEX_ROBUST
-      * If the process containing the owning thread of a robust mutex
-      * terminates while holding the mutex lock, the next thread that
-      * acquires the mutex shall be notified about the termination by
-      * the return value [EOWNERDEAD] from the locking function. If the
-      * owning thread of a robust mutex terminates while holding the mutex
-      * lock, the next thread that acquires the mutex may be notified
-      * about the termination by the return value [EOWNERDEAD]. The
-      * notified thread can then attempt to mark the state protected by
-      * the mutex as consistent again by a call to
-      * pthread_mutex_consistent(). After a subsequent successful call to
-      * pthread_mutex_unlock(), the mutex lock shall be released and can
-      * be used normally by other threads. If the mutex is unlocked without
-      * a call to pthread_mutex_consistent(), it shall be in a permanently
-      * unusable state and all attempts to lock the mutex shall fail with
-      * the error [ENOTRECOVERABLE]. The only permissible operation on such
-      * a mutex is pthread_mutex_destroy().
-      *
-      * RESULTS
-      *              0               successfully set attribute,
-      *              EINVAL          'attr' or 'robust' is invalid,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = EINVAL;
-
-  if ((attr != NULL && *attr != NULL))
-    {
-      switch (robust)
-        {
-          case PTHREAD_MUTEX_STALLED:
-          case PTHREAD_MUTEX_ROBUST:
-	    (*attr)->robustness = robust;
-            result = 0;
-            break;
-        }
-    }
-
-  return (result);
-}				/* pthread_mutexattr_setrobust */
diff --git a/deps/w32-pthreads/pthread_mutexattr_settype.c b/deps/w32-pthreads/pthread_mutexattr_settype.c
deleted file mode 100644
index e6b95ae..0000000
--- a/deps/w32-pthreads/pthread_mutexattr_settype.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * pthread_mutexattr_settype.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind)
-     /*
-      * ------------------------------------------------------
-      *
-      * DOCPUBLIC
-      * The pthread_mutexattr_settype() and
-      * pthread_mutexattr_gettype() functions  respectively set and
-      * get the mutex type  attribute. This attribute is set in  the
-      * type parameter to these functions.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_mutexattr_t
-      *
-      *      type
-      *              must be one of:
-      *
-      *                      PTHREAD_MUTEX_DEFAULT
-      *
-      *                      PTHREAD_MUTEX_NORMAL
-      *
-      *                      PTHREAD_MUTEX_ERRORCHECK
-      *
-      *                      PTHREAD_MUTEX_RECURSIVE
-      *
-      * DESCRIPTION
-      * The pthread_mutexattr_settype() and
-      * pthread_mutexattr_gettype() functions  respectively set and
-      * get the mutex type  attribute. This attribute is set in  the
-      * type  parameter to these functions. The default value of the
-      * type  attribute is  PTHREAD_MUTEX_DEFAULT.
-      * 
-      * The type of mutex is contained in the type  attribute of the
-      * mutex attributes. Valid mutex types include:
-      *
-      * PTHREAD_MUTEX_NORMAL
-      *          This type of mutex does  not  detect  deadlock.  A
-      *          thread  attempting  to  relock  this mutex without
-      *          first unlocking it will  deadlock.  Attempting  to
-      *          unlock  a  mutex  locked  by  a  different  thread
-      *          results  in  undefined  behavior.  Attempting   to
-      *          unlock  an  unlocked  mutex  results  in undefined
-      *          behavior.
-      * 
-      * PTHREAD_MUTEX_ERRORCHECK
-      *          This type of  mutex  provides  error  checking.  A
-      *          thread  attempting  to  relock  this mutex without
-      *          first unlocking it will return with  an  error.  A
-      *          thread  attempting to unlock a mutex which another
-      *          thread has locked will return  with  an  error.  A
-      *          thread attempting to unlock an unlocked mutex will
-      *          return with an error.
-      *
-      * PTHREAD_MUTEX_DEFAULT
-      *          Same as PTHREAD_MUTEX_NORMAL.
-      * 
-      * PTHREAD_MUTEX_RECURSIVE
-      *          A thread attempting to relock this  mutex  without
-      *          first  unlocking  it  will  succeed in locking the
-      *          mutex. The relocking deadlock which can occur with
-      *          mutexes of type  PTHREAD_MUTEX_NORMAL cannot occur
-      *          with this type of mutex. Multiple  locks  of  this
-      *          mutex  require  the  same  number  of  unlocks  to
-      *          release  the  mutex  before  another  thread   can
-      *          acquire the mutex. A thread attempting to unlock a
-      *          mutex which another thread has locked will  return
-      *          with  an  error. A thread attempting to  unlock an
-      *          unlocked mutex will return  with  an  error.  This
-      *          type  of mutex is only supported for mutexes whose
-      *          process        shared         attribute         is
-      *          PTHREAD_PROCESS_PRIVATE.
-      *
-      * RESULTS
-      *              0               successfully set attribute,
-      *              EINVAL          'attr' or 'type' is invalid,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-
-  if ((attr != NULL && *attr != NULL))
-    {
-      switch (kind)
-	{
-	case PTHREAD_MUTEX_FAST_NP:
-	case PTHREAD_MUTEX_RECURSIVE_NP:
-	case PTHREAD_MUTEX_ERRORCHECK_NP:
-	  (*attr)->kind = kind;
-	  break;
-	default:
-	  result = EINVAL;
-	  break;
-	}
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  return (result);
-}				/* pthread_mutexattr_settype */
diff --git a/deps/w32-pthreads/pthread_num_processors_np.c b/deps/w32-pthreads/pthread_num_processors_np.c
deleted file mode 100644
index 081dff6..0000000
--- a/deps/w32-pthreads/pthread_num_processors_np.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * pthread_num_processors_np.c
- *
- * Description:
- * This translation unit implements non-portable thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/*
- * pthread_num_processors_np()
- *
- * Get the number of CPUs available to the process.
- */
-int
-pthread_num_processors_np (void)
-{
-  int count;
-
-  if (ptw32_getprocessors (&count) != 0)
-    {
-      count = 1;
-    }
-
-  return (count);
-}
diff --git a/deps/w32-pthreads/pthread_once.c b/deps/w32-pthreads/pthread_once.c
deleted file mode 100644
index 5c9e900..0000000
--- a/deps/w32-pthreads/pthread_once.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * pthread_once.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_once (pthread_once_t * once_control, void (PTW32_CDECL *init_routine) (void))
-{
-  if (once_control == NULL || init_routine == NULL)
-    {
-      return EINVAL;
-    }
-  
-  if ((PTW32_INTERLOCKED_LONG)PTW32_FALSE ==
-      (PTW32_INTERLOCKED_LONG)PTW32_INTERLOCKED_EXCHANGE_ADD_LONG((PTW32_INTERLOCKED_LONGPTR)&once_control->done,
-                                                                  (PTW32_INTERLOCKED_LONG)0)) /* MBR fence */
-    {
-      ptw32_mcs_local_node_t node;
-
-      ptw32_mcs_lock_acquire((ptw32_mcs_lock_t *)&once_control->lock, &node);
-
-      if (!once_control->done)
-	{
-
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth(0)
-#endif
-
-	  pthread_cleanup_push(ptw32_mcs_lock_release, &node);
-	  (*init_routine)();
-	  pthread_cleanup_pop(0);
-
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth()
-#endif
-
-	  once_control->done = PTW32_TRUE;
-	}
-
-	ptw32_mcs_lock_release(&node);
-    }
-
-  return 0;
-
-}				/* pthread_once */
diff --git a/deps/w32-pthreads/pthread_rwlock_destroy.c b/deps/w32-pthreads/pthread_rwlock_destroy.c
deleted file mode 100644
index fe79e1e..0000000
--- a/deps/w32-pthreads/pthread_rwlock_destroy.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * pthread_rwlock_destroy.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlock_destroy (pthread_rwlock_t * rwlock)
-{
-  pthread_rwlock_t rwl;
-  int result = 0, result1 = 0, result2 = 0;
-
-  if (rwlock == NULL || *rwlock == NULL)
-    {
-      return EINVAL;
-    }
-
-  if (*rwlock != PTHREAD_RWLOCK_INITIALIZER)
-    {
-      rwl = *rwlock;
-
-      if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
-	{
-	  return EINVAL;
-	}
-
-      if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0)
-	{
-	  return result;
-	}
-
-      if ((result =
-	   pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
-	{
-	  (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-	  return result;
-	}
-
-      /*
-       * Check whether any threads own/wait for the lock (wait for ex.access);
-       * report "BUSY" if so.
-       */
-      if (rwl->nExclusiveAccessCount > 0
-	  || rwl->nSharedAccessCount > rwl->nCompletedSharedAccessCount)
-	{
-	  result = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
-	  result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-	  result2 = EBUSY;
-	}
-      else
-	{
-	  rwl->nMagic = 0;
-
-	  if ((result =
-	       pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
-	    {
-	      pthread_mutex_unlock (&rwl->mtxExclusiveAccess);
-	      return result;
-	    }
-
-	  if ((result =
-	       pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))) != 0)
-	    {
-	      return result;
-	    }
-
-	  *rwlock = NULL;	/* Invalidate rwlock before anything else */
-	  result = pthread_cond_destroy (&(rwl->cndSharedAccessCompleted));
-	  result1 = pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted));
-	  result2 = pthread_mutex_destroy (&(rwl->mtxExclusiveAccess));
-	  (void) free (rwl);
-	}
-    }
-  else
-    {
-      ptw32_mcs_local_node_t node;
-      /*
-       * See notes in ptw32_rwlock_check_need_init() above also.
-       */
-      ptw32_mcs_lock_acquire(&ptw32_rwlock_test_init_lock, &node);
-
-      /*
-       * Check again.
-       */
-      if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
-	{
-	  /*
-	   * This is all we need to do to destroy a statically
-	   * initialised rwlock that has not yet been used (initialised).
-	   * If we get to here, another thread
-	   * waiting to initialise this rwlock will get an EINVAL.
-	   */
-	  *rwlock = NULL;
-	}
-      else
-	{
-	  /*
-	   * The rwlock has been initialised while we were waiting
-	   * so assume it's in use.
-	   */
-	  result = EBUSY;
-	}
-
-      ptw32_mcs_lock_release(&node);
-    }
-
-  return ((result != 0) ? result : ((result1 != 0) ? result1 : result2));
-}
diff --git a/deps/w32-pthreads/pthread_rwlock_init.c b/deps/w32-pthreads/pthread_rwlock_init.c
deleted file mode 100644
index cbba633..0000000
--- a/deps/w32-pthreads/pthread_rwlock_init.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * pthread_rwlock_init.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlock_init (pthread_rwlock_t * rwlock,
-		     const pthread_rwlockattr_t * attr)
-{
-  int result;
-  pthread_rwlock_t rwl = 0;
-
-  if (rwlock == NULL)
-    {
-      return EINVAL;
-    }
-
-  if (attr != NULL && *attr != NULL)
-    {
-      result = EINVAL;		/* Not supported */
-      goto DONE;
-    }
-
-  rwl = (pthread_rwlock_t) calloc (1, sizeof (*rwl));
-
-  if (rwl == NULL)
-    {
-      result = ENOMEM;
-      goto DONE;
-    }
-
-  rwl->nSharedAccessCount = 0;
-  rwl->nExclusiveAccessCount = 0;
-  rwl->nCompletedSharedAccessCount = 0;
-
-  result = pthread_mutex_init (&rwl->mtxExclusiveAccess, NULL);
-  if (result != 0)
-    {
-      goto FAIL0;
-    }
-
-  result = pthread_mutex_init (&rwl->mtxSharedAccessCompleted, NULL);
-  if (result != 0)
-    {
-      goto FAIL1;
-    }
-
-  result = pthread_cond_init (&rwl->cndSharedAccessCompleted, NULL);
-  if (result != 0)
-    {
-      goto FAIL2;
-    }
-
-  rwl->nMagic = PTW32_RWLOCK_MAGIC;
-
-  result = 0;
-  goto DONE;
-
-FAIL2:
-  (void) pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted));
-
-FAIL1:
-  (void) pthread_mutex_destroy (&(rwl->mtxExclusiveAccess));
-
-FAIL0:
-  (void) free (rwl);
-  rwl = NULL;
-
-DONE:
-  *rwlock = rwl;
-
-  return result;
-}
diff --git a/deps/w32-pthreads/pthread_rwlock_rdlock.c b/deps/w32-pthreads/pthread_rwlock_rdlock.c
deleted file mode 100644
index fb91b70..0000000
--- a/deps/w32-pthreads/pthread_rwlock_rdlock.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * pthread_rwlock_rdlock.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlock_rdlock (pthread_rwlock_t * rwlock)
-{
-  int result;
-  pthread_rwlock_t rwl;
-
-  if (rwlock == NULL || *rwlock == NULL)
-    {
-      return EINVAL;
-    }
-
-  /*
-   * We do a quick check to see if we need to do more work
-   * to initialise a static rwlock. We check
-   * again inside the guarded section of ptw32_rwlock_check_need_init()
-   * to avoid race conditions.
-   */
-  if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
-    {
-      result = ptw32_rwlock_check_need_init (rwlock);
-
-      if (result != 0 && result != EBUSY)
-	{
-	  return result;
-	}
-    }
-
-  rwl = *rwlock;
-
-  if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
-    {
-      return EINVAL;
-    }
-
-  if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0)
-    {
-      return result;
-    }
-
-  if (++rwl->nSharedAccessCount == INT_MAX)
-    {
-      if ((result =
-	   pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
-	{
-	  (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-	  return result;
-	}
-
-      rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
-      rwl->nCompletedSharedAccessCount = 0;
-
-      if ((result =
-	   pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
-	{
-	  (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-	  return result;
-	}
-    }
-
-  return (pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)));
-}
diff --git a/deps/w32-pthreads/pthread_rwlock_timedrdlock.c b/deps/w32-pthreads/pthread_rwlock_timedrdlock.c
deleted file mode 100644
index d73dd10..0000000
--- a/deps/w32-pthreads/pthread_rwlock_timedrdlock.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * pthread_rwlock_timedrdlock.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlock_timedrdlock (pthread_rwlock_t * rwlock,
-			    const struct timespec *abstime)
-{
-  int result;
-  pthread_rwlock_t rwl;
-
-  if (rwlock == NULL || *rwlock == NULL)
-    {
-      return EINVAL;
-    }
-
-  /*
-   * We do a quick check to see if we need to do more work
-   * to initialise a static rwlock. We check
-   * again inside the guarded section of ptw32_rwlock_check_need_init()
-   * to avoid race conditions.
-   */
-  if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
-    {
-      result = ptw32_rwlock_check_need_init (rwlock);
-
-      if (result != 0 && result != EBUSY)
-	{
-	  return result;
-	}
-    }
-
-  rwl = *rwlock;
-
-  if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
-    {
-      return EINVAL;
-    }
-
-  if ((result =
-       pthread_mutex_timedlock (&(rwl->mtxExclusiveAccess), abstime)) != 0)
-    {
-      return result;
-    }
-
-  if (++rwl->nSharedAccessCount == INT_MAX)
-    {
-      if ((result =
-	   pthread_mutex_timedlock (&(rwl->mtxSharedAccessCompleted),
-				    abstime)) != 0)
-	{
-	  if (result == ETIMEDOUT)
-	    {
-	      ++rwl->nCompletedSharedAccessCount;
-	    }
-	  (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-	  return result;
-	}
-
-      rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
-      rwl->nCompletedSharedAccessCount = 0;
-
-      if ((result =
-	   pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
-	{
-	  (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-	  return result;
-	}
-    }
-
-  return (pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)));
-}
diff --git a/deps/w32-pthreads/pthread_rwlock_timedwrlock.c b/deps/w32-pthreads/pthread_rwlock_timedwrlock.c
deleted file mode 100644
index 8e8e14e..0000000
--- a/deps/w32-pthreads/pthread_rwlock_timedwrlock.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * pthread_rwlock_timedwrlock.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlock_timedwrlock (pthread_rwlock_t * rwlock,
-			    const struct timespec *abstime)
-{
-  int result;
-  pthread_rwlock_t rwl;
-
-  if (rwlock == NULL || *rwlock == NULL)
-    {
-      return EINVAL;
-    }
-
-  /*
-   * We do a quick check to see if we need to do more work
-   * to initialise a static rwlock. We check
-   * again inside the guarded section of ptw32_rwlock_check_need_init()
-   * to avoid race conditions.
-   */
-  if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
-    {
-      result = ptw32_rwlock_check_need_init (rwlock);
-
-      if (result != 0 && result != EBUSY)
-	{
-	  return result;
-	}
-    }
-
-  rwl = *rwlock;
-
-  if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
-    {
-      return EINVAL;
-    }
-
-  if ((result =
-       pthread_mutex_timedlock (&(rwl->mtxExclusiveAccess), abstime)) != 0)
-    {
-      return result;
-    }
-
-  if ((result =
-       pthread_mutex_timedlock (&(rwl->mtxSharedAccessCompleted),
-				abstime)) != 0)
-    {
-      (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-      return result;
-    }
-
-  if (rwl->nExclusiveAccessCount == 0)
-    {
-      if (rwl->nCompletedSharedAccessCount > 0)
-	{
-	  rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
-	  rwl->nCompletedSharedAccessCount = 0;
-	}
-
-      if (rwl->nSharedAccessCount > 0)
-	{
-	  rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount;
-
-	  /*
-	   * This routine may be a cancelation point
-	   * according to POSIX 1003.1j section 18.1.2.
-	   */
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth(0)
-#endif
-	  pthread_cleanup_push (ptw32_rwlock_cancelwrwait, (void *) rwl);
-
-	  do
-	    {
-	      result =
-		pthread_cond_timedwait (&(rwl->cndSharedAccessCompleted),
-					&(rwl->mtxSharedAccessCompleted),
-					abstime);
-	    }
-	  while (result == 0 && rwl->nCompletedSharedAccessCount < 0);
-
-	  pthread_cleanup_pop ((result != 0) ? 1 : 0);
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth()
-#endif
-
-	  if (result == 0)
-	    {
-	      rwl->nSharedAccessCount = 0;
-	    }
-	}
-    }
-
-  if (result == 0)
-    {
-      rwl->nExclusiveAccessCount++;
-    }
-
-  return result;
-}
diff --git a/deps/w32-pthreads/pthread_rwlock_tryrdlock.c b/deps/w32-pthreads/pthread_rwlock_tryrdlock.c
deleted file mode 100644
index 10e1460..0000000
--- a/deps/w32-pthreads/pthread_rwlock_tryrdlock.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * pthread_rwlock_tryrdlock.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlock_tryrdlock (pthread_rwlock_t * rwlock)
-{
-  int result;
-  pthread_rwlock_t rwl;
-
-  if (rwlock == NULL || *rwlock == NULL)
-    {
-      return EINVAL;
-    }
-
-  /*
-   * We do a quick check to see if we need to do more work
-   * to initialise a static rwlock. We check
-   * again inside the guarded section of ptw32_rwlock_check_need_init()
-   * to avoid race conditions.
-   */
-  if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
-    {
-      result = ptw32_rwlock_check_need_init (rwlock);
-
-      if (result != 0 && result != EBUSY)
-	{
-	  return result;
-	}
-    }
-
-  rwl = *rwlock;
-
-  if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
-    {
-      return EINVAL;
-    }
-
-  if ((result = pthread_mutex_trylock (&(rwl->mtxExclusiveAccess))) != 0)
-    {
-      return result;
-    }
-
-  if (++rwl->nSharedAccessCount == INT_MAX)
-    {
-      if ((result =
-	   pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
-	{
-	  (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-	  return result;
-	}
-
-      rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
-      rwl->nCompletedSharedAccessCount = 0;
-
-      if ((result =
-	   pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
-	{
-	  (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-	  return result;
-	}
-    }
-
-  return (pthread_mutex_unlock (&rwl->mtxExclusiveAccess));
-}
diff --git a/deps/w32-pthreads/pthread_rwlock_trywrlock.c b/deps/w32-pthreads/pthread_rwlock_trywrlock.c
deleted file mode 100644
index 249ecf7..0000000
--- a/deps/w32-pthreads/pthread_rwlock_trywrlock.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * pthread_rwlock_trywrlock.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlock_trywrlock (pthread_rwlock_t * rwlock)
-{
-  int result, result1;
-  pthread_rwlock_t rwl;
-
-  if (rwlock == NULL || *rwlock == NULL)
-    {
-      return EINVAL;
-    }
-
-  /*
-   * We do a quick check to see if we need to do more work
-   * to initialise a static rwlock. We check
-   * again inside the guarded section of ptw32_rwlock_check_need_init()
-   * to avoid race conditions.
-   */
-  if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
-    {
-      result = ptw32_rwlock_check_need_init (rwlock);
-
-      if (result != 0 && result != EBUSY)
-	{
-	  return result;
-	}
-    }
-
-  rwl = *rwlock;
-
-  if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
-    {
-      return EINVAL;
-    }
-
-  if ((result = pthread_mutex_trylock (&(rwl->mtxExclusiveAccess))) != 0)
-    {
-      return result;
-    }
-
-  if ((result =
-       pthread_mutex_trylock (&(rwl->mtxSharedAccessCompleted))) != 0)
-    {
-      result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-      return ((result1 != 0) ? result1 : result);
-    }
-
-  if (rwl->nExclusiveAccessCount == 0)
-    {
-      if (rwl->nCompletedSharedAccessCount > 0)
-	{
-	  rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
-	  rwl->nCompletedSharedAccessCount = 0;
-	}
-
-      if (rwl->nSharedAccessCount > 0)
-	{
-	  if ((result =
-	       pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
-	    {
-	      (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-	      return result;
-	    }
-
-	  if ((result =
-	       pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))) == 0)
-	    {
-	      result = EBUSY;
-	    }
-	}
-      else
-	{
-	  rwl->nExclusiveAccessCount = 1;
-	}
-    }
-  else
-    {
-      result = EBUSY;
-    }
-
-  return result;
-}
diff --git a/deps/w32-pthreads/pthread_rwlock_unlock.c b/deps/w32-pthreads/pthread_rwlock_unlock.c
deleted file mode 100644
index a2f69d1..0000000
--- a/deps/w32-pthreads/pthread_rwlock_unlock.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * pthread_rwlock_unlock.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlock_unlock (pthread_rwlock_t * rwlock)
-{
-  int result, result1;
-  pthread_rwlock_t rwl;
-
-  if (rwlock == NULL || *rwlock == NULL)
-    {
-      return (EINVAL);
-    }
-
-  if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
-    {
-      /*
-       * Assume any race condition here is harmless.
-       */
-      return 0;
-    }
-
-  rwl = *rwlock;
-
-  if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
-    {
-      return EINVAL;
-    }
-
-  if (rwl->nExclusiveAccessCount == 0)
-    {
-      if ((result =
-	   pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
-	{
-	  return result;
-	}
-
-      if (++rwl->nCompletedSharedAccessCount == 0)
-	{
-	  result = pthread_cond_signal (&(rwl->cndSharedAccessCompleted));
-	}
-
-      result1 = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
-    }
-  else
-    {
-      rwl->nExclusiveAccessCount--;
-
-      result = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
-      result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-
-    }
-
-  return ((result != 0) ? result : result1);
-}
diff --git a/deps/w32-pthreads/pthread_rwlock_wrlock.c b/deps/w32-pthreads/pthread_rwlock_wrlock.c
deleted file mode 100644
index 30ce75d..0000000
--- a/deps/w32-pthreads/pthread_rwlock_wrlock.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * pthread_rwlock_wrlock.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlock_wrlock (pthread_rwlock_t * rwlock)
-{
-  int result;
-  pthread_rwlock_t rwl;
-
-  if (rwlock == NULL || *rwlock == NULL)
-    {
-      return EINVAL;
-    }
-
-  /*
-   * We do a quick check to see if we need to do more work
-   * to initialise a static rwlock. We check
-   * again inside the guarded section of ptw32_rwlock_check_need_init()
-   * to avoid race conditions.
-   */
-  if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
-    {
-      result = ptw32_rwlock_check_need_init (rwlock);
-
-      if (result != 0 && result != EBUSY)
-	{
-	  return result;
-	}
-    }
-
-  rwl = *rwlock;
-
-  if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
-    {
-      return EINVAL;
-    }
-
-  if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0)
-    {
-      return result;
-    }
-
-  if ((result = pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
-    {
-      (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-      return result;
-    }
-
-  if (rwl->nExclusiveAccessCount == 0)
-    {
-      if (rwl->nCompletedSharedAccessCount > 0)
-	{
-	  rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
-	  rwl->nCompletedSharedAccessCount = 0;
-	}
-
-      if (rwl->nSharedAccessCount > 0)
-	{
-	  rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount;
-
-	  /*
-	   * This routine may be a cancelation point
-	   * according to POSIX 1003.1j section 18.1.2.
-	   */
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth(0)
-#endif
-	  pthread_cleanup_push (ptw32_rwlock_cancelwrwait, (void *) rwl);
-
-	  do
-	    {
-	      result = pthread_cond_wait (&(rwl->cndSharedAccessCompleted),
-					  &(rwl->mtxSharedAccessCompleted));
-	    }
-	  while (result == 0 && rwl->nCompletedSharedAccessCount < 0);
-
-	  pthread_cleanup_pop ((result != 0) ? 1 : 0);
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth()
-#endif
-
-	  if (result == 0)
-	    {
-	      rwl->nSharedAccessCount = 0;
-	    }
-	}
-    }
-
-  if (result == 0)
-    {
-      rwl->nExclusiveAccessCount++;
-    }
-
-  return result;
-}
diff --git a/deps/w32-pthreads/pthread_rwlockattr_destroy.c b/deps/w32-pthreads/pthread_rwlockattr_destroy.c
deleted file mode 100644
index c2c7d99..0000000
--- a/deps/w32-pthreads/pthread_rwlockattr_destroy.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * pthread_rwlockattr_destroy.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Destroys a rwlock attributes object. The object can
-      *      no longer be used.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_rwlockattr_t
-      *
-      *
-      * DESCRIPTION
-      *      Destroys a rwlock attributes object. The object can
-      *      no longer be used.
-      *
-      *      NOTES:
-      *              1)      Does not affect rwlockss created using 'attr'
-      *
-      * RESULTS
-      *              0               successfully released attr,
-      *              EINVAL          'attr' is invalid.
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-
-  if (attr == NULL || *attr == NULL)
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      pthread_rwlockattr_t rwa = *attr;
-
-      *attr = NULL;
-      free (rwa);
-    }
-
-  return (result);
-}				/* pthread_rwlockattr_destroy */
diff --git a/deps/w32-pthreads/pthread_rwlockattr_getpshared.c b/deps/w32-pthreads/pthread_rwlockattr_getpshared.c
deleted file mode 100644
index 0474e08..0000000
--- a/deps/w32-pthreads/pthread_rwlockattr_getpshared.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * pthread_rwlockattr_getpshared.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
-			       int *pshared)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Determine whether rwlocks created with 'attr' can be
-      *      shared between processes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_rwlockattr_t
-      *
-      *      pshared
-      *              will be set to one of:
-      *
-      *                      PTHREAD_PROCESS_SHARED
-      *                              May be shared if in shared memory
-      *
-      *                      PTHREAD_PROCESS_PRIVATE
-      *                              Cannot be shared.
-      *
-      *
-      * DESCRIPTION
-      *      Rwlocks creatd with 'attr' can be shared between
-      *      processes if pthread_rwlock_t variable is allocated
-      *      in memory shared by these processes.
-      *      NOTES:
-      *              1)      pshared rwlocks MUST be allocated in shared
-      *                      memory.
-      *              2)      The following macro is defined if shared rwlocks
-      *                      are supported:
-      *                              _POSIX_THREAD_PROCESS_SHARED
-      *
-      * RESULTS
-      *              0               successfully retrieved attribute,
-      *              EINVAL          'attr' is invalid,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-
-  if ((attr != NULL && *attr != NULL) && (pshared != NULL))
-    {
-      *pshared = (*attr)->pshared;
-      result = 0;
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  return (result);
-
-}				/* pthread_rwlockattr_getpshared */
diff --git a/deps/w32-pthreads/pthread_rwlockattr_init.c b/deps/w32-pthreads/pthread_rwlockattr_init.c
deleted file mode 100644
index a028421..0000000
--- a/deps/w32-pthreads/pthread_rwlockattr_init.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * pthread_rwlockattr_init.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlockattr_init (pthread_rwlockattr_t * attr)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Initializes a rwlock attributes object with default
-      *      attributes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_rwlockattr_t
-      *
-      *
-      * DESCRIPTION
-      *      Initializes a rwlock attributes object with default
-      *      attributes.
-      *
-      * RESULTS
-      *              0               successfully initialized attr,
-      *              ENOMEM          insufficient memory for attr.
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  pthread_rwlockattr_t rwa;
-
-  rwa = (pthread_rwlockattr_t) calloc (1, sizeof (*rwa));
-
-  if (rwa == NULL)
-    {
-      result = ENOMEM;
-    }
-  else
-    {
-      rwa->pshared = PTHREAD_PROCESS_PRIVATE;
-    }
-
-  *attr = rwa;
-
-  return (result);
-}				/* pthread_rwlockattr_init */
diff --git a/deps/w32-pthreads/pthread_rwlockattr_setpshared.c b/deps/w32-pthreads/pthread_rwlockattr_setpshared.c
deleted file mode 100644
index 7b4c2cb..0000000
--- a/deps/w32-pthreads/pthread_rwlockattr_setpshared.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * pthread_rwlockattr_setpshared.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, int pshared)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Rwlocks created with 'attr' can be shared between
-      *      processes if pthread_rwlock_t variable is allocated
-      *      in memory shared by these processes.
-      *
-      * PARAMETERS
-      *      attr
-      *              pointer to an instance of pthread_rwlockattr_t
-      *
-      *      pshared
-      *              must be one of:
-      *
-      *                      PTHREAD_PROCESS_SHARED
-      *                              May be shared if in shared memory
-      *
-      *                      PTHREAD_PROCESS_PRIVATE
-      *                              Cannot be shared.
-      *
-      * DESCRIPTION
-      *      Rwlocks creatd with 'attr' can be shared between
-      *      processes if pthread_rwlock_t variable is allocated
-      *      in memory shared by these processes.
-      *
-      *      NOTES:
-      *              1)      pshared rwlocks MUST be allocated in shared
-      *                      memory.
-      *
-      *              2)      The following macro is defined if shared rwlocks
-      *                      are supported:
-      *                              _POSIX_THREAD_PROCESS_SHARED
-      *
-      * RESULTS
-      *              0               successfully set attribute,
-      *              EINVAL          'attr' or pshared is invalid,
-      *              ENOSYS          PTHREAD_PROCESS_SHARED not supported,
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result;
-
-  if ((attr != NULL && *attr != NULL) &&
-      ((pshared == PTHREAD_PROCESS_SHARED) ||
-       (pshared == PTHREAD_PROCESS_PRIVATE)))
-    {
-      if (pshared == PTHREAD_PROCESS_SHARED)
-	{
-
-#if !defined( _POSIX_THREAD_PROCESS_SHARED )
-
-	  result = ENOSYS;
-	  pshared = PTHREAD_PROCESS_PRIVATE;
-
-#else
-
-	  result = 0;
-
-#endif /* _POSIX_THREAD_PROCESS_SHARED */
-
-	}
-      else
-	{
-	  result = 0;
-	}
-
-      (*attr)->pshared = pshared;
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  return (result);
-
-}				/* pthread_rwlockattr_setpshared */
diff --git a/deps/w32-pthreads/pthread_self.c b/deps/w32-pthreads/pthread_self.c
deleted file mode 100644
index f13926f..0000000
--- a/deps/w32-pthreads/pthread_self.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * pthread_self.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-pthread_t
-pthread_self (void)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function returns a reference to the current running
-      *      thread.
-      *
-      * PARAMETERS
-      *      N/A
-      *
-      *
-      * DESCRIPTION
-      *      This function returns a reference to the current running
-      *      thread.
-      *
-      * RESULTS
-      *              pthread_t       reference to the current thread
-      *
-      * ------------------------------------------------------
-      */
-{
-  pthread_t self;
-  pthread_t nil = {NULL, 0};
-  ptw32_thread_t * sp;
-
-#if defined(_UWIN)
-  if (!ptw32_selfThreadKey)
-    return nil;
-#endif
-
-  sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
-
-  if (sp != NULL)
-    {
-      self = sp->ptHandle;
-    }
-  else
-    {
-      /*
-       * Need to create an implicit 'self' for the currently
-       * executing thread.
-       */
-      self = ptw32_new ();
-      sp = (ptw32_thread_t *) self.p;
-
-      if (sp != NULL)
-	{
-	  /*
-	   * This is a non-POSIX thread which has chosen to call
-	   * a POSIX threads function for some reason. We assume that
-	   * it isn't joinable, but we do assume that it's
-	   * (deferred) cancelable.
-	   */
-	  sp->implicit = 1;
-	  sp->detachState = PTHREAD_CREATE_DETACHED;
-	  sp->thread = GetCurrentThreadId ();
-
-#if defined(NEED_DUPLICATEHANDLE)
-	  /*
-	   * DuplicateHandle does not exist on WinCE.
-	   *
-	   * NOTE:
-	   * GetCurrentThread only returns a pseudo-handle
-	   * which is only valid in the current thread context.
-	   * Therefore, you should not pass the handle to
-	   * other threads for whatever purpose.
-	   */
-	  sp->threadH = GetCurrentThread ();
-#else
-	  if (!DuplicateHandle (GetCurrentProcess (),
-				GetCurrentThread (),
-				GetCurrentProcess (),
-				&sp->threadH,
-				0, FALSE, DUPLICATE_SAME_ACCESS))
-	    {
-	      /*
-	       * Should not do this, but we have no alternative if
-	       * we can't get a Win32 thread handle.
-	       * Thread structs are never freed.
-	       */
-	      ptw32_threadReusePush (self);
-	      /*
-	       * As this is a win32 thread calling us and we have failed,
-	       * return a value that makes sense to win32.
-	       */
-	      return nil;
-	    }
-#endif
-
-	  /*
-	   * No need to explicitly serialise access to sched_priority
-	   * because the new handle is not yet public.
-	   */
-	  sp->sched_priority = GetThreadPriority (sp->threadH);
-	  pthread_setspecific (ptw32_selfThreadKey, (void *) sp);
-	}
-    }
-
-  return (self);
-
-}				/* pthread_self */
diff --git a/deps/w32-pthreads/pthread_setcancelstate.c b/deps/w32-pthreads/pthread_setcancelstate.c
deleted file mode 100644
index 126801f..0000000
--- a/deps/w32-pthreads/pthread_setcancelstate.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * pthread_setcancelstate.c
- *
- * Description:
- * POSIX thread functions related to thread cancellation.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_setcancelstate (int state, int *oldstate)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function atomically sets the calling thread's
-      *      cancelability state to 'state' and returns the previous
-      *      cancelability state at the location referenced by
-      *      'oldstate'
-      *
-      * PARAMETERS
-      *      state,
-      *      oldstate
-      *              PTHREAD_CANCEL_ENABLE
-      *                      cancellation is enabled,
-      *
-      *              PTHREAD_CANCEL_DISABLE
-      *                      cancellation is disabled
-      *
-      *
-      * DESCRIPTION
-      *      This function atomically sets the calling thread's
-      *      cancelability state to 'state' and returns the previous
-      *      cancelability state at the location referenced by
-      *      'oldstate'.
-      *
-      *      NOTES:
-      *      1)      Use to disable cancellation around 'atomic' code that
-      *              includes cancellation points
-      *
-      * COMPATIBILITY ADDITIONS
-      *      If 'oldstate' is NULL then the previous state is not returned
-      *      but the function still succeeds. (Solaris)
-      *
-      * RESULTS
-      *              0               successfully set cancelability type,
-      *              EINVAL          'state' is invalid
-      *
-      * ------------------------------------------------------
-      */
-{
-  ptw32_mcs_local_node_t stateLock;
-  int result = 0;
-  pthread_t self = pthread_self ();
-  ptw32_thread_t * sp = (ptw32_thread_t *) self.p;
-
-  if (sp == NULL
-      || (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE))
-    {
-      return EINVAL;
-    }
-
-  /*
-   * Lock for async-cancel safety.
-   */
-  ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
-
-  if (oldstate != NULL)
-    {
-      *oldstate = sp->cancelState;
-    }
-
-  sp->cancelState = state;
-
-  /*
-   * Check if there is a pending asynchronous cancel
-   */
-  if (state == PTHREAD_CANCEL_ENABLE
-      && sp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS
-      && WaitForSingleObject (sp->cancelEvent, 0) == WAIT_OBJECT_0)
-    {
-      sp->state = PThreadStateCanceling;
-      sp->cancelState = PTHREAD_CANCEL_DISABLE;
-      ResetEvent (sp->cancelEvent);
-      ptw32_mcs_lock_release (&stateLock);
-      ptw32_throw (PTW32_EPS_CANCEL);
-
-      /* Never reached */
-    }
-
-  ptw32_mcs_lock_release (&stateLock);
-
-  return (result);
-
-}				/* pthread_setcancelstate */
diff --git a/deps/w32-pthreads/pthread_setcanceltype.c b/deps/w32-pthreads/pthread_setcanceltype.c
deleted file mode 100644
index 00522ae..0000000
--- a/deps/w32-pthreads/pthread_setcanceltype.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * pthread_setcanceltype.c
- *
- * Description:
- * POSIX thread functions related to thread cancellation.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_setcanceltype (int type, int *oldtype)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function atomically sets the calling thread's
-      *      cancelability type to 'type' and returns the previous
-      *      cancelability type at the location referenced by
-      *      'oldtype'
-      *
-      * PARAMETERS
-      *      type,
-      *      oldtype
-      *              PTHREAD_CANCEL_DEFERRED
-      *                      only deferred cancelation is allowed,
-      *
-      *              PTHREAD_CANCEL_ASYNCHRONOUS
-      *                      Asynchronous cancellation is allowed
-      *
-      *
-      * DESCRIPTION
-      *      This function atomically sets the calling thread's
-      *      cancelability type to 'type' and returns the previous
-      *      cancelability type at the location referenced by
-      *      'oldtype'
-      *
-      *      NOTES:
-      *      1)      Use with caution; most code is not safe for use
-      *              with asynchronous cancelability.
-      *
-      * COMPATIBILITY ADDITIONS
-      *      If 'oldtype' is NULL then the previous type is not returned
-      *      but the function still succeeds. (Solaris)
-      *
-      * RESULTS
-      *              0               successfully set cancelability type,
-      *              EINVAL          'type' is invalid
-      *
-      * ------------------------------------------------------
-      */
-{
-  ptw32_mcs_local_node_t stateLock;
-  int result = 0;
-  pthread_t self = pthread_self ();
-  ptw32_thread_t * sp = (ptw32_thread_t *) self.p;
-
-  if (sp == NULL
-      || (type != PTHREAD_CANCEL_DEFERRED
-	  && type != PTHREAD_CANCEL_ASYNCHRONOUS))
-    {
-      return EINVAL;
-    }
-
-  /*
-   * Lock for async-cancel safety.
-   */
-  ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
-
-  if (oldtype != NULL)
-    {
-      *oldtype = sp->cancelType;
-    }
-
-  sp->cancelType = type;
-
-  /*
-   * Check if there is a pending asynchronous cancel
-   */
-  if (sp->cancelState == PTHREAD_CANCEL_ENABLE
-      && type == PTHREAD_CANCEL_ASYNCHRONOUS
-      && WaitForSingleObject (sp->cancelEvent, 0) == WAIT_OBJECT_0)
-    {
-      sp->state = PThreadStateCanceling;
-      sp->cancelState = PTHREAD_CANCEL_DISABLE;
-      ResetEvent (sp->cancelEvent);
-      ptw32_mcs_lock_release (&stateLock);
-      ptw32_throw (PTW32_EPS_CANCEL);
-
-      /* Never reached */
-    }
-
-  ptw32_mcs_lock_release (&stateLock);
-
-  return (result);
-
-}				/* pthread_setcanceltype */
diff --git a/deps/w32-pthreads/pthread_setconcurrency.c b/deps/w32-pthreads/pthread_setconcurrency.c
deleted file mode 100644
index 7fd2a3b..0000000
--- a/deps/w32-pthreads/pthread_setconcurrency.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * pthread_setconcurrency.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_setconcurrency (int level)
-{
-  if (level < 0)
-    {
-      return EINVAL;
-    }
-  else
-    {
-      ptw32_concurrency = level;
-      return 0;
-    }
-}
diff --git a/deps/w32-pthreads/pthread_setschedparam.c b/deps/w32-pthreads/pthread_setschedparam.c
deleted file mode 100644
index 63025fd..0000000
--- a/deps/w32-pthreads/pthread_setschedparam.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * sched_setschedparam.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-int
-pthread_setschedparam (pthread_t thread, int policy,
-		       const struct sched_param *param)
-{
-  int result;
-
-  /* Validate the thread id. */
-  result = pthread_kill (thread, 0);
-  if (0 != result)
-    {
-      return result;
-    }
-
-  /* Validate the scheduling policy. */
-  if (policy < SCHED_MIN || policy > SCHED_MAX)
-    {
-      return EINVAL;
-    }
-
-  /* Ensure the policy is SCHED_OTHER. */
-  if (policy != SCHED_OTHER)
-    {
-      return ENOTSUP;
-    }
-
-  return (ptw32_setthreadpriority (thread, policy, param->sched_priority));
-}
-
-
-int
-ptw32_setthreadpriority (pthread_t thread, int policy, int priority)
-{
-  int prio;
-  ptw32_mcs_local_node_t threadLock;
-  int result = 0;
-  ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
-
-  prio = priority;
-
-  /* Validate priority level. */
-  if (prio < sched_get_priority_min (policy) ||
-      prio > sched_get_priority_max (policy))
-    {
-      return EINVAL;
-    }
-
-#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
-/* WinCE */
-#else
-/* Everything else */
-
-  if (THREAD_PRIORITY_IDLE < prio && THREAD_PRIORITY_LOWEST > prio)
-    {
-      prio = THREAD_PRIORITY_LOWEST;
-    }
-  else if (THREAD_PRIORITY_TIME_CRITICAL > prio
-	   && THREAD_PRIORITY_HIGHEST < prio)
-    {
-      prio = THREAD_PRIORITY_HIGHEST;
-    }
-
-#endif
-
-  ptw32_mcs_lock_acquire (&tp->threadLock, &threadLock);
-
-  /* If this fails, the current priority is unchanged. */
-  if (0 == SetThreadPriority (tp->threadH, prio))
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      /*
-       * Must record the thread's sched_priority as given,
-       * not as finally adjusted.
-       */
-      tp->sched_priority = priority;
-    }
-
-  ptw32_mcs_lock_release (&threadLock);
-
-  return result;
-}
diff --git a/deps/w32-pthreads/pthread_setspecific.c b/deps/w32-pthreads/pthread_setspecific.c
deleted file mode 100644
index 5f66cae..0000000
--- a/deps/w32-pthreads/pthread_setspecific.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * pthread_setspecific.c
- *
- * Description:
- * POSIX thread functions which implement thread-specific data (TSD).
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_setspecific (pthread_key_t key, const void *value)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function sets the value of the thread specific
-      *      key in the calling thread.
-      *
-      * PARAMETERS
-      *      key
-      *              an instance of pthread_key_t
-      *      value
-      *              the value to set key to
-      *
-      *
-      * DESCRIPTION
-      *      This function sets the value of the thread specific
-      *      key in the calling thread.
-      *
-      * RESULTS
-      *              0               successfully set value
-      *              EAGAIN          could not set value
-      *              ENOENT          SERIOUS!!
-      *
-      * ------------------------------------------------------
-      */
-{
-  pthread_t self;
-  int result = 0;
-
-  if (key != ptw32_selfThreadKey)
-    {
-      /*
-       * Using pthread_self will implicitly create
-       * an instance of pthread_t for the current
-       * thread if one wasn't explicitly created
-       */
-      self = pthread_self ();
-      if (self.p == NULL)
-	{
-	  return ENOENT;
-	}
-    }
-  else
-    {
-      /*
-       * Resolve catch-22 of registering thread with selfThread
-       * key
-       */
-      ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
-
-      if (sp == NULL)
-        {
-	  if (value == NULL)
-	    {
-	      return ENOENT;
-	    }
-          self = *((pthread_t *) value);
-        }
-      else
-        {
-	  self = sp->ptHandle;
-        }
-    }
-
-  result = 0;
-
-  if (key != NULL)
-    {
-      if (self.p != NULL && key->destructor != NULL && value != NULL)
-	{
-          ptw32_mcs_local_node_t keyLock;
-          ptw32_mcs_local_node_t threadLock;
-	  ptw32_thread_t * sp = (ptw32_thread_t *) self.p;
-	  /*
-	   * Only require associations if we have to
-	   * call user destroy routine.
-	   * Don't need to locate an existing association
-	   * when setting data to NULL for WIN32 since the
-	   * data is stored with the operating system; not
-	   * on the association; setting assoc to NULL short
-	   * circuits the search.
-	   */
-	  ThreadKeyAssoc *assoc;
-
-	  ptw32_mcs_lock_acquire(&(key->keyLock), &keyLock);
-	  ptw32_mcs_lock_acquire(&(sp->threadLock), &threadLock);
-
-	  assoc = (ThreadKeyAssoc *) sp->keys;
-	  /*
-	   * Locate existing association
-	   */
-	  while (assoc != NULL)
-	    {
-	      if (assoc->key == key)
-		{
-		  /*
-		   * Association already exists
-		   */
-		  break;
-		}
-		assoc = assoc->nextKey;
-	    }
-
-	  /*
-	   * create an association if not found
-	   */
-	  if (assoc == NULL)
-	    {
-	      result = ptw32_tkAssocCreate (sp, key);
-	    }
-
-	  ptw32_mcs_lock_release(&threadLock);
-	  ptw32_mcs_lock_release(&keyLock);
-	}
-
-      if (result == 0)
-	{
-	  if (!TlsSetValue (key->key, (LPVOID) value))
-	    {
-	      result = EAGAIN;
-	    }
-	}
-    }
-
-  return (result);
-}				/* pthread_setspecific */
diff --git a/deps/w32-pthreads/pthread_spin_destroy.c b/deps/w32-pthreads/pthread_spin_destroy.c
deleted file mode 100644
index 39451d5..0000000
--- a/deps/w32-pthreads/pthread_spin_destroy.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * pthread_spin_destroy.c
- *
- * Description:
- * This translation unit implements spin lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_spin_destroy (pthread_spinlock_t * lock)
-{
-  register pthread_spinlock_t s;
-  int result = 0;
-
-  if (lock == NULL || *lock == NULL)
-    {
-      return EINVAL;
-    }
-
-  if ((s = *lock) != PTHREAD_SPINLOCK_INITIALIZER)
-    {
-      if (s->interlock == PTW32_SPIN_USE_MUTEX)
-	{
-	  result = pthread_mutex_destroy (&(s->u.mutex));
-	}
-      else if ((PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED !=
-	       PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock,
-						   (PTW32_INTERLOCKED_LONG) PTW32_SPIN_INVALID,
-						   (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED))
-	{
-	  result = EINVAL;
-	}
-
-      if (0 == result)
-	{
-	  /*
-	   * We are relying on the application to ensure that all other threads
-	   * have finished with the spinlock before destroying it.
-	   */
-	  *lock = NULL;
-	  (void) free (s);
-	}
-    }
-  else
-    {
-      /*
-       * See notes in ptw32_spinlock_check_need_init() above also.
-       */
-      ptw32_mcs_local_node_t node;
-
-      ptw32_mcs_lock_acquire(&ptw32_spinlock_test_init_lock, &node);
-
-      /*
-       * Check again.
-       */
-      if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
-	{
-	  /*
-	   * This is all we need to do to destroy a statically
-	   * initialised spinlock that has not yet been used (initialised).
-	   * If we get to here, another thread
-	   * waiting to initialise this mutex will get an EINVAL.
-	   */
-	  *lock = NULL;
-	}
-      else
-	{
-	  /*
-	   * The spinlock has been initialised while we were waiting
-	   * so assume it's in use.
-	   */
-	  result = EBUSY;
-	}
-
-       ptw32_mcs_lock_release(&node);
-    }
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_spin_init.c b/deps/w32-pthreads/pthread_spin_init.c
deleted file mode 100644
index 268372b..0000000
--- a/deps/w32-pthreads/pthread_spin_init.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * pthread_spin_init.c
- *
- * Description:
- * This translation unit implements spin lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_spin_init (pthread_spinlock_t * lock, int pshared)
-{
-  pthread_spinlock_t s;
-  int cpus = 0;
-  int result = 0;
-
-  if (lock == NULL)
-    {
-      return EINVAL;
-    }
-
-  if (0 != ptw32_getprocessors (&cpus))
-    {
-      cpus = 1;
-    }
-
-  if (cpus > 1)
-    {
-      if (pshared == PTHREAD_PROCESS_SHARED)
-	{
-	  /*
-	   * Creating spinlock that can be shared between
-	   * processes.
-	   */
-#if _POSIX_THREAD_PROCESS_SHARED >= 0
-
-	  /*
-	   * Not implemented yet.
-	   */
-
-#error ERROR [__FILE__, line __LINE__]: Process shared spin locks are not supported yet.
-
-#else
-
-	  return ENOSYS;
-
-#endif /* _POSIX_THREAD_PROCESS_SHARED */
-
-	}
-    }
-
-  s = (pthread_spinlock_t) calloc (1, sizeof (*s));
-
-  if (s == NULL)
-    {
-      return ENOMEM;
-    }
-
-  if (cpus > 1)
-    {
-      s->u.cpus = cpus;
-      s->interlock = PTW32_SPIN_UNLOCKED;
-    }
-  else
-    {
-      pthread_mutexattr_t ma;
-      result = pthread_mutexattr_init (&ma);
-
-      if (0 == result)
-	{
-	  ma->pshared = pshared;
-	  result = pthread_mutex_init (&(s->u.mutex), &ma);
-	  if (0 == result)
-	    {
-	      s->interlock = PTW32_SPIN_USE_MUTEX;
-	    }
-	}
-      (void) pthread_mutexattr_destroy (&ma);
-    }
-
-  if (0 == result)
-    {
-      *lock = s;
-    }
-  else
-    {
-      (void) free (s);
-      *lock = NULL;
-    }
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/pthread_spin_lock.c b/deps/w32-pthreads/pthread_spin_lock.c
deleted file mode 100644
index 67d6e0c..0000000
--- a/deps/w32-pthreads/pthread_spin_lock.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * pthread_spin_lock.c
- *
- * Description:
- * This translation unit implements spin lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_spin_lock (pthread_spinlock_t * lock)
-{
-  register pthread_spinlock_t s;
-
-  if (NULL == lock || NULL == *lock)
-    {
-      return (EINVAL);
-    }
-
-  if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
-    {
-      int result;
-
-      if ((result = ptw32_spinlock_check_need_init (lock)) != 0)
-	{
-	  return (result);
-	}
-    }
-
-  s = *lock;
-
-  while ((PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED ==
-	 PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock,
-					          (PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED,
-					          (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED))
-    {
-    }
-
-  if (s->interlock == PTW32_SPIN_LOCKED)
-    {
-      return 0;
-    }
-  else if (s->interlock == PTW32_SPIN_USE_MUTEX)
-    {
-      return pthread_mutex_lock (&(s->u.mutex));
-    }
-
-  return EINVAL;
-}
diff --git a/deps/w32-pthreads/pthread_spin_trylock.c b/deps/w32-pthreads/pthread_spin_trylock.c
deleted file mode 100644
index a300773..0000000
--- a/deps/w32-pthreads/pthread_spin_trylock.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * pthread_spin_trylock.c
- *
- * Description:
- * This translation unit implements spin lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_spin_trylock (pthread_spinlock_t * lock)
-{
-  register pthread_spinlock_t s;
-
-  if (NULL == lock || NULL == *lock)
-    {
-      return (EINVAL);
-    }
-
-  if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
-    {
-      int result;
-
-      if ((result = ptw32_spinlock_check_need_init (lock)) != 0)
-	{
-	  return (result);
-	}
-    }
-
-  s = *lock;
-
-  switch ((long)
-	  PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock,
-					           (PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED,
-					           (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED))
-    {
-    case PTW32_SPIN_UNLOCKED:
-      return 0;
-    case PTW32_SPIN_LOCKED:
-      return EBUSY;
-    case PTW32_SPIN_USE_MUTEX:
-      return pthread_mutex_trylock (&(s->u.mutex));
-    }
-
-  return EINVAL;
-}
diff --git a/deps/w32-pthreads/pthread_spin_unlock.c b/deps/w32-pthreads/pthread_spin_unlock.c
deleted file mode 100644
index cfb2428..0000000
--- a/deps/w32-pthreads/pthread_spin_unlock.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * pthread_spin_unlock.c
- *
- * Description:
- * This translation unit implements spin lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-pthread_spin_unlock (pthread_spinlock_t * lock)
-{
-  register pthread_spinlock_t s;
-
-  if (NULL == lock || NULL == *lock)
-    {
-      return (EINVAL);
-    }
-
-  s = *lock;
-
-  if (s == PTHREAD_SPINLOCK_INITIALIZER)
-    {
-      return EPERM;
-    }
-
-  switch ((long)
-	  PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock,
-					      (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED,
-					      (PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED))
-    {
-    case PTW32_SPIN_LOCKED:
-    case PTW32_SPIN_UNLOCKED:
-      return 0;
-    case PTW32_SPIN_USE_MUTEX:
-      return pthread_mutex_unlock (&(s->u.mutex));
-    }
-
-  return EINVAL;
-}
diff --git a/deps/w32-pthreads/pthread_testcancel.c b/deps/w32-pthreads/pthread_testcancel.c
deleted file mode 100644
index 1cccc33..0000000
--- a/deps/w32-pthreads/pthread_testcancel.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * pthread_testcancel.c
- *
- * Description:
- * POSIX thread functions related to thread cancellation.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-void
-pthread_testcancel (void)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function creates a deferred cancellation point
-      *      in the calling thread. The call has no effect if the
-      *      current cancelability state is
-      *              PTHREAD_CANCEL_DISABLE
-      *
-      * PARAMETERS
-      *      N/A
-      *
-      *
-      * DESCRIPTION
-      *      This function creates a deferred cancellation point
-      *      in the calling thread. The call has no effect if the
-      *      current cancelability state is
-      *              PTHREAD_CANCEL_DISABLE
-      *
-      *      NOTES:
-      *      1)      Cancellation is asynchronous. Use pthread_join
-      *              to wait for termination of thread if necessary
-      *
-      * RESULTS
-      *              N/A
-      *
-      * ------------------------------------------------------
-      */
-{
-  ptw32_mcs_local_node_t stateLock;
-  pthread_t self = pthread_self ();
-  ptw32_thread_t * sp = (ptw32_thread_t *) self.p;
-
-  if (sp == NULL)
-    {
-      return;
-    }
-
-  /*
-   * Pthread_cancel() will have set sp->state to PThreadStateCancelPending
-   * and set an event, so no need to enter kernel space if
-   * sp->state != PThreadStateCancelPending - that only slows us down.
-   */
-  if (sp->state != PThreadStateCancelPending)
-    {
-      return;
-    }
-
-  ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
-
-  if (sp->cancelState != PTHREAD_CANCEL_DISABLE)
-    {
-      ResetEvent(sp->cancelEvent);
-      sp->state = PThreadStateCanceling;
-      sp->cancelState = PTHREAD_CANCEL_DISABLE;
-      ptw32_mcs_lock_release (&stateLock);
-      ptw32_throw (PTW32_EPS_CANCEL);
-      /* Never returns here */
-    }
-
-  ptw32_mcs_lock_release (&stateLock);
-}				/* pthread_testcancel */
diff --git a/deps/w32-pthreads/pthread_timechange_handler_np.c b/deps/w32-pthreads/pthread_timechange_handler_np.c
deleted file mode 100644
index 0145df2..0000000
--- a/deps/w32-pthreads/pthread_timechange_handler_np.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * pthread_timechange_handler_np.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-/*
- * Notes on handling system time adjustments (especially negative ones).
- * ---------------------------------------------------------------------
- *
- * This solution was suggested by Alexander Terekhov, but any errors
- * in the implementation are mine - [Ross Johnson]
- *
- * 1) The problem: threads doing a timedwait on a CV may expect to timeout
- *    at a specific absolute time according to a system timer. If the
- *    system clock is adjusted backwards then those threads sleep longer than
- *    expected. Also, pthreads-win32 converts absolute times to intervals in
- *    order to make use of the underlying Win32, and so waiting threads may
- *    awake before their proper abstimes.
- *
- * 2) We aren't able to distinquish between threads on timed or untimed waits,
- *    so we wake them all at the time of the adjustment so that they can
- *    re-evaluate their conditions and re-compute their timeouts.
- *
- * 3) We rely on correctly written applications for this to work. Specifically,
- *    they must be able to deal properly with spurious wakeups. That is,
- *    they must re-test their condition upon wakeup and wait again if
- *    the condition is not satisfied.
- */
-
-void *
-pthread_timechange_handler_np (void *arg)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      Broadcasts all CVs to force re-evaluation and
-      *      new timeouts if required.
-      *
-      * PARAMETERS
-      *      NONE
-      *
-      *
-      * DESCRIPTION
-      *      Broadcasts all CVs to force re-evaluation and
-      *      new timeouts if required.
-      *
-      *      This routine may be passed directly to pthread_create()
-      *      as a new thread in order to run asynchronously.
-      *
-      *
-      * RESULTS
-      *              0               successfully broadcast all CVs
-      *              EAGAIN          Not all CVs were broadcast
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  pthread_cond_t cv;
-  ptw32_mcs_local_node_t node;
-
-  ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node);
-
-  cv = ptw32_cond_list_head;
-
-  while (cv != NULL && 0 == result)
-    {
-      result = pthread_cond_broadcast (&cv);
-      cv = cv->next;
-    }
-
-  ptw32_mcs_lock_release(&node);
-
-  return (void *) (size_t) (result != 0 ? EAGAIN : 0);
-}
diff --git a/deps/w32-pthreads/pthread_win32_attach_detach_np.c b/deps/w32-pthreads/pthread_win32_attach_detach_np.c
deleted file mode 100644
index d17cabc..0000000
--- a/deps/w32-pthreads/pthread_win32_attach_detach_np.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * pthread_win32_attach_detach_np.c
- *
- * Description:
- * This translation unit implements non-portable thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-#include <tchar.h>
-
-/*
- * Handle to quserex.dll 
- */
-static HINSTANCE ptw32_h_quserex;
-
-BOOL
-pthread_win32_process_attach_np ()
-{
-  TCHAR QuserExDLLPathBuf[1024];
-  BOOL result = TRUE;
-
-  result = ptw32_processInitialize ();
-
-#if defined(_UWIN)
-  pthread_count++;
-#endif
-
-#if defined(__GNUC__)
-  ptw32_features = 0;
-#else
-  /*
-   * This is obsolete now.
-   */
-  ptw32_features = PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE;
-#endif
-
-  /*
-   * Load QUSEREX.DLL and try to get address of QueueUserAPCEx.
-   * Because QUSEREX.DLL requires a driver to be installed we will
-   * assume the DLL is in the system directory.
-   *
-   * This should take care of any security issues.
-   */
-#if defined(__GNUC__) || _MSC_VER < 1400
-  if(GetSystemDirectory(QuserExDLLPathBuf, sizeof(QuserExDLLPathBuf)))
-  {
-    (void) strncat(QuserExDLLPathBuf,
-                   "\\QUSEREX.DLL",
-                   sizeof(QuserExDLLPathBuf) - strlen(QuserExDLLPathBuf) - 1);
-    ptw32_h_quserex = LoadLibrary(QuserExDLLPathBuf);
-  }
-#else
-  /* strncat is secure - this is just to avoid a warning */
-  if(GetSystemDirectory(QuserExDLLPathBuf, sizeof(QuserExDLLPathBuf) / sizeof(TCHAR)) &&
-     0 == _tcsncat_s(QuserExDLLPathBuf, sizeof(QuserExDLLPathBuf) / sizeof(TCHAR), TEXT("\\QUSEREX.DLL"), 12))
-  {
-    ptw32_h_quserex = LoadLibrary(QuserExDLLPathBuf);
-  }
-#endif
-
-  if (ptw32_h_quserex != NULL)
-    {
-      ptw32_register_cancelation = (DWORD (*)(PAPCFUNC, HANDLE, DWORD))
-#if defined(NEED_UNICODE_CONSTS)
-	GetProcAddress (ptw32_h_quserex,
-			(const TCHAR *) TEXT ("QueueUserAPCEx"));
-#else
-	GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx");
-#endif
-    }
-
-  if (NULL == ptw32_register_cancelation)
-    {
-      ptw32_register_cancelation = ptw32_RegisterCancelation;
-
-      if (ptw32_h_quserex != NULL)
-	{
-	  (void) FreeLibrary (ptw32_h_quserex);
-	}
-      ptw32_h_quserex = 0;
-    }
-  else
-    {
-      /* Initialise QueueUserAPCEx */
-      BOOL (*queue_user_apc_ex_init) (VOID);
-
-      queue_user_apc_ex_init = (BOOL (*)(VOID))
-#if defined(NEED_UNICODE_CONSTS)
-	GetProcAddress (ptw32_h_quserex,
-			(const TCHAR *) TEXT ("QueueUserAPCEx_Init"));
-#else
-	GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx_Init");
-#endif
-
-      if (queue_user_apc_ex_init == NULL || !queue_user_apc_ex_init ())
-	{
-	  ptw32_register_cancelation = ptw32_RegisterCancelation;
-
-	  (void) FreeLibrary (ptw32_h_quserex);
-	  ptw32_h_quserex = 0;
-	}
-    }
-
-  if (ptw32_h_quserex)
-    {
-      ptw32_features |= PTW32_ALERTABLE_ASYNC_CANCEL;
-    }
-
-  return result;
-}
-
-
-BOOL
-pthread_win32_process_detach_np ()
-{
-  if (ptw32_processInitialized)
-    {
-      ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
-
-      if (sp != NULL)
-	{
-	  /*
-	   * Detached threads have their resources automatically
-	   * cleaned up upon exit (others must be 'joined').
-	   */
-	  if (sp->detachState == PTHREAD_CREATE_DETACHED)
-	    {
-	      ptw32_threadDestroy (sp->ptHandle);
-	      TlsSetValue (ptw32_selfThreadKey->key, NULL);
-	    }
-	}
-
-      /*
-       * The DLL is being unmapped from the process's address space
-       */
-      ptw32_processTerminate ();
-
-      if (ptw32_h_quserex)
-	{
-	  /* Close QueueUserAPCEx */
-	  BOOL (*queue_user_apc_ex_fini) (VOID);
-
-	  queue_user_apc_ex_fini = (BOOL (*)(VOID))
-#if defined(NEED_UNICODE_CONSTS)
-	    GetProcAddress (ptw32_h_quserex,
-			    (const TCHAR *) TEXT ("QueueUserAPCEx_Fini"));
-#else
-	    GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx_Fini");
-#endif
-
-	  if (queue_user_apc_ex_fini != NULL)
-	    {
-	      (void) queue_user_apc_ex_fini ();
-	    }
-	  (void) FreeLibrary (ptw32_h_quserex);
-	}
-    }
-
-  return TRUE;
-}
-
-BOOL
-pthread_win32_thread_attach_np ()
-{
-  return TRUE;
-}
-
-BOOL
-pthread_win32_thread_detach_np ()
-{
-  if (ptw32_processInitialized)
-    {
-      /*
-       * Don't use pthread_self() - to avoid creating an implicit POSIX thread handle
-       * unnecessarily.
-       */
-      ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
-
-      if (sp != NULL) // otherwise Win32 thread with no implicit POSIX handle.
-	{
-          ptw32_mcs_local_node_t stateLock;
-	  ptw32_callUserDestroyRoutines (sp->ptHandle);
-
-	  ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
-	  sp->state = PThreadStateLast;
-	  /*
-	   * If the thread is joinable at this point then it MUST be joined
-	   * or detached explicitly by the application.
-	   */
-	  ptw32_mcs_lock_release (&stateLock);
-
-          /*
-           * Robust Mutexes
-           */
-          while (sp->robustMxList != NULL)
-            {
-              pthread_mutex_t mx = sp->robustMxList->mx;
-              ptw32_robust_mutex_remove(&mx, sp);
-              (void) PTW32_INTERLOCKED_EXCHANGE_LONG(
-                       (PTW32_INTERLOCKED_LONGPTR)&mx->robustNode->stateInconsistent,
-                       (PTW32_INTERLOCKED_LONG)-1);
-              /*
-               * If there are no waiters then the next thread to block will
-               * sleep, wakeup immediately and then go back to sleep.
-               * See pthread_mutex_lock.c.
-               */
-              SetEvent(mx->event);
-            }
-
-
-	  if (sp->detachState == PTHREAD_CREATE_DETACHED)
-	    {
-	      ptw32_threadDestroy (sp->ptHandle);
-
-	      TlsSetValue (ptw32_selfThreadKey->key, NULL);
-	    }
-	}
-    }
-
-  return TRUE;
-}
-
-BOOL
-pthread_win32_test_features_np (int feature_mask)
-{
-  return ((ptw32_features & feature_mask) == feature_mask);
-}
diff --git a/deps/w32-pthreads/ptw32_MCS_lock.c b/deps/w32-pthreads/ptw32_MCS_lock.c
deleted file mode 100644
index 5eec5ce..0000000
--- a/deps/w32-pthreads/ptw32_MCS_lock.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * ptw32_MCS_lock.c
- *
- * Description:
- * This translation unit implements queue-based locks.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-/*
- * About MCS locks:
- *
- * MCS locks are queue-based locks, where the queue nodes are local to the
- * thread. The 'lock' is nothing more than a global pointer that points to
- * the last node in the queue, or is NULL if the queue is empty.
- * 
- * Originally designed for use as spin locks requiring no kernel resources
- * for synchronisation or blocking, the implementation below has adapted
- * the MCS spin lock for use as a general mutex that will suspend threads
- * when there is lock contention.
- *
- * Because the queue nodes are thread-local, most of the memory read/write
- * operations required to add or remove nodes from the queue do not trigger
- * cache-coherence updates.
- *
- * Like 'named' mutexes, MCS locks consume system resources transiently -
- * they are able to acquire and free resources automatically - but MCS
- * locks do not require any unique 'name' to identify the lock to all
- * threads using it.
- *
- * Usage of MCS locks:
- *
- * - you need a global ptw32_mcs_lock_t instance initialised to 0 or NULL.
- * - you need a local thread-scope ptw32_mcs_local_node_t instance, which
- *   may serve several different locks but you need at least one node for
- *   every lock held concurrently by a thread.
- *
- * E.g.:
- * 
- * ptw32_mcs_lock_t lock1 = 0;
- * ptw32_mcs_lock_t lock2 = 0;
- *
- * void *mythread(void *arg)
- * {
- *   ptw32_mcs_local_node_t node;
- *
- *   ptw32_mcs_acquire (&lock1, &node);
- *   ptw32_mcs_lock_release (&node);
- *
- *   ptw32_mcs_lock_acquire (&lock2, &node);
- *   ptw32_mcs_lock_release (&node);
- *   {
- *      ptw32_mcs_local_node_t nodex;
- *
- *      ptw32_mcs_lock_acquire (&lock1, &node);
- *      ptw32_mcs_lock_acquire (&lock2, &nodex);
- *
- *      ptw32_mcs_lock_release (&nodex);
- *      ptw32_mcs_lock_release (&node);
- *   }
- *   return (void *)0;
- * }
- */
-
-#include "pthread.h"
-#include "sched.h"
-#include "implement.h"
-
-/*
- * ptw32_mcs_flag_set -- notify another thread about an event.
- * 
- * Set event if an event handle has been stored in the flag, and
- * set flag to -1 otherwise. Note that -1 cannot be a valid handle value.
- */
-INLINE void 
-ptw32_mcs_flag_set (HANDLE * flag)
-{
-  HANDLE e = (HANDLE)(PTW32_INTERLOCKED_SIZE)PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
-						(PTW32_INTERLOCKED_SIZEPTR)flag,
-						(PTW32_INTERLOCKED_SIZE)-1,
-						(PTW32_INTERLOCKED_SIZE)0);
-  if ((HANDLE)0 != e)
-    {
-      /* another thread has already stored an event handle in the flag */
-      SetEvent(e);
-    }
-}
-
-/*
- * ptw32_mcs_flag_set -- wait for notification from another.
- * 
- * Store an event handle in the flag and wait on it if the flag has not been
- * set, and proceed without creating an event otherwise.
- */
-INLINE void 
-ptw32_mcs_flag_wait (HANDLE * flag)
-{
-  if ((PTW32_INTERLOCKED_LONG)0 ==
-        PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)flag,
-                                            (PTW32_INTERLOCKED_SIZE)0)) /* MBR fence */
-    {
-      /* the flag is not set. create event. */
-
-      HANDLE e = CreateEvent(NULL, PTW32_FALSE, PTW32_FALSE, NULL);
-
-      if ((PTW32_INTERLOCKED_SIZE)0 == PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
-			                  (PTW32_INTERLOCKED_SIZEPTR)flag,
-			                  (PTW32_INTERLOCKED_SIZE)e,
-			                  (PTW32_INTERLOCKED_SIZE)0))
-	{
-	  /* stored handle in the flag. wait on it now. */
-	  WaitForSingleObject(e, INFINITE);
-	}
-
-      CloseHandle(e);
-    }
-}
-
-/*
- * ptw32_mcs_lock_acquire -- acquire an MCS lock.
- * 
- * See: 
- * J. M. Mellor-Crummey and M. L. Scott.
- * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors.
- * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991.
- */
-#if defined(PTW32_BUILD_INLINED)
-INLINE 
-#endif /* PTW32_BUILD_INLINED */
-void 
-ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node)
-{
-  ptw32_mcs_local_node_t  *pred;
-  
-  node->lock = lock;
-  node->nextFlag = 0;
-  node->readyFlag = 0;
-  node->next = 0; /* initially, no successor */
-  
-  /* queue for the lock */
-  pred = (ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock,
-								  (PTW32_INTERLOCKED_PVOID)node);
-
-  if (0 != pred)
-    {
-      /* the lock was not free. link behind predecessor. */
-      pred->next = node;
-      ptw32_mcs_flag_set(&pred->nextFlag);
-      ptw32_mcs_flag_wait(&node->readyFlag);
-    }
-}
-
-/*
- * ptw32_mcs_lock_release -- release an MCS lock.
- * 
- * See: 
- * J. M. Mellor-Crummey and M. L. Scott.
- * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors.
- * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991.
- */
-#if defined(PTW32_BUILD_INLINED)
-INLINE 
-#endif /* PTW32_BUILD_INLINED */
-void 
-ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node)
-{
-  ptw32_mcs_lock_t *lock = node->lock;
-  ptw32_mcs_local_node_t *next =
-    (ptw32_mcs_local_node_t *)
-      PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)&node->next, (PTW32_INTERLOCKED_SIZE)0); /* MBR fence */
-
-  if (0 == next)
-    {
-      /* no known successor */
-
-      if (node == (ptw32_mcs_local_node_t *)
-	  PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock,
-						 (PTW32_INTERLOCKED_PVOID)0,
-						 (PTW32_INTERLOCKED_PVOID)node))
-	{
-	  /* no successor, lock is free now */
-	  return;
-	}
-  
-      /* A successor has started enqueueing behind us so wait for them to link to us */
-      ptw32_mcs_flag_wait(&node->nextFlag);
-      next = (ptw32_mcs_local_node_t *)
-	PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)&node->next, (PTW32_INTERLOCKED_SIZE)0); /* MBR fence */
-    }
-
-  /* pass the lock */
-  ptw32_mcs_flag_set(&next->readyFlag);
-}
-
-/*
-  * ptw32_mcs_lock_try_acquire
- */
-#if defined(PTW32_BUILD_INLINED)
-INLINE 
-#endif /* PTW32_BUILD_INLINED */
-int 
-ptw32_mcs_lock_try_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node)
-{
-  node->lock = lock;
-  node->nextFlag = 0;
-  node->readyFlag = 0;
-  node->next = 0; /* initially, no successor */
-
-  return ((PTW32_INTERLOCKED_PVOID)PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock,
-                                                        (PTW32_INTERLOCKED_PVOID)node,
-                                                        (PTW32_INTERLOCKED_PVOID)0)
-                                 == (PTW32_INTERLOCKED_PVOID)0) ? 0 : EBUSY;
-}
-
-/*
- * ptw32_mcs_node_transfer -- move an MCS lock local node, usually from thread
- * space to, for example, global space so that another thread can release
- * the lock on behalf of the current lock owner.
- *
- * Example: used in pthread_barrier_wait where we want the last thread out of
- * the barrier to release the lock owned by the last thread to enter the barrier
- * (the one that releases all threads but not necessarily the last to leave).
- *
- * Should only be called by the thread that has the lock.
- */
-#if defined(PTW32_BUILD_INLINED)
-INLINE 
-#endif /* PTW32_BUILD_INLINED */
-void 
-ptw32_mcs_node_transfer (ptw32_mcs_local_node_t * new_node, ptw32_mcs_local_node_t * old_node)
-{
-  new_node->lock = old_node->lock;
-  new_node->nextFlag = 0; /* Not needed - used only in initial Acquire */
-  new_node->readyFlag = 0; /* Not needed - we were waiting on this */
-  new_node->next = 0;
-
-  if ((ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)new_node->lock,
-                                                                       (PTW32_INTERLOCKED_PVOID)new_node,
-                                                                       (PTW32_INTERLOCKED_PVOID)old_node)
-       != old_node)
-    {
-      /*
-       * A successor has queued after us, so wait for them to link to us
-       */
-      while (old_node->next == 0)
-        {
-          sched_yield();
-        }
-      new_node->next = old_node->next;
-    }
-}
diff --git a/deps/w32-pthreads/ptw32_OLL_lock.c b/deps/w32-pthreads/ptw32_OLL_lock.c
deleted file mode 100644
index b92b8fa..0000000
--- a/deps/w32-pthreads/ptw32_OLL_lock.c
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- * ptw32_OLL_lock.c
- *
- * Description:
- * This translation unit implements extended reader/writer queue-based locks.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-/*
- * About the OLL lock (Scalable Reader-Writer Lock):
- *
- * OLL locks are queue-based locks similar to the MCS queue lock, where the queue
- * nodes are local to the thread but where reader threads can enter the critical
- * section immediately without going through a central guard lock if there are
- * already readers holding the lock.
- *
- * Covered by United States Patent Application 20100241774 (Oracle)
- */
-
-#include "pthread.h"
-#include "sched.h"
-#include "implement.h"
-
-/*
- * C-SNZI support
- */
-typedef union  ptw32_oll_counter_t_		ptw32_oll_counter_t;
-typedef struct ptw32_oll_snziRoot_t_		ptw32_oll_snziRoot_t;
-typedef struct ptw32_oll_snziNode_t_		ptw32_oll_snziNode_t;
-typedef union  ptw32_oll_snziNodeOrRoot_t_	ptw32_oll_snziNodeOrRoot_t;
-typedef struct ptw32_oll_queryResult_t_		ptw32_oll_queryResult_t;
-typedef struct ptw32_oll_ticket_t_		ptw32_oll_ticket_t;
-typedef struct ptw32_oll_csnzi_t_		ptw32_oll_csnzi_t;
-
-enum
-{
-  ptw32_archWidth	= sizeof(size_t)*8,
-  ptw32_oll_countWidth	= ptw32_archWidth-2
-};
-
-#define PTW32_OLL_MAXREADERS (((size_t)2<<(ptw32_oll_countWidth-1))-1)
-
-union ptw32_oll_counter_t_
-{
-  size_t	word	: ptw32_archWidth;
-  struct
-  {
-    /*
-     * This needs to be a single word
-     *
-     *    ------------------------------------
-     *    | STATE |  ROOT  | COUNT (readers) |
-     *    ------------------------------------
-     *     63 / 31  62 / 30   61 / 29 .. 0
-     */
-    size_t	count	: ptw32_oll_countWidth;
-    size_t	root	: 1;			/* ROOT or NODE */
-    size_t	state	: 1;			/* OPEN or CLOSED (root only) */
-  } internal;
-};
-
-struct ptw32_oll_snziRoot_t_
-{
-  /*
-   * "counter" must be at same offset in both
-   * ptw32_oll_snziNode_t and ptw32_oll_snziRoot_t
-   */
-  ptw32_oll_counter_t	counter;
-};
-
-enum
-{
-  ptw32_oll_snziRoot_open	= 0,
-  ptw32_oll_snziRoot_closed	= 1
-};
-
-enum
-{
-  ptw32_oll_snzi_root	= 0,
-  ptw32_oll_snzi_node	= 1
-};
-
-/*
- * Some common SNZI root whole-word states that can be used to set or compare
- * root words with a single operation.
- */
-ptw32_oll_snziRoot_t ptw32_oll_snziRoot_openAndZero = {.counter.internal.count = 0,
-                                                       .counter.internal.root = ptw32_oll_snzi_root,
-                                                       .counter.internal.state = ptw32_oll_snziRoot_open};
-ptw32_oll_snziRoot_t ptw32_oll_snziRoot_closedAndZero = {.counter.internal.count = 0,
-                                                         .counter.internal.root = ptw32_oll_snzi_root,
-                                                         .counter.internal.state = ptw32_oll_snziRoot_closed};
-
-struct ptw32_oll_queryResult_t_
-{
-  BOOL	nonZero;
-  BOOL	open;
-};
-
-union ptw32_oll_snziNodeOrRoot_t_
-{
-  ptw32_oll_snziRoot_t* rootPtr;
-  ptw32_oll_snziNode_t* nodePtr;
-};
-
-struct ptw32_oll_snziNode_t_
-{
-  /* "counter" must be at same offset in both
-   * ptw32_oll_snziNode_t and ptw32_oll_snziRoot_t
-   */
-  ptw32_oll_counter_t		counter;
-  ptw32_oll_snziNodeOrRoot_t	parentPtr;
-};
-
-struct ptw32_oll_ticket_t_
-{
-  ptw32_oll_snziNodeOrRoot_t	snziNodeOrRoot;
-};
-
-ptw32_oll_ticket_t ptw32_oll_ticket_null = {NULL};
-
-struct ptw32_oll_csnzi_t_
-{
-  ptw32_oll_snziRoot_t	proxyRoot;
-  ptw32_oll_snziNode_t	leafs[];
-};
-
-/*
- * FOLL lock support
- */
-
-typedef struct ptw32_foll_node_t_ ptw32_foll_node_t;
-typedef struct ptw32_foll_local_t_ ptw32_foll_local_t;
-typedef struct ptw32_foll_rwlock_t_ ptw32_foll_rwlock_t;
-
-enum
-{
-  ptw32_srwl_reader,
-  ptw32_srwl_writer
-};
-
-enum
-{
-  ptw32_srwl_free,
-  ptw32_srwl_in_use
-};
-
-struct ptw32_foll_node_t_
-{
-  ptw32_foll_node_t*	qNextPtr;
-  ptw32_oll_csnzi_t*	csnziPtr;
-  ptw32_foll_node_t*	nextPtr;
-  int			kind;
-  int			allocState;
-  BOOL			spin;
-};
-
-struct ptw32_foll_local_t_
-{
-  ptw32_foll_node_t*	rNodePtr; // Default read node. Immutable
-  ptw32_foll_node_t*	wNodePtr; // Write node. Immutable.
-  ptw32_foll_node_t*	departFromPtr; // List node we last arrived at.
-  ptw32_oll_ticket_t	ticket; // C-SNZI ticket
-};
-
-struct ptw32_foll_rwlock_t_
-{
-  ptw32_foll_node_t*	tailPtr;
-  ptw32_foll_node_t*	rNodesPtr; // Head of reader node
-};
-
-/*
- * ShouldArriveAtTree() returns true if:
- *   the compare_exchange in Arrive() fails too often under read access; or
- *   ??
- * Note that this is measured across all access to 
- * this lock, not just this attempt, so that highly
- * read-contended locks will use C-SNZI. Lightly
- * read-contended locks can reduce memory usage and some
- * processing by using the root directly.
- */
-BOOL
-ptw32_oll_ShouldArriveAtTree()
-{
-  return PTW32_FALSE;
-}
-
-size_t
-ptw32_oll_GetLeafForThread()
-{
-  return 0;
-}
-
-/*
- * Only readers call ptw32_oll_Arrive()
- *
- * Checks whether the C-SNZI state is OPEN, and if so,
- * increments the surplus of the C-SNZI by either directly
- * arriving at the root node, or calling TreeArrive on one
- * of the leaf nodes. Returns a ticket pointing to the node
- * that was arrived at. If the state is CLOSED, makes no
- * change and returns a ticket that contains no pointer.
- */
-ptw32_oll_ticket_t
-ptw32_oll_Arrive(ptw32_oll_csnzi_t* csnzi)
-{
-  for (;;)
-  {
-    ptw32_oll_ticket_t ticket;
-    ptw32_oll_snziRoot_t oldProxy = csnzi->proxyRoot;
-    if (oldProxy.counter.internal.state != ptw32_oll_snziRoot_open)
-    {
-      ticket.snziNodeOrRoot.rootPtr = (ptw32_oll_snziRoot_t*)NULL;
-      return ticket;
-    }
-    if (!ptw32_oll_ShouldArriveAtTree())
-    {
-      ptw32_oll_snziRoot_t newProxy = oldProxy;
-      newProxy.counter.internal.count++;
-      if (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
-                (PTW32_INTERLOCKED_SIZEPTR)&csnzi->proxyRoot.counter,
-                (PTW32_INTERLOCKED_SIZE)newProxy.counter.word,
-                (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word)
-          == (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word)
-      {
-        /* Exchange successful */
-        ticket.snziNodeOrRoot.rootPtr = &csnzi->proxyRoot;
-        return ticket;
-      }
-    }
-    else
-    {
-      ptw32_oll_snziNode_t* leafPtr = &csnzi->leafs[ptw32_oll_GetLeafForThread()];
-      ticket.snziNodeOrRoot.nodePtr = (ptw32_oll_TreeArrive(leafPtr) ? leafPtr : (ptw32_oll_snziNode_t*)NULL);
-      return ticket;
-    }
-  }
-}
-
-/*
- * Decrements the C-SNZI surplus. Returns false iff the
- * resulting state is CLOSED and the surplus is zero.
- * Ticket must have been returned by an arrival. Must have
- * received this ticket from Arrive more times than Depart
- * has been called with the ticket. (Thus, the surplus
- * must be greater than zero.)
- */
-BOOL
-ptw32_oll_Depart(ptw32_oll_ticket_t ticket)
-{
-  return ptw32_oll_TreeDepart(ticket.snziNodeOrRoot);
-}
-
-/*
- * Increments the C-SNZI surplus and returns true if the
- * C-SNZI is open or has a surplus. Calls TreeArrive
- * recursively on the node’s parent if needed.
- * Otherwise, returns false without making any changes.
- */
-BOOL
-ptw32_oll_TreeArrive(ptw32_oll_snziNodeOrRoot_t snziNodeOrRoot)
-{
-  if (snziNodeOrRoot.nodePtr->counter.internal.root != ptw32_oll_snzi_root)
-  {
-    /* Non-root node */
-    ptw32_oll_counter_t newCounter, oldCounter;
-    BOOL arrivedAtParent = PTW32_FALSE;
-    do
-    {
-      oldCounter = snziNodeOrRoot.nodePtr->counter;
-      if (0 == oldCounter.internal.count && !arrivedAtParent)
-      {
-        if (ptw32_oll_TreeArrive(snziNodeOrRoot.nodePtr->parentPtr))
-          arrivedAtParent = PTW32_TRUE;
-        else
-          return PTW32_FALSE;
-      }
-      newCounter = oldCounter;
-      newCounter.internal.count++;
-    } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
-                  (PTW32_INTERLOCKED_SIZEPTR)&snziNodeOrRoot.nodePtr->counter,
-                  (PTW32_INTERLOCKED_SIZE)newCounter.word,
-                  (PTW32_INTERLOCKED_SIZE)oldCounter.word)
-             != (PTW32_INTERLOCKED_SIZE)oldCounter.word);
-    if (newCounter.internal.count != 0 && arrivedAtParent)
-      ptw32_oll_TreeDepart(snziNodeOrRoot.nodePtr->parentPtr);
-    return PTW32_TRUE;
-  }
-  else
-  {
-    /* Root node */
-    ptw32_oll_snziRoot_t newRoot, oldRoot;
-    do
-    {
-      oldRoot = *(ptw32_oll_snziRoot_t*)snziNodeOrRoot.rootPtr;
-      if (oldRoot.counter.word == ptw32_oll_snziRoot_closedAndZero.counter.word)
-        return PTW32_FALSE;
-      newRoot = oldRoot;
-      newRoot.counter.internal.count++;
-    } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
-                   (PTW32_INTERLOCKED_SIZEPTR)&snziNodeOrRoot.rootPtr->counter,
-                   (PTW32_INTERLOCKED_SIZE)newRoot.counter.word,
-                   (PTW32_INTERLOCKED_SIZE)oldRoot.counter.word)
-             != (PTW32_INTERLOCKED_SIZE)oldRoot.counter.word);
-    return PTW32_TRUE;
-  }
-}
-
-/*
- * Decrements the C-SNZI surplus, calling TreeDepart
- * recursively on the node’s parent if needed. Returns
- * false iff the resulting state of the C-SNZI is CLOSED
- * and the surplus is zero. Otherwise, returns true.
- */
-BOOL
-ptw32_oll_TreeDepart(ptw32_oll_snziNodeOrRoot_t snziNodeOrRoot)
-{
-  if (snziNodeOrRoot.nodePtr->counter.internal.root != ptw32_oll_snzi_root)
-  {
-    /* Non-root node */
-    ptw32_oll_counter_t newCounter, oldCounter;
-    do
-    {
-      newCounter = oldCounter = snziNodeOrRoot.nodePtr->counter;
-      newCounter.internal.count--;
-    } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
-                   (PTW32_INTERLOCKED_SIZEPTR)&snziNodeOrRoot.nodePtr->counter,
-                   (PTW32_INTERLOCKED_SIZE)newCounter.word,
-                   (PTW32_INTERLOCKED_SIZE)oldCounter.word)
-             != (PTW32_INTERLOCKED_SIZE)oldCounter.word);
-    return (0 == newCounter.internal.count)
-             ? ptw32_oll_TreeDepart(snziNodeOrRoot.nodePtr->parentPtr)
-             : PTW32_TRUE;
-  }
-  else
-  {
-    /* Root node */
-    ptw32_oll_snziRoot_t newRoot, oldRoot;
-    do
-    {
-      newRoot = oldRoot = *(ptw32_oll_snziRoot_t*)snziNodeOrRoot.rootPtr;
-      newRoot.counter.internal.count--;
-    } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
-                   (PTW32_INTERLOCKED_SIZEPTR)&snziNodeOrRoot.rootPtr->counter,
-                   (PTW32_INTERLOCKED_SIZE)newRoot.counter.word,
-                   (PTW32_INTERLOCKED_SIZE)oldRoot.counter.word)
-             != (PTW32_INTERLOCKED_SIZE)oldRoot.counter.word);
-    return (newRoot.counter.word != ptw32_oll_snziRoot_closedAndZero.counter.word);
-  }
-}
-
-/*
- * Opens a C-SNZI object. Requires C-SNZI state to be
- * CLOSED and the surplus to be zero.
- */
-void
-ptw32_oll_Open(ptw32_oll_csnzi_t* csnziPtr)
-{
-  csnziPtr->proxyRoot = ptw32_oll_snziRoot_openAndZero;
-}
-
-/*
- * Opens a C-SNZI object while atomically performing count
- * arrivals. Requires C-SNZI state to be CLOSED and
- * the surplus to be zero.
- */
-void
-ptw32_oll_OpenWithArrivals(ptw32_oll_csnzi_t* csnziPtr, size_t count, BOOL close)
-{
-  csnziPtr->proxyRoot.counter.internal.count = count;
-  csnziPtr->proxyRoot.counter.internal.state = (close ? ptw32_oll_snziRoot_closed : ptw32_oll_snziRoot_open);
-}
-
-/*
- * Closes a C-SNZI object. Returns true iff the C-SNZI
- * state changed from OPEN to CLOSED and the surplus is
- * zero.
- */
-BOOL
-ptw32_oll_Close(ptw32_oll_csnzi_t* csnziPtr)
-{
-  ptw32_oll_snziRoot_t newProxy, oldProxy;
-  do
-  {
-    oldProxy = csnziPtr->proxyRoot;
-    if (oldProxy.counter.internal.state != ptw32_oll_snziRoot_open)
-    {
-      return PTW32_FALSE;
-    }
-    newProxy = oldProxy;
-    newProxy.counter.internal.state = ptw32_oll_snziRoot_closed;
-  } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
-                 (PTW32_INTERLOCKED_SIZEPTR)&csnziPtr->proxyRoot.counter,
-                 (PTW32_INTERLOCKED_SIZE)newProxy.counter.word,
-                 (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word)
-           != (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word);
-  return (newProxy.counter.word == ptw32_oll_snziRoot_closedAndZero.counter.word);
-}
-
-/*
- * Closes a C-SNZI if its surplus is zero. Otherwise, does
- * nothing. Returns true iff C-SNZI state changed from
- * OPEN to CLOSED.
- */
-BOOL
-ptw32_oll_CloseIfEmpty(ptw32_oll_csnzi_t* csnziPtr)
-{
-  ptw32_oll_snziRoot_t newProxy, oldProxy;
-  do
-  {
-    oldProxy = csnziPtr->proxyRoot;
-    if (oldProxy.counter.word != ptw32_oll_snziRoot_openAndZero.counter.word)
-    {
-      return PTW32_FALSE;
-    }
-    newProxy = ptw32_oll_snziRoot_closedAndZero;
-  } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
-                 (PTW32_INTERLOCKED_SIZEPTR)&csnziPtr->proxyRoot.counter,
-                 (PTW32_INTERLOCKED_SIZE)newProxy.counter.word,
-                 (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word)
-           != (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word);
-  return PTW32_TRUE;
-}
-
-/*
- * Returns whether the C-SNZI has a nonzero surplus and
- * whether the C-SNZI is open.
- * "nonZero" doesn't appear to be used anywhere in the algorithms.
- */
-ptw32_oll_queryResult_t
-ptw32_oll_Query(ptw32_oll_csnzi_t* csnziPtr)
-{
-  ptw32_oll_queryResult_t query;
-  ptw32_oll_snziRoot_t proxy = csnziPtr->proxyRoot;
-
-  query.nonZero = (proxy.counter.internal.count > 0);
-  query.open = (proxy.counter.internal.state == ptw32_oll_snziRoot_open);
-  return query;
-}
-
-/*
- * Returns whether the Arrive operation that returned
- * the ticket succeeded.
- */
-BOOL
-ptw32_oll_Arrived(ptw32_oll_ticket_t t)
-{
-  return (t.snziNodeOrRoot.nodePtr != NULL);
-}
-
-/*
- * Constructs and returns a ticket that can be used to
- * depart from the root node.
- */
-ptw32_oll_ticket_t
-ptw32_oll_DirectTicket(ptw32_oll_csnzi_t* csnziPtr)
-{
-  ptw32_oll_ticket_t ticket;
-  ticket.snziNodeOrRoot.rootPtr = &csnziPtr->proxyRoot;
-  return ticket;
-}
-
-/* Scalable RW Locks */
-
-typedef struct ptw32_srwl_rwlock_t_ ptw32_srwl_rwlock_t;
-typedef struct ptw32_srwl_node_t_ ptw32_srwl_node_t;
-typedef struct ptw32_srwl_local_t_ ptw32_srwl_local_t;
-
-enum
-{
-  ptw32_srwl_reader	= 0,
-  ptw32_srwl_writer	= 1
-};
-
-enum
-{
-  ptw32_srwl_free	= 0,
-  ptw32_srwl_in_use	= 1
-};
-
-struct ptw32_srwl_rwlock_t_
-{
-  ptw32_srwl_node_t* tailPtr;
-  ptw32_srwl_node_t* readerNodePtr;
-};
-
-struct ptw32_srwl_node_t_
-{
-  ptw32_srwl_node_t*	qNextPtr;
-  ptw32_oll_csnzi_t*	csnziPtr;
-  ptw32_srwl_node_t*	nextReaderPtr;
-  int			kind;		/* ptw32_srwl_reader, ptw32_srwl_writer */
-  int			allocState;	/* ptw32_srwl_free, ptw32_srwl_in_use */
-  BOOL			spin;
-};
-
-/*
- * When a ptw32_srwl_local_t is instantiated the "kind" of each of
- * rNode and wNode must be set as appropriate. This is the only
- * time "kind" is set.
- */
-struct ptw32_srwl_local_t_
-{
-  ptw32_srwl_node_t*	rNodePtr;
-  ptw32_srwl_node_t*	wNodePtr;
-  ptw32_srwl_node_t*	departFromPtr;
-  ptw32_oll_ticket_t	ticket;
-};
-
-/* Allocates a new reader node. */
-ptw32_srwl_node_t*
-ptw32_srwl_AllocReaderNode(ptw32_srwl_local_t* local)
-{
-  ptw32_srwl_node_t* currNodePtr = local->rNodePtr;
-  for (;;)
-  {
-    if (currNodePtr->allocState == ptw32_srwl_free)
-    {
-      if (PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
-            (PTW32_INTERLOCKED_LONGPTR)&currNodePtr->allocState,
-            (PTW32_INTERLOCKED_LONG)ptw32_srwl_in_use,
-            (PTW32_INTERLOCKED_LONG)ptw32_srwl_free)
-          == (PTW32_INTERLOCKED_LONG)ptw32_srwl_in_use)
-      {
-        return currNodePtr;
-      }
-    }
-    currNodePtr = currNodePtr->next;
-  }
-}
-
-/*
- * Frees a reader node. Requires that its allocState
- * is ptw32_srwl_in_use.
- */
-void
-ptw32_srwl_FreeReaderNode(ptw32_srwl_node_t* nodePtr)
-{
-  nodePtr->allocState := ptw32_srwl_free;
-}
-
-void
-ptw32_srwl_WriterLock(ptw32_srwl_rwlock_t* lockPtr, ptw32_srwl_local_t* localPtr)
-{
-  oldTailPtr = (ptw32_srwl_rwlock_t*)PTW32_INTERLOCKED_EXCHANGE_PTR(
-                                       (PTW32_INTERLOCKED_PVOID_PTR)&lockPtr->tailPtr,
-                                       (PTW32_INTERLOCKED_PVOID)localPtr->wNodePtr);
-  if (oldTailPtr != NULL)
-  {
-    localPtr->wNodePtr->spin := PTW32_TRUE;
-    oldTailPtr->qNextPtr = localPtr->wNodePtr;
-    if (oldTailPtr->kind == ptw32_srwl_writer)
-    {
-      while (localPtr->wNodePtr->spin);
-    }
-    else
-    {
-      /* Wait until node is properly recycled */
-      while (ptw32_oll_Query(oldTailPtr->csnzi).open);
-      /*
-       * Close C-SNZI of previous reader node.
-       * If there are no readers to signal us, spin on
-       * previous node and free it before entering
-       * critical section.
-       */
-      if (ptw32_oll_Close(oldTailPtr->csnzi))
-      {
-        while (oldTailPtr->spin);
-        ptw32_srwl_FreeReaderNode(oldTailPtr);
-      }
-      else
-      {
-        while (localPtr->wNodePtr->spin);
-      }
-    }
-  }
-}
-
-void
-ptw32_srwl_WriterUnlock(ptw32_srwl_rwlock_t* lockPtr, ptw32_srwl_local_t* localPtr)
-{
-  if (localPtr->wNodePtr->qNextPtr == NULL)
-  {
-    if (PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(
-              (PTW32_INTERLOCKED_PVOIDPTR)&lockPtr->tailPtr,
-              (PTW32_INTERLOCKED_PVOID)NULL,
-              (PTW32_INTERLOCKED_PVOID)localPtr->wNodePtr)
-        == (PTW32_INTERLOCKED_PVOID)NULL)
-    {
-      return;
-    }
-    else
-    {
-      while (localPtr->wNodePtr->qNextPtr == NULL);
-    }
-  }
-  /* Clean up */
-  localPtr->wNodePtr->qNextPtr->spin = PTW32_FALSE;
-  localPtr->wNodePtr->qNextPtr = NULL;
-}
-
-void
-ptw32_srwl_ReaderLock(ptw32_srwl_rwlock_t* lockPtr, ptw32_srwl_local_t* localPtr)
-{
-  ptw32_srwl_node_t* rNodePtr = NULL;
-  for (;;)
-  {
-    ptw32_srwl_node_t* tailPtr = lockPtr->tailPtr;
-    /* If no nodes are in the queue */
-    if (tailPtr == NULL)
-    {
-      if (rNodePtr == NULL)
-      {
-        rNodePtr = ptw32_srwl_AllocReaderNode(localPtr);
-      }
-      rNodePtr->spin = PTW32_FALSE;
-      if (PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(
-                (PTW32_INTERLOCKED_PVOIDPTR)&lockPtr->tailPtr,
-                (PTW32_INTERLOCKED_PVOID)rNodePtr,
-                (PTW32_INTERLOCKED_PVOID)NULL)
-          == (PTW32_INTERLOCKED_PVOID)rNodePtr)
-      {
-        ptw32_oll_Open(rNodePtr->csnzi);
-        localPtr->ticket = ptw32_oll_Arrive(rNodePtr->csnzi);
-        if (ptw32_oll_Arrived(localPtr->ticket))
-        {
-          localPtr->departFromPtr = rNodePtr;
-          return;
-        }
-        /* Avoid reusing inserted node */
-        rNodePtr = NULL;
-      }
-    }
-    /* Otherwise, there is a node in the queue */
-    else
-    {
-      /* Is last node a writer node? */
-      if (tailPtr->kind == ptw32_srwl_writer)
-      {
-        if (rNodePtr == NULL)
-        {
-          rNodePtr = ptw32_srwl_AllocReaderNode(localPtr);
-        }
-        rNodePtr->spin = PTW32_TRUE;
-        if (PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(
-                  (PTW32_INTERLOCKED_PVOIDPTR)&lockPtr->tailPtr,
-                  (PTW32_INTERLOCKED_PVOID)rNodePtr,
-                  (PTW32_INTERLOCKED_PVOID)tailPtr)
-            == (PTW32_INTERLOCKED_PVOID)rNodePtr)
-        {
-          tailPtr->qNextPtr = rNodePtr;
-          localPtr->ticket = ptw32_oll_Arrive(rNodePtr->csnzi);
-          if (ptw32_oll_Arrived(localPtr->ticket))
-          {
-            localPtr->departFromPtr = rNodePtr;
-            while (rNodePtr->spin);
-            return;
-          }
-          /* Avoid reusing inserted node */
-          rNodePtr = NULL;
-        }
-      }
-      /*
-       * Otherwise, last node is a reader node.
-       * (tailPtr->kind == ptw32_srwl_reader)
-       */
-      else
-      {
-        localPtr->ticket = ptw32_oll_Arrive(tailPtr->csnzi);
-        if (ptw32_oll_Arrived(localPtr->ticket))
-        {
-          if (rNodePtr != NULL)
-          {
-            ptw32_srwl_FreeReaderNode(rNodePtr);
-          }
-          localPtr->departFromPtr = tailPtr;
-          while (tailPtr->spin);
-          return;
-        }
-      }
-    }
-  }
-}
-
-void
-ptw32_srwl_ReaderUnlock(ptw32_srwl_rwlock_t* lockPtr, ptw32_srwl_local_t* localPtr)
-{
-  if (ptw32_oll_Depart(localPtr->departFromPtr->csnzi, localPtr->ticket))
-  {
-    return;
-  }
-  /* Clean up */
-  localPtr->departFromPtr->qNextPtr->spin = PTW32_FALSE;
-  localPtr->departFromPtr->qNextPtr = NULL;
-  ptw32_srwl_FreeReaderNode(localPtr->departFromPtr);
-}
-
-
-#include <stdio.h>
-
-int main()
-{
-  printf("%lx\n", PTW32_OLL_MAXREADERS);
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/ptw32_callUserDestroyRoutines.c b/deps/w32-pthreads/ptw32_callUserDestroyRoutines.c
deleted file mode 100644
index ab15f2c..0000000
--- a/deps/w32-pthreads/ptw32_callUserDestroyRoutines.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * ptw32_callUserDestroyRoutines.c
- *
- * Description:
- * This translation unit implements routines which are private to
- * the implementation and may be used throughout it.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-#if defined(__CLEANUP_CXX)
-# if defined(_MSC_VER)
-#  include <eh.h>
-# elif defined(__WATCOMC__)
-#  include <eh.h>
-#  include <exceptio.h>
-# else
-#  if defined(__GNUC__) && __GNUC__ < 3
-#    include <new.h>
-#  else
-#    include <new>
-     using
-       std::terminate;
-#  endif
-# endif
-#endif
-
-void
-ptw32_callUserDestroyRoutines (pthread_t thread)
-     /*
-      * -------------------------------------------------------------------
-      * DOCPRIVATE
-      *
-      * This the routine runs through all thread keys and calls
-      * the destroy routines on the user's data for the current thread.
-      * It simulates the behaviour of POSIX Threads.
-      *
-      * PARAMETERS
-      *              thread
-      *                      an instance of pthread_t
-      *
-      * RETURNS
-      *              N/A
-      * -------------------------------------------------------------------
-      */
-{
-  ThreadKeyAssoc * assoc;
-
-  if (thread.p != NULL)
-    {
-      ptw32_mcs_local_node_t threadLock;
-      ptw32_mcs_local_node_t keyLock;
-      int assocsRemaining;
-      int iterations = 0;
-      ptw32_thread_t * sp = (ptw32_thread_t *) thread.p;
-
-      /*
-       * Run through all Thread<-->Key associations
-       * for the current thread.
-       *
-       * Do this process at most PTHREAD_DESTRUCTOR_ITERATIONS times.
-       */
-      do
-	{
-	  assocsRemaining = 0;
-	  iterations++;
-
-	  ptw32_mcs_lock_acquire(&(sp->threadLock), &threadLock);
-	  /*
-	   * The pointer to the next assoc is stored in the thread struct so that
-	   * the assoc destructor in pthread_key_delete can adjust it
-	   * if it deletes this assoc. This can happen if we fail to acquire
-	   * both locks below, and are forced to release all of our locks,
-	   * leaving open the opportunity for pthread_key_delete to get in
-	   * before us.
-	   */
-	  sp->nextAssoc = sp->keys;
-	  ptw32_mcs_lock_release(&threadLock);
-
-	  for (;;)
-	    {
-	      void * value;
-	      pthread_key_t k;
-	      void (*destructor) (void *);
-
-	      /*
-	       * First we need to serialise with pthread_key_delete by locking
-	       * both assoc guards, but in the reverse order to our convention,
-	       * so we must be careful to avoid deadlock.
-	       */
-	      ptw32_mcs_lock_acquire(&(sp->threadLock), &threadLock);
-
-	      if ((assoc = (ThreadKeyAssoc *)sp->nextAssoc) == NULL)
-		{
-		  /* Finished */
-		  ptw32_mcs_lock_release(&threadLock);
-		  break;
-		}
-	      else
-		{
-		  /*
-		   * assoc->key must be valid because assoc can't change or be
-		   * removed from our chain while we hold at least one lock. If
-		   * the assoc was on our key chain then the key has not been
-		   * deleted yet.
-		   *
-		   * Now try to acquire the second lock without deadlocking.
-		   * If we fail, we need to relinquish the first lock and the
-		   * processor and then try to acquire them all again.
-		   */
-		  if (ptw32_mcs_lock_try_acquire(&(assoc->key->keyLock), &keyLock) == EBUSY)
-		    {
-		      ptw32_mcs_lock_release(&threadLock);
-		      Sleep(0);
-		      /*
-		       * Go around again.
-		       * If pthread_key_delete has removed this assoc in the meantime,
-		       * sp->nextAssoc will point to a new assoc.
-		       */
-		      continue;
-		    }
-		}
-
-	      /* We now hold both locks */
-
-	      sp->nextAssoc = assoc->nextKey;
-
-	      /*
-	       * Key still active; pthread_key_delete
-	       * will block on these same mutexes before
-	       * it can release actual key; therefore,
-	       * key is valid and we can call the destroy
-	       * routine;
-	       */
-	      k = assoc->key;
-	      destructor = k->destructor;
-	      value = TlsGetValue(k->key);
-	      TlsSetValue (k->key, NULL);
-
-	      // Every assoc->key exists and has a destructor
-	      if (value != NULL && iterations <= PTHREAD_DESTRUCTOR_ITERATIONS)
-		{
-		  /*
-		   * Unlock both locks before the destructor runs.
-		   * POSIX says pthread_key_delete can be run from destructors,
-		   * and that probably includes with this key as target.
-		   * pthread_setspecific can also be run from destructors and
-		   * also needs to be able to access the assocs.
-		   */
-		  ptw32_mcs_lock_release(&threadLock);
-		  ptw32_mcs_lock_release(&keyLock);
-
-		  assocsRemaining++;
-
-#if defined(__cplusplus)
-
-		  try
-		    {
-		      /*
-		       * Run the caller's cleanup routine.
-		       */
-		      destructor (value);
-		    }
-		  catch (...)
-		    {
-		      /*
-		       * A system unexpected exception has occurred
-		       * running the user's destructor.
-		       * We get control back within this block in case
-		       * the application has set up it's own terminate
-		       * handler. Since we are leaving the thread we
-		       * should not get any internal pthreads
-		       * exceptions.
-		       */
-		      terminate ();
-		    }
-
-#else /* __cplusplus */
-
-		  /*
-		   * Run the caller's cleanup routine.
-		   */
-		  destructor (value);
-
-#endif /* __cplusplus */
-
-		}
-	      else
-		{
-		  /*
-		   * Remove association from both the key and thread chains
-		   * and reclaim it's memory resources.
-		   */
-		  ptw32_tkAssocDestroy (assoc);
-		  ptw32_mcs_lock_release(&threadLock);
-		  ptw32_mcs_lock_release(&keyLock);
-		}
-	    }
-	}
-      while (assocsRemaining);
-    }
-}				/* ptw32_callUserDestroyRoutines */
diff --git a/deps/w32-pthreads/ptw32_calloc.c b/deps/w32-pthreads/ptw32_calloc.c
deleted file mode 100644
index 7fad76b..0000000
--- a/deps/w32-pthreads/ptw32_calloc.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * ptw32_calloc.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-#if defined(NEED_CALLOC)
-void *
-ptw32_calloc (size_t n, size_t s)
-{
-  unsigned int m = n * s;
-  void *p;
-
-  p = malloc (m);
-  if (p == NULL)
-    return NULL;
-
-  memset (p, 0, m);
-
-  return p;
-}
-#endif
diff --git a/deps/w32-pthreads/ptw32_cond_check_need_init.c b/deps/w32-pthreads/ptw32_cond_check_need_init.c
deleted file mode 100644
index 20b045b..0000000
--- a/deps/w32-pthreads/ptw32_cond_check_need_init.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * ptw32_cond_check_need_init.c
- *
- * Description:
- * This translation unit implements condition variables and their primitives.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-INLINE int
-ptw32_cond_check_need_init (pthread_cond_t * cond)
-{
-  int result = 0;
-  ptw32_mcs_local_node_t node;
-
-  /*
-   * The following guarded test is specifically for statically
-   * initialised condition variables (via PTHREAD_OBJECT_INITIALIZER).
-   */
-  ptw32_mcs_lock_acquire(&ptw32_cond_test_init_lock, &node);
-
-  /*
-   * We got here possibly under race
-   * conditions. Check again inside the critical section.
-   * If a static cv has been destroyed, the application can
-   * re-initialise it only by calling pthread_cond_init()
-   * explicitly.
-   */
-  if (*cond == PTHREAD_COND_INITIALIZER)
-    {
-      result = pthread_cond_init (cond, NULL);
-    }
-  else if (*cond == NULL)
-    {
-      /*
-       * The cv has been destroyed while we were waiting to
-       * initialise it, so the operation that caused the
-       * auto-initialisation should fail.
-       */
-      result = EINVAL;
-    }
-
-  ptw32_mcs_lock_release(&node);
-
-  return result;
-}
diff --git a/deps/w32-pthreads/ptw32_getprocessors.c b/deps/w32-pthreads/ptw32_getprocessors.c
deleted file mode 100644
index 9207491..0000000
--- a/deps/w32-pthreads/ptw32_getprocessors.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * ptw32_getprocessors.c
- *
- * Description:
- * This translation unit implements routines which are private to
- * the implementation and may be used throughout it.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-/*
- * ptw32_getprocessors()
- *
- * Get the number of CPUs available to the process.
- *
- * If the available number of CPUs is 1 then pthread_spin_lock()
- * will block rather than spin if the lock is already owned.
- *
- * pthread_spin_init() calls this routine when initialising
- * a spinlock. If the number of available processors changes
- * (after a call to SetProcessAffinityMask()) then only
- * newly initialised spinlocks will notice.
- */
-int
-ptw32_getprocessors (int *count)
-{
-  DWORD_PTR vProcessCPUs;
-  DWORD_PTR vSystemCPUs;
-  int result = 0;
-
-#if defined(NEED_PROCESS_AFFINITY_MASK)
-
-  *count = 1;
-
-#else
-
-  if (GetProcessAffinityMask (GetCurrentProcess (),
-			      &vProcessCPUs, &vSystemCPUs))
-    {
-      DWORD_PTR bit;
-      int CPUs = 0;
-
-      for (bit = 1; bit != 0; bit <<= 1)
-	{
-	  if (vProcessCPUs & bit)
-	    {
-	      CPUs++;
-	    }
-	}
-      *count = CPUs;
-    }
-  else
-    {
-      result = EAGAIN;
-    }
-
-#endif
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/ptw32_is_attr.c b/deps/w32-pthreads/ptw32_is_attr.c
deleted file mode 100644
index 1b633e1..0000000
--- a/deps/w32-pthreads/ptw32_is_attr.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * ptw32_is_attr.c
- *
- * Description:
- * This translation unit implements operations on thread attribute objects.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-int
-ptw32_is_attr (const pthread_attr_t * attr)
-{
-  /* Return 0 if the attr object is valid, non-zero otherwise. */
-
-  return (attr == NULL ||
-	  *attr == NULL || (*attr)->valid != PTW32_ATTR_VALID);
-}
diff --git a/deps/w32-pthreads/ptw32_mutex_check_need_init.c b/deps/w32-pthreads/ptw32_mutex_check_need_init.c
deleted file mode 100644
index 9574233..0000000
--- a/deps/w32-pthreads/ptw32_mutex_check_need_init.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * ptw32_mutex_check_need_init.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-static struct pthread_mutexattr_t_ ptw32_recursive_mutexattr_s =
-  {PTHREAD_PROCESS_PRIVATE, PTHREAD_MUTEX_RECURSIVE};
-static struct pthread_mutexattr_t_ ptw32_errorcheck_mutexattr_s =
-  {PTHREAD_PROCESS_PRIVATE, PTHREAD_MUTEX_ERRORCHECK};
-static pthread_mutexattr_t ptw32_recursive_mutexattr = &ptw32_recursive_mutexattr_s;
-static pthread_mutexattr_t ptw32_errorcheck_mutexattr = &ptw32_errorcheck_mutexattr_s;
-
-
-INLINE int
-ptw32_mutex_check_need_init (pthread_mutex_t * mutex)
-{
-  register int result = 0;
-  register pthread_mutex_t mtx;
-  ptw32_mcs_local_node_t node;
-
-  ptw32_mcs_lock_acquire(&ptw32_mutex_test_init_lock, &node);
-
-  /*
-   * We got here possibly under race
-   * conditions. Check again inside the critical section
-   * and only initialise if the mutex is valid (not been destroyed).
-   * If a static mutex has been destroyed, the application can
-   * re-initialise it only by calling pthread_mutex_init()
-   * explicitly.
-   */
-  mtx = *mutex;
-
-  if (mtx == PTHREAD_MUTEX_INITIALIZER)
-    {
-      result = pthread_mutex_init (mutex, NULL);
-    }
-  else if (mtx == PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
-    {
-      result = pthread_mutex_init (mutex, &ptw32_recursive_mutexattr);
-    }
-  else if (mtx == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
-    {
-      result = pthread_mutex_init (mutex, &ptw32_errorcheck_mutexattr);
-    }
-  else if (mtx == NULL)
-    {
-      /*
-       * The mutex has been destroyed while we were waiting to
-       * initialise it, so the operation that caused the
-       * auto-initialisation should fail.
-       */
-      result = EINVAL;
-    }
-
-  ptw32_mcs_lock_release(&node);
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/ptw32_new.c b/deps/w32-pthreads/ptw32_new.c
deleted file mode 100644
index b0ba268..0000000
--- a/deps/w32-pthreads/ptw32_new.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * ptw32_new.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-pthread_t
-ptw32_new (void)
-{
-  pthread_t t;
-  pthread_t nil = {NULL, 0};
-  ptw32_thread_t * tp;
-
-  /*
-   * If there's a reusable pthread_t then use it.
-   */
-  t = ptw32_threadReusePop ();
-
-  if (NULL != t.p)
-    {
-      tp = (ptw32_thread_t *) t.p;
-    }
-  else
-    {
-      /* No reuse threads available */
-      tp = (ptw32_thread_t *) calloc (1, sizeof(ptw32_thread_t));
-
-      if (tp == NULL)
-	{
-	  return nil;
-	}
-
-      /* ptHandle.p needs to point to it's parent ptw32_thread_t. */
-      t.p = tp->ptHandle.p = tp;
-      t.x = tp->ptHandle.x = 0;
-    }
-
-  /* Set default state. */
-  tp->seqNumber = ++ptw32_threadSeqNumber;
-  tp->sched_priority = THREAD_PRIORITY_NORMAL;
-  tp->detachState = PTHREAD_CREATE_JOINABLE;
-  tp->cancelState = PTHREAD_CANCEL_ENABLE;
-  tp->cancelType = PTHREAD_CANCEL_DEFERRED;
-  tp->stateLock = 0;
-  tp->threadLock = 0;
-  tp->robustMxListLock = 0;
-  tp->robustMxList = NULL;
-  tp->cancelEvent = CreateEvent (0, (int) PTW32_TRUE,	/* manualReset  */
-				 (int) PTW32_FALSE,	/* setSignaled  */
-				 NULL);
-
-  if (tp->cancelEvent == NULL)
-    {
-      ptw32_threadReusePush (tp->ptHandle);
-      return nil;
-    }
-
-  return t;
-
-}
diff --git a/deps/w32-pthreads/ptw32_processInitialize.c b/deps/w32-pthreads/ptw32_processInitialize.c
deleted file mode 100644
index 4a63df8..0000000
--- a/deps/w32-pthreads/ptw32_processInitialize.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * ptw32_processInitialize.c
- *
- * Description:
- * This translation unit implements routines which are private to
- * the implementation and may be used throughout it.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-ptw32_processInitialize (void)
-     /*
-      * ------------------------------------------------------
-      * DOCPRIVATE
-      *      This function performs process wide initialization for
-      *      the pthread library.
-      *
-      * PARAMETERS
-      *      N/A
-      *
-      * DESCRIPTION
-      *      This function performs process wide initialization for
-      *      the pthread library.
-      *      If successful, this routine sets the global variable
-      *      ptw32_processInitialized to TRUE.
-      *
-      * RESULTS
-      *              TRUE    if successful,
-      *              FALSE   otherwise
-      *
-      * ------------------------------------------------------
-      */
-{
-  if (ptw32_processInitialized)
-    {
-      /* 
-       * Ignore if already initialized. this is useful for 
-       * programs that uses a non-dll pthread
-       * library. Such programs must call ptw32_processInitialize() explicitly,
-       * since this initialization routine is automatically called only when
-       * the dll is loaded.
-       */
-      return PTW32_TRUE;
-    }
-
-  ptw32_processInitialized = PTW32_TRUE;
-
-  /*
-   * Initialize Keys
-   */
-  if ((pthread_key_create (&ptw32_selfThreadKey, NULL) != 0) ||
-      (pthread_key_create (&ptw32_cleanupKey, NULL) != 0))
-    {
-
-      ptw32_processTerminate ();
-    }
-
-  return (ptw32_processInitialized);
-
-}				/* processInitialize */
diff --git a/deps/w32-pthreads/ptw32_processTerminate.c b/deps/w32-pthreads/ptw32_processTerminate.c
deleted file mode 100644
index 8b017a7..0000000
--- a/deps/w32-pthreads/ptw32_processTerminate.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * ptw32_processTerminate.c
- *
- * Description:
- * This translation unit implements routines which are private to
- * the implementation and may be used throughout it.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-void
-ptw32_processTerminate (void)
-     /*
-      * ------------------------------------------------------
-      * DOCPRIVATE
-      *      This function performs process wide termination for
-      *      the pthread library.
-      *
-      * PARAMETERS
-      *      N/A
-      *
-      * DESCRIPTION
-      *      This function performs process wide termination for
-      *      the pthread library.
-      *      This routine sets the global variable
-      *      ptw32_processInitialized to FALSE
-      *
-      * RESULTS
-      *              N/A
-      *
-      * ------------------------------------------------------
-      */
-{
-  if (ptw32_processInitialized)
-    {
-      ptw32_thread_t * tp, * tpNext;
-      ptw32_mcs_local_node_t node;
-
-      if (ptw32_selfThreadKey != NULL)
-	{
-	  /*
-	   * Release ptw32_selfThreadKey
-	   */
-	  pthread_key_delete (ptw32_selfThreadKey);
-
-	  ptw32_selfThreadKey = NULL;
-	}
-
-      if (ptw32_cleanupKey != NULL)
-	{
-	  /*
-	   * Release ptw32_cleanupKey
-	   */
-	  pthread_key_delete (ptw32_cleanupKey);
-
-	  ptw32_cleanupKey = NULL;
-	}
-
-      ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
-
-      tp = ptw32_threadReuseTop;
-      while (tp != PTW32_THREAD_REUSE_EMPTY)
-	{
-	  tpNext = tp->prevReuse;
-	  free (tp);
-	  tp = tpNext;
-	}
-
-      ptw32_mcs_lock_release(&node);
-
-      ptw32_processInitialized = PTW32_FALSE;
-    }
-
-}				/* processTerminate */
diff --git a/deps/w32-pthreads/ptw32_relmillisecs.c b/deps/w32-pthreads/ptw32_relmillisecs.c
deleted file mode 100644
index 5459206..0000000
--- a/deps/w32-pthreads/ptw32_relmillisecs.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * ptw32_relmillisecs.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#if !defined(NEED_FTIME)
-#include <sys/timeb.h>
-#endif
-
-
-#if defined(PTW32_BUILD_INLINED)
-INLINE 
-#endif /* PTW32_BUILD_INLINED */
-DWORD
-ptw32_relmillisecs (const struct timespec * abstime)
-{
-  const int64_t NANOSEC_PER_MILLISEC = 1000000;
-  const int64_t MILLISEC_PER_SEC = 1000;
-  DWORD milliseconds;
-  int64_t tmpAbsMilliseconds;
-  int64_t tmpCurrMilliseconds;
-#if defined(NEED_FTIME)
-  struct timespec currSysTime;
-  FILETIME ft;
-  SYSTEMTIME st;
-#else /* ! NEED_FTIME */
-#if ( defined(_MSC_VER) && _MSC_VER >= 1300 ) || \
-    ( (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 )
-  struct __timeb64 currSysTime;
-#else
-  struct _timeb currSysTime;
-#endif
-#endif /* NEED_FTIME */
-
-
-  /* 
-   * Calculate timeout as milliseconds from current system time. 
-   */
-
-  /*
-   * subtract current system time from abstime in a way that checks
-   * that abstime is never in the past, or is never equivalent to the
-   * defined INFINITE value (0xFFFFFFFF).
-   *
-   * Assume all integers are unsigned, i.e. cannot test if less than 0.
-   */
-  tmpAbsMilliseconds =  (int64_t)abstime->tv_sec * MILLISEC_PER_SEC;
-  tmpAbsMilliseconds += ((int64_t)abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC;
-
-  /* get current system time */
-
-#if defined(NEED_FTIME)
-
-  GetSystemTime(&st);
-  SystemTimeToFileTime(&st, &ft);
-  /*
-   * GetSystemTimeAsFileTime(&ft); would be faster,
-   * but it does not exist on WinCE
-   */
-
-  ptw32_filetime_to_timespec(&ft, &currSysTime);
-
-  tmpCurrMilliseconds = (int64_t)currSysTime.tv_sec * MILLISEC_PER_SEC;
-  tmpCurrMilliseconds += ((int64_t)currSysTime.tv_nsec + (NANOSEC_PER_MILLISEC/2))
-			   / NANOSEC_PER_MILLISEC;
-
-#else /* ! NEED_FTIME */
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-  _ftime64_s(&currSysTime);
-#elif ( defined(_MSC_VER) && _MSC_VER >= 1300 ) || \
-      ( (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 )
-  _ftime64(&currSysTime);
-#else
-  _ftime(&currSysTime);
-#endif
-
-  tmpCurrMilliseconds = (int64_t) currSysTime.time * MILLISEC_PER_SEC;
-  tmpCurrMilliseconds += (int64_t) currSysTime.millitm;
-
-#endif /* NEED_FTIME */
-
-  if (tmpAbsMilliseconds > tmpCurrMilliseconds)
-    {
-      milliseconds = (DWORD) (tmpAbsMilliseconds - tmpCurrMilliseconds);
-      if (milliseconds == INFINITE)
-        {
-          /* Timeouts must be finite */
-          milliseconds--;
-        }
-    }
-  else
-    {
-      /* The abstime given is in the past */
-      milliseconds = 0;
-    }
-
-  return milliseconds;
-}
diff --git a/deps/w32-pthreads/ptw32_reuse.c b/deps/w32-pthreads/ptw32_reuse.c
deleted file mode 100644
index f252528..0000000
--- a/deps/w32-pthreads/ptw32_reuse.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * ptw32_threadReuse.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-/*
- * How it works:
- * A pthread_t is a struct (2x32 bit scalar types on IA-32, 2x64 bit on IA-64)
- * which is normally passed/returned by value to/from pthreads routines.
- * Applications are therefore storing a copy of the struct as it is at that
- * time.
- *
- * The original pthread_t struct plus all copies of it contain the address of
- * the thread state struct ptw32_thread_t_ (p), plus a reuse counter (x). Each
- * ptw32_thread_t contains the original copy of it's pthread_t.
- * Once malloced, a ptw32_thread_t_ struct is not freed until the process exits.
- * 
- * The thread reuse stack is a simple LILO stack managed through a singly
- * linked list element in the ptw32_thread_t.
- *
- * Each time a thread is destroyed, the ptw32_thread_t address is pushed onto the
- * reuse stack after it's ptHandle's reuse counter has been incremented.
- * 
- * The following can now be said from this:
- * - two pthread_t's are identical if their ptw32_thread_t reference pointers
- * are equal and their reuse counters are equal. That is,
- *
- *   equal = (a.p == b.p && a.x == b.x)
- *
- * - a pthread_t copy refers to a destroyed thread if the reuse counter in
- * the copy is not equal to the reuse counter in the original.
- *
- *   threadDestroyed = (copy.x != ((ptw32_thread_t *)copy.p)->ptHandle.x)
- *
- */
-
-/*
- * Pop a clean pthread_t struct off the reuse stack.
- */
-pthread_t
-ptw32_threadReusePop (void)
-{
-  pthread_t t = {NULL, 0};
-  ptw32_mcs_local_node_t node;
-
-  ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
-
-  if (PTW32_THREAD_REUSE_EMPTY != ptw32_threadReuseTop)
-    {
-      ptw32_thread_t * tp;
-
-      tp = ptw32_threadReuseTop;
-
-      ptw32_threadReuseTop = tp->prevReuse;
-
-      if (PTW32_THREAD_REUSE_EMPTY == ptw32_threadReuseTop)
-        {
-          ptw32_threadReuseBottom = PTW32_THREAD_REUSE_EMPTY;
-        }
-
-      tp->prevReuse = NULL;
-
-      t = tp->ptHandle;
-    }
-
-  ptw32_mcs_lock_release(&node);
-
-  return t;
-
-}
-
-/*
- * Push a clean pthread_t struct onto the reuse stack.
- * Must be re-initialised when reused.
- * All object elements (mutexes, events etc) must have been either
- * detroyed before this, or never initialised.
- */
-void
-ptw32_threadReusePush (pthread_t thread)
-{
-  ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
-  pthread_t t;
-  ptw32_mcs_local_node_t node;
-
-  ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
-
-  t = tp->ptHandle;
-  memset(tp, 0, sizeof(ptw32_thread_t));
-
-  /* Must restore the original POSIX handle that we just wiped. */
-  tp->ptHandle = t;
-
-  /* Bump the reuse counter now */
-#if defined(PTW32_THREAD_ID_REUSE_INCREMENT)
-  tp->ptHandle.x += PTW32_THREAD_ID_REUSE_INCREMENT;
-#else
-  tp->ptHandle.x++;
-#endif
-
-  tp->state = PThreadStateReuse;
-
-  tp->prevReuse = PTW32_THREAD_REUSE_EMPTY;
-
-  if (PTW32_THREAD_REUSE_EMPTY != ptw32_threadReuseBottom)
-    {
-      ptw32_threadReuseBottom->prevReuse = tp;
-    }
-  else
-    {
-      ptw32_threadReuseTop = tp;
-    }
-
-  ptw32_threadReuseBottom = tp;
-
-  ptw32_mcs_lock_release(&node);
-}
diff --git a/deps/w32-pthreads/ptw32_rwlock_cancelwrwait.c b/deps/w32-pthreads/ptw32_rwlock_cancelwrwait.c
deleted file mode 100644
index 4124d98..0000000
--- a/deps/w32-pthreads/ptw32_rwlock_cancelwrwait.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * ptw32_rwlock_cancelwrwait.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-void
-ptw32_rwlock_cancelwrwait (void *arg)
-{
-  pthread_rwlock_t rwl = (pthread_rwlock_t) arg;
-
-  rwl->nSharedAccessCount = -rwl->nCompletedSharedAccessCount;
-  rwl->nCompletedSharedAccessCount = 0;
-
-  (void) pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
-  (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
-}
diff --git a/deps/w32-pthreads/ptw32_rwlock_check_need_init.c b/deps/w32-pthreads/ptw32_rwlock_check_need_init.c
deleted file mode 100644
index 7a7ef9c..0000000
--- a/deps/w32-pthreads/ptw32_rwlock_check_need_init.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * pthread_rwlock_check_need_init.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-INLINE int
-ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock)
-{
-  int result = 0;
-  ptw32_mcs_local_node_t node;
-
-  /*
-   * The following guarded test is specifically for statically
-   * initialised rwlocks (via PTHREAD_RWLOCK_INITIALIZER).
-   */
-  ptw32_mcs_lock_acquire(&ptw32_rwlock_test_init_lock, &node);
-
-  /*
-   * We got here possibly under race
-   * conditions. Check again inside the critical section
-   * and only initialise if the rwlock is valid (not been destroyed).
-   * If a static rwlock has been destroyed, the application can
-   * re-initialise it only by calling pthread_rwlock_init()
-   * explicitly.
-   */
-  if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
-    {
-      result = pthread_rwlock_init (rwlock, NULL);
-    }
-  else if (*rwlock == NULL)
-    {
-      /*
-       * The rwlock has been destroyed while we were waiting to
-       * initialise it, so the operation that caused the
-       * auto-initialisation should fail.
-       */
-      result = EINVAL;
-    }
-
-  ptw32_mcs_lock_release(&node);
-
-  return result;
-}
diff --git a/deps/w32-pthreads/ptw32_semwait.c b/deps/w32-pthreads/ptw32_semwait.c
deleted file mode 100644
index bc96487..0000000
--- a/deps/w32-pthreads/ptw32_semwait.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * ptw32_semwait.c
- *
- * Description:
- * This translation unit implements mutual exclusion (mutex) primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#if !defined(_UWIN)
-/*#   include <process.h> */
-#endif
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-ptw32_semwait (sem_t * sem)
-     /*
-      * ------------------------------------------------------
-      * DESCRIPTION
-      *      This function waits on a POSIX semaphore. If the
-      *      semaphore value is greater than zero, it decreases
-      *      its value by one. If the semaphore value is zero, then
-      *      the calling thread (or process) is blocked until it can
-      *      successfully decrease the value.
-      *
-      *      Unlike sem_wait(), this routine is non-cancelable.
-      *
-      * RESULTS
-      *              0               successfully decreased semaphore,
-      *              -1              failed, error in errno.
-      * ERRNO
-      *              EINVAL          'sem' is not a valid semaphore,
-      *              ENOSYS          semaphores are not supported,
-      *              EINTR           the function was interrupted by a signal,
-      *              EDEADLK         a deadlock condition was detected.
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  sem_t s = *sem;
-
-  if (s == NULL)
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      if ((result = pthread_mutex_lock (&s->lock)) == 0)
-        {
-          int v;
-
-	  /* See sem_destroy.c
-	   */
-	  if (*sem == NULL)
-	    {
-	      (void) pthread_mutex_unlock (&s->lock);
-	      errno = EINVAL;
-	      return -1;
-	    }
-
-          v = --s->value;
-          (void) pthread_mutex_unlock (&s->lock);
-
-          if (v < 0)
-            {
-              /* Must wait */
-              if (WaitForSingleObject (s->sem, INFINITE) == WAIT_OBJECT_0)
-		{
-#if defined(NEED_SEM)
-		  if (pthread_mutex_lock (&s->lock) == 0)
-		    {
-        	      if (*sem == NULL)
-        	        {
-        	          (void) pthread_mutex_unlock (&s->lock);
-        	          errno = EINVAL;
-        	          return -1;
-        	        }
-
-		      if (s->leftToUnblock > 0)
-			{
-			  --s->leftToUnblock;
-			  SetEvent(s->sem);
-			}
-		      (void) pthread_mutex_unlock (&s->lock);
-		    }
-#endif
-		  return 0;
-		}
-            }
-          else
-	    {
-	      return 0;
-	    }
-        }
-    }
-
-  if (result != 0)
-    {
-      errno = result;
-      return -1;
-    }
-
-  return 0;
-
-}				/* ptw32_semwait */
diff --git a/deps/w32-pthreads/ptw32_spinlock_check_need_init.c b/deps/w32-pthreads/ptw32_spinlock_check_need_init.c
deleted file mode 100644
index 1fa63d9..0000000
--- a/deps/w32-pthreads/ptw32_spinlock_check_need_init.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * ptw32_spinlock_check_need_init.c
- *
- * Description:
- * This translation unit implements spin lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-INLINE int
-ptw32_spinlock_check_need_init (pthread_spinlock_t * lock)
-{
-  int result = 0;
-  ptw32_mcs_local_node_t node;
-
-  /*
-   * The following guarded test is specifically for statically
-   * initialised spinlocks (via PTHREAD_SPINLOCK_INITIALIZER).
-   */
-  ptw32_mcs_lock_acquire(&ptw32_spinlock_test_init_lock, &node);
-
-  /*
-   * We got here possibly under race
-   * conditions. Check again inside the critical section
-   * and only initialise if the spinlock is valid (not been destroyed).
-   * If a static spinlock has been destroyed, the application can
-   * re-initialise it only by calling pthread_spin_init()
-   * explicitly.
-   */
-  if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
-    {
-      result = pthread_spin_init (lock, PTHREAD_PROCESS_PRIVATE);
-    }
-  else if (*lock == NULL)
-    {
-      /*
-       * The spinlock has been destroyed while we were waiting to
-       * initialise it, so the operation that caused the
-       * auto-initialisation should fail.
-       */
-      result = EINVAL;
-    }
-
-  ptw32_mcs_lock_release(&node);
-
-  return (result);
-}
diff --git a/deps/w32-pthreads/ptw32_threadDestroy.c b/deps/w32-pthreads/ptw32_threadDestroy.c
deleted file mode 100644
index 38b7417..0000000
--- a/deps/w32-pthreads/ptw32_threadDestroy.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * ptw32_threadDestroy.c
- *
- * Description:
- * This translation unit implements routines which are private to
- * the implementation and may be used throughout it.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-void
-ptw32_threadDestroy (pthread_t thread)
-{
-  ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
-  ptw32_thread_t threadCopy;
-
-  if (tp != NULL)
-    {
-      /*
-       * Copy thread state so that the thread can be atomically NULLed.
-       */
-      memcpy (&threadCopy, tp, sizeof (threadCopy));
-
-      /*
-       * Thread ID structs are never freed. They're NULLed and reused.
-       * This also sets the thread to PThreadStateInitial (invalid).
-       */
-      ptw32_threadReusePush (thread);
-
-      /* Now work on the copy. */
-      if (threadCopy.cancelEvent != NULL)
-	{
-	  CloseHandle (threadCopy.cancelEvent);
-	}
-
-#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
-      /*
-       * See documentation for endthread vs endthreadex.
-       */
-      if (threadCopy.threadH != 0)
-	{
-	  CloseHandle (threadCopy.threadH);
-	}
-#endif
-
-    }
-}				/* ptw32_threadDestroy */
-
diff --git a/deps/w32-pthreads/ptw32_threadStart.c b/deps/w32-pthreads/ptw32_threadStart.c
deleted file mode 100644
index e7d3925..0000000
--- a/deps/w32-pthreads/ptw32_threadStart.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * ptw32_threadStart.c
- *
- * Description:
- * This translation unit implements routines which are private to
- * the implementation and may be used throughout it.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include <stdio.h>
-
-#if defined(__CLEANUP_C)
-# include <setjmp.h>
-#endif
-
-#if defined(__CLEANUP_SEH)
-
-static DWORD
-ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei)
-{
-  switch (ep->ExceptionRecord->ExceptionCode)
-    {
-    case EXCEPTION_PTW32_SERVICES:
-      {
-	DWORD param;
-	DWORD numParams = ep->ExceptionRecord->NumberParameters;
-
-	numParams = (numParams > 3) ? 3 : numParams;
-
-	for (param = 0; param < numParams; param++)
-	  {
-	    ei[param] = ep->ExceptionRecord->ExceptionInformation[param];
-	  }
-
-	return EXCEPTION_EXECUTE_HANDLER;
-	break;
-      }
-    default:
-      {
-	/*
-	 * A system unexpected exception has occurred running the user's
-	 * routine. We need to cleanup before letting the exception
-	 * out of thread scope.
-	 */
-	pthread_t self = pthread_self ();
-
-	ptw32_callUserDestroyRoutines (self);
-
-	return EXCEPTION_CONTINUE_SEARCH;
-	break;
-      }
-    }
-}
-
-#elif defined(__CLEANUP_CXX)
-
-#if defined(_MSC_VER)
-# include <eh.h>
-#elif defined(__WATCOMC__)
-# include <eh.h>
-# include <exceptio.h>
-typedef terminate_handler
-  terminate_function;
-#else
-# if defined(__GNUC__) && __GNUC__ < 3
-#   include <new.h>
-# else
-#   include <new>
-using
-  std::terminate_handler;
-using
-  std::terminate;
-using
-  std::set_terminate;
-# endif
-typedef terminate_handler
-  terminate_function;
-#endif
-
-static terminate_function
-  ptw32_oldTerminate;
-
-void
-ptw32_terminate ()
-{
-  set_terminate (ptw32_oldTerminate);
-  (void) pthread_win32_thread_detach_np ();
-  terminate ();
-}
-
-#endif
-
-#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || (defined (__MSVCRT__) && ! defined (__DMC__))
-unsigned
-  __stdcall
-#else
-void
-#endif
-ptw32_threadStart (void *vthreadParms)
-{
-  ThreadParms * threadParms = (ThreadParms *) vthreadParms;
-  pthread_t self;
-  ptw32_thread_t * sp;
-  void * (PTW32_CDECL *start) (void *);
-  void * arg;
-
-#if defined(__CLEANUP_SEH)
-  DWORD
-  ei[] = { 0, 0, 0 };
-#endif
-
-#if defined(__CLEANUP_C)
-  int setjmp_rc;
-#endif
-
-  ptw32_mcs_local_node_t stateLock;
-  void * status = (void *) 0;
-
-  self = threadParms->tid;
-  sp = (ptw32_thread_t *) self.p;
-  start = threadParms->start;
-  arg = threadParms->arg;
-
-  free (threadParms);
-
-#if (defined(__MINGW64__) || defined(__MINGW32__)) && ! defined (__MSVCRT__)
-  /*
-   * beginthread does not return the thread id and is running
-   * before it returns us the thread handle, and so we do it here.
-   */
-  sp->thread = GetCurrentThreadId ();
-  /*
-   * Here we're using stateLock as a general-purpose lock
-   * to make the new thread wait until the creating thread
-   * has the new handle.
-   */
-  ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
-  pthread_setspecific (ptw32_selfThreadKey, sp);
-#else
-  pthread_setspecific (ptw32_selfThreadKey, sp);
-  ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
-#endif
-
-  sp->state = PThreadStateRunning;
-  ptw32_mcs_lock_release (&stateLock);
-
-#if defined(__CLEANUP_SEH)
-
-  __try
-  {
-    /*
-     * Run the caller's routine;
-     */
-    status = sp->exitStatus = (*start) (arg);
-    sp->state = PThreadStateExiting;
-
-#if defined(_UWIN)
-    if (--pthread_count <= 0)
-      exit (0);
-#endif
-
-  }
-  __except (ExceptionFilter (GetExceptionInformation (), ei))
-  {
-    switch (ei[0])
-      {
-      case PTW32_EPS_CANCEL:
-	status = sp->exitStatus = PTHREAD_CANCELED;
-#if defined(_UWIN)
-	if (--pthread_count <= 0)
-	  exit (0);
-#endif
-	break;
-      case PTW32_EPS_EXIT:
-	status = sp->exitStatus;
-	break;
-      default:
-	status = sp->exitStatus = PTHREAD_CANCELED;
-	break;
-      }
-  }
-
-#else /* __CLEANUP_SEH */
-
-#if defined(__CLEANUP_C)
-
-  setjmp_rc = setjmp (sp->start_mark);
-
-  if (0 == setjmp_rc)
-    {
-
-      /*
-       * Run the caller's routine;
-       */
-      status = sp->exitStatus = (*start) (arg);
-      sp->state = PThreadStateExiting;
-    }
-  else
-    {
-      switch (setjmp_rc)
-	{
-	case PTW32_EPS_CANCEL:
-	  status = sp->exitStatus = PTHREAD_CANCELED;
-	  break;
-	case PTW32_EPS_EXIT:
-	  status = sp->exitStatus;
-	  break;
-	default:
-	  status = sp->exitStatus = PTHREAD_CANCELED;
-	  break;
-	}
-    }
-
-#else /* __CLEANUP_C */
-
-#if defined(__CLEANUP_CXX)
-
-  ptw32_oldTerminate = set_terminate (&ptw32_terminate);
-
-  try
-  {
-    /*
-     * Run the caller's routine in a nested try block so that we
-     * can run the user's terminate function, which may call
-     * pthread_exit() or be canceled.
-     */
-    try
-    {
-      status = sp->exitStatus = (*start) (arg);
-      sp->state = PThreadStateExiting;
-    }
-    catch (ptw32_exception &)
-    {
-      /*
-       * Pass these through to the outer block.
-       */
-      throw;
-    }
-    catch (...)
-    {
-      /*
-       * We want to run the user's terminate function if supplied.
-       * That function may call pthread_exit() or be canceled, which will
-       * be handled by the outer try block.
-       *
-       * ptw32_terminate() will be called if there is no user
-       * supplied function.
-       */
-      terminate_function
-	term_func = set_terminate (0);
-      set_terminate (term_func);
-
-      if (term_func != 0)
-	{
-	  term_func ();
-	}
-      throw;
-    }
-  }
-  catch (ptw32_exception_cancel &)
-  {
-    /*
-     * Thread was canceled.
-     */
-    status = sp->exitStatus = PTHREAD_CANCELED;
-  }
-  catch (ptw32_exception_exit &)
-  {
-    /*
-     * Thread was exited via pthread_exit().
-     */
-    status = sp->exitStatus;
-  }
-  catch (...)
-  {
-    /*
-     * A system unexpected exception has occurred running the user's
-     * terminate routine. We get control back within this block
-     * and exit with a substitute status. If the thread was not
-     * cancelled then this indicates the unhandled exception.
-     */
-    status = sp->exitStatus = PTHREAD_CANCELED;
-  }
-
-  (void) set_terminate (ptw32_oldTerminate);
-
-#else
-
-#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
-
-#endif /* __CLEANUP_CXX */
-#endif /* __CLEANUP_C */
-#endif /* __CLEANUP_SEH */
-
-#if defined(PTW32_STATIC_LIB)
-  /*
-   * We need to cleanup the pthread now if we have
-   * been statically linked, in which case the cleanup
-   * in dllMain won't get done. Joinable threads will
-   * only be partially cleaned up and must be fully cleaned
-   * up by pthread_join() or pthread_detach().
-   *
-   * Note: if this library has been statically linked,
-   * implicitly created pthreads (those created
-   * for Win32 threads which have called pthreads routines)
-   * must be cleaned up explicitly by the application
-   * (by calling pthread_win32_thread_detach_np()).
-   * For the dll, dllMain will do the cleanup automatically.
-   */
-  (void) pthread_win32_thread_detach_np ();
-#endif
-
-#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
-  _endthreadex ((unsigned)(size_t) status);
-#else
-  _endthread ();
-#endif
-
-  /*
-   * Never reached.
-   */
-
-#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
-  return (unsigned)(size_t) status;
-#endif
-
-}				/* ptw32_threadStart */
diff --git a/deps/w32-pthreads/ptw32_throw.c b/deps/w32-pthreads/ptw32_throw.c
deleted file mode 100644
index ff1895a..0000000
--- a/deps/w32-pthreads/ptw32_throw.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * ptw32_throw.c
- *
- * Description:
- * This translation unit implements routines which are private to
- * the implementation and may be used throughout it.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-#if defined(__CLEANUP_C)
-# include <setjmp.h>
-#endif
-
-/*
- * ptw32_throw
- *
- * All canceled and explicitly exited POSIX threads go through
- * here. This routine knows how to exit both POSIX initiated threads and
- * 'implicit' POSIX threads for each of the possible language modes (C,
- * C++, and SEH).
- */
-#if defined(_MSC_VER)
-/*
- * Ignore the warning:
- * "C++ exception specification ignored except to indicate that
- * the function is not __declspec(nothrow)."
- */
-#pragma warning(disable:4290)
-#endif
-void
-ptw32_throw (DWORD exception)
-#if defined(__CLEANUP_CXX)
-  throw(ptw32_exception_cancel,ptw32_exception_exit)
-#endif
-{
-  /*
-   * Don't use pthread_self() to avoid creating an implicit POSIX thread handle
-   * unnecessarily.
-   */
-  ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
-
-#if defined(__CLEANUP_SEH)
-  DWORD exceptionInformation[3];
-#endif
-
-  sp->state = PThreadStateExiting;
-
-  if (exception != PTW32_EPS_CANCEL && exception != PTW32_EPS_EXIT)
-    {
-      /* Should never enter here */
-      exit (1);
-    }
-
-  if (NULL == sp || sp->implicit)
-    {
-      /*
-       * We're inside a non-POSIX initialised Win32 thread
-       * so there is no point to jump or throw back to. Just do an
-       * explicit thread exit here after cleaning up POSIX
-       * residue (i.e. cleanup handlers, POSIX thread handle etc).
-       */
-#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
-      unsigned exitCode = 0;
-
-      switch (exception)
-	{
-	case PTW32_EPS_CANCEL:
-	  exitCode = (unsigned)(size_t) PTHREAD_CANCELED;
-	  break;
-	case PTW32_EPS_EXIT:
-	  if (NULL != sp)
-	    {
-	      exitCode = (unsigned)(size_t) sp->exitStatus;
-	    }
-	  break;
-	}
-#endif
-
-#if defined(PTW32_STATIC_LIB)
-
-      pthread_win32_thread_detach_np ();
-
-#endif
-
-#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
-      _endthreadex (exitCode);
-#else
-      _endthread ();
-#endif
-
-    }
-
-#if defined(__CLEANUP_SEH)
-
-
-  exceptionInformation[0] = (DWORD) (exception);
-  exceptionInformation[1] = (DWORD) (0);
-  exceptionInformation[2] = (DWORD) (0);
-
-  RaiseException (EXCEPTION_PTW32_SERVICES, 0, 3, exceptionInformation);
-
-#else /* __CLEANUP_SEH */
-
-#if defined(__CLEANUP_C)
-
-  ptw32_pop_cleanup_all (1);
-  longjmp (sp->start_mark, exception);
-
-#else /* __CLEANUP_C */
-
-#if defined(__CLEANUP_CXX)
-
-  switch (exception)
-    {
-    case PTW32_EPS_CANCEL:
-      throw ptw32_exception_cancel ();
-      break;
-    case PTW32_EPS_EXIT:
-      throw ptw32_exception_exit ();
-      break;
-    }
-
-#else
-
-#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
-
-#endif /* __CLEANUP_CXX */
-
-#endif /* __CLEANUP_C */
-
-#endif /* __CLEANUP_SEH */
-
-  /* Never reached */
-}
-
-
-void
-ptw32_pop_cleanup_all (int execute)
-{
-  while (NULL != ptw32_pop_cleanup (execute))
-    {
-    }
-}
-
-
-DWORD
-ptw32_get_exception_services_code (void)
-{
-#if defined(__CLEANUP_SEH)
-
-  return EXCEPTION_PTW32_SERVICES;
-
-#else
-
-  return (DWORD)0;
-
-#endif
-}
diff --git a/deps/w32-pthreads/ptw32_timespec.c b/deps/w32-pthreads/ptw32_timespec.c
deleted file mode 100644
index 1ce8f46..0000000
--- a/deps/w32-pthreads/ptw32_timespec.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * ptw32_timespec.c
- *
- * Description:
- * This translation unit implements routines which are private to
- * the implementation and may be used throughout it.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-#if defined(NEED_FTIME)
-
-/*
- * time between jan 1, 1601 and jan 1, 1970 in units of 100 nanoseconds
- */
-#define PTW32_TIMESPEC_TO_FILETIME_OFFSET \
-	  ( ((int64_t) 27111902 << 32) + (int64_t) 3577643008 )
-
-INLINE void
-ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft)
-     /*
-      * -------------------------------------------------------------------
-      * converts struct timespec
-      * where the time is expressed in seconds and nanoseconds from Jan 1, 1970.
-      * into FILETIME (as set by GetSystemTimeAsFileTime), where the time is
-      * expressed in 100 nanoseconds from Jan 1, 1601,
-      * -------------------------------------------------------------------
-      */
-{
-  *(int64_t *) ft = ts->tv_sec * 10000000
-    + (ts->tv_nsec + 50) / 100 + PTW32_TIMESPEC_TO_FILETIME_OFFSET;
-}
-
-INLINE void
-ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts)
-     /*
-      * -------------------------------------------------------------------
-      * converts FILETIME (as set by GetSystemTimeAsFileTime), where the time is
-      * expressed in 100 nanoseconds from Jan 1, 1601,
-      * into struct timespec
-      * where the time is expressed in seconds and nanoseconds from Jan 1, 1970.
-      * -------------------------------------------------------------------
-      */
-{
-  ts->tv_sec =
-    (int) ((*(int64_t *) ft - PTW32_TIMESPEC_TO_FILETIME_OFFSET) / 10000000);
-  ts->tv_nsec =
-    (int) ((*(int64_t *) ft - PTW32_TIMESPEC_TO_FILETIME_OFFSET -
-	    ((int64_t) ts->tv_sec * (int64_t) 10000000)) * 100);
-}
-
-#endif /* NEED_FTIME */
diff --git a/deps/w32-pthreads/ptw32_tkAssocCreate.c b/deps/w32-pthreads/ptw32_tkAssocCreate.c
deleted file mode 100644
index 7f0fab2..0000000
--- a/deps/w32-pthreads/ptw32_tkAssocCreate.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * ptw32_tkAssocCreate.c
- *
- * Description:
- * This translation unit implements routines which are private to
- * the implementation and may be used throughout it.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-int
-ptw32_tkAssocCreate (ptw32_thread_t * sp, pthread_key_t key)
-     /*
-      * -------------------------------------------------------------------
-      * This routine creates an association that
-      * is unique for the given (thread,key) combination.The association 
-      * is referenced by both the thread and the key.
-      * This association allows us to determine what keys the
-      * current thread references and what threads a given key
-      * references.
-      * See the detailed description
-      * at the beginning of this file for further details.
-      *
-      * Notes:
-      *      1)      New associations are pushed to the beginning of the
-      *              chain so that the internal ptw32_selfThreadKey association
-      *              is always last, thus allowing selfThreadExit to
-      *              be implicitly called last by pthread_exit.
-      *      2)      
-      *
-      * Parameters:
-      *              thread
-      *                      current running thread.
-      *              key
-      *                      key on which to create an association.
-      * Returns:
-      *       0              - if successful,
-      *       ENOMEM         - not enough memory to create assoc or other object
-      *       EINVAL         - an internal error occurred
-      *       ENOSYS         - an internal error occurred
-      * -------------------------------------------------------------------
-      */
-{
-  ThreadKeyAssoc *assoc;
-
-  /*
-   * Have to create an association and add it
-   * to both the key and the thread.
-   *
-   * Both key->keyLock and thread->threadLock are locked before
-   * entry to this routine.
-   */
-  assoc = (ThreadKeyAssoc *) calloc (1, sizeof (*assoc));
-
-  if (assoc == NULL)
-    {
-      return ENOMEM;
-    }
-
-  assoc->thread = sp;
-  assoc->key = key;
-
-  /*
-   * Register assoc with key
-   */
-  assoc->prevThread = NULL;
-  assoc->nextThread = (ThreadKeyAssoc *) key->threads;
-  if (assoc->nextThread != NULL)
-    {
-      assoc->nextThread->prevThread = assoc;
-    }
-  key->threads = (void *) assoc;
-
-  /*
-   * Register assoc with thread
-   */
-  assoc->prevKey = NULL;
-  assoc->nextKey = (ThreadKeyAssoc *) sp->keys;
-  if (assoc->nextKey != NULL)
-    {
-      assoc->nextKey->prevKey = assoc;
-    }
-  sp->keys = (void *) assoc;
-
-  return (0);
-
-}				/* ptw32_tkAssocCreate */
diff --git a/deps/w32-pthreads/ptw32_tkAssocDestroy.c b/deps/w32-pthreads/ptw32_tkAssocDestroy.c
deleted file mode 100644
index d43974f..0000000
--- a/deps/w32-pthreads/ptw32_tkAssocDestroy.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * ptw32_tkAssocDestroy.c
- *
- * Description:
- * This translation unit implements routines which are private to
- * the implementation and may be used throughout it.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-void
-ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc)
-     /*
-      * -------------------------------------------------------------------
-      * This routine releases all resources for the given ThreadKeyAssoc
-      * once it is no longer being referenced
-      * ie) either the key or thread has stopped referencing it.
-      *
-      * Parameters:
-      *              assoc
-      *                      an instance of ThreadKeyAssoc.
-      * Returns:
-      *      N/A
-      * -------------------------------------------------------------------
-      */
-{
-
-  /*
-   * Both key->keyLock and thread->threadLock are locked before
-   * entry to this routine.
-   */
-  if (assoc != NULL)
-    {
-      ThreadKeyAssoc * prev, * next;
-
-      /* Remove assoc from thread's keys chain */
-      prev = assoc->prevKey;
-      next = assoc->nextKey;
-      if (prev != NULL)
-	{
-	  prev->nextKey = next;
-	}
-      if (next != NULL)
-	{
-	  next->prevKey = prev;
-	}
-
-      if (assoc->thread->keys == assoc)
-	{
-	  /* We're at the head of the thread's keys chain */
-	  assoc->thread->keys = next;
-	}
-      if (assoc->thread->nextAssoc == assoc)
-	{
-	  /*
-	   * Thread is exiting and we're deleting the assoc to be processed next.
-	   * Hand thread the assoc after this one.
-	   */
-	  assoc->thread->nextAssoc = next;
-	}
-
-      /* Remove assoc from key's threads chain */
-      prev = assoc->prevThread;
-      next = assoc->nextThread;
-      if (prev != NULL)
-	{
-	  prev->nextThread = next;
-	}
-      if (next != NULL)
-	{
-	  next->prevThread = prev;
-	}
-
-      if (assoc->key->threads == assoc)
-	{
-	  /* We're at the head of the key's threads chain */
-	  assoc->key->threads = next;
-	}
-
-      free (assoc);
-    }
-
-}				/* ptw32_tkAssocDestroy */
diff --git a/deps/w32-pthreads/rwlock.c b/deps/w32-pthreads/rwlock.c
deleted file mode 100644
index 089cf36..0000000
--- a/deps/w32-pthreads/rwlock.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * rwlock.c
- *
- * Description:
- * This translation unit implements read/write lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "ptw32_rwlock_check_need_init.c"
-#include "ptw32_rwlock_cancelwrwait.c"
-#include "pthread_rwlock_init.c"
-#include "pthread_rwlock_destroy.c"
-#include "pthread_rwlockattr_init.c"
-#include "pthread_rwlockattr_destroy.c"
-#include "pthread_rwlockattr_getpshared.c"
-#include "pthread_rwlockattr_setpshared.c"
-#include "pthread_rwlock_rdlock.c"
-#include "pthread_rwlock_timedrdlock.c"
-#include "pthread_rwlock_wrlock.c"
-#include "pthread_rwlock_timedwrlock.c"
-#include "pthread_rwlock_unlock.c"
-#include "pthread_rwlock_tryrdlock.c"
-#include "pthread_rwlock_trywrlock.c"
diff --git a/deps/w32-pthreads/sched.c b/deps/w32-pthreads/sched.c
deleted file mode 100644
index 34dcbc0..0000000
--- a/deps/w32-pthreads/sched.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * sched.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-#include "pthread_attr_setschedpolicy.c"
-#include "pthread_attr_getschedpolicy.c"
-#include "pthread_attr_setschedparam.c"
-#include "pthread_attr_getschedparam.c"
-#include "pthread_attr_setinheritsched.c"
-#include "pthread_attr_getinheritsched.c"
-#include "pthread_setschedparam.c"
-#include "pthread_getschedparam.c"
-#include "sched_get_priority_max.c"
-#include "sched_get_priority_min.c"
-#include "sched_setscheduler.c"
-#include "sched_getscheduler.c"
-#include "sched_yield.c"
diff --git a/deps/w32-pthreads/sched.h b/deps/w32-pthreads/sched.h
deleted file mode 100644
index 806ee52..0000000
--- a/deps/w32-pthreads/sched.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Module: sched.h
- *
- * Purpose:
- *      Provides an implementation of POSIX realtime extensions
- *      as defined in 
- *
- *              POSIX 1003.1b-1993      (POSIX.1b)
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-#if !defined(_SCHED_H)
-#define _SCHED_H
-
-#undef PTW32_SCHED_LEVEL
-
-#if defined(_POSIX_SOURCE)
-#define PTW32_SCHED_LEVEL 0
-/* Early POSIX */
-#endif
-
-#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
-#undef PTW32_SCHED_LEVEL
-#define PTW32_SCHED_LEVEL 1
-/* Include 1b, 1c and 1d */
-#endif
-
-#if defined(INCLUDE_NP)
-#undef PTW32_SCHED_LEVEL
-#define PTW32_SCHED_LEVEL 2
-/* Include Non-Portable extensions */
-#endif
-
-#define PTW32_SCHED_LEVEL_MAX 3
-
-#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 )  || !defined(PTW32_SCHED_LEVEL)
-#define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX
-/* Include everything */
-#endif
-
-
-#if defined(__GNUC__) && !defined(__declspec)
-# error Please upgrade your GNU compiler to one that supports __declspec.
-#endif
-
-/*
- * When building the library, you should define PTW32_BUILD so that
- * the variables/functions are exported correctly. When using the library,
- * do NOT define PTW32_BUILD, and then the variables/functions will
- * be imported correctly.
- */
-#if !defined(PTW32_STATIC_LIB)
-#  if defined(PTW32_BUILD)
-#    define PTW32_DLLPORT __declspec (dllexport)
-#  else
-#    define PTW32_DLLPORT
-#  endif
-#else
-#  define PTW32_DLLPORT
-#endif
-
-/*
- * This is a duplicate of what is in the autoconf config.h,
- * which is only used when building the pthread-win32 libraries.
- */
-
-#if !defined(PTW32_CONFIG_H)
-#  if defined(WINCE)
-#    define NEED_ERRNO
-#    define NEED_SEM
-#  endif
-#  if defined(__MINGW64__)
-#    define HAVE_STRUCT_TIMESPEC
-#    define HAVE_MODE_T
-#  elif defined(_UWIN) || defined(__MINGW32__)
-#    define HAVE_MODE_T
-#  endif
-#endif
-
-/*
- *
- */
-
-#if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX
-#if defined(NEED_ERRNO)
-#include "need_errno.h"
-#else
-#include <errno.h>
-#endif
-#endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */
-
-#if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN)
-# if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX
-/* For pid_t */
-#  include <sys/types.h>
-/* Required by Unix 98 */
-#  include <time.h>
-# else
-   typedef int pid_t;
-# endif
-#else
- typedef int pid_t;
-#endif
-
-/* Thread scheduling policies */
-
-enum {
-  SCHED_OTHER = 0,
-  SCHED_FIFO,
-  SCHED_RR,
-  SCHED_MIN   = SCHED_OTHER,
-  SCHED_MAX   = SCHED_RR
-};
-
-struct sched_param {
-  int sched_priority;
-};
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif                          /* __cplusplus */
-
-PTW32_DLLPORT int __cdecl sched_yield (void);
-
-PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy);
-
-PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy);
-
-PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy);
-
-PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid);
-
-/*
- * Note that this macro returns ENOTSUP rather than
- * ENOSYS as might be expected. However, returning ENOSYS
- * should mean that sched_get_priority_{min,max} are
- * not implemented as well as sched_rr_get_interval.
- * This is not the case, since we just don't support
- * round-robin scheduling. Therefore I have chosen to
- * return the same value as sched_setscheduler when
- * SCHED_RR is passed to it.
- */
-#define sched_rr_get_interval(_pid, _interval) \
-  ( errno = ENOTSUP, (int) -1 )
-
-
-#if defined(__cplusplus)
-}                               /* End of extern "C" */
-#endif                          /* __cplusplus */
-
-#undef PTW32_SCHED_LEVEL
-#undef PTW32_SCHED_LEVEL_MAX
-
-#endif                          /* !_SCHED_H */
-
diff --git a/deps/w32-pthreads/sched_get_priority_max.c b/deps/w32-pthreads/sched_get_priority_max.c
deleted file mode 100644
index bd9de08..0000000
--- a/deps/w32-pthreads/sched_get_priority_max.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * sched_get_priority_max.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-/*
- * On Windows98, THREAD_PRIORITY_LOWEST is (-2) and 
- * THREAD_PRIORITY_HIGHEST is 2, and everything works just fine.
- * 
- * On WinCE 3.0, it so happen that THREAD_PRIORITY_LOWEST is 5
- * and THREAD_PRIORITY_HIGHEST is 1 (yes, I know, it is funny:
- * highest priority use smaller numbers) and the following happens:
- * 
- * sched_get_priority_min() returns 5
- * sched_get_priority_max() returns 1
- *
- * The following table shows the base priority levels for combinations
- * of priority class and priority value in Win32.
- *
- *   Process Priority Class               Thread Priority Level
- *   -----------------------------------------------------------------
- *   1 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_IDLE
- *   1 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_IDLE
- *   1 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_IDLE
- *   1 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_IDLE
- *   1 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_IDLE
- *   2 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_LOWEST
- *   3 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_BELOW_NORMAL
- *   4 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_NORMAL
- *   4 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_LOWEST
- *   5 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_ABOVE_NORMAL
- *   5 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_BELOW_NORMAL
- *   5 Background NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_LOWEST
- *   6 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_HIGHEST
- *   6 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_NORMAL
- *   6 Background NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_BELOW_NORMAL
- *   7 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_ABOVE_NORMAL
- *   7 Background NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_NORMAL
- *   7 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_LOWEST
- *   8 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_HIGHEST
- *   8 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_ABOVE_NORMAL
- *   8 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_BELOW_NORMAL
- *   8 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_LOWEST
- *   9 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_HIGHEST
- *   9 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_NORMAL
- *   9 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_BELOW_NORMAL
- *  10 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_ABOVE_NORMAL
- *  10 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_NORMAL
- *  11 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_HIGHEST
- *  11 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_ABOVE_NORMAL
- *  11 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_LOWEST
- *  12 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_HIGHEST
- *  12 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_BELOW_NORMAL
- *  13 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_NORMAL
- *  14 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_ABOVE_NORMAL
- *  15 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_HIGHEST
- *  15 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_TIME_CRITICAL
- *  15 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_TIME_CRITICAL
- *  15 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_TIME_CRITICAL
- *  15 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_TIME_CRITICAL
- *  15 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_TIME_CRITICAL
- *  16 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_IDLE
- *  17 REALTIME_PRIORITY_CLASS            -7
- *  18 REALTIME_PRIORITY_CLASS            -6
- *  19 REALTIME_PRIORITY_CLASS            -5
- *  20 REALTIME_PRIORITY_CLASS            -4
- *  21 REALTIME_PRIORITY_CLASS            -3
- *  22 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_LOWEST
- *  23 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_BELOW_NORMAL
- *  24 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_NORMAL
- *  25 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_ABOVE_NORMAL
- *  26 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_HIGHEST
- *  27 REALTIME_PRIORITY_CLASS             3
- *  28 REALTIME_PRIORITY_CLASS             4
- *  29 REALTIME_PRIORITY_CLASS             5
- *  30 REALTIME_PRIORITY_CLASS             6
- *  31 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_TIME_CRITICAL
- *
- * Windows NT:  Values -7, -6, -5, -4, -3, 3, 4, 5, and 6 are not supported.
- */
-
-
-int
-sched_get_priority_max (int policy)
-{
-  if (policy < SCHED_MIN || policy > SCHED_MAX)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-
-#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
-  /* WinCE? */
-  return PTW32_MAX (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
-#else
-  /* This is independent of scheduling policy in Win32. */
-  return PTW32_MAX (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
-#endif
-}
diff --git a/deps/w32-pthreads/sched_get_priority_min.c b/deps/w32-pthreads/sched_get_priority_min.c
deleted file mode 100644
index 7e50f1e..0000000
--- a/deps/w32-pthreads/sched_get_priority_min.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * sched_get_priority_min.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-/*
- * On Windows98, THREAD_PRIORITY_LOWEST is (-2) and 
- * THREAD_PRIORITY_HIGHEST is 2, and everything works just fine.
- * 
- * On WinCE 3.0, it so happen that THREAD_PRIORITY_LOWEST is 5
- * and THREAD_PRIORITY_HIGHEST is 1 (yes, I know, it is funny:
- * highest priority use smaller numbers) and the following happens:
- * 
- * sched_get_priority_min() returns 5
- * sched_get_priority_max() returns 1
- *
- * The following table shows the base priority levels for combinations
- * of priority class and priority value in Win32.
- *
- *   Process Priority Class               Thread Priority Level
- *   -----------------------------------------------------------------
- *   1 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_IDLE
- *   1 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_IDLE
- *   1 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_IDLE
- *   1 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_IDLE
- *   1 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_IDLE
- *   2 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_LOWEST
- *   3 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_BELOW_NORMAL
- *   4 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_NORMAL
- *   4 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_LOWEST
- *   5 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_ABOVE_NORMAL
- *   5 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_BELOW_NORMAL
- *   5 Background NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_LOWEST
- *   6 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_HIGHEST
- *   6 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_NORMAL
- *   6 Background NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_BELOW_NORMAL
- *   7 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_ABOVE_NORMAL
- *   7 Background NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_NORMAL
- *   7 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_LOWEST
- *   8 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_HIGHEST
- *   8 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_ABOVE_NORMAL
- *   8 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_BELOW_NORMAL
- *   8 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_LOWEST
- *   9 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_HIGHEST
- *   9 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_NORMAL
- *   9 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_BELOW_NORMAL
- *  10 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_ABOVE_NORMAL
- *  10 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_NORMAL
- *  11 Foreground NORMAL_PRIORITY_CLASS   THREAD_PRIORITY_HIGHEST
- *  11 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_ABOVE_NORMAL
- *  11 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_LOWEST
- *  12 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_HIGHEST
- *  12 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_BELOW_NORMAL
- *  13 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_NORMAL
- *  14 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_ABOVE_NORMAL
- *  15 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_HIGHEST
- *  15 HIGH_PRIORITY_CLASS                THREAD_PRIORITY_TIME_CRITICAL
- *  15 IDLE_PRIORITY_CLASS                THREAD_PRIORITY_TIME_CRITICAL
- *  15 BELOW_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_TIME_CRITICAL
- *  15 NORMAL_PRIORITY_CLASS              THREAD_PRIORITY_TIME_CRITICAL
- *  15 ABOVE_NORMAL_PRIORITY_CLASS        THREAD_PRIORITY_TIME_CRITICAL
- *  16 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_IDLE
- *  17 REALTIME_PRIORITY_CLASS            -7
- *  18 REALTIME_PRIORITY_CLASS            -6
- *  19 REALTIME_PRIORITY_CLASS            -5
- *  20 REALTIME_PRIORITY_CLASS            -4
- *  21 REALTIME_PRIORITY_CLASS            -3
- *  22 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_LOWEST
- *  23 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_BELOW_NORMAL
- *  24 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_NORMAL
- *  25 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_ABOVE_NORMAL
- *  26 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_HIGHEST
- *  27 REALTIME_PRIORITY_CLASS             3
- *  28 REALTIME_PRIORITY_CLASS             4
- *  29 REALTIME_PRIORITY_CLASS             5
- *  30 REALTIME_PRIORITY_CLASS             6
- *  31 REALTIME_PRIORITY_CLASS            THREAD_PRIORITY_TIME_CRITICAL
- *
- * Windows NT:  Values -7, -6, -5, -4, -3, 3, 4, 5, and 6 are not supported.
- *
- */
-
-
-int
-sched_get_priority_min (int policy)
-{
-  if (policy < SCHED_MIN || policy > SCHED_MAX)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-
-#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
-  /* WinCE? */
-  return PTW32_MIN (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
-#else
-  /* This is independent of scheduling policy in Win32. */
-  return PTW32_MIN (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
-#endif
-}
diff --git a/deps/w32-pthreads/sched_getscheduler.c b/deps/w32-pthreads/sched_getscheduler.c
deleted file mode 100644
index f849936..0000000
--- a/deps/w32-pthreads/sched_getscheduler.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * sched_getscheduler.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-int
-sched_getscheduler (pid_t pid)
-{
-  /*
-   * Win32 only has one policy which we call SCHED_OTHER.
-   * However, we try to provide other valid side-effects
-   * such as EPERM and ESRCH errors.
-   */
-  if (0 != pid)
-    {
-      int selfPid = (int) GetCurrentProcessId ();
-
-      if (pid != selfPid)
-	{
-	  HANDLE h =
-	    OpenProcess (PROCESS_QUERY_INFORMATION, PTW32_FALSE, (DWORD) pid);
-
-	  if (NULL == h)
-	    {
-	      errno =
-		(GetLastError () ==
-		 (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH;
-	      return -1;
-	    }
-	  else
-	    CloseHandle(h);
-	}
-    }
-
-  return SCHED_OTHER;
-}
diff --git a/deps/w32-pthreads/sched_setscheduler.c b/deps/w32-pthreads/sched_setscheduler.c
deleted file mode 100644
index c292888..0000000
--- a/deps/w32-pthreads/sched_setscheduler.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * sched_setscheduler.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-int
-sched_setscheduler (pid_t pid, int policy)
-{
-  /*
-   * Win32 only has one policy which we call SCHED_OTHER.
-   * However, we try to provide other valid side-effects
-   * such as EPERM and ESRCH errors. Choosing to check
-   * for a valid policy last allows us to get the most value out
-   * of this function.
-   */
-  if (0 != pid)
-    {
-      int selfPid = (int) GetCurrentProcessId ();
-
-      if (pid != selfPid)
-	{
-	  HANDLE h =
-	    OpenProcess (PROCESS_SET_INFORMATION, PTW32_FALSE, (DWORD) pid);
-
-	  if (NULL == h)
-	    {
-	      errno =
-		(GetLastError () ==
-		 (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH;
-	      return -1;
-	    }
-	  else
-	    CloseHandle(h);
-	}
-    }
-
-  if (SCHED_OTHER != policy)
-    {
-      errno = ENOSYS;
-      return -1;
-    }
-
-  /*
-   * Don't set anything because there is nothing to set.
-   * Just return the current (the only possible) value.
-   */
-  return SCHED_OTHER;
-}
diff --git a/deps/w32-pthreads/sched_yield.c b/deps/w32-pthreads/sched_yield.c
deleted file mode 100644
index 9744071..0000000
--- a/deps/w32-pthreads/sched_yield.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * sched_yield.c
- * 
- * Description:
- * POSIX thread functions that deal with thread scheduling.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-#include "sched.h"
-
-int
-sched_yield (void)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function indicates that the calling thread is
-      *      willing to give up some time slices to other threads.
-      *
-      * PARAMETERS
-      *      N/A
-      *
-      *
-      * DESCRIPTION
-      *      This function indicates that the calling thread is
-      *      willing to give up some time slices to other threads.
-      *      NOTE: Since this is part of POSIX 1003.1b
-      *                (realtime extensions), it is defined as returning
-      *                -1 if an error occurs and sets errno to the actual
-      *                error.
-      *
-      * RESULTS
-      *              0               successfully created semaphore,
-      *              ENOSYS          sched_yield not supported,
-      *
-      * ------------------------------------------------------
-      */
-{
-  Sleep (0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/sem_close.c b/deps/w32-pthreads/sem_close.c
deleted file mode 100644
index 6e434a1..0000000
--- a/deps/w32-pthreads/sem_close.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: sem_close.c
- *
- * Purpose:
- *	Semaphores aren't actually part of the PThreads standard.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1b-1993	(POSIX.1b)
- *
- * -------------------------------------------------------------
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-/* ignore warning "unreferenced formal parameter" */
-#if defined(_MSC_VER)
-#pragma warning( disable : 4100 )
-#endif
-
-int
-sem_close (sem_t * sem)
-{
-  errno = ENOSYS;
-  return -1;
-}				/* sem_close */
diff --git a/deps/w32-pthreads/sem_destroy.c b/deps/w32-pthreads/sem_destroy.c
deleted file mode 100644
index 880a412..0000000
--- a/deps/w32-pthreads/sem_destroy.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: sem_destroy.c
- *
- * Purpose:
- *	Semaphores aren't actually part of the PThreads standard.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1b-1993	(POSIX.1b)
- *
- * -------------------------------------------------------------
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-
-int
-sem_destroy (sem_t * sem)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function destroys an unnamed semaphore.
-      *
-      * PARAMETERS
-      *      sem
-      *              pointer to an instance of sem_t
-      *
-      * DESCRIPTION
-      *      This function destroys an unnamed semaphore.
-      *
-      * RESULTS
-      *              0               successfully destroyed semaphore,
-      *              -1              failed, error in errno
-      * ERRNO
-      *              EINVAL          'sem' is not a valid semaphore,
-      *              ENOSYS          semaphores are not supported,
-      *              EBUSY           threads (or processes) are currently
-      *                                      blocked on 'sem'
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  sem_t s = NULL;
-
-  if (sem == NULL || *sem == NULL)
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      s = *sem;
-
-      if ((result = pthread_mutex_lock (&s->lock)) == 0)
-        {
-          if (s->value < 0)
-            {
-              (void) pthread_mutex_unlock (&s->lock);
-              result = EBUSY;
-            }
-          else
-            {
-              /* There are no threads currently blocked on this semaphore. */
-
-              if (!CloseHandle (s->sem))
-	        {
-                  (void) pthread_mutex_unlock (&s->lock);
-	          result = EINVAL;
-	        }
-	      else
-	        {
-                  /*
-                   * Invalidate the semaphore handle when we have the lock.
-                   * Other sema operations should test this after acquiring the lock
-                   * to check that the sema is still valid, i.e. before performing any
-                   * operations. This may only be necessary before the sema op routine
-                   * returns so that the routine can return EINVAL - e.g. if setting
-                   * s->value to SEM_VALUE_MAX below does force a fall-through.
-                   */
-                  *sem = NULL;
-
-                  /* Prevent anyone else actually waiting on or posting this sema.
-                   */
-                  s->value = SEM_VALUE_MAX;
-
-                  (void) pthread_mutex_unlock (&s->lock);
-
-                  do
-                    {
-                      /* Give other threads a chance to run and exit any sema op
-                       * routines. Due to the SEM_VALUE_MAX value, if sem_post or
-                       * sem_wait were blocked by us they should fall through.
-                       */
-                      Sleep(0);
-                    }
-                  while (pthread_mutex_destroy (&s->lock) == EBUSY);
-                }
-            }
-        }
-    }
-
-  if (result != 0)
-    {
-      errno = result;
-      return -1;
-    }
-
-  free (s);
-
-  return 0;
-
-}				/* sem_destroy */
diff --git a/deps/w32-pthreads/sem_getvalue.c b/deps/w32-pthreads/sem_getvalue.c
deleted file mode 100644
index 13525c6..0000000
--- a/deps/w32-pthreads/sem_getvalue.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: sem_getvalue.c
- *
- * Purpose:
- *	Semaphores aren't actually part of PThreads.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1-2001
- *
- * -------------------------------------------------------------
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-
-int
-sem_getvalue (sem_t * sem, int *sval)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function stores the current count value of the
-      *      semaphore.
-      * RESULTS
-      *
-      * Return value
-      *
-      *       0                  sval has been set.
-      *      -1                  failed, error in errno
-      *
-      *  in global errno
-      *
-      *      EINVAL              'sem' is not a valid semaphore,
-      *      ENOSYS              this function is not supported,
-      *
-      *
-      * PARAMETERS
-      *
-      *      sem                 pointer to an instance of sem_t
-      *
-      *      sval                pointer to int.
-      *
-      * DESCRIPTION
-      *      This function stores the current count value of the semaphore
-      *      pointed to by sem in the int pointed to by sval.
-      */
-{
-  if (sem == NULL || *sem == NULL || sval == NULL)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-  else
-    {
-      long value;
-      register sem_t s = *sem;
-      int result = 0;
-
-      if ((result = pthread_mutex_lock(&s->lock)) == 0)
-        {
-	  /* See sem_destroy.c
-	   */
-	  if (*sem == NULL)
-	    {
-	      (void) pthread_mutex_unlock (&s->lock);
-	      errno = EINVAL;
-	      return -1;
-	    }
-
-          value = s->value;
-          (void) pthread_mutex_unlock(&s->lock);
-          *sval = value;
-        }
-
-      return result;
-    }
-
-}				/* sem_getvalue */
diff --git a/deps/w32-pthreads/sem_init.c b/deps/w32-pthreads/sem_init.c
deleted file mode 100644
index b8c31fe..0000000
--- a/deps/w32-pthreads/sem_init.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: sem_init.c
- *
- * Purpose:
- *	Semaphores aren't actually part of PThreads.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1-2001
- *
- * -------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-int
-sem_init (sem_t * sem, int pshared, unsigned int value)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function initializes a semaphore. The
-      *      initial value of the semaphore is 'value'
-      *
-      * PARAMETERS
-      *      sem
-      *              pointer to an instance of sem_t
-      *
-      *      pshared
-      *              if zero, this semaphore may only be shared between
-      *              threads in the same process.
-      *              if nonzero, the semaphore can be shared between
-      *              processes
-      *
-      *      value
-      *              initial value of the semaphore counter
-      *
-      * DESCRIPTION
-      *      This function initializes a semaphore. The
-      *      initial value of the semaphore is set to 'value'.
-      *
-      * RESULTS
-      *              0               successfully created semaphore,
-      *              -1              failed, error in errno
-      * ERRNO
-      *              EINVAL          'sem' is not a valid semaphore, or
-      *                              'value' >= SEM_VALUE_MAX
-      *              ENOMEM          out of memory,
-      *              ENOSPC          a required resource has been exhausted,
-      *              ENOSYS          semaphores are not supported,
-      *              EPERM           the process lacks appropriate privilege
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  sem_t s = NULL;
-
-  if (pshared != 0)
-    {
-      /*
-       * Creating a semaphore that can be shared between
-       * processes
-       */
-      result = EPERM;
-    }
-  else if (value > (unsigned int)SEM_VALUE_MAX)
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      s = (sem_t) calloc (1, sizeof (*s));
-
-      if (NULL == s)
-	{
-	  result = ENOMEM;
-	}
-      else
-	{
-
-	  s->value = value;
-	  if (pthread_mutex_init(&s->lock, NULL) == 0)
-	    {
-
-#if defined(NEED_SEM)
-
-	  s->sem = CreateEvent (NULL,
-				PTW32_FALSE,	/* auto (not manual) reset */
-				PTW32_FALSE,	/* initial state is unset */
-				NULL);
-
-	  if (0 == s->sem)
-	    {
-	      free (s);
-	      (void) pthread_mutex_destroy(&s->lock);
-	      result = ENOSPC;
-	    }
-	  else
-	    {
-	      s->leftToUnblock = 0;
-	    }
-
-#else /* NEED_SEM */
-
-	      if ((s->sem = CreateSemaphore (NULL,	/* Always NULL */
-					     (long) 0,	/* Force threads to wait */
-					     (long) SEM_VALUE_MAX,	/* Maximum value */
-					     NULL)) == 0)	/* Name */
-		{
-		  (void) pthread_mutex_destroy(&s->lock);
-		  result = ENOSPC;
-		}
-
-#endif /* NEED_SEM */
-
-	    }
-	  else
-	    {
-	      result = ENOSPC;
-	    }
-
-	  if (result != 0)
-	    {
-	      free(s);
-	    }
-	}
-    }
-
-  if (result != 0)
-    {
-      errno = result;
-      return -1;
-    }
-
-  *sem = s;
-
-  return 0;
-
-}				/* sem_init */
diff --git a/deps/w32-pthreads/sem_open.c b/deps/w32-pthreads/sem_open.c
deleted file mode 100644
index a0d7a34..0000000
--- a/deps/w32-pthreads/sem_open.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: sem_open.c
- *
- * Purpose:
- *	Semaphores aren't actually part of the PThreads standard.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1b-1993	(POSIX.1b)
- *
- * -------------------------------------------------------------
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-/* ignore warning "unreferenced formal parameter" */
-#if defined(_MSC_VER)
-#pragma warning( disable : 4100 )
-#endif
-
-int
-sem_open (const char *name, int oflag, mode_t mode, unsigned int value)
-{
-  errno = ENOSYS;
-  return -1;
-}				/* sem_open */
diff --git a/deps/w32-pthreads/sem_post.c b/deps/w32-pthreads/sem_post.c
deleted file mode 100644
index d8a3e3d..0000000
--- a/deps/w32-pthreads/sem_post.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: sem_post.c
- *
- * Purpose:
- *	Semaphores aren't actually part of the PThreads standard.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1b-1993	(POSIX.1b)
- *
- * -------------------------------------------------------------
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-
-int
-sem_post (sem_t * sem)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function posts a wakeup to a semaphore.
-      *
-      * PARAMETERS
-      *      sem
-      *              pointer to an instance of sem_t
-      *
-      * DESCRIPTION
-      *      This function posts a wakeup to a semaphore. If there
-      *      are waiting threads (or processes), one is awakened;
-      *      otherwise, the semaphore value is incremented by one.
-      *
-      * RESULTS
-      *              0               successfully posted semaphore,
-      *              -1              failed, error in errno
-      * ERRNO
-      *              EINVAL          'sem' is not a valid semaphore,
-      *              ENOSYS          semaphores are not supported,
-      *              ERANGE          semaphore count is too big
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  sem_t s = *sem;
-
-  if (s == NULL)
-    {
-      result = EINVAL;
-    }
-  else if ((result = pthread_mutex_lock (&s->lock)) == 0)
-    {
-      /* See sem_destroy.c
-       */
-      if (*sem == NULL)
-        {
-          (void) pthread_mutex_unlock (&s->lock);
-          result = EINVAL;
-          return -1;
-        }
-
-      if (s->value < SEM_VALUE_MAX)
-	{
-#if defined(NEED_SEM)
-	  if (++s->value <= 0
-	      && !SetEvent(s->sem))
-	    {
-	      s->value--;
-	      result = EINVAL;
-	    }
-#else
-	  if (++s->value <= 0
-	      && !ReleaseSemaphore (s->sem, 1, NULL))
-	    {
-	      s->value--;
-	      result = EINVAL;
-	    }
-#endif /* NEED_SEM */
-	}
-      else
-	{
-	  result = ERANGE;
-	}
-
-      (void) pthread_mutex_unlock (&s->lock);
-    }
-
-  if (result != 0)
-    {
-      errno = result;
-      return -1;
-    }
-
-  return 0;
-
-}				/* sem_post */
diff --git a/deps/w32-pthreads/sem_post_multiple.c b/deps/w32-pthreads/sem_post_multiple.c
deleted file mode 100644
index c0a3f68..0000000
--- a/deps/w32-pthreads/sem_post_multiple.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: sem_post_multiple.c
- *
- * Purpose:
- *	Semaphores aren't actually part of the PThreads standard.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1b-1993	(POSIX.1b)
- *
- * -------------------------------------------------------------
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-
-int
-sem_post_multiple (sem_t * sem, int count)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function posts multiple wakeups to a semaphore.
-      *
-      * PARAMETERS
-      *      sem
-      *              pointer to an instance of sem_t
-      *
-      *      count
-      *              counter, must be greater than zero.
-      *
-      * DESCRIPTION
-      *      This function posts multiple wakeups to a semaphore. If there
-      *      are waiting threads (or processes), n <= count are awakened;
-      *      the semaphore value is incremented by count - n.
-      *
-      * RESULTS
-      *              0               successfully posted semaphore,
-      *              -1              failed, error in errno
-      * ERRNO
-      *              EINVAL          'sem' is not a valid semaphore
-      *                              or count is less than or equal to zero.
-      *              ERANGE          semaphore count is too big
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  long waiters;
-  sem_t s = *sem;
-
-  if (s == NULL || count <= 0)
-    {
-      result = EINVAL;
-    }
-  else if ((result = pthread_mutex_lock (&s->lock)) == 0)
-    {
-      /* See sem_destroy.c
-       */
-      if (*sem == NULL)
-        {
-          (void) pthread_mutex_unlock (&s->lock);
-          result = EINVAL;
-          return -1;
-        }
-
-      if (s->value <= (SEM_VALUE_MAX - count))
-	{
-	  waiters = -s->value;
-	  s->value += count;
-	  if (waiters > 0)
-	    {
-#if defined(NEED_SEM)
-	      if (SetEvent(s->sem))
-		{
-		  waiters--;
-		  s->leftToUnblock += count - 1;
-		  if (s->leftToUnblock > waiters)
-		    {
-		      s->leftToUnblock = waiters;
-		    }
-		}
-#else
-	      if (ReleaseSemaphore (s->sem,  (waiters<=count)?waiters:count, 0))
-		{
-		  /* No action */
-		}
-#endif
-	      else
-		{
-		  s->value -= count;
-		  result = EINVAL;
-		}
-	    }
-	}
-      else
-	{
-	  result = ERANGE;
-	}
-      (void) pthread_mutex_unlock (&s->lock);
-    }
-
-  if (result != 0)
-    {
-      errno = result;
-      return -1;
-    }
-
-  return 0;
-
-}				/* sem_post_multiple */
diff --git a/deps/w32-pthreads/sem_timedwait.c b/deps/w32-pthreads/sem_timedwait.c
deleted file mode 100644
index 831a050..0000000
--- a/deps/w32-pthreads/sem_timedwait.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: sem_timedwait.c
- *
- * Purpose:
- *	Semaphores aren't actually part of the PThreads standard.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1b-1993	(POSIX.1b)
- *
- * -------------------------------------------------------------
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-
-typedef struct {
-  sem_t sem;
-  int * resultPtr;
-} sem_timedwait_cleanup_args_t;
-
-
-static void PTW32_CDECL
-ptw32_sem_timedwait_cleanup (void * args)
-{
-  sem_timedwait_cleanup_args_t * a = (sem_timedwait_cleanup_args_t *)args;
-  sem_t s = a->sem;
-
-  if (pthread_mutex_lock (&s->lock) == 0)
-    {
-      /*
-       * We either timed out or were cancelled.
-       * If someone has posted between then and now we try to take the semaphore.
-       * Otherwise the semaphore count may be wrong after we
-       * return. In the case of a cancellation, it is as if we
-       * were cancelled just before we return (after taking the semaphore)
-       * which is ok.
-       */
-      if (WaitForSingleObject(s->sem, 0) == WAIT_OBJECT_0)
-	{
-	  /* We got the semaphore on the second attempt */
-	  *(a->resultPtr) = 0;
-	}
-      else
-	{
-	  /* Indicate we're no longer waiting */
-	  s->value++;
-#if defined(NEED_SEM)
-	  if (s->value > 0)
-	    {
-	      s->leftToUnblock = 0;
-	    }
-#else
-          /*
-           * Don't release the W32 sema, it doesn't need adjustment
-           * because it doesn't record the number of waiters.
-           */
-#endif
-	}
-      (void) pthread_mutex_unlock (&s->lock);
-    }
-}
-
-
-int
-sem_timedwait (sem_t * sem, const struct timespec *abstime)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function waits on a semaphore possibly until
-      *      'abstime' time.
-      *
-      * PARAMETERS
-      *      sem
-      *              pointer to an instance of sem_t
-      *
-      *      abstime
-      *              pointer to an instance of struct timespec
-      *
-      * DESCRIPTION
-      *      This function waits on a semaphore. If the
-      *      semaphore value is greater than zero, it decreases
-      *      its value by one. If the semaphore value is zero, then
-      *      the calling thread (or process) is blocked until it can
-      *      successfully decrease the value or until interrupted by
-      *      a signal.
-      *
-      *      If 'abstime' is a NULL pointer then this function will
-      *      block until it can successfully decrease the value or
-      *      until interrupted by a signal.
-      *
-      * RESULTS
-      *              0               successfully decreased semaphore,
-      *              -1              failed, error in errno
-      * ERRNO
-      *              EINVAL          'sem' is not a valid semaphore,
-      *              ENOSYS          semaphores are not supported,
-      *              EINTR           the function was interrupted by a signal,
-      *              EDEADLK         a deadlock condition was detected.
-      *              ETIMEDOUT       abstime elapsed before success.
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  sem_t s = *sem;
-
-  pthread_testcancel();
-
-  if (sem == NULL)
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      DWORD milliseconds;
-
-      if (abstime == NULL)
-	{
-	  milliseconds = INFINITE;
-	}
-      else
-	{
-	  /* 
-	   * Calculate timeout as milliseconds from current system time. 
-	   */
-	  milliseconds = ptw32_relmillisecs (abstime);
-	}
-
-      if ((result = pthread_mutex_lock (&s->lock)) == 0)
-	{
-	  int v;
-
-	  /* See sem_destroy.c
-	   */
-	  if (*sem == NULL)
-	    {
-	      (void) pthread_mutex_unlock (&s->lock);
-	      errno = EINVAL;
-	      return -1;
-	    }
-
-	  v = --s->value;
-	  (void) pthread_mutex_unlock (&s->lock);
-
-	  if (v < 0)
-	    {
-#if defined(NEED_SEM)
-	      int timedout;
-#endif
-	      sem_timedwait_cleanup_args_t cleanup_args;
-
-	      cleanup_args.sem = s;
-	      cleanup_args.resultPtr = &result;
-
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth(0)
-#endif
-	      /* Must wait */
-              pthread_cleanup_push(ptw32_sem_timedwait_cleanup, (void *) &cleanup_args);
-#if defined(NEED_SEM)
-	      timedout =
-#endif
-	      result = pthreadCancelableTimedWait (s->sem, milliseconds);
-	      pthread_cleanup_pop(result);
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth()
-#endif
-
-#if defined(NEED_SEM)
-
-	      if (!timedout && pthread_mutex_lock (&s->lock) == 0)
-	        {
-        	  if (*sem == NULL)
-        	    {
-        	      (void) pthread_mutex_unlock (&s->lock);
-        	      errno = EINVAL;
-        	      return -1;
-        	    }
-
-	          if (s->leftToUnblock > 0)
-	            {
-		      --s->leftToUnblock;
-		      SetEvent(s->sem);
-		    }
-	          (void) pthread_mutex_unlock (&s->lock);
-	        }
-
-#endif /* NEED_SEM */
-
-	    }
-	}
-
-    }
-
-  if (result != 0)
-    {
-
-      errno = result;
-      return -1;
-
-    }
-
-  return 0;
-
-}				/* sem_timedwait */
diff --git a/deps/w32-pthreads/sem_trywait.c b/deps/w32-pthreads/sem_trywait.c
deleted file mode 100644
index cf5f5bb..0000000
--- a/deps/w32-pthreads/sem_trywait.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: sem_trywait.c
- *
- * Purpose:
- *	Semaphores aren't actually part of the PThreads standard.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1b-1993	(POSIX.1b)
- *
- * -------------------------------------------------------------
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-
-int
-sem_trywait (sem_t * sem)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function tries to wait on a semaphore.
-      *
-      * PARAMETERS
-      *      sem
-      *              pointer to an instance of sem_t
-      *
-      * DESCRIPTION
-      *      This function tries to wait on a semaphore. If the
-      *      semaphore value is greater than zero, it decreases
-      *      its value by one. If the semaphore value is zero, then
-      *      this function returns immediately with the error EAGAIN
-      *
-      * RESULTS
-      *              0               successfully decreased semaphore,
-      *              -1              failed, error in errno
-      * ERRNO
-      *              EAGAIN          the semaphore was already locked,
-      *              EINVAL          'sem' is not a valid semaphore,
-      *              ENOTSUP         sem_trywait is not supported,
-      *              EINTR           the function was interrupted by a signal,
-      *              EDEADLK         a deadlock condition was detected.
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  sem_t s = *sem;
-
-  if (s == NULL)
-    {
-      result = EINVAL;
-    }
-  else if ((result = pthread_mutex_lock (&s->lock)) == 0)
-    {
-      /* See sem_destroy.c
-       */
-     if (*sem == NULL)
-        {
-          (void) pthread_mutex_unlock (&s->lock);
-          errno = EINVAL;
-          return -1;
-        }
-
-      if (s->value > 0)
-	{
-	  s->value--;
-	}
-      else
-	{
-	  result = EAGAIN;
-	}
-
-      (void) pthread_mutex_unlock (&s->lock);
-    }
-
-  if (result != 0)
-    {
-      errno = result;
-      return -1;
-    }
-
-  return 0;
-
-}				/* sem_trywait */
diff --git a/deps/w32-pthreads/sem_unlink.c b/deps/w32-pthreads/sem_unlink.c
deleted file mode 100644
index a232caf..0000000
--- a/deps/w32-pthreads/sem_unlink.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: sem_unlink.c
- *
- * Purpose:
- *	Semaphores aren't actually part of the PThreads standard.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1b-1993	(POSIX.1b)
- *
- * -------------------------------------------------------------
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-/* ignore warning "unreferenced formal parameter" */
-#if defined(_MSC_VER)
-#pragma warning( disable : 4100 )
-#endif
-
-int
-sem_unlink (const char *name)
-{
-  errno = ENOSYS;
-  return -1;
-}				/* sem_unlink */
diff --git a/deps/w32-pthreads/sem_wait.c b/deps/w32-pthreads/sem_wait.c
deleted file mode 100644
index 26184fa..0000000
--- a/deps/w32-pthreads/sem_wait.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: sem_wait.c
- *
- * Purpose:
- *	Semaphores aren't actually part of the PThreads standard.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1b-1993	(POSIX.1b)
- *
- * -------------------------------------------------------------
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-
-static void PTW32_CDECL
-ptw32_sem_wait_cleanup(void * sem)
-{
-  sem_t s = (sem_t) sem;
-
-  if (pthread_mutex_lock (&s->lock) == 0)
-    {
-      /*
-       * If sema is destroyed do nothing, otherwise:-
-       * If the sema is posted between us being cancelled and us locking
-       * the sema again above then we need to consume that post but cancel
-       * anyway. If we don't get the semaphore we indicate that we're no
-       * longer waiting.
-       */
-      if (*((sem_t *)sem) != NULL && !(WaitForSingleObject(s->sem, 0) == WAIT_OBJECT_0))
-	{
-	  ++s->value;
-#if defined(NEED_SEM)
-	  if (s->value > 0)
-	    {
-	      s->leftToUnblock = 0;
-	    }
-#else
-	  /*
-	   * Don't release the W32 sema, it doesn't need adjustment
-	   * because it doesn't record the number of waiters.
-	   */
-#endif /* NEED_SEM */
-	}
-      (void) pthread_mutex_unlock (&s->lock);
-    }
-}
-
-int
-sem_wait (sem_t * sem)
-     /*
-      * ------------------------------------------------------
-      * DOCPUBLIC
-      *      This function  waits on a semaphore.
-      *
-      * PARAMETERS
-      *      sem
-      *              pointer to an instance of sem_t
-      *
-      * DESCRIPTION
-      *      This function waits on a semaphore. If the
-      *      semaphore value is greater than zero, it decreases
-      *      its value by one. If the semaphore value is zero, then
-      *      the calling thread (or process) is blocked until it can
-      *      successfully decrease the value or until interrupted by
-      *      a signal.
-      *
-      * RESULTS
-      *              0               successfully decreased semaphore,
-      *              -1              failed, error in errno
-      * ERRNO
-      *              EINVAL          'sem' is not a valid semaphore,
-      *              ENOSYS          semaphores are not supported,
-      *              EINTR           the function was interrupted by a signal,
-      *              EDEADLK         a deadlock condition was detected.
-      *
-      * ------------------------------------------------------
-      */
-{
-  int result = 0;
-  sem_t s = *sem;
-
-  pthread_testcancel();
-
-  if (s == NULL)
-    {
-      result = EINVAL;
-    }
-  else
-    {
-      if ((result = pthread_mutex_lock (&s->lock)) == 0)
-	{
-	  int v;
-
-	  /* See sem_destroy.c
-	   */
-	  if (*sem == NULL)
-	    {
-	      (void) pthread_mutex_unlock (&s->lock);
-	      errno = EINVAL;
-	      return -1;
-	    }
-
-          v = --s->value;
-	  (void) pthread_mutex_unlock (&s->lock);
-
-	  if (v < 0)
-	    {
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth(0)
-#endif
-	      /* Must wait */
-	      pthread_cleanup_push(ptw32_sem_wait_cleanup, (void *) s);
-	      result = pthreadCancelableWait (s->sem);
-	      /* Cleanup if we're canceled or on any other error */
-	      pthread_cleanup_pop(result);
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#pragma inline_depth()
-#endif
-	    }
-#if defined(NEED_SEM)
-
-	  if (!result && pthread_mutex_lock (&s->lock) == 0)
-	    {
-	      if (*sem == NULL)
-	        {
-	          (void) pthread_mutex_unlock (&s->lock);
-	          errno = EINVAL;
-	          return -1;
-	        }
-
-	      if (s->leftToUnblock > 0)
-		{
-		  --s->leftToUnblock;
-		  SetEvent(s->sem);
-		}
-	      (void) pthread_mutex_unlock (&s->lock);
-	    }
-
-#endif /* NEED_SEM */
-
-	}
-
-    }
-
-  if (result != 0)
-    {
-      errno = result;
-      return -1;
-    }
-
-  return 0;
-
-}				/* sem_wait */
diff --git a/deps/w32-pthreads/semaphore.c b/deps/w32-pthreads/semaphore.c
deleted file mode 100644
index dfcab9e..0000000
--- a/deps/w32-pthreads/semaphore.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * -------------------------------------------------------------
- *
- * Module: semaphore.c
- *
- * Purpose:
- *	Concatenated version of separate modules to allow
- *	inlining optimisation, which it is assumed can only
- *	be effective within a single module.
- *
- *	Semaphores aren't actually part of the PThreads standard.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1b-1993	(POSIX.1b)
- *
- * -------------------------------------------------------------
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#if !defined(NEED_FTIME)
-#  include <sys/timeb.h>
-#endif
-
-#include <limits.h>
-
-#include "pthread.h"
-#include "semaphore.h"
-#include "implement.h"
-
-
-#include "sem_init.c"
-#include "sem_destroy.c"
-#include "sem_trywait.c"
-#include "sem_wait.c"
-#include "sem_timedwait.c"
-#include "sem_post.c"
-#include "sem_post_multiple.c"
-#include "sem_getvalue.c"
-#include "sem_open.c"
-#include "sem_close.c"
-#include "sem_unlink.c"
diff --git a/deps/w32-pthreads/semaphore.h b/deps/w32-pthreads/semaphore.h
deleted file mode 100644
index 52890ed..0000000
--- a/deps/w32-pthreads/semaphore.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Module: semaphore.h
- *
- * Purpose:
- *	Semaphores aren't actually part of the PThreads standard.
- *	They are defined by the POSIX Standard:
- *
- *		POSIX 1003.1b-1993	(POSIX.1b)
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-#if !defined( SEMAPHORE_H )
-#define SEMAPHORE_H
-
-#undef PTW32_SEMAPHORE_LEVEL
-
-#if defined(_POSIX_SOURCE)
-#define PTW32_SEMAPHORE_LEVEL 0
-/* Early POSIX */
-#endif
-
-#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
-#undef PTW32_SEMAPHORE_LEVEL
-#define PTW32_SEMAPHORE_LEVEL 1
-/* Include 1b, 1c and 1d */
-#endif
-
-#if defined(INCLUDE_NP)
-#undef PTW32_SEMAPHORE_LEVEL
-#define PTW32_SEMAPHORE_LEVEL 2
-/* Include Non-Portable extensions */
-#endif
-
-#define PTW32_SEMAPHORE_LEVEL_MAX 3
-
-#if !defined(PTW32_SEMAPHORE_LEVEL)
-#define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX
-/* Include everything */
-#endif
-
-#if defined(__GNUC__) && ! defined (__declspec)
-# error Please upgrade your GNU compiler to one that supports __declspec.
-#endif
-
-/*
- * When building the library, you should define PTW32_BUILD so that
- * the variables/functions are exported correctly. When using the library,
- * do NOT define PTW32_BUILD, and then the variables/functions will
- * be imported correctly.
- */
-#if !defined(PTW32_STATIC_LIB)
-#  if defined(PTW32_BUILD)
-#    define PTW32_DLLPORT __declspec (dllexport)
-#  else
-#    define PTW32_DLLPORT
-#  endif
-#else
-#  define PTW32_DLLPORT
-#endif
-
-/*
- * This is a duplicate of what is in the autoconf config.h,
- * which is only used when building the pthread-win32 libraries.
- */
-
-#if !defined(PTW32_CONFIG_H)
-#  if defined(WINCE)
-#    define NEED_ERRNO
-#    define NEED_SEM
-#  endif
-#  if defined(__MINGW64__)
-#    define HAVE_STRUCT_TIMESPEC
-#    define HAVE_MODE_T
-#  elif defined(_UWIN) || defined(__MINGW32__)
-#    define HAVE_MODE_T
-#  endif
-#endif
-
-/*
- *
- */
-
-#if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX
-#if defined(NEED_ERRNO)
-#include "need_errno.h"
-#else
-#include <errno.h>
-#endif
-#endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */
-
-#define _POSIX_SEMAPHORES
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif				/* __cplusplus */
-
-#if !defined(HAVE_MODE_T)
-typedef unsigned int mode_t;
-#endif
-
-
-typedef struct sem_t_ * sem_t;
-
-PTW32_DLLPORT int __cdecl sem_init (sem_t * sem,
-			    int pshared,
-			    unsigned int value);
-
-PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem);
-
-PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem);
-
-PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem);
-
-PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem,
-				 const struct timespec * abstime);
-
-PTW32_DLLPORT int __cdecl sem_post (sem_t * sem);
-
-PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem,
-				     int count);
-
-PTW32_DLLPORT int __cdecl sem_open (const char * name,
-			    int oflag,
-			    mode_t mode,
-			    unsigned int value);
-
-PTW32_DLLPORT int __cdecl sem_close (sem_t * sem);
-
-PTW32_DLLPORT int __cdecl sem_unlink (const char * name);
-
-PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem,
-				int * sval);
-
-#if defined(__cplusplus)
-}				/* End of extern "C" */
-#endif				/* __cplusplus */
-
-#undef PTW32_SEMAPHORE_LEVEL
-#undef PTW32_SEMAPHORE_LEVEL_MAX
-
-#endif				/* !SEMAPHORE_H */
diff --git a/deps/w32-pthreads/signal.c b/deps/w32-pthreads/signal.c
deleted file mode 100644
index 32a1e44..0000000
--- a/deps/w32-pthreads/signal.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * signal.c
- *
- * Description:
- * Thread-aware signal functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-/*
- * Possible future strategy for implementing pthread_kill()
- * ========================================================
- *
- * Win32 does not implement signals.
- * Signals are simply software interrupts.
- * pthread_kill() asks the system to deliver a specified
- * signal (interrupt) to a specified thread in the same
- * process.
- * Signals are always asynchronous (no deferred signals).
- * Pthread-win32 has an async cancelation mechanism.
- * A similar system can be written to deliver signals
- * within the same process (on ix86 processors at least).
- *
- * Each thread maintains information about which
- * signals it will respond to. Handler routines
- * are set on a per-process basis - not per-thread.
- * When signalled, a thread will check it's sigmask
- * and, if the signal is not being ignored, call the
- * handler routine associated with the signal. The
- * thread must then (except for some signals) return to
- * the point where it was interrupted.
- *
- * Ideally the system itself would check the target thread's
- * mask before possibly needlessly bothering the thread
- * itself. This could be done by pthread_kill(), that is,
- * in the signaling thread since it has access to
- * all pthread_t structures. It could also retrieve
- * the handler routine address to minimise the target
- * threads response overhead. This may also simplify
- * serialisation of the access to the per-thread signal
- * structures.
- *
- * pthread_kill() eventually calls a routine similar to
- * ptw32_cancel_thread() which manipulates the target
- * threads processor context to cause the thread to
- * run the handler launcher routine. pthread_kill() must
- * save the target threads current context so that the
- * handler launcher routine can restore the context after
- * the signal handler has returned. Some handlers will not
- * return, eg. the default SIGKILL handler may simply
- * call pthread_exit().
- *
- * The current context is saved in the target threads
- * pthread_t structure.
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-#if defined(HAVE_SIGSET_T)
-
-static void
-ptw32_signal_thread ()
-{
-}
-
-static void
-ptw32_signal_callhandler ()
-{
-}
-
-int
-pthread_sigmask (int how, sigset_t const *set, sigset_t * oset)
-{
-  pthread_t thread = pthread_self ();
-
-  if (thread.p == NULL)
-    {
-      return ENOENT;
-    }
-
-  /* Validate the `how' argument. */
-  if (set != NULL)
-    {
-      switch (how)
-	{
-	case SIG_BLOCK:
-	  break;
-	case SIG_UNBLOCK:
-	  break;
-	case SIG_SETMASK:
-	  break;
-	default:
-	  /* Invalid `how' argument. */
-	  return EINVAL;
-	}
-    }
-
-  /* Copy the old mask before modifying it. */
-  if (oset != NULL)
-    {
-      memcpy (oset, &(thread.p->sigmask), sizeof (sigset_t));
-    }
-
-  if (set != NULL)
-    {
-      unsigned int i;
-
-      /* FIXME: this code assumes that sigmask is an even multiple of
-         the size of a long integer. */
-
-      unsigned long *src = (unsigned long const *) set;
-      unsigned long *dest = (unsigned long *) &(thread.p->sigmask);
-
-      switch (how)
-	{
-	case SIG_BLOCK:
-	  for (i = 0; i < (sizeof (sigset_t) / sizeof (unsigned long)); i++)
-	    {
-	      /* OR the bit field longword-wise. */
-	      *dest++ |= *src++;
-	    }
-	  break;
-	case SIG_UNBLOCK:
-	  for (i = 0; i < (sizeof (sigset_t) / sizeof (unsigned long)); i++)
-	    {
-	      /* XOR the bitfield longword-wise. */
-	      *dest++ ^= *src++;
-	    }
-	case SIG_SETMASK:
-	  /* Replace the whole sigmask. */
-	  memcpy (&(thread.p->sigmask), set, sizeof (sigset_t));
-	  break;
-	}
-    }
-
-  return 0;
-}
-
-int
-sigwait (const sigset_t * set, int *sig)
-{
-  /* This routine is a cancellation point */
-  pthread_test_cancel();
-}
-
-int
-sigaction (int signum, const struct sigaction *act, struct sigaction *oldact)
-{
-}
-
-#endif /* HAVE_SIGSET_T */
diff --git a/deps/w32-pthreads/spin.c b/deps/w32-pthreads/spin.c
deleted file mode 100644
index bf44e59..0000000
--- a/deps/w32-pthreads/spin.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * spin.c
- *
- * Description:
- * This translation unit implements spin lock primitives.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-#include "ptw32_spinlock_check_need_init.c"
-#include "pthread_spin_init.c"
-#include "pthread_spin_destroy.c"
-#include "pthread_spin_lock.c"
-#include "pthread_spin_unlock.c"
-#include "pthread_spin_trylock.c"
diff --git a/deps/w32-pthreads/sync.c b/deps/w32-pthreads/sync.c
deleted file mode 100644
index c0f8fca..0000000
--- a/deps/w32-pthreads/sync.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * sync.c
- *
- * Description:
- * This translation unit implements functions related to thread
- * synchronisation.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-#include "pthread_detach.c"
-#include "pthread_join.c"
diff --git a/deps/w32-pthreads/tests/Bmakefile b/deps/w32-pthreads/tests/Bmakefile
deleted file mode 100644
index 277ad5f..0000000
--- a/deps/w32-pthreads/tests/Bmakefile
+++ /dev/null
@@ -1,358 +0,0 @@
-# Makefile for the pthreads test suite.
-# If all of the .pass files can be created, the test suite has passed.
-#
-# --------------------------------------------------------------------------
-#
-#      Pthreads-win32 - POSIX Threads Library for Win32
-#      Copyright(C) 1998 John E. Bossom
-#      Copyright(C) 1999,2005 Pthreads-win32 contributors
-# 
-#      Contact Email: rpj at callisto.canberra.edu.au
-# 
-#      The current list of contributors is contained
-#      in the file CONTRIBUTORS included with the source
-#      code distribution. The list can also be seen at the
-#      following World Wide Web location:
-#      http://sources.redhat.com/pthreads-win32/contributors.html
-# 
-#      This library is free software; you can redistribute it and/or
-#      modify it under the terms of the GNU Lesser General Public
-#      License as published by the Free Software Foundation; either
-#      version 2 of the License, or (at your option) any later version.
-# 
-#      This library is distributed in the hope that it will be useful,
-#      but WITHOUT ANY WARRANTY; without even the implied warranty of
-#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#      Lesser General Public License for more details.
-# 
-#      You should have received a copy of the GNU Lesser General Public
-#      License along with this library in the file COPYING.LIB;
-#      if not, write to the Free Software Foundation, Inc.,
-#      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-#
-
-DLL_VER	= 2
-
-CP	= copy
-RM	= erase
-CAT	= type
-MKDIR	= mkdir
-TOUCH	= echo Passed >
-ECHO	= @echo
-
-# The next path is relative to $BUILD_DIR
-QAPC	= # ..\QueueUserAPCEx\User\quserex.dll
-
-CPHDR	= pthread.h semaphore.h sched.h
-
-OPTIM	= -O2
-
-XXLIBS	= cw32mti.lib ws2_32.lib
-
-# C++ Exceptions
-BCEFLAGS	= -P -DPtW32NoCatchWarn -D__CLEANUP_CXX
-BCELIB	= pthreadBCE$(DLL_VER).lib
-BCEDLL	= pthreadBCE$(DLL_VER).dll
-# C cleanup code
-BCFLAGS	= -D__CLEANUP_C
-BCLIB	= pthreadBC$(DLL_VER).lib
-BCDLL	= pthreadBC$(DLL_VER).dll
-# C++ Exceptions in application - using VC version of pthreads dll
-BCXFLAGS	= -D__CLEANUP_C
-
-# Defaults
-CPLIB	= $(BCLIB)
-CPDLL	= $(BCDLL)
-
-CFLAGS= -q $(OPTIM) /D_WIN32_WINNT=0x400 -w -tWC -tWM -4 -w-aus -w-asc -w-par
-LFLAGS= 
-INCLUDES=-I.
-BUILD_DIR=..
-
-COPYFILES	= $(CPHDR) $(CPLIB) $(CPDLL) $(QAPC)
-
-EHFLAGS	=
-
-# If a test case returns a non-zero exit code to the shell, make will
-# stop.
-
-PASSES=   loadfree.pass \
-	  errno1.pass  \
-	  self1.pass  mutex5.pass  \
-	  mutex1.pass  mutex1n.pass  mutex1e.pass  mutex1r.pass  \
-	  semaphore1.pass  semaphore2.pass  semaphore3.pass  \
-	  mutex2.pass  mutex3.pass  \
-	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  \
-	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  \
-	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  \
-	  sequence1.pass  kill1.pass  valid1.pass  valid2.pass  \
-	  exit2.pass  exit3.pass  exit4.pass  exit5.pass  \
-	  join0.pass  join1.pass  detach1.pass  join2.pass join3.pass  \
-	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  \
-	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  \
-	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  \
-	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  \
-	  robust1.pass  robust2.pass  robust3.pass  robust4.pass  robust5.pass  \
-	  count1.pass  \
-	  once1.pass  once2.pass  once3.pass  once4.pass  \
-	  self2.pass  \
-	  cancel1.pass  cancel2.pass  \
-	  semaphore4.pass  semaphore4t.pass  semaphore5.pass  \
-	  barrier1.pass  barrier2.pass  barrier3.pass  barrier4.pass  barrier5.pass barrier6.pass \
-	  tsd1.pass  tsd2.pass  delay1.pass  delay2.pass  eyal1.pass  \
-	  condvar3.pass  condvar3_1.pass  condvar3_2.pass  condvar3_3.pass  \
-	  condvar4.pass  condvar5.pass  condvar6.pass  \
-	  condvar7.pass  condvar8.pass  condvar9.pass  \
-	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  \
-	  rwlock5.pass  rwlock6.pass  rwlock7.pass  rwlock8.pass  \
-	  rwlock2_t.pass  rwlock3_t.pass  rwlock4_t.pass  rwlock5_t.pass  rwlock6_t.pass  rwlock6_t2.pass  \
-	  context1.pass  \
-	  cancel3.pass  cancel4.pass  cancel5.pass  cancel6a.pass  cancel6d.pass  \
-	  cancel7.pass  cancel8.pass  \
-	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  \
-	  priority1.pass priority2.pass inherit1.pass  \
-	  spin1.pass  spin2.pass  spin3.pass  spin4.pass  \
-	  exception1.pass  exception2.pass  exception3.pass  \
-	  cancel9.pass  stress1.pass
-
-BENCHRESULTS = \
-	  benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench
-
-help:
-	@ $(ECHO) Run one of the following command lines:
-	@ $(ECHO) make clean BC    (to test using BC dll with VC (no EH) applications)
-	@ $(ECHO) make clean BCX   (to test using BC dll with VC++ (EH) applications)
-	@ $(ECHO) make clean BCE   (to test using the BCE dll with VC++ EH applications)
-	@ $(ECHO) make clean BC-bench    (to benchtest using BC dll with C bench app)
-	@ $(ECHO) make clean BCX-bench   (to benchtest using BC dll with C++ bench app)
-	@ $(ECHO) make clean BCE-bench   (to benchtest using BCE dll with C++ bench app)
-
-all:
-	@ make clean BC
-	@ make clean BCX
-	@ make clean BCE
-	@ make clean BC-bench
-
-# This allows an individual test application to be made using the default lib.
-# e.g. make clean test cancel3.exe
-test: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC)
-
-tests: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) sizes.pass $(PASSES)
-	@ $(ECHO) ALL TESTS PASSED! Congratulations!
-
-benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(BENCHRESULTS)
-	@ $(ECHO) ALL BENCH TESTS DONE.
-
-sizes.pass: sizes.exe
-	@ $(ECHO) ... Running $(TEST) test: $*.exe
-	@ .\$*.exe > SIZES.$(TEST)
-	@ $(CAT) SIZES.$(TEST)
-	@ $(ECHO) ...... Passed
-	@ $(TOUCH) $*.pass
-
-BCE:
-	@ make -f Bmakefile TEST="$@" CPLIB="$(BCELIB)" CPDLL="$(BCEDLL)" EHFLAGS="$(BCEFLAGS)" tests
-
-BC:
-	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCFLAGS)" tests
-
-BCX:
-	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCXFLAGS)" tests
-
-BCE-bench:
-	@ make -f Bmakefile TEST="$@" CPLIB="$(BCELIB)" CPDLL="$(BCEDLL)" EHFLAGS="$(BCEFLAGS)" XXLIBS="benchlib.o" benchtests
-
-BC-bench:
-	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCFLAGS)" XXLIBS="benchlib.o" benchtests
-
-BCX-bench:
-	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCXFLAGS)" XXLIBS="benchlib.o" benchtests
-
-.exe.pass:
-	@ $(ECHO) ... Running $(TEST) test: $<
-	@ .\$<
-	@ $(ECHO) ...... Passed
-	@ $(TOUCH) $@
-
-.exe.bench:
-	@ $(ECHO) ... Running $(TEST) benchtest: $<
-	@ .\$<
-	@ $(ECHO) ...... Done
-	@ $(TOUCH) $@
-
-.c.exe:
-	@ $(ECHO) $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< -e$@ $(LFLAGS) $(CPLIB) $(XXLIBS)
-	@ $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< -e$@ $(LFLAGS) $(CPLIB) $(XXLIBS)
-
-.c.o:
-	@ $(ECHO) $(CC) $(EHFLAGS) -c $(CFLAGS) $(INCLUDES) $< -o$@
-	@ $(CC) $(EHFLAGS) $(CFLAGS) -c $(INCLUDES) $< -o$@
-
-
-.c.i:
-	@ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $<
-
-$(COPYFILES):
-	@ $(ECHO) Copying $(BUILD_DIR)\$@
-	@ $(CP) $(BUILD_DIR)\$@ .
-
-pthread.dll: $(CPDLL)
-	@ $(CP) $(CPDLL) pthread.dll
-	@ $(CP) $(CPLIB) pthread.lib
-
-clean:
-	- $(RM) *.dll
-	- $(RM) *.lib
-	- $(RM) pthread.h
-	- $(RM) semaphore.h
-	- $(RM) sched.h
-	- $(RM) *.e
-	- $(RM) *.i
-	- $(RM) *.obj
-	- $(RM) *.tds
-	- $(RM) *.pdb
-	- $(RM) *.o
-	- $(RM) *.asm
-	- $(RM) *.exe
-	- $(RM) *.pass
-	- $(RM) *.bench
-	- $(RM) *.log
-
-benchtest1.bench:
-benchtest2.bench:
-benchtest3.bench:
-benchtest4.bench:
-benchtest5.bench:
-barrier1.pass: semaphore4.pass
-barrier2.pass: barrier1.pass
-barrier3.pass: barrier2.pass
-barrier4.pass: barrier3.pass
-barrier5.pass: barrier4.pass
-barrier6.pass: barrier5.pass
-cancel1.pass: create1.pass
-cancel2.pass: cancel1.pass
-cancel3.pass: context1.pass
-cancel4.pass: cancel3.pass
-cancel5.pass: cancel3.pass
-cancel6a.pass: cancel3.pass
-cancel6d.pass: cancel3.pass
-cancel7.pass: kill1.pass
-cancel8.pass: cancel7.pass
-cancel9.pass: cancel8.pass
-cleanup0.pass: cancel5.pass
-cleanup1.pass: cleanup0.pass
-cleanup2.pass: cleanup1.pass
-cleanup3.pass: cleanup2.pass
-condvar1.pass:
-condvar1_1.pass: condvar1.pass
-condvar1_2.pass: join2.pass
-condvar2.pass: condvar1.pass
-condvar2_1.pass: condvar2.pass join2.pass
-condvar3.pass: create1.pass condvar2.pass
-condvar3_1.pass: condvar3.pass join2.pass
-condvar3_2.pass: condvar3_1.pass
-condvar3_3.pass: condvar3_2.pass
-condvar4.pass: create1.pass
-condvar5.pass: condvar4.pass
-condvar6.pass: condvar5.pass
-condvar7.pass: condvar6.pass cleanup1.pass
-condvar8.pass: condvar7.pass
-condvar9.pass: condvar8.pass
-context1.pass: cancel1.pass
-count1.pass: join1.pass
-create1.pass: mutex2.pass
-create2.pass: create1.pass
-delay1.pass:
-delay2.pass: delay1.pass
-detach1.pass: join0.pass
-equal1.pass: create1.pass
-errno1.pass: mutex3.pass
-exception1.pass: cancel4.pass
-exception2.pass: exception1.pass
-exception3.pass: exception2.pass
-exit1.pass:
-exit2.pass: create1.pass
-exit3.pass: create1.pass
-exit4.pass:
-exit5.pass: kill1.pass
-eyal1.pass: tsd1.pass
-inherit1.pass: join1.pass priority1.pass
-join0.pass: create1.pass
-join1.pass: create1.pass
-join2.pass: create1.pass
-join3.pass: join2.pass
-kill1.pass: 
-loadfree.pass: pthread.dll
-mutex1.pass: self1.pass
-mutex1n.pass: mutex1.pass
-mutex1e.pass: mutex1.pass
-mutex1r.pass: mutex1.pass
-mutex2.pass: mutex1.pass
-mutex2r.pass: mutex2.pass
-mutex2e.pass: mutex2.pass
-mutex3.pass: create1.pass
-mutex3r.pass: mutex3.pass
-mutex3e.pass: mutex3.pass
-mutex4.pass: mutex3.pass
-mutex5.pass:
-mutex6.pass: mutex4.pass
-mutex6n.pass: mutex4.pass
-mutex6e.pass: mutex4.pass
-mutex6r.pass: mutex4.pass
-mutex6s.pass: mutex6.pass
-mutex6rs.pass: mutex6r.pass
-mutex6es.pass: mutex6e.pass
-mutex7.pass: mutex6.pass
-mutex7n.pass: mutex6n.pass
-mutex7e.pass: mutex6e.pass
-mutex7r.pass: mutex6r.pass
-mutex8.pass: mutex7.pass
-mutex8n.pass: mutex7n.pass
-mutex8e.pass: mutex7e.pass
-mutex8r.pass: mutex7r.pass
-once1.pass: create1.pass
-once2.pass: once1.pass
-once3.pass: once2.pass
-once4.pass: once3.pass
-priority1.pass: join1.pass
-priority2.pass: priority1.pass barrier3.pass
-reuse1.pass: create2.pass
-reuse2.pass: reuse1.pass
-robust1.pass: mutex8r.pass
-robust2.pass: mutex8r.pass
-robust3.pass: robust2.pass
-robust4.pass: robust3.pass
-robust5.pass: robust4.pass
-rwlock1.pass: condvar6.pass
-rwlock2.pass: rwlock1.pass
-rwlock3.pass: rwlock2.pass join2.pass
-rwlock4.pass: rwlock3.pass
-rwlock5.pass: rwlock4.pass
-rwlock6.pass: rwlock5.pass
-rwlock7.pass: rwlock6.pass
-rwlock8.pass: rwlock7.pass
-rwlock2_t.pass: rwlock2.pass
-rwlock3_t.pass: rwlock2_t.pass
-rwlock4_t.pass: rwlock3_t.pass
-rwlock5_t.pass: rwlock4_t.pass
-rwlock6_t.pass: rwlock5_t.pass
-rwlock6_t2.pass: rwlock6_t.pass
-self1.pass:
-self2.pass: create1.pass
-semaphore1.pass:
-semaphore2.pass:
-semaphore3.pass: semaphore2.pass
-semaphore4.pass: semaphore3.pass cancel1.pass
-semaphore4t.pass: semaphore4.pass
-semaphore5.pass: semaphore4.pass
-sequence1.pass: reuse2.pass
-sizes.pass:
-spin1.pass:
-spin2.pass: spin1.pass
-spin3.pass: spin2.pass
-spin4.pass: spin3.pass
-stress1.pass:
-tsd1.pass: barrier5.pass join1.pass
-tsd2.pass: tsd1.pass
-valid1.pass: join1.pass
-valid2.pass: valid1.pass
diff --git a/deps/w32-pthreads/tests/ChangeLog b/deps/w32-pthreads/tests/ChangeLog
deleted file mode 100644
index dfb4f45..0000000
--- a/deps/w32-pthreads/tests/ChangeLog
+++ /dev/null
@@ -1,1000 +0,0 @@
-2011-07-03  Ross Johnson <ross dot johnson at homemail dot com dot au>
-
-	* create3.c: Removed; testing a condition that is not in the library's
-	scope and was more trouble than it was worth.
-	* cancel2.c: Ensure this test only runs for Structured or C++ EH.
-	* exit2.c: Shorten Sleep() time.
-	* exit3.c: Likewise.
-	* cancel1.c: Likewise.
-	* cancel3.c: Likewise.
-	* exception3.c: Likewise; make terminate routine consistent for all
-	build environments.
-
-2011-07-02  Ross Johnson <ross dot johnson at homemail dot com dot au>
-
-	* spin3.c: Unlock the unlocked spinlock now returns success.
-	* rwlock3.c: Join the thread to ensure it's completed.
-	* rwlock4.c: Likewise.
-	* rwlock5.c: Likewise.
-	* Makefile: Adjust prerequisites.
-	* GNUmakefile: Likewise.
-	* Bmakefile: Likewise.
-	* Wmakefile: Likewise.
-
-2011-07-02 Daniel Richard G. <skunk at iskunk dot org>
-
-	* *.[ch]: Cleanups around timeb struct, mainly centralising
-	macro definitions in test.h.
-	* Makefile: Fix annoying nmake warning.
-
-2011-06-30  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* sequence1.c: Fix loop overrun.
-
-2011-05-11  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* GNUmakefile (GCE-debug): New target; expects pthreadGCE2d.dll.
-	
-2011-05-05  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* openmp1.c: Add missing test; used to comfirm that this
-	library works with libgomp; if this test produces a segfault
-	then try upgrading your version of libgomp/gcc; gcc version
-	4.5.2 passes this test.
-
-2011-03-26  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* sequence1.c: New test for new pthread_getsequence_np().
-
-2011-03-24  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* mutex*.c: Include tests for robust mutexes wherever
-	appropriate.
-	* benchtest*.c: Include comparisons for robust mutexes.
-	* robust1.c: New test for robust mutex handling.
-	* robust2.c: Likewise.
-	* robust3.c: Likewise.
-	* robust4.c: Likewise.
-	* robust5.c: Likewise.
-	* GNUmakefile: Include new tests.
-	* Makefile: Likewise.
-	* Bmakefile: Likewise (not tested).
-	* Wmakefile: Likewise (not tested).
-
-2011-03-06  Ross Johnson <ross.johnson at homemail.com.au>
-
-	* several (MINGW64): Cast and call fixups for 64 bit compatibility;
-	clean build via x86_64-w64-mingw32 cross toolchain on Linux
-	i686 targeting x86_64 win64.
-
-2011-03-04  Ross Johnson <Ross dot Johnson at homemail dot com dot au>
-
-	* condvar3_2.c: abstime.tv_sec operation warning fixed.
-	* several: Use correct casting on pthread_join result arg
-	and associated declaration and usage; assumed that 64 bit
-	gcc gave some warnings for it.
-
-2011-02-28  Ross Johnson <Ross dot Johnson at homemail dot com dot au>
-
-	* test.h: Define FTIME to be _ftime64_s or _ftime64 or _ftime
-	in that order of preference where supported.
-	* several: Replace calls to _ftime with the FTIME macro.
-
-2010-06-19  Ross Johnson <Ross dot Johnson at homemail dot com dot au>
-
-	* Makefile (STATICRESULTS): Add all tests into suite for static
-	library.
-	* GNUmakefile (STATICTESTS): Likewise, except for openmp1.c which
-	has a DLL dependency.
-
-2010-02-04  Ross Johnson <Ross dot Johnson at homemail dot com dot au>
-
-	* openmp1.c: New; for libgomp compatibility (OpenMP).
-	* barrier5.c: Rewrite after changes to barriers.
-	* barrier6.c: New.
-	* benchtest6.c: New; timing barriers.
-	* GNUMakefile: Update for new tests.
-	* Makefile: Ditto.
-	* BMakefile: Ditto.
-	* once3.c: Improve cancelation testing.
-	* stress1.c: Fix comment.
-
-2007-01-04  Ross Johnson <Ross dot Johnson at homemail dot com dot au>
-
-        * context1.c: Include context.h from library sources and remove
-        x86 dependence in main().
-
-2005-06-12  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* stress1.c (millisecondsFromNow): Remove limit 0 <= millisecs < 1000;
-	now works for -INT_MAX <= millisecs <= INT_MAX; not needed for
-	stress1.c but should be general anyway.
-
-2005-05-18  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* reuse2.c (main): Must use a read with memory barrier semantics
-	when polling 'done' to force the cache into coherence on MP systems.
-
-2005-05-15  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* detach1.c: New test.
-	* join1.c: Reduce sleep times.
-	* join0.c: Remove MSVCRT conditional compile - join should always
-	return the thread exit code.
-	* join1.c: Likewise.
-	* join2.c: Likewise.
-	* join3.c: Likewise.
-
-2005-04-18  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* condvar3.c: Remove locks from around signalling calls - should not
-	be required for normal operation and only serve to mask deficiencies;
-	ensure that CV destruction is not premature after removing guards.
-	* condvar3_1.c: Likewise.
-	* condvar3_2.c: Likewise.
-	* condvar3_3.c: Likewise.
-	* condvar4.c: Likewise.
-	* condvar5.c: Likewise.
-	* condvar6.c: Likewise.
-	* condvar7.c: Likewise.
-	* condvar8.c: Likewise.
-	* condvar9.c: Likewise.
-
-2005-04-11  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-        * once4.c: New test; tries to test priority adjustments
-        in pthread_once(); set priority class to realtime so that
-        any failures can be seen.
-
-2005-04-06  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* cleanup0.c: Fix unguarded global variable accesses.
-	* cleanup1.c: Likewise.
-	* cleanup2.c: Likewise.
-	* cleanup3.c: Likewise.
-	* once2.c: Likewise.
-	* once3.c: Likewise.
-
-2005-04-01  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* GNUmakefile: Add target to test linking static link library.
-	* Makefile: Likewise.
-	* self1.c: Run process attach/detach routines when static linked.
-
-2005-03-16  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* mutex5.c: Prevent optimiser from removing asserts.
-
-2005-03-12  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* once3.c: New test.
-
-2005-03-08  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-        * once2.c: New test.
-
-2004-11-19  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* Bmakefile: New makefile for Borland.
-	* Makefile (DLL_VER): Added.
-	* GNUmakefile (DLL_VER): Added.
-	* Wmakefile (DLL_VER): Added.
-
-2004-10-29  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* semaphore4.c: New test.
-	* semaphore4t.c: New test.
-	* Debug.dsp (et al): Created MSVC Workspace project to aid debugging.
-	* All: Many tests have been modified to work with the new pthread
-	ID type; some other corrections were made after some library
-	functions were semantically strengthened. For example,
-	pthread_cond_destroy() no longer destroys a busy CV, which
-	required minor redesigns of some tests, including some where
-	the mutex associated with the CV was not locked during
-	signaling and broadcasting.
-
-2004-10-23  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* condvar3.c: Fixed mutex operations that were incorrectly
-	placed in relation to their condition variable operations.
-	The error became evident after sem_destroy() was rewritten
-	and conditions for destroing the semaphore were tightened.
-	As a result, pthread_cond_destroy() was not able to
-	destroy the cv queueing sempahore.
-	* condvar3_1.c: Likewise.
-	* condvar3_2.c: Likewise.
-	* condvar4.c: Likewise.
-	* condvar5.c: Likewise.
-	* condvar6.c: Likewise.
-	* condvar7.c: Likewise.
-	* condvar8.c: Likewise.
-	* condvar9.c: Likewise.
-
-2004-10-19  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* semaphore3.c: New test.
-
-2004-10-14  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* rwlock7.c (main): Tidy up statistics reporting; randomise
-	update accesses.
-	* rwlock8.c: New test.
-
-2004-09-08  Alexandre Girao  <alexgirao at gmail.com>
-
-	* cancel7.c (main): Win98 wants a valid (non-NULL) location
-	for the last arg of _beginthreadex().
-	* cancel8.c (main): Likewise.
-	* exit4.c (main): Likewise.
-	* exit5.c (main): Likewise.
-
-2004-08-26  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* create3.c: New test.
-
-2004-06-21  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* mutex2r.c: New test.
-	* mutex2e.c: New test.
-	* mutex3r.c: New test.
-	* mutex3e.c: New test.
-	* mutex6s.c: New test.
-	* mutex6rs.c: New test.
-	* mutex6es.c: New test.
-
-2004-05-21  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* join3.c: New test.
-
-2004-05-16  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* condvar2.c (WIN32_WINNT): Define to avoid redefinition warning
-	from inclusion of implement.h.
-	* convar2_1.c: Likewise.
-	* condvar3_1.c: Likewise.
-	* condvar3_2.c: Likewise.
-	* context1.c: Likewise.
-	* sizes.c: Likewise.
-	* Makefile: Don't define _WIN32_WINNT on compiler command line.
-	* GNUmakefile: Likewise.
-	* priority1.c (main): Add column to output for actual win32
-	priority.
-
-2004-05-16  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* cancel9.c: New test.
-	* cancel3.c: Remove inappropriate conditional compilation;
-	GNU C version of test suite no longer quietly skips this test.
-	* cancel5.c: Likewise.
-	* GNUmakefile: Can now build individual test app using default
-	C version of library using 'make clean testname.c'.
-	* Makefile: Likewise for VC using 'nmake clean test testname.c'.
-
-2003-10-14  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* Wmakefile: New makefile for Watcom testing.
-
-2003-09-18  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* benchtest.h: Move old mutex code into benchlib.c.
-	* benchlib.c: New statically linked module to ensure that
-	bench apps don't inline the code and therefore have an unfair
-	advantage over the pthreads lib routines. Made little or no
-	difference.
-	* benchtest1.c: Minor change to avoid compiler warnings.
-	* benchtest5.c: Likewise.
-	* benchtest2.c: Fix misinformation in output report.
-	* README.BENCH: Add comments on results.
-
-2003-09-14  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* priority1.c: Reworked to comply with modified priority
-	management and provide additional output.
-	* priority2.c: Likewise.
-	* inherit1.c: Likewise.
-
-2003-09-03  Ross Johnson  <rpj at callisto.canberra.edu.au>
-
-	* exit4.c: New test.
-	* exit5.c: New test.
-	* cancel7.c: New test.
-	* cancel8.c: New test.
-
-2003-08-13  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-	* reuse1.c: New test.
-	* reuse1.c: New test.
-	* valid1.c: New test.
-	* valid2.c: New test.
-	* kill1.c: New test.
- 	* create2.c: Now included in test regime.
-
-2003-07-19  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-	* eyal1.c (waste_time): Make threads do more work to ensure that
-	all threads get to do some work.
-	* semaphore1.c: Make it clear that certain errors are expected.
-	* exception2.c (non_MSVC code sections): Change to include
-	C++ standard include file, i.e. change <new.h> to <exception>.
-	* exception3.c (non_MSVC code sections): Likewise; qualify std::
-	namespace entities where necessary.
-	* GNUmakefile: modified to work in the MsysDTK (newer MinGW)
-	environment; define CC as gcc or g++ as appropriate because
-	using gcc -x c++ doesn't link with required c++ libs by default,
-	but g++ does.
-
-2002-12-11  Ross Johnson  <ross at special.ise.canberra.edu.au>
-
-	* mutex7e.c: Assert EBUSY return instead of EDEADLK.
-
-2002-06-03  Ross Johnson  <rpj at digit.ise.canberra.edu.au>
-
-	* semaphore2.c: New test.
-
-2002-03-02  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* Makefile (CFLAGS): Changed /MT to /MD to link with
-	the correct library MSVCRT.LIB. Otherwise errno doesn't
-	work.
-
-2002-02-28  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* exception3.c: Correct recent change.
-
-	* semaphore1.c: New test.
-
-	* Makefile: Add rule to generate pre-processor output.
-
-2002-02-28  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* exception3.c (terminateFunction): For MSVC++, call
-	exit() rather than pthread_exit(). Add comments to explain
-	why.
-	   * Notes from the MSVC++ manual:
-	   *       1) A term_func() should call exit(), otherwise
-	   *          abort() will be called on return to the caller.
-	   *          abort() raises SIGABRT. The default signal handler
-	   *          for all signals terminates the calling program with
-	   *          exit code 3.
-	   *       2) A term_func() must not throw an exception. Therefore
-	   *          term_func() should not call pthread_exit() if an
-	   *          an exception-using version of pthreads-win32 library
-	   *          is being used (i.e. either pthreadVCE or pthreadVSE).
-
-
-2002-02-23  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* rwlock2_t.c: New test.
-	* rwlock3_t.c: New test.
-	* rwlock4_t.c: New test.
-	* rwlock5_t.c: New test.
-	* rwlock6_t.c: New test.
-	* rwlock6_t2.c: New test.
-	* rwlock6.c (main): Swap thread and result variables
-	to correspond to actual thread functions.
-	* rwlock1.c: Change test description comment to correspond
-	to the actual test.
-
-	* condvar1_2.c: Loop over the test many times in the hope
-	of detecting any intermittent deadlocks. This is to
-	test a fixed problem in pthread_cond_destroy.c.
-
-	* spin4.c: Remove unused variable.
-
-2002-02-17  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* condvar1_1.c: New test.
-	* condvar1_2.c: New test.
-
-2002-02-07  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* delay1.c: New test.
-	* delay2.c: New test.
-	* exit4.c: New test.
-
-2002-02-02  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* mutex8: New test.
-	* mutex8n: New test.
-	* mutex8e: New test.
-	* mutex8r: New test.
-	* cancel6a: New test.
-	* cancel6d: New test.
-	* cleanup0.c: Add pragmas for inline optimisation control.
-	* cleanup1.c: Add pragmas for inline optimisation control.
-	* cleanup2.c: Add pragmas for inline optimisation control.
-	* cleanup3.c: Add pragmas for inline optimisation control.
-	* condvar7.c: Add pragmas for inline optimisation control.
-	* condvar8.c: Add pragmas for inline optimisation control.
-	* condvar9.c: Add pragmas for inline optimisation control.
-
-2002-01-30  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* cleanup1.c (): Must be declared __cdecl when compiled
-	as C++ AND testing the standard C library version.
-
-2002-01-16  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* spin4.c (main): Fix renamed function call.
-
-2002-01-14  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* exception3.c (main): Shorten wait time.
-
-2002-01-09  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* mutex7.c: New test.
-	* mutex7n.c: New test.
-	* mutex7e.c: New test.
-	* mutex7r.c: New test.
-	* mutex6.c: Modified to avoid leaving the locked mutex
-	around on exit.
-
-2001-10-25  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* condvar2.c: Remove reference to cv->nWaitersUnblocked.
-	* condvar2_1.c: Likewise; lower NUMTHREADS from 60 to 30.
-	* condvar3_1.c: Likewise.
-	* condvar3_2.c: Likewise.
-	* count1.c: lower NUMTHREADS from 60 to 30.
-	* inherit1.c: Determine valid priority values and then
-	assert values returned by POSIX routines are the same.
-	* priority1.c: Likewise.
-	* priority2.c: Likewise.
-	
-2001-07-12  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* barrier5.c: Assert that precisely one thread receives
-	PTHREAD_BARRIER_SERIAL_THREAD at each barrier.
-
-2001-07-09  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* barrier3.c: Fixed.
-	* barrier4.c: Fixed.
-	* barrier5.c: New; proves that all threads in the group
-	reaching the barrier wait and then resume together. Repeats the test
-	using groups of 1 to 16 threads. Each group of threads must negotiate
-	a large number of barriers (10000).
-	* spin4.c: Fixed.
-	* test.h (error_string): Modified the success (0) value.
-
-2001-07-07  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
-
-	* spin3.c: Changed test and fixed.
-	* spin4.c: Fixed.
-	* barrier3.c: Fixed.
-	* barrier4.c: Fixed.
-
-2001-07-05  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* spin1.c: New; testing spinlocks.
-	* spin2.c: New; testing spinlocks.
-	* spin3.c: New; testing spinlocks.
-	* spin4.c: New; testing spinlocks.
-	* barrier1.c: New; testing barriers.
-	* barrier2.c: New; testing barriers.
-	* barrier3.c: New; testing barriers.
-	* barrier4.c: New; testing barriers.
-	* GNUmakefile: Add new tests.
-	* Makefile: Add new tests.
-
-2001-07-01  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* benchtest3.c: New; timing mutexes.
-	* benchtest4.c: New; time mutexes.
-	* condvar3_1.c: Fixed bug - Alexander Terekhov
-	* condvar3_3.c: New test.
-
-2001-06-25  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* priority1.c: New test.
-	* priority2.c: New test.
-	* inherit1.c: New test.
-	* benchtest1.c: New; timing mutexes.
-	* benchtest2.c: New; timing mutexes.
-	* mutex4.c: Modified to test all mutex types.
-
-2001-06-8  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* mutex5.c: Insert inert change to quell compiler warnings.
-	* condvar3_2.c: Remove unused variable.
-	
-2001-06-3  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* condvar2_1.c: New test.
-	* condvar3_1.c: New test.
-	* condvar3_2.c: New test.
-
-2001-05-30  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* mutex1n.c: New test.
-	* mutex1e.c: New test.
-	* mutex1r.c: New test.
-	* mutex4.c: Now locks and unlocks a mutex.
-	* mutex5.c: New test.
-	* mutex6.c: New test.
-	* mutex6n.c: New test.
-	* mutex6e.c: New test.
-	* mutex6r.c: New test.
-	* Makefile: Added new tests; reorganised.
-	* GNUmakefile: Likewise.
-	* rwlock6.c: Fix to properly prove read-while-write locking
-	and single writer locking.
-
-2001-05-29  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* Makefile: Reorganisation.
-	* GNUmakefile: Likewise.
-	- Thomas Pfaff <tpfaff at gmx.net>
-
-	* exception1.c: Add stdio.h include to define fprintf and stderr
-	in non-exception C version of main().
-	* exception2.c: Likewise.
-	* exception3.c: Likewise.
-
-	* Makefile (rwlock7): Add new test.
-	* GNUmakefile (rwlock7): Add new test.
-	* rwlock7.c: New test.
-	* rwlock6.c: Changed to test that writer has priority.
-
-	* eyal1.c (main): Unlock each mutex_start lock before destroying
-	it.
-
-2000-12-29  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* GNUmakefile: Add mutex4 test; ensure libpthreadw32.a is
-	removed for "clean" target.
-	* Makefile: Add mutex4 test.
-
-	* exception3.c: Remove SEH code; automatically pass the test
-	under SEH (which is an N/A environment).
-
-	* mutex4.c: New test.
-
-	* eyal1.c (do_work_unit): Add a dummy "if" to force the
-	optimiser to retain code; reduce thread work loads.
-
-	* condvar8.c (main): Add an additional "assert" for debugging;
-	increase pthread_cond_signal timeout.
-
-2000-12-28  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* eyal1.c: Increase thread work loads.
-	* exception2.c: New test.
-	* exception3.c: New test.
-	* Makefile: Add new tests exception2.c and exception3.c.
-	* GNUmakefile: Likewise.
-
-2000-12-11  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* cleanup3.c: Remove unused variable.
-	* cleanup2.c: Likewise.
-	* exception1.c: Throw an exception rather than use
-	a deliberate zero divide so that catch(...) will
-	handle it under Mingw32. Mingw32 now builds the
-	library correctly to pass all tests - see Thomas
-	Pfaff's detailed instructions re needed changes
-	to Mingw32 in the Pthreads-Win32 FAQ.
-
-2000-09-08  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* cancel5.c: New; tests calling pthread_cancel()
-	from the main thread without first creating a
-	POSIX thread struct for the non-POSIX main thread
-	- this forces pthread_cancel() to create one via
-	pthread_self().
-	* Makefile (cancel5): Add new test.
-	* GNUmakefile (cancel5): Likewise.
-
-2000-08-17  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* create2.c: New; Test that pthread_t contains
-	the W32 HANDLE before it calls the thread routine
-	proper.
-
-2000-08-13  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* condvar3.c: Minor change to eliminate compiler
-	warning.
-
-	* condvar4.c: ditto.
-
-	* condvar5.c: ditto.
-
-	* condvar6.c: ditto.
-
-	* condvar7.c: ditto.
-
-	* condvar8.c: ditto.
-
-	* condvar9.c: ditto.
-
-	* exit1.c: Function needed return statement.
-
-	* cleanup1.c: Remove unnecessary printf arg.
-
-	* cleanup2.c: Fix cast.
-
-	* rwlock6.c: Fix casts.
-
-	* exception1.c (PtW32CatchAll): Had the wrong name;
-	fix casts.
-
-	* cancel3.c: Remove unused waitLock variable.
-
-	* GNUmakefile: Change library/dll naming; add new tests;
-	general minor changes.
-
-	* Makefile: Change library/dll naming; add targets for
-	testing each of the two VC++ EH scheme versions;
-	default target now issues help message; compile warnings
-	now interpreted as errors to stop the make; add new
-	tests; restructure to remove prerequisites needed
-	otherwise.
-
-	* README: Updated.
-
-
-2000-08-10  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* eyal1.c (main): Change implicit cast to explicit
-	cast when passing "print_server" function pointer;
-	G++ no longer allows implicit func parameter casts.
-
-	* cleanup1.c: Remove unused "waitLock".
-	(main): Fix implicit parameter cast.
-
-	* cancel2.c (main): Fix implicit parameter cast.
-
-	* cancel4.c (main): Fix implicit parameter cast.
-
-	* cancel3.c (main): Fix implicit parameter cast.
-
-	* GNUmakefile: Renamed from Makefile; Add missing
-	cancel1 and cancel2 test targets.
-
-	* Makefile: Converted for use with MS nmake.
-
-2000-08-06  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* ccl.bat: Add /nologo to remove extraneous output.
-
-	* exception1.c (exceptionedThread): Init 'dummy';
-	put expression into if condition to prevent optimising away;
-	remove unused variable.
-
-	* cancel4.c (mythread): Cast return value to avoid warnings.
-
-	* cancel2.c (mythread): Missing #endif.
-
-	* condvar9.c (mythread): Cast return value to avoid warnings.
-
-	* condvar8.c (mythread): Cast return value to avoid warnings.
-
-	* condvar7.c (mythread): Cast return value to avoid warnings.
-
-	* cleanup3.c (mythread): Cast return value to avoid warnings.
-
-	* cleanup2.c (mythread): Cast return value to avoid warnings.
-
-	* cleanup1.c (mythread): Cast return value to avoid warnings.
-
-	* condvar5.c (mythread): Cast return value to avoid warnings.
-
-	* condvar3.c (mythread): Cast return value to avoid warnings.
-
-	* condvar6.c (mythread): Cast return value to avoid warnings.
-
-	* condvar4.c (mythread): Cast return value to avoid warnings.
-
-2000-08-05  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* cancel2.c: Use PtW32CatchAll macro if defined.
-
-	* exception1.c: Use PtW32CatchAll macro if defined.
-
-2000-08-02  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* tsd1.c: Fix typecasts of &result [g++ is now very fussy].
-	
-	* test.h (assert): Return 0's explicitly to allay
-	g++ errors.
-	
-	* join2.c: Add explicit typecasts.
-	
-	* join1.c: Add explicit typecasts.
-	
-	* join0.c: Add explicit typecasts.
-	
-	* eyal1.c: Add explicit typecasts.
-	
-	* count1.c (main): Add type cast to remove g++ parse warning
-	[gcc-2.95.2 seems to have tightened up on this].
-
-	* Makefile (GLANG): Use c++ explicitly.
-	Remove MSVC sections (was commented out).
-	Add target to generate cpp output.
-
-2000-07-25  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* runtest.bat: modified to work under W98.
-	
-	* runall.bat: Add new tests; modified to work under W98.
-	It was ok under NT.
-
-	* Makefile: Add new tests.
-
-	* exception1.c: New; Test passing exceptions back to the
-	application and retaining library internal exceptions.
-
-	* join0.c: New; Test a single join.
-
-2000-01-06  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* cleanup1.c: New; Test cleanup handler executes (when thread is
-	canceled).
-
-	* cleanup2.c: New; Test cleanup handler executes (when thread is
-	not canceled).
-
-	* cleanup3.c: New; Test cleanup handler does not execute
-	(when thread is not canceled).
-
-2000-01-04  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* cancel4.c: New; Test cancelation does not occur in deferred
-	cancelation threads with no cancelation points.
-
-	* cancel3.c: New; Test asynchronous cancelation.
-
-	* context1.c: New; Test context switching method for async
-	cancelation.
-
-1999-11-23  Ross Johnson  <rpj at special.ise.canberra.edu.au>
-
-	* test.h: Add header includes; include local header versions rather
-	than system versions; rearrange the assert macro defines.
-
-1999-11-07  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* loadfree.c: New. Test loading and freeing the library (DLL).
-
-1999-10-30  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* cancel1.c: New. Test pthread_setcancelstate and
-	pthread_setcanceltype functions.
-	* eyal1.c (waste_time): Change calculation to avoid FP exception
-	on Aplhas
-	- Rich Peters <rpeters at micro-magic.com>
-
-Oct 14 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* condvar7.c: New. Test broadcast after waiting thread is canceled.
-	* condvar8.c: New. Test multiple broadcasts.
-	* condvar9.c: New. Test multiple broadcasts with thread
-	cancelation.
-	
-Sep 16 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* rwlock6.c: New test.
-
-Sep 15 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* rwlock1.c: New test.
-	* rwlock2.c: New test.
-	* rwlock3.c: New test.
-	* rwlock4.c: New test.
-	* rwlock5.c: New test.
-
-Aug 22 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* runall.bat (join2): Add test.
-
-Aug 19 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* join2.c: New test.
-
-Wed Aug 12 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* Makefile (LIBS): Add -L.
-
-Mon May 31 10:25:01 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* Makefile (GLANG): Add GCC language option.
-
-Sat May 29 23:29:04 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* runall.bat (condvar5): Add new test.
-
-	* runall.bat (condvar6): Add new test.
-
-	* Makefile (condvar5) : Add new test.
-	
-	* Makefile (condvar6) : Add new test.
-	
-	* condvar5.c: New test for pthread_cond_broadcast().
-
-	* condvar6.c: New test for pthread_cond_broadcast().
-
-Sun Apr  4 12:04:28 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* tsd1.c (mythread): Change Sleep(0) to sched_yield().
-	(sched.h): Include.
-
-	* condvar3.c (mythread): Remove redundant Sleep().
-
-	* runtest.bat: Re-organised to make more informative.
-
-Fri Mar 19 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* *.bat: redirect unwanted output to nul:
-
-	* runall.bat: new.
-
-	* cancel1.c: new. Not part of suite yet.
-	
-Mon Mar 15 00:17:55 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* mutex1.c: only test mutex init and destroy; add assertions.
-
-	* count1.c: raise number of spawned threads to 60 (appears to
-	be the limit under Win98).
-
-Sun Mar 14 21:31:02 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* test.h (assert): add assertion trace option.
-	Use:
-	"#define ASSERT_TRACE 1" to turn it on,
-	"#define ASSERT_TRACE 0" to turn it off (default).
-
-	* condvar3.c (main): add more assertions.
-
-	* condvar4.c (main): add more assertions.
-
-	* condvar1.c (main): add more assertions.
-
-Fri Mar 12 08:34:15 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* condvar4.c (cvthing): switch the order of the INITIALIZERs.
-
-	* eyal1.c (main): Fix trylock loop; was not waiting for thread to lock
-	the "started" mutex.
-
-Wed Mar 10 10:41:52 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* tryentercs.c: Apply typo patch from bje.
-
-	* tryentercs2.c: Ditto.
-
-Sun Mar  7 10:41:52 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* Makefile (condvar3, condvar4): Add tests.
-
-	* condvar4.c (General): Reduce to simple test case; prerequisite
-	is condvar3.c; add description.
-
-	* condvar3.c (General): Reduce to simple test case; prerequisite
-	is condvar2.c; add description.
-
-	* condvar2.c (General): Reduce to simple test case; prerequisite
-	is condvar1.c; add description.
-
-	* condvar1.c (General): Reduce to simple test case; add
-	description.
-
-	* Template.c (Comments): Add generic test detail.
-
-1999-02-23  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-        * Template.c: Revamp.
-
-        * condvar1.c: Add.
-
-        * condvar2.c: Add.
-
-        * Makefile: Add condvar1 condvar2 tests.
-
-        * exit1.c, exit2.c, exit3.c: Cosmetic changes.
-
-1999-02-23  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-	* Makefile: Some refinement.
-
-	* *.c: More exhaustive checking through assertions; clean up;
-	add some more tests.
-
-	* Makefile: Now actually runs the tests.
-
-	* tests.h: Define our own assert macro. The Mingw32
-	version pops up a dialog but we want to run non-interactively.
-
-	* equal1.c: use assert a little more directly so that it
-	prints the actual call statement.
-
-	* exit1.c: Modify to return 0 on success, 1 on failure.
-
-1999-02-22  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-	* self2.c: Bring up to date.
-
-	* self3.c: Ditto.
-
-1999-02-21  Ben Elliston  <bje at cygnus.com>
-
-	* README: Update.
-
-	* Makefile: New file. Run all tests automatically. Primitive tests
-	are run first; more complex tests are run last.
-
-	* count1.c: New test. Validate the thread count.
-
-	* exit2.c: Perform a simpler test.
-	
-	* exit3.c: New test. Replaces exit2.c, since exit2.c needs to
-	perform simpler checking first.
-
-	* create1.c: Update to use the new testsuite exiting convention.
-	
-	* equal1.c: Likewise.
-
-	* mutex1.c: Likewise.
-
-	* mutex2.c: Likewise.
-
-	* once1.c: Likewise.
-
-	* self2.c: Likewise.
-
-	* self3.c: Likewise.
-
-	* tsd1.c: Likewise.
-
-1999-02-20  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-	* mutex2.c: Test static mutex initialisation.
-
-	* test.h: New. Declares a table mapping error numbers to
-	error names.
-
-1999-01-17  Ross Johnson  <rpj at ise.canberra.edu.au>
-
-	* runtest: New script to build and run a test in the tests directory.
-
-Wed Dec 30 11:22:44 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* tsd1.c: Re-written. See comments at start of file.
-	* Template.c: New. Contains skeleton code and comment template
-	intended to fully document the test.
-
-Fri Oct 16 17:59:49 1998  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* tsd1.c (destroy_key): Add function. Change diagnostics.
-
-Thu Oct 15 17:42:37 1998  Ross Johnson  <rpj at swan.canberra.edu.au>
-
-	* tsd1.c (mythread): Fix some casts and add some message
-	output. Fix inverted conditional.
-
-Mon Oct 12 02:12:29 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
-
-	* tsd1.c: New. Test TSD using 1 key and 2 threads.
-
-1998-09-13  Ben Elliston  <bje at cygnus.com>
-
-	* eyal1.c: New file; contributed by Eyal Lebedinsky
-	<eyal at eyal.emu.id.au>.
-
-1998-09-12  Ben Elliston  <bje at cygnus.com>
-
-	* exit2.c (func): Return a value.
-	(main): Call the right thread entry function.
-
-1998-07-22  Ben Elliston  <bje at cygnus.com>
-
-	* exit2.c (main): Fix size of pthread_t array.
-
-1998-07-10  Ben Elliston  <bje at cygnus.com>
-
-	* exit2.c: New file; test pthread_exit() harder.
-
-	* exit1.c: New file; test pthread_exit().
diff --git a/deps/w32-pthreads/tests/Debug.dsp b/deps/w32-pthreads/tests/Debug.dsp
deleted file mode 100644
index 191b978..0000000
--- a/deps/w32-pthreads/tests/Debug.dsp
+++ /dev/null
@@ -1,93 +0,0 @@
-# Microsoft Developer Studio Project File - Name="Debug" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=Debug - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "Debug.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "Debug.mak" CFG="Debug - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "Debug - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "Debug - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "Debug - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0xc09 /d "NDEBUG"
-# ADD RSC /l 0xc09 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "Debug - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /WX /Gm /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "CLEANUP_C" /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0xc09 /d "_DEBUG"
-# ADD RSC /l 0xc09 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib pthreadVC2d.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:".."
-
-!ENDIF 
-
-# Begin Target
-
-# Name "Debug - Win32 Release"
-# Name "Debug - Win32 Debug"
-# Begin Source File
-
-SOURCE=.\Debug.txt
-# End Source File
-# Begin Source File
-
-SOURCE=.\semaphore1.c
-# End Source File
-# End Target
-# End Project
diff --git a/deps/w32-pthreads/tests/Debug.dsw b/deps/w32-pthreads/tests/Debug.dsw
deleted file mode 100644
index 5fd6af3..0000000
--- a/deps/w32-pthreads/tests/Debug.dsw
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "Debug"=.\Debug.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/deps/w32-pthreads/tests/Debug.plg b/deps/w32-pthreads/tests/Debug.plg
deleted file mode 100644
index 22ce672..0000000
--- a/deps/w32-pthreads/tests/Debug.plg
+++ /dev/null
@@ -1,32 +0,0 @@
-<html>
-<body>
-<pre>
-<h1>Build Log</h1>
-<h3>
---------------------Configuration: Debug - Win32 Debug--------------------
-</h3>
-<h3>Command Lines</h3>
-Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP9.tmp" with contents
-[
-/nologo /MDd /W3 /WX /Gm /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "CLEANUP_C" /FR"Debug/" /Fp"Debug/Debug.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 
-"E:\PTHREADS\pthreads.2\tests\semaphore1.c"
-]
-Creating command line "cl.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP9.tmp" 
-Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSPA.tmp" with contents
-[
-kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib pthreadVC2d.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/Debug.pdb" /debug /machine:I386 /out:"Debug/Debug.exe" /pdbtype:sept /libpath:".." 
-.\Debug\semaphore1.obj
-]
-Creating command line "link.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSPA.tmp"
-<h3>Output Window</h3>
-Compiling...
-semaphore1.c
-Linking...
-
-
-
-<h3>Results</h3>
-Debug.exe - 0 error(s), 0 warning(s)
-</pre>
-</body>
-</html>
diff --git a/deps/w32-pthreads/tests/Debug.txt b/deps/w32-pthreads/tests/Debug.txt
deleted file mode 100644
index 5323874..0000000
--- a/deps/w32-pthreads/tests/Debug.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This project is used to debug individual test case programs.
-
-To build and debug a test case:
-- add the .c file to this project;
-- remove any .c files from other test cases from this project.
-- build and debug as usual.
\ No newline at end of file
diff --git a/deps/w32-pthreads/tests/GNUmakefile b/deps/w32-pthreads/tests/GNUmakefile
deleted file mode 100644
index f6bfd31..0000000
--- a/deps/w32-pthreads/tests/GNUmakefile
+++ /dev/null
@@ -1,447 +0,0 @@
-# Makefile for the pthreads test suite.
-# If all of the .pass files can be created, the test suite has passed.
-#
-# --------------------------------------------------------------------------
-#
-#      Pthreads-win32 - POSIX Threads Library for Win32
-#      Copyright(C) 1998 John E. Bossom
-#      Copyright(C) 1999,2005 Pthreads-win32 contributors
-# 
-#      Contact Email: rpj at callisto.canberra.edu.au
-# 
-#      The current list of contributors is contained
-#      in the file CONTRIBUTORS included with the source
-#      code distribution. The list can also be seen at the
-#      following World Wide Web location:
-#      http://sources.redhat.com/pthreads-win32/contributors.html
-# 
-#      This library is free software; you can redistribute it and/or
-#      modify it under the terms of the GNU Lesser General Public
-#      License as published by the Free Software Foundation; either
-#      version 2 of the License, or (at your option) any later version.
-# 
-#      This library is distributed in the hope that it will be useful,
-#      but WITHOUT ANY WARRANTY; without even the implied warranty of
-#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#      Lesser General Public License for more details.
-# 
-#      You should have received a copy of the GNU Lesser General Public
-#      License along with this library in the file COPYING.LIB;
-#      if not, write to the Free Software Foundation, Inc.,
-#      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-#
-
-DLL_VER	= 2
-
-CP	= cp -f
-MV	= mv -f
-RM	= rm -f
-CAT	= cat
-MKDIR	= mkdir
-TOUCH	= echo Passed >
-ECHO	= @echo
-MAKE	= make -k
-
-# For cross compiling use e.g.
-# # make CROSS=i386-mingw32msvc- clean GC
-CROSS   =
-
-# For cross testing use e.g.
-# # make RUN=wine CROSS=i386-mingw32msvc- clean GC
-RUN     =
-
-AR      = $(CROSS)ar
-DLLTOOL = $(CROSS)dlltool
-CC      = $(CROSS)gcc
-CXX     = $(CROSS)g++
-RANLIB  = $(CROSS)ranlib
-
-#
-# Mingw32
-#
-XXCFLAGS	= 
-XXLIBS	= -lws2_32 -lgomp
-OPT	= -O3
-DOPT	= -g -O0
-#CFLAGS	= -O3 -UNDEBUG -Wall $(XXCFLAGS)
-CFLAGS	= ${OPT} -UNDEBUG -Wall $(XXCFLAGS)
-BUILD_DIR	= ..
-INCLUDES	= -I.
-
-.INTERMEDIATE: %.exe %.pass
-.SECONDARY: %.exe %.pass
-.PRECIOUS: %.exe %.pass
-
-TEST	= GC
-
-# Default lib version
-GCX	= $(TEST)$(DLL_VER)
-
-# Files we need to run the tests
-# - paths are relative to pthreads build dir.
-HDR	= pthread.h semaphore.h sched.h
-LIB	= libpthread$(GCX).a
-DLL	= pthread$(GCX).dll
-# The next path is relative to $BUILD_DIR
-QAPC	=  # ../QueueUserAPCEx/User/quserex.dll
-
-COPYFILES	= $(HDR) $(LIB) $(DLL) $(QAPC)
-
-# If a test case returns a non-zero exit code to the shell, make will
-# stop.
-
-TESTS	= \
-	  sizes loadfree \
-	  self1 mutex5 mutex1 mutex1e mutex1n mutex1r \
-	  semaphore1 semaphore2 semaphore3 \
-	  condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \
-	  create1 create2 create3 reuse1 reuse2 equal1 \
-	  sequence1 kill1 valid1 valid2 \
-	  exit2 exit3 exit4 exit5 \
-	  join0 join1 detach1 join2 join3 \
-	  mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \
-	  mutex4 mutex6 mutex6n mutex6e mutex6r \
-	  mutex6s mutex6es mutex6rs \
-	  mutex7 mutex7n mutex7e mutex7r mutex8 mutex8n mutex8e mutex8r \
-	  robust1 robust2 robust3 robust4 robust5 \
-	  count1 \
-	  once1 once2 once3 once4 self2 \
-	  cancel1 cancel2 \
-	  semaphore4 semaphore4t semaphore5 \
-	  barrier1 barrier2 barrier3 barrier4 barrier5 barrier6 \
-	  tsd1 tsd2 openmp1 delay1 delay2 eyal1 \
-	  condvar3 condvar3_1 condvar3_2 condvar3_3 \
-	  condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \
-	  errno1 \
-	  rwlock1 rwlock2 rwlock3 rwlock4 rwlock5 rwlock6 rwlock7 rwlock8 \
-	  rwlock2_t rwlock3_t rwlock4_t rwlock5_t rwlock6_t rwlock6_t2 \
-	  context1 cancel3 cancel4 cancel5 cancel6a cancel6d \
-	  cancel7 cancel8 \
-	  cleanup0 cleanup1 cleanup2 cleanup3 \
-	  priority1 priority2 inherit1 \
-	  spin1 spin2 spin3 spin4 \
-	  exception1 exception2 exception3 \
-	  cancel9 stress1
-
-STRESSTESTS = \
-	stress1
-
-BENCHTESTS = \
-	benchtest1 benchtest2 benchtest3 benchtest4 benchtest5
-
-STATICTESTS = \
-	  sizes \
-	  self1 mutex5 mutex1 mutex1e mutex1n mutex1r \
-	  semaphore1 semaphore2 semaphore3 \
-	  condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \
-	  create1 create2 create3 reuse1 reuse2 equal1 \
-	  sequence1 kill1 valid1 valid2 \
-	  exit2 exit3 exit4 exit5 \
-	  join0 join1 detach1 join2 join3 \
-	  mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \
-	  mutex4 mutex6 mutex6n mutex6e mutex6r \
-	  mutex6s mutex6es mutex6rs \
-	  mutex7 mutex7n mutex7e mutex7r mutex8 mutex8n mutex8e mutex8r \
-	  robust1 robust2 robust3 robust4 robust5 \
-	  count1 \
-	  once1 once2 once3 once4 self2 \
-	  cancel1 cancel2 \
-	  semaphore4 semaphore4t semaphore5 \
-	  barrier1 barrier2 barrier3 barrier4 barrier5 barrier6 \
-	  tsd1 tsd2 delay1 delay2 eyal1 \
-	  condvar3 condvar3_1 condvar3_2 condvar3_3 \
-	  condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \
-	  errno1 \
-	  rwlock1 rwlock2 rwlock3 rwlock4 rwlock5 rwlock6 rwlock7 rwlock8 \
-	  rwlock2_t rwlock3_t rwlock4_t rwlock5_t rwlock6_t rwlock6_t2 \
-	  context1 cancel3 cancel4 cancel5 cancel6a cancel6d \
-	  cancel7 cancel8 \
-	  cleanup0 cleanup1 cleanup2 cleanup3 \
-	  priority1 priority2 inherit1 \
-	  spin1 spin2 spin3 spin4 \
-	  exception1 exception2 exception3 \
-	  cancel9 stress1
-
-ALLTESTS = $(TESTS) $(BENCHTESTS)
-
-ASM		= $(ALLTESTS:%=%.s)
-PASSES		= $(TESTS:%=%.pass)
-BENCHRESULTS	= $(BENCHTESTS:%=%.bench)
-STRESSRESULTS	= $(STRESSTESTS:%=%.pass)
-STATICRESULTS	= $(STATICTESTS:%=%.pass)
-
-help:
-	@ $(ECHO) "Run one of the following command lines:"
-	@ $(ECHO) "make clean GC    (to test using GC dll with C (no EH) applications)"
-	@ $(ECHO) "make clean GCX   (to test using GC dll with C++ (EH) applications)"
-	@ $(ECHO) "make clean GCE   (to test using GCE dll with C++ (EH) applications)"
-	@ $(ECHO) "make clean GC-bench	  (to benchtest using GNU C dll with C cleanup code)"
-	@ $(ECHO) "make clean GCE-bench   (to benchtest using GNU C dll with C++ exception handling)"
-	@ $(ECHO) "make clean GC-stress	  (to stresstest using GNU C dll with C cleanup code)"
-	@ $(ECHO) "make clean GCE-stress   (to stresstest using GNU C dll with C++ exception handling)"
-	@ $(ECHO) "make clean GC-static   (to test using GC static lib with C (no EH) applications)"
-	@ $(ECHO) "make clean GC-debug    (to test using GC dll with C (no EH) applications)"
-
-all:
-	@ $(MAKE) clean GC
-	@ $(MAKE) clean GCX
-	@ $(MAKE) clean GCE
-
-GC:
-	$(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-fopenmp -D__CLEANUP_C" all-pass
-
-GC-asm:
-	$(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-fopenmp -D__CLEANUP_C" all-asm
-
-GCE:
-	$(MAKE) TEST=GCE CC=$(CXX) XXCFLAGS="-fopenmp -mthreads -D__CLEANUP_CXX" all-pass
-
-GCX:
-	$(MAKE) TEST=GC CC=$(CXX) XXCFLAGS="-fopenmp -mthreads -D__CLEANUP_C" all-pass
-
-GC-bench:
-	$(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-D__CLEANUP_C" XXLIBS="benchlib.o" all-bench
-
-GCE-bench:
-	$(MAKE) TEST=GCE  CC=$(CXX) XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="benchlib." all-bench
-
-GC-debug:
-	$(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-fopenmp -D__CLEANUP_C" OPT="${DOPT}" DLL_VER="$(DLL_VER)d" all-pass
-
-GCE-debug:
-	$(MAKE) TEST=GCE CC=$(CXX) XXCFLAGS="-fopenmp -D__CLEANUP_CXX" OPT="${DOPT}" DLL_VER="$(DLL_VER)d" all-pass
-
-GC-bench-debug:
-	$(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-D__CLEANUP_C" XXLIBS="benchlib.o" OPT="${OPT}" DLL_VER="$(DLL_VER)d" all-bench
-
-GC-static:
-	$(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-D__CLEANUP_C -DPTW32_STATIC_LIB" XXLIBS="-lws2_32" DLL="" all-static
-
-GC-stress:
-	$(ECHO) Stress tests can take a long time since they are trying to
-	$(ECHO) expose weaknesses that may be intermittant or statistically rare.
-	$(ECHO) A pass does not prove correctness, but may give greater confidence.
-	$(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-D__CLEANUP_C" XXLIBS="" all-stress
-
-GCE-stress:
-	$(MAKE) TEST=GCE  CC=$(CXX) XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="" all-stress
-
-all-asm: $(ASM)
-	@ $(ECHO) ALL TESTS PASSED! Congratulations!
-
-all-pass: $(PASSES)
-	@ $(ECHO) ALL TESTS PASSED! Congratulations!
-
-all-bench: $(BENCHRESULTS)
-	@ $(ECHO) BENCH TESTS COMPLETED.
-
-all-stress: $(STRESSRESULTS)
-	@ $(ECHO) STRESS TESTS COMPLETED.
-
-all-static: $(STATICRESULTS)
-	@ $(ECHO) ALL STATIC TESTS PASSED! Congratulations!
-
-benchtest1.bench:
-benchtest2.bench:
-benchtest3.bench:
-benchtest4.bench:
-benchtest5.bench:
-
-barrier1.pass: semaphore4.pass
-barrier2.pass: barrier1.pass
-barrier3.pass: barrier2.pass
-barrier4.pass: barrier3.pass
-barrier5.pass: barrier4.pass
-barrier6.pass: barrier5.pass
-cancel1.pass: create1.pass
-cancel2.pass: cancel1.pass
-cancel3.pass: context1.pass
-cancel4.pass: cancel3.pass
-cancel5.pass: cancel3.pass
-cancel6a.pass: cancel3.pass
-cancel6d.pass: cancel3.pass
-cancel7.pass: kill1.pass
-cancel8.pass: cancel7.pass
-cancel9.pass: cancel8.pass
-cleanup0.pass: cancel5.pass
-cleanup1.pass: cleanup0.pass
-cleanup2.pass: cleanup1.pass
-cleanup3.pass: cleanup2.pass
-condvar1.pass:
-condvar1_1.pass: condvar1.pass
-condvar1_2.pass: join2.pass
-condvar2.pass: condvar1.pass
-condvar2_1.pass: condvar2.pass join2.pass
-condvar3.pass: create1.pass condvar2.pass
-condvar3_1.pass: condvar3.pass join2.pass
-condvar3_2.pass: condvar3_1.pass
-condvar3_3.pass: condvar3_2.pass
-condvar4.pass: create1.pass
-condvar5.pass: condvar4.pass
-condvar6.pass: condvar5.pass
-condvar7.pass: condvar6.pass cleanup1.pass
-condvar8.pass: condvar7.pass
-condvar9.pass: condvar8.pass
-context1.pass: cancel1.pass
-count1.pass: join1.pass
-create1.pass: mutex2.pass
-create2.pass: create1.pass
-create3.pass: create2.pass
-delay1.pass:
-delay2.pass: delay1.pass
-detach1.pass: join0.pass
-equal1.pass: create1.pass
-errno1.pass: mutex3.pass
-exception1.pass: cancel4.pass
-exception2.pass: exception1.pass
-exception3.pass: exception2.pass
-exit1.pass:
-exit2.pass: create1.pass
-exit3.pass: create1.pass
-exit4.pass:
-exit5.pass: exit4.pass kill1.pass
-eyal1.pass: tsd1.pass
-inherit1.pass: join1.pass priority1.pass
-join0.pass: create1.pass
-join1.pass: create1.pass
-join2.pass: create1.pass
-join3.pass: join2.pass
-kill1.pass:
-loadfree.pass: pthread.dll
-mutex1.pass: self1.pass
-mutex1n.pass: mutex1.pass
-mutex1e.pass: mutex1.pass
-mutex1r.pass: mutex1.pass
-mutex2.pass: mutex1.pass
-mutex2r.pass: mutex2.pass
-mutex2e.pass: mutex2.pass
-mutex3.pass: create1.pass
-mutex3r.pass: mutex3.pass
-mutex3e.pass: mutex3.pass
-mutex4.pass: mutex3.pass
-mutex5.pass:
-mutex6.pass: mutex4.pass
-mutex6n.pass: mutex4.pass
-mutex6e.pass: mutex4.pass
-mutex6r.pass: mutex4.pass
-mutex6s.pass: mutex6.pass
-mutex6rs.pass: mutex6r.pass
-mutex6es.pass: mutex6e.pass
-mutex7.pass: mutex6.pass
-mutex7n.pass: mutex6n.pass
-mutex7e.pass: mutex6e.pass
-mutex7r.pass: mutex6r.pass
-mutex8.pass: mutex7.pass
-mutex8n.pass: mutex7n.pass
-mutex8e.pass: mutex7e.pass
-mutex8r.pass: mutex7r.pass
-once1.pass: create1.pass
-once2.pass: once1.pass
-once3.pass: once2.pass
-once4.pass: once3.pass
-openmp1.pass: tsd2.pass
-priority1.pass: join1.pass
-priority2.pass: priority1.pass barrier3.pass
-reuse1.pass: create3.pass
-reuse2.pass: reuse1.pass
-robust1.pass: mutex8r.pass
-robust2.pass: mutex8r.pass
-robust3.pass: robust2.pass
-robust4.pass: robust3.pass
-robust5.pass: robust4.pass
-rwlock1.pass: condvar6.pass
-rwlock2.pass: rwlock1.pass
-rwlock3.pass: rwlock2.pass join2.pass
-rwlock4.pass: rwlock3.pass
-rwlock5.pass: rwlock4.pass
-rwlock6.pass: rwlock5.pass
-rwlock7.pass: rwlock6.pass
-rwlock8.pass: rwlock7.pass
-rwlock2_t.pass: rwlock2.pass
-rwlock3_t.pass: rwlock2_t.pass
-rwlock4_t.pass: rwlock3_t.pass
-rwlock5_t.pass: rwlock4_t.pass
-rwlock6_t.pass: rwlock5_t.pass
-rwlock6_t2.pass: rwlock6_t.pass
-self1.pass:
-self2.pass: create1.pass
-semaphore1.pass:
-semaphore2.pass:
-semaphore3.pass: semaphore2.pass
-semaphore4.pass: semaphore3.pass cancel1.pass
-semaphore4t.pass: semaphore4.pass
-semaphore5.pass: semaphore4.pass
-sequence1.pass: reuse2.pass
-sizes.pass:
-spin1.pass:
-spin2.pass: spin1.pass
-spin3.pass: spin2.pass
-spin4.pass: spin3.pass
-stress1.pass:
-tsd1.pass: barrier5.pass join1.pass
-tsd2.pass: tsd1.pass
-valid1.pass: join1.pass
-valid2.pass: valid1.pass
-
-sizes.pass: sizes.exe
-	@ $(ECHO) Running $*
-	@ $(RUN) ./$< > SIZES.$(TEST)
-	@ $(CAT) SIZES.$(TEST)
-	@ $(ECHO) Passed
-	@ $(TOUCH) $@
-
-%.pass: %.exe
-	@ $(ECHO) Running $*
-	@ $(RUN) ./$*
-	@ $(ECHO) Passed
-	@ $(TOUCH) $@
-
-%.bench: $(LIB) $(DLL) $(HDR) $(QAPC) $(XXLIBS) %.exe
-	@ $(ECHO) Running $*
-	@ $(RUN) ./$*
-	@ $(ECHO) Done
-	@ $(TOUCH) $@
-
-%.exe: %.c $(LIB) $(DLL) $(HDR) $(QAPC)
-	@ $(ECHO) Compiling $@
-	@ $(ECHO) $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS)
-	@ $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS)
-
-%.pre: %.c $(HDR)
-	@ $(CC) -E $(CFLAGS) -o $@ $< $(INCLUDES)
-
-%.s: %.c $(HDR)
-	@ $(ECHO) Compiling $@
-	@ $(CC) -S $(CFLAGS) -o $@ $< $(INCLUDES)
-
-$(COPYFILES):
-	@ $(ECHO) Copying $(BUILD_DIR)/$@
-	@ $(CP) $(BUILD_DIR)/$@ .
-
-benchlib.o: benchlib.c
-	@ $(ECHO) Compiling $@
-	@ $(ECHO) $(CC) -c $(CFLAGS) $< $(INCLUDES)
-	@ $(CC) -c $(CFLAGS) $< $(INCLUDES)
-
-pthread.dll: $(DLL)
-	@ $(CP) $(DLL) $@
-
-clean:
-	- $(RM) *.dll
-	- $(RM) *.lib
-	- $(RM) pthread.h
-	- $(RM) semaphore.h
-	- $(RM) sched.h
-	- $(RM) *.a
-	- $(RM) *.e
-	- $(RM) *.i
-	- $(RM) *.o
-	- $(RM) *.s
-	- $(RM) *.so
-	- $(RM) *.obj
-	- $(RM) *.pdb
-	- $(RM) *.exe
-	- $(RM) *.pass
-	- $(RM) *.bench
-	- $(RM) *.static
-	- $(RM) *.log
diff --git a/deps/w32-pthreads/tests/Makefile b/deps/w32-pthreads/tests/Makefile
deleted file mode 100644
index 55991f1..0000000
--- a/deps/w32-pthreads/tests/Makefile
+++ /dev/null
@@ -1,450 +0,0 @@
-# Makefile for the pthreads test suite.
-# If all of the .pass files can be created, the test suite has passed.
-#
-# --------------------------------------------------------------------------
-#
-#      Pthreads-win32 - POSIX Threads Library for Win32
-#      Copyright(C) 1998 John E. Bossom
-#      Copyright(C) 1999,2005 Pthreads-win32 contributors
-# 
-#      Contact Email: rpj at callisto.canberra.edu.au
-# 
-#      The current list of contributors is contained
-#      in the file CONTRIBUTORS included with the source
-#      code distribution. The list can also be seen at the
-#      following World Wide Web location:
-#      http://sources.redhat.com/pthreads-win32/contributors.html
-# 
-#      This library is free software; you can redistribute it and/or
-#      modify it under the terms of the GNU Lesser General Public
-#      License as published by the Free Software Foundation; either
-#      version 2 of the License, or (at your option) any later version.
-# 
-#      This library is distributed in the hope that it will be useful,
-#      but WITHOUT ANY WARRANTY; without even the implied warranty of
-#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#      Lesser General Public License for more details.
-# 
-#      You should have received a copy of the GNU Lesser General Public
-#      License along with this library in the file COPYING.LIB;
-#      if not, write to the Free Software Foundation, Inc.,
-#      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-#
-
-DLL_VER	= 2
-
-CP	= copy
-RM	= erase
-CAT	= type
-MKDIR	= mkdir
-TOUCH	= echo Passed >
-ECHO	= echo
-
-# The next path is relative to $BUILD_DIR
-QAPC	= # ..\QueueUserAPCEx\User\quserex.dll
-
-CPHDR	= pthread.h semaphore.h sched.h
-
-OPTIM	= /O2 /Ob0
-
-XXLIBS	= ws2_32.lib
-
-# C++ Exceptions
-VCEFLAGS	= /EHsc /TP /DPtW32NoCatchWarn /D__CLEANUP_CXX
-VCELIB	= pthreadVCE$(DLL_VER).lib
-VCEDLL	= pthreadVCE$(DLL_VER).dll
-# Structured Exceptions
-VSEFLAGS	= /D__CLEANUP_SEH
-VSELIB	= pthreadVSE$(DLL_VER).lib
-VSEDLL	= pthreadVSE$(DLL_VER).dll
-# C cleanup code
-VCFLAGS	= /D__CLEANUP_C
-VCLIB	= pthreadVC$(DLL_VER).lib
-VCDLL	= pthreadVC$(DLL_VER).dll
-# C++ Exceptions in application - using VC version of pthreads dll
-VCXFLAGS	= /EHsc /TP /D__CLEANUP_C
-
-# Defaults
-CPLIB	= $(VCLIB)
-CPDLL	= $(VCDLL)
-
-CFLAGS= $(OPTIM) /W3 /MD /nologo /Z7
-LFLAGS= /INCREMENTAL:NO
-INCLUDES=-I.
-BUILD_DIR=..
-
-COPYFILES	= $(CPHDR) $(CPLIB) $(CPDLL) $(QAPC)
-
-TEST		=
-EHFLAGS	=
-
-# If a test case returns a non-zero exit code to the shell, make will
-# stop.
-
-PASSES = sizes.pass $(REGULAR_PASSES)
-
-REGULAR_PASSES = loadfree.pass \
-	  self1.pass  mutex5.pass  \
-	  mutex1.pass  mutex1n.pass  mutex1e.pass  mutex1r.pass  \
-	  semaphore1.pass  semaphore2.pass  semaphore3.pass  \
-	  mutex2.pass  mutex3.pass  \
-	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  \
-	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  \
-	  exit1.pass  create1.pass  create2.pass create3.pass reuse1.pass  reuse2.pass  equal1.pass  \
-	  sequence1.pass  kill1.pass  valid1.pass  valid2.pass  \
-	  exit2.pass  exit3.pass  exit4.pass  exit5.pass  \
-	  join0.pass  join1.pass  detach1.pass  join2.pass join3.pass  \
-	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  \
-	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  \
-	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  \
-	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  \
-	  robust1.pass  robust2.pass  robust3.pass  robust4.pass  robust5.pass  \
-	  count1.pass  \
-	  once1.pass  once2.pass  once3.pass  once4.pass  \
-	  self2.pass  \
-	  cancel1.pass  cancel2.pass  \
-	  semaphore4.pass  semaphore4t.pass  semaphore5.pass  \
-	  barrier1.pass  barrier2.pass  barrier3.pass  barrier4.pass  barrier5.pass  barrier6.pass  \
-	  tsd1.pass  tsd2.pass  delay1.pass  delay2.pass  eyal1.pass  \
-	  condvar3.pass  condvar3_1.pass  condvar3_2.pass  condvar3_3.pass  \
-	  condvar4.pass  condvar5.pass  condvar6.pass  \
-	  condvar7.pass  condvar8.pass  condvar9.pass  \
-	  errno1.pass  \
-	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  \
-	  rwlock5.pass  rwlock6.pass  rwlock7.pass  rwlock8.pass  \
-	  rwlock2_t.pass  rwlock3_t.pass  rwlock4_t.pass  rwlock5_t.pass  rwlock6_t.pass  rwlock6_t2.pass  \
-	  context1.pass  \
-	  cancel3.pass  cancel4.pass  cancel5.pass  cancel6a.pass  cancel6d.pass  \
-	  cancel7.pass  cancel8.pass  \
-	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  \
-	  priority1.pass priority2.pass inherit1.pass  \
-	  spin1.pass  spin2.pass  spin3.pass  spin4.pass  \
-	  exception1.pass  exception2.pass  exception3.pass  \
-	  cancel9.pass  stress1.pass
-
-BENCHRESULTS = \
-	  benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench
-
-STRESSRESULTS = \
-	  stress1.stress
-
-STATICRESULTS = \
-	  sizes.pass  \
-	  self1.pass  mutex5.pass  \
-	  mutex1.pass  mutex1n.pass  mutex1e.pass  mutex1r.pass  \
-	  semaphore1.pass  semaphore2.pass  semaphore3.pass  \
-	  mutex2.pass  mutex3.pass  \
-	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  \
-	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  \
-	  exit1.pass  create1.pass  create2.pass  create3.pass  reuse1.pass  reuse2.pass  equal1.pass  \
-	  sequence1.pass  kill1.pass  valid1.pass  valid2.pass  \
-	  exit2.pass  exit3.pass  exit4.pass  exit5.pass  \
-	  join0.pass  join1.pass  detach1.pass  join2.pass join3.pass  \
-	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  \
-	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  \
-	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  \
-	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  \
-	  robust1.pass  robust2.pass  robust3.pass  robust4.pass  robust5.pass  \
-	  count1.pass  \
-	  once1.pass  once2.pass  once3.pass  once4.pass  \
-	  self2.pass  \
-	  cancel1.pass  cancel2.pass  \
-	  semaphore4.pass  semaphore4t.pass  semaphore5.pass  \
-	  barrier1.pass  barrier2.pass  barrier3.pass  barrier4.pass  barrier5.pass  barrier6.pass  \
-	  tsd1.pass  tsd2.pass  delay1.pass  delay2.pass  eyal1.pass  \
-	  condvar3.pass  condvar3_1.pass  condvar3_2.pass  condvar3_3.pass  \
-	  condvar4.pass  condvar5.pass  condvar6.pass  \
-	  condvar7.pass  condvar8.pass  condvar9.pass  \
-	  errno1.pass  \
-	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  \
-	  rwlock5.pass  rwlock6.pass  rwlock7.pass  rwlock8.pass  \
-	  rwlock2_t.pass  rwlock3_t.pass  rwlock4_t.pass  rwlock5_t.pass  rwlock6_t.pass  rwlock6_t2.pass  \
-	  context1.pass  \
-	  cancel3.pass  cancel4.pass  cancel5.pass  cancel6a.pass  cancel6d.pass  \
-	  cancel7.pass  cancel8.pass  \
-	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  \
-	  priority1.pass priority2.pass inherit1.pass  \
-	  spin1.pass  spin2.pass  spin3.pass  spin4.pass  \
-	  exception1.pass  exception2.pass  exception3.pass  \
-	  cancel9.pass  stress1.pass
-
-help:
-	@ $(ECHO) Run one of the following command lines:
-	@ $(ECHO) nmake clean VC          (to test using VC dll with VC (no EH) apps)
-	@ $(ECHO) nmake clean VC-bench    (to benchtest using VC dll with C bench apps)
-	@ $(ECHO) nmake clean VC-stress   (to stresstest using VC dll with C stress apps)
-	@ $(ECHO) nmake clean VC-static   (to test using VC static lib with VC (no EH) apps)
-	@ $(ECHO) nmake clean VCX         (to test using VC dll with VC++ (EH) applications)
-	@ $(ECHO) nmake clean VCX-bench   (to benchtest using VC dll with C++ bench apps)
-	@ $(ECHO) nmake clean VCX-stress  (to stresstest using VC dll with C++ stress apps)
-	@ $(ECHO) nmake clean VCE         (to test using the VCE dll with VC++ EH applications)
-	@ $(ECHO) nmake clean VCE-bench   (to benchtest using VCE dll with C++ bench apps)
-	@ $(ECHO) nmake clean VCE-stress  (to stresstest using VCE dll with C++ stress apps)
-	@ $(ECHO) nmake clean VSE         (to test using VSE dll with VC (SEH) apps)
-	@ $(ECHO) nmake clean VSE-bench   (to benchtest using VSE dll with SEH bench apps)
-	@ $(ECHO) nmake clean VSE-stress  (to stresstest using VSE dll with SEH stress apps)
-
-all:
-	@ $(MAKE) /E clean VC
-	@ $(MAKE) /E clean VCX
-	@ $(MAKE) /E clean VCE
-	@ $(MAKE) /E clean VSE
-	@ $(MAKE) /E clean VC-bench
-	@ $(MAKE) /E clean VC-stress
-
-# This allows an individual test application to be made using the default lib.
-# e.g. nmake clean test cancel3.exe
-test: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC)
-
-tests: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) $(PASSES)
-	@ $(ECHO) ALL TESTS PASSED! Congratulations!
-
-benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(XXLIBS) $(BENCHRESULTS)
-	@ $(ECHO) ALL BENCH TESTS DONE.
-
-stresstests: $(CPLIB) $(CPDLL) $(CPHDR) $(STRESSRESULTS)
-	@ $(ECHO) ALL STRESS TESTS DONE.
-
-statictests: $(CPLIB) $(CPDLL) $(CPHDR) $(STATICRESULTS)
-	@ $(ECHO) ALL STATIC TESTS DONE.
-
-sizes.pass: sizes.exe
-	@ $(ECHO) ... Running $(TEST)$(DLL_VER) test: $*.exe
-	@ .\$*.exe > SIZES.$(TEST)
-	@ $(CAT) SIZES.$(TEST)
-	@ $(ECHO) ...... Passed
-	@ $(TOUCH) $*.pass
-
-$(REGULAR_PASSES): $*.exe
-	@ $(ECHO) ... Running $(TEST) test: $*.exe
-	@ .\$*.exe
-	@ $(ECHO) ...... Passed
-	@ $(TOUCH) $*.pass
-
-$(BENCHRESULTS): $*.exe
-	@ $(ECHO) ... Running $(TEST) benchtest: $*.exe
-	@ .\$*.exe
-	@ $(ECHO) ...... Done
-	@ $(TOUCH) $*.bench
-
-$(STRESSRESULTS): $*.exe
-	@ $(ECHO) ... Running $(TEST) stresstest: $*.exe
-	@ .\$*.exe
-	@ $(ECHO) ...... Done
-	@ $(TOUCH) $*.pass
-
-VC:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" tests
-
-VCE:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" tests
-
-VSE:	
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" tests
-
-VCX:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" tests
-
-VC-bench:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" XXLIBS="benchlib.o" benchtests
-
-VCE-bench:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" XXLIBS="benchlib.o" benchtests
-
-VSE-bench:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" XXLIBS="benchlib.o" benchtests
-
-VCX-bench:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" XXLIBS="benchlib.o" benchtests
-
-VC-stress:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" stresstests
-
-VCE-stress:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" stresstests
-
-VSE-stress:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" stresstests
-
-VCX-stress:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" stresstests
-
-VC-static:
-	@ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="" EHFLAGS="$(VCFLAGS) /DPTW32_STATIC_LIB" statictests
-
-.c.exe:
-	@ $(ECHO) $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< /Fe$@ /link $(LFLAGS) $(CPLIB) $(XXLIBS)
-	@ $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< /Fe$@ /link $(LFLAGS) $(CPLIB) $(XXLIBS)
-
-.c.o:
-	@ $(ECHO) $(CC) $(EHFLAGS) /c $(CFLAGS) $(INCLUDES) $< /Fo$@
-	@ $(CC) $(EHFLAGS) $(CFLAGS) /c $(INCLUDES) $< /Fo$@
-
-.c.i:
-	@ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $<
-
-$(COPYFILES):
-	@ $(ECHO) Copying $(BUILD_DIR)\$@
-	@ $(CP) $(BUILD_DIR)\$@ .
-
-pthread.dll: $(CPDLL)
-	@ $(CP) $(CPDLL) pthread.dll
-	@ $(CP) $(CPLIB) pthread.lib
-
-clean:
-	- $(RM) *.dll
-	- $(RM) *.lib
-	- $(RM) pthread.h
-	- $(RM) semaphore.h
-	- $(RM) sched.h
-	- $(RM) *.e
-	- $(RM) *.i
-	- $(RM) *.obj
-	- $(RM) *.pdb
-	- $(RM) *.o
-	- $(RM) *.asm
-	- $(RM) *.exe
-	- $(RM) *.pass
-	- $(RM) *.bench
-	- $(RM) *.log
-
-benchtest1.bench:
-benchtest2.bench:
-benchtest3.bench:
-benchtest4.bench:
-benchtest5.bench:
-
-barrier1.pass: semaphore4.pass
-barrier2.pass: barrier1.pass
-barrier3.pass: barrier2.pass
-barrier4.pass: barrier3.pass
-barrier5.pass: barrier4.pass
-barrier6.pass: barrier5.pass
-cancel1.pass: create1.pass
-cancel2.pass: cancel1.pass
-cancel3.pass: context1.pass
-cancel4.pass: cancel3.pass
-cancel5.pass: cancel3.pass
-cancel6a.pass: cancel3.pass
-cancel6d.pass: cancel3.pass
-cancel7.pass: kill1.pass
-cancel8.pass: cancel7.pass
-cancel9.pass: cancel8.pass
-cleanup0.pass: cancel5.pass
-cleanup1.pass: cleanup0.pass
-cleanup2.pass: cleanup1.pass
-cleanup3.pass: cleanup2.pass
-condvar1.pass:
-condvar1_1.pass: condvar1.pass
-condvar1_2.pass: join2.pass
-condvar2.pass: condvar1.pass
-condvar2_1.pass: condvar2.pass join2.pass
-condvar3.pass: create1.pass condvar2.pass
-condvar3_1.pass: condvar3.pass join2.pass
-condvar3_2.pass: condvar3_1.pass
-condvar3_3.pass: condvar3_2.pass
-condvar4.pass: create1.pass
-condvar5.pass: condvar4.pass
-condvar6.pass: condvar5.pass
-condvar7.pass: condvar6.pass cleanup1.pass
-condvar8.pass: condvar7.pass
-condvar9.pass: condvar8.pass
-context1.pass: cancel1.pass
-count1.pass: join1.pass
-create1.pass: mutex2.pass
-create2.pass: create1.pass
-create3.pass: create2.pass
-delay1.pass:
-delay2.pass: delay1.pass
-detach1.pass: join0.pass
-equal1.pass: create1.pass
-errno1.pass: mutex3.pass
-exception1.pass: cancel4.pass
-exception2.pass: exception1.pass
-exception3.pass: exception2.pass
-exit1.pass:
-exit2.pass: create1.pass
-exit3.pass: create1.pass
-exit4.pass:
-exit5.pass: kill1.pass
-eyal1.pass: tsd1.pass
-inherit1.pass: join1.pass priority1.pass
-join0.pass: create1.pass
-join1.pass: create1.pass
-join2.pass: create1.pass
-join3.pass: join2.pass
-kill1.pass: 
-loadfree.pass: pthread.dll
-mutex1.pass: self1.pass
-mutex1n.pass: mutex1.pass
-mutex1e.pass: mutex1.pass
-mutex1r.pass: mutex1.pass
-mutex2.pass: mutex1.pass
-mutex2r.pass: mutex2.pass
-mutex2e.pass: mutex2.pass
-mutex3.pass: create1.pass
-mutex3r.pass: mutex3.pass
-mutex3e.pass: mutex3.pass
-mutex4.pass: mutex3.pass
-mutex5.pass:
-mutex6.pass: mutex4.pass
-mutex6n.pass: mutex4.pass
-mutex6e.pass: mutex4.pass
-mutex6r.pass: mutex4.pass
-mutex6s.pass: mutex6.pass
-mutex6rs.pass: mutex6r.pass
-mutex6es.pass: mutex6e.pass
-mutex7.pass: mutex6.pass
-mutex7n.pass: mutex6n.pass
-mutex7e.pass: mutex6e.pass
-mutex7r.pass: mutex6r.pass
-mutex8.pass: mutex7.pass
-mutex8n.pass: mutex7n.pass
-mutex8e.pass: mutex7e.pass
-mutex8r.pass: mutex7r.pass
-once1.pass: create1.pass
-once2.pass: once1.pass
-once3.pass: once2.pass
-once4.pass: once3.pass
-priority1.pass: join1.pass
-priority2.pass: priority1.pass barrier3.pass
-reuse1.pass: create3.pass
-reuse2.pass: reuse1.pass
-robust1.pass: mutex8r.pass
-robust2.pass: mutex8r.pass
-robust3.pass: robust2.pass
-robust4.pass: robust3.pass
-robust5.pass: robust4.pass
-rwlock1.pass: condvar6.pass
-rwlock2.pass: rwlock1.pass
-rwlock3.pass: rwlock2.pass join2.pass
-rwlock4.pass: rwlock3.pass
-rwlock5.pass: rwlock4.pass
-rwlock6.pass: rwlock5.pass
-rwlock7.pass: rwlock6.pass
-rwlock8.pass: rwlock7.pass
-rwlock2_t.pass: rwlock2.pass
-rwlock3_t.pass: rwlock2_t.pass
-rwlock4_t.pass: rwlock3_t.pass
-rwlock5_t.pass: rwlock4_t.pass
-rwlock6_t.pass: rwlock5_t.pass
-rwlock6_t2.pass: rwlock6_t.pass
-self1.pass:
-self2.pass: create1.pass
-semaphore1.pass:
-semaphore2.pass:
-semaphore3.pass: semaphore2.pass
-semaphore4.pass: semaphore3.pass cancel1.pass
-semaphore4t.pass: semaphore4.pass
-semaphore5.pass: semaphore4.pass
-sequence1.pass: reuse2.pass
-sizes.pass:
-spin1.pass:
-spin2.pass: spin1.pass
-spin3.pass: spin2.pass
-spin4.pass: spin3.pass
-stress1.pass: condvar9.pass barrier5.pass
-tsd1.pass: barrier5.pass join1.pass
-tsd2.pass: tsd1.pass
-valid1.pass: join1.pass
-valid2.pass: valid1.pass
diff --git a/deps/w32-pthreads/tests/README b/deps/w32-pthreads/tests/README
deleted file mode 100644
index a1b5646..0000000
--- a/deps/w32-pthreads/tests/README
+++ /dev/null
@@ -1,44 +0,0 @@
-Running test cases in this directory
-------------------------------------
-
-These make scripts expect to be able to copy the dll, library
-and header files from this directory's parent directory,
-which should be the pthreads-win32 source directory.
-
-MS VC nmake
--------------
-
-Run the target corresponding to the DLL version being tested:
- 
-nmake clean VC
- 
-or:
- 
-nmake clean VS
-
-
-GNU GCC make
-------------
-
-Run "make clean" and then "make". See the "Known bugs" section
-in ..\README.
-
-
-Writing Test Cases
-------------------
-
-Tests written in this test suite should behave in the following manner:
-
-	* If a test fails, leave main() with a result of 1.
-
-	* If a test succeeds, leave main() with a result of 0.
-
-	* No diagnostic output should appear when the test is succeeding.
-	  Diagnostic output may be emitted if something in the test
-	  fails, to help determine the cause of the test failure.
-
-Notes:
-------
-
-Many test cases use knowledge of implementation internals which are supposed
-to be opaque to portable applications.
diff --git a/deps/w32-pthreads/tests/README.BENCHTESTS b/deps/w32-pthreads/tests/README.BENCHTESTS
deleted file mode 100644
index 448570c..0000000
--- a/deps/w32-pthreads/tests/README.BENCHTESTS
+++ /dev/null
@@ -1,74 +0,0 @@
-
-------------
-Benchmarking
-------------
-There is a set a benchmarking programs in the
-"tests" directory. These should be runnable using the
-following command-lines corresponding to each of the possible
-library builds:
-
-MSVC:
-nmake clean VC-bench
-nmake clean VCE-bench
-nmake clean VSE-bench
-
-Mingw32:
-make clean GC-bench
-make clean GCE-bench
-
-UWIN:
-The benchtests are run as part of the testsuite.
-
-
-Mutex benchtests
-----------------
-
-benchtest1 - Lock plus unlock on an unlocked mutex.
-benchtest2 - Lock plus unlock on a locked mutex.
-benchtest3 - Trylock on a locked mutex.
-benchtest4 - Trylock plus unlock on an unlocked mutex.
-
-
-Each test times up to three alternate synchronisation
-implementations as a reference, and then times each of
-the four mutex types provided by the library. Each is
-described below:
-
-Simple Critical Section
-- uses a simple Win32 critical section. There is no
-additional overhead for this case as there is in the
-remaining cases.
-
-POSIX mutex implemented using a Critical Section
-- The old implementation which uses runtime adaptation
-depending on the Windows variant being run on. When
-the pthreads DLL was run on WinNT or higher then
-POSIX mutexes would use Win32 Critical Sections.
-
-POSIX mutex implemented using a Win32 Mutex
-- The old implementation which uses runtime adaptation
-depending on the Windows variant being run on. When
-the pthreads DLL was run on Win9x then POSIX mutexes
-would use Win32 Mutexes (because TryEnterCriticalSection
-is not implemented on Win9x).
-
-PTHREAD_MUTEX_DEFAULT
-PTHREAD_MUTEX_NORMAL
-PTHREAD_MUTEX_ERRORCHECK
-PTHREAD_MUTEX_RECURSIVE
-- The current implementation supports these mutex types.
-The underlying basis of POSIX mutexes is now the same
-irrespective of the Windows variant, and should therefore
-have consistent performance.
-
-
-Semaphore benchtests
---------------------
-
-benchtest5 - Timing for various uncontended cases.
-
-
-In all benchtests, the operation is repeated a large
-number of times and an average is calculated. Loop
-overhead is measured and subtracted from all test times.
-
diff --git a/deps/w32-pthreads/tests/SIZES.GC b/deps/w32-pthreads/tests/SIZES.GC
deleted file mode 100644
index 4a575cb..0000000
--- a/deps/w32-pthreads/tests/SIZES.GC
+++ /dev/null
@@ -1,21 +0,0 @@
-Sizes of pthreads-win32 structs
--------------------------------
-                     pthread_t    8
-                ptw32_thread_t  160
-               pthread_attr_t_   28
-                        sem_t_   12
-              pthread_mutex_t_   28
-          pthread_mutexattr_t_   12
-           pthread_spinlock_t_    8
-            pthread_barrier_t_   36
-        pthread_barrierattr_t_    4
-                pthread_key_t_   16
-               pthread_cond_t_   32
-           pthread_condattr_t_    4
-             pthread_rwlock_t_   28
-         pthread_rwlockattr_t_    4
-               pthread_once_t_   16
-               ptw32_cleanup_t   12
-             ptw32_mcs_node_t_   16
-                   sched_param    4
--------------------------------
diff --git a/deps/w32-pthreads/tests/SIZES.GCE b/deps/w32-pthreads/tests/SIZES.GCE
deleted file mode 100644
index 048b3ab..0000000
--- a/deps/w32-pthreads/tests/SIZES.GCE
+++ /dev/null
@@ -1,21 +0,0 @@
-Sizes of pthreads-win32 structs
--------------------------------
-                     pthread_t    8
-                ptw32_thread_t   96
-               pthread_attr_t_   28
-                        sem_t_   12
-              pthread_mutex_t_   28
-          pthread_mutexattr_t_   12
-           pthread_spinlock_t_    8
-            pthread_barrier_t_   36
-        pthread_barrierattr_t_    4
-                pthread_key_t_   16
-               pthread_cond_t_   32
-           pthread_condattr_t_    4
-             pthread_rwlock_t_   28
-         pthread_rwlockattr_t_    4
-               pthread_once_t_   16
-               ptw32_cleanup_t   12
-             ptw32_mcs_node_t_   16
-                   sched_param    4
--------------------------------
diff --git a/deps/w32-pthreads/tests/SIZES.VC b/deps/w32-pthreads/tests/SIZES.VC
deleted file mode 100644
index a73236d..0000000
--- a/deps/w32-pthreads/tests/SIZES.VC
+++ /dev/null
@@ -1,21 +0,0 @@
-Sizes of pthreads-win32 structs
--------------------------------
-                     pthread_t   16
-                ptw32_thread_t  432
-               pthread_attr_t_   40
-                        sem_t_   24
-              pthread_mutex_t_   48
-          pthread_mutexattr_t_   12
-           pthread_spinlock_t_   16
-            pthread_barrier_t_   64
-        pthread_barrierattr_t_    4
-                pthread_key_t_   32
-               pthread_cond_t_   56
-           pthread_condattr_t_    4
-             pthread_rwlock_t_   40
-         pthread_rwlockattr_t_    4
-               pthread_once_t_   24
-               ptw32_cleanup_t   24
-             ptw32_mcs_node_t_   32
-                   sched_param    4
--------------------------------
diff --git a/deps/w32-pthreads/tests/SIZES.VCE b/deps/w32-pthreads/tests/SIZES.VCE
deleted file mode 100644
index 048b3ab..0000000
--- a/deps/w32-pthreads/tests/SIZES.VCE
+++ /dev/null
@@ -1,21 +0,0 @@
-Sizes of pthreads-win32 structs
--------------------------------
-                     pthread_t    8
-                ptw32_thread_t   96
-               pthread_attr_t_   28
-                        sem_t_   12
-              pthread_mutex_t_   28
-          pthread_mutexattr_t_   12
-           pthread_spinlock_t_    8
-            pthread_barrier_t_   36
-        pthread_barrierattr_t_    4
-                pthread_key_t_   16
-               pthread_cond_t_   32
-           pthread_condattr_t_    4
-             pthread_rwlock_t_   28
-         pthread_rwlockattr_t_    4
-               pthread_once_t_   16
-               ptw32_cleanup_t   12
-             ptw32_mcs_node_t_   16
-                   sched_param    4
--------------------------------
diff --git a/deps/w32-pthreads/tests/SIZES.VSE b/deps/w32-pthreads/tests/SIZES.VSE
deleted file mode 100644
index 048b3ab..0000000
--- a/deps/w32-pthreads/tests/SIZES.VSE
+++ /dev/null
@@ -1,21 +0,0 @@
-Sizes of pthreads-win32 structs
--------------------------------
-                     pthread_t    8
-                ptw32_thread_t   96
-               pthread_attr_t_   28
-                        sem_t_   12
-              pthread_mutex_t_   28
-          pthread_mutexattr_t_   12
-           pthread_spinlock_t_    8
-            pthread_barrier_t_   36
-        pthread_barrierattr_t_    4
-                pthread_key_t_   16
-               pthread_cond_t_   32
-           pthread_condattr_t_    4
-             pthread_rwlock_t_   28
-         pthread_rwlockattr_t_    4
-               pthread_once_t_   16
-               ptw32_cleanup_t   12
-             ptw32_mcs_node_t_   16
-                   sched_param    4
--------------------------------
diff --git a/deps/w32-pthreads/tests/Wmakefile b/deps/w32-pthreads/tests/Wmakefile
deleted file mode 100644
index f732e94..0000000
--- a/deps/w32-pthreads/tests/Wmakefile
+++ /dev/null
@@ -1,355 +0,0 @@
-# Watcom makefile for the pthreads test suite.
-# If all of the .pass files can be created, the test suite has passed.
-#
-# --------------------------------------------------------------------------
-#
-#      Pthreads-win32 - POSIX Threads Library for Win32
-#      Copyright(C) 1998 John E. Bossom
-#      Copyright(C) 1999,2005 Pthreads-win32 contributors
-# 
-#      Contact Email: rpj at callisto.canberra.edu.au
-# 
-#      The current list of contributors is contained
-#      in the file CONTRIBUTORS included with the source
-#      code distribution. The list can also be seen at the
-#     following World Wide Web location:
-#      http://sources.redhat.com/pthreads-win32/contributors.html
-# 
-#      This library is free software; you can redistribute it and/or
-#      modify it under the terms of the GNU Lesser General Public
-#      License as published by the Free Software Foundation; either
-#      version 2 of the License, or (at your option) any later version.
-# 
-#      This library is distributed in the hope that it will be useful,
-#      but WITHOUT ANY WARRANTY; without even the implied warranty of
-#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#      Lesser General Public License for more details.
-# 
-#      You should have received a copy of the GNU Lesser General Public
-#      License along with this library in the file COPYING.LIB;
-#      if not, write to the Free Software Foundation, Inc.,
-#      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-#
-
-
-DLL_VER	= 2
-
-.EXTENSIONS:
-
-.EXTENSIONS: .pass .exe .obj .i .c
-
-CP	= copy
-RM	= erase
-CAT	= type
-MKDIR	= mkdir
-TOUCH	= echo Passed >
-ECHO	= @echo
-
-CPHDR	= pthread.h semaphore.h sched.h
-
-OPTIM	= -od
-
-XXLIBS	=
-
-# C++ Exceptions
-WCEFLAGS	= -xs -dPtW32NoCatchWarn -d__CLEANUP_CXX
-WCELIB	= pthreadWCE$(DLL_VER).lib
-WCEDLL	= pthreadWCE$(DLL_VER).dll
-# C cleanup code
-WCFLAGS	= -d__CLEANUP_C
-WCLIB	= pthreadWC$(DLL_VER).lib
-WCDLL	= pthreadWC$(DLL_VER).dll
-# C++ Exceptions in application - using WC version of pthreads dll
-WCXFLAGS	= -xs -d__CLEANUP_C
-
-CFLAGS= -w4 -e25 -d_WIN32_WINNT=0x400 -d_REENTRANT -zq -bm $(OPTIM) -5r -bt=nt -mf -d2
-
-LFLAGS= 
-INCLUDES= -i=.
-BUILD_DIR=..
-
-# The next path is relative to $BUILD_DIR
-QAPC	= # ..\QueueUserAPCEx\User\quserex.dll
-
-COPYFILES	= $(CPHDR) $(CPLIB) $(CPDLL) $(QAPC)
-
-TEST		=
-EHFLAGS	=
-
-# If a test case returns a non-zero exit code to the shell, make will
-# stop.
-
-PASSES	= sizes.pass  loadfree.pass &
-	  self1.pass  mutex5.pass  &
-	  mutex1.pass  mutex1n.pass  mutex1e.pass  mutex1r.pass &
-	  semaphore1.pass  semaphore2.pass semaphore3.pass &
-	  mutex2.pass  mutex3.pass  &
-	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  &
-	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  &
-	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  &
-	  sequence1.pass  kill1.pass  valid1.pass  valid2.pass  &
-	  exit2.pass  exit3.pass  exit4  exit5  &
-	  join0.pass  join1.pass  detach1.pass  join2.pass join3.pass  &
-	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  &
-	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  &
-	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  &
-	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  &
-	  robust1.pass  robust2.pass  robust3.pass  robust4.pass  robust5.pass  &
-	  count1.pass  &
-	  once1.pass  once2.pass  once3.pass  once4.pass  tsd1.pass  &
-	  self2.pass  &
-	  cancel1.pass  cancel2.pass  &
-	  semaphore4.pass semaphore4t.pass semaphore5.pass &
-	  delay1.pass  delay2.pass  eyal1.pass  &
-	  condvar3.pass  condvar3_1.pass  condvar3_2.pass  condvar3_3.pass  &
-	  condvar4.pass  condvar5.pass  condvar6.pass  &
-	  condvar7.pass  condvar8.pass  condvar9.pass  &
-	  errno1.pass  &
-	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  rwlock5.pass  &
-	  rwlock6.pass  rwlock7.pass  rwlock8.pass  &
-	  rwlock2_t.pass  rwlock3_t.pass  rwlock4_t.pass  rwlock5_t.pass  rwlock6_t.pass  rwlock6_t2.pass  &
-	  context1.pass  &
-	  cancel3.pass  cancel4.pass  cancel5.pass  cancel6a.pass  cancel6d.pass  &
-	  cancel7  cancel8  &
-	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  &
-	  priority1.pass priority2.pass inherit1.pass  &
-	  spin1.pass  spin2.pass  spin3.pass  spin4.pass  &
-	  barrier1.pass  barrier2.pass  barrier3.pass  barrier4.pass  barrier5.pass  &
-	  exception1.pass  exception2.pass  exception3.pass  &
-	  cancel9.pass  stress1.pass
-
-BENCHRESULTS = &
-	  benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench
-
-help: .SYMBOLIC
-	@ $(ECHO) Run one of the following command lines:
-	@ $(ECHO) wmake /f Wmakefile clean WC    (to test using WC dll with wcc386 (no EH) applications)
-	@ $(ECHO) wmake /f Wmakefile clean WCX   (to test using WC dll with wpp386 (EH) applications)
-	@ $(ECHO) wmake /f Wmakefile clean WCE   (to test using the WCE dll with wpp386 EH applications)
-	@ $(ECHO) wmake /f Wmakefile clean WC-bench    (to benchtest using WC dll with C bench app)
-	@ $(ECHO) wmake /f Wmakefile clean WCX-bench   (to benchtest using WC dll with C++ bench app)
-	@ $(ECHO) wmake /f Wmakefile clean WCE-bench   (to benchtest using WCE dll with C++ bench app)
-
-all: .SYMBOLIC
-	@ wmake /f Wmakefile clean WC
-	@ wmake /f Wmakefile clean WCX
-	@ wmake /f Wmakefile clean WCE
-	@ wmake /f Wmakefile clean WSE
-	@ wmake /f Wmakefile clean WC-bench
-
-tests: $(CPLIB) $(CPDLL) $(CPHDR) $(PASSES) .SYMBOLIC
-	@ $(ECHO) ALL TESTS PASSED! Congratulations!
-
-benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(XXLIBS) $(BENCHRESULTS) .SYMBOLIC
-	@ $(ECHO) ALL BENCH TESTS DONE.
-
-$(BENCHRESULTS): ($[*).exe
-	@ $(ECHO) ... Running $(TEST) benchtest: ($[*).exe
-	@ .\($[*).exe
-	@ $(ECHO) ...... Done
-	@ $(TOUCH) ($[*).bench
-
-WCE: .SYMBOLIC
-	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCELIB)" CPDLL="$(WCEDLL)" EHFLAGS="$(WCEFLAGS)" tests
-
-WC: .SYMBOLIC
-	@ wmake /f Wmakefile CC=wcc386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCFLAGS)" tests
-
-WCX: .SYMBOLIC
-	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCXFLAGS)" tests
-
-WCE-bench: .SYMBOLIC
-	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCELIB)" CPDLL="$(WCEDLL)" EHFLAGS="$(WCEFLAGS)" XXLIBS="benchlib.o" benchtests
-
-WC-bench: .SYMBOLIC
-	@ wmake /f Wmakefile CC=wcc386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCFLAGS)" XXLIBS="benchlib.o" benchtests
-
-WCX-bench: .SYMBOLIC
-	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCXFLAGS)" XXLIBS="benchlib.o" benchtests
-
-sizes.pass: sizes.exe
-	@ $(ECHO) ... Running $(TEST) test: $^*
-	@ $[@ > SIZES.$(TEST)
-	@ $(CAT) SIZES.$(TEST)
-	@ $(ECHO) ...... Passed
-	@ $(TOUCH) $^@
-
-.exe.pass:
-	@ $(ECHO) ... Running $(TEST) test: $^*
-	@ $[@
-	@ $(ECHO) ...... Passed
-	@ $(TOUCH) $^@
-
-.obj.exe:
-	@ $(ECHO) wlink NAME $^@ FILE $[@ LIBRARY $(CPLIB) OPTION quiet
-	@ wlink NAME $^@ FILE $[@ LIBRARY $(CPLIB) OPTION quiet
-
-.c.obj:
-	@ $(ECHO) $(CC) $^* $(EHFLAGS) $(CFLAGS) $(INCLUDES)
-	@ $(CC) $^* $(EHFLAGS) $(CFLAGS) $(INCLUDES)
-
-.c.i:
-	@ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $<
-
-$(COPYFILES): .SYMBOLIC
-	@ $(ECHO) Copying $(BUILD_DIR)\$@
-	@ $(CP) $(BUILD_DIR)\$@ .
-
-pthread.dll:
-	@ $(CP) $(CPDLL) $*.dll
-	@ $(CP) $(CPLIB) $*.lib
-
-clean: .SYMBOLIC
-	@ if exist *.dll $(RM) *.dll
-	@ if exist *.lib $(RM) *.lib
-	@ if exist *.err $(RM) *.err
-	@ if exist pthread.h $(RM) pthread.h
-	@ if exist semaphore.h $(RM) semaphore.h
-	@ if exist sched.h $(RM) sched.h
-	@ if exist *.e $(RM) *.e
-	@ if exist *.i $(RM) *.i
-	@ if exist *.obj $(RM) *.obj
-	@ if exist *.pdb $(RM) *.pdb
-	@ if exist *.o $(RM) *.o
-	@ if exist *.asm $(RM) *.asm
-	@ if exist *.exe $(RM) *.exe
-	@ if exist *.pass $(RM) *.pass
-	@ if exist *.bench $(RM) *.bench
-	@ if exist *.log $(RM) *.log
-	@ $(ECHO) Clean completed.
-
-benchtest1.bench:
-benchtest2.bench:
-benchtest3.bench:
-benchtest4.bench:
-benchtest5.bench:
-barrier1.pass:
-barrier2.pass: barrier1.pass
-barrier3.pass: barrier2.pass
-barrier4.pass: barrier3.pass
-barrier5.pass: barrier4.pass
-cancel1.pass: create1.pass
-cancel2.pass: cancel1.pass
-cancel3.pass: context1.pass
-cancel4.pass: cancel3.pass
-cancel5.pass: cancel3.pass
-cancel6a.pass: cancel3.pass
-cancel6d.pass: cancel3.pass
-cancel7.pass: kill1.pass
-cancel8.pass: cancel7.pass
-cleanup0.pass: cancel5.pass
-cleanup1.pass: cleanup0.pass
-cleanup2.pass: cleanup1.pass
-cleanup3.pass: cleanup2.pass
-condvar1.pass:
-condvar1_1.pass: condvar1.pass
-condvar1_2.pass: join2.pass
-condvar2.pass: condvar1.pass
-condvar2_1.pass: condvar2.pass join2.pass
-condvar3.pass: create1.pass condvar2.pass
-condvar3_1.pass: condvar3.pass join2.pass
-condvar3_2.pass: condvar3_1.pass
-condvar3_3.pass: condvar3_2.pass
-condvar4.pass: create1.pass
-condvar5.pass: condvar4.pass
-condvar6.pass: condvar5.pass
-condvar7.pass: condvar6.pass cleanup1.pass
-condvar8.pass: condvar7.pass
-condvar9.pass: condvar8.pass
-context1.pass: cancel1.pass
-count1.pass: join1.pass
-create1.pass: mutex2.pass
-create2.pass: create1.pass
-delay1.pass:
-delay2.pass: delay1.pass
-detach1.pass: join0.pass
-equal1.pass: create1.pass
-errno1.pass: mutex3.pass
-exception1.pass: cancel4.pass
-exception2.pass: exception1.pass
-exception3.pass: exception2.pass
-exit1.pass:
-exit2.pass: create1.pass
-exit3.pass: create1.pass
-exit4.pass:
-exit5.pass: kill1.pass
-eyal1.pass: tsd1.pass
-inherit1.pass: join1.pass priority1.pass
-join0.pass: create1.pass
-join1.pass: create1.pass
-join2.pass: create1.pass
-join3.pass: join2.pass
-kill1.pass: 
-loadfree.pass: pthread.dll
-mutex1.pass: self1.pass
-mutex1n.pass: mutex1.pass
-mutex1e.pass: mutex1.pass
-mutex1r.pass: mutex1.pass
-mutex2.pass: mutex1.pass
-mutex2r.pass: mutex2.pass
-mutex2e.pass: mutex2.pass
-mutex3.pass: create1.pass
-mutex3r.pass: mutex3.pass
-mutex3e.pass: mutex3.pass
-mutex4.pass: mutex3.pass
-mutex5.pass:
-mutex6.pass: mutex4.pass
-mutex6n.pass: mutex4.pass
-mutex6e.pass: mutex4.pass
-mutex6r.pass: mutex4.pass
-mutex6s.pass: mutex6.pass
-mutex6rs.pass: mutex6r.pass
-mutex6es.pass: mutex6e.pass
-mutex7.pass: mutex6.pass
-mutex7n.pass: mutex6n.pass
-mutex7e.pass: mutex6e.pass
-mutex7r.pass: mutex6r.pass
-mutex8.pass: mutex7.pass
-mutex8n.pass: mutex7n.pass
-mutex8e.pass: mutex7e.pass
-mutex8r.pass: mutex7r.pass
-once1.pass: create1.pass
-once2.pass: once1.pass
-once3.pass: once2.pass
-once4.pass: once3.pass
-priority1.pass: join1.pass
-priority2.pass: priority1.pass barrier3.pass
-reuse1.pass: create2.pass
-reuse2.pass: reuse1.pass
-robust1.pass: mutex8r.pass
-robust2.pass: mutex8r.pass
-robust3.pass: robust2.pass
-robust4.pass: robust3.pass
-robust5.pass: robust4.pass
-rwlock1.pass: condvar6.pass
-rwlock2.pass: rwlock1.pass
-rwlock3.pass: rwlock2.pass join2.pass
-rwlock4.pass: rwlock3.pass
-rwlock5.pass: rwlock4.pass
-rwlock6.pass: rwlock5.pass
-rwlock7.pass: rwlock6.pass
-rwlock2_t.pass: rwlock2.pass
-rwlock3_t.pass: rwlock2_t.pass
-rwlock4_t.pass: rwlock3_t.pass
-rwlock5_t.pass: rwlock4_t.pass
-rwlock6_t.pass: rwlock5_t.pass
-rwlock6_t2.pass: rwlock6_t.pass
-self1.pass:
-self2.pass: create1.pass
-semaphore1.pass:
-semaphore2.pass:
-semaphore3.pass: semaphore2.pass
-semaphore4.pass: semaphore3.pass cancel1.pass
-semaphore4t.pass: semaphore4.pass
-semaphore5.pass: semaphore4.pass
-sequence1.pass: reuse2.pass
-sizes.pass:
-spin1.pass:
-spin2.pass: spin1.pass
-spin3.pass: spin2.pass
-spin4.pass: spin3.pass
-stress1.pass:
-tsd1.pass: join1.pass
-valid1.pass: join1.pass
-valid2.pass: valid1.pass
-cancel9.pass: cancel8.pass
diff --git a/deps/w32-pthreads/tests/barrier1.c b/deps/w32-pthreads/tests/barrier1.c
deleted file mode 100644
index bdcb6b9..0000000
--- a/deps/w32-pthreads/tests/barrier1.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* 
- * barrier1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Create a barrier object and then destroy it.
- *
- */
-
-#include "test.h"
-
-pthread_barrier_t barrier = NULL;
-
-int
-main()
-{
-  assert(barrier == NULL);
-
-  assert(pthread_barrier_init(&barrier, NULL, 1) == 0);
-
-  assert(barrier != NULL);
-
-  assert(pthread_barrier_destroy(&barrier) == 0);
-
-  assert(barrier == NULL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/barrier2.c b/deps/w32-pthreads/tests/barrier2.c
deleted file mode 100644
index e489469..0000000
--- a/deps/w32-pthreads/tests/barrier2.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* 
- * barrier2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a single barrier object, wait on it, 
- * and then destroy it.
- *
- */
-
-#include "test.h"
- 
-pthread_barrier_t barrier = NULL;
-
-int
-main()
-{
-  assert(pthread_barrier_init(&barrier, NULL, 1) == 0);
-
-  assert(pthread_barrier_wait(&barrier) == PTHREAD_BARRIER_SERIAL_THREAD);
-
-  assert(pthread_barrier_destroy(&barrier) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/barrier3.c b/deps/w32-pthreads/tests/barrier3.c
deleted file mode 100644
index a458e4c..0000000
--- a/deps/w32-pthreads/tests/barrier3.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * barrier3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a single barrier object with barrier attribute, wait on it, 
- * and then destroy it.
- *
- */
-
-#include "test.h"
- 
-pthread_barrier_t barrier = NULL;
-static void* result = (void*)1;
-
-void * func(void * arg)
-{
-  return (void *) (size_t)pthread_barrier_wait(&barrier);
-}
- 
-int
-main()
-{
-  pthread_t t;
-  pthread_barrierattr_t ba;
-
-  assert(pthread_barrierattr_init(&ba) == 0);
-  assert(pthread_barrierattr_setpshared(&ba, PTHREAD_PROCESS_PRIVATE) == 0);
-  assert(pthread_barrier_init(&barrier, &ba, 1) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-
-  assert(pthread_join(t, &result) == 0);
-
-  assert((int)(size_t)result == PTHREAD_BARRIER_SERIAL_THREAD);
-
-  assert(pthread_barrier_destroy(&barrier) == 0);
-  assert(pthread_barrierattr_destroy(&ba) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/barrier4.c b/deps/w32-pthreads/tests/barrier4.c
deleted file mode 100644
index 633fe10..0000000
--- a/deps/w32-pthreads/tests/barrier4.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * barrier4.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a single barrier object, multiple wait on it, 
- * and then destroy it.
- *
- */
-
-#include "test.h"
-
-enum {
-  NUMTHREADS = 16
-};
- 
-pthread_barrier_t barrier = NULL;
-pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;
-static int serialThreadCount = 0;
-static int otherThreadCount = 0;
-
-void *
-func(void * arg)
-{
-  int result = pthread_barrier_wait(&barrier);
-
-  assert(pthread_mutex_lock(&mx) == 0);
-
-  if (result == PTHREAD_BARRIER_SERIAL_THREAD)
-    {
-      serialThreadCount++;
-    }
-  else if (0 == result)
-    {
-      otherThreadCount++;
-    }
-  else
-    {
-      printf("Barrier wait failed: error = %s\n", error_string[result]);
-      fflush(stdout);
-      return NULL;
-    }
-  assert(pthread_mutex_unlock(&mx) == 0);
-
-  return NULL;
-}
-
-int
-main()
-{
-  int i, j;
-  pthread_t t[NUMTHREADS + 1];
-
-  for (j = 1; j <= NUMTHREADS; j++)
-    {
-      printf("Barrier height = %d\n", j);
-
-      serialThreadCount = 0;
-
-      assert(pthread_barrier_init(&barrier, NULL, j) == 0);
-
-      for (i = 1; i <= j; i++)
-        {
-          assert(pthread_create(&t[i], NULL, func, NULL) == 0);
-        }
-
-      for (i = 1; i <= j; i++)
-        {
-          assert(pthread_join(t[i], NULL) == 0);
-        }
-
-      assert(serialThreadCount == 1);
-
-      assert(pthread_barrier_destroy(&barrier) == 0);
-    }
-
-  assert(pthread_mutex_destroy(&mx) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/barrier5.c b/deps/w32-pthreads/tests/barrier5.c
deleted file mode 100644
index b359349..0000000
--- a/deps/w32-pthreads/tests/barrier5.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * barrier5.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Set up a series of barriers at different heights and test various numbers
- * of threads accessing, especially cases where there are more threads than the
- * barrier height (count), i.e. test contention when the barrier is released.
- */
-
-#include "test.h"
-
-enum {
-  NUMTHREADS = 15,
-  HEIGHT = 10,
-  BARRIERMULTIPLE = 1000
-};
- 
-pthread_barrier_t barrier = NULL;
-pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;
-LONG totalThreadCrossings;
-
-void *
-func(void * crossings)
-{
-  int result;
-  int serialThreads = 0;
-
-  while ((LONG)(size_t)crossings >= (LONG)InterlockedIncrement((LPLONG)&totalThreadCrossings))
-    {
-      result = pthread_barrier_wait(&barrier);
-
-      if (result == PTHREAD_BARRIER_SERIAL_THREAD)
-        {
-          serialThreads++;
-        }
-      else if (result != 0)
-        {
-          printf("Barrier failed: result = %s\n", error_string[result]);
-          fflush(stdout);
-          return NULL;
-        }
-    }
-
-  return (void*)(size_t)serialThreads;
-}
-
-int
-main()
-{
-  int i, j;
-  void* result;
-  int serialThreadsTotal;
-  LONG Crossings;
-  pthread_t t[NUMTHREADS + 1];
-
-  for (j = 1; j <= NUMTHREADS; j++)
-    {
-      int height = j<HEIGHT?j:HEIGHT;
-
-      totalThreadCrossings = 0;
-      Crossings = height * BARRIERMULTIPLE;
-
-      printf("Threads=%d, Barrier height=%d\n", j, height);
-
-      assert(pthread_barrier_init(&barrier, NULL, height) == 0);
-
-      for (i = 1; i <= j; i++)
-        {
-          assert(pthread_create(&t[i], NULL, func, (void *)(size_t)Crossings) == 0);
-        }
-
-      serialThreadsTotal = 0;
-      for (i = 1; i <= j; i++)
-        {
-          assert(pthread_join(t[i], &result) == 0);
-          serialThreadsTotal += (int)(size_t)result;
-        }
-
-      assert(serialThreadsTotal == BARRIERMULTIPLE);
-
-      assert(pthread_barrier_destroy(&barrier) == 0);
-    }
-
-  assert(pthread_mutex_destroy(&mx) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/barrier6.c b/deps/w32-pthreads/tests/barrier6.c
deleted file mode 100644
index a78c453..0000000
--- a/deps/w32-pthreads/tests/barrier6.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * barrier6.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Destroy the barrier after initial count threads are released then let
- * additional threads attempt to wait on it.
- *
- */
-
-#include "test.h"
-
-enum {
-  NUMTHREADS = 31
-};
- 
-pthread_barrier_t barrier = NULL;
-pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;
-static int serialThreadCount = 0;
-static int otherThreadCount = 0;
-
-void *
-func(void * arg)
-{
-  int result = pthread_barrier_wait(&barrier);
-
-  assert(pthread_mutex_lock(&mx) == 0);
-
-  if (result == PTHREAD_BARRIER_SERIAL_THREAD)
-    {
-      serialThreadCount++;
-    }
-  else if (0 == result)
-    {
-      otherThreadCount++;
-    }
-  assert(pthread_mutex_unlock(&mx) == 0);
-
-  return NULL;
-}
-
-int
-main()
-{
-  int i, j, k;
-  pthread_t t[NUMTHREADS + 1];
-
-  for (j = 1; j <= NUMTHREADS; j++)
-    {
-      int howHigh = j/2 + 1;
-
-      printf("Barrier height = %d, Total threads %d\n", howHigh, j);
-
-      serialThreadCount = 0;
-      otherThreadCount = 0;
-
-      assert(pthread_barrier_init(&barrier, NULL, howHigh) == 0);
-
-      for (i = 1; i <= j; i++)
-        {
-          assert(pthread_create(&t[i], NULL, func, NULL) == 0);
-
-          if (i == howHigh)
-            {
-              for (k = 1; k <= howHigh; k++)
-                {
-                  assert(pthread_join(t[k], NULL) == 0);
-                }
-              assert(pthread_barrier_destroy(&barrier) == 0);
-            }
-        }
-
-      for (i = howHigh+1; i <= j; i++)
-        {
-          assert(pthread_join(t[i], NULL) == 0);
-        }
-
-      assert(serialThreadCount == 1);
-      assert(otherThreadCount == (howHigh - 1));
-
-      assert(pthread_barrier_destroy(&barrier) == EINVAL);
-    }
-
-  assert(pthread_mutex_destroy(&mx) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/benchlib.c b/deps/w32-pthreads/tests/benchlib.c
deleted file mode 100644
index 0119f43..0000000
--- a/deps/w32-pthreads/tests/benchlib.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- */
-
-#include "../config.h"
-
-#include "pthread.h"
-#include "sched.h"
-#include "semaphore.h"
-#include <windows.h>
-#include <stdio.h>
-
-#ifdef __GNUC__
-#include <stdlib.h>
-#endif
-
-#include "benchtest.h"
-
-int old_mutex_use = OLD_WIN32CS;
-
-BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION) = NULL;
-HINSTANCE ptw32_h_kernel32;
-
-void
-dummy_call(int * a)
-{
-}
-
-void
-interlocked_inc_with_conditionals(int * a)
-{
-  if (a != NULL)
-    if (InterlockedIncrement((long *) a) == -1)
-      {
-        *a = 0;
-      }
-}
-
-void
-interlocked_dec_with_conditionals(int * a)
-{
-  if (a != NULL)
-    if (InterlockedDecrement((long *) a) == -1)
-      {
-        *a = 0;
-      }
-}
-
-int
-old_mutex_init(old_mutex_t *mutex, const old_mutexattr_t *attr)
-{
-  int result = 0;
-  old_mutex_t mx;
-
-  if (mutex == NULL)
-    {
-      return EINVAL;
-    }
-
-  mx = (old_mutex_t) calloc(1, sizeof(*mx));
-
-  if (mx == NULL)
-    {
-      result = ENOMEM;
-      goto FAIL0;
-    }
-
-  mx->mutex = 0;
-
-  if (attr != NULL
-      && *attr != NULL
-      && (*attr)->pshared == PTHREAD_PROCESS_SHARED
-      )
-    {
-      result = ENOSYS;
-    }
-  else
-    {
-        CRITICAL_SECTION cs;
-
-        /*
-         * Load KERNEL32 and try to get address of TryEnterCriticalSection
-         */
-        ptw32_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL"));
-        ptw32_try_enter_critical_section = (BOOL (WINAPI *)(LPCRITICAL_SECTION))
-
-#if defined(NEED_UNICODE_CONSTS)
-        GetProcAddress(ptw32_h_kernel32,
-                       (const TCHAR *)TEXT("TryEnterCriticalSection"));
-#else
-        GetProcAddress(ptw32_h_kernel32,
-                       (LPCSTR) "TryEnterCriticalSection");
-#endif
-
-        if (ptw32_try_enter_critical_section != NULL)
-          {
-            InitializeCriticalSection(&cs);
-            if ((*ptw32_try_enter_critical_section)(&cs))
-              {
-                LeaveCriticalSection(&cs);
-              }
-            else
-              {
-                /*
-                 * Not really supported (Win98?).
-                 */
-                ptw32_try_enter_critical_section = NULL;
-              }
-            DeleteCriticalSection(&cs);
-          }
-
-        if (ptw32_try_enter_critical_section == NULL)
-          {
-            (void) FreeLibrary(ptw32_h_kernel32);
-            ptw32_h_kernel32 = 0;
-          }
-
-      if (old_mutex_use == OLD_WIN32CS)
-	{
-	  InitializeCriticalSection(&mx->cs);
-	}
-      else if (old_mutex_use == OLD_WIN32MUTEX)
-      {
-	  mx->mutex = CreateMutex (NULL,
-				   FALSE,
-				   NULL);
-
-	  if (mx->mutex == 0)
-	    {
-	      result = EAGAIN;
-	    }
-	}
-      else
-	{
-        result = EINVAL;
-      }
-    }
-
-  if (result != 0 && mx != NULL)
-    {
-      free(mx);
-      mx = NULL;
-    }
-
-FAIL0:
-  *mutex = mx;
-
-  return(result);
-}
-
-
-int
-old_mutex_lock(old_mutex_t *mutex)
-{
-  int result = 0;
-  old_mutex_t mx;
-
-  if (mutex == NULL || *mutex == NULL)
-    {
-      return EINVAL;
-    }
-
-  if (*mutex == (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
-    {
-      /*
-       * Don't use initialisers when benchtesting.
-       */
-      result = EINVAL;
-    }
-
-  mx = *mutex;
-
-  if (result == 0)
-    {
-      if (mx->mutex == 0)
-	{
-	  EnterCriticalSection(&mx->cs);
-	}
-      else
-	{
-	  result = (WaitForSingleObject(mx->mutex, INFINITE) 
-		    == WAIT_OBJECT_0)
-	    ? 0
-	    : EINVAL;
-	}
-    }
-
-  return(result);
-}
-
-int
-old_mutex_unlock(old_mutex_t *mutex)
-{
-  int result = 0;
-  old_mutex_t mx;
-
-  if (mutex == NULL || *mutex == NULL)
-    {
-      return EINVAL;
-    }
-
-  mx = *mutex;
-
-  if (mx != (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
-    {
-      if (mx->mutex == 0)
-	{
-	  LeaveCriticalSection(&mx->cs);
-	}
-      else
-	{
-	  result = (ReleaseMutex (mx->mutex) ? 0 : EINVAL);
-	}
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  return(result);
-}
-
-
-int
-old_mutex_trylock(old_mutex_t *mutex)
-{
-  int result = 0;
-  old_mutex_t mx;
-
-  if (mutex == NULL || *mutex == NULL)
-    {
-      return EINVAL;
-    }
-
-  if (*mutex == (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
-    {
-      /*
-       * Don't use initialisers when benchtesting.
-       */
-      result = EINVAL;
-    }
-
-  mx = *mutex;
-
-  if (result == 0)
-    {
-      if (mx->mutex == 0)
-	{
-	  if (ptw32_try_enter_critical_section == NULL)
-          {
-            result = 0;
-          }
-        else if ((*ptw32_try_enter_critical_section)(&mx->cs) != TRUE)
-	    {
-	      result = EBUSY;
-	    }
-	}
-      else
-	{
-	  DWORD status;
-
-	  status = WaitForSingleObject (mx->mutex, 0);
-
-	  if (status != WAIT_OBJECT_0)
-	    {
-	      result = ((status == WAIT_TIMEOUT)
-			? EBUSY
-			: EINVAL);
-	    }
-	}
-    }
-
-  return(result);
-}
-
-
-int
-old_mutex_destroy(old_mutex_t *mutex)
-{
-  int result = 0;
-  old_mutex_t mx;
-
-  if (mutex == NULL
-      || *mutex == NULL)
-    {
-      return EINVAL;
-    }
-
-  if (*mutex != (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
-    {
-      mx = *mutex;
-
-      if ((result = old_mutex_trylock(&mx)) == 0)
-        {
-          *mutex = NULL;
-
-          (void) old_mutex_unlock(&mx);
-
-          if (mx->mutex == 0)
-            {
-              DeleteCriticalSection(&mx->cs);
-            }
-          else
-            {
-              result = (CloseHandle (mx->mutex) ? 0 : EINVAL);
-            }
-
-          if (result == 0)
-            {
-              mx->mutex = 0;
-              free(mx);
-            }
-          else
-            {
-              *mutex = mx;
-            }
-        }
-    }
-  else
-    {
-      result = EINVAL;
-    }
-
-  if (ptw32_try_enter_critical_section != NULL)
-    {
-      (void) FreeLibrary(ptw32_h_kernel32);
-      ptw32_h_kernel32 = 0;
-    }
-
-  return(result);
-}
-
-/****************************************************************************************/
diff --git a/deps/w32-pthreads/tests/benchtest.h b/deps/w32-pthreads/tests/benchtest.h
deleted file mode 100644
index 429af5c..0000000
--- a/deps/w32-pthreads/tests/benchtest.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- */
-
-#include "../config.h"
-
-enum {
-  OLD_WIN32CS,
-  OLD_WIN32MUTEX
-};
-
-extern int old_mutex_use;
-
-struct old_mutex_t_ {
-  HANDLE mutex;
-  CRITICAL_SECTION cs;
-};
-
-typedef struct old_mutex_t_ * old_mutex_t;
-
-struct old_mutexattr_t_ {
-  int pshared;
-};
-
-typedef struct old_mutexattr_t_ * old_mutexattr_t;
-
-extern BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION);
-extern HINSTANCE ptw32_h_kernel32;
-
-#define PTW32_OBJECT_AUTO_INIT ((void *) -1)
-
-void dummy_call(int * a);
-void interlocked_inc_with_conditionals(int *a);
-void interlocked_dec_with_conditionals(int *a);
-int old_mutex_init(old_mutex_t *mutex, const old_mutexattr_t *attr);
-int old_mutex_lock(old_mutex_t *mutex);
-int old_mutex_unlock(old_mutex_t *mutex);
-int old_mutex_trylock(old_mutex_t *mutex);
-int old_mutex_destroy(old_mutex_t *mutex);
-/****************************************************************************************/
diff --git a/deps/w32-pthreads/tests/benchtest1.c b/deps/w32-pthreads/tests/benchtest1.c
deleted file mode 100644
index 92be49c..0000000
--- a/deps/w32-pthreads/tests/benchtest1.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * benchtest1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Measure time taken to complete an elementary operation.
- *
- * - Mutex
- *   Single thread iteration over lock/unlock for each mutex type.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-#ifdef __GNUC__
-#include <stdlib.h>
-#endif
-
-#include "benchtest.h"
-
-#define PTW32_MUTEX_TYPES
-#define ITERATIONS      10000000L
-
-pthread_mutex_t mx;
-pthread_mutexattr_t ma;
-PTW32_STRUCT_TIMEB currSysTimeStart;
-PTW32_STRUCT_TIMEB currSysTimeStop;
-long durationMilliSecs;
-long overHeadMilliSecs = 0;
-int two = 2;
-int one = 1;
-int zero = 0;
-int iter;
-
-#define GetDurationMilliSecs(_TStart, _TStop) ((long)((_TStop.time*1000+_TStop.millitm) \
-                                               - (_TStart.time*1000+_TStart.millitm)))
-
-/*
- * Dummy use of j, otherwise the loop may be removed by the optimiser
- * when doing the overhead timing with an empty loop.
- */
-#define TESTSTART \
-  { int i, j = 0, k = 0; PTW32_FTIME(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
-
-#define TESTSTOP \
-  }; PTW32_FTIME(&currSysTimeStop); if (j + k == i) j++; }
-
-
-void
-runTest (char * testNameString, int mType)
-{
-#ifdef PTW32_MUTEX_TYPES
-  assert(pthread_mutexattr_settype(&ma, mType) == 0);
-#endif
-  assert(pthread_mutex_init(&mx, &ma) == 0);
-
-  TESTSTART
-  assert((pthread_mutex_lock(&mx),1) == one);
-  assert((pthread_mutex_unlock(&mx),2) == two);
-  TESTSTOP
-
-  assert(pthread_mutex_destroy(&mx) == 0);
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-
-  printf( "%-45s %15ld %15.3f\n",
-	    testNameString,
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int i = 0;
-  CRITICAL_SECTION cs;
-  old_mutex_t ox;
-  pthread_mutexattr_init(&ma);
-
-  printf( "=============================================================================\n");
-  printf( "\nLock plus unlock on an unlocked mutex.\n%ld iterations\n\n",
-          ITERATIONS);
-  printf( "%-45s %15s %15s\n",
-	    "Test",
-	    "Total(msec)",
-	    "average(usec)");
-  printf( "-----------------------------------------------------------------------------\n");
-
-  /*
-   * Time the loop overhead so we can subtract it from the actual test times.
-   */
-  TESTSTART
-  assert(1 == one);
-  assert(2 == two);
-  TESTSTOP
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  overHeadMilliSecs = durationMilliSecs;
-
-
-  TESTSTART
-  assert((dummy_call(&i), 1) == one);
-  assert((dummy_call(&i), 2) == two);
-  TESTSTOP
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-
-  printf( "%-45s %15ld %15.3f\n",
-	    "Dummy call x 2",
-          durationMilliSecs,
-          (float) (durationMilliSecs * 1E3 / ITERATIONS));
-
-
-  TESTSTART
-  assert((interlocked_inc_with_conditionals(&i), 1) == one);
-  assert((interlocked_dec_with_conditionals(&i), 2) == two);
-  TESTSTOP
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-
-  printf( "%-45s %15ld %15.3f\n",
-	    "Dummy call -> Interlocked with cond x 2",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-
-
-  TESTSTART
-  assert((InterlockedIncrement((LPLONG)&i), 1) == (LONG)one);
-  assert((InterlockedDecrement((LPLONG)&i), 2) == (LONG)two);
-  TESTSTOP
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-
-  printf( "%-45s %15ld %15.3f\n",
-	    "InterlockedOp x 2",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-
-
-  InitializeCriticalSection(&cs);
-
-  TESTSTART
-  assert((EnterCriticalSection(&cs), 1) == one);
-  assert((LeaveCriticalSection(&cs), 2) == two);
-  TESTSTOP
-
-  DeleteCriticalSection(&cs);
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-
-  printf( "%-45s %15ld %15.3f\n",
-	    "Simple Critical Section",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-
-
-  old_mutex_use = OLD_WIN32CS;
-  assert(old_mutex_init(&ox, NULL) == 0);
-
-  TESTSTART
-  assert(old_mutex_lock(&ox) == zero);
-  assert(old_mutex_unlock(&ox) == zero);
-  TESTSTOP
-
-  assert(old_mutex_destroy(&ox) == 0);
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-
-  printf( "%-45s %15ld %15.3f\n",
-	    "Old PT Mutex using a Critical Section (WNT)",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-
-
-  old_mutex_use = OLD_WIN32MUTEX;
-  assert(old_mutex_init(&ox, NULL) == 0);
-
-  TESTSTART
-  assert(old_mutex_lock(&ox) == zero);
-  assert(old_mutex_unlock(&ox) == zero);
-  TESTSTOP
-
-  assert(old_mutex_destroy(&ox) == 0);
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-
-  printf( "%-45s %15ld %15.3f\n",
-	    "Old PT Mutex using a Win32 Mutex (W9x)",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-
-  printf( ".............................................................................\n");
-
-  /*
-   * Now we can start the actual tests
-   */
-#ifdef PTW32_MUTEX_TYPES
-  runTest("PTHREAD_MUTEX_DEFAULT", PTHREAD_MUTEX_DEFAULT);
-
-  runTest("PTHREAD_MUTEX_NORMAL", PTHREAD_MUTEX_NORMAL);
-
-  runTest("PTHREAD_MUTEX_ERRORCHECK", PTHREAD_MUTEX_ERRORCHECK);
-
-  runTest("PTHREAD_MUTEX_RECURSIVE", PTHREAD_MUTEX_RECURSIVE);
-#else
-  runTest("Non-blocking lock", 0);
-#endif
-
-  printf( ".............................................................................\n");
-
-  pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST);
-
-#ifdef PTW32_MUTEX_TYPES
-  runTest("PTHREAD_MUTEX_DEFAULT (Robust)", PTHREAD_MUTEX_DEFAULT);
-
-  runTest("PTHREAD_MUTEX_NORMAL (Robust)", PTHREAD_MUTEX_NORMAL);
-
-  runTest("PTHREAD_MUTEX_ERRORCHECK (Robust)", PTHREAD_MUTEX_ERRORCHECK);
-
-  runTest("PTHREAD_MUTEX_RECURSIVE (Robust)", PTHREAD_MUTEX_RECURSIVE);
-#else
-  runTest("Non-blocking lock", 0);
-#endif
-
-  printf( "=============================================================================\n");
-
-  /*
-   * End of tests.
-   */
-
-  pthread_mutexattr_destroy(&ma);
-
-  one = i; /* Dummy assignment to avoid 'variable unused' warning */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/benchtest2.c b/deps/w32-pthreads/tests/benchtest2.c
deleted file mode 100644
index 488d9c1..0000000
--- a/deps/w32-pthreads/tests/benchtest2.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * benchtest1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Measure time taken to complete an elementary operation.
- *
- * - Mutex
- *   Two threads iterate over lock/unlock for each mutex type.
- *   The two threads are forced into lock-step using two mutexes,
- *   forcing the threads to block on each lock operation. The
- *   time measured is therefore the worst case senario.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-#ifdef __GNUC__
-#include <stdlib.h>
-#endif
-
-#include "benchtest.h"
-
-#define PTW32_MUTEX_TYPES
-#define ITERATIONS      100000L
-
-pthread_mutex_t gate1, gate2;
-old_mutex_t ox1, ox2;
-CRITICAL_SECTION cs1, cs2;
-pthread_mutexattr_t ma;
-long durationMilliSecs;
-long overHeadMilliSecs = 0;
-PTW32_STRUCT_TIMEB currSysTimeStart;
-PTW32_STRUCT_TIMEB currSysTimeStop;
-pthread_t worker;
-int running = 0;
-
-#define GetDurationMilliSecs(_TStart, _TStop) ((long)((_TStop.time*1000+_TStop.millitm) \
-                                               - (_TStart.time*1000+_TStart.millitm)))
-
-/*
- * Dummy use of j, otherwise the loop may be removed by the optimiser
- * when doing the overhead timing with an empty loop.
- */
-#define TESTSTART \
-  { int i, j = 0, k = 0; PTW32_FTIME(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
-
-#define TESTSTOP \
-  }; PTW32_FTIME(&currSysTimeStop); if (j + k == i) j++; }
-
-
-void *
-overheadThread(void * arg)
-{
-  do
-    {
-      sched_yield();
-    }
-  while (running);
-
-  return NULL;
-}
-
-
-void *
-oldThread(void * arg)
-{
-  do
-    {
-      (void) old_mutex_lock(&ox1);
-      (void) old_mutex_lock(&ox2);
-      (void) old_mutex_unlock(&ox1);
-      sched_yield();
-      (void) old_mutex_unlock(&ox2);
-    }
-  while (running);
-
-  return NULL;
-}
-
-void *
-workerThread(void * arg)
-{
-  do
-    {
-      (void) pthread_mutex_lock(&gate1);
-      (void) pthread_mutex_lock(&gate2);
-      (void) pthread_mutex_unlock(&gate1);
-      sched_yield();
-      (void) pthread_mutex_unlock(&gate2);
-    }
-  while (running);
-
-  return NULL;
-}
-
-void *
-CSThread(void * arg)
-{
-  do
-    {
-      EnterCriticalSection(&cs1);
-      EnterCriticalSection(&cs2);
-      LeaveCriticalSection(&cs1);
-      sched_yield();
-      LeaveCriticalSection(&cs2);
-    }
-  while (running);
-
-  return NULL;
-}
-
-void
-runTest (char * testNameString, int mType)
-{
-#ifdef PTW32_MUTEX_TYPES
-  assert(pthread_mutexattr_settype(&ma, mType) == 0);
-#endif
-  assert(pthread_mutex_init(&gate1, &ma) == 0);
-  assert(pthread_mutex_init(&gate2, &ma) == 0);
-  assert(pthread_mutex_lock(&gate1) == 0);
-  assert(pthread_mutex_lock(&gate2) == 0);
-  running = 1;
-  assert(pthread_create(&worker, NULL, workerThread, NULL) == 0);
-  TESTSTART
-  (void) pthread_mutex_unlock(&gate1);
-  sched_yield();
-  (void) pthread_mutex_unlock(&gate2);
-  (void) pthread_mutex_lock(&gate1);
-  (void) pthread_mutex_lock(&gate2);
-  TESTSTOP
-  running = 0;
-  assert(pthread_mutex_unlock(&gate2) == 0);
-  assert(pthread_mutex_unlock(&gate1) == 0);
-  assert(pthread_join(worker, NULL) == 0);
-  assert(pthread_mutex_destroy(&gate2) == 0);
-  assert(pthread_mutex_destroy(&gate1) == 0);
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  printf( "%-45s %15ld %15.3f\n",
-	    testNameString,
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS / 4   /* Four locks/unlocks per iteration */);
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  assert(pthread_mutexattr_init(&ma) == 0);
-
-  printf( "=============================================================================\n");
-  printf( "\nLock plus unlock on a locked mutex.\n");
-  printf("%ld iterations, four locks/unlocks per iteration.\n\n", ITERATIONS);
-
-  printf( "%-45s %15s %15s\n",
-	    "Test",
-	    "Total(msec)",
-	    "average(usec)");
-  printf( "-----------------------------------------------------------------------------\n");
-
-  /*
-   * Time the loop overhead so we can subtract it from the actual test times.
-   */
-
-  running = 1;
-  assert(pthread_create(&worker, NULL, overheadThread, NULL) == 0);
-  TESTSTART
-  sched_yield();
-  sched_yield();
-  TESTSTOP
-  running = 0;
-  assert(pthread_join(worker, NULL) == 0);
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  overHeadMilliSecs = durationMilliSecs;
-
-
-  InitializeCriticalSection(&cs1);
-  InitializeCriticalSection(&cs2);
-  EnterCriticalSection(&cs1);
-  EnterCriticalSection(&cs2);
-  running = 1;
-  assert(pthread_create(&worker, NULL, CSThread, NULL) == 0);
-  TESTSTART
-  LeaveCriticalSection(&cs1);
-  sched_yield();
-  LeaveCriticalSection(&cs2);
-  EnterCriticalSection(&cs1);
-  EnterCriticalSection(&cs2);
-  TESTSTOP
-  running = 0;
-  LeaveCriticalSection(&cs2);
-  LeaveCriticalSection(&cs1);
-  assert(pthread_join(worker, NULL) == 0);
-  DeleteCriticalSection(&cs2);
-  DeleteCriticalSection(&cs1);
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  printf( "%-45s %15ld %15.3f\n",
-	    "Simple Critical Section",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS / 4 );
-
-
-  old_mutex_use = OLD_WIN32CS;
-  assert(old_mutex_init(&ox1, NULL) == 0);
-  assert(old_mutex_init(&ox2, NULL) == 0);
-  assert(old_mutex_lock(&ox1) == 0);
-  assert(old_mutex_lock(&ox2) == 0);
-  running = 1;
-  assert(pthread_create(&worker, NULL, oldThread, NULL) == 0);
-  TESTSTART
-  (void) old_mutex_unlock(&ox1);
-  sched_yield();
-  (void) old_mutex_unlock(&ox2);
-  (void) old_mutex_lock(&ox1);
-  (void) old_mutex_lock(&ox2);
-  TESTSTOP
-  running = 0;
-  assert(old_mutex_unlock(&ox1) == 0);
-  assert(old_mutex_unlock(&ox2) == 0);
-  assert(pthread_join(worker, NULL) == 0);
-  assert(old_mutex_destroy(&ox2) == 0);
-  assert(old_mutex_destroy(&ox1) == 0);
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  printf( "%-45s %15ld %15.3f\n",
-	    "Old PT Mutex using a Critical Section (WNT)",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS / 4);
-
-
-  old_mutex_use = OLD_WIN32MUTEX;
-  assert(old_mutex_init(&ox1, NULL) == 0);
-  assert(old_mutex_init(&ox2, NULL) == 0);
-  assert(old_mutex_lock(&ox1) == 0);
-  assert(old_mutex_lock(&ox2) == 0);
-  running = 1;
-  assert(pthread_create(&worker, NULL, oldThread, NULL) == 0);
-  TESTSTART
-  (void) old_mutex_unlock(&ox1);
-  sched_yield();
-  (void) old_mutex_unlock(&ox2);
-  (void) old_mutex_lock(&ox1);
-  (void) old_mutex_lock(&ox2);
-  TESTSTOP
-  running = 0;
-  assert(old_mutex_unlock(&ox1) == 0);
-  assert(old_mutex_unlock(&ox2) == 0);
-  assert(pthread_join(worker, NULL) == 0);
-  assert(old_mutex_destroy(&ox2) == 0);
-  assert(old_mutex_destroy(&ox1) == 0);
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  printf( "%-45s %15ld %15.3f\n",
-	    "Old PT Mutex using a Win32 Mutex (W9x)",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS / 4);
-
-  printf( ".............................................................................\n");
-
-  /*
-   * Now we can start the actual tests
-   */
-#ifdef PTW32_MUTEX_TYPES
-  runTest("PTHREAD_MUTEX_DEFAULT", PTHREAD_MUTEX_DEFAULT);
-
-  runTest("PTHREAD_MUTEX_NORMAL", PTHREAD_MUTEX_NORMAL);
-
-  runTest("PTHREAD_MUTEX_ERRORCHECK", PTHREAD_MUTEX_ERRORCHECK);
-
-  runTest("PTHREAD_MUTEX_RECURSIVE", PTHREAD_MUTEX_RECURSIVE);
-#else
-  runTest("Non-blocking lock", 0);
-#endif
-
-  printf( ".............................................................................\n");
-
-  pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST);
-
-#ifdef PTW32_MUTEX_TYPES
-  runTest("PTHREAD_MUTEX_DEFAULT (Robust)", PTHREAD_MUTEX_DEFAULT);
-
-  runTest("PTHREAD_MUTEX_NORMAL (Robust)", PTHREAD_MUTEX_NORMAL);
-
-  runTest("PTHREAD_MUTEX_ERRORCHECK (Robust)", PTHREAD_MUTEX_ERRORCHECK);
-
-  runTest("PTHREAD_MUTEX_RECURSIVE (Robust)", PTHREAD_MUTEX_RECURSIVE);
-#else
-  runTest("Non-blocking lock", 0);
-#endif
-
-  printf( "=============================================================================\n");
-  /*
-   * End of tests.
-   */
-
-  pthread_mutexattr_destroy(&ma);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/benchtest3.c b/deps/w32-pthreads/tests/benchtest3.c
deleted file mode 100644
index e63aa6e..0000000
--- a/deps/w32-pthreads/tests/benchtest3.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * benchtest3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Measure time taken to complete an elementary operation.
- *
- * - Mutex
- *   Single thread iteration over a trylock on a locked mutex for each mutex type.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-#ifdef __GNUC__
-#include <stdlib.h>
-#endif
-
-#include "benchtest.h"
-
-#define PTW32_MUTEX_TYPES
-#define ITERATIONS      10000000L
-
-pthread_mutex_t mx;
-old_mutex_t ox;
-pthread_mutexattr_t ma;
-PTW32_STRUCT_TIMEB currSysTimeStart;
-PTW32_STRUCT_TIMEB currSysTimeStop;
-long durationMilliSecs;
-long overHeadMilliSecs = 0;
-
-#define GetDurationMilliSecs(_TStart, _TStop) ((long)((_TStop.time*1000+_TStop.millitm) \
-                                               - (_TStart.time*1000+_TStart.millitm)))
-
-/*
- * Dummy use of j, otherwise the loop may be removed by the optimiser
- * when doing the overhead timing with an empty loop.
- */
-#define TESTSTART \
-  { int i, j = 0, k = 0; PTW32_FTIME(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
-
-#define TESTSTOP \
-  }; PTW32_FTIME(&currSysTimeStop); if (j + k == i) j++; }
-
-
-void *
-trylockThread (void * arg)
-{
-  TESTSTART
-  (void) pthread_mutex_trylock(&mx);
-  TESTSTOP
-
-  return NULL;
-}
-
-
-void *
-oldTrylockThread (void * arg)
-{
-  TESTSTART
-  (void) old_mutex_trylock(&ox);
-  TESTSTOP
-
-  return NULL;
-}
-
-
-void
-runTest (char * testNameString, int mType)
-{
-  pthread_t t;
-
-#ifdef PTW32_MUTEX_TYPES
-  (void) pthread_mutexattr_settype(&ma, mType);
-#endif
-  assert(pthread_mutex_init(&mx, &ma) == 0);
-  assert(pthread_mutex_lock(&mx) == 0);
-  assert(pthread_create(&t, NULL, trylockThread, 0) == 0);
-  assert(pthread_join(t, NULL) == 0);
-  assert(pthread_mutex_unlock(&mx) == 0);
-  assert(pthread_mutex_destroy(&mx) == 0);
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-
-  printf( "%-45s %15ld %15.3f\n",
-	    testNameString,
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  pthread_t t;
-
-  assert(pthread_mutexattr_init(&ma) == 0);
-
-  printf( "=============================================================================\n");
-  printf( "\nTrylock on a locked mutex.\n");
-  printf( "%ld iterations.\n\n", ITERATIONS);
-  printf( "%-45s %15s %15s\n",
-	    "Test",
-	    "Total(msec)",
-	    "average(usec)");
-  printf( "-----------------------------------------------------------------------------\n");
-
-  /*
-   * Time the loop overhead so we can subtract it from the actual test times.
-   */
-
-  TESTSTART
-  TESTSTOP
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  overHeadMilliSecs = durationMilliSecs;
-
-
-  old_mutex_use = OLD_WIN32CS;
-  assert(old_mutex_init(&ox, NULL) == 0);
-  assert(old_mutex_lock(&ox) == 0);
-  assert(pthread_create(&t, NULL, oldTrylockThread, 0) == 0);
-  assert(pthread_join(t, NULL) == 0);
-  assert(old_mutex_unlock(&ox) == 0);
-  assert(old_mutex_destroy(&ox) == 0);
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  printf( "%-45s %15ld %15.3f\n",
-	    "Old PT Mutex using a Critical Section (WNT)",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-
-  old_mutex_use = OLD_WIN32MUTEX;
-  assert(old_mutex_init(&ox, NULL) == 0);
-  assert(old_mutex_lock(&ox) == 0);
-  assert(pthread_create(&t, NULL, oldTrylockThread, 0) == 0);
-  assert(pthread_join(t, NULL) == 0);
-  assert(old_mutex_unlock(&ox) == 0);
-  assert(old_mutex_destroy(&ox) == 0);
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  printf( "%-45s %15ld %15.3f\n",
-	    "Old PT Mutex using a Win32 Mutex (W9x)",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-
-  printf( ".............................................................................\n");
-
-  /*
-   * Now we can start the actual tests
-   */
-#ifdef PTW32_MUTEX_TYPES
-  runTest("PTHREAD_MUTEX_DEFAULT", PTHREAD_MUTEX_DEFAULT);
-
-  runTest("PTHREAD_MUTEX_NORMAL", PTHREAD_MUTEX_NORMAL);
-
-  runTest("PTHREAD_MUTEX_ERRORCHECK", PTHREAD_MUTEX_ERRORCHECK);
-
-  runTest("PTHREAD_MUTEX_RECURSIVE", PTHREAD_MUTEX_RECURSIVE);
-#else
-  runTest("Non-blocking lock", 0);
-#endif
-
-  printf( ".............................................................................\n");
-
-  pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST);
-
-#ifdef PTW32_MUTEX_TYPES
-  runTest("PTHREAD_MUTEX_DEFAULT (Robust)", PTHREAD_MUTEX_DEFAULT);
-
-  runTest("PTHREAD_MUTEX_NORMAL (Robust)", PTHREAD_MUTEX_NORMAL);
-
-  runTest("PTHREAD_MUTEX_ERRORCHECK (Robust)", PTHREAD_MUTEX_ERRORCHECK);
-
-  runTest("PTHREAD_MUTEX_RECURSIVE (Robust)", PTHREAD_MUTEX_RECURSIVE);
-#else
-  runTest("Non-blocking lock", 0);
-#endif
-
-  printf( "=============================================================================\n");
-
-  /*
-   * End of tests.
-   */
-
-  pthread_mutexattr_destroy(&ma);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/benchtest4.c b/deps/w32-pthreads/tests/benchtest4.c
deleted file mode 100644
index 073ed9e..0000000
--- a/deps/w32-pthreads/tests/benchtest4.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * benchtest4.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Measure time taken to complete an elementary operation.
- *
- * - Mutex
- *   Single thread iteration over trylock/unlock for each mutex type.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-#ifdef __GNUC__
-#include <stdlib.h>
-#endif
-
-#include "benchtest.h"
-
-#define PTW32_MUTEX_TYPES
-#define ITERATIONS      10000000L
-
-pthread_mutex_t mx;
-old_mutex_t ox;
-pthread_mutexattr_t ma;
-PTW32_STRUCT_TIMEB currSysTimeStart;
-PTW32_STRUCT_TIMEB currSysTimeStop;
-long durationMilliSecs;
-long overHeadMilliSecs = 0;
-
-#define GetDurationMilliSecs(_TStart, _TStop) ((long)((_TStop.time*1000+_TStop.millitm) \
-                                               - (_TStart.time*1000+_TStart.millitm)))
-
-/*
- * Dummy use of j, otherwise the loop may be removed by the optimiser
- * when doing the overhead timing with an empty loop.
- */
-#define TESTSTART \
-  { int i, j = 0, k = 0; PTW32_FTIME(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
-
-#define TESTSTOP \
-  }; PTW32_FTIME(&currSysTimeStop); if (j + k == i) j++; }
-
-
-void
-oldRunTest (char * testNameString, int mType)
-{
-}
-
-
-void
-runTest (char * testNameString, int mType)
-{
-#ifdef PTW32_MUTEX_TYPES
-  pthread_mutexattr_settype(&ma, mType);
-#endif
-  pthread_mutex_init(&mx, &ma);
-
-  TESTSTART
-  (void) pthread_mutex_trylock(&mx);
-  (void) pthread_mutex_unlock(&mx);
-  TESTSTOP
-
-  pthread_mutex_destroy(&mx);
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-
-  printf( "%-45s %15ld %15.3f\n",
-	    testNameString,
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  pthread_mutexattr_init(&ma);
-
-  printf( "=============================================================================\n");
-  printf( "Trylock plus unlock on an unlocked mutex.\n");
-  printf( "%ld iterations.\n\n", ITERATIONS);
-  printf( "%-45s %15s %15s\n",
-	    "Test",
-	    "Total(msec)",
-	    "average(usec)");
-  printf( "-----------------------------------------------------------------------------\n");
-
-  /*
-   * Time the loop overhead so we can subtract it from the actual test times.
-   */
-
-  TESTSTART
-  TESTSTOP
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  overHeadMilliSecs = durationMilliSecs;
-
-  old_mutex_use = OLD_WIN32CS;
-  assert(old_mutex_init(&ox, NULL) == 0);
-  TESTSTART
-  (void) old_mutex_trylock(&ox);
-  (void) old_mutex_unlock(&ox);
-  TESTSTOP
-  assert(old_mutex_destroy(&ox) == 0);
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  printf( "%-45s %15ld %15.3f\n",
-	    "Old PT Mutex using a Critical Section (WNT)",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-
-  old_mutex_use = OLD_WIN32MUTEX;
-  assert(old_mutex_init(&ox, NULL) == 0);
-  TESTSTART
-  (void) old_mutex_trylock(&ox);
-  (void) old_mutex_unlock(&ox);
-  TESTSTOP
-  assert(old_mutex_destroy(&ox) == 0);
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  printf( "%-45s %15ld %15.3f\n",
-	    "Old PT Mutex using a Win32 Mutex (W9x)",
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-
-  printf( ".............................................................................\n");
-
-  /*
-   * Now we can start the actual tests
-   */
-#ifdef PTW32_MUTEX_TYPES
-  runTest("PTHREAD_MUTEX_DEFAULT", PTHREAD_MUTEX_DEFAULT);
-
-  runTest("PTHREAD_MUTEX_NORMAL", PTHREAD_MUTEX_NORMAL);
-
-  runTest("PTHREAD_MUTEX_ERRORCHECK", PTHREAD_MUTEX_ERRORCHECK);
-
-  runTest("PTHREAD_MUTEX_RECURSIVE", PTHREAD_MUTEX_RECURSIVE);
-#else
-  runTest("Non-blocking lock", 0);
-#endif
-
-  printf( ".............................................................................\n");
-
-  pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST);
-
-#ifdef PTW32_MUTEX_TYPES
-  runTest("PTHREAD_MUTEX_DEFAULT (Robust)", PTHREAD_MUTEX_DEFAULT);
-
-  runTest("PTHREAD_MUTEX_NORMAL (Robust)", PTHREAD_MUTEX_NORMAL);
-
-  runTest("PTHREAD_MUTEX_ERRORCHECK (Robust)", PTHREAD_MUTEX_ERRORCHECK);
-
-  runTest("PTHREAD_MUTEX_RECURSIVE (Robust)", PTHREAD_MUTEX_RECURSIVE);
-#else
-  runTest("Non-blocking lock", 0);
-#endif
-
-  printf( "=============================================================================\n");
-
-  /*
-   * End of tests.
-   */
-
-  pthread_mutexattr_destroy(&ma);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/benchtest5.c b/deps/w32-pthreads/tests/benchtest5.c
deleted file mode 100644
index 368074b..0000000
--- a/deps/w32-pthreads/tests/benchtest5.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * benchtest5.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Measure time taken to complete an elementary operation.
- *
- * - Semaphore
- *   Single thread iteration over post/wait for a semaphore.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-#ifdef __GNUC__
-#include <stdlib.h>
-#endif
-
-#include "benchtest.h"
-
-#define ITERATIONS      1000000L
-
-sem_t sema;
-HANDLE w32sema;
-
-PTW32_STRUCT_TIMEB currSysTimeStart;
-PTW32_STRUCT_TIMEB currSysTimeStop;
-long durationMilliSecs;
-long overHeadMilliSecs = 0;
-int one = 1;
-int zero = 0;
-
-#define GetDurationMilliSecs(_TStart, _TStop) ((long)((_TStop.time*1000+_TStop.millitm) \
-                                               - (_TStart.time*1000+_TStart.millitm)))
-
-/*
- * Dummy use of j, otherwise the loop may be removed by the optimiser
- * when doing the overhead timing with an empty loop.
- */
-#define TESTSTART \
-  { int i, j = 0, k = 0; PTW32_FTIME(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
-
-#define TESTSTOP \
-  }; PTW32_FTIME(&currSysTimeStop); if (j + k == i) j++; }
-
-
-void
-reportTest (char * testNameString)
-{
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-
-  printf( "%-45s %15ld %15.3f\n",
-	    testNameString,
-          durationMilliSecs,
-          (float) durationMilliSecs * 1E3 / ITERATIONS);
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  printf( "=============================================================================\n");
-  printf( "\nOperations on a semaphore.\n%ld iterations\n\n",
-          ITERATIONS);
-  printf( "%-45s %15s %15s\n",
-	    "Test",
-	    "Total(msec)",
-	    "average(usec)");
-  printf( "-----------------------------------------------------------------------------\n");
-
-  /*
-   * Time the loop overhead so we can subtract it from the actual test times.
-   */
-
-  TESTSTART
-  assert(1 == one);
-  TESTSTOP
-
-  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
-  overHeadMilliSecs = durationMilliSecs;
-
-
-  /*
-   * Now we can start the actual tests
-   */
-  assert((w32sema = CreateSemaphore(NULL, (long) 0, (long) ITERATIONS, NULL)) != 0);
-  TESTSTART
-  assert((ReleaseSemaphore(w32sema, 1, NULL),1) == one);
-  TESTSTOP
-  assert(CloseHandle(w32sema) != 0);
-
-  reportTest("W32 Post with no waiters");
-
-
-  assert((w32sema = CreateSemaphore(NULL, (long) ITERATIONS, (long) ITERATIONS, NULL)) != 0);
-  TESTSTART
-  assert((WaitForSingleObject(w32sema, INFINITE),1) == one);
-  TESTSTOP
-  assert(CloseHandle(w32sema) != 0);
-
-  reportTest("W32 Wait without blocking");
-
-
-  assert(sem_init(&sema, 0, 0) == 0);
-  TESTSTART
-  assert((sem_post(&sema),1) == one);
-  TESTSTOP
-  assert(sem_destroy(&sema) == 0);
-
-  reportTest("POSIX Post with no waiters");
-
-
-  assert(sem_init(&sema, 0, ITERATIONS) == 0);
-  TESTSTART
-  assert((sem_wait(&sema),1) == one);
-  TESTSTOP
-  assert(sem_destroy(&sema) == 0);
-
-  reportTest("POSIX Wait without blocking");
-
-
-  printf( "=============================================================================\n");
-
-  /*
-   * End of tests.
-   */
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/cancel1.c b/deps/w32-pthreads/tests/cancel1.c
deleted file mode 100644
index b9d0d94..0000000
--- a/deps/w32-pthreads/tests/cancel1.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * File: cancel1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test setting cancel state and cancel type.
- * - 
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * - pthread_setcancelstate function
- * - pthread_setcanceltype function
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - pthread_create, pthread_self work.
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 2
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-void *
-mythread(void * arg)
-{
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* ... */
-  {
-    int oldstate;
-    int oldtype;
-
-    assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) == 0);
-    assert(oldstate == PTHREAD_CANCEL_ENABLE); /* Check default */
-    assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-    assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) == 0);
-    assert(pthread_setcancelstate(oldstate, &oldstate) == 0);
-    assert(oldstate == PTHREAD_CANCEL_DISABLE); /* Check setting */
-
-    assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype) == 0);
-    assert(oldtype == PTHREAD_CANCEL_DEFERRED); /* Check default */
-    assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0);
-    assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-    assert(pthread_setcanceltype(oldtype, &oldtype) == 0);
-    assert(oldtype == PTHREAD_CANCEL_ASYNCHRONOUS); /* Check setting */
-  }
-
-  return 0;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      failed = !threadbag[i].started;
-
-      if (failed)
-	{
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print ouput on failure.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      /* ... */
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/cancel2.c b/deps/w32-pthreads/tests/cancel2.c
deleted file mode 100644
index 95bd1e3..0000000
--- a/deps/w32-pthreads/tests/cancel2.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * File: cancel2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test SEH or C++ cancel exception handling within
- * application exception blocks.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-/*
- * Don't know how to identify if we are using SEH so it's only C++ for now
- */
-#if defined(__cplusplus)
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 4
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-static pthread_mutex_t waitLock = PTHREAD_MUTEX_INITIALIZER;
-
-void *
-mythread(void * arg)
-{
-  int result = 0;
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* Set to known state and type */
-
-  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  switch (bag->threadnum % 2)
-    {
-    case 0:
-      assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-      result = 0;
-      break;
-    case 1:
-      assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0);
-      result = 1;
-      break;
-    }
-
-#if !defined(__cplusplus)
-  __try
-#else
-  try
-#endif
-    {
-      /* Wait for go from main */
-      assert(pthread_mutex_lock(&waitLock) == 0);
-      assert(pthread_mutex_unlock(&waitLock) == 0);
-      sched_yield();
-
-      for (;;)
-	{
-	  pthread_testcancel();
-	}
-    }
-#if !defined(__cplusplus)
-  __except(EXCEPTION_EXECUTE_HANDLER)
-#else
-#if defined(PtW32CatchAll)
-  PtW32CatchAll
-#else
-  catch(...)
-#endif
-#endif
-    {
-      /*
-       * Should not get into here.
-       */
-      result += 100;
-    }
-
-  /* 
-   * Should not get to here either.
-   */
-  result += 1000;
-
-  return (void *) (size_t)result;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  assert((t[0] = pthread_self()).p != NULL);
-  assert(pthread_mutex_lock(&waitLock) == 0);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(500);
-
-  assert(pthread_mutex_unlock(&waitLock) == 0);
-
-  Sleep(500);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_cancel(t[i]) == 0);
-    }
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      void* result = (void*)0;
-
-      assert(pthread_join(t[i], &result) == 0);
-      fail = ((int)(size_t)result != (int) PTHREAD_CANCELED);
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: location %d: cancel type %s\n",
-		  i,
-		  threadbag[i].started,
-		  (int)(size_t)result,
-		  (((int)(size_t)result % 2) == 0) ? "ASYNCHRONOUS" : "DEFERRED");
-	}
-      failed |= fail;
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
-#else /* defined(__cplusplus) */
-
-#include <stdio.h>
-
-int
-main()
-{
-  fprintf(stderr, "Test N/A for this compiler environment.\n");
-  return 0;
-}
-
-#endif /* defined(__cplusplus) */
-
diff --git a/deps/w32-pthreads/tests/cancel3.c b/deps/w32-pthreads/tests/cancel3.c
deleted file mode 100644
index 5e89a32..0000000
--- a/deps/w32-pthreads/tests/cancel3.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * File: cancel3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test asynchronous cancelation (alertable or non-alertable).
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * - Async cancel if thread is not blocked (i.e. voluntarily resumes if blocked).
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join.
- * - quserex.dll and alertdrv.sys are not available.
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum
-{
-  NUMTHREADS = 4
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_
-{
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-void *
-mythread (void *arg)
-{
-  void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1);
-  bag_t *bag = (bag_t *) arg;
-
-  assert (bag == &threadbag[bag->threadnum]);
-  assert (bag->started == 0);
-  bag->started = 1;
-
-  /* Set to known state and type */
-
-  assert (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-
-  /*
-   * We wait up to 10 seconds, waking every 0.1 seconds,
-   * for a cancelation to be applied to us.
-   */
-  for (bag->count = 0; bag->count < 100; bag->count++)
-    Sleep (100);
-
-  return result;
-}
-
-int
-main ()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  assert ((t[0] = pthread_self ()).p != NULL);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert (pthread_create (&t[i], NULL, mythread, (void *) &threadbag[i])
-	      == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep (NUMTHREADS * 100);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert (pthread_cancel (t[i]) == 0);
-    }
-
-  /*
-   * Give threads time to complete.
-   */
-  Sleep (NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf (stderr, "Thread %d: started %d\n", i,
-		   threadbag[i].started);
-	}
-    }
-
-  assert (!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      void* result = (void*)0;
-
-      /*
-       * The thread does not contain any cancelation points, so
-       * a return value of PTHREAD_CANCELED confirms that async
-       * cancelation succeeded.
-       */
-      assert (pthread_join (t[i], &result) == 0);
-
-      fail = (result != PTHREAD_CANCELED);
-
-      if (fail)
-	{
-	  fprintf (stderr, "Thread %d: started %d: count %d\n",
-		   i, threadbag[i].started, threadbag[i].count);
-	}
-      failed = (failed || fail);
-    }
-
-  assert (!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/cancel4.c b/deps/w32-pthreads/tests/cancel4.c
deleted file mode 100644
index 972e2b8..0000000
--- a/deps/w32-pthreads/tests/cancel4.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * File: cancel4.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test cancelation does not occur in deferred
- *                cancelation threads with no cancelation points.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - pthread_create
- *   pthread_self
- *   pthread_cancel
- *   pthread_join
- *   pthread_setcancelstate
- *   pthread_setcanceltype
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 4
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-void *
-mythread(void * arg)
-{
-  void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1);
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* Set to known state and type */
-
-  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0);
-
-  /*
-   * We wait up to 2 seconds, waking every 0.1 seconds,
-   * for a cancelation to be applied to us.
-   */
-  for (bag->count = 0; bag->count < 20; bag->count++)
-    Sleep(100);
-
-  return result;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(500);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_cancel(t[i]) == 0);
-    }
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      void* result = (void*)0;
-
-      /*
-       * The thread does not contain any cancelation points, so
-       * a return value of PTHREAD_CANCELED indicates that async
-       * cancelation occurred.
-       */
-      assert(pthread_join(t[i], &result) == 0);
-
-      fail = (result == PTHREAD_CANCELED);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: count %d\n",
-		  i,
-		  threadbag[i].started,
-		  threadbag[i].count);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/cancel5.c b/deps/w32-pthreads/tests/cancel5.c
deleted file mode 100644
index 03c9da6..0000000
--- a/deps/w32-pthreads/tests/cancel5.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * File: cancel5.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test calling pthread_cancel from the main thread
- *                without calling pthread_self() in main.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum
-{
-  NUMTHREADS = 4
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_
-{
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-void *
-mythread (void *arg)
-{
-  void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1);
-  bag_t *bag = (bag_t *) arg;
-
-  assert (bag == &threadbag[bag->threadnum]);
-  assert (bag->started == 0);
-  bag->started = 1;
-
-  /* Set to known state and type */
-
-  assert (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-
-  /*
-   * We wait up to 10 seconds, waking every 0.1 seconds,
-   * for a cancelation to be applied to us.
-   */
-  for (bag->count = 0; bag->count < 100; bag->count++)
-    Sleep (100);
-
-  return result;
-}
-
-int
-main ()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert (pthread_create (&t[i], NULL, mythread, (void *) &threadbag[i])
-	      == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep (500);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert (pthread_cancel (t[i]) == 0);
-    }
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep (NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf (stderr, "Thread %d: started %d\n", i,
-		   threadbag[i].started);
-	}
-    }
-
-  assert (!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1);
-
-      /*
-       * The thread does not contain any cancelation points, so
-       * a return value of PTHREAD_CANCELED confirms that async
-       * cancelation succeeded.
-       */
-      assert (pthread_join (t[i], &result) == 0);
-
-      fail = (result != PTHREAD_CANCELED);
-
-      if (fail)
-	{
-	  fprintf (stderr, "Thread %d: started %d: count %d\n",
-		   i, threadbag[i].started, threadbag[i].count);
-	}
-      failed = (failed || fail);
-    }
-
-  assert (!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/cancel6a.c b/deps/w32-pthreads/tests/cancel6a.c
deleted file mode 100644
index ba22391..0000000
--- a/deps/w32-pthreads/tests/cancel6a.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * File: cancel6a.c
- *
- *
- * Pthreads-win32 - POSIX Threads Library for Win32
- * Copyright (C) 1998 Ben Elliston and Ross Johnson
- * Copyright (C) 1999,2000,2001 Ross Johnson
- *
- * Contact Email: rpj at ise.canberra.edu.au
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test double cancelation - asynchronous.
- * Second attempt should fail (ESRCH).
- *
- * Test Method (Validation or Falsification):
- * -
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 4
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-void *
-mythread(void * arg)
-{
-  void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1);
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* Set to known state and type */
-
-  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-
-  /*
-   * We wait up to 10 seconds, waking every 0.1 seconds,
-   * for a cancelation to be applied to us.
-   */
-  for (bag->count = 0; bag->count < 100; bag->count++)
-    Sleep(100);
-
-  return result;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(500);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_cancel(t[i]) == 0);
-      assert(pthread_cancel(t[i]) == ESRCH);
-    }
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      void* result = (void*)0;
-
-      /*
-       * The thread does not contain any cancelation points, so
-       * a return value of PTHREAD_CANCELED confirms that async
-       * cancelation succeeded.
-       */
-      assert(pthread_join(t[i], &result) == 0);
-
-      fail = (result != PTHREAD_CANCELED);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: count %d\n",
-		  i,
-		  threadbag[i].started,
-		  threadbag[i].count);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/cancel6d.c b/deps/w32-pthreads/tests/cancel6d.c
deleted file mode 100644
index 9c18d8b..0000000
--- a/deps/w32-pthreads/tests/cancel6d.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * File: cancel6d.c
- *
- *
- * Pthreads-win32 - POSIX Threads Library for Win32
- * Copyright (C) 1998 Ben Elliston and Ross Johnson
- * Copyright (C) 1999,2000,2001 Ross Johnson
- *
- * Contact Email: rpj at ise.canberra.edu.au
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test double cancelation - deferred.
- * Second attempt should succeed (unless the canceled thread has started
- * cancelation already - not tested here).
- *
- * Test Method (Validation or Falsification):
- * -
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 4
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-void *
-mythread(void * arg)
-{
-  void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1);
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* Set to known state and type */
-
-  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0);
-
-  /*
-   * We wait up to 10 seconds, waking every 0.1 seconds,
-   * for a cancelation to be applied to us.
-   */
-  for (bag->count = 0; bag->count < 100; bag->count++)
-    {
-      Sleep(100);
-      pthread_testcancel();
-    }
-
-  return result;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *)(size_t) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(500);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_cancel(t[i]) == 0);
-      if (pthread_cancel(t[i]) != 0)
-        {
-          printf("Second cancelation failed but this is expected sometimes.\n");
-        }
-    }
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      void* result = (void*)0;
-
-      assert(pthread_join(t[i], &result) == 0);
-
-      fail = (result != PTHREAD_CANCELED);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: count %d\n",
-		  i,
-		  threadbag[i].started,
-		  threadbag[i].count);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/cancel7.c b/deps/w32-pthreads/tests/cancel7.c
deleted file mode 100644
index 0132b38..0000000
--- a/deps/w32-pthreads/tests/cancel7.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * File: cancel7.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test canceling a Win32 thread having created an
- * implicit POSIX handle for it.
- *
- * Test Method (Validation or Falsification):
- * - Validate return value and that POSIX handle is created and destroyed.
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#ifndef _UWIN
-#include <process.h>
-#endif
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 4
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-  pthread_t self;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-unsigned __stdcall
-#else
-void
-#endif
-Win32thread(void * arg)
-{
-  int i;
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  assert((bag->self = pthread_self()).p != NULL);
-  assert(pthread_kill(bag->self, 0) == 0);
-
-  for (i = 0; i < 100; i++)
-    {
-      Sleep(100);
-      pthread_testcancel();
-    }
-
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-  return 0;
-#endif
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  HANDLE h[NUMTHREADS + 1];
-  unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-      h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr);
-#else
-      h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]);
-#endif
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(500);
-
-  /*
-   * Cancel all threads.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_kill(threadbag[i].self, 0) == 0);
-      assert(pthread_cancel(threadbag[i].self) == 0);
-    }
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      int result = 0;
-
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-      assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE);
-#else
-      /*
-       * Can't get a result code.
-       */
-      result = (int)(size_t)PTHREAD_CANCELED;
-#endif
-
-      assert(threadbag[i].self.p != NULL);
-      assert(pthread_kill(threadbag[i].self, 0) == ESRCH);
-
-      fail = (result != (int)(size_t)PTHREAD_CANCELED);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: count %d\n",
-		  i,
-		  threadbag[i].started,
-		  threadbag[i].count);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/cancel8.c b/deps/w32-pthreads/tests/cancel8.c
deleted file mode 100644
index d7799fb..0000000
--- a/deps/w32-pthreads/tests/cancel8.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * File: cancel8.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test cancelling a blocked Win32 thread having created an
- * implicit POSIX handle for it.
- *
- * Test Method (Validation or Falsification):
- * - Validate return value and that POSIX handle is created and destroyed.
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#ifndef _UWIN
-#include <process.h>
-#endif
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 4
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-  pthread_t self;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-pthread_cond_t CV = PTHREAD_COND_INITIALIZER;
-pthread_mutex_t CVLock = PTHREAD_MUTEX_INITIALIZER;
-
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-unsigned __stdcall
-#else
-void
-#endif
-Win32thread(void * arg)
-{
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  assert((bag->self = pthread_self()).p != NULL);
-  assert(pthread_kill(bag->self, 0) == 0);
-
-  assert(pthread_mutex_lock(&CVLock) == 0);
-  pthread_cleanup_push(pthread_mutex_unlock, &CVLock);
-  pthread_cond_wait(&CV, &CVLock);
-  pthread_cleanup_pop(1);
-
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-  return 0;
-#endif
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  HANDLE h[NUMTHREADS + 1];
-  unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-      h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr);
-#else
-      h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]);
-#endif
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(500);
-
-  /*
-   * Cancel all threads.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_kill(threadbag[i].self, 0) == 0);
-      assert(pthread_cancel(threadbag[i].self) == 0);
-    }
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      int result = 0;
-
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-      assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE);
-#else
-      /*
-       * Can't get a result code.
-       */
-      result = (int)(size_t)PTHREAD_CANCELED;
-#endif
-
-      assert(threadbag[i].self.p != NULL);
-      assert(pthread_kill(threadbag[i].self, 0) == ESRCH);
-
-      fail = (result != (int)(size_t)PTHREAD_CANCELED);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: count %d\n",
-		  i,
-		  threadbag[i].started,
-		  threadbag[i].count);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/cancel9.c b/deps/w32-pthreads/tests/cancel9.c
deleted file mode 100644
index ab28aec..0000000
--- a/deps/w32-pthreads/tests/cancel9.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * File: cancel9.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test true asynchronous cancelation with Alert driver.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * - Cancel threads, including those blocked on system recources
- *   such as network I/O.
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#include <windows.h>
-
-
-void *
-test_udp (void *arg)
-{
-  struct sockaddr_in serverAddress;
-  struct sockaddr_in clientAddress;
-  SOCKET UDPSocket;
-  int addr_len;
-  int nbyte, bytes;
-  char buffer[4096];
-  WORD wsaVersion = MAKEWORD (2, 2);
-  WSADATA wsaData;
-
-  pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
-  pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
-
-  if (WSAStartup (wsaVersion, &wsaData) != 0)
-    {
-      return NULL;
-    }
-
-  UDPSocket = socket (AF_INET, SOCK_DGRAM, 0);
-  if ((int)UDPSocket == -1)
-    {
-      printf ("Server: socket ERROR \n");
-      exit (-1);
-    }
-
-  serverAddress.sin_family = AF_INET;
-  serverAddress.sin_addr.s_addr = INADDR_ANY;
-  serverAddress.sin_port = htons (9003);
-
-  if (bind
-      (UDPSocket, (struct sockaddr *) &serverAddress,
-       sizeof (struct sockaddr_in)))
-    {
-      printf ("Server: ERROR can't bind UDPSocket");
-      exit (-1);
-    }
-
-  addr_len = sizeof (struct sockaddr);
-
-  nbyte = 512;
-
-  bytes =
-    recvfrom (UDPSocket, (char *) buffer, nbyte, 0,
-	      (struct sockaddr *) &clientAddress, &addr_len);
-
-  closesocket (UDPSocket);
-  WSACleanup ();
-
-  return NULL;
-}
-
-
-void *
-test_sleep (void *arg)
-{
-  pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
-  pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
-
-  Sleep (1000);
-  return NULL;
-
-}
-
-void *
-test_wait (void *arg)
-{
-  HANDLE hEvent;
-  DWORD dwEvent;
-
-  pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
-  pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
-
-  hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
-
-  dwEvent = WaitForSingleObject (hEvent, 1000);	/* WAIT_IO_COMPLETION */
-
-  return NULL;
-}
-
-
-int
-main ()
-{
-  pthread_t t;
-  void *result;
-
-  if (pthread_win32_test_features_np (PTW32_ALERTABLE_ASYNC_CANCEL))
-    {
-      printf ("Cancel sleeping thread.\n");
-      assert (pthread_create (&t, NULL, test_sleep, NULL) == 0);
-      /* Sleep for a while; then cancel */
-      Sleep (100);
-      assert (pthread_cancel (t) == 0);
-      assert (pthread_join (t, &result) == 0);
-      assert (result == PTHREAD_CANCELED && "test_sleep" != NULL);
-
-      printf ("Cancel waiting thread.\n");
-      assert (pthread_create (&t, NULL, test_wait, NULL) == 0);
-      /* Sleep for a while; then cancel. */
-      Sleep (100);
-      assert (pthread_cancel (t) == 0);
-      assert (pthread_join (t, &result) == 0);
-      assert (result == PTHREAD_CANCELED && "test_wait");
-
-      printf ("Cancel blocked thread (blocked on network I/O).\n");
-      assert (pthread_create (&t, NULL, test_udp, NULL) == 0);
-      /* Sleep for a while; then cancel. */
-      Sleep (100);
-      assert (pthread_cancel (t) == 0);
-      assert (pthread_join (t, &result) == 0);
-      assert (result == PTHREAD_CANCELED && "test_udp" != NULL);
-    }
-  else
-    {
-      printf ("Alertable async cancel not available.\n");
-    }
-
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/cleanup0.c b/deps/w32-pthreads/tests/cleanup0.c
deleted file mode 100644
index 8303064..0000000
--- a/deps/w32-pthreads/tests/cleanup0.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * File: cleanup1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test cleanup handler executes (when thread is not canceled).
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#if defined(_MSC_VER) || defined(__cplusplus)
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 10
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-typedef struct {
-  int i;
-  CRITICAL_SECTION cs;
-} sharedInt_t;
-
-static sharedInt_t pop_count = {0, {0}};
-
-static void
-increment_pop_count(void * arg)
-{
-  sharedInt_t * sI = (sharedInt_t *) arg;
-
-  EnterCriticalSection(&sI->cs);
-  sI->i++;
-  LeaveCriticalSection(&sI->cs);
-}
-
-void *
-mythread(void * arg)
-{
-  int result = 0;
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* Set to known state and type */
-
-  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-
-#ifdef _MSC_VER
-#pragma inline_depth(0)
-#endif
-  pthread_cleanup_push(increment_pop_count, (void *) &pop_count);
-
-  Sleep(100);
-
-  pthread_cleanup_pop(1);
-#ifdef _MSC_VER
-#pragma inline_depth()
-#endif
-
-  return (void *) (size_t)result;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  InitializeCriticalSection(&pop_count.cs);
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(500);
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      void* result = (void*)0;
-
-      assert(pthread_join(t[i], &result) == 0);
-
-      fail = ((int)(size_t)result == (int) PTHREAD_CANCELED);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: result %d\n",
-		  i,
-		  threadbag[i].started,
-		(int)(size_t)result);
-	  fflush(stderr);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  assert(pop_count.i == NUMTHREADS);
-
-  DeleteCriticalSection(&pop_count.cs);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
-#else /* defined(_MSC_VER) || defined(__cplusplus) */
-
-int
-main()
-{
-  return 0;
-}
-
-#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/deps/w32-pthreads/tests/cleanup1.c b/deps/w32-pthreads/tests/cleanup1.c
deleted file mode 100644
index 4ddd5d0..0000000
--- a/deps/w32-pthreads/tests/cleanup1.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * File: cleanup1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test cleanup handler executes (when thread is canceled).
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#if defined(_MSC_VER) || defined(__cplusplus)
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 10
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-typedef struct {
-  int i;
-  CRITICAL_SECTION cs;
-} sharedInt_t;
-
-static sharedInt_t pop_count = {0, {0}};
-
-static void
-#ifdef __CLEANUP_C
-__cdecl
-#endif
-increment_pop_count(void * arg)
-{
-  sharedInt_t * sI = (sharedInt_t *) arg;
-
-  EnterCriticalSection(&sI->cs);
-  sI->i++;
-  LeaveCriticalSection(&sI->cs);
-}
-
-void *
-mythread(void * arg)
-{
-  int result = 0;
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* Set to known state and type */
-
-  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-
-#ifdef _MSC_VER
-#pragma inline_depth(0)
-#endif
-  pthread_cleanup_push(increment_pop_count, (void *) &pop_count);
-  /*
-   * We don't have true async cancelation - it relies on the thread
-   * at least re-entering the run state at some point.
-   * We wait up to 10 seconds, waking every 0.1 seconds,
-   * for a cancelation to be applied to us.
-   */
-  for (bag->count = 0; bag->count < 100; bag->count++)
-    Sleep(100);
-
-  pthread_cleanup_pop(0);
-#ifdef _MSC_VER
-#pragma inline_depth()
-#endif
-
-  return (void *) (size_t)result;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  InitializeCriticalSection(&pop_count.cs);
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(500);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_cancel(t[i]) == 0);
-    }
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      void* result = (void*)0;
-
-      assert(pthread_join(t[i], &result) == 0);
-
-      fail = ((int)(size_t)result != (int) PTHREAD_CANCELED);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: result %d\n",
-		  i,
-		  threadbag[i].started,
-		  (int)(size_t)result);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  assert(pop_count.i == NUMTHREADS);
-
-  DeleteCriticalSection(&pop_count.cs);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
-#else /* defined(_MSC_VER) || defined(__cplusplus) */
-
-int
-main()
-{
-  return 0;
-}
-
-#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/deps/w32-pthreads/tests/cleanup2.c b/deps/w32-pthreads/tests/cleanup2.c
deleted file mode 100644
index b167490..0000000
--- a/deps/w32-pthreads/tests/cleanup2.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * File: cleanup2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test cleanup handler executes (when thread is not canceled).
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#if defined(_MSC_VER) || defined(__cplusplus)
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 10
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-typedef struct {
-  int i;
-  CRITICAL_SECTION cs;
-} sharedInt_t;
-
-static sharedInt_t pop_count = {0, {0}};
-
-static void
-increment_pop_count(void * arg)
-{
-  sharedInt_t * sI = (sharedInt_t *) arg;
-
-  EnterCriticalSection(&sI->cs);
-  sI->i++;
-  LeaveCriticalSection(&sI->cs);
-}
-
-void *
-mythread(void * arg)
-{
-  int result = 0;
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-#ifdef _MSC_VER
-#pragma inline_depth(0)
-#endif
-  pthread_cleanup_push(increment_pop_count, (void *) &pop_count);
-
-  sched_yield();
-
-  pthread_cleanup_pop(1);
-#ifdef _MSC_VER
-#pragma inline_depth()
-#endif
-
-  return (void *) (size_t)result;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  InitializeCriticalSection(&pop_count.cs);
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(1000);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      void* result = (void*)0;
-
-      assert(pthread_join(t[i], &result) == 0);
-
-      fail = ((int)(size_t)result != 0);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: result: %d\n",
-		  i,
-		  threadbag[i].started,
-		  (int)(size_t)result);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  assert(pop_count.i == NUMTHREADS);
-
-  DeleteCriticalSection(&pop_count.cs);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
-#else /* defined(_MSC_VER) || defined(__cplusplus) */
-
-int
-main()
-{
-  return 0;
-}
-
-#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/deps/w32-pthreads/tests/cleanup3.c b/deps/w32-pthreads/tests/cleanup3.c
deleted file mode 100644
index 37f5168..0000000
--- a/deps/w32-pthreads/tests/cleanup3.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * File: cleanup3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test cleanup handler does not execute (when thread is
- * not canceled).
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#if defined(_MSC_VER) || defined(__cplusplus)
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 10
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-typedef struct {
-  int i;
-  CRITICAL_SECTION cs;
-} sharedInt_t;
-
-static sharedInt_t pop_count = {0, {0}};
-
-static void
-increment_pop_count(void * arg)
-{
-  sharedInt_t * sI = (sharedInt_t *) arg;
-
-  EnterCriticalSection(&sI->cs);
-  sI->i++;
-  LeaveCriticalSection(&sI->cs);
-}
-
-void *
-mythread(void * arg)
-{
-  int result = 0;
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-#ifdef _MSC_VER
-#pragma inline_depth(0)
-#endif
-  pthread_cleanup_push(increment_pop_count, (void *) &pop_count);
-
-  sched_yield();
-
-  EnterCriticalSection(&pop_count.cs);
-  pop_count.i--;
-  LeaveCriticalSection(&pop_count.cs);
-
-  pthread_cleanup_pop(0);
-#ifdef _MSC_VER
-#pragma inline_depth()
-#endif
-
-  return (void *) (size_t)result;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  InitializeCriticalSection(&pop_count.cs);
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(1000);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      void* result = (void*)0;
-
-      assert(pthread_join(t[i], &result) == 0);
-
-      fail = ((int)(size_t)result != 0);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: result: %d\n",
-		  i,
-		  threadbag[i].started,
-		  (int)(size_t)result);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  assert(pop_count.i == -(NUMTHREADS));
-
-  DeleteCriticalSection(&pop_count.cs);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
-#else /* defined(_MSC_VER) || defined(__cplusplus) */
-
-int
-main()
-{
-  return 0;
-}
-
-#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/deps/w32-pthreads/tests/condvar1.c b/deps/w32-pthreads/tests/condvar1.c
deleted file mode 100644
index da0c7af..0000000
--- a/deps/w32-pthreads/tests/condvar1.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * File: condvar1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test initialisation and destruction of a CV.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Creates and then imediately destroys a CV. Does not
- *   test the CV.
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - pthread_cond_init returns 0, and
- * - pthread_cond_destroy returns 0.
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - pthread_cond_init returns non-zero, or
- * - pthread_cond_destroy returns non-zero.
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-static pthread_cond_t cv = NULL;
-
-int
-main()
-{
-  assert(cv == NULL);
-
-  assert(pthread_cond_init(&cv, NULL) == 0);
-
-  assert(cv != NULL);
-
-  assert(pthread_cond_destroy(&cv) == 0);
-
-  assert(cv == NULL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar1_1.c b/deps/w32-pthreads/tests/condvar1_1.c
deleted file mode 100644
index 12bf85f..0000000
--- a/deps/w32-pthreads/tests/condvar1_1.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * File: condvar1_1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test CV linked list management.
- *
- * Test Method (Validation or Falsification):
- * - Validation:
- *   Initiate and destroy several CVs in random order.
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Creates and then imediately destroys a CV. Does not
- *   test the CV.
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - All initialised CVs destroyed without segfault.
- * - Successfully broadcasts all remaining CVs after
- *   each CV is removed.
- *
- * Fail Criteria:
- */
-
-#include <stdlib.h>
-#include "test.h"
-
-enum {
-  NUM_CV = 100
-};
-
-static pthread_cond_t cv[NUM_CV];
-
-int
-main()
-{
-  int i, j;
-
-  for (i = 0; i < NUM_CV; i++)
-    {
-      /* Traverse the list before every init of a CV. */
-      assert(pthread_timechange_handler_np(NULL) == (void *) 0);
-      assert(pthread_cond_init(&cv[i], NULL) == 0);
-    }
-
-  j = NUM_CV;
-  (void) srand((unsigned)time(NULL));
-
-  do
-    {
-      i = (NUM_CV - 1) * rand() / RAND_MAX;
-      if (cv[i] != NULL)
-        {
-          j--;
-          assert(pthread_cond_destroy(&cv[i]) == 0);
-          /* Traverse the list every time we remove a CV. */
-          assert(pthread_timechange_handler_np(NULL) == (void *) 0);
-        }
-    }
-  while (j > 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar1_2.c b/deps/w32-pthreads/tests/condvar1_2.c
deleted file mode 100644
index 8a591a0..0000000
--- a/deps/w32-pthreads/tests/condvar1_2.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * File: condvar1_2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test CV linked list management and serialisation.
- *
- * Test Method (Validation or Falsification):
- * - Validation:
- *   Initiate and destroy several CVs in random order.
- *   Asynchronously traverse the CV list and broadcast.
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Creates and then imediately destroys a CV. Does not
- *   test the CV.
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - All initialised CVs destroyed without segfault.
- * - Successfully broadcasts all remaining CVs after
- *   each CV is removed.
- *
- * Fail Criteria:
- */
-
-#include <stdlib.h>
-#include "test.h"
-
-enum {
-  NUM_CV = 5,
-  NUM_LOOPS = 5
-};
-
-static pthread_cond_t cv[NUM_CV];
-
-int
-main()
-{
-  int i, j, k;
-  void* result = (void*)-1;
-  pthread_t t;
-
-  for (k = 0; k < NUM_LOOPS; k++)
-    {
-      for (i = 0; i < NUM_CV; i++)
-        {
-          assert(pthread_cond_init(&cv[i], NULL) == 0);
-        }
-
-      j = NUM_CV;
-      (void) srand((unsigned)time(NULL));
-
-      /* Traverse the list asynchronously. */
-      assert(pthread_create(&t, NULL, pthread_timechange_handler_np, NULL) == 0);
-
-      do
-        {
-          i = (NUM_CV - 1) * rand() / RAND_MAX;
-          if (cv[i] != NULL)
-            {
-              j--;
-              assert(pthread_cond_destroy(&cv[i]) == 0);
-            }
-        }
-      while (j > 0);
-
-      assert(pthread_join(t, &result) == 0);
-      assert ((int)(size_t)result == 0);
-    }
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar2.c b/deps/w32-pthreads/tests/condvar2.c
deleted file mode 100644
index 159f777..0000000
--- a/deps/w32-pthreads/tests/condvar2.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * File: condvar2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test timed wait on a CV.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Because the CV is never signaled, we expect the wait to time out.
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - pthread_cond_timedwait returns ETIMEDOUT.
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - pthread_cond_timedwait does not return ETIMEDOUT.
- * - Process returns non-zero exit status.
- */
-
-#define _WIN32_WINNT 0x400
-
-#include "test.h"
-#include <sys/timeb.h>
-
-pthread_cond_t cv;
-pthread_mutex_t mutex;
-
-#include "../implement.h"
-
-int
-main()
-{
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  assert(pthread_cond_init(&cv, NULL) == 0);
-
-  assert(pthread_mutex_init(&mutex, NULL) == 0);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  /* get current system time */
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 1;
-
-  assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == ETIMEDOUT);
-  
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  {
-  int result = pthread_cond_destroy(&cv);
-  if (result != 0)
-    {
-      fprintf(stderr, "Result = %s\n", error_string[result]);
-	fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked);
-	fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone);
-	fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock);
-	fflush(stderr);
-    }
-  assert(result == 0);
-  }
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar2_1.c b/deps/w32-pthreads/tests/condvar2_1.c
deleted file mode 100644
index 6b3fdd6..0000000
--- a/deps/w32-pthreads/tests/condvar2_1.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * File: condvar2_1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test timeout of multiple waits on a CV with no signal/broadcast.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Because the CV is never signaled, we expect the waits to time out.
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - pthread_cond_timedwait returns ETIMEDOUT.
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - pthread_cond_timedwait does not return ETIMEDOUT.
- * - Process returns non-zero exit status.
- */
-
-#define _WIN32_WINNT 0x400
-
-#include "test.h"
-#include <sys/timeb.h>
-
-static pthread_cond_t cv;
-static pthread_mutex_t mutex;
-static struct timespec abstime = { 0, 0 };
-
-enum {
-  NUMTHREADS = 30
-};
-
-void *
-mythread(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == ETIMEDOUT);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return arg;
-}
-
-#include "../implement.h"
-
-int
-main()
-{
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-  void* result = (void*)0;
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  assert(pthread_cond_init(&cv, NULL) == 0);
-
-  assert(pthread_mutex_init(&mutex, NULL) == 0);
-
-  /* get current system time */
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 5;
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_create(&t[i], NULL, mythread, (void *)(size_t)i) == 0);
-    }
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_join(t[i], &result) == 0);
-	assert((int)(size_t)result == i);
-    }
-
-  {
-  int result = pthread_cond_destroy(&cv);
-  if (result != 0)
-    {
-      fprintf(stderr, "Result = %s\n", error_string[result]);
-	fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked);
-	fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone);
-	fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock);
-	fflush(stderr);
-    }
-  assert(result == 0);
-  }
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar3.c b/deps/w32-pthreads/tests/condvar3.c
deleted file mode 100644
index fea8d21..0000000
--- a/deps/w32-pthreads/tests/condvar3.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * File: condvar3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test basic function of a CV
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - The primary thread takes the lock before creating any threads.
- *   The secondary thread blocks on the lock allowing the primary
- *   thread to enter the cv wait state which releases the lock.
- *   The secondary thread then takes the lock and signals the waiting
- *   primary thread.
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - pthread_cond_timedwait returns 0.
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - pthread_cond_timedwait returns ETIMEDOUT.
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-static pthread_cond_t cv;
-static pthread_mutex_t mutex;
-static int shared = 0;
-
-enum {
-  NUMTHREADS = 2         /* Including the primary thread. */
-};
-
-void *
-mythread(void * arg)
-{
-  int result = 0;
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-  shared++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  if ((result = pthread_cond_signal(&cv)) != 0)
-    {
-      printf("Error = %s\n", error_string[result]);
-    }
-  assert(result == 0);
-
-
-  return (void *) 0;
-}
-
-int
-main()
-{
-  pthread_t t[NUMTHREADS];
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  assert(pthread_cond_init(&cv, NULL) == 0);
-
-  assert(pthread_mutex_init(&mutex, NULL) == 0);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  /* get current system time */
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0);
-
-  abstime.tv_sec += 5;
-
-  while (! (shared > 0))
-    assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == 0);
-
-  assert(shared > 0);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  assert(pthread_join(t[1], NULL) == 0);
-
-  assert(pthread_cond_destroy(&cv) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar3_1.c b/deps/w32-pthreads/tests/condvar3_1.c
deleted file mode 100644
index f4cf9cc..0000000
--- a/deps/w32-pthreads/tests/condvar3_1.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * File: condvar3_1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test timeout of multiple waits on a CV with some signaled.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Because some CVs are never signaled, we expect their waits to time out.
- *   Some are signaled, the rest time out. Pthread_cond_destroy() will fail
- *   unless all are accounted for, either signaled or timedout.
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - pthread_cond_timedwait returns ETIMEDOUT.
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - pthread_cond_timedwait does not return ETIMEDOUT.
- * - Process returns non-zero exit status.
- */
-
-#define _WIN32_WINNT 0x400
-
-#include "test.h"
-#include <sys/timeb.h>
-
-static pthread_cond_t cv;
-static pthread_cond_t cv1;
-static pthread_mutex_t mutex;
-static pthread_mutex_t mutex1;
-static struct timespec abstime = { 0, 0 };
-static int timedout = 0;
-static int signaled = 0;
-static int awoken = 0;
-static int waiting = 0;
-
-enum {
-  NUMTHREADS = 30
-};
-
-void *
-mythread(void * arg)
-{
-  int result;
-
-  assert(pthread_mutex_lock(&mutex1) == 0);
-  ++waiting;
-  assert(pthread_mutex_unlock(&mutex1) == 0);
-  assert(pthread_cond_signal(&cv1) == 0);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-  result = pthread_cond_timedwait(&cv, &mutex, &abstime);
-  if (result == ETIMEDOUT)
-    {
-      timedout++;
-    }
-  else
-    {
-      awoken++;
-    }
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return arg;
-}
-
-#include "../implement.h"
-
-int
-main()
-{
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-  void* result = (void*)0;
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  assert(pthread_cond_init(&cv, NULL) == 0);
-  assert(pthread_cond_init(&cv1, NULL) == 0);
-
-  assert(pthread_mutex_init(&mutex, NULL) == 0);
-  assert(pthread_mutex_init(&mutex1, NULL) == 0);
-
-  /* get current system time */
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 5;
-
-  assert(pthread_mutex_lock(&mutex1) == 0);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_create(&t[i], NULL, mythread, (void *)(size_t)i) == 0);
-    }
-
-  do {
-    assert(pthread_cond_wait(&cv1,&mutex1) == 0);
-  } while ( NUMTHREADS > waiting );
-
-  assert(pthread_mutex_unlock(&mutex1) == 0);
-
-  for (i = NUMTHREADS/3; i <= 2*NUMTHREADS/3; i++)
-    {
-//      assert(pthread_mutex_lock(&mutex) == 0);
-      assert(pthread_cond_signal(&cv) == 0);
-//      assert(pthread_mutex_unlock(&mutex) == 0);
-
-      signaled++;
-    }
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_join(t[i], &result) == 0);
-        assert((int)(size_t)result == i);
-    }
-
-      fprintf(stderr, "awk = %d\n", awoken);
-      fprintf(stderr, "sig = %d\n", signaled);
-      fprintf(stderr, "tot = %d\n", timedout);
-
-  assert(signaled == awoken);
-  assert(timedout == NUMTHREADS - signaled);
-
-  assert(pthread_cond_destroy(&cv1) == 0);
-
-  {
-  int result = pthread_cond_destroy(&cv);
-  if (result != 0)
-    {
-      fprintf(stderr, "Result = %s\n", error_string[result]);
-        fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked);
-        fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone);
-        fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock);
-        fflush(stderr);
-    }
-  assert(result == 0);
-  }
-
-  assert(pthread_mutex_destroy(&mutex1) == 0);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar3_2.c b/deps/w32-pthreads/tests/condvar3_2.c
deleted file mode 100644
index 4a90959..0000000
--- a/deps/w32-pthreads/tests/condvar3_2.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * File: condvar3_2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test timeout of multiple waits on a CV with remainder broadcast awoken.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Because some CVs are never signaled, we expect their waits to time out.
- *   Some time out, the rest are broadcast signaled. Pthread_cond_destroy() will fail
- *   unless all are accounted for, either signaled or timedout.
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - pthread_cond_timedwait returns ETIMEDOUT.
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - pthread_cond_timedwait does not return ETIMEDOUT.
- * - Process returns non-zero exit status.
- */
-
-#define _WIN32_WINNT 0x400
-
-#include "test.h"
-#include <sys/timeb.h>
-
-static pthread_cond_t cv;
-static pthread_mutex_t mutex;
-static struct timespec abstime = { 0, 0 };
-static struct timespec abstime2 = { 0, 0 };
-static int timedout = 0;
-static int awoken = 0;
-
-enum {
-  NUMTHREADS = 30
-};
-
-void *
-mythread(void * arg)
-{
-  int result;
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  abstime2.tv_sec = abstime.tv_sec;
-
-  if ((int) (size_t)arg % 3 == 0)
-    {
-      abstime2.tv_sec += 2;
-    }
-
-  result = pthread_cond_timedwait(&cv, &mutex, &abstime2);
-  assert(pthread_mutex_unlock(&mutex) == 0);
-  if (result == ETIMEDOUT)
-    {
-      InterlockedIncrement((LPLONG)&timedout);
-    }
-  else
-    {
-      InterlockedIncrement((LPLONG)&awoken);
-    }
-
-
-  return arg;
-}
-
-#include "../implement.h"
-
-int
-main()
-{
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-  void* result = (void*)0;
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  assert(pthread_cond_init(&cv, NULL) == 0);
-
-  assert(pthread_mutex_init(&mutex, NULL) == 0);
-
-  /* get current system time */
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = abstime2.tv_sec = (long)currSysTime.time + 5;
-  abstime.tv_nsec = abstime2.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_create(&t[i], NULL, mythread, (void *)(size_t)i) == 0);
-    }
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_join(t[i], &result) == 0);
-	assert((int)(size_t)result == i);
-      /*
-       * Approximately 2/3rds of the threads are expected to time out.
-       * Signal the remainder after some threads have woken up and exited
-       * and while some are still waking up after timeout.
-       * Also tests that redundant broadcasts don't return errors.
-       */
-
-//      assert(pthread_mutex_lock(&mutex) == 0);
-
-      if (InterlockedExchangeAdd((LPLONG)&awoken, 0L) > NUMTHREADS/3)
-        {
-          assert(pthread_cond_broadcast(&cv) == 0);
-        }
-
-//      assert(pthread_mutex_unlock(&mutex) == 0);
-
-    }
-
-  assert(awoken == NUMTHREADS - timedout);
-
-  {
-  int result = pthread_cond_destroy(&cv);
-  if (result != 0)
-    {
-      fprintf(stderr, "Result = %s\n", error_string[result]);
-	fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked);
-	fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone);
-	fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock);
-	fflush(stderr);
-    }
-  assert(result == 0);
-  }
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar3_3.c b/deps/w32-pthreads/tests/condvar3_3.c
deleted file mode 100644
index bc479a5..0000000
--- a/deps/w32-pthreads/tests/condvar3_3.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * File: condvar3_3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test timeouts and lost signals on a CV.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - pthread_cond_timedwait returns ETIMEDOUT.
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - pthread_cond_timedwait does not return ETIMEDOUT.
- * - Process returns non-zero exit status.
- */
-
-/* Timur Aydin (taydin at snet.net) */
-
-#include "test.h"
-
-#include <sys/timeb.h>
-
-pthread_cond_t cnd;
-pthread_mutex_t mtx;
-
-int main()
-{
-   int rc;
-
-   struct timespec abstime = { 0, 0 };
-   PTW32_STRUCT_TIMEB currSysTime;
-   const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-   assert(pthread_cond_init(&cnd, 0) == 0);
-   assert(pthread_mutex_init(&mtx, 0) == 0);
-
-   /* get current system time */
-   PTW32_FTIME(&currSysTime);
-
-   abstime.tv_sec = (long)currSysTime.time;
-   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-   abstime.tv_sec += 1;
-
-   /* Here pthread_cond_timedwait should time out after one second. */
-
-   assert(pthread_mutex_lock(&mtx) == 0);
-
-   assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT);
-
-   assert(pthread_mutex_unlock(&mtx) == 0);
-
-   /* Here, the condition variable is signaled, but there are no
-      threads waiting on it. The signal should be lost and
-      the next pthread_cond_timedwait should time out too. */
-
-//   assert(pthread_mutex_lock(&mtx) == 0);
-
-   assert((rc = pthread_cond_signal(&cnd)) == 0);
-
-//   assert(pthread_mutex_unlock(&mtx) == 0);
-
-   assert(pthread_mutex_lock(&mtx) == 0);
-
-   abstime.tv_sec = (long)currSysTime.time;
-   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-   abstime.tv_sec += 1;
-
-   assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT);
-
-   assert(pthread_mutex_unlock(&mtx) == 0);
-
-   return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar4.c b/deps/w32-pthreads/tests/condvar4.c
deleted file mode 100644
index 15a47e0..0000000
--- a/deps/w32-pthreads/tests/condvar4.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * File: condvar4.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test PTHREAD_COND_INITIALIZER.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Test basic CV function but starting with a static initialised
- *   CV.
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - pthread_cond_timedwait returns 0.
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - pthread_cond_timedwait returns ETIMEDOUT.
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-typedef struct cvthing_t_ cvthing_t;
-
-struct cvthing_t_ {
-  pthread_cond_t notbusy;
-  pthread_mutex_t lock;
-  int shared;
-};
-
-static cvthing_t cvthing = {
-  PTHREAD_COND_INITIALIZER,
-  PTHREAD_MUTEX_INITIALIZER,
-  0
-};
-
-enum {
-  NUMTHREADS = 2
-};
-
-void *
-mythread(void * arg)
-{
-  assert(pthread_mutex_lock(&cvthing.lock) == 0);
-  cvthing.shared++;
-  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-  assert(pthread_cond_signal(&cvthing.notbusy) == 0);
-
-  return (void *) 0;
-}
-
-int
-main()
-{
-  pthread_t t[NUMTHREADS];
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  cvthing.shared = 0;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
-
-  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
-
-  assert(pthread_mutex_lock(&cvthing.lock) == 0);
-
-  assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER);
-
-  /* get current system time */
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 5;
-
-  assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT);
-  
-  assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER);
-
-  assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0);
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 5;
-
-  while (! (cvthing.shared > 0))
-    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
-
-  assert(cvthing.shared > 0);
-
-  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-  assert(pthread_join(t[1], NULL) == 0);
-
-  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
-
-  assert(cvthing.lock == NULL);
-
-  assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
-
-  assert(cvthing.notbusy == NULL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar5.c b/deps/w32-pthreads/tests/condvar5.c
deleted file mode 100644
index e8d00e3..0000000
--- a/deps/w32-pthreads/tests/condvar5.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * File: condvar5.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test pthread_cond_broadcast.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Test broadcast with one waiting CV.
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - pthread_cond_timedwait returns 0.
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - pthread_cond_timedwait returns ETIMEDOUT.
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-typedef struct cvthing_t_ cvthing_t;
-
-struct cvthing_t_ {
-  pthread_cond_t notbusy;
-  pthread_mutex_t lock;
-  int shared;
-};
-
-static cvthing_t cvthing = {
-  PTHREAD_COND_INITIALIZER,
-  PTHREAD_MUTEX_INITIALIZER,
-  0
-};
-
-enum {
-  NUMTHREADS = 2
-};
-
-void *
-mythread(void * arg)
-{
-  assert(pthread_mutex_lock(&cvthing.lock) == 0);
-  cvthing.shared++;
-  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-  assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
-
-  return (void *) 0;
-}
-
-int
-main()
-{
-  pthread_t t[NUMTHREADS];
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  cvthing.shared = 0;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
-
-  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
-
-  assert(pthread_mutex_lock(&cvthing.lock) == 0);
-
-  assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER);
-
-  /* get current system time */
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 5;
-
-  assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT);
-  
-  assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER);
-
-  assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0);
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 5;
-
-  while (! (cvthing.shared > 0))
-    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
-
-  assert(cvthing.shared > 0);
-
-  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-  assert(pthread_join(t[1], NULL) == 0);
-
-  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
-
-  assert(cvthing.lock == NULL);
-
-  assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
-
-  assert(cvthing.notbusy == NULL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar6.c b/deps/w32-pthreads/tests/condvar6.c
deleted file mode 100644
index fc0047b..0000000
--- a/deps/w32-pthreads/tests/condvar6.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * File: condvar6.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test pthread_cond_broadcast.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Test broadcast with NUMTHREADS (=5) waiting CVs.
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 5
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-typedef struct cvthing_t_ cvthing_t;
-
-struct cvthing_t_ {
-  pthread_cond_t notbusy;
-  pthread_mutex_t lock;
-  int shared;
-};
-
-static cvthing_t cvthing = {
-  PTHREAD_COND_INITIALIZER,
-  PTHREAD_MUTEX_INITIALIZER,
-  0
-};
-
-static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
-
-static struct timespec abstime = { 0, 0 };
-
-static int awoken;
-
-void *
-mythread(void * arg)
-{
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* Wait for the start gun */
-  assert(pthread_mutex_lock(&start_flag) == 0);
-  assert(pthread_mutex_unlock(&start_flag) == 0);
-
-  assert(pthread_mutex_lock(&cvthing.lock) == 0);
-
-  while (! (cvthing.shared > 0))
-    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
-
-  assert(cvthing.shared > 0);
-
-  awoken++;
-
-  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-  return (void *) 0;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  cvthing.shared = 0;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
-
-  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
-
-  assert(pthread_mutex_lock(&start_flag) == 0);
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 5;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  awoken = 0;
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-
-  assert(pthread_mutex_unlock(&start_flag) == 0);
-
-  /*
-   * Give threads time to start.
-   */
-  Sleep(1000);
-
-  assert(pthread_mutex_lock(&cvthing.lock) == 0);
-  cvthing.shared++;
-  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-  assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
-
-  /*
-   * Give threads time to complete.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_join(t[i], NULL) == 0);
-    }
-
-  /* 
-   * Cleanup the CV.
-   */
-  
-  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
-
-  assert(cvthing.lock == NULL);
-
-  assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
-
-  assert(cvthing.notbusy == NULL);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      failed = !threadbag[i].started;
-
-      if (failed)
-	{
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here.
-   */
-
-  assert(awoken == NUMTHREADS);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
-
diff --git a/deps/w32-pthreads/tests/condvar7.c b/deps/w32-pthreads/tests/condvar7.c
deleted file mode 100644
index d42d1d0..0000000
--- a/deps/w32-pthreads/tests/condvar7.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * File: condvar7.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test pthread_cond_broadcast with thread cancelation.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Test broadcast with NUMTHREADS (=5) waiting CVs, one is canceled while waiting.
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 5
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-typedef struct cvthing_t_ cvthing_t;
-
-struct cvthing_t_ {
-  pthread_cond_t notbusy;
-  pthread_mutex_t lock;
-  int shared;
-};
-
-static cvthing_t cvthing = {
-  PTHREAD_COND_INITIALIZER,
-  PTHREAD_MUTEX_INITIALIZER,
-  0
-};
-
-static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
-
-static struct timespec abstime = { 0, 0 };
-
-static int awoken;
-
-void *
-mythread(void * arg)
-{
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* Wait for the start gun */
-  assert(pthread_mutex_lock(&start_flag) == 0);
-  assert(pthread_mutex_unlock(&start_flag) == 0);
-
-  assert(pthread_mutex_lock(&cvthing.lock) == 0);
-
-#ifdef _MSC_VER
-#pragma inline_depth(0)
-#endif
-  pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock);
-
-  while (! (cvthing.shared > 0))
-    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
-
-  pthread_cleanup_pop(0);
-#ifdef _MSC_VER
-#pragma inline_depth()
-#endif
-
-  assert(cvthing.shared > 0);
-
-  awoken++;
-
-  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-  return (void *) 0;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  cvthing.shared = 0;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
-
-  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
-
-  assert(pthread_mutex_lock(&start_flag) == 0);
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (time_t)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 10;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  awoken = 0;
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-
-  assert(pthread_mutex_unlock(&start_flag) == 0);
-
-  /*
-   * Give threads time to start.
-   */
-  Sleep(1000);
-
-  /*
-   * Cancel one of the threads.
-   */
-  assert(pthread_cancel(t[1]) == 0);
-  assert(pthread_join(t[1], NULL) == 0);
-
-  assert(pthread_mutex_lock(&cvthing.lock) == 0);
-  cvthing.shared++;
-  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-  /*
-   * Signal all remaining waiting threads.
-   */
-  assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
-
-  /*
-   * Wait for all threads to complete.
-   */
-  for (i = 2; i <= NUMTHREADS; i++)
-    assert(pthread_join(t[i], NULL) == 0);
-
-  /* 
-   * Cleanup the CV.
-   */
-  
-  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
-
-  assert(cvthing.lock == NULL);
-
-  assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
-
-  assert(cvthing.notbusy == NULL);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      failed = !threadbag[i].started;
-
-      if (failed)
-	{
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here.
-   */
-
-  assert(awoken == (NUMTHREADS - 1));
-
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar8.c b/deps/w32-pthreads/tests/condvar8.c
deleted file mode 100644
index 3155c2d..0000000
--- a/deps/w32-pthreads/tests/condvar8.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * File: condvar8.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test multiple pthread_cond_broadcasts.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Make NUMTHREADS threads wait on CV, broadcast signal them, and then repeat.
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 5
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-typedef struct cvthing_t_ cvthing_t;
-
-struct cvthing_t_ {
-  pthread_cond_t notbusy;
-  pthread_mutex_t lock;
-  int shared;
-};
-
-static cvthing_t cvthing = {
-  PTHREAD_COND_INITIALIZER,
-  PTHREAD_MUTEX_INITIALIZER,
-  0
-};
-
-static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
-
-static struct timespec abstime = { 0, 0 };
-
-static int awoken;
-
-static void *
-mythread(void * arg)
-{
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* Wait for the start gun */
-  assert(pthread_mutex_lock(&start_flag) == 0);
-  assert(pthread_mutex_unlock(&start_flag) == 0);
-
-  assert(pthread_mutex_lock(&cvthing.lock) == 0);
-
-#ifdef _MSC_VER
-#pragma inline_depth(0)
-#endif
-  pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock);
-
-  while (! (cvthing.shared > 0))
-    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
-
-  pthread_cleanup_pop(0);
-#ifdef _MSC_VER
-#pragma inline_depth()
-#endif
-
-  assert(cvthing.shared > 0);
-
-  awoken++;
-
-  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-  return (void *) 0;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  int first, last;
-  pthread_t t[NUMTHREADS + 1];
-
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
-
-  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 10;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  awoken = 0;
-
-  for (first = 1, last = NUMTHREADS / 2;
-       first < NUMTHREADS;
-       first = last + 1, last = NUMTHREADS)
-    {
-      assert(pthread_mutex_lock(&start_flag) == 0);
-
-      for (i = first; i <= last; i++)
-	{
-	  threadbag[i].started = 0;
-	  threadbag[i].threadnum = i;
-	  assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-	}
-
-      /*
-       * Code to control or munipulate child threads should probably go here.
-       */
-      cvthing.shared = 0;
-
-      assert(pthread_mutex_unlock(&start_flag) == 0);
-
-      /*
-       * Give threads time to start.
-       */
-      Sleep(100);
-
-      assert(pthread_mutex_lock(&cvthing.lock) == 0);
-      cvthing.shared++;
-      assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-      assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
-
-      /*
-       * Give threads time to complete.
-       */
-      for (i = first; i <= last; i++)
-	{
-	  assert(pthread_join(t[i], NULL) == 0);
-	}
-
-      assert(awoken == (i - 1));
-    }
-
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      failed = !threadbag[i].started;
-
-      if (failed)
-	{
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  /* 
-   * Cleanup the CV.
-   */
-  
-  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
-
-  assert(cvthing.lock == NULL);
-
-  assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
-
-  assert(cvthing.notbusy == NULL);
-
-  assert(!failed);
-
-  /*
-   * Check any results here.
-   */
-
-  assert(awoken == NUMTHREADS);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/condvar9.c b/deps/w32-pthreads/tests/condvar9.c
deleted file mode 100644
index 97286e6..0000000
--- a/deps/w32-pthreads/tests/condvar9.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * File: condvar9.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test multiple pthread_cond_broadcasts with thread cancelation.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - Make NUMTHREADS threads wait on CV, cancel one, broadcast signal them,
- *   and then repeat.
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 9
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  int finished;
-  /* Add more per-thread state variables here */
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-typedef struct cvthing_t_ cvthing_t;
-
-struct cvthing_t_ {
-  pthread_cond_t notbusy;
-  pthread_mutex_t lock;
-  int shared;
-};
-
-static cvthing_t cvthing = {
-  PTHREAD_COND_INITIALIZER,
-  PTHREAD_MUTEX_INITIALIZER,
-  0
-};
-
-static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
-
-static struct timespec abstime = { 0, 0 };
-
-static int awoken;
-
-static void *
-mythread(void * arg)
-{
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* Wait for the start gun */
-  assert(pthread_mutex_lock(&start_flag) == 0);
-  assert(pthread_mutex_unlock(&start_flag) == 0);
-
-  assert(pthread_mutex_lock(&cvthing.lock) == 0);
-
-  /*
-   * pthread_cond_timedwait is a cancelation point and we're
-   * going to cancel some threads deliberately.
-   */
-#ifdef _MSC_VER
-#pragma inline_depth(0)
-#endif
-  pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock);
-
-  while (! (cvthing.shared > 0))
-    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
-
-  pthread_cleanup_pop(0);
-#ifdef _MSC_VER
-#pragma inline_depth()
-#endif
-
-  assert(cvthing.shared > 0);
-
-  awoken++;
-  bag->finished = 1;
-
-  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-  return (void *) 0;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  int first, last;
-  int canceledThreads = 0;
-  pthread_t t[NUMTHREADS + 1];
-
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
-
-  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 5;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  awoken = 0;
-
-  for (first = 1, last = NUMTHREADS / 2;
-       first < NUMTHREADS;
-       first = last + 1, last = NUMTHREADS)
-    {
-      int ct;
-
-      assert(pthread_mutex_lock(&start_flag) == 0);
-
-      for (i = first; i <= last; i++)
-	{
-	  threadbag[i].started = threadbag[i].finished = 0;
-	  threadbag[i].threadnum = i;
-	  assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-	}
-
-      /*
-       * Code to control or munipulate child threads should probably go here.
-       */
-      cvthing.shared = 0;
-
-      assert(pthread_mutex_unlock(&start_flag) == 0);
-
-      /*
-       * Give threads time to start.
-       */
-      Sleep(1000);
-
-      ct = (first + last) / 2;
-      assert(pthread_cancel(t[ct]) == 0);
-      canceledThreads++;
-      assert(pthread_join(t[ct], NULL) == 0);
-
-      assert(pthread_mutex_lock(&cvthing.lock) == 0);
-      cvthing.shared++;
-      assert(pthread_mutex_unlock(&cvthing.lock) == 0);
-
-      assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
-
-      /*
-       * Standard check that all threads started - and wait for them to finish.
-       */
-      for (i = first; i <= last; i++)
-	{ 
-	  failed = !threadbag[i].started;
-
-          if (failed)
-	    {
-	      fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	    }
-	  else
-	    {
-	      assert(pthread_join(t[i], NULL) == 0 || threadbag[i].finished == 0);
-//	      fprintf(stderr, "Thread %d: finished %d\n", i, threadbag[i].finished);
-	    }
-	}
-    }
-
-  /* 
-   * Cleanup the CV.
-   */
-
-  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
-
-  assert(cvthing.lock == NULL);
-
-  assert_e(pthread_cond_destroy(&cvthing.notbusy), ==, 0);
-
-  assert(cvthing.notbusy == NULL);
-
-  assert(!failed);
-
-  /*
-   * Check any results here.
-   */
-
-  assert(awoken == NUMTHREADS - canceledThreads);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/context1.c b/deps/w32-pthreads/tests/context1.c
deleted file mode 100644
index 6f4daa9..0000000
--- a/deps/w32-pthreads/tests/context1.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * File: context1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test context switching method.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - pthread_create
- *   pthread_exit
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#define _WIN32_WINNT 0x400
-
-#include "test.h"
-#include "../implement.h"
-#include "../context.h"
-
-static int washere = 0;
-
-static void * func(void * arg)
-{
-  washere = 1;
-
-  Sleep(1000);
-
-  return 0; 
-}
-
-static void
-anotherEnding ()
-{
-  /*
-   * Switched context
-   */
-  washere++;
-
-  pthread_exit(0);
-}
-
-int
-main()
-{
-  pthread_t t;
-  HANDLE hThread;
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-
-  hThread = ((ptw32_thread_t *)t.p)->threadH;
-
-  Sleep(500);
-
-  SuspendThread(hThread);
-
-  if (WaitForSingleObject(hThread, 0) == WAIT_TIMEOUT) 
-    {
-      /*
-       * Ok, thread did not exit before we got to it.
-       */
-      CONTEXT context;
-
-      context.ContextFlags = CONTEXT_CONTROL;
-
-      GetThreadContext(hThread, &context);
-      PTW32_PROGCTR (context) = (DWORD_PTR) anotherEnding;
-      SetThreadContext(hThread, &context);
-      ResumeThread(hThread);
-    }
-  else
-    {
-      printf("Exited early\n");
-      fflush(stdout);
-    }
-
-  Sleep(1000);
-
-  assert(washere == 2);
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/count1.c b/deps/w32-pthreads/tests/count1.c
deleted file mode 100644
index 16ecef1..0000000
--- a/deps/w32-pthreads/tests/count1.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * count1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Description:
- * Test some basic assertions about the number of threads at runtime.
- */
-
-#include "test.h"
-
-#define NUMTHREADS (30)
-
-static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_t threads[NUMTHREADS];
-static unsigned numThreads = 0;
-
-void *
-myfunc(void *arg)
-{
-  pthread_mutex_lock(&lock);
-  numThreads++;
-  pthread_mutex_unlock(&lock);
-
-  Sleep(1000);
-  return 0;
-}
-int
-main()
-{
-  int i;
-  int maxThreads = sizeof(threads) / sizeof(pthread_t);
-
-  /*
-   * Spawn NUMTHREADS threads. Each thread should increment the
-   * numThreads variable, sleep for one second.
-   */
-  for (i = 0; i < maxThreads; i++)
-    {
-      assert(pthread_create(&threads[i], NULL, myfunc, 0) == 0);
-    }
-  
-  /*
-   * Wait for all the threads to exit.
-   */
-  for (i = 0; i < maxThreads; i++)
-    {
-      assert(pthread_join(threads[i], NULL) == 0);
-    }
-
-  /* 
-   * Check the number of threads created.
-   */
-  assert((int) numThreads == maxThreads);
-  
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/create1.c b/deps/w32-pthreads/tests/create1.c
deleted file mode 100644
index bf7a1cb..0000000
--- a/deps/w32-pthreads/tests/create1.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * create1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Description:
- * Create a thread and check that it ran.
- *
- * Depends on API functions: None.
- */
-
-#include "test.h"
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  washere = 1;
-  return 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-
-  /* A dirty hack, but we cannot rely on pthread_join in this
-     primitive test. */
-  Sleep(2000);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/create2.c b/deps/w32-pthreads/tests/create2.c
deleted file mode 100644
index f3fd3c0..0000000
--- a/deps/w32-pthreads/tests/create2.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * File: create2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test that threads have a Win32 handle when started.
- *
- * Test Method (Validation or Falsification):
- * - Statistical, not absolute (depends on sample size).
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * -
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-enum {
-  NUMTHREADS = 10000
-};
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  washere = 1;
-  return (void *) 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-  pthread_attr_t attr;
-  void * result = NULL;
-  int i;
-
-  pthread_attr_init(&attr);
-  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      washere = 0;
-      assert(pthread_create(&t, &attr, func, NULL) == 0);
-      assert(pthread_join(t, &result) == 0);
-      assert((int)(size_t)result == 0);
-      assert(washere == 1);
-    }
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/create3.c b/deps/w32-pthreads/tests/create3.c
deleted file mode 100644
index c8a4323..0000000
--- a/deps/w32-pthreads/tests/create3.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * File: create3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test passing arg to thread function.
- *
- * Test Method (Validation or Falsification):
- * - Statistical, not absolute (depends on sample size).
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * -
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-enum {
-  NUMTHREADS = 10000
-};
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  washere = (int)(size_t)arg;
-  return (void *) 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-  pthread_attr_t attr;
-  void * result = NULL;
-  int i;
-
-  pthread_attr_init(&attr);
-  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      washere = 0;
-      assert(pthread_create(&t, &attr, func, (void *)(size_t)1) == 0);
-      assert(pthread_join(t, &result) == 0);
-      assert((int)(size_t)result == 0);
-      assert(washere == 1);
-    }
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/delay1.c b/deps/w32-pthreads/tests/delay1.c
deleted file mode 100644
index e8a7d5f..0000000
--- a/deps/w32-pthreads/tests/delay1.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * delay1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Depends on API functions:
- *    pthread_delay_np
- */
-
-#include "test.h"
-
-int
-main(int argc, char * argv[])
-{
-  struct timespec interval = {1L, 500000000L};
-
-  assert(pthread_delay_np(&interval) == 0);
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/delay2.c b/deps/w32-pthreads/tests/delay2.c
deleted file mode 100644
index bc933f4..0000000
--- a/deps/w32-pthreads/tests/delay2.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * delay1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Depends on API functions:
- *    pthread_delay_np
- */
-
-#include "test.h"
-
-pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;
-
-void *
-func(void * arg)
-{
-  struct timespec interval = {5, 500000000L};
-
-  assert(pthread_mutex_lock(&mx) == 0);
-
-#ifdef _MSC_VER
-#pragma inline_depth(0)
-#endif
-  pthread_cleanup_push(pthread_mutex_unlock, &mx);
-  assert(pthread_delay_np(&interval) == 0);
-  pthread_cleanup_pop(1);
-#ifdef _MSC_VER
-#pragma inline_depth()
-#endif
-
-  return (void *)(size_t)1;
-}
-
-int
-main(int argc, char * argv[])
-{
-  pthread_t t;
-  void* result = (void*)0;
-
-  assert(pthread_mutex_lock(&mx) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-  assert(pthread_cancel(t) == 0);
-
-  assert(pthread_mutex_unlock(&mx) == 0);
-
-  assert(pthread_join(t, &result) == 0);
-  assert(result == (void*)PTHREAD_CANCELED);
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/detach1.c b/deps/w32-pthreads/tests/detach1.c
deleted file mode 100644
index 3f219fd..0000000
--- a/deps/w32-pthreads/tests/detach1.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Test for pthread_detach().
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Depends on API functions: pthread_create(), pthread_detach(), pthread_exit().
- */
-
-#include "test.h"
-
-
-enum {
-  NUMTHREADS = 100
-};
-
-void *
-func(void * arg)
-{
-    int i = (int)(size_t)arg;
-
-    Sleep(i * 10);
-
-    pthread_exit(arg);
-
-    /* Never reached. */
-    exit(1);
-}
-
-int
-main(int argc, char * argv[])
-{
-	pthread_t id[NUMTHREADS];
-	int i;
-
-	/* Create a few threads and then exit. */
-	for (i = 0; i < NUMTHREADS; i++)
-	  {
-	    assert(pthread_create(&id[i], NULL, func, (void *)(size_t)i) == 0);
-	  }
-
-	/* Some threads will finish before they are detached, some after. */
-	Sleep(NUMTHREADS/2 * 10 + 50);
-
-	for (i = 0; i < NUMTHREADS; i++)
-	  {
-	    assert(pthread_detach(id[i]) == 0);
-	  }
-
-	Sleep(NUMTHREADS * 10 + 100);
-
-	/*
-	 * Check that all threads are now invalid.
-	 * This relies on unique thread IDs - e.g. works with
-	 * pthreads-w32 or Solaris, but may not work for Linux, BSD etc.
-	 */
-	for (i = 0; i < NUMTHREADS; i++)
-	  {
-	    assert(pthread_kill(id[i], 0) == ESRCH);
-	  }
-
-	/* Success. */
-	return 0;
-}
diff --git a/deps/w32-pthreads/tests/equal1.c b/deps/w32-pthreads/tests/equal1.c
deleted file mode 100644
index 3f5cad7..0000000
--- a/deps/w32-pthreads/tests/equal1.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Test for pthread_equal.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Depends on functions: pthread_create().
- */
-
-#include "test.h"
-
-void * func(void * arg)
-{
-  Sleep(2000);
-  return 0;
-}
-
-int 
-main()
-{
-  pthread_t t1, t2;
-
-  assert(pthread_create(&t1, NULL, func, (void *) 1) == 0);
-
-  assert(pthread_create(&t2, NULL, func, (void *) 2) == 0);
-
-  assert(pthread_equal(t1, t2) == 0);
-
-  assert(pthread_equal(t1,t1) != 0);
-
-  /* This is a hack. We don't want to rely on pthread_join
-     yet if we can help it. */
-   Sleep(4000);
-
-  /* Success. */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/errno1.c b/deps/w32-pthreads/tests/errno1.c
deleted file mode 100644
index 53558bd..0000000
--- a/deps/w32-pthreads/tests/errno1.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * File: errno1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test thread-safety of errno
- * - 
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 3
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-pthread_mutex_t stop_here = PTHREAD_MUTEX_INITIALIZER;
-
-void *
-mythread(void * arg)
-{
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  errno = bag->threadnum;
-
-  Sleep(1000);
-
-  pthread_mutex_lock(&stop_here);
-
-  assert(errno == bag->threadnum);
-
-  pthread_mutex_unlock(&stop_here);
-
-  Sleep(1000);
-
-  return 0;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  pthread_mutex_lock(&stop_here);
-  errno = 0;
-
-  assert((t[0] = pthread_self()).p != NULL);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(2000);
-  pthread_mutex_unlock(&stop_here);
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 1000);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      failed = !threadbag[i].started;
-
-      if (failed)
-	{
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print ouput on failure.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      /* ... */
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/exception1.c b/deps/w32-pthreads/tests/exception1.c
deleted file mode 100644
index c0b0812..0000000
--- a/deps/w32-pthreads/tests/exception1.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * File: exception1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test passing of exceptions back to the application.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#if defined(_MSC_VER) || defined(__cplusplus)
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 4
-};
-
-void *
-exceptionedThread(void * arg)
-{
-  int dummy = 0;
-  void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1);
-  /* Set to async cancelable */
-
-  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-
-  Sleep(100);
-
-#if defined(_MSC_VER) && !defined(__cplusplus)
-  __try
-  {
-    int zero = (int) (size_t)arg; /* Passed in from arg to avoid compiler error */
-    int one = 1;
-    /*
-     * The deliberate exception condition (zero divide) is
-     * in an "if" to avoid being optimised out.
-     */
-    if (dummy == one/zero)
-      Sleep(0);
-  }
-  __except (EXCEPTION_EXECUTE_HANDLER)
-  {
-    /* Should get into here. */
-    result = (void*)((int)(size_t)PTHREAD_CANCELED + 2);
-  }
-#elif defined(__cplusplus)
-  try
-  {
-    /*
-     * I had a zero divide exception here but it
-     * wasn't being caught by the catch(...)
-     * below under Mingw32. That could be a problem.
-     */
-    throw dummy;
-  }
-#if defined(PtW32CatchAll)
-  PtW32CatchAll
-#else
-  catch (...)
-#endif
-  {
-    /* Should get into here. */
-    result = (void*)((int)(size_t)PTHREAD_CANCELED + 2);
-  }
-#endif
-
-  return (void *) (size_t)result;
-}
-
-void *
-canceledThread(void * arg)
-{
-  void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1);
-  int count;
-
-  /* Set to async cancelable */
-
-  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-
-#if defined(_MSC_VER) && !defined(__cplusplus)
-  __try
-  {
-    /*
-     * We wait up to 10 seconds, waking every 0.1 seconds,
-     * for a cancelation to be applied to us.
-     */
-    for (count = 0; count < 100; count++)
-      Sleep(100);
-  }
-  __except (EXCEPTION_EXECUTE_HANDLER)
-  {
-    /* Should NOT get into here. */
-    result = (void*)((int)(size_t)PTHREAD_CANCELED + 2);
-  }
-#elif defined(__cplusplus)
-  try
-  {
-    /*
-     * We wait up to 10 seconds, waking every 0.1 seconds,
-     * for a cancelation to be applied to us.
-     */
-    for (count = 0; count < 100; count++)
-      Sleep(100);
-  }
-#if defined(PtW32CatchAll)
-  PtW32CatchAll
-#else
-  catch (...)
-#endif
-  {
-    /* Should NOT get into here. */
-    result = (void*)((int)(size_t)PTHREAD_CANCELED + 2);
-  }
-#endif
-
-  return (void *) (size_t)result;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t mt;
-  pthread_t et[NUMTHREADS];
-  pthread_t ct[NUMTHREADS];
-
-  assert((mt = pthread_self()).p != NULL);
-
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      assert(pthread_create(&et[i], NULL, exceptionedThread, (void *) 0) == 0);
-      assert(pthread_create(&ct[i], NULL, canceledThread, NULL) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(1000);
-
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      assert(pthread_cancel(ct[i]) == 0);
-    }
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 1000);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      int fail = 0;
-      void* result = (void*)0;
-
-	/* Canceled thread */
-      assert(pthread_join(ct[i], &result) == 0);
-      assert(!(fail = (result != PTHREAD_CANCELED)));
-
-      failed = (failed || fail);
-
-      /* Exceptioned thread */
-      assert(pthread_join(et[i], &result) == 0);
-      assert(!(fail = (result != (void*)((int)(size_t)PTHREAD_CANCELED + 2))));
-
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
-#else /* defined(_MSC_VER) || defined(__cplusplus) */
-
-#include <stdio.h>
-
-int
-main()
-{
-  fprintf(stderr, "Test N/A for this compiler environment.\n");
-  return 0;
-}
-
-#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/deps/w32-pthreads/tests/exception2.c b/deps/w32-pthreads/tests/exception2.c
deleted file mode 100644
index 16eda12..0000000
--- a/deps/w32-pthreads/tests/exception2.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * File: exception2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test passing of exceptions out of thread scope.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-
-#if defined(_MSC_VER) || defined(__cplusplus)
-
-#if defined(_MSC_VER) && defined(__cplusplus)
-#include <eh.h>
-#elif defined(__cplusplus)
-#include <exception>
-#endif
-
-#ifdef __GNUC__
-#include <stdlib.h>
-#endif
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 1
-};
-
-
-void *
-exceptionedThread(void * arg)
-{
-  int dummy = 0x1;
-
-#if defined(_MSC_VER) && !defined(__cplusplus)
-
-  RaiseException(dummy, 0, 0, NULL);
-
-#elif defined(__cplusplus)
-
-  throw dummy;
-
-#endif
-
-  return (void *) 100;
-}
-
-int
-main(int argc, char* argv[])
-{
-  int i;
-  pthread_t mt;
-  pthread_t et[NUMTHREADS];
-
-  if (argc <= 1)
-    {
-      int result;
-
-      printf("You should see an \"abnormal termination\" message\n");
-      fflush(stdout);
-      result = system("exception2.exe die");
-      exit(0);
-    }
-
-  assert((mt = pthread_self()).p != NULL);
-
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0);
-    }
-
-  Sleep(1000);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
-#else /* defined(_MSC_VER) || defined(__cplusplus) */
-
-#include <stdio.h>
-
-int
-main()
-{
-  fprintf(stderr, "Test N/A for this compiler environment.\n");
-  return 0;
-}
-
-#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/deps/w32-pthreads/tests/exception3.c b/deps/w32-pthreads/tests/exception3.c
deleted file mode 100644
index cb98393..0000000
--- a/deps/w32-pthreads/tests/exception3.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * File: exception3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test running of user supplied terminate() function.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-#if defined(__cplusplus)
-
-#if defined(_MSC_VER)
-# include <eh.h>
-#else
-# if defined(__GNUC__) && __GNUC__ < 3
-#   include <new.h>
-# else
-#   include <new>
-    using std::set_terminate;
-# endif
-#endif
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 1
-};
-
-int caught = 0;
-pthread_mutex_t caughtLock;
-
-void
-terminateFunction ()
-{
-  assert(pthread_mutex_lock(&caughtLock) == 0);
-  caught++;
-#if 0
-  {
-     FILE * fp = fopen("pthread.log", "a");
-     fprintf(fp, "Caught = %d\n", caught);
-     fclose(fp);
-  }
-#endif
-  assert(pthread_mutex_unlock(&caughtLock) == 0);
-
-  /*
-   * Notes from the MSVC++ manual:
-   *       1) A term_func() should call exit(), otherwise
-   *          abort() will be called on return to the caller.
-   *          abort() raises SIGABRT. The default signal handler
-   *          for all signals terminates the calling program with
-   *          exit code 3.
-   *       2) A term_func() must not throw an exception. Dev: Therefore
-   *          term_func() should not call pthread_exit() if an
-   *          exception-using version of pthreads-win32 library
-   *          is being used (i.e. either pthreadVCE or pthreadVSE).
-   */
-  exit(0);
-}
-
-void *
-exceptionedThread(void * arg)
-{
-  int dummy = 0x1;
-
-  (void) set_terminate(&terminateFunction);
-
-  throw dummy;
-
-  return (void *) 0;
-}
-
-int
-main()
-{
-  int i;
-  pthread_t mt;
-  pthread_t et[NUMTHREADS];
-  pthread_mutexattr_t ma;
-
-  assert((mt = pthread_self()).p != NULL);
-
-  printf("See the notes inside of exception3.c re term_funcs.\n");
-
-  assert(pthread_mutexattr_init(&ma) == 0);
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0);
-  assert(pthread_mutex_init(&caughtLock, &ma) == 0);
-  assert(pthread_mutexattr_destroy(&ma) == 0);
-
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0);
-    }
-
-  Sleep(NUMTHREADS * 100);
-
-  assert(caught == NUMTHREADS);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
-#else /* defined(__cplusplus) */
-
-#include <stdio.h>
-
-int
-main()
-{
-  fprintf(stderr, "Test N/A for this compiler environment.\n");
-  return 0;
-}
-
-#endif /* defined(__cplusplus) */
diff --git a/deps/w32-pthreads/tests/exit1.c b/deps/w32-pthreads/tests/exit1.c
deleted file mode 100644
index 8625e10..0000000
--- a/deps/w32-pthreads/tests/exit1.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Test for pthread_exit().
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Depends on API functions: None.
- */
-
-#include "test.h"
-
-int
-main(int argc, char * argv[])
-{
-	/* A simple test first. */
-	pthread_exit((void *) 0);
-
-	/* Not reached */
-	assert(0);
-	return 0;
-}
diff --git a/deps/w32-pthreads/tests/exit2.c b/deps/w32-pthreads/tests/exit2.c
deleted file mode 100644
index 21a193c..0000000
--- a/deps/w32-pthreads/tests/exit2.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Test for pthread_exit().
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Depends on API functions:
- *	pthread_create()
- *	pthread_exit()
- */
-
-#include "test.h"
-
-void *
-func(void * arg)
-{
-	pthread_exit(arg);
-
-	/* Never reached. */
-	assert(0);
-
-	return NULL;
-}
-
-int
-main(int argc, char * argv[])
-{
-  pthread_t t;
-
-  assert(pthread_create(&t, NULL, func, (void *) NULL) == 0);
-
-  Sleep(100);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/exit3.c b/deps/w32-pthreads/tests/exit3.c
deleted file mode 100644
index f7e3103..0000000
--- a/deps/w32-pthreads/tests/exit3.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Test for pthread_exit().
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Depends on API functions: pthread_create().
- */
-
-#include "test.h"
-
-void *
-func(void * arg)
-{
-	pthread_exit(arg);
-
-	/* Never reached. */
-	assert(0);
-
-	return NULL;
-}
-
-int
-main(int argc, char * argv[])
-{
-	pthread_t id[4];
-	int i;
-
-	/* Create a few threads and then exit. */
-	for (i = 0; i < 4; i++)
-	  {
-	    assert(pthread_create(&id[i], NULL, func, (void *)(size_t)i) == 0);
-	  }
-
-	Sleep(400);
-
-	/* Success. */
-	return 0;
-}
diff --git a/deps/w32-pthreads/tests/exit4.c b/deps/w32-pthreads/tests/exit4.c
deleted file mode 100644
index d23c6f9..0000000
--- a/deps/w32-pthreads/tests/exit4.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * File: exit4.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test calling pthread_exit from a Win32 thread
- *                without having created an implicit POSIX handle for it.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#ifndef _UWIN
-#include <process.h>
-#endif
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 4
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-unsigned __stdcall
-#else
-void
-#endif
-Win32thread(void * arg)
-{
-  int result = 1;
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /*
-   * Doesn't return and doesn't create an implicit POSIX handle.
-   */
-  pthread_exit((void *)(size_t)result);
-
-  return 0;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  HANDLE h[NUMTHREADS + 1];
-  unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-      h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr);
-#else
-      h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]);
-#endif
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(500);
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      int result = 0;
-
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-      assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE);
-#else
-      /*
-       * Can't get a result code.
-       */
-      result = 1;
-#endif
-
-      fail = (result != 1);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: count %d\n",
-		  i,
-		  threadbag[i].started,
-		  threadbag[i].count);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/exit5.c b/deps/w32-pthreads/tests/exit5.c
deleted file mode 100644
index 6cb3f27..0000000
--- a/deps/w32-pthreads/tests/exit5.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * File: exit5.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Test calling pthread_exit from a Win32 thread
- *                having created an implicit POSIX handle for it.
- *
- * Test Method (Validation or Falsification):
- * - Validate return value and that POSIX handle is created and destroyed.
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-#ifndef _UWIN
-#include <process.h>
-#endif
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 4
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-  pthread_t self;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-unsigned __stdcall
-#else
-void
-#endif
-Win32thread(void * arg)
-{
-  int result = 1;
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  assert((bag->self = pthread_self()).p != NULL);
-  assert(pthread_kill(bag->self, 0) == 0);
-
-  /*
-   * Doesn't return.
-   */
-  pthread_exit((void *)(size_t)result);
-
-  return 0;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  HANDLE h[NUMTHREADS + 1];
-  unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-      h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr);
-#else
-      h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]);
-#endif
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(500);
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      int result = 0;
-
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-      assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE);
-#else
-      /*
-       * Can't get a result code.
-       */
-      result = 1;
-#endif
-
-      assert(threadbag[i].self.p != NULL && pthread_kill(threadbag[i].self, 0) == ESRCH);
-
-      fail = (result != 1);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: count %d\n",
-		  i,
-		  threadbag[i].started,
-		  threadbag[i].count);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/eyal1.c b/deps/w32-pthreads/tests/eyal1.c
deleted file mode 100644
index b2f5881..0000000
--- a/deps/w32-pthreads/tests/eyal1.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/* Simple POSIX threads program.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Author: Eyal Lebedinsky eyal at eyal.emu.id.au
- * Written: Sep 1998.
- * Version Date: 12 Sep 1998
- *
- * Do we need to lock stdout or is it thread safe?
- *
- * Used:
- *	pthread_t
- *	pthread_attr_t
- *	pthread_create()
- *	pthread_join()
- *	pthread_mutex_t
- *	PTHREAD_MUTEX_INITIALIZER
- *	pthread_mutex_init() [not used now]
- *	pthread_mutex_destroy()
- *	pthread_mutex_lock()
- *	pthread_mutex_trylock()
- *	pthread_mutex_unlock()
- *
- * What this program does is establish a work queue (implemented using
- * four mutexes for each thread). It then schedules work (by storing
- * a number in 'todo') and releases the threads. When the work is done
- * the threads will block. The program then repeats the same thing once
- * more (just to test the logic) and when the work is done it destroyes
- * the threads.
- *
- * The 'work' we do is simply burning CPU cycles in a loop.
- * The 'todo' work queue is trivial - each threads pops one element
- * off it by incrementing it, the poped number is the 'work' to do.
- * When 'todo' reaches the limit (nwork) the queue is considered
- * empty.
- *
- * The number displayed at the end is the amount of work each thread
- * did, so we can see if the load was properly distributed.
- *
- * The program was written to test a threading setup (not seen here)
- * rather than to demonstrate correct usage of the pthread facilities.
- *
- * Note how each thread is given access to a thread control structure
- * (TC) which is used for communicating to/from the main program (e.g.
- * the threads knows its 'id' and also filles in the 'work' done).
-*/
-
-#include "test.h"
-
-#include <stdlib.h>
-#include <math.h>
-
-struct thread_control {
-  int		id;
-  pthread_t	thread;		/* thread id */
-  pthread_mutex_t	mutex_start;
-  pthread_mutex_t	mutex_started;
-  pthread_mutex_t	mutex_end;
-  pthread_mutex_t	mutex_ended;
-  long		work;		/* work done */
-  int		stat;		/* pthread_init status */
-};
-
-typedef struct thread_control	TC;
-
-static TC		*tcs = NULL;
-static int		nthreads = 10;
-static int		nwork = 100;
-static int		quiet = 0;
-
-static int		todo = -1;
-
-static pthread_mutex_t	mutex_todo = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t	mutex_stdout = PTHREAD_MUTEX_INITIALIZER;
-
-
-static void
-die (int ret)
-{
-  if (NULL != tcs)
-    {
-      free (tcs);
-      tcs = NULL;
-    }
-
-  if (ret)
-    exit (ret);
-}
-
-
-static double
-waste_time (int n)
-{
-  int		i;
-  double	f, g, h, s;
-
-  s = 0.0;
-
-  /*
-   * Useless work.
-   */
-  for (i = n*100; i > 0; --i)
-    {
-      f = rand ();
-      g = rand ();
-      h = rand ();
-      s += 2.0 * f * g / (h != 0.0 ? (h * h) : 1.0);
-    }
-  return s;
-}
-
-static int
-do_work_unit (int who, int n)
-{
-  int		i;
-  static int	nchars = 0;
-  double	f = 0.0;
-
-  if (quiet)
-    i = 0;
-  else {
-    /*
-     * get lock on stdout
-     */
-    assert(pthread_mutex_lock (&mutex_stdout) == 0);
-
-    /*
-     * do our job
-     */
-    i = printf ("%c", "0123456789abcdefghijklmnopqrstuvwxyz"[who]);
-
-    if (!(++nchars % 50))
-      printf ("\n");
-
-    fflush (stdout);
-
-    /*
-     * release lock on stdout
-     */
-    assert(pthread_mutex_unlock (&mutex_stdout) == 0);
-  }
-
-  n = rand () % 10000;	/* ignore incoming 'n' */
-  f = waste_time (n);
-
-  /* This prevents the statement above from being optimised out */
-  if (f > 0.0)
-    return(n);
-
-  return (n);
-}
-
-static int
-print_server (void *ptr)
-{
-  int		mywork;
-  int		n;
-  TC		*tc = (TC *)ptr;
-
-  assert(pthread_mutex_lock (&tc->mutex_started) == 0);
-
-  for (;;)
-    {
-      assert(pthread_mutex_lock (&tc->mutex_start) == 0);
-      assert(pthread_mutex_unlock (&tc->mutex_start) == 0);
-      assert(pthread_mutex_lock (&tc->mutex_ended) == 0);
-      assert(pthread_mutex_unlock (&tc->mutex_started) == 0);
-
-      for (;;)
-	{
-
-	  /*
-	   * get lock on todo list
-	   */
-	  assert(pthread_mutex_lock (&mutex_todo) == 0);
-
-	  mywork = todo;
-	  if (todo >= 0)
-	    {
-	      ++todo;
-	      if (todo >= nwork)
-		todo = -1;
-	    }
-	  assert(pthread_mutex_unlock (&mutex_todo) == 0);
-
-	  if (mywork < 0)
-	    break;
-
-	  assert((n = do_work_unit (tc->id, mywork)) >= 0);
-	  tc->work += n;
-	}
-
-      assert(pthread_mutex_lock (&tc->mutex_end) == 0);
-      assert(pthread_mutex_unlock (&tc->mutex_end) == 0);
-      assert(pthread_mutex_lock (&tc->mutex_started) == 0);
-      assert(pthread_mutex_unlock (&tc->mutex_ended) == 0);
-
-      if (-2 == mywork)
-	break;
-    }
-
-  assert(pthread_mutex_unlock (&tc->mutex_started) == 0);
-
-  return (0);
-}
-
-static void
-dosync (void)
-{
-  int		i;
-
-  for (i = 0; i < nthreads; ++i)
-    {
-      assert(pthread_mutex_lock (&tcs[i].mutex_end) == 0);
-      assert(pthread_mutex_unlock (&tcs[i].mutex_start) == 0);
-      assert(pthread_mutex_lock (&tcs[i].mutex_started) == 0);
-      assert(pthread_mutex_unlock (&tcs[i].mutex_started) == 0);
-    }
-
-  /*
-   * Now threads do their work
-   */
-  for (i = 0; i < nthreads; ++i)
-    {
-      assert(pthread_mutex_lock (&tcs[i].mutex_start) == 0);
-      assert(pthread_mutex_unlock (&tcs[i].mutex_end) == 0);
-      assert(pthread_mutex_lock (&tcs[i].mutex_ended) == 0);
-      assert(pthread_mutex_unlock (&tcs[i].mutex_ended) == 0);
-    }
-}
-
-static void
-dowork (void)
-{
-  todo = 0;
-  dosync();
-
-  todo = 0;
-  dosync();
-}
-
-int
-main (int argc, char *argv[])
-{
-  int		i;
-
-  assert(NULL != (tcs = (TC *) calloc (nthreads, sizeof (*tcs))));
-
-  /* 
-   * Launch threads
-   */
-  for (i = 0; i < nthreads; ++i)
-    {
-      tcs[i].id = i;
-
-      assert(pthread_mutex_init (&tcs[i].mutex_start, NULL) == 0);
-      assert(pthread_mutex_init (&tcs[i].mutex_started, NULL) == 0);
-      assert(pthread_mutex_init (&tcs[i].mutex_end, NULL) == 0);
-      assert(pthread_mutex_init (&tcs[i].mutex_ended, NULL) == 0);
-
-      tcs[i].work = 0;  
-
-      assert(pthread_mutex_lock (&tcs[i].mutex_start) == 0);
-      assert((tcs[i].stat = 
-	      pthread_create (&tcs[i].thread,
-			      NULL,
-                  (void *(*)(void *))print_server,
-                (void *) &tcs[i])
-	      ) == 0);
-
-      /* 
-       * Wait for thread initialisation
-       */
-      {
-	int trylock = 0;
-
-	while (trylock == 0)
-	  {
-	    trylock = pthread_mutex_trylock(&tcs[i].mutex_started);
-	    assert(trylock == 0 || trylock == EBUSY);
-
-	    if (trylock == 0)
-	      {
-		assert(pthread_mutex_unlock (&tcs[i].mutex_started) == 0);
-	      }
-	  }
-      }
-    }
-
-  dowork ();
-
-  /*
-   * Terminate threads
-   */
-  todo = -2;	/* please terminate */
-  dosync();
-
-  for (i = 0; i < nthreads; ++i)
-    {
-      if (0 == tcs[i].stat)
-	assert(pthread_join (tcs[i].thread, NULL) == 0);
-    }
-
-  /* 
-   * destroy locks
-   */
-  assert(pthread_mutex_destroy (&mutex_stdout) == 0);
-  assert(pthread_mutex_destroy (&mutex_todo) == 0);
-
-  /*
-   * Cleanup
-   */
-  printf ("\n");
-
-  /*
-   * Show results
-   */
-  for (i = 0; i < nthreads; ++i)
-    {
-      printf ("%2d ", i);
-      if (0 == tcs[i].stat)
-	printf ("%10ld\n", tcs[i].work);
-      else
-	printf ("failed %d\n", tcs[i].stat);
-
-      assert(pthread_mutex_unlock(&tcs[i].mutex_start) == 0);
-
-      assert(pthread_mutex_destroy (&tcs[i].mutex_start) == 0);
-      assert(pthread_mutex_destroy (&tcs[i].mutex_started) == 0);
-      assert(pthread_mutex_destroy (&tcs[i].mutex_end) == 0);
-      assert(pthread_mutex_destroy (&tcs[i].mutex_ended) == 0);
-    }
-
-  die (0);
-
-  return (0);
-}
diff --git a/deps/w32-pthreads/tests/inherit1.c b/deps/w32-pthreads/tests/inherit1.c
deleted file mode 100644
index b7464eb..0000000
--- a/deps/w32-pthreads/tests/inherit1.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * File: inherit1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test thread priority inheritance.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * -
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-enum {
-  PTW32TEST_THREAD_INIT_PRIO = 0,
-  PTW32TEST_MAXPRIORITIES = 512
-};
-
-int minPrio;
-int maxPrio;
-int validPriorities[PTW32TEST_MAXPRIORITIES];
-
-
-void * func(void * arg)
-{
-  int policy;
-  struct sched_param param;
-
-  assert(pthread_getschedparam(pthread_self(), &policy, &param) == 0);
-  return (void *) (size_t)param.sched_priority;
-}
-
-
-void *
-getValidPriorities(void * arg)
-{
-  int prioSet;
-  pthread_t thread = pthread_self();
-  HANDLE threadH = pthread_getw32threadhandle_np(thread);
-  struct sched_param param;
-
-  for (prioSet = minPrio;
-       prioSet <= maxPrio;
-       prioSet++)
-    {
-        /*
-       * If prioSet is invalid then the threads priority is unchanged
-       * from the previous value. Make the previous value a known
-       * one so that we can check later.
-       */
-        param.sched_priority = prioSet;
-        assert(pthread_setschedparam(thread, SCHED_OTHER, &param) == 0);
-        validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH);
-    }
-
-  return (void *) 0;
-}
-
-
-int
-main()
-{
-  pthread_t t;
-  pthread_t mainThread = pthread_self();
-  pthread_attr_t attr;
-  void * result = NULL;
-  struct sched_param param;
-  struct sched_param mainParam;
-  int prio;
-  int policy;
-  int inheritsched = -1;
-  pthread_t threadID = pthread_self();
-  HANDLE threadH = pthread_getw32threadhandle_np(threadID);
-
-  assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1);
-  assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1);
-
-  assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0);
-  assert(pthread_join(t, &result) == 0);
-
-  assert(pthread_attr_init(&attr) == 0);
-  assert(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED) == 0);
-  assert(pthread_attr_getinheritsched(&attr, &inheritsched) == 0);
-  assert(inheritsched == PTHREAD_INHERIT_SCHED);
-
-  for (prio = minPrio; prio <= maxPrio; prio++)
-    {
-      mainParam.sched_priority = prio;
-
-      /* Set the thread's priority to a known initial value. */
-      SetThreadPriority(threadH, PTW32TEST_THREAD_INIT_PRIO);
-
-      /* Change the main thread priority */
-      assert(pthread_setschedparam(mainThread, SCHED_OTHER, &mainParam) == 0);
-      assert(pthread_getschedparam(mainThread, &policy, &mainParam) == 0);
-      assert(policy == SCHED_OTHER);
-      /* Priority returned below should be the level set by pthread_setschedparam(). */
-      assert(mainParam.sched_priority == prio);
-      assert(GetThreadPriority(threadH) ==
-               validPriorities[prio+(PTW32TEST_MAXPRIORITIES/2)]);
-
-      for (param.sched_priority = prio;
-           param.sched_priority <= maxPrio;
-           param.sched_priority++)
-        {
-          /* The new thread create should ignore this new priority */
-          assert(pthread_attr_setschedparam(&attr, &param) == 0);
-          assert(pthread_create(&t, &attr, func, NULL) == 0);
-          pthread_join(t, &result);
-          assert((int)(size_t) result == mainParam.sched_priority);
-        }
-    }
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/join0.c b/deps/w32-pthreads/tests/join0.c
deleted file mode 100644
index 044e56f..0000000
--- a/deps/w32-pthreads/tests/join0.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Test for pthread_join().
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Depends on API functions: pthread_create(), pthread_exit().
- */
-
-#include "test.h"
-
-void *
-func(void * arg)
-{
-  Sleep(2000);
-
-  pthread_exit(arg);
-
-  /* Never reached. */
-  exit(1);
-}
-
-int
-main(int argc, char * argv[])
-{
-  pthread_t id;
-  void* result = (void*)0;
-
-  /* Create a single thread and wait for it to exit. */
-  assert(pthread_create(&id, NULL, func, (void *) 123) == 0);
-
-  assert(pthread_join(id, &result) == 0);
-
-  assert((int)(size_t)result == 123);
-
-  /* Success. */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/join1.c b/deps/w32-pthreads/tests/join1.c
deleted file mode 100644
index 68ad159..0000000
--- a/deps/w32-pthreads/tests/join1.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Test for pthread_join().
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Depends on API functions: pthread_create(), pthread_join(), pthread_exit().
- */
-
-#include "test.h"
-
-void *
-func(void * arg)
-{
-    int i = (int)(size_t)arg;
-
-    Sleep(i * 100);
-
-    pthread_exit(arg);
-
-    /* Never reached. */
-    exit(1);
-}
-
-int
-main(int argc, char * argv[])
-{
-	pthread_t id[4];
-	int i;
-	void* result = (void*)-1;
-
-	/* Create a few threads and then exit. */
-	for (i = 0; i < 4; i++)
-	  {
-	    assert(pthread_create(&id[i], NULL, func, (void *)(size_t)i) == 0);
-	  }
-
-	/* Some threads will finish before they are joined, some after. */
-	Sleep(2 * 100 + 50);
-
-	for (i = 0; i < 4; i++)
-	  {
-	    assert(pthread_join(id[i], &result) == 0);
-	    assert((int)(size_t)result == i);
-	  }
-
-	/* Success. */
-	return 0;
-}
diff --git a/deps/w32-pthreads/tests/join2.c b/deps/w32-pthreads/tests/join2.c
deleted file mode 100644
index 05fe37e..0000000
--- a/deps/w32-pthreads/tests/join2.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Test for pthread_join() returning return value from threads.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Depends on API functions: pthread_create().
- */
-
-#include "test.h"
-
-void *
-func(void * arg)
-{
-	Sleep(1000);
-	return arg;
-}
-
-int
-main(int argc, char * argv[])
-{
-	pthread_t id[4];
-	int i;
-	void* result = (void*)-1;
-
-	/* Create a few threads and then exit. */
-	for (i = 0; i < 4; i++)
-	  {
-	    assert(pthread_create(&id[i], NULL, func, (void *)(size_t)i) == 0);
-	  }
-
-	for (i = 0; i < 4; i++)
-	  {
-	    assert(pthread_join(id[i], &result) == 0);
-	    assert((int)(size_t)result == i);
-	  }
-
-	/* Success. */
-	return 0;
-}
diff --git a/deps/w32-pthreads/tests/join3.c b/deps/w32-pthreads/tests/join3.c
deleted file mode 100644
index 6e5426f..0000000
--- a/deps/w32-pthreads/tests/join3.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Test for pthread_join() returning return value from threads.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Depends on API functions: pthread_create().
- */
-
-#include "test.h"
-
-void *
-func(void * arg)
-{
-	sched_yield();
-	return arg;
-}
-
-int
-main(int argc, char * argv[])
-{
-	pthread_t id[4];
-	int i;
-	void* result = (void*)-1;
-
-	/* Create a few threads and then exit. */
-	for (i = 0; i < 4; i++)
-	  {
-	    assert(pthread_create(&id[i], NULL, func, (void *)(size_t)i) == 0);
-	  }
-
-	/*
-	 * Let threads exit before we join them.
-	 * We should still retrieve the exit code for the threads.
-	 */
-	Sleep(1000);
-
-	for (i = 0; i < 4; i++)
-	  {
-	    assert(pthread_join(id[i], &result) == 0);
-	    assert((int)(size_t)result == i);
-	  }
-
-	/* Success. */
-	return 0;
-}
diff --git a/deps/w32-pthreads/tests/kill1.c b/deps/w32-pthreads/tests/kill1.c
deleted file mode 100644
index ce34361..0000000
--- a/deps/w32-pthreads/tests/kill1.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * File: kill1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - pthread_kill() does not support non zero signals..
- *
- * Test Method (Validation or Falsification):
- * -
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * -
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-
-int
-main()
-{
-  assert(pthread_kill(pthread_self(), 1) == EINVAL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/loadfree.c b/deps/w32-pthreads/tests/loadfree.c
deleted file mode 100644
index e278a02..0000000
--- a/deps/w32-pthreads/tests/loadfree.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- * From: Todd Owen <towen at lucidcalm.dropbear.id.au>
- * To: pthreads-win32 at sourceware.cygnus.com
- * Subject: invalid page fault when using LoadLibrary/FreeLibrary
- * 
- * hi,
- * for me, pthread.dll consistently causes an "invalid page fault in
- * kernel32.dll" when I load it "explicitly"...to be precise, loading (with
- * LoadLibrary) isn't a problem, it gives the error when I call FreeLibrary.
- * I guess that the dll's cleanup must be causing the error.
- * 
- * Implicit linkage of the dll has never given me this problem.  Here's a
- * program (console application) that gives me the error.
- * 
- * I compile with: mingw32 (gcc-2.95 release), with the MSVCRT add-on (not
- * that the compiler should make much difference in this case).
- * PTHREAD.DLL: is the precompiled 1999-11-02 one (I tried an older one as
- * well, with the same result).
- * 
- * Fascinatingly, if you have your own dll (mycode.dll) which implicitly
- * loads pthread.dll, and then do LoadLibrary/FreeLibrary on _this_ dll, the
- * same thing happens.
- * 
- */
-
-#include "test.h"
-
-int main() {
-  HINSTANCE hinst;
-
-  assert((hinst = LoadLibrary("pthread")) != (HINSTANCE) 0);
-
-  Sleep(100);
-
-  FreeLibrary(hinst);
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/mutex1.c b/deps/w32-pthreads/tests/mutex1.c
deleted file mode 100644
index a2c1e69..0000000
--- a/deps/w32-pthreads/tests/mutex1.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* 
- * mutex1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Create a simple mutex object, lock it, and then unlock it again.
- * This is the simplest test of the pthread mutex family that we can do.
- *
- * Depends on API functions:
- * 	pthread_mutex_init()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- *	pthread_mutex_destroy()
- */
-
-#include "test.h"
-
-pthread_mutex_t mutex = NULL;
-
-int
-main()
-{
-  assert(mutex == NULL);
-
-  assert(pthread_mutex_init(&mutex, NULL) == 0);
-
-  assert(mutex != NULL);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  assert(mutex == NULL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex1e.c b/deps/w32-pthreads/tests/mutex1e.c
deleted file mode 100644
index 11d2a06..0000000
--- a/deps/w32-pthreads/tests/mutex1e.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 
- * mutex1e.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * As for mutex1.c but with type set to PTHREAD_MUTEX_ERRORCHECK.
- *
- * Create a simple mutex object, lock it, unlock it, then destroy it.
- * This is the simplest test of the pthread mutex family that we can do.
- *
- * Depends on API functions:
- *	pthread_mutexattr_settype()
- * 	pthread_mutex_init()
- *	pthread_mutex_destroy()
- */
-
-#include "test.h"
-
-pthread_mutex_t mutex = NULL;
-pthread_mutexattr_t mxAttr;
-
-int
-main()
-{
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0);
-
-  assert(mutex == NULL);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(mutex != NULL);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  assert(mutex == NULL);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex1n.c b/deps/w32-pthreads/tests/mutex1n.c
deleted file mode 100644
index a898744..0000000
--- a/deps/w32-pthreads/tests/mutex1n.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 
- * mutex1n.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * As for mutex1.c but with type set to PTHREAD_MUTEX_NORMAL.
- *
- * Create a simple mutex object, lock it, unlock it, then destroy it.
- * This is the simplest test of the pthread mutex family that we can do.
- *
- * Depends on API functions:
- *	pthread_mutexattr_settype()
- * 	pthread_mutex_init()
- *	pthread_mutex_destroy()
- */
-
-#include "test.h"
-
-pthread_mutex_t mutex = NULL;
-pthread_mutexattr_t mxAttr;
-
-int
-main()
-{
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0);
-
-  assert(mutex == NULL);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(mutex != NULL);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  assert(mutex == NULL);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex1r.c b/deps/w32-pthreads/tests/mutex1r.c
deleted file mode 100644
index 8087ab3..0000000
--- a/deps/w32-pthreads/tests/mutex1r.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 
- * mutex1r.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * As for mutex1.c but with type set to PTHREAD_MUTEX_RECURSIVE.
- *
- * Create a simple mutex object, lock it, unlock it, then destroy it.
- * This is the simplest test of the pthread mutex family that we can do.
- *
- * Depends on API functions:
- *	pthread_mutexattr_settype()
- * 	pthread_mutex_init()
- *	pthread_mutex_destroy()
- */
-
-#include "test.h"
-
-pthread_mutex_t mutex = NULL;
-pthread_mutexattr_t mxAttr;
-
-int
-main()
-{
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0);
-
-  assert(mutex == NULL);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(mutex != NULL);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  assert(mutex == NULL);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex2.c b/deps/w32-pthreads/tests/mutex2.c
deleted file mode 100644
index 0782100..0000000
--- a/deps/w32-pthreads/tests/mutex2.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* 
- * mutex2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static mutex object, lock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
- 
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-int
-main()
-{
-  assert(mutex == PTHREAD_MUTEX_INITIALIZER);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(mutex != PTHREAD_MUTEX_INITIALIZER);
-
-  assert(mutex != NULL);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  assert(mutex == NULL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex2e.c b/deps/w32-pthreads/tests/mutex2e.c
deleted file mode 100644
index a12f31c..0000000
--- a/deps/w32-pthreads/tests/mutex2e.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* 
- * mutex2e.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static mutex object, lock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
- 
-pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;
-
-int
-main()
-{
-  assert(mutex == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(mutex != PTHREAD_ERRORCHECK_MUTEX_INITIALIZER);
-
-  assert(mutex != NULL);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  assert(mutex == NULL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex2r.c b/deps/w32-pthreads/tests/mutex2r.c
deleted file mode 100644
index a84152a..0000000
--- a/deps/w32-pthreads/tests/mutex2r.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* 
- * mutex2r.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static mutex object, lock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
- 
-pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
-
-int
-main()
-{
-  assert(mutex == PTHREAD_RECURSIVE_MUTEX_INITIALIZER);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(mutex != PTHREAD_RECURSIVE_MUTEX_INITIALIZER);
-
-  assert(mutex != NULL);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  assert(mutex == NULL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex3.c b/deps/w32-pthreads/tests/mutex3.c
deleted file mode 100644
index e6014b2..0000000
--- a/deps/w32-pthreads/tests/mutex3.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* 
- * mutex3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static mutex object, lock it, trylock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *	pthread_mutex_lock()
- *	pthread_mutex_trylock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
- 
-pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  assert(pthread_mutex_trylock(&mutex1) == EBUSY);
-
-  washere = 1;
-
-  return 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_mutex_lock(&mutex1) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-  assert(pthread_join(t, NULL) == 0);
-
-  assert(pthread_mutex_unlock(&mutex1) == 0);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex3e.c b/deps/w32-pthreads/tests/mutex3e.c
deleted file mode 100644
index 3eeaaa6..0000000
--- a/deps/w32-pthreads/tests/mutex3e.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* 
- * mutex3e.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static mutex object, lock it, trylock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *	pthread_mutex_lock()
- *	pthread_mutex_trylock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
- 
-pthread_mutex_t mutex1 = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  assert(pthread_mutex_trylock(&mutex1) == EBUSY);
-
-  washere = 1;
-
-  return 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_mutex_lock(&mutex1) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-  assert(pthread_join(t, NULL) == 0);
-
-  assert(pthread_mutex_unlock(&mutex1) == 0);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex3r.c b/deps/w32-pthreads/tests/mutex3r.c
deleted file mode 100644
index 2364d71..0000000
--- a/deps/w32-pthreads/tests/mutex3r.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* 
- * mutex3r.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static mutex object, lock it, trylock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *	pthread_mutex_lock()
- *	pthread_mutex_trylock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
- 
-pthread_mutex_t mutex1 = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  assert(pthread_mutex_trylock(&mutex1) == EBUSY);
-
-  washere = 1;
-
-  return 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_mutex_lock(&mutex1) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-  assert(pthread_join(t, NULL) == 0);
-
-  assert(pthread_mutex_unlock(&mutex1) == 0);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex4.c b/deps/w32-pthreads/tests/mutex4.c
deleted file mode 100644
index c324645..0000000
--- a/deps/w32-pthreads/tests/mutex4.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* 
- * mutex4.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Thread A locks mutex - thread B tries to unlock.
- *
- * Depends on API functions: 
- *	pthread_mutex_lock()
- *	pthread_mutex_trylock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int wasHere = 0;
-
-static pthread_mutex_t mutex1;
- 
-void * unlocker(void * arg)
-{
-  int expectedResult = (int)(size_t)arg;
-
-  wasHere++;
-  assert(pthread_mutex_unlock(&mutex1) == expectedResult);
-  wasHere++;
-  return NULL;
-}
- 
-int
-main()
-{
-  pthread_t t;
-  pthread_mutexattr_t ma;
-
-  assert(pthread_mutexattr_init(&ma) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(ma)
-
-  wasHere = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_DEFAULT) == 0);
-  assert(pthread_mutex_init(&mutex1, &ma) == 0);
-  assert(pthread_mutex_lock(&mutex1) == 0);
-  assert(pthread_create(&t, NULL, unlocker, (void *)(size_t)(IS_ROBUST?EPERM:0)) == 0);
-  assert(pthread_join(t, NULL) == 0);
-  assert(pthread_mutex_unlock(&mutex1) == 0);
-  assert(wasHere == 2);
-
-  wasHere = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0);
-  assert(pthread_mutex_init(&mutex1, &ma) == 0);
-  assert(pthread_mutex_lock(&mutex1) == 0);
-  assert(pthread_create(&t, NULL, unlocker, (void *)(size_t)(IS_ROBUST?EPERM:0)) == 0);
-  assert(pthread_join(t, NULL) == 0);
-  assert(pthread_mutex_unlock(&mutex1) == 0);
-  assert(wasHere == 2);
-
-  wasHere = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0);
-  assert(pthread_mutex_init(&mutex1, &ma) == 0);
-  assert(pthread_mutex_lock(&mutex1) == 0);
-  assert(pthread_create(&t, NULL, unlocker, (void *)(size_t) EPERM) == 0);
-  assert(pthread_join(t, NULL) == 0);
-  assert(pthread_mutex_unlock(&mutex1) == 0);
-  assert(wasHere == 2);
-
-  wasHere = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0);
-  assert(pthread_mutex_init(&mutex1, &ma) == 0);
-  assert(pthread_mutex_lock(&mutex1) == 0);
-  assert(pthread_create(&t, NULL, unlocker, (void *)(size_t) EPERM) == 0);
-  assert(pthread_join(t, NULL) == 0);
-  assert(pthread_mutex_unlock(&mutex1) == 0);
-  assert(wasHere == 2);
-
-  END_MUTEX_STALLED_ROBUST(ma)
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex5.c b/deps/w32-pthreads/tests/mutex5.c
deleted file mode 100644
index 741c6ac..0000000
--- a/deps/w32-pthreads/tests/mutex5.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* 
- * mutex5.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Confirm the equality/inequality of the various mutex types,
- * and the default not-set value.
- */
-
-#include "test.h"
-
-static pthread_mutexattr_t mxAttr;
-
-/* Prevent optimiser from removing dead or obvious asserts. */
-int _optimiseFoil;
-#define FOIL(x) (_optimiseFoil = x)
-
-int
-main()
-{
-  int mxType = -1;
-
-  assert(FOIL(PTHREAD_MUTEX_DEFAULT) == PTHREAD_MUTEX_NORMAL);
-  assert(FOIL(PTHREAD_MUTEX_DEFAULT) != PTHREAD_MUTEX_ERRORCHECK);
-  assert(FOIL(PTHREAD_MUTEX_DEFAULT) != PTHREAD_MUTEX_RECURSIVE);
-  assert(FOIL(PTHREAD_MUTEX_RECURSIVE) != PTHREAD_MUTEX_ERRORCHECK);
-
-  assert(FOIL(PTHREAD_MUTEX_NORMAL) == PTHREAD_MUTEX_FAST_NP);
-  assert(FOIL(PTHREAD_MUTEX_RECURSIVE) == PTHREAD_MUTEX_RECURSIVE_NP);
-  assert(FOIL(PTHREAD_MUTEX_ERRORCHECK) == PTHREAD_MUTEX_ERRORCHECK_NP);
-
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-  assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
-  assert(mxType == PTHREAD_MUTEX_NORMAL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex6.c b/deps/w32-pthreads/tests/mutex6.c
deleted file mode 100644
index e181c22..0000000
--- a/deps/w32-pthreads/tests/mutex6.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* 
- * mutex6.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test the default (type not set) mutex type.
- * Should be the same as PTHREAD_MUTEX_NORMAL.
- * Thread locks mutex twice (recursive lock).
- * Locking thread should deadlock on second attempt.
- *
- * Depends on API functions: 
- *	pthread_mutex_lock()
- *	pthread_mutex_trylock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int lockCount = 0;
-
-static pthread_mutex_t mutex;
-
-void * locker(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-
-  /* Should wait here (deadlocked) */
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return 0;
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_mutex_init(&mutex, NULL) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  Sleep(1000);
-
-  assert(lockCount == 1);
-
-  /*
-   * Should succeed even though we don't own the lock
-   * because FAST mutexes don't check ownership.
-   */
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  Sleep (1000);
-
-  assert(lockCount == 2);
-
-  exit(0);
-
-  /* Never reached */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex6e.c b/deps/w32-pthreads/tests/mutex6e.c
deleted file mode 100644
index aca99b6..0000000
--- a/deps/w32-pthreads/tests/mutex6e.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* 
- * mutex6e.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Tests PTHREAD_MUTEX_ERRORCHECK mutex type.
- * Thread locks mutex twice (recursive lock).
- * This should fail with an EDEADLK error.
- * The second unlock attempt should fail with an EPERM error.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *      pthread_mutexattr_init()
- *      pthread_mutexattr_destroy()
- *      pthread_mutexattr_settype()
- *      pthread_mutexattr_gettype()
- *      pthread_mutex_init()
- *      pthread_mutex_destroy()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-static pthread_mutexattr_t mxAttr;
-
-void * locker(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex) == EDEADLK);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-  assert(pthread_mutex_unlock(&mutex) == EPERM);
-
-  return (void *) 555;
-}
- 
-int
-main()
-{
-  pthread_t t;
-  void* result = (void*)0;
-  int mxType = -1;
-
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0);
-  assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
-  assert(mxType == PTHREAD_MUTEX_ERRORCHECK);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  assert(pthread_join(t, &result) == 0);
-  assert((int)(size_t)result == 555);
-
-  assert(lockCount == 2);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  assert(pthread_mutexattr_destroy(&mxAttr) == 0);
-
-  exit(0);
-
-  /* Never reached */
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/mutex6es.c b/deps/w32-pthreads/tests/mutex6es.c
deleted file mode 100644
index a2d7d14..0000000
--- a/deps/w32-pthreads/tests/mutex6es.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/* 
- * mutex6es.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Tests PTHREAD_MUTEX_ERRORCHECK static mutex type.
- * Thread locks mutex twice (recursive lock).
- * This should fail with an EDEADLK error.
- * The second unlock attempt should fail with an EPERM error.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *      pthread_mutexattr_init()
- *      pthread_mutexattr_destroy()
- *      pthread_mutexattr_settype()
- *      pthread_mutexattr_gettype()
- *      pthread_mutex_init()
- *      pthread_mutex_destroy()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int lockCount = 0;
-
-static pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;
-
-void * locker(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex) == EDEADLK);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-  assert(pthread_mutex_unlock(&mutex) == EPERM);
-
-  return (void *) 555;
-}
- 
-int
-main()
-{
-  pthread_t t;
-  void* result = (void*)0;
-
-  assert(mutex == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  assert(pthread_join(t, &result) == 0);
-  assert((int)(size_t)result == 555);
-
-  assert(lockCount == 2);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  exit(0);
-
-  /* Never reached */
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/mutex6n.c b/deps/w32-pthreads/tests/mutex6n.c
deleted file mode 100644
index 2b3d6db..0000000
--- a/deps/w32-pthreads/tests/mutex6n.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* 
- * mutex6n.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Tests PTHREAD_MUTEX_NORMAL mutex type.
- * Thread locks mutex twice (recursive lock).
- * The thread should deadlock.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_mutexattr_init()
- *      pthread_mutexattr_settype()
- *      pthread_mutexattr_gettype()
- *      pthread_mutex_init()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-static pthread_mutexattr_t mxAttr;
-
-void * locker(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-
-  /* Should wait here (deadlocked) */
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return (void *) 555;
-}
- 
-int
-main()
-{
-  pthread_t t;
-  int mxType = -1;
-
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0);
-  assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
-  assert(mxType == PTHREAD_MUTEX_NORMAL);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  Sleep(100);
-
-  assert(lockCount == 1);
-
-  assert(pthread_mutex_unlock(&mutex) == IS_ROBUST?EPERM:0);
-
-  Sleep (100);
-
-  assert(lockCount == IS_ROBUST?1:2);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  exit(0);
-
-  /* Never reached */
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/mutex6r.c b/deps/w32-pthreads/tests/mutex6r.c
deleted file mode 100644
index c761cbc..0000000
--- a/deps/w32-pthreads/tests/mutex6r.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* 
- * mutex6r.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Tests PTHREAD_MUTEX_RECURSIVE mutex type.
- * Thread locks mutex twice (recursive lock).
- * Both locks and unlocks should succeed.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *      pthread_mutexattr_init()
- *      pthread_mutexattr_destroy()
- *      pthread_mutexattr_settype()
- *      pthread_mutexattr_gettype()
- *      pthread_mutex_init()
- *      pthread_mutex_destroy()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-static pthread_mutexattr_t mxAttr;
-
-void * locker(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return (void *) 555;
-}
- 
-int
-main()
-{
-  pthread_t t;
-  void* result = (void*)0;
-  int mxType = -1;
-
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0);
-  assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
-  assert(mxType == PTHREAD_MUTEX_RECURSIVE);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  assert(pthread_join(t, &result) == 0);
-  assert((int)(size_t)result == 555);
-
-  assert(lockCount == 2);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  assert(pthread_mutexattr_destroy(&mxAttr) == 0);
-
-  exit(0);
-
-  /* Never reached */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex6rs.c b/deps/w32-pthreads/tests/mutex6rs.c
deleted file mode 100644
index 754ad4e..0000000
--- a/deps/w32-pthreads/tests/mutex6rs.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* 
- * mutex6rs.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Tests PTHREAD_MUTEX_RECURSIVE static mutex type.
- * Thread locks mutex twice (recursive lock).
- * Both locks and unlocks should succeed.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *      pthread_mutexattr_init()
- *      pthread_mutexattr_destroy()
- *      pthread_mutexattr_settype()
- *      pthread_mutexattr_gettype()
- *      pthread_mutex_init()
- *      pthread_mutex_destroy()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int lockCount = 0;
-
-static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
-
-void * locker(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return (void *) 555;
-}
- 
-int
-main()
-{
-  pthread_t t;
-  void* result = (void*)0;
-
-  assert(mutex == PTHREAD_RECURSIVE_MUTEX_INITIALIZER);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  assert(pthread_join(t, &result) == 0);
-  assert((int)(size_t)result == 555);
-
-  assert(lockCount == 2);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  exit(0);
-
-  /* Never reached */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex6s.c b/deps/w32-pthreads/tests/mutex6s.c
deleted file mode 100644
index 4f16a7b..0000000
--- a/deps/w32-pthreads/tests/mutex6s.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* 
- * mutex6s.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test the default (type not set) static mutex type.
- * Should be the same as PTHREAD_MUTEX_NORMAL.
- * Thread locks mutex twice (recursive lock).
- * Locking thread should deadlock on second attempt.
- *
- * Depends on API functions: 
- *	pthread_mutex_lock()
- *	pthread_mutex_trylock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int lockCount = 0;
-
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-void * locker(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-
-  /* Should wait here (deadlocked) */
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return 0;
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  assert(mutex == PTHREAD_MUTEX_INITIALIZER);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  Sleep(1000);
-
-  assert(lockCount == 1);
-
-  /*
-   * Should succeed even though we don't own the lock
-   * because FAST mutexes don't check ownership.
-   */
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  Sleep (1000);
-
-  assert(lockCount == 2);
-
-  exit(0);
-
-  /* Never reached */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex7.c b/deps/w32-pthreads/tests/mutex7.c
deleted file mode 100644
index 0fd4b90..0000000
--- a/deps/w32-pthreads/tests/mutex7.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* 
- * mutex7.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test the default (type not set) mutex type.
- * Should be the same as PTHREAD_MUTEX_NORMAL.
- * Thread locks then trylocks mutex (attempted recursive lock).
- * The thread should lock first time and EBUSY second time.
- *
- * Depends on API functions: 
- *	pthread_mutex_lock()
- *	pthread_mutex_trylock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int lockCount = 0;
-
-static pthread_mutex_t mutex;
-
-void * locker(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_trylock(&mutex) == EBUSY);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return 0;
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_mutex_init(&mutex, NULL) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  Sleep(1000);
-
-  assert(lockCount == 2);
-
-  exit(0);
-
-  /* Never reached */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex7e.c b/deps/w32-pthreads/tests/mutex7e.c
deleted file mode 100644
index d27c4ca..0000000
--- a/deps/w32-pthreads/tests/mutex7e.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* 
- * mutex7e.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Tests PTHREAD_MUTEX_ERRORCHECK mutex type.
- * Thread locks and then trylocks mutex (attempted recursive lock).
- * Trylock should fail with an EBUSY error.
- * The second unlock attempt should fail with an EPERM error.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *      pthread_mutexattr_init()
- *      pthread_mutexattr_destroy()
- *      pthread_mutexattr_settype()
- *      pthread_mutexattr_gettype()
- *      pthread_mutex_init()
- *      pthread_mutex_destroy()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-static pthread_mutexattr_t mxAttr;
-
-void * locker(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_trylock(&mutex) == EBUSY);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return (void *) 555;
-}
- 
-int
-main()
-{
-  pthread_t t;
-  void* result = (void*)0;
-  int mxType = -1;
-
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0);
-  assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
-  assert(mxType == PTHREAD_MUTEX_ERRORCHECK);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  assert(pthread_join(t, &result) == 0);
-  assert((int)(size_t)result == 555);
-
-  assert(lockCount == 2);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  assert(pthread_mutexattr_destroy(&mxAttr) == 0);
-
-  exit(0);
-
-  /* Never reached */
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/mutex7n.c b/deps/w32-pthreads/tests/mutex7n.c
deleted file mode 100644
index 979e58d..0000000
--- a/deps/w32-pthreads/tests/mutex7n.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/* 
- * mutex7n.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Tests PTHREAD_MUTEX_NORMAL mutex type.
- * Thread locks then trylocks mutex (attempted recursive lock).
- * The thread should lock first time and EBUSY second time.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_mutexattr_init()
- *      pthread_mutexattr_settype()
- *      pthread_mutexattr_gettype()
- *      pthread_mutex_init()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-static pthread_mutexattr_t mxAttr;
-
-void * locker(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_trylock(&mutex) == EBUSY);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return (void *) 555;
-}
- 
-int
-main()
-{
-  pthread_t t;
-  int mxType = -1;
-
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0);
-  assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
-  assert(mxType == PTHREAD_MUTEX_NORMAL);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  Sleep(100);
-
-  assert(lockCount == 2);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  assert(pthread_mutexattr_destroy(&mxAttr) == 0);
-
-  exit(0);
-
-  /* Never reached */
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/mutex7r.c b/deps/w32-pthreads/tests/mutex7r.c
deleted file mode 100644
index f3adc52..0000000
--- a/deps/w32-pthreads/tests/mutex7r.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* 
- * mutex7r.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Tests PTHREAD_MUTEX_RECURSIVE mutex type.
- * Thread locks mutex then trylocks mutex (recursive lock twice).
- * Both locks and unlocks should succeed.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *      pthread_mutexattr_init()
- *      pthread_mutexattr_destroy()
- *      pthread_mutexattr_settype()
- *      pthread_mutexattr_gettype()
- *      pthread_mutex_init()
- *      pthread_mutex_destroy()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-static pthread_mutexattr_t mxAttr;
-
-void * locker(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_trylock(&mutex) == 0);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return (void *) 555;
-}
- 
-int
-main()
-{
-  pthread_t t;
-  void* result = (void*)0;
-  int mxType = -1;
-
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0);
-  assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
-  assert(mxType == PTHREAD_MUTEX_RECURSIVE);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  assert(pthread_join(t, &result) == 0);
-  assert((int)(size_t)result == 555);
-
-  assert(lockCount == 2);
-
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  assert(pthread_mutexattr_destroy(&mxAttr) == 0);
-
-  exit(0);
-
-  /* Never reached */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex8.c b/deps/w32-pthreads/tests/mutex8.c
deleted file mode 100644
index 8e25aaa..0000000
--- a/deps/w32-pthreads/tests/mutex8.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* 
- * mutex8.c
- *
- *
- * Pthreads-win32 - POSIX Threads Library for Win32
- * Copyright (C) 1998 Ben Elliston and Ross Johnson
- * Copyright (C) 1999,2000,2001 Ross Johnson
- *
- * Contact Email: rpj at ise.canberra.edu.au
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test the default (type not set) mutex type exercising timedlock.
- * Thread locks mutex, another thread timedlocks the mutex.
- * Timed thread should timeout.
- *
- * Depends on API functions:
- *	pthread_mutex_lock()
- *	pthread_mutex_timedlock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-static int lockCount = 0;
-
-static pthread_mutex_t mutex;
-
-void * locker(void * arg)
-{
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 1;
-
-  assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT);
-
-  lockCount++;
-
-  return 0;
-}
-
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_mutex_init(&mutex, NULL) == 0);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  Sleep(2000);
-
-  assert(lockCount == 1);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/mutex8e.c b/deps/w32-pthreads/tests/mutex8e.c
deleted file mode 100644
index 936bd1b..0000000
--- a/deps/w32-pthreads/tests/mutex8e.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* 
- * mutex8e.c
- *
- *
- * Pthreads-win32 - POSIX Threads Library for Win32
- * Copyright (C) 1998 Ben Elliston and Ross Johnson
- * Copyright (C) 1999,2000,2001 Ross Johnson
- *
- * Contact Email: rpj at ise.canberra.edu.au
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Tests PTHREAD_MUTEX_ERRORCHECK mutex type exercising timedlock.
- * Thread locks mutex, another thread timedlocks the mutex.
- * Timed thread should timeout.
- *
- * Depends on API functions:
- *	pthread_create()
- *	pthread_mutexattr_init()
- *	pthread_mutexattr_destroy()
- *	pthread_mutexattr_settype()
- *	pthread_mutexattr_gettype()
- *	pthread_mutex_init()
- *	pthread_mutex_destroy()
- *	pthread_mutex_lock()
- *	pthread_mutex_timedlock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-static pthread_mutexattr_t mxAttr;
-
-void * locker(void * arg)
-{
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 1;
-
-  assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT);
-
-  lockCount++;
-
-  return 0;
-}
-
-int
-main()
-{
-  pthread_t t;
-  int mxType = -1;
-
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0);
-  assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
-  assert(mxType == PTHREAD_MUTEX_ERRORCHECK);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  Sleep(2000);
-
-  assert(lockCount == 1);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/mutex8n.c b/deps/w32-pthreads/tests/mutex8n.c
deleted file mode 100644
index 42a3330..0000000
--- a/deps/w32-pthreads/tests/mutex8n.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * mutex8n.c
- *
- *
- * Pthreads-win32 - POSIX Threads Library for Win32
- * Copyright (C) 1998 Ben Elliston and Ross Johnson
- * Copyright (C) 1999,2000,2001 Ross Johnson
- *
- * Contact Email: rpj at ise.canberra.edu.au
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Tests PTHREAD_MUTEX_NORMAL mutex type exercising timedlock.
- * Thread locks mutex, another thread timedlocks the mutex.
- * Timed thread should timeout.
- *
- * Depends on API functions:
- *	pthread_create()
- *	pthread_mutexattr_init()
- *	pthread_mutexattr_destroy()
- *	pthread_mutexattr_settype()
- *	pthread_mutexattr_gettype()
- *	pthread_mutex_init()
- *	pthread_mutex_destroy()
- *	pthread_mutex_lock()
- *	pthread_mutex_timedlock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-static pthread_mutexattr_t mxAttr;
-
-void * locker(void * arg)
-{
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 1;
-
-  assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT);
-
-  lockCount++;
-
-  return 0;
-}
-
-int
-main()
-{
-  pthread_t t;
-  int mxType = -1;
-
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0);
-  assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
-  assert(mxType == PTHREAD_MUTEX_NORMAL);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  Sleep(2000);
-
-  assert(lockCount == 1);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/mutex8r.c b/deps/w32-pthreads/tests/mutex8r.c
deleted file mode 100644
index 3443edb..0000000
--- a/deps/w32-pthreads/tests/mutex8r.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* 
- * mutex8r.c
- *
- *
- * Pthreads-win32 - POSIX Threads Library for Win32
- * Copyright (C) 1998 Ben Elliston and Ross Johnson
- * Copyright (C) 1999,2000,2001 Ross Johnson
- *
- * Contact Email: rpj at ise.canberra.edu.au
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Tests PTHREAD_MUTEX_RECURSIVE mutex type exercising timedlock.
- * Thread locks mutex, another thread timedlocks the mutex.
- * Timed thread should timeout.
- *
- * Depends on API functions:
- *	pthread_create()
- *	pthread_mutexattr_init()
- *	pthread_mutexattr_destroy()
- *	pthread_mutexattr_settype()
- *	pthread_mutexattr_gettype()
- *	pthread_mutex_init()
- *	pthread_mutex_destroy()
- *	pthread_mutex_lock()
- *	pthread_mutex_timedlock()
- *	pthread_mutex_unlock()
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-static pthread_mutexattr_t mxAttr;
-
-void * locker(void * arg)
-{
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 1;
-
-  assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT);
-
-  lockCount++;
-
-  return 0;
-}
-
-int
-main()
-{
-  pthread_t t;
-  int mxType = -1;
-
-  assert(pthread_mutexattr_init(&mxAttr) == 0);
-
-  BEGIN_MUTEX_STALLED_ROBUST(mxAttr)
-
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0);
-  assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
-  assert(mxType == PTHREAD_MUTEX_RECURSIVE);
-
-  assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
-
-  assert(pthread_mutex_lock(&mutex) == 0);
-
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-
-  Sleep(2000);
-
-  assert(lockCount == 1);
-
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  END_MUTEX_STALLED_ROBUST(mxAttr)
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/once1.c b/deps/w32-pthreads/tests/once1.c
deleted file mode 100644
index ac41367..0000000
--- a/deps/w32-pthreads/tests/once1.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * once1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Create a static pthread_once and test that it calls myfunc once.
- *
- * Depends on API functions:
- *	pthread_once()
- *	pthread_create()
- */
-
-#include "test.h"
-
-pthread_once_t once = PTHREAD_ONCE_INIT;
-
-static int washere = 0;
-
-void
-myfunc(void)
-{
-  washere++;
-}
-
-void *
-mythread(void * arg)
-{
-   assert(pthread_once(&once, myfunc) == 0);
-
-   return 0;
-}
-
-int
-main()
-{
-  pthread_t t1, t2;
-  
-  assert(pthread_create(&t1, NULL, mythread, NULL) == 0);
-
-  assert(pthread_create(&t2, NULL, mythread, NULL) == 0);
-
-  Sleep(2000);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/once2.c b/deps/w32-pthreads/tests/once2.c
deleted file mode 100644
index 2cce93e..0000000
--- a/deps/w32-pthreads/tests/once2.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * once2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Create several static pthread_once objects and channel several threads
- * through each.
- *
- * Depends on API functions:
- *	pthread_once()
- *	pthread_create()
- */
-
-#include "test.h"
-
-#define NUM_THREADS 100 /* Targeting each once control */
-#define NUM_ONCE    10
-
-pthread_once_t o = PTHREAD_ONCE_INIT;
-pthread_once_t once[NUM_ONCE];
-
-typedef struct {
-  int i;
-  CRITICAL_SECTION cs;
-} sharedInt_t;
-
-static sharedInt_t numOnce = {0, {0}};
-static sharedInt_t numThreads = {0, {0}};
-
-void
-myfunc(void)
-{
-  EnterCriticalSection(&numOnce.cs);
-  numOnce.i++;
-  LeaveCriticalSection(&numOnce.cs);
-  /* Simulate slow once routine so that following threads pile up behind it */
-  Sleep(100);
-}
-
-void *
-mythread(void * arg)
-{
-   assert(pthread_once(&once[(int)(size_t)arg], myfunc) == 0);
-   EnterCriticalSection(&numThreads.cs);
-   numThreads.i++;   
-   LeaveCriticalSection(&numThreads.cs);
-   return (void*)(size_t)0;
-}
-
-int
-main()
-{
-  pthread_t t[NUM_THREADS][NUM_ONCE];
-  int i, j;
-  
-  InitializeCriticalSection(&numThreads.cs);
-  InitializeCriticalSection(&numOnce.cs);
-
-  for (j = 0; j < NUM_ONCE; j++)
-    {
-      once[j] = o;
-
-      for (i = 0; i < NUM_THREADS; i++)
-        {
-	  /* GCC build: create was failing with EAGAIN after 790 threads */
-          while (0 != pthread_create(&t[i][j], NULL, mythread, (void *)(size_t)j))
-	    sched_yield();
-        }
-    }
-
-  for (j = 0; j < NUM_ONCE; j++)
-    for (i = 0; i < NUM_THREADS; i++)
-      if (pthread_join(t[i][j], NULL) != 0)
-        printf("Join failed for [thread,once] = [%d,%d]\n", i, j);
-
-  assert(numOnce.i == NUM_ONCE);
-  assert(numThreads.i == NUM_THREADS * NUM_ONCE);
-
-  DeleteCriticalSection(&numOnce.cs);
-  DeleteCriticalSection(&numThreads.cs);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/once3.c b/deps/w32-pthreads/tests/once3.c
deleted file mode 100644
index e34c17e..0000000
--- a/deps/w32-pthreads/tests/once3.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * once3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Create several pthread_once objects and channel several threads
- * through each. Make the init_routine cancelable and cancel them with
- * waiters waiting.
- *
- * Depends on API functions:
- *	pthread_once()
- *	pthread_create()
- *      pthread_testcancel()
- *      pthread_cancel()
- *      pthread_once()
- */
-
-/* #define ASSERT_TRACE */
-
-#include "test.h"
-
-#define NUM_THREADS 100 /* Targeting each once control */
-#define NUM_ONCE    10
-
-static pthread_once_t o = PTHREAD_ONCE_INIT;
-static pthread_once_t once[NUM_ONCE];
-
-typedef struct {
-  int i;
-  CRITICAL_SECTION cs;
-} sharedInt_t;
-
-static sharedInt_t numOnce = {0, {0}};
-static sharedInt_t numThreads = {0, {0}};
-
-void
-myfunc(void)
-{
-  EnterCriticalSection(&numOnce.cs);
-  numOnce.i++;
-  assert(numOnce.i > 0);
-  LeaveCriticalSection(&numOnce.cs);
-  /* Simulate slow once routine so that following threads pile up behind it */
-  Sleep(10);
-  /* test for cancelation late so we're sure to have waiters. */
-  pthread_testcancel();
-}
-
-void *
-mythread(void * arg)
-{
-  /*
-   * Cancel every thread. These threads are deferred cancelable only, so
-   * only the thread performing the once routine (my_func) will see it (there are
-   * no other cancelation points here). The result will be that every thread
-   * eventually cancels only when it becomes the new 'once' thread.
-   */
-  assert(pthread_cancel(pthread_self()) == 0);
-  assert(pthread_once(&once[(int)(size_t)arg], myfunc) == 0);
-  EnterCriticalSection(&numThreads.cs);
-  numThreads.i++;
-  LeaveCriticalSection(&numThreads.cs);
-  return (void*)(size_t)0;
-}
-
-int
-main()
-{
-  pthread_t t[NUM_THREADS][NUM_ONCE];
-  int i, j;
-  
-  InitializeCriticalSection(&numThreads.cs);
-  InitializeCriticalSection(&numOnce.cs);
-
-  for (j = 0; j < NUM_ONCE; j++)
-    {
-      once[j] = o;
-
-      for (i = 0; i < NUM_THREADS; i++)
-        {
-          /* GCC build: create was failing with EAGAIN after 790 threads */
-          while (0 != pthread_create(&t[i][j], NULL, mythread, (void *)(size_t)j))
-            sched_yield();
-        }
-    }
-
-  for (j = 0; j < NUM_ONCE; j++)
-    for (i = 0; i < NUM_THREADS; i++)
-      if (pthread_join(t[i][j], NULL) != 0)
-        printf("Join failed for [thread,once] = [%d,%d]\n", i, j);
-
-  /*
-   * All threads will cancel, none will return normally from
-   * pthread_once and so numThreads should never be incremented. However,
-   * numOnce should be incremented by every thread (NUM_THREADS*NUM_ONCE).
-   */
-  assert(numOnce.i == NUM_ONCE * NUM_THREADS);
-  assert(numThreads.i == 0);
-
-  DeleteCriticalSection(&numOnce.cs);
-  DeleteCriticalSection(&numThreads.cs);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/once4.c b/deps/w32-pthreads/tests/once4.c
deleted file mode 100644
index 722f729..0000000
--- a/deps/w32-pthreads/tests/once4.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * once4.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Create several pthread_once objects and channel several threads
- * through each. Make the init_routine cancelable and cancel them
- * waiters waiting. Vary the priorities.
- *
- * Depends on API functions:
- *	pthread_once()
- *	pthread_create()
- *      pthread_testcancel()
- *      pthread_cancel()
- *      pthread_once()
- */
-
-#include "test.h"
-
-#define NUM_THREADS 100 /* Targeting each once control */
-#define NUM_ONCE    10
-
-pthread_once_t o = PTHREAD_ONCE_INIT;
-pthread_once_t once[NUM_ONCE];
-
-typedef struct {
-  int i;
-  CRITICAL_SECTION cs;
-} sharedInt_t;
-
-static sharedInt_t numOnce = {0, {0}};
-static sharedInt_t numThreads = {0, {0}};
-
-typedef struct {
-  int threadnum;
-  int oncenum;
-  int myPrio;
-  HANDLE w32Thread;
-} bag_t;
-
-static bag_t threadbag[NUM_THREADS][NUM_ONCE];
-
-CRITICAL_SECTION print_lock;
-
-void
-mycleanupfunc(void * arg)
-{
-  bag_t * bag = (bag_t *) arg;
-  EnterCriticalSection(&print_lock);
-  /*      once thrd  prio error */
-  printf("%4d %4d %4d %4d\n",
-	 bag->oncenum,
-	 bag->threadnum,
-	 bag->myPrio,
-	 bag->myPrio - GetThreadPriority(bag->w32Thread));
-  LeaveCriticalSection(&print_lock);
-}
-
-void
-myinitfunc(void)
-{
-  EnterCriticalSection(&numOnce.cs);
-  numOnce.i++;
-  LeaveCriticalSection(&numOnce.cs);
-  /* Simulate slow once routine so that following threads pile up behind it */
-  Sleep(10);
-  /* test for cancelation late so we're sure to have waiters. */
-  pthread_testcancel();
-}
-
-void *
-mythread(void * arg)
-{
-  bag_t * bag = (bag_t *) arg;
-  struct sched_param param;
-
-  /*
-   * Cancel every thread. These threads are deferred cancelable only, so
-   * only the thread performing the init_routine will see it (there are
-   * no other cancelation points here). The result will be that every thread
-   * eventually cancels only when it becomes the new initter.
-   */
-  pthread_t self = pthread_self();
-  bag->w32Thread = pthread_getw32threadhandle_np(self);
-  /*
-   * Set priority between -2 and 2 inclusive.
-   */
-  bag->myPrio = (bag->threadnum % 5) - 2;
-  param.sched_priority = bag->myPrio;
-  pthread_setschedparam(self, SCHED_OTHER, &param);
-
-  /* Trigger a cancellation at the next cancellation point in this thread */
-  pthread_cancel(self);
-#if 0
-  pthread_cleanup_push(mycleanupfunc, arg);
-  assert(pthread_once(&once[bag->oncenum], myinitfunc) == 0);
-  pthread_cleanup_pop(1);
-#else
-  assert(pthread_once(&once[bag->oncenum], myinitfunc) == 0);
-#endif
-  EnterCriticalSection(&numThreads.cs);
-  numThreads.i++;
-  LeaveCriticalSection(&numThreads.cs);
-  return 0;
-}
-
-int
-main()
-{
-  pthread_t t[NUM_THREADS][NUM_ONCE];
-  int i, j;
-  
-  InitializeCriticalSection(&print_lock);
-  InitializeCriticalSection(&numThreads.cs);
-  InitializeCriticalSection(&numOnce.cs);
-
-#if 0
-  /*       once thrd  prio change */
-  printf("once thrd  prio  error\n");
-#endif
-
-  /*
-   * Set the priority class to realtime - otherwise normal
-   * Windows random priority boosting will obscure any problems.
-   */
-  SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
-  /* Set main thread to lower prio than threads */
-  SetThreadPriority(GetCurrentThread(), -2);
-
-  for (j = 0; j < NUM_ONCE; j++)
-    {
-      once[j] = o;
-
-      for (i = 0; i < NUM_THREADS; i++)
-        {
-	  bag_t * bag = &threadbag[i][j];
-	  bag->threadnum = i;
-	  bag->oncenum = j;
-          /* GCC build: create was failing with EAGAIN after 790 threads */
-          while (0 != pthread_create(&t[i][j], NULL, mythread, (void *)bag))
-            sched_yield();
-        }
-    }
-
-  for (j = 0; j < NUM_ONCE; j++)
-    for (i = 0; i < NUM_THREADS; i++)
-      if (pthread_join(t[i][j], NULL) != 0)
-        printf("Join failed for [thread,once] = [%d,%d]\n", i, j);
-
-  /*
-   * All threads will cancel, none will return normally from
-   * pthread_once and so numThreads should never be incremented. However,
-   * numOnce should be incremented by every thread (NUM_THREADS*NUM_ONCE).
-   */
-  assert(numOnce.i == NUM_ONCE * NUM_THREADS);
-  assert(numThreads.i == 0);
-
-  DeleteCriticalSection(&numOnce.cs);
-  DeleteCriticalSection(&numThreads.cs);
-  DeleteCriticalSection(&print_lock);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/openmp1.c b/deps/w32-pthreads/tests/openmp1.c
deleted file mode 100644
index ee36e75..0000000
--- a/deps/w32-pthreads/tests/openmp1.c
+++ /dev/null
@@ -1,140 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef _OPENMP
-#  include <omp.h>
-#endif
-#include <pthread.h>
-
-enum {
-  Size = 10000
-};
-
-const int  ShouldSum = (Size-1)*Size/2;
-
-short Verbose = 1;
-
-short ThreadOK[3] = {0,0,0}; // Main, Thread1, Thread2
-
-// Thread
-void *_thread(void* Id) {
-  int i;
-  int x[Size];
-
-#ifdef _OPENMP
-#  pragma omp parallel for
-#endif
-  for ( i = 0; i < Size; i++ ) {
-#ifdef _OPENMP
-    if (Verbose && i%1000==0) {
-      int tid = omp_get_thread_num();
-#  pragma omp critical
-      printf("thread %d : tid %d handles %d\n",(int)Id,tid,i);
-    }
-#endif
-
-    x[i] = i;
-  }
-
-  int Sum=0;
-  for ( i = 0; i < Size; i++ ) {
-    Sum += x[i];
-  }
-  if (Verbose) {
-#ifdef _OPENMP
-#  pragma omp critical
-#endif
-    printf("Id %d : %s : %d(should be %d)\n",(int)Id, __FUNCTION__, Sum,ShouldSum);
-  }
-  if (Sum == ShouldSum) ThreadOK[(int)Id] = 1;
-  return NULL;
-}
-
-// MainThread
-void MainThread() {
-  int i;
-
-#ifdef _OPENMP
-#  pragma omp parallel for
-#endif
-  for ( i = 0; i < 4; i++ ) {
-#ifdef _OPENMP
-      int tid = omp_get_thread_num();
-#  pragma omp critical
-      printf("Main : tid %d\n",tid);
-      _thread((void *)tid);
-#endif
-  }
-  return;
-}
-
-// Comment in/out for checking the effect of multiple threads.
-#define SPAWN_THREADS
-
-// main
-int main(int argc, char *argv[]) {
-
-  if (argc>1) Verbose = 1;
-
-#ifdef _OPENMP
-  omp_set_nested(-1);
-  printf("%s%s%s\n", "Nested parallel blocks are ", omp_get_nested()?" ":"NOT ", "supported.");
-#endif
-
-  MainThread();
-
-#ifdef SPAWN_THREADS
-  {
-    pthread_t a_thr;
-    pthread_t b_thr;
-    int status;
-
-    printf("%s:%d - %s - a_thr:%p - b_thr:%p\n",
-           __FILE__,__LINE__,__FUNCTION__,a_thr.p,b_thr.p);
-
-    status = pthread_create(&a_thr, NULL, _thread, (void*) 1 );
-    if ( status != 0 ) {
-      printf("Failed to create thread 1\n");
-      return (-1);
-    }
-
-    status = pthread_create(&b_thr, NULL, _thread, (void*) 2 );
-    if ( status != 0 ) {
-      printf("Failed to create thread 2\n");
-      return (-1);
-    }
-
-    status = pthread_join(a_thr, NULL);
-    if ( status != 0 ) {
-      printf("Failed to join thread 1\n");
-      return (-1);
-    }
-    printf("Joined thread1\n");
-
-    status = pthread_join(b_thr, NULL);
-    if ( status != 0 ) {
-      printf("Failed to join thread 2\n");
-      return (-1);
-    }
-    printf("Joined thread2\n");
-  }
-#endif // SPAWN_THREADS
-
-  short OK = 0;
-  // Check that we have OpenMP before declaring things OK formally.
-#ifdef _OPENMP
-    OK = 1;
-    {
-      short i;
-      for (i=0;i<3;i++) OK &= ThreadOK[i];
-    }
-    if (OK) printf("OMP : All looks good\n");
-    else printf("OMP : Error\n");
-#else
-    printf("OpenMP seems not enabled ...\n");
-#endif
-
-  return OK?0:1;
-}
-
-//g++ -fopenmp omp_test.c -o omp_test -lpthread
-
diff --git a/deps/w32-pthreads/tests/priority1.c b/deps/w32-pthreads/tests/priority1.c
deleted file mode 100644
index 1bbf8a6..0000000
--- a/deps/w32-pthreads/tests/priority1.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * File: priority1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test thread priority explicit setting using thread attribute.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * -
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-enum {
-  PTW32TEST_THREAD_INIT_PRIO = 0,
-  PTW32TEST_MAXPRIORITIES = 512
-};
-
-int minPrio;
-int maxPrio;
-int validPriorities[PTW32TEST_MAXPRIORITIES];
-
-void *
-func(void * arg)
-{
-  int policy;
-  struct sched_param param;
-  pthread_t threadID = pthread_self();
-
-  assert(pthread_getschedparam(threadID, &policy, &param) == 0);
-  assert(policy == SCHED_OTHER);
-  return (void *) (size_t)(param.sched_priority);
-}
-
-void *
-getValidPriorities(void * arg)
-{
-  int prioSet;
-  pthread_t threadID = pthread_self();
-  HANDLE threadH = pthread_getw32threadhandle_np(threadID);
-
-  printf("Using GetThreadPriority\n");
-  printf("%10s %10s\n", "Set value", "Get value");
-
-  for (prioSet = minPrio;
-       prioSet <= maxPrio;
-       prioSet++)
-    {
-	/*
-       * If prioSet is invalid then the threads priority is unchanged
-       * from the previous value. Make the previous value a known
-       * one so that we can check later.
-       */
-        if (prioSet < 0)
-	  SetThreadPriority(threadH, THREAD_PRIORITY_LOWEST);
-        else
-	  SetThreadPriority(threadH, THREAD_PRIORITY_HIGHEST);
-	SetThreadPriority(threadH, prioSet);
-	validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH);
-	printf("%10d %10d\n", prioSet, validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)]);
-    }
-
-  return (void *) 0;
-}
-
-
-int
-main()
-{
-  pthread_t t;
-  pthread_attr_t attr;
-  void * result = NULL;
-  struct sched_param param;
-
-  assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1);
-  assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1);
-
-  assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0);
-  assert(pthread_join(t, &result) == 0);
-
-  assert(pthread_attr_init(&attr) == 0);
-  assert(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0);
-
-  /* Set the thread's priority to a known initial value. */
-  SetThreadPriority(pthread_getw32threadhandle_np(pthread_self()),
-                    PTW32TEST_THREAD_INIT_PRIO);
-
-  printf("Using pthread_getschedparam\n");
-  printf("%10s %10s %10s\n", "Set value", "Get value", "Win priority");
-
-  for (param.sched_priority = minPrio;
-       param.sched_priority <= maxPrio;
-       param.sched_priority++)
-    {
-      int prio;
-
-      assert(pthread_attr_setschedparam(&attr, &param) == 0);
-      assert(pthread_create(&t, &attr, func, (void *) &attr) == 0);
-
-      assert((prio = GetThreadPriority(pthread_getw32threadhandle_np(t)))
-             == validPriorities[param.sched_priority+(PTW32TEST_MAXPRIORITIES/2)]);
-
-      assert(pthread_join(t, &result) == 0);
-
-      assert(param.sched_priority == (int)(size_t) result);
-      printf("%10d %10d %10d\n", param.sched_priority, (int)(size_t) result, prio);
-    }
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/priority2.c b/deps/w32-pthreads/tests/priority2.c
deleted file mode 100644
index d190202..0000000
--- a/deps/w32-pthreads/tests/priority2.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * File: priority2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test thread priority setting after creation.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * -
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-enum {
-  PTW32TEST_THREAD_INIT_PRIO = 0,
-  PTW32TEST_MAXPRIORITIES = 512
-};
-
-int minPrio;
-int maxPrio;
-int validPriorities[PTW32TEST_MAXPRIORITIES];
-pthread_barrier_t startBarrier, endBarrier;
-
-void * func(void * arg)
-{
-  int policy;
-  int result;
-  struct sched_param param;
-
-  result = pthread_barrier_wait(&startBarrier);
-  assert(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD);
-  assert(pthread_getschedparam(pthread_self(), &policy, &param) == 0);
-  assert(policy == SCHED_OTHER);
-  result = pthread_barrier_wait(&endBarrier);
-  assert(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD);
-  return (void *) (size_t)param.sched_priority;
-}
-
-
-void *
-getValidPriorities(void * arg)
-{
-  int prioSet;
-  pthread_t thread = pthread_self();
-  HANDLE threadH = pthread_getw32threadhandle_np(thread);
-  struct sched_param param;
-
-  for (prioSet = minPrio;
-       prioSet <= maxPrio;
-       prioSet++)
-    {
-	/*
-       * If prioSet is invalid then the threads priority is unchanged
-       * from the previous value. Make the previous value a known
-       * one so that we can check later.
-       */
-        param.sched_priority = prioSet;
-	assert(pthread_setschedparam(thread, SCHED_OTHER, &param) == 0);
-	validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH);
-    }
-
-  return (void *) 0;
-}
-
-
-int
-main()
-{
-  pthread_t t;
-  void * result = NULL;
-  int result2;
-  struct sched_param param;
-
-  assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1);
-  assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1);
-
-  assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0);
-  assert(pthread_join(t, &result) == 0);
-
-  assert(pthread_barrier_init(&startBarrier, NULL, 2) == 0);
-  assert(pthread_barrier_init(&endBarrier, NULL, 2) == 0);
-
-  /* Set the thread's priority to a known initial value.
-   * If the new priority is invalid then the threads priority
-   * is unchanged from the previous value.
-   */
-  SetThreadPriority(pthread_getw32threadhandle_np(pthread_self()),
-                    PTW32TEST_THREAD_INIT_PRIO);
-
-  for (param.sched_priority = minPrio;
-       param.sched_priority <= maxPrio;
-       param.sched_priority++)
-    {
-      assert(pthread_create(&t, NULL, func, NULL) == 0);
-      assert(pthread_setschedparam(t, SCHED_OTHER, &param) == 0);
-      result2 = pthread_barrier_wait(&startBarrier);
-      assert(result2 == 0 || result2 == PTHREAD_BARRIER_SERIAL_THREAD);
-      result2 = pthread_barrier_wait(&endBarrier);
-      assert(result2 == 0 || result2 == PTHREAD_BARRIER_SERIAL_THREAD);
-      assert(GetThreadPriority(pthread_getw32threadhandle_np(t)) ==
-	  validPriorities[param.sched_priority+(PTW32TEST_MAXPRIORITIES/2)]);
-      pthread_join(t, &result);
-      assert(param.sched_priority == (int)(size_t)result);
-    }
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/reuse1.c b/deps/w32-pthreads/tests/reuse1.c
deleted file mode 100644
index a467e77..0000000
--- a/deps/w32-pthreads/tests/reuse1.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * File: reuse1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Confirm that thread reuse works for joined threads.
- *
- * Test Method (Validation or Falsification):
- * -
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * -
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-enum {
-	NUMTHREADS = 100
-};
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  washere = 1;
-  return arg; 
-}
- 
-int
-main()
-{
-  pthread_t t,
-            last_t;
-  pthread_attr_t attr;
-  void * result = NULL;
-  int i;
-
-  assert(pthread_attr_init(&attr) == 0);;
-  assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == 0);
-
-  washere = 0;
-  assert(pthread_create(&t, &attr, func, NULL) == 0);
-  assert(pthread_join(t, &result) == 0);;
-  assert((int)(size_t)result == 0);
-  assert(washere == 1);
-  last_t = t;
-
-  for (i = 1; i < NUMTHREADS; i++)
-    {
-      washere = 0;
-      assert(pthread_create(&t, &attr, func, (void *)(size_t)i) == 0);
-      pthread_join(t, &result);
-      assert((int)(size_t) result == i);
-      assert(washere == 1);
-      /* thread IDs should be unique */
-      assert(!pthread_equal(t, last_t));
-      /* thread struct pointers should be the same */
-      assert(t.p == last_t.p);
-      /* thread handle reuse counter should be different by one */
-      assert(t.x == last_t.x+1);
-      last_t = t;
-    }
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/reuse2.c b/deps/w32-pthreads/tests/reuse2.c
deleted file mode 100644
index 208e81d..0000000
--- a/deps/w32-pthreads/tests/reuse2.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * File: reuse2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test that thread reuse works for detached threads.
- * - Analyse thread struct reuse.
- *
- * Test Method (Validation or Falsification):
- * -
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * -
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * - This test is implementation specific
- * because it uses knowledge of internals that should be
- * opaque to an application.
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-/*
- */
-
-enum {
-	NUMTHREADS = 10000
-};
-
-
-static long done = 0;
-
-void * func(void * arg)
-{
-  sched_yield();
-
-  InterlockedIncrement(&done);
-
-  return (void *) 0; 
-}
- 
-int
-main()
-{
-  pthread_t t[NUMTHREADS];
-  pthread_attr_t attr;
-  int i;
-  unsigned int notUnique = 0,
-	       totalHandles = 0,
-	       reuseMax = 0,
-	       reuseMin = NUMTHREADS;
-
-  assert(pthread_attr_init(&attr) == 0);
-  assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0);
-
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      while(pthread_create(&t[i], &attr, func, NULL) != 0)
-        Sleep(1);
-    }
-
-  while (NUMTHREADS > InterlockedExchangeAdd((LPLONG)&done, 0L))
-    Sleep(100);
-
-  Sleep(100);
-
-  /*
-   * Analyse reuse by computing min and max number of times pthread_create()
-   * returned the same pthread_t value.
-   */
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      if (t[i].p != NULL)
-        {
-          unsigned int j, thisMax;
-
-          thisMax = t[i].x;
-
-          for (j = i+1; j < NUMTHREADS; j++)
-            if (t[i].p == t[j].p)
-              {
-		if (t[i].x == t[j].x)
-		  notUnique++;
-                if (thisMax < t[j].x)
-                  thisMax = t[j].x;
-                t[j].p = NULL;
-              }
-
-          if (reuseMin > thisMax)
-            reuseMin = thisMax;
-
-          if (reuseMax < thisMax)
-            reuseMax = thisMax;
-        }
-    }
-
-  for (i = 0; i < NUMTHREADS; i++)
-    if (t[i].p != NULL)
-      totalHandles++;
-
-  /*
-   * pthread_t reuse counts start at 0, so we need to add 1
-   * to the max and min values derived above.
-   */
-  printf("For %d total threads:\n", NUMTHREADS);
-  printf("Non-unique IDs = %d\n", notUnique);
-  printf("Reuse maximum  = %d\n", reuseMax + 1);
-  printf("Reuse minimum  = %d\n", reuseMin + 1);
-  printf("Total handles  = %d\n", totalHandles);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/robust1.c b/deps/w32-pthreads/tests/robust1.c
deleted file mode 100644
index 04f0655..0000000
--- a/deps/w32-pthreads/tests/robust1.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* 
- * robust1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * For all robust mutex types.
- * Thread A locks mutex
- * Thread A terminates with no threads waiting on robust mutex
- * Thread B acquires (inherits) mutex and unlocks
- * Main attempts to lock mutex with unrecovered state.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *	pthread_mutex_init()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- *	pthread_mutex_destroy()
- *	pthread_mutexattr_init()
- *	pthread_mutexattr_setrobust()
- *	pthread_mutexattr_settype()
- *	pthread_mutexattr_destroy()
- */
-
-#include "test.h"
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-
-void * owner(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-
-  return 0;
-}
- 
-void * inheritor(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == EOWNERDEAD);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return 0;
-}
- 
-int
-main()
-{
-  pthread_t to, ti;
-  pthread_mutexattr_t ma;
-
-  assert(pthread_mutexattr_init(&ma) == 0);
-  assert(pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) == 0);
-
-  /* Default (NORMAL) type */ 
-  lockCount = 0;
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE);
-  assert(pthread_mutex_unlock(&mutex) == EPERM);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  /* NORMAL type */ 
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0);
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE);
-  assert(pthread_mutex_unlock(&mutex) == EPERM);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  /* ERRORCHECK type */ 
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0);
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE);
-  assert(pthread_mutex_unlock(&mutex) == EPERM);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  /* RECURSIVE type */ 
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0);
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE);
-  assert(pthread_mutex_unlock(&mutex) == EPERM);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  assert(pthread_mutexattr_destroy(&ma) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/robust2.c b/deps/w32-pthreads/tests/robust2.c
deleted file mode 100644
index c269842..0000000
--- a/deps/w32-pthreads/tests/robust2.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* 
- * robust2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * For all robust mutex types.
- * Thread A locks mutex
- * Thread B blocks on mutex
- * Thread A terminates with threads waiting on robust mutex
- * Thread B awakes and inherits mutex and unlocks
- * Main attempts to lock mutex with unrecovered state.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *	pthread_mutex_init()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- *	pthread_mutex_destroy()
- *	pthread_mutexattr_init()
- *	pthread_mutexattr_setrobust()
- *	pthread_mutexattr_settype()
- *	pthread_mutexattr_destroy()
- */
-
-#include "test.h"
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-
-void * owner(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  Sleep(200);
-
-  return 0;
-}
- 
-void * inheritor(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == EOWNERDEAD);
-  lockCount++;
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return 0;
-}
- 
-int
-main()
-{
-  pthread_t to, ti;
-  pthread_mutexattr_t ma;
-
-  assert(pthread_mutexattr_init(&ma) == 0);
-  assert(pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) == 0);
-
-  /* Default (NORMAL) type */ 
-  lockCount = 0;
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  /* NORMAL type */ 
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0);
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  /* ERRORCHECK type */ 
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0);
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  /* RECURSIVE type */ 
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0);
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  assert(pthread_mutexattr_destroy(&ma) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/robust3.c b/deps/w32-pthreads/tests/robust3.c
deleted file mode 100644
index bff868b..0000000
--- a/deps/w32-pthreads/tests/robust3.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* 
- * robust3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * For all robust mutex types.
- * Thread A locks mutex
- * Thread B blocks on mutex
- * Thread A terminates with threads waiting on robust mutex
- * Thread B awakes and inherits mutex, sets consistent and unlocks
- * Main acquires mutex with recovered state.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *	pthread_mutex_init()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- *	pthread_mutex_consistent()
- *	pthread_mutex_destroy()
- *	pthread_mutexattr_init()
- *	pthread_mutexattr_setrobust()
- *	pthread_mutexattr_settype()
- *	pthread_mutexattr_destroy()
- */
-
-#include "test.h"
-
-static int lockCount;
-
-static pthread_mutex_t mutex;
-
-void * owner(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == 0);
-  lockCount++;
-  Sleep(200);
-
-  return 0;
-}
- 
-void * inheritor(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex) == EOWNERDEAD);
-  lockCount++;
-  assert(pthread_mutex_consistent(&mutex) == 0);
-  assert(pthread_mutex_unlock(&mutex) == 0);
-
-  return 0;
-}
- 
-int
-main()
-{
-  pthread_t to, ti;
-  pthread_mutexattr_t ma;
-
-  assert(pthread_mutexattr_init(&ma) == 0);
-  assert(pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) == 0);
-
-  /* Default (NORMAL) type */ 
-  lockCount = 0;
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == 0);
-  assert(pthread_mutex_unlock(&mutex) == 0);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  /* NORMAL type */ 
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0);
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == 0);
-  assert(pthread_mutex_unlock(&mutex) == 0);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  /* ERRORCHECK type */ 
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0);
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == 0);
-  assert(pthread_mutex_unlock(&mutex) == 0);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  /* RECURSIVE type */ 
-  lockCount = 0;
-  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0);
-  assert(pthread_mutex_init(&mutex, &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 2);
-  assert(pthread_mutex_lock(&mutex) == 0);
-  assert(pthread_mutex_unlock(&mutex) == 0);
-  assert(pthread_mutex_destroy(&mutex) == 0);
-
-  assert(pthread_mutexattr_destroy(&ma) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/robust4.c b/deps/w32-pthreads/tests/robust4.c
deleted file mode 100644
index d284330..0000000
--- a/deps/w32-pthreads/tests/robust4.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/* 
- * robust4.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Thread A locks multiple robust mutexes
- * Thread B blocks on same mutexes in different orderings
- * Thread A terminates with thread waiting on mutexes
- * Thread B awakes and inherits each mutex in turn, sets consistent and unlocks
- * Main acquires mutexes with recovered state.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *	pthread_mutex_init()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- *	pthread_mutex_destroy()
- *	pthread_mutexattr_init()
- *	pthread_mutexattr_setrobust()
- *	pthread_mutexattr_settype()
- *	pthread_mutexattr_destroy()
- */
-
-#include "test.h"
-
-static int lockCount;
-
-static pthread_mutex_t mutex[3];
-
-void * owner(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex[0]) == 0);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex[1]) == 0);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex[2]) == 0);
-  lockCount++;
-  Sleep(200);
-
-  return 0;
-}
- 
-void * inheritor(void * arg)
-{
-  int* o = (int*)arg;
-
-  assert(pthread_mutex_lock(&mutex[o[0]]) == EOWNERDEAD);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex[o[1]]) == EOWNERDEAD);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex[o[2]]) == EOWNERDEAD);
-  lockCount++;
-  assert(pthread_mutex_consistent(&mutex[o[2]]) == 0);
-  assert(pthread_mutex_consistent(&mutex[o[1]]) == 0);
-  assert(pthread_mutex_consistent(&mutex[o[0]]) == 0);
-  assert(pthread_mutex_unlock(&mutex[o[2]]) == 0);
-  assert(pthread_mutex_unlock(&mutex[o[1]]) == 0);
-  assert(pthread_mutex_unlock(&mutex[o[0]]) == 0);
-
-  return 0;
-}
- 
-int
-main()
-{
-  pthread_t to, ti;
-  pthread_mutexattr_t ma;
-  int order[3];
-
-  assert(pthread_mutexattr_init(&ma) == 0);
-  assert(pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) == 0);
-
-  order[0]=0;
-  order[1]=1;
-  order[2]=2;
-  lockCount = 0;
-  assert(pthread_mutex_init(&mutex[0], &ma) == 0);
-  assert(pthread_mutex_init(&mutex[1], &ma) == 0);
-  assert(pthread_mutex_init(&mutex[2], &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, (void *)order) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 6);
-  assert(pthread_mutex_lock(&mutex[0]) == 0);
-  assert(pthread_mutex_unlock(&mutex[0]) == 0);
-  assert(pthread_mutex_destroy(&mutex[0]) == 0);
-  assert(pthread_mutex_lock(&mutex[1]) == 0);
-  assert(pthread_mutex_unlock(&mutex[1]) == 0);
-  assert(pthread_mutex_destroy(&mutex[1]) == 0);
-  assert(pthread_mutex_lock(&mutex[2]) == 0);
-  assert(pthread_mutex_unlock(&mutex[2]) == 0);
-  assert(pthread_mutex_destroy(&mutex[2]) == 0);
-
-  order[0]=1;
-  order[1]=0;
-  order[2]=2;
-  lockCount = 0;
-  assert(pthread_mutex_init(&mutex[0], &ma) == 0);
-  assert(pthread_mutex_init(&mutex[1], &ma) == 0);
-  assert(pthread_mutex_init(&mutex[2], &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, (void *)order) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 6);
-  assert(pthread_mutex_lock(&mutex[0]) == 0);
-  assert(pthread_mutex_unlock(&mutex[0]) == 0);
-  assert(pthread_mutex_destroy(&mutex[0]) == 0);
-  assert(pthread_mutex_lock(&mutex[1]) == 0);
-  assert(pthread_mutex_unlock(&mutex[1]) == 0);
-  assert(pthread_mutex_destroy(&mutex[1]) == 0);
-  assert(pthread_mutex_lock(&mutex[2]) == 0);
-  assert(pthread_mutex_unlock(&mutex[2]) == 0);
-  assert(pthread_mutex_destroy(&mutex[2]) == 0);
-
-  order[0]=0;
-  order[1]=2;
-  order[2]=1;
-  lockCount = 0;
-  assert(pthread_mutex_init(&mutex[0], &ma) == 0);
-  assert(pthread_mutex_init(&mutex[1], &ma) == 0);
-  assert(pthread_mutex_init(&mutex[2], &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, (void *)order) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 6);
-  assert(pthread_mutex_lock(&mutex[0]) == 0);
-  assert(pthread_mutex_unlock(&mutex[0]) == 0);
-  assert(pthread_mutex_destroy(&mutex[0]) == 0);
-  assert(pthread_mutex_lock(&mutex[1]) == 0);
-  assert(pthread_mutex_unlock(&mutex[1]) == 0);
-  assert(pthread_mutex_destroy(&mutex[1]) == 0);
-  assert(pthread_mutex_lock(&mutex[2]) == 0);
-  assert(pthread_mutex_unlock(&mutex[2]) == 0);
-  assert(pthread_mutex_destroy(&mutex[2]) == 0);
-
-  order[0]=2;
-  order[1]=1;
-  order[2]=0;
-  lockCount = 0;
-  assert(pthread_mutex_init(&mutex[0], &ma) == 0);
-  assert(pthread_mutex_init(&mutex[1], &ma) == 0);
-  assert(pthread_mutex_init(&mutex[2], &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&ti, NULL, inheritor, (void *)order) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 6);
-  assert(pthread_mutex_lock(&mutex[0]) == 0);
-  assert(pthread_mutex_unlock(&mutex[0]) == 0);
-  assert(pthread_mutex_destroy(&mutex[0]) == 0);
-  assert(pthread_mutex_lock(&mutex[1]) == 0);
-  assert(pthread_mutex_unlock(&mutex[1]) == 0);
-  assert(pthread_mutex_destroy(&mutex[1]) == 0);
-  assert(pthread_mutex_lock(&mutex[2]) == 0);
-  assert(pthread_mutex_unlock(&mutex[2]) == 0);
-  assert(pthread_mutex_destroy(&mutex[2]) == 0);
-
-  assert(pthread_mutexattr_destroy(&ma) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/robust5.c b/deps/w32-pthreads/tests/robust5.c
deleted file mode 100644
index de8ae36..0000000
--- a/deps/w32-pthreads/tests/robust5.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* 
- * robust5.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Thread A locks multiple robust mutexes
- * Thread B blocks on same mutexes
- * Thread A terminates with thread waiting on mutexes
- * Thread B awakes and inherits each mutex in turn
- * Thread B terminates leaving orphaned mutexes
- * Main inherits mutexes, sets consistent and unlocks.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *	pthread_mutex_init()
- *	pthread_mutex_lock()
- *	pthread_mutex_unlock()
- *	pthread_mutex_destroy()
- *	pthread_mutexattr_init()
- *	pthread_mutexattr_setrobust()
- *	pthread_mutexattr_settype()
- *	pthread_mutexattr_destroy()
- */
-
-#include "test.h"
-
-static int lockCount;
-
-static pthread_mutex_t mutex[3];
-
-void * owner(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex[0]) == 0);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex[1]) == 0);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex[2]) == 0);
-  lockCount++;
-
-  return 0;
-}
- 
-void * inheritor(void * arg)
-{
-  assert(pthread_mutex_lock(&mutex[0]) == EOWNERDEAD);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex[1]) == EOWNERDEAD);
-  lockCount++;
-  assert(pthread_mutex_lock(&mutex[2]) == EOWNERDEAD);
-  lockCount++;
-
-  return 0;
-}
- 
-int
-main()
-{
-  pthread_t to, ti;
-  pthread_mutexattr_t ma;
-
-  assert(pthread_mutexattr_init(&ma) == 0);
-  assert(pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) == 0);
-
-  lockCount = 0;
-  assert(pthread_mutex_init(&mutex[0], &ma) == 0);
-  assert(pthread_mutex_init(&mutex[1], &ma) == 0);
-  assert(pthread_mutex_init(&mutex[2], &ma) == 0);
-  assert(pthread_create(&to, NULL, owner, NULL) == 0);
-  assert(pthread_join(to, NULL) == 0);
-  assert(pthread_create(&ti, NULL, inheritor, NULL) == 0);
-  assert(pthread_join(ti, NULL) == 0);
-  assert(lockCount == 6);
-  assert(pthread_mutex_lock(&mutex[0]) == EOWNERDEAD);
-  assert(pthread_mutex_consistent(&mutex[0]) == 0);
-  assert(pthread_mutex_unlock(&mutex[0]) == 0);
-  assert(pthread_mutex_destroy(&mutex[0]) == 0);
-  assert(pthread_mutex_lock(&mutex[1]) == EOWNERDEAD);
-  assert(pthread_mutex_consistent(&mutex[1]) == 0);
-  assert(pthread_mutex_unlock(&mutex[1]) == 0);
-  assert(pthread_mutex_destroy(&mutex[1]) == 0);
-  assert(pthread_mutex_lock(&mutex[2]) == EOWNERDEAD);
-  assert(pthread_mutex_consistent(&mutex[2]) == 0);
-  assert(pthread_mutex_unlock(&mutex[2]) == 0);
-  assert(pthread_mutex_destroy(&mutex[2]) == 0);
-
-  assert(pthread_mutexattr_destroy(&ma) == 0);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock1.c b/deps/w32-pthreads/tests/rwlock1.c
deleted file mode 100644
index 3063763..0000000
--- a/deps/w32-pthreads/tests/rwlock1.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* 
- * rwlock1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Create a simple rwlock object and then destroy it.
- *
- * Depends on API functions:
- * 	pthread_rwlock_init()
- *	pthread_rwlock_destroy()
- */
-
-#include "test.h"
-
-pthread_rwlock_t rwlock = NULL;
-
-int
-main()
-{
-  assert(rwlock == NULL);
-
-  assert(pthread_rwlock_init(&rwlock, NULL) == 0);
-
-  assert(rwlock != NULL);
-
-  assert(pthread_rwlock_destroy(&rwlock) == 0);
-
-  assert(rwlock == NULL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock2.c b/deps/w32-pthreads/tests/rwlock2.c
deleted file mode 100644
index b99f05a..0000000
--- a/deps/w32-pthreads/tests/rwlock2.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* 
- * rwlock2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static rwlock object, lock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *	pthread_rwlock_rdlock()
- *	pthread_rwlock_unlock()
- */
-
-#include "test.h"
- 
-pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
-
-int
-main()
-{
-  assert(rwlock == PTHREAD_RWLOCK_INITIALIZER);
-
-  assert(pthread_rwlock_rdlock(&rwlock) == 0);
-
-  assert(rwlock != PTHREAD_RWLOCK_INITIALIZER);
-
-  assert(rwlock != NULL);
-
-  assert(pthread_rwlock_unlock(&rwlock) == 0);
-
-  assert(pthread_rwlock_destroy(&rwlock) == 0);
-
-  assert(rwlock == NULL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock2_t.c b/deps/w32-pthreads/tests/rwlock2_t.c
deleted file mode 100644
index 0f41d7f..0000000
--- a/deps/w32-pthreads/tests/rwlock2_t.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 
- * rwlock2_t.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static rwlock object, timed-lock it, 
- * and then unlock it again.
- *
- * Depends on API functions:
- *	pthread_rwlock_timedrdlock()
- *	pthread_rwlock_unlock()
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
-
-int
-main()
-{
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 1;
-
-  assert(rwlock == PTHREAD_RWLOCK_INITIALIZER);
-
-  assert(pthread_rwlock_timedrdlock(&rwlock, &abstime) == 0);
-
-  assert(rwlock != PTHREAD_RWLOCK_INITIALIZER);
-
-  assert(rwlock != NULL);
-
-  assert(pthread_rwlock_unlock(&rwlock) == 0);
-
-  assert(pthread_rwlock_destroy(&rwlock) == 0);
-
-  assert(rwlock == NULL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock3.c b/deps/w32-pthreads/tests/rwlock3.c
deleted file mode 100644
index e27f7ed..0000000
--- a/deps/w32-pthreads/tests/rwlock3.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 
- * rwlock3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static rwlock object, wrlock it, trywrlock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *	pthread_create()
- *	pthread_join()
- *	pthread_rwlock_wrlock()
- *	pthread_rwlock_trywrlock()
- *	pthread_rwlock_unlock()
- */
-
-#include "test.h"
- 
-pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY);
-
-  washere = 1;
-
-  return 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_rwlock_wrlock(&rwlock1) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-
-  assert(pthread_join(t, NULL) == 0);
-
-  assert(pthread_rwlock_unlock(&rwlock1) == 0);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock3_t.c b/deps/w32-pthreads/tests/rwlock3_t.c
deleted file mode 100644
index 7cbc987..0000000
--- a/deps/w32-pthreads/tests/rwlock3_t.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* 
- * rwlock3_t.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static rwlock object, timed-wrlock it, trywrlock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *	pthread_rwlock_timedwrlock()
- *	pthread_rwlock_trywrlock()
- *	pthread_rwlock_unlock()
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY);
-
-  washere = 1;
-
-  return 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 1;
-
-  assert(pthread_rwlock_timedwrlock(&rwlock1, &abstime) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-
-  Sleep(2000);
-
-  assert(pthread_rwlock_unlock(&rwlock1) == 0);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock4.c b/deps/w32-pthreads/tests/rwlock4.c
deleted file mode 100644
index 863784f..0000000
--- a/deps/w32-pthreads/tests/rwlock4.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 
- * rwlock4.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static rwlock object, rdlock it, trywrlock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- * 	pthread_create()
- * 	pthread_join()
- *	pthread_rwlock_rdlock()
- *	pthread_rwlock_trywrlock()
- *	pthread_rwlock_unlock()
- */
-
-#include "test.h"
- 
-pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY);
-
-  washere = 1;
-
-  return 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_rwlock_rdlock(&rwlock1) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-
-  assert(pthread_join(t, NULL) == 0);
-
-  assert(pthread_rwlock_unlock(&rwlock1) == 0);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock4_t.c b/deps/w32-pthreads/tests/rwlock4_t.c
deleted file mode 100644
index 41ce795..0000000
--- a/deps/w32-pthreads/tests/rwlock4_t.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* 
- * rwlock4_t.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static rwlock object, timed-rdlock it, trywrlock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *	pthread_rwlock_timedrdlock()
- *	pthread_rwlock_trywrlock()
- *	pthread_rwlock_unlock()
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY);
-
-  washere = 1;
-
-  return 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 1;
-
-  assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-
-  Sleep(2000);
-
-  assert(pthread_rwlock_unlock(&rwlock1) == 0);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock5.c b/deps/w32-pthreads/tests/rwlock5.c
deleted file mode 100644
index d87b19c..0000000
--- a/deps/w32-pthreads/tests/rwlock5.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* 
- * rwlock5.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static rwlock object, rdlock it, tryrdlock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *      pthread_create()
- *      pthread_join()
- *	pthread_rwlock_rdlock()
- *	pthread_rwlock_tryrdlock()
- *	pthread_rwlock_unlock()
- */
-
-#include "test.h"
- 
-pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  assert(pthread_rwlock_tryrdlock(&rwlock1) == 0);
-
-  assert(pthread_rwlock_unlock(&rwlock1) == 0);
-
-  washere = 1;
-
-  return 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_rwlock_rdlock(&rwlock1) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-
-  assert(pthread_join(t, NULL) == 0);
-
-  assert(pthread_rwlock_unlock(&rwlock1) == 0);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock5_t.c b/deps/w32-pthreads/tests/rwlock5_t.c
deleted file mode 100644
index 6280ce2..0000000
--- a/deps/w32-pthreads/tests/rwlock5_t.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* 
- * rwlock5_t.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static rwlock object, timed-rdlock it, tryrdlock it, 
- * and then unlock it again.
- *
- * Depends on API functions: 
- *	pthread_rwlock_timedrdlock()
- *	pthread_rwlock_tryrdlock()
- *	pthread_rwlock_unlock()
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  assert(pthread_rwlock_tryrdlock(&rwlock1) == 0);
-
-  assert(pthread_rwlock_unlock(&rwlock1) == 0);
-
-  washere = 1;
-
-  return 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 1;
-
-  assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-
-  Sleep(2000);
-
-  assert(pthread_rwlock_unlock(&rwlock1) == 0);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock6.c b/deps/w32-pthreads/tests/rwlock6.c
deleted file mode 100644
index 3241c8f..0000000
--- a/deps/w32-pthreads/tests/rwlock6.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * rwlock6.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Check writer and reader locking
- *
- * Depends on API functions:
- *      pthread_rwlock_rdlock()
- *      pthread_rwlock_wrlock()
- *      pthread_rwlock_unlock()
- */
-
-#include "test.h"
-
-static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
-
-static int bankAccount = 0;
-
-void * wrfunc(void * arg)
-{
-  int ba;
-
-  assert(pthread_rwlock_wrlock(&rwlock1) == 0);
-  Sleep(200);
-  bankAccount += 10;
-  ba = bankAccount;
-  assert(pthread_rwlock_unlock(&rwlock1) == 0);
-
-  return ((void *)(size_t)ba);
-}
-
-void * rdfunc(void * arg)
-{
-  int ba;
-
-  assert(pthread_rwlock_rdlock(&rwlock1) == 0);
-  ba = bankAccount;
-  assert(pthread_rwlock_unlock(&rwlock1) == 0);
-
-  return ((void *)(size_t)ba);
-}
-
-int
-main()
-{
-  pthread_t wrt1;
-  pthread_t wrt2;
-  pthread_t rdt;
-  void* wr1Result = (void*)0;
-  void* wr2Result = (void*)0;
-  void* rdResult = (void*)0;
-
-  bankAccount = 0;
-
-  assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0);
-  Sleep(50);
-  assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0);
-  Sleep(50);
-  assert(pthread_create(&wrt2, NULL, wrfunc, NULL) == 0);
-
-  assert(pthread_join(wrt1, &wr1Result) == 0);
-  assert(pthread_join(rdt, &rdResult) == 0);
-  assert(pthread_join(wrt2, &wr2Result) == 0);
-
-  assert((int)(size_t)wr1Result == 10);
-  assert((int)(size_t)rdResult == 10);
-  assert((int)(size_t)wr2Result == 20);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock6_t.c b/deps/w32-pthreads/tests/rwlock6_t.c
deleted file mode 100644
index 8e664e7..0000000
--- a/deps/w32-pthreads/tests/rwlock6_t.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * rwlock6_t.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Check writer and reader locking with reader timeouts
- *
- * Depends on API functions: 
- *      pthread_rwlock_timedrdlock()
- *      pthread_rwlock_wrlock()
- *      pthread_rwlock_unlock()
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
-
-static int bankAccount = 0;
-
-void * wrfunc(void * arg)
-{
-  assert(pthread_rwlock_wrlock(&rwlock1) == 0);
-  Sleep(2000);
-  bankAccount += 10;
-  assert(pthread_rwlock_unlock(&rwlock1) == 0);
-
-  return ((void *)(size_t)bankAccount);
-}
-
-void * rdfunc(void * arg)
-{
-  int ba = -1;
-  struct timespec abstime = { 0, 0 };
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-
-  if ((int) (size_t)arg == 1)
-    {
-      abstime.tv_sec += 1;
-      assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == ETIMEDOUT);
-      ba = 0;
-    }
-  else if ((int) (size_t)arg == 2)
-    {
-      abstime.tv_sec += 3;
-      assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0);
-      ba = bankAccount;
-      assert(pthread_rwlock_unlock(&rwlock1) == 0);
-    }
-
-  return ((void *)(size_t)ba);
-}
-
-int
-main()
-{
-  pthread_t wrt1;
-  pthread_t wrt2;
-  pthread_t rdt1;
-  pthread_t rdt2;
-  void* wr1Result = (void*)0;
-  void* wr2Result = (void*)0;
-  void* rd1Result = (void*)0;
-  void* rd2Result = (void*)0;
-
-  bankAccount = 0;
-
-  assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0);
-  Sleep(500);
-  assert(pthread_create(&rdt1, NULL, rdfunc, (void *)(size_t)1) == 0);
-  Sleep(500);
-  assert(pthread_create(&wrt2, NULL, wrfunc, NULL) == 0);
-  Sleep(500);
-  assert(pthread_create(&rdt2, NULL, rdfunc, (void *)(size_t)2) == 0);
-
-  assert(pthread_join(wrt1, &wr1Result) == 0);
-  assert(pthread_join(rdt1, &rd1Result) == 0);
-  assert(pthread_join(wrt2, &wr2Result) == 0);
-  assert(pthread_join(rdt2, &rd2Result) == 0);
-
-  assert((int)(size_t)wr1Result == 10);
-  assert((int)(size_t)rd1Result == 0);
-  assert((int)(size_t)wr2Result == 20);
-  assert((int)(size_t)rd2Result == 20);
-
-  return 0;
-}
-
-
diff --git a/deps/w32-pthreads/tests/rwlock6_t2.c b/deps/w32-pthreads/tests/rwlock6_t2.c
deleted file mode 100644
index 2e6d7ce..0000000
--- a/deps/w32-pthreads/tests/rwlock6_t2.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * rwlock6_t2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Check writer and reader timeouts.
- *
- * Depends on API functions: 
- *      pthread_rwlock_timedrdlock()
- *      pthread_rwlock_timedwrlock()
- *      pthread_rwlock_unlock()
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
-
-static int bankAccount = 0;
-struct timespec abstime = { 0, 0 };
-
-void * wrfunc(void * arg)
-{
-  int result;
-
-  result = pthread_rwlock_timedwrlock(&rwlock1, &abstime);
-  if ((int) (size_t)arg == 1)
-    {
-      assert(result == 0);
-      Sleep(2000);
-      bankAccount += 10;
-      assert(pthread_rwlock_unlock(&rwlock1) == 0);
-      return ((void *)(size_t)bankAccount);
-    }
-  else if ((int) (size_t)arg == 2)
-    {
-      assert(result == ETIMEDOUT);
-      return ((void *) 100);
-    }
-
-  return ((void *)(size_t)-1);
-}
-
-void * rdfunc(void * arg)
-{
-  int ba = 0;
-
-  assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == ETIMEDOUT);
-
-  return ((void *)(size_t)ba);
-}
-
-int
-main()
-{
-  pthread_t wrt1;
-  pthread_t wrt2;
-  pthread_t rdt;
-  void* wr1Result = (void*)0;
-  void* wr2Result = (void*)0;
-  void* rdResult = (void*)0;
-  PTW32_STRUCT_TIMEB currSysTime;
-  const DWORD NANOSEC_PER_MILLISEC = 1000000;
-
-  PTW32_FTIME(&currSysTime);
-
-  abstime.tv_sec = (long)currSysTime.time;
-  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
-
-  abstime.tv_sec += 1;
-
-  bankAccount = 0;
-
-  assert(pthread_create(&wrt1, NULL, wrfunc, (void *)(size_t)1) == 0);
-  Sleep(100);
-  assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0);
-  Sleep(100);
-  assert(pthread_create(&wrt2, NULL, wrfunc, (void *)(size_t)2) == 0);
-
-  assert(pthread_join(wrt1, &wr1Result) == 0);
-  assert(pthread_join(rdt, &rdResult) == 0);
-  assert(pthread_join(wrt2, &wr2Result) == 0);
-
-  assert((int)(size_t)wr1Result == 10);
-  assert((int)(size_t)rdResult == 0);
-  assert((int)(size_t)wr2Result == 100);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock7.c b/deps/w32-pthreads/tests/rwlock7.c
deleted file mode 100644
index 69d1a73..0000000
--- a/deps/w32-pthreads/tests/rwlock7.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * rwlock7.c
- *
- * Hammer on a bunch of rwlocks to test robustness and fairness.
- * Printed stats should be roughly even for each thread.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-#ifdef __GNUC__
-#include <stdlib.h>
-#endif
-
-#define THREADS         5
-#define DATASIZE        7
-#define ITERATIONS      1000000
-
-/*
- * Keep statistics for each thread.
- */
-typedef struct thread_tag {
-  int         thread_num;
-  pthread_t   thread_id;
-  int         updates;
-  int         reads;
-  int         changed;
-  int         seed;
-} thread_t;
-
-/*
- * Read-write lock and shared data
- */
-typedef struct data_tag {
-  pthread_rwlock_t    lock;
-  int                 data;
-  int                 updates;
-} data_t;
-
-static thread_t threads[THREADS];
-static data_t data[DATASIZE];
-
-/*
- * Thread start routine that uses read-write locks
- */
-void *thread_routine (void *arg)
-{
-  thread_t *self = (thread_t*)arg;
-  int iteration;
-  int element = 0;
-  int seed = self->seed;
-  int interval = 1 + rand_r (&seed) % 71;
-
-  self->changed = 0;
-
-  for (iteration = 0; iteration < ITERATIONS; iteration++)
-    {
-      if (iteration % (ITERATIONS / 10) == 0)
-        {
-          putchar('.');
-          fflush(stdout);
-        }
-      /*
-       * Each "self->interval" iterations, perform an
-       * update operation (write lock instead of read
-       * lock).
-       */
-      if ((iteration % interval) == 0)
-        {
-          assert(pthread_rwlock_wrlock (&data[element].lock) == 0);
-          data[element].data = self->thread_num;
-          data[element].updates++;
-          self->updates++;
-	  interval = 1 + rand_r (&seed) % 71;
-          assert(pthread_rwlock_unlock (&data[element].lock) == 0);
-        } else {
-          /*
-           * Look at the current data element to see whether
-           * the current thread last updated it. Count the
-           * times, to report later.
-           */
-          assert(pthread_rwlock_rdlock (&data[element].lock) == 0);
-
-          self->reads++;
-
-          if (data[element].data != self->thread_num)
-            {
-              self->changed++;
-	      interval = 1 + self->changed % 71;
-            }
-
-          assert(pthread_rwlock_unlock (&data[element].lock) == 0);
-        }
-
-      element = (element + 1) % DATASIZE;
-
-    }
-
-  return NULL;
-}
-
-int
-main (int argc, char *argv[])
-{
-  int count;
-  int data_count;
-  int thread_updates = 0;
-  int data_updates = 0;
-  int seed = 1;
-
-  PTW32_STRUCT_TIMEB currSysTime1;
-  PTW32_STRUCT_TIMEB currSysTime2;
-
-  /*
-   * Initialize the shared data.
-   */
-  for (data_count = 0; data_count < DATASIZE; data_count++)
-    {
-      data[data_count].data = 0;
-      data[data_count].updates = 0;
-
-      assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0);
-    }
-
-  PTW32_FTIME(&currSysTime1);
-
-  /*
-   * Create THREADS threads to access shared data.
-   */
-  for (count = 0; count < THREADS; count++)
-    {
-      threads[count].thread_num = count;
-      threads[count].updates = 0;
-      threads[count].reads = 0;
-      threads[count].seed = 1 + rand_r (&seed) % 71;
-
-      assert(pthread_create (&threads[count].thread_id,
-                             NULL, thread_routine, (void*)(size_t)&threads[count]) == 0);
-    }
-
-  /*
-   * Wait for all threads to complete, and collect
-   * statistics.
-   */
-  for (count = 0; count < THREADS; count++)
-    {
-      assert(pthread_join (threads[count].thread_id, NULL) == 0);
-    }
-
-  putchar('\n');
-  fflush(stdout);
-
-  for (count = 0; count < THREADS; count++)
-    {
-      if (threads[count].changed > 0)
-        {
-          printf ("Thread %d found changed elements %d times\n",
-                  count, threads[count].changed);
-        }
-    }
-
-  putchar('\n');
-  fflush(stdout);
-
-  for (count = 0; count < THREADS; count++)
-    {
-      thread_updates += threads[count].updates;
-      printf ("%02d: seed %d, updates %d, reads %d\n",
-              count, threads[count].seed,
-              threads[count].updates, threads[count].reads);
-    }
-
-  putchar('\n');
-  fflush(stdout);
-
-  /*
-   * Collect statistics for the data.
-   */
-  for (data_count = 0; data_count < DATASIZE; data_count++)
-    {
-      data_updates += data[data_count].updates;
-      printf ("data %02d: value %d, %d updates\n",
-              data_count, data[data_count].data, data[data_count].updates);
-      assert(pthread_rwlock_destroy (&data[data_count].lock) == 0);
-    }
-
-  printf ("%d thread updates, %d data updates\n",
-          thread_updates, data_updates);
-
-  PTW32_FTIME(&currSysTime2);
-
-  printf( "\nstart: %ld/%d, stop: %ld/%d, duration:%ld\n",
-          (long)currSysTime1.time,currSysTime1.millitm,
-          (long)currSysTime2.time,currSysTime2.millitm,
-          ((long)((currSysTime2.time*1000+currSysTime2.millitm) -
-          (currSysTime1.time*1000+currSysTime1.millitm))));
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/rwlock8.c b/deps/w32-pthreads/tests/rwlock8.c
deleted file mode 100644
index 99c357a..0000000
--- a/deps/w32-pthreads/tests/rwlock8.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * rwlock8.c
- *
- * Hammer on a bunch of rwlocks to test robustness and fairness.
- * Printed stats should be roughly even for each thread.
- *
- * Yield during each access to exercise lock contention code paths
- * more than rwlock7.c does (particularly on uni-processor systems).
- */
-
-#include "test.h"
-#include <sys/timeb.h>
-
-#ifdef __GNUC__
-#include <stdlib.h>
-#endif
-
-#define THREADS         5
-#define DATASIZE        7
-#define ITERATIONS      100000
-
-/*
- * Keep statistics for each thread.
- */
-typedef struct thread_tag {
-  int         thread_num;
-  pthread_t   thread_id;
-  int         updates;
-  int         reads;
-  int         changed;
-  int         seed;
-} thread_t;
-
-/*
- * Read-write lock and shared data
- */
-typedef struct data_tag {
-  pthread_rwlock_t    lock;
-  int                 data;
-  int                 updates;
-} data_t;
-
-static thread_t threads[THREADS];
-static data_t data[DATASIZE];
-
-/*
- * Thread start routine that uses read-write locks
- */
-void *thread_routine (void *arg)
-{
-  thread_t *self = (thread_t*)arg;
-  int iteration;
-  int element = 0;
-  int seed = self->seed;
-  int interval = 1 + rand_r (&seed) % 71;
-
-  self->changed = 0;
-
-  for (iteration = 0; iteration < ITERATIONS; iteration++)
-    {
-      if (iteration % (ITERATIONS / 10) == 0)
-        {
-          putchar('.');
-          fflush(stdout);
-        }
-      /*
-       * Each "self->interval" iterations, perform an
-       * update operation (write lock instead of read
-       * lock).
-       */
-      if ((iteration % interval) == 0)
-        {
-          assert(pthread_rwlock_wrlock (&data[element].lock) == 0);
-          data[element].data = self->thread_num;
-          data[element].updates++;
-          self->updates++;
-	  interval = 1 + rand_r (&seed) % 71;
-	  sched_yield();
-          assert(pthread_rwlock_unlock (&data[element].lock) == 0);
-        } else {
-          /*
-           * Look at the current data element to see whether
-           * the current thread last updated it. Count the
-           * times, to report later.
-           */
-          assert(pthread_rwlock_rdlock (&data[element].lock) == 0);
-
-          self->reads++;
-
-          if (data[element].data != self->thread_num)
-            {
-              self->changed++;
-	      interval = 1 + self->changed % 71;
-            }
-
-	  sched_yield();
-
-          assert(pthread_rwlock_unlock (&data[element].lock) == 0);
-        }
-
-      element = (element + 1) % DATASIZE;
-
-    }
-
-  return NULL;
-}
-
-int
-main (int argc, char *argv[])
-{
-  int count;
-  int data_count;
-  int thread_updates = 0;
-  int data_updates = 0;
-  int seed = 1;
-
-  PTW32_STRUCT_TIMEB currSysTime1;
-  PTW32_STRUCT_TIMEB currSysTime2;
-
-  /*
-   * Initialize the shared data.
-   */
-  for (data_count = 0; data_count < DATASIZE; data_count++)
-    {
-      data[data_count].data = 0;
-      data[data_count].updates = 0;
-
-      assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0);
-    }
-
-  PTW32_FTIME(&currSysTime1);
-
-  /*
-   * Create THREADS threads to access shared data.
-   */
-  for (count = 0; count < THREADS; count++)
-    {
-      threads[count].thread_num = count;
-      threads[count].updates = 0;
-      threads[count].reads = 0;
-      threads[count].seed = 1 + rand_r (&seed) % 71;
-
-      assert(pthread_create (&threads[count].thread_id,
-                             NULL, thread_routine, (void*)(size_t)&threads[count]) == 0);
-    }
-
-  /*
-   * Wait for all threads to complete, and collect
-   * statistics.
-   */
-  for (count = 0; count < THREADS; count++)
-    {
-      assert(pthread_join (threads[count].thread_id, NULL) == 0);
-    }
-
-  putchar('\n');
-  fflush(stdout);
-
-  for (count = 0; count < THREADS; count++)
-    {
-      if (threads[count].changed > 0)
-        {
-          printf ("Thread %d found changed elements %d times\n",
-                  count, threads[count].changed);
-        }
-    }
-
-  putchar('\n');
-  fflush(stdout);
-
-  for (count = 0; count < THREADS; count++)
-    {
-      thread_updates += threads[count].updates;
-      printf ("%02d: seed %d, updates %d, reads %d\n",
-              count, threads[count].seed,
-              threads[count].updates, threads[count].reads);
-    }
-
-  putchar('\n');
-  fflush(stdout);
-
-  /*
-   * Collect statistics for the data.
-   */
-  for (data_count = 0; data_count < DATASIZE; data_count++)
-    {
-      data_updates += data[data_count].updates;
-      printf ("data %02d: value %d, %d updates\n",
-              data_count, data[data_count].data, data[data_count].updates);
-      assert(pthread_rwlock_destroy (&data[data_count].lock) == 0);
-    }
-
-  printf ("%d thread updates, %d data updates\n",
-          thread_updates, data_updates);
-
-  PTW32_FTIME(&currSysTime2);
-
-  printf( "\nstart: %ld/%d, stop: %ld/%d, duration:%ld\n",
-          (long)currSysTime1.time,currSysTime1.millitm,
-          (long)currSysTime2.time,currSysTime2.millitm,
-          ((long)((currSysTime2.time*1000+currSysTime2.millitm) -
-          (currSysTime1.time*1000+currSysTime1.millitm))));
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/self1.c b/deps/w32-pthreads/tests/self1.c
deleted file mode 100644
index 7bc4a80..0000000
--- a/deps/w32-pthreads/tests/self1.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * self1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test for pthread_self().
- *
- * Depends on API functions:
- *	pthread_self()
- *
- * Implicitly depends on:
- *	pthread_getspecific()
- *	pthread_setspecific()
- */
-
-#include "test.h"
-
-int
-main(int argc, char * argv[])
-{
-	/*
-	 * This should always succeed unless the system has no
-	 * resources (memory) left.
-	 */
-	pthread_t self;
-
-#if defined(PTW32_STATIC_LIB) && !(defined(_MSC_VER) || defined(__MINGW32__))
-	pthread_win32_process_attach_np();
-#endif
-
-	self = pthread_self();
-
-	assert(self.p != NULL);
-
-#if defined(PTW32_STATIC_LIB) && !(defined(_MSC_VER) || defined(__MINGW32__))
-	pthread_win32_process_detach_np();
-#endif
-	return 0;
-}
diff --git a/deps/w32-pthreads/tests/self2.c b/deps/w32-pthreads/tests/self2.c
deleted file mode 100644
index e92ede4..0000000
--- a/deps/w32-pthreads/tests/self2.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * self2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test for pthread_self().
- *
- * Depends on API functions:
- *	pthread_create()
- *	pthread_self()
- *
- * Implicitly depends on:
- *	pthread_getspecific()
- *	pthread_setspecific()
- */
-
-#include "test.h"
-#include <string.h>
-
-static pthread_t me;
-
-void *
-entry(void * arg)
-{
-  me = pthread_self();
-
-  return arg;
-}
-
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_create(&t, NULL, entry, NULL) == 0);
-
-  Sleep(100);
-
-  assert(pthread_equal(t, me) != 0);
-
-  /* Success. */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/semaphore1.c b/deps/w32-pthreads/tests/semaphore1.c
deleted file mode 100644
index a6c02e6..0000000
--- a/deps/w32-pthreads/tests/semaphore1.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * File: semaphore1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Verify trywait() returns -1 and sets EAGAIN.
- * - 
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-void *
-thr(void * arg)
-{
-  sem_t s;
-  int result;
-
-  assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0);
-
-  assert((result = sem_trywait(&s)) == -1);
-
-  if ( result == -1 )
-  {
-    int err = errno;
-    if (err != EAGAIN)
-    {
-      printf("thread: sem_trywait 1: expecting error %s: got %s\n",
-	     error_string[EAGAIN], error_string[err]); fflush(stdout);
-    }
-    assert(err == EAGAIN);
-  }
-  else
-  {
-    printf("thread: ok 1\n");
-  }
-
-  assert((result = sem_post(&s)) == 0);
-
-  assert((result = sem_trywait(&s)) == 0);
-
-  assert(sem_post(&s) == 0);
-
-  return NULL;
-}
-
-
-int
-main()
-{
-  pthread_t t;
-  sem_t s;
-  void* result1 = (void*)-1;
-  int result2;
-
-  assert(pthread_create(&t, NULL, thr, NULL) == 0);
-  assert(pthread_join(t, &result1) == 0);
-  assert((int)(size_t)result1 == 0);
-
-  assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0);
-
-  assert((result2 = sem_trywait(&s)) == -1);
-
-  if (result2 == -1)
-  {
-    int err = errno;
-    if (err != EAGAIN)
-    {
-      printf("main: sem_trywait 1: expecting error %s: got %s\n",
-	     error_string[EAGAIN], error_string[err]); fflush(stdout);
-    }
-    assert(err == EAGAIN);
-  }
-  else
-  {
-    printf("main: ok 1\n");
-  }
-
-  assert((result2 = sem_post(&s)) == 0);
-
-  assert((result2 = sem_trywait(&s)) == 0);
-
-  assert(sem_post(&s) == 0);
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/semaphore2.c b/deps/w32-pthreads/tests/semaphore2.c
deleted file mode 100644
index 5a4e236..0000000
--- a/deps/w32-pthreads/tests/semaphore2.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * File: semaphore2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Verify sem_getvalue returns the correct value.
- * - 
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-#define MAX_COUNT 100
-
-int
-main()
-{
-  sem_t s;
-	int value = 0;
-	int i;
-
-  assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, MAX_COUNT) == 0);
-	assert(sem_getvalue(&s, &value) == 0);
-	assert(value == MAX_COUNT);
-//	  printf("Value = %ld\n", value);
-
-	for (i = MAX_COUNT - 1; i >= 0; i--)
-		{
-			assert(sem_wait(&s) == 0);
-			assert(sem_getvalue(&s, &value) == 0);
-//			  printf("Value = %ld\n", value);
-			assert(value == i);
-		}
-
-	for (i = 1; i <= MAX_COUNT; i++)
-		{
-			assert(sem_post(&s) == 0);
-			assert(sem_getvalue(&s, &value) == 0);
-//			  printf("Value = %ld\n", value);
-			assert(value == i);
-		}
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/semaphore3.c b/deps/w32-pthreads/tests/semaphore3.c
deleted file mode 100644
index 0ee8e5d..0000000
--- a/deps/w32-pthreads/tests/semaphore3.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * File: semaphore3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Verify sem_getvalue returns the correct number of waiters.
- * - 
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-#define MAX_COUNT 100
-
-sem_t s;
-
-void *
-thr (void * arg)
-{
-  assert(sem_wait(&s) == 0);
-  assert(pthread_detach(pthread_self()) == 0);
-  return NULL;
-}
-
-int
-main()
-{
-	int value = 0;
-	int i;
-	pthread_t t[MAX_COUNT+1];
-
-	assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0);
-	assert(sem_getvalue(&s, &value) == 0);
-//	printf("Value = %d\n", value);	fflush(stdout);
-	assert(value == 0);
-
-	for (i = 1; i <= MAX_COUNT; i++)
-		{
-			assert(pthread_create(&t[i], NULL, thr, NULL) == 0);
-			do {
-			  sched_yield();
-			  assert(sem_getvalue(&s, &value) == 0);
-			} while (value != -i);
-//			printf("Value = %d\n", value); fflush(stdout);
-			assert(-value == i);
-		}
-
-	for (i = MAX_COUNT - 1; i >= 0; i--)
-		{
-			assert(sem_post(&s) == 0);
-			assert(sem_getvalue(&s, &value) == 0);
-//			printf("Value = %d\n", value);	fflush(stdout);
-			assert(-value == i);
-		}
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/semaphore4.c b/deps/w32-pthreads/tests/semaphore4.c
deleted file mode 100644
index b1356e4..0000000
--- a/deps/w32-pthreads/tests/semaphore4.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * File: semaphore4.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Verify sem_getvalue returns the correct number of waiters
- * after threads are cancelled.
- * - 
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-#define MAX_COUNT 100
-
-sem_t s;
-
-void *
-thr (void * arg)
-{
-  assert(sem_wait(&s) == 0);
-  return NULL;
-}
-
-int
-main()
-{
-	int value = 0;
-	int i;
-	pthread_t t[MAX_COUNT+1];
-
-	assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0);
-	assert(sem_getvalue(&s, &value) == 0);
-	assert(value == 0);
-
-	for (i = 1; i <= MAX_COUNT; i++)
-		{
-			assert(pthread_create(&t[i], NULL, thr, NULL) == 0);
-			do {
-			  sched_yield();
-			  assert(sem_getvalue(&s, &value) == 0);
-			} while (value != -i);
-			assert(-value == i);
-		}
-
-	assert(sem_getvalue(&s, &value) == 0);
-	assert(-value == MAX_COUNT);
-	assert(pthread_cancel(t[50]) == 0);
-	  {
-	    void* result;
-	    assert(pthread_join(t[50], &result) == 0);
-	  }
-	assert(sem_getvalue(&s, &value) == 0);
-	assert(-value == (MAX_COUNT - 1));
-
-	for (i = MAX_COUNT - 2; i >= 0; i--)
-		{
-			assert(sem_post(&s) == 0);
-			assert(sem_getvalue(&s, &value) == 0);
-			assert(-value == i);
-		}
-
-	for (i = 1; i <= MAX_COUNT; i++)
-	  if (i != 50)
-	    assert(pthread_join(t[i], NULL) == 0);
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/semaphore4t.c b/deps/w32-pthreads/tests/semaphore4t.c
deleted file mode 100644
index 5a8d7a9..0000000
--- a/deps/w32-pthreads/tests/semaphore4t.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * File: semaphore4t.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Verify sem_getvalue returns the correct number of waiters
- * after threads are cancelled.
- * - 
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - sem_timedwait cancellation.
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-#define MAX_COUNT 100
-
-sem_t s;
-
-void *
-thr (void * arg)
-{
-  assert(sem_timedwait(&s, NULL) == 0);
-  return NULL;
-}
-
-int
-main()
-{
-	int value = 0;
-	int i;
-	pthread_t t[MAX_COUNT+1];
-
-	assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0);
-	assert(sem_getvalue(&s, &value) == 0);
-	assert(value == 0);
-
-	for (i = 1; i <= MAX_COUNT; i++)
-		{
-			assert(pthread_create(&t[i], NULL, thr, NULL) == 0);
-			do {
-			  sched_yield();
-			  assert(sem_getvalue(&s, &value) == 0);
-			} while (value != -i);
-			assert(-value == i);
-		}
-
-	assert(sem_getvalue(&s, &value) == 0);
-	assert(-value == MAX_COUNT);
-	assert(pthread_cancel(t[50]) == 0);
-	assert(pthread_join(t[50], NULL) == 0);
-	assert(sem_getvalue(&s, &value) == 0);
-	assert(-value == MAX_COUNT - 1);
-
-	for (i = MAX_COUNT - 2; i >= 0; i--)
-		{
-			assert(sem_post(&s) == 0);
-			assert(sem_getvalue(&s, &value) == 0);
-			assert(-value == i);
-		}
-
-        for (i = 1; i <= MAX_COUNT; i++)
-          if (i != 50)
-            assert(pthread_join(t[i], NULL) == 0);
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/semaphore5.c b/deps/w32-pthreads/tests/semaphore5.c
deleted file mode 100644
index 67fd339..0000000
--- a/deps/w32-pthreads/tests/semaphore5.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * File: semaphore5.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis: Verify sem_destroy EBUSY race avoidance
- * - 
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - 
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-// #define ASSERT_TRACE
-
-#include "test.h"
-
-void *
-thr(void * arg)
-{
-  assert(sem_post((sem_t *)arg) == 0);
-
-  return 0;
-}
-
-
-int
-main()
-{
-  pthread_t t;
-  sem_t s;
-
-  assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0);
-  assert(pthread_create(&t, NULL, thr, (void *)&s) == 0);
-
-  assert(sem_wait(&s) == 0);
-  assert(sem_destroy(&s) == 0);
-
-  assert(pthread_join(t, NULL) == 0);
-
-  return 0;
-}
-
diff --git a/deps/w32-pthreads/tests/sequence1.c b/deps/w32-pthreads/tests/sequence1.c
deleted file mode 100644
index fa1cdc5..0000000
--- a/deps/w32-pthreads/tests/sequence1.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * File: sequence1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - that unique thread sequence numbers are generated.
- * - Analyse thread struct reuse.
- *
- * Test Method (Validation or Falsification):
- * -
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * -
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * - This test is implementation specific
- * because it uses knowledge of internals that should be
- * opaque to an application.
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - analysis output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - unique sequence numbers are generated for every new thread.
- *
- * Fail Criteria:
- * - 
- */
-
-#include "test.h"
-
-/*
- */
-
-enum {
-	NUMTHREADS = 10000
-};
-
-
-static long done = 0;
-/*
- * seqmap should have 1 in every element except [0]
- * Thread sequence numbers start at 1 and we will also
- * include this main thread so we need NUMTHREADS+2
- * elements. 
- */
-static UINT64 seqmap[NUMTHREADS+2];
-
-void * func(void * arg)
-{
-  sched_yield();
-  seqmap[(int)pthread_getunique_np(pthread_self())] = 1;
-  InterlockedIncrement(&done);
-
-  return (void *) 0; 
-}
- 
-int
-main()
-{
-  pthread_t t[NUMTHREADS];
-  pthread_attr_t attr;
-  int i;
-
-  assert(pthread_attr_init(&attr) == 0);
-  assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0);
-
-  for (i = 0; i < NUMTHREADS+2; i++)
-    {
-      seqmap[i] = 0;
-    }
-
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      if (NUMTHREADS/2 == i)
-        {
-          /* Include this main thread, which will be an implicit pthread_t */
-          seqmap[(int)pthread_getunique_np(pthread_self())] = 1;
-        }
-      assert(pthread_create(&t[i], &attr, func, NULL) == 0);
-    }
-
-  while (NUMTHREADS > InterlockedExchangeAdd((LPLONG)&done, 0L))
-    Sleep(100);
-
-  Sleep(100);
-
-  assert(seqmap[0] == 0);
-  for (i = 1; i < NUMTHREADS+2; i++)
-    {
-      assert(seqmap[i] == 1);
-    }
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/sizes.c b/deps/w32-pthreads/tests/sizes.c
deleted file mode 100644
index 554d0e8..0000000
--- a/deps/w32-pthreads/tests/sizes.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#define _WIN32_WINNT 0x400
-
-#include "test.h"
-#include "../implement.h"
-
-int
-main()
-{
-  printf("Sizes of pthreads-win32 structs\n");
-  printf("-------------------------------\n");
-  printf("%30s %4d\n", "pthread_t", (int)sizeof(pthread_t));
-  printf("%30s %4d\n", "ptw32_thread_t", (int)sizeof(ptw32_thread_t));
-  printf("%30s %4d\n", "pthread_attr_t_", (int)sizeof(struct pthread_attr_t_));
-  printf("%30s %4d\n", "sem_t_", (int)sizeof(struct sem_t_));
-  printf("%30s %4d\n", "pthread_mutex_t_", (int)sizeof(struct pthread_mutex_t_));
-  printf("%30s %4d\n", "pthread_mutexattr_t_", (int)sizeof(struct pthread_mutexattr_t_));
-  printf("%30s %4d\n", "pthread_spinlock_t_", (int)sizeof(struct pthread_spinlock_t_));
-  printf("%30s %4d\n", "pthread_barrier_t_", (int)sizeof(struct pthread_barrier_t_));
-  printf("%30s %4d\n", "pthread_barrierattr_t_", (int)sizeof(struct pthread_barrierattr_t_));
-  printf("%30s %4d\n", "pthread_key_t_", (int)sizeof(struct pthread_key_t_));
-  printf("%30s %4d\n", "pthread_cond_t_", (int)sizeof(struct pthread_cond_t_));
-  printf("%30s %4d\n", "pthread_condattr_t_", (int)sizeof(struct pthread_condattr_t_));
-  printf("%30s %4d\n", "pthread_rwlock_t_", (int)sizeof(struct pthread_rwlock_t_));
-  printf("%30s %4d\n", "pthread_rwlockattr_t_", (int)sizeof(struct pthread_rwlockattr_t_));
-  printf("%30s %4d\n", "pthread_once_t_", (int)sizeof(struct pthread_once_t_));
-  printf("%30s %4d\n", "ptw32_cleanup_t", (int)sizeof(struct ptw32_cleanup_t));
-  printf("%30s %4d\n", "ptw32_mcs_node_t_", (int)sizeof(struct ptw32_mcs_node_t_));
-  printf("%30s %4d\n", "sched_param", (int)sizeof(struct sched_param));
-  printf("-------------------------------\n");
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/spin1.c b/deps/w32-pthreads/tests/spin1.c
deleted file mode 100644
index 6ba5dac..0000000
--- a/deps/w32-pthreads/tests/spin1.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* 
- * spin1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Create a simple spinlock object, lock it, and then unlock it again.
- * This is the simplest test of the pthread mutex family that we can do.
- *
- */
-
-#include "test.h"
-
-pthread_spinlock_t lock;
-
-int
-main()
-{
-  assert(pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE) == 0);
-
-  assert(pthread_spin_lock(&lock) == 0);
-
-  assert(pthread_spin_unlock(&lock) == 0);
-
-  assert(pthread_spin_destroy(&lock) == 0);
-
-  assert(pthread_spin_lock(&lock) == EINVAL);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/spin2.c b/deps/w32-pthreads/tests/spin2.c
deleted file mode 100644
index d08ac98..0000000
--- a/deps/w32-pthreads/tests/spin2.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* 
- * spin2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a spinlock object, lock it, trylock it, 
- * and then unlock it again.
- *
- */
-
-#include "test.h"
- 
-pthread_spinlock_t lock = NULL;
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  assert(pthread_spin_trylock(&lock) == EBUSY);
-
-  washere = 1;
-
-  return 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  assert(pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE) == 0);
-
-  assert(pthread_spin_lock(&lock) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-  assert(pthread_join(t, NULL) == 0);
-
-  assert(pthread_spin_unlock(&lock) == 0);
-
-  assert(pthread_spin_destroy(&lock) == 0);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/spin3.c b/deps/w32-pthreads/tests/spin3.c
deleted file mode 100644
index ebf69ca..0000000
--- a/deps/w32-pthreads/tests/spin3.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* 
- * spin3.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Thread A locks spin - thread B tries to unlock.
- * This should succeed, but it's undefined behaviour.
- *
- */
-
-#include "test.h"
-
-static int wasHere = 0;
-
-static pthread_spinlock_t spin;
- 
-void * unlocker(void * arg)
-{
-  int expectedResult = (int)(size_t)arg;
-
-  wasHere++;
-  assert(pthread_spin_unlock(&spin) == expectedResult);
-  wasHere++;
-  return NULL;
-}
- 
-int
-main()
-{
-  pthread_t t;
-
-  wasHere = 0;
-  assert(pthread_spin_init(&spin, PTHREAD_PROCESS_PRIVATE) == 0);
-  assert(pthread_spin_lock(&spin) == 0);
-  assert(pthread_create(&t, NULL, unlocker, (void*)0) == 0);
-  assert(pthread_join(t, NULL) == 0);
-  /*
-   * Our spinlocks don't record the owner thread so any thread can unlock the spinlock,
-   * but nor is it an error for any thread to unlock a spinlock that is not locked.
-   */
-  assert(pthread_spin_unlock(&spin) == 0);
-  assert(pthread_spin_destroy(&spin) == 0);
-  assert(wasHere == 2);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/spin4.c b/deps/w32-pthreads/tests/spin4.c
deleted file mode 100644
index 277efd7..0000000
--- a/deps/w32-pthreads/tests/spin4.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* 
- * spin4.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Declare a static spinlock object, lock it, spin on it, 
- * and then unlock it again.
- */
-
-#include "test.h"
-#include <sys/timeb.h>
- 
-pthread_spinlock_t lock = PTHREAD_SPINLOCK_INITIALIZER;
-PTW32_STRUCT_TIMEB currSysTimeStart;
-PTW32_STRUCT_TIMEB currSysTimeStop;
-
-#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \
-					       - (_TStart.time*1000+_TStart.millitm))
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  PTW32_FTIME(&currSysTimeStart);
-  washere = 1;
-  assert(pthread_spin_lock(&lock) == 0);
-  assert(pthread_spin_unlock(&lock) == 0);
-  PTW32_FTIME(&currSysTimeStop);
-
-  return (void *)(size_t)GetDurationMilliSecs(currSysTimeStart, currSysTimeStop);
-}
- 
-int
-main()
-{
-  void* result = (void*)0;
-  pthread_t t;
-  int CPUs;
-  PTW32_STRUCT_TIMEB sysTime;
-
-  if ((CPUs = pthread_num_processors_np()) == 1)
-    {
-      printf("Test not run - it requires multiple CPUs.\n");
-	exit(0);
-    }
-
-  assert(pthread_spin_lock(&lock) == 0);
-
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-
-  while (washere == 0)
-    {
-      sched_yield();
-    }
-
-  do
-    {
-      sched_yield();
-      PTW32_FTIME(&sysTime);
-    }
-  while (GetDurationMilliSecs(currSysTimeStart, sysTime) <= 1000);
-
-  assert(pthread_spin_unlock(&lock) == 0);
-
-  assert(pthread_join(t, &result) == 0);
-  assert((int)(size_t)result > 1000);
-
-  assert(pthread_spin_destroy(&lock) == 0);
-
-  assert(washere == 1);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/stress1.c b/deps/w32-pthreads/tests/stress1.c
deleted file mode 100644
index 04bdc16..0000000
--- a/deps/w32-pthreads/tests/stress1.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * stress1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Stress test condition variables, mutexes, semaphores.
- *
- * Test Method (Validation or Falsification):
- * - Validation
- *
- * Requirements Tested:
- * - Correct accounting of semaphore and condition variable waiters.
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * Attempting to expose race conditions in cond vars, semaphores etc.
- * - Master attempts to signal slave close to when timeout is due.
- * - Master and slave do battle continuously until main tells them to stop.
- * - Afterwards, the CV must be successfully destroyed (will return an
- * error if there are waiters (including any internal semaphore waiters,
- * which, if there are, cannot be real waiters).
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - 
- *
- * Pass Criteria:
- * - CV is successfully destroyed.
- *
- * Fail Criteria:
- * - CV destroy fails.
- */
-
-#include "test.h"
-#include <string.h>
-#include <sys/timeb.h>
-
-
-const unsigned int ITERATIONS = 1000;
-
-static pthread_t master, slave;
-typedef struct {
-  int value;
-  pthread_cond_t cv;
-  pthread_mutex_t mx;
-} mysig_t;
-
-static int allExit;
-static mysig_t control = {0, PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER};
-static pthread_barrier_t startBarrier, readyBarrier, holdBarrier;
-static int timeoutCount = 0;
-static int signalsTakenCount = 0;
-static int signalsSent = 0;
-static int bias = 0;
-static int timeout = 10; // Must be > 0
-
-enum {
-  CTL_STOP     = -1
-};
-
-/*
- * Returns abstime 'milliseconds' from 'now'.
- *
- * Works for: -INT_MAX <= millisecs <= INT_MAX
- */
-struct timespec *
-millisecondsFromNow (struct timespec * time, int millisecs)
-{
-  PTW32_STRUCT_TIMEB currSysTime;
-  int64_t nanosecs, secs;
-  const int64_t NANOSEC_PER_MILLISEC = 1000000;
-  const int64_t NANOSEC_PER_SEC = 1000000000;
-
-  /* get current system time and add millisecs */
-  PTW32_FTIME(&currSysTime);
-
-  secs = (int64_t)(currSysTime.time) + (millisecs / 1000);
-  nanosecs = ((int64_t) (millisecs%1000 + currSysTime.millitm)) * NANOSEC_PER_MILLISEC;
-  if (nanosecs >= NANOSEC_PER_SEC)
-    {
-      secs++;
-      nanosecs -= NANOSEC_PER_SEC;
-    }
-  else if (nanosecs < 0)
-    {
-      secs--;
-      nanosecs += NANOSEC_PER_SEC;
-    }
-
-  time->tv_nsec = (long)nanosecs;
-  time->tv_sec = (long)secs;
-
-  return time;
-}
-
-void *
-masterThread (void * arg)
-{
-  int dither = (int)(size_t)arg;
-
-  timeout = (int)(size_t)arg;
-
-  pthread_barrier_wait(&startBarrier);
-
-  do
-    {
-      int sleepTime;
-
-      assert(pthread_mutex_lock(&control.mx) == 0);
-      control.value = timeout;
-      assert(pthread_mutex_unlock(&control.mx) == 0);
-
-      /*
-       * We are attempting to send the signal close to when the slave
-       * is due to timeout. We feel around by adding some [non-random] dither.
-       *
-       * dither is in the range 2*timeout peak-to-peak
-       * sleep time is the average of timeout plus dither.
-       * e.g.
-       * if timeout = 10 then dither = 20 and
-       * sleep millisecs is: 5 <= ms <= 15
-       *
-       * The bias value attempts to apply some negative feedback to keep
-       * the ratio of timeouts to signals taken close to 1:1.
-       * bias changes more slowly than dither so as to average more.
-       *
-       * Finally, if abs(bias) exceeds timeout then timeout is incremented.
-       */
-      if (signalsSent % timeout == 0)
-	{
-          if (timeoutCount > signalsTakenCount)
-	    {
-	      bias++;
-	    }
-          else if (timeoutCount < signalsTakenCount)
-	    {
-	      bias--;
-	    }
-	  if (bias < -timeout || bias > timeout)
-	    {
-	      timeout++;
-	    }
-	}
-      dither = (dither + 1 ) % (timeout * 2);
-      sleepTime = (timeout - bias + dither) / 2;
-      Sleep(sleepTime);
-      assert(pthread_cond_signal(&control.cv) == 0);
-      signalsSent++;
-
-      pthread_barrier_wait(&holdBarrier);
-      pthread_barrier_wait(&readyBarrier);
-    }
-  while (!allExit);
-
-  return NULL;
-}
-
-void *
-slaveThread (void * arg)
-{
-  struct timespec time;
-
-  pthread_barrier_wait(&startBarrier);
-
-  do
-    {
-      assert(pthread_mutex_lock(&control.mx) == 0);
-      if (pthread_cond_timedwait(&control.cv,
-				 &control.mx,
-				 millisecondsFromNow(&time, control.value)) == ETIMEDOUT)
-	{
-	  timeoutCount++;
-	}
-      else
-	{
-	  signalsTakenCount++;
-	}
-      assert(pthread_mutex_unlock(&control.mx) == 0);
-
-      pthread_barrier_wait(&holdBarrier);
-      pthread_barrier_wait(&readyBarrier);
-    }
-  while (!allExit);
-
-  return NULL;
-}
-
-int
-main ()
-{
-  unsigned int i;
-
-  assert(pthread_barrier_init(&startBarrier, NULL, 3) == 0);
-  assert(pthread_barrier_init(&readyBarrier, NULL, 3) == 0);
-  assert(pthread_barrier_init(&holdBarrier, NULL, 3) == 0);
-
-  assert(pthread_create(&master, NULL, masterThread, (void *)(size_t)timeout) == 0);
-  assert(pthread_create(&slave, NULL, slaveThread, NULL) == 0);
-
-  allExit = FALSE;
-
-  pthread_barrier_wait(&startBarrier);
-
-  for (i = 1; !allExit; i++)
-    {
-      pthread_barrier_wait(&holdBarrier);
-      if (i >= ITERATIONS)
-	{
-	  allExit = TRUE;
-	}
-      pthread_barrier_wait(&readyBarrier);
-    }
-
-  assert(pthread_join(slave, NULL) == 0);
-  assert(pthread_join(master, NULL) == 0);
-
-  printf("Signals sent = %d\nWait timeouts = %d\nSignals taken = %d\nBias = %d\nTimeout = %d\n",
-	 signalsSent,
-	 timeoutCount,
-	 signalsTakenCount,
-	 (int) bias,
-	 timeout);
-
-  /* Cleanup */
-  assert(pthread_barrier_destroy(&holdBarrier) == 0);
-  assert(pthread_barrier_destroy(&readyBarrier) == 0);
-  assert(pthread_barrier_destroy(&startBarrier) == 0);
-  assert(pthread_cond_destroy(&control.cv) == 0);
-  assert(pthread_mutex_destroy(&control.mx) == 0);
-
-  /* Success. */
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/test.h b/deps/w32-pthreads/tests/test.h
deleted file mode 100644
index 1756a64..0000000
--- a/deps/w32-pthreads/tests/test.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/* 
- * test.h
- *
- * Useful definitions and declarations for tests.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- */
-
-#ifndef _PTHREAD_TEST_H_
-#define _PTHREAD_TEST_H_
-
-#include "pthread.h"
-#include "sched.h"
-#include "semaphore.h"
-
-#include <windows.h>
-#include <stdio.h>
-
-#define PTW32_THREAD_NULL_ID {NULL,0}
-
-/*
- * Some non-thread POSIX API substitutes
- */
-#define rand_r( _seed ) \
-        ( _seed == _seed? rand() : rand() )
-
-#if defined(__MINGW32__)
-#include <stdint.h>
-#elif defined(__BORLANDC__)
-#define int64_t ULONGLONG
-#else
-#define int64_t _int64
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-#  define PTW32_FTIME(x) _ftime64_s(x)
-#  define PTW32_STRUCT_TIMEB struct __timeb64
-#elif ( defined(_MSC_VER) && _MSC_VER >= 1300 ) || \
-      ( defined(__MINGW32__) && __MSVCRT_VERSION__ >= 0x0601 )
-#  define PTW32_FTIME(x) _ftime64(x)
-#  define PTW32_STRUCT_TIMEB struct __timeb64
-#else
-#  define PTW32_FTIME(x) _ftime(x)
-#  define PTW32_STRUCT_TIMEB struct _timeb
-#endif
-
-
-const char * error_string[] = {
-  "ZERO_or_EOK",
-  "EPERM",
-  "ENOFILE_or_ENOENT",
-  "ESRCH",
-  "EINTR",
-  "EIO",
-  "ENXIO",
-  "E2BIG",
-  "ENOEXEC",
-  "EBADF",
-  "ECHILD",
-  "EAGAIN",
-  "ENOMEM",
-  "EACCES",
-  "EFAULT",
-  "UNKNOWN_15",
-  "EBUSY",
-  "EEXIST",
-  "EXDEV",
-  "ENODEV",
-  "ENOTDIR",
-  "EISDIR",
-  "EINVAL",
-  "ENFILE",
-  "EMFILE",
-  "ENOTTY",
-  "UNKNOWN_26",
-  "EFBIG",
-  "ENOSPC",
-  "ESPIPE",
-  "EROFS",
-  "EMLINK",
-  "EPIPE",
-  "EDOM",
-  "ERANGE",
-  "UNKNOWN_35",
-  "EDEADLOCK_or_EDEADLK",
-  "UNKNOWN_37",
-  "ENAMETOOLONG",
-  "ENOLCK",
-  "ENOSYS",
-  "ENOTEMPTY",
-  "EILSEQ",
-  "EOWNERDEAD",
-  "ENOTRECOVERABLE"
-};
-
-/*
- * The Mingw32 assert macro calls the CRTDLL _assert function
- * which pops up a dialog. We want to run in batch mode so
- * we define our own assert macro.
- */
-#ifdef assert
-# undef assert
-#endif
-
-#ifndef ASSERT_TRACE
-# define ASSERT_TRACE 0
-#else
-# undef ASSERT_TRACE
-# define ASSERT_TRACE 1
-#endif
-
-# define assert(e) \
-   ((e) ? ((ASSERT_TRACE) ? fprintf(stderr, \
-                                    "Assertion succeeded: (%s), file %s, line %d\n", \
-			            #e, __FILE__, (int) __LINE__), \
-	                            fflush(stderr) : \
-                             0) : \
-          (fprintf(stderr, "Assertion failed: (%s), file %s, line %d\n", \
-                   #e, __FILE__, (int) __LINE__), exit(1), 0))
-
-int assertE;
-# define assert_e(e, o, r) \
-   (((assertE = e) o (r)) ? ((ASSERT_TRACE) ? fprintf(stderr, \
-                                    "Assertion succeeded: (%s), file %s, line %d\n", \
-			            #e, __FILE__, (int) __LINE__), \
-	                            fflush(stderr) : \
-                             0) : \
-          (fprintf(stderr, "Assertion failed: (%s %s %s), file %s, line %d, error %s\n", \
-                   #e,#o,#r, __FILE__, (int) __LINE__, error_string[assertE]), exit(1), 0))
-
-#endif
-
-# define BEGIN_MUTEX_STALLED_ROBUST(mxAttr) \
-  for(;;) \
-    { \
-      static int _i=0; \
-      static int _robust; \
-      pthread_mutexattr_getrobust(&(mxAttr), &_robust);
-
-# define END_MUTEX_STALLED_ROBUST(mxAttr) \
-      printf("Pass %s\n", _robust==PTHREAD_MUTEX_ROBUST?"Robust":"Non-robust"); \
-      if (++_i > 1) \
-        break; \
-      else \
-        { \
-          pthread_mutexattr_t *pma, *pmaEnd; \
-          for(pma = &(mxAttr), pmaEnd = pma + sizeof(mxAttr)/sizeof(pthread_mutexattr_t); \
-              pma < pmaEnd; \
-              pthread_mutexattr_setrobust(pma++, PTHREAD_MUTEX_ROBUST)); \
-        } \
-    }
-
-# define IS_ROBUST (_robust==PTHREAD_MUTEX_ROBUST)
diff --git a/deps/w32-pthreads/tests/tryentercs.c b/deps/w32-pthreads/tests/tryentercs.c
deleted file mode 100644
index 2f606ec..0000000
--- a/deps/w32-pthreads/tests/tryentercs.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * tryentercs.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * See if we have the TryEnterCriticalSection function.
- * Does not use any part of pthreads.
- */
-
-#include <windows.h>
-#include <process.h>
-#include <stdio.h>
-
-/*
- * Function pointer to TryEnterCriticalSection if it exists
- * - otherwise NULL
- */
-BOOL (WINAPI *_try_enter_critical_section)(LPCRITICAL_SECTION) =
-NULL;
-
-/*
- * Handle to kernel32.dll
- */
-static HINSTANCE _h_kernel32;
-
-
-int
-main()
-{
-  CRITICAL_SECTION cs;
-
-  SetLastError(0);
-
-  printf("Last Error [main enter] %ld\n", (long) GetLastError());
-
-  /*
-   * Load KERNEL32 and try to get address of TryEnterCriticalSection
-   */
-  _h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL"));
-  _try_enter_critical_section =
-        (BOOL (PT_STDCALL *)(LPCRITICAL_SECTION))
-        GetProcAddress(_h_kernel32,
-                         (LPCSTR) "TryEnterCriticalSection");
-
-  if (_try_enter_critical_section != NULL)
-    {
-      InitializeCriticalSection(&cs);
-
-      SetLastError(0);
-
-      if ((*_try_enter_critical_section)(&cs) != 0)
-        {
-          LeaveCriticalSection(&cs);
-        }
-	else
-	  {
-	    printf("Last Error [try enter] %ld\n", (long) GetLastError());
-
-	    _try_enter_critical_section = NULL;
-	  }
-      DeleteCriticalSection(&cs);
-    }
-
-  (void) FreeLibrary(_h_kernel32);
-
-  printf("This system %s TryEnterCriticalSection.\n",
-         (_try_enter_critical_section == NULL) ? "DOES NOT SUPPORT" : "SUPPORTS");
-  printf("POSIX Mutexes will be based on Win32 %s.\n",
-         (_try_enter_critical_section == NULL) ? "Mutexes" : "Critical Sections");
-
-  return(0);
-}
-
diff --git a/deps/w32-pthreads/tests/tryentercs2.c b/deps/w32-pthreads/tests/tryentercs2.c
deleted file mode 100644
index eeba906..0000000
--- a/deps/w32-pthreads/tests/tryentercs2.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * tryentercs.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * See if we have the TryEnterCriticalSection function.
- * Does not use any part of pthreads.
- */
-
-#include <windows.h>
-#include <process.h>
-#include <stdio.h>
-
-/*
- * Function pointer to TryEnterCriticalSection if it exists
- * - otherwise NULL
- */
-BOOL (WINAPI *_try_enter_critical_section)(LPCRITICAL_SECTION) = NULL;
-
-/*
- * Handle to kernel32.dll
- */
-static HINSTANCE _h_kernel32;
-
-
-int
-main()
-{
-  LPCRITICAL_SECTION lpcs = NULL;
-
-  SetLastError(0);
-
-  printf("Last Error [main enter] %ld\n", (long) GetLastError());
-
-  /*
-   * Load KERNEL32 and try to get address of TryEnterCriticalSection
-   */
-  _h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL"));
-  _try_enter_critical_section =
-        (BOOL (PT_STDCALL *)(LPCRITICAL_SECTION))
-        GetProcAddress(_h_kernel32,
-                         (LPCSTR) "TryEnterCriticalSection");
-
-  if (_try_enter_critical_section != NULL)
-    {
-      SetLastError(0);
-
-      (*_try_enter_critical_section)(lpcs);
-
-      printf("Last Error [try enter] %ld\n", (long) GetLastError());
-    }
-
-  (void) FreeLibrary(_h_kernel32);
-
-  printf("This system %s TryEnterCriticalSection.\n",
-         (_try_enter_critical_section == NULL) ? "DOES NOT SUPPORT" : "SUPPORTS");
-  printf("POSIX Mutexes will be based on Win32 %s.\n",
-         (_try_enter_critical_section == NULL) ? "Mutexes" : "Critical Sections");
-
-  return(0);
-}
-
diff --git a/deps/w32-pthreads/tests/tsd1.c b/deps/w32-pthreads/tests/tsd1.c
deleted file mode 100644
index d2e9c9f..0000000
--- a/deps/w32-pthreads/tests/tsd1.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * tsd1.c
- *
- * Test Thread Specific Data (TSD) key creation and destruction.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- *
- * --------------------------------------------------------------------------
- *
- * Description:
- * - 
- *
- * Test Method (validation or falsification):
- * - validation
- *
- * Requirements Tested:
- * - keys are created for each existing thread including the main thread
- * - keys are created for newly created threads
- * - keys are thread specific
- * - destroy routine is called on each thread exit including the main thread
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - none
- *
- * Output:
- * - text to stdout
- *
- * Assumptions:
- * - already validated:     pthread_create()
- *                          pthread_once()
- * - main thread also has a POSIX thread identity
- *
- * Pass Criteria:
- * - stdout matches file reference/tsd1.out
- *
- * Fail Criteria:
- * - fails to match file reference/tsd1.out
- * - output identifies failed component
- */
-
-#include <sched.h>
-#include "test.h"
-
-enum {
-  NUM_THREADS = 100
-};
-
-static pthread_key_t key = NULL;
-static int accesscount[NUM_THREADS];
-static int thread_set[NUM_THREADS];
-static int thread_destroyed[NUM_THREADS];
-static pthread_barrier_t startBarrier;
-
-static void
-destroy_key(void * arg)
-{
-  int * j = (int *) arg;
-
-  (*j)++;
-
-  assert(*j == 2);
-
-  thread_destroyed[j - accesscount] = 1;
-}
-
-static void
-setkey(void * arg)
-{
-  int * j = (int *) arg;
-
-  thread_set[j - accesscount] = 1;
-
-  assert(*j == 0);
-
-  assert(pthread_getspecific(key) == NULL);
-
-  assert(pthread_setspecific(key, arg) == 0);
-  assert(pthread_setspecific(key, arg) == 0);
-  assert(pthread_setspecific(key, arg) == 0);
-
-  assert(pthread_getspecific(key) == arg);
-
-  (*j)++;
-
-  assert(*j == 1);
-}
-
-static void *
-mythread(void * arg)
-{
-  (void) pthread_barrier_wait(&startBarrier);
-
-  setkey(arg);
-
-  return 0;
-
-  /* Exiting the thread will call the key destructor. */
-}
-
-int
-main()
-{
-  int i;
-  int fail = 0;
-  pthread_t thread[NUM_THREADS];
-
-  assert(pthread_barrier_init(&startBarrier, NULL, NUM_THREADS/2) == 0);
-
-  for (i = 1; i < NUM_THREADS/2; i++)
-    {
-      accesscount[i] = thread_set[i] = thread_destroyed[i] = 0;
-      assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0);
-    }
-
-  /*
-   * Here we test that existing threads will get a key created
-   * for them.
-   */
-  assert(pthread_key_create(&key, destroy_key) == 0);
-
-  (void) pthread_barrier_wait(&startBarrier);
-
-  /*
-   * Test main thread key.
-   */
-  accesscount[0] = 0;
-  setkey((void *) &accesscount[0]);
-
-  /*
-   * Here we test that new threads will get a key created
-   * for them.
-   */
-  for (i = NUM_THREADS/2; i < NUM_THREADS; i++)
-    {
-      accesscount[i] = thread_set[i] = thread_destroyed[i] = 0;
-      assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0);
-    }
-
-  /*
-   * Wait for all threads to complete.
-   */
-  for (i = 1; i < NUM_THREADS; i++)
-    {
-	assert(pthread_join(thread[i], NULL) == 0);
-    }
-
-  assert(pthread_key_delete(key) == 0);
-
-  assert(pthread_barrier_destroy(&startBarrier) == 0);
-
-  for (i = 1; i < NUM_THREADS; i++)
-    {
-	/*
-	 * The counter is incremented once when the key is set to
-	 * a value, and again when the key is destroyed. If the key
-	 * doesn't get set for some reason then it will still be
-	 * NULL and the destroy function will not be called, and
-	 * hence accesscount will not equal 2.
-	 */
-	if (accesscount[i] != 2)
-	  {
-	    fail++;
-	    fprintf(stderr, "Thread %d key, set = %d, destroyed = %d\n",
-			i, thread_set[i], thread_destroyed[i]);
-	  }
-    }
-
-  fflush(stderr);
-
-  return (fail);
-}
diff --git a/deps/w32-pthreads/tests/tsd2.c b/deps/w32-pthreads/tests/tsd2.c
deleted file mode 100644
index 97082ed..0000000
--- a/deps/w32-pthreads/tests/tsd2.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * tsd2.c
- *
- * Test Thread Specific Data (TSD) key creation and destruction.
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- *
- * --------------------------------------------------------------------------
- *
- * Description:
- * - 
- *
- * Test Method (validation or falsification):
- * - validation
- *
- * Requirements Tested:
- * - keys are created for each existing thread including the main thread
- * - keys are created for newly created threads
- * - keys are thread specific
- * - destroy routine is called on each thread exit including the main thread
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - none
- *
- * Output:
- * - text to stdout
- *
- * Assumptions:
- * - already validated:     pthread_create()
- *                          pthread_once()
- * - main thread also has a POSIX thread identity
- *
- * Pass Criteria:
- * - stdout matches file reference/tsd1.out
- *
- * Fail Criteria:
- * - fails to match file reference/tsd1.out
- * - output identifies failed component
- */
-
-#include <sched.h>
-#include "test.h"
-
-enum {
-  NUM_THREADS = 100
-};
-
-static pthread_key_t key = NULL;
-static int accesscount[NUM_THREADS];
-static int thread_set[NUM_THREADS];
-static int thread_destroyed[NUM_THREADS];
-static pthread_barrier_t startBarrier;
-
-static void
-destroy_key(void * arg)
-{
-  int * j = (int *) arg;
-
-  (*j)++;
-
-  /* Set TSD key from the destructor to test destructor iteration */
-  if (*j == 2)
-    assert(pthread_setspecific(key, arg) == 0);
-  else
-    assert(*j == 3);
-
-  thread_destroyed[j - accesscount] = 1;
-}
-
-static void
-setkey(void * arg)
-{
-  int * j = (int *) arg;
-
-  thread_set[j - accesscount] = 1;
-
-  assert(*j == 0);
-
-  assert(pthread_getspecific(key) == NULL);
-
-  assert(pthread_setspecific(key, arg) == 0);
-  assert(pthread_setspecific(key, arg) == 0);
-  assert(pthread_setspecific(key, arg) == 0);
-
-  assert(pthread_getspecific(key) == arg);
-
-  (*j)++;
-
-  assert(*j == 1);
-}
-
-static void *
-mythread(void * arg)
-{
-  (void) pthread_barrier_wait(&startBarrier);
-
-  setkey(arg);
-
-  return 0;
-
-  /* Exiting the thread will call the key destructor. */
-}
-
-int
-main()
-{
-  int i;
-  int fail = 0;
-  pthread_t thread[NUM_THREADS];
-
-  assert(pthread_barrier_init(&startBarrier, NULL, NUM_THREADS/2) == 0);
-
-  for (i = 1; i < NUM_THREADS/2; i++)
-    {
-      accesscount[i] = thread_set[i] = thread_destroyed[i] = 0;
-      assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0);
-    }
-
-  /*
-   * Here we test that existing threads will get a key created
-   * for them.
-   */
-  assert(pthread_key_create(&key, destroy_key) == 0);
-
-  (void) pthread_barrier_wait(&startBarrier);
-
-  /*
-   * Test main thread key.
-   */
-  accesscount[0] = 0;
-  setkey((void *) &accesscount[0]);
-
-  /*
-   * Here we test that new threads will get a key created
-   * for them.
-   */
-  for (i = NUM_THREADS/2; i < NUM_THREADS; i++)
-    {
-      accesscount[i] = thread_set[i] = thread_destroyed[i] = 0;
-      assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0);
-    }
-
-  /*
-   * Wait for all threads to complete.
-   */
-  for (i = 1; i < NUM_THREADS; i++)
-    {
-	assert(pthread_join(thread[i], NULL) == 0);
-    }
-
-  assert(pthread_key_delete(key) == 0);
-
-  assert(pthread_barrier_destroy(&startBarrier) == 0);
-
-  for (i = 1; i < NUM_THREADS; i++)
-    {
-	/*
-	 * The counter is incremented once when the key is set to
-	 * a value, and again when the key is destroyed. If the key
-	 * doesn't get set for some reason then it will still be
-	 * NULL and the destroy function will not be called, and
-	 * hence accesscount will not equal 2.
-	 */
-	if (accesscount[i] != 3)
-	  {
-	    fail++;
-	    fprintf(stderr, "Thread %d key, set = %d, destroyed = %d\n",
-			i, thread_set[i], thread_destroyed[i]);
-	  }
-    }
-
-  fflush(stderr);
-
-  return (fail);
-}
diff --git a/deps/w32-pthreads/tests/valid1.c b/deps/w32-pthreads/tests/valid1.c
deleted file mode 100644
index 2db6095..0000000
--- a/deps/w32-pthreads/tests/valid1.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * File: valid1.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Test that thread validation works.
- *
- * Test Method (Validation or Falsification):
- * -
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * -
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
-
-enum {
-	NUMTHREADS = 1
-};
-
-static int washere = 0;
-
-void * func(void * arg)
-{
-  washere = 1;
-  return (void *) 0; 
-}
- 
-int
-main()
-{
-  pthread_t t;
-  void * result = NULL;
-
-  washere = 0;
-  assert(pthread_create(&t, NULL, func, NULL) == 0);
-  assert(pthread_join(t, &result) == 0);
-  assert((int)(size_t)result == 0);
-  assert(washere == 1);
-  sched_yield();
-  assert(pthread_kill(t, 0) == ESRCH);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tests/valid2.c b/deps/w32-pthreads/tests/valid2.c
deleted file mode 100644
index 4d14857..0000000
--- a/deps/w32-pthreads/tests/valid2.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * File: valid2.c
- *
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * --------------------------------------------------------------------------
- *
- * Test Synopsis:
- * - Confirm that thread validation fails for garbage thread ID.
- *
- * Test Method (Validation or Falsification):
- * -
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * -
- *
- * Cases Tested:
- * -
- *
- * Description:
- * -
- *
- * Environment:
- * -
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * -
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#include "test.h"
- 
-int
-main()
-{
-  pthread_t NullThread = PTW32_THREAD_NULL_ID;
-
-  assert(pthread_kill(NullThread, 0) == ESRCH);
-
-  return 0;
-}
diff --git a/deps/w32-pthreads/tsd.c b/deps/w32-pthreads/tsd.c
deleted file mode 100644
index 9b4715b..0000000
--- a/deps/w32-pthreads/tsd.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * tsd.c
- *
- * Description:
- * POSIX thread functions which implement thread-specific data (TSD).
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-#include "pthread_key_create.c"
-#include "pthread_key_delete.c"
-#include "pthread_setspecific.c"
-#include "pthread_getspecific.c"
diff --git a/deps/w32-pthreads/version.rc b/deps/w32-pthreads/version.rc
deleted file mode 100644
index cac5304..0000000
--- a/deps/w32-pthreads/version.rc
+++ /dev/null
@@ -1,394 +0,0 @@
-/* This is an implementation of the threads API of POSIX 1003.1-2001.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <winver.h>
-#include "pthread.h"
-
-/*
- * Note: the correct __CLEANUP_* macro must be defined corresponding to
- * the definition used for the object file builds. This is done in the
- * relevent makefiles for the command line builds, but users should ensure
- * that their resource compiler knows what it is too.
- * If using the default (no __CLEANUP_* defined), pthread.h will define it
- * as __CLEANUP_C.
- */
-
-#if defined(__MINGW64__)
-#  define PTW32_ARCH "x64 (mingw64)"
-#elif defined (__MINGW32__)
-#  define PTW32_ARCH "x86 (mingw32)"
-#endif
-#if defined(PTW32_ARCHx64)
-#  define PTW32_ARCH "x64"
-#elif defined(PTW32_ARCHx86)
-#  define PTW32_ARCH "x86"
-#endif
-
-#if defined(PTW32_RC_MSC)
-#  if defined(__CLEANUP_C)
-#    define PTW32_VERSIONINFO_NAME "pthreadVC2.DLL\0"
-#    define PTW32_VERSIONINFO_DESCRIPTION "MS C " PTW32_ARCH "\0"
-#  elif defined(__CLEANUP_CXX)
-#    define PTW32_VERSIONINFO_NAME "pthreadVCE2.DLL\0"
-#    define PTW32_VERSIONINFO_DESCRIPTION "MS C++ " PTW32_ARCH "\0"
-#  elif defined(__CLEANUP_SEH)
-#    define PTW32_VERSIONINFO_NAME "pthreadVSE2.DLL\0"
-#    define PTW32_VERSIONINFO_DESCRIPTION "MS C SEH " PTW32_ARCH "\0"
-#  else
-#    error Resource compiler doesn't know which cleanup style you're using - see version.rc
-#  endif
-#elif defined(__GNUC__)
-#  if defined(__CLEANUP_C)
-#    define PTW32_VERSIONINFO_NAME "pthreadGC2.DLL\0"
-#    define PTW32_VERSIONINFO_DESCRIPTION "GNU C " PTW32_ARCH "\0"
-#  elif defined(__CLEANUP_CXX)
-#    define PTW32_VERSIONINFO_NAME "pthreadGCE2.DLL\0"
-#    define PTW32_VERSIONINFO_DESCRIPTION "GNU C++ " PTW32_ARCH "\0"
-#  else
-#    error Resource compiler doesn't know which cleanup style you're using - see version.rc
-#  endif
-#elif defined(__BORLANDC__)
-#  if defined(__CLEANUP_C)
-#    define PTW32_VERSIONINFO_NAME "pthreadBC2.DLL\0"
-#    define PTW32_VERSIONINFO_DESCRIPTION "BORLAND C " PTW32_ARCH "\0"
-#  elif defined(__CLEANUP_CXX)
-#    define PTW32_VERSIONINFO_NAME "pthreadBCE2.DLL\0"
-#    define PTW32_VERSIONINFO_DESCRIPTION "BORLAND C++ " PTW32_ARCH "\0"
-#  else
-#    error Resource compiler doesn't know which cleanup style you're using - see version.rc
-#  endif
-#elif defined(__WATCOMC__)
-#  if defined(__CLEANUP_C)
-#    define PTW32_VERSIONINFO_NAME "pthreadWC2.DLL\0"
-#    define PTW32_VERSIONINFO_DESCRIPTION "WATCOM C " PTW32_ARCH "\0"
-#  elif defined(__CLEANUP_CXX)
-#    define PTW32_VERSIONINFO_NAME "pthreadWCE2.DLL\0"
-#    define PTW32_VERSIONINFO_DESCRIPTION "WATCOM C++ " PTW32_ARCH "\0"
-#  else
-#    error Resource compiler doesn't know which cleanup style you're using - see version.rc
-#  endif
-#else
-#  error Resource compiler doesn't know which compiler you're using - see version.rc
-#endif
-
-
-VS_VERSION_INFO VERSIONINFO
-  FILEVERSION    PTW32_VERSION
-  PRODUCTVERSION PTW32_VERSION
-  FILEFLAGSMASK  VS_FFI_FILEFLAGSMASK
-  FILEFLAGS      0
-  FILEOS         VOS__WINDOWS32
-  FILETYPE       VFT_DLL
-BEGIN
-    BLOCK "StringFileInfo"
-    BEGIN
-        BLOCK "040904b0"
-        BEGIN
-            VALUE "ProductName", "POSIX Threads for Windows LPGL\0"
-            VALUE "ProductVersion", PTW32_VERSION_STRING
-            VALUE "FileVersion", PTW32_VERSION_STRING
-            VALUE "FileDescription", PTW32_VERSIONINFO_DESCRIPTION
-            VALUE "InternalName", PTW32_VERSIONINFO_NAME
-            VALUE "OriginalFilename", PTW32_VERSIONINFO_NAME
-            VALUE "CompanyName", "Open Source Software community LGPL\0"
-            VALUE "LegalCopyright", "Copyright (C) Project contributors 2012\0"
-            VALUE "Comments", "http://sourceware.org/pthreads-win32/\0"
-        END
-    END
-    BLOCK "VarFileInfo"
-    BEGIN
-        VALUE "Translation", 0x409, 1200
-    END
-END
-
-/*
-VERSIONINFO Resource
-
-The VERSIONINFO resource-definition statement creates a version-information
-resource. The resource contains such information about the file as its
-version number, its intended operating system, and its original filename.
-The resource is intended to be used with the Version Information functions.
-
-versionID VERSIONINFO fixed-info  { block-statement...}
-
-versionID
-    Version-information resource identifier. This value must be 1.
-
-fixed-info
-    Version information, such as the file version and the intended operating
-    system. This parameter consists of the following statements.
-
-
-    Statement 		Description
-    --------------------------------------------------------------------------
-    FILEVERSION
-    version 		Binary version number for the file. The version
-			consists of two 32-bit integers, defined by four
-			16-bit integers. For example, "FILEVERSION 3,10,0,61"
-			is translated into two doublewords: 0x0003000a and
-			0x0000003d, in that order. Therefore, if version is
-			defined by the DWORD values dw1 and dw2, they need
-			to appear in the FILEVERSION statement as follows:
-			HIWORD(dw1), LOWORD(dw1), HIWORD(dw2), LOWORD(dw2).
-    PRODUCTVERSION
-    version 		Binary version number for the product with which the
-			file is distributed. The version parameter is two
-			32-bit integers, defined by four 16-bit integers.
-			For more information about version, see the
-			FILEVERSION description.
-    FILEFLAGSMASK
-    fileflagsmask 	Bits in the FILEFLAGS statement are valid. If a bit
-			is set, the corresponding bit in FILEFLAGS is valid.
-    FILEFLAGSfileflags 	Attributes of the file. The fileflags parameter must
-			be the combination of all the file flags that are
-			valid at compile time. For 16-bit Windows, this
-			value is 0x3f.
-    FILEOSfileos 	Operating system for which this file was designed.
-			The fileos parameter can be one of the operating
-			system values given in the Remarks section.
-    FILETYPEfiletype 	General type of file. The filetype parameter can be
-			one of the file type values listed in the Remarks
-			section.
-    FILESUBTYPE
-    subtype 		Function of the file. The subtype parameter is zero
-			unless the type parameter in the FILETYPE statement
-			is VFT_DRV, VFT_FONT, or VFT_VXD. For a list of file
-			subtype values, see the Remarks section.
-
-block-statement
-    Specifies one or more version-information blocks. A block can contain
-    string information or variable information. For more information, see
-    StringFileInfo Block or VarFileInfo Block.
-
-Remarks
-
-To use the constants specified with the VERSIONINFO statement, you must
-include the Winver.h or Windows.h header file in the resource-definition file.
-
-The following list describes the parameters used in the VERSIONINFO statement:
-
-fileflags
-    A combination of the following values.
-
-    Value 		Description
-
-    VS_FF_DEBUG 	File contains debugging information or is compiled
-			with debugging features enabled.
-    VS_FF_PATCHED 	File has been modified and is not identical to the
-			original shipping file of the same version number.
-    VS_FF_PRERELEASE 	File is a development version, not a commercially
-			released product.
-    VS_FF_PRIVATEBUILD 	File was not built using standard release procedures.
-			If this value is given, the StringFileInfo block must
-			contain a PrivateBuild string.
-    VS_FF_SPECIALBUILD 	File was built by the original company using standard
-			release procedures but is a variation of the standard
-			file of the same version number. If this value is
-			given, the StringFileInfo block must contain a
-			SpecialBuild string.
-
-fileos
-    One of the following values.
-
-    Value 		Description
-
-    VOS_UNKNOWN 	The operating system for which the file was designed
-			is unknown.
-    VOS_DOS 		File was designed for MS-DOS.
-    VOS_NT 		File was designed for Windows Server 2003 family,
-			Windows XP, Windows 2000, or Windows NT.
-    VOS__WINDOWS16 	File was designed for 16-bit Windows.
-    VOS__WINDOWS32 	File was designed for 32-bit Windows.
-    VOS_DOS_WINDOWS16 	File was designed for 16-bit Windows running with
-			MS-DOS.
-    VOS_DOS_WINDOWS32 	File was designed for 32-bit Windows running with
-			MS-DOS.
-    VOS_NT_WINDOWS32 	File was designed for Windows Server 2003 family,
-			Windows XP, Windows 2000, or Windows NT.
-
-    The values 0x00002L, 0x00003L, 0x20000L and 0x30000L are reserved.
-
-filetype
-    One of the following values.
-
-    Value 		Description
-
-    VFT_UNKNOWN 	File type is unknown.
-    VFT_APP 		File contains an application.
-    VFT_DLL 		File contains a dynamic-link library (DLL).
-    VFT_DRV 		File contains a device driver. If filetype is
-			VFT_DRV, subtype contains a more specific
-			description of the driver.
-    VFT_FONT 		File contains a font. If filetype is VFT_FONT,
-			subtype contains a more specific description of the
-			font.
-    VFT_VXD 		File contains a virtual device.
-    VFT_STATIC_LIB 	File contains a static-link library.
-
-    All other values are reserved for use by Microsoft.
-
-subtype
-    Additional information about the file type.
-
-    If filetype specifies VFT_DRV, this parameter can be one of the
-    following values.
-
-    Value 			Description
-
-    VFT2_UNKNOWN 		Driver type is unknown.
-    VFT2_DRV_COMM 		File contains a communications driver.
-    VFT2_DRV_PRINTER 		File contains a printer driver.
-    VFT2_DRV_KEYBOARD 		File contains a keyboard driver.
-    VFT2_DRV_LANGUAGE 		File contains a language driver.
-    VFT2_DRV_DISPLAY 		File contains a display driver.
-    VFT2_DRV_MOUSE 		File contains a mouse driver.
-    VFT2_DRV_NETWORK 		File contains a network driver.
-    VFT2_DRV_SYSTEM 		File contains a system driver.
-    VFT2_DRV_INSTALLABLE 	File contains an installable driver.
-    VFT2_DRV_SOUND 		File contains a sound driver.
-    VFT2_DRV_VERSIONED_PRINTER 	File contains a versioned printer driver.
-
-    If filetype specifies VFT_FONT, this parameter can be one of the
-    following values.
-
-    Value 		Description
-
-    VFT2_UNKNOWN 	Font type is unknown.
-    VFT2_FONT_RASTER 	File contains a raster font.
-    VFT2_FONT_VECTOR 	File contains a vector font.
-    VFT2_FONT_TRUETYPE 	File contains a TrueType font.
-
-    If filetype specifies VFT_VXD, this parameter must be the virtual-device
-    identifier included in the virtual-device control block.
-
-    All subtype values not listed here are reserved for use by Microsoft.
-
-langID
-    One of the following language codes.
-
-    Code 	Language 		Code 	Language
-
-    0x0401 	Arabic 			0x0415 	Polish
-    0x0402 	Bulgarian 		0x0416 	Portuguese (Brazil)
-    0x0403 	Catalan 		0x0417 	Rhaeto-Romanic
-    0x0404 	Traditional Chinese 	0x0418 	Romanian
-    0x0405 	Czech 			0x0419 	Russian
-    0x0406 	Danish 			0x041A 	Croato-Serbian (Latin)
-    0x0407 	German 			0x041B 	Slovak
-    0x0408 	Greek 			0x041C 	Albanian
-    0x0409 	U.S. English 		0x041D 	Swedish
-    0x040A 	Castilian Spanish 	0x041E 	Thai
-    0x040B 	Finnish 		0x041F 	Turkish
-    0x040C 	French 			0x0420 	Urdu
-    0x040D 	Hebrew 			0x0421 	Bahasa
-    0x040E 	Hungarian 		0x0804 	Simplified Chinese
-    0x040F 	Icelandic 		0x0807 	Swiss German
-    0x0410 	Italian 		0x0809 	U.K. English
-    0x0411 	Japanese 		0x080A 	Mexican Spanish
-    0x0412 	Korean 			0x080C 	Belgian French
-    0x0413 	Dutch 			0x0C0C 	Canadian French
-    0x0414 	Norwegian – Bokmal 	0x100C 	Swiss French
-    0x0810 	Swiss Italian 		0x0816 	Portuguese (Portugal)
-    0x0813 	Belgian Dutch 		0x081A 	Serbo-Croatian (Cyrillic)
-    0x0814 	Norwegian – Nynorsk 	  	 
-
-charsetID
-    One of the following character-set identifiers.
-
-    Identifier 	Character Set
-
-    0 		7-bit ASCII
-    932 	Japan (Shift %G–%@ JIS X-0208)
-    949 	Korea (Shift %G–%@ KSC 5601)
-    950 	Taiwan (Big5)
-    1200 	Unicode
-    1250 	Latin-2 (Eastern European)
-    1251 	Cyrillic
-    1252 	Multilingual
-    1253 	Greek
-    1254 	Turkish
-    1255 	Hebrew
-    1256 	Arabic
-
-string-name
-    One of the following predefined names.
-
-    Name 		Description
-
-    Comments 		Additional information that should be displayed for
-			diagnostic purposes.
-    CompanyName 	Company that produced the file%G—%@for example,
-			"Microsoft Corporation" or "Standard Microsystems
-			Corporation, Inc." This string is required.
-    FileDescription 	File description to be presented to users. This
-			string may be displayed in a list box when the user
-			is choosing files to install%G—%@for example,
-			"Keyboard Driver for AT-Style Keyboards". This
-			string is required.
-    FileVersion 	Version number of the file%G—%@for example,
-			"3.10" or "5.00.RC2". This string is required.
-    InternalName 	Internal name of the file, if one exists — for
-			example, a module name if the file is a dynamic-link
-			library. If the file has no internal name, this
-			string should be the original filename, without
-			extension. This string is required.
-    LegalCopyright 	Copyright notices that apply to the file. This
-			should include the full text of all notices, legal
-			symbols, copyright dates, and so on — for example,
-			"Copyright (C) Microsoft Corporation 1990–1999".
-			This string is optional.
-    LegalTrademarks 	Trademarks and registered trademarks that apply to
-			the file. This should include the full text of all
-			notices, legal symbols, trademark numbers, and so on.
-			This string is optional.
-    OriginalFilename 	Original name of the file, not including a path.
-			This information enables an application to determine
-			whether a file has been renamed by a user. The
-			format of the name depends on the file system for
-			which the file was created. This string is required.
-    PrivateBuild 	Information about a private version of the file — for
-			example, "Built by TESTER1 on \TESTBED". This string
-			should be present only if VS_FF_PRIVATEBUILD is
-			specified in the fileflags parameter of the root
-			block.
-    ProductName 	Name of the product with which the file is
-			distributed. This string is required.
-    ProductVersion 	Version of the product with which the file is
-			distributed — for example, "3.10" or "5.00.RC2".
-			This string is required.
-    SpecialBuild 	Text that indicates how this version of the file
-			differs from the standard version — for example,
-			"Private build for TESTER1 solving mouse problems
-			on M250 and M250E computers". This string should be
-			present only if VS_FF_SPECIALBUILD is specified in
-			the fileflags parameter of the root block.
- */
diff --git a/deps/w32-pthreads/w32-pthreadsConfig.cmake.in b/deps/w32-pthreads/w32-pthreadsConfig.cmake.in
deleted file mode 100644
index 2fe4aec..0000000
--- a/deps/w32-pthreads/w32-pthreadsConfig.cmake.in
+++ /dev/null
@@ -1,15 +0,0 @@
-# - Config file for the w32-pthreads package
-# It defines the following variables
-#  THREADS_INCLUDE_DIRS
-#  THREADS_LIBRARIES
-
-set(W32_PTHREADS_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@")
-
-# Cleanup possible relative paths
-get_filename_component(W32_PTHREADS_INCLUDE_DIRS "${THREADS_INCLUDE_DIRS}" ABSOLUTE)
-
-if(NOT TARGET w32-pthreads)
-	include("${CMAKE_CURRENT_LIST_DIR}/w32-pthreadsTarget.cmake")
-endif()
-
-set(W32_PTHREADS_LIBRARIES w32-pthreads)
diff --git a/deps/w32-pthreads/w32-pthreadsConfigVersion.cmake.in b/deps/w32-pthreads/w32-pthreadsConfigVersion.cmake.in
deleted file mode 100644
index e69de29..0000000
diff --git a/deps/w32-pthreads/w32_CancelableWait.c b/deps/w32-pthreads/w32_CancelableWait.c
deleted file mode 100644
index eb4c611..0000000
--- a/deps/w32-pthreads/w32_CancelableWait.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * w32_CancelableWait.c
- *
- * Description:
- * This translation unit implements miscellaneous thread functions.
- *
- * --------------------------------------------------------------------------
- *
- *      Pthreads-win32 - POSIX Threads Library for Win32
- *      Copyright(C) 1998 John E. Bossom
- *      Copyright(C) 1999,2005 Pthreads-win32 contributors
- * 
- *      Contact Email: rpj at callisto.canberra.edu.au
- * 
- *      The current list of contributors is contained
- *      in the file CONTRIBUTORS included with the source
- *      code distribution. The list can also be seen at the
- *      following World Wide Web location:
- *      http://sources.redhat.com/pthreads-win32/contributors.html
- * 
- *      This library is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU Lesser General Public
- *      License as published by the Free Software Foundation; either
- *      version 2 of the License, or (at your option) any later version.
- * 
- *      This library is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *      Lesser General Public License for more details.
- * 
- *      You should have received a copy of the GNU Lesser General Public
- *      License along with this library in the file COPYING.LIB;
- *      if not, write to the Free Software Foundation, Inc.,
- *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "pthread.h"
-#include "implement.h"
-
-
-static INLINE int
-ptw32_cancelable_wait (HANDLE waitHandle, DWORD timeout)
-     /*
-      * -------------------------------------------------------------------
-      * This provides an extra hook into the pthread_cancel
-      * mechanism that will allow you to wait on a Windows handle and make it a
-      * cancellation point. This function blocks until the given WIN32 handle is
-      * signaled or pthread_cancel has been called. It is implemented using
-      * WaitForMultipleObjects on 'waitHandle' and a manually reset WIN32
-      * event used to implement pthread_cancel.
-      * 
-      * Given this hook it would be possible to implement more of the cancellation
-      * points.
-      * -------------------------------------------------------------------
-      */
-{
-  int result;
-  pthread_t self;
-  ptw32_thread_t * sp;
-  HANDLE handles[2];
-  DWORD nHandles = 1;
-  DWORD status;
-
-  handles[0] = waitHandle;
-
-  self = pthread_self();
-  sp = (ptw32_thread_t *) self.p;
-
-  if (sp != NULL)
-    {
-      /*
-       * Get cancelEvent handle
-       */
-      if (sp->cancelState == PTHREAD_CANCEL_ENABLE)
-	{
-
-	  if ((handles[1] = sp->cancelEvent) != NULL)
-	    {
-	      nHandles++;
-	    }
-	}
-    }
-  else
-    {
-      handles[1] = NULL;
-    }
-
-  status = WaitForMultipleObjects (nHandles, handles, PTW32_FALSE, timeout);
-
-  switch (status - WAIT_OBJECT_0)
-    {
-    case 0:
-      /*
-       * Got the handle.
-       * In the event that both handles are signalled, the smallest index
-       * value (us) is returned. As it has been arranged, this ensures that
-       * we don't drop a signal that we should act on (i.e. semaphore,
-       * mutex, or condition variable etc).
-       */
-      result = 0;
-      break;
-
-    case 1:
-      /*
-       * Got cancel request.
-       * In the event that both handles are signaled, the cancel will
-       * be ignored (see case 0 comment).
-       */
-      ResetEvent (handles[1]);
-
-      if (sp != NULL)
-	{
-          ptw32_mcs_local_node_t stateLock;
-	  /*
-	   * Should handle POSIX and implicit POSIX threads..
-	   * Make sure we haven't been async-canceled in the meantime.
-	   */
-	  ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
-	  if (sp->state < PThreadStateCanceling)
-	    {
-	      sp->state = PThreadStateCanceling;
-	      sp->cancelState = PTHREAD_CANCEL_DISABLE;
-	      ptw32_mcs_lock_release (&stateLock);
-	      ptw32_throw (PTW32_EPS_CANCEL);
-
-	      /* Never reached */
-	    }
-	  ptw32_mcs_lock_release (&stateLock);
-	}
-
-      /* Should never get to here. */
-      result = EINVAL;
-      break;
-
-    default:
-      if (status == WAIT_TIMEOUT)
-	{
-	  result = ETIMEDOUT;
-	}
-      else
-	{
-	  result = EINVAL;
-	}
-      break;
-    }
-
-  return (result);
-
-}				/* CancelableWait */
-
-int
-pthreadCancelableWait (HANDLE waitHandle)
-{
-  return (ptw32_cancelable_wait (waitHandle, INFINITE));
-}
-
-int
-pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout)
-{
-  return (ptw32_cancelable_wait (waitHandle, timeout));
-}
diff --git a/libobs-d3d11/CMakeLists.txt b/libobs-d3d11/CMakeLists.txt
index 95d85c0..e30828b 100644
--- a/libobs-d3d11/CMakeLists.txt
+++ b/libobs-d3d11/CMakeLists.txt
@@ -14,6 +14,7 @@ set(libobs-d3d11_SOURCES
 	d3d11-texture2d.cpp
 	d3d11-vertexbuffer.cpp
 	d3d11-duplicator.cpp
+	d3d11-rebuild.cpp
 	d3d11-zstencilbuffer.cpp)
 
 set(libobs-d3d11_HEADERS
diff --git a/libobs-d3d11/d3d11-duplicator.cpp b/libobs-d3d11/d3d11-duplicator.cpp
index 547522b..5970b4a 100644
--- a/libobs-d3d11/d3d11-duplicator.cpp
+++ b/libobs-d3d11/d3d11-duplicator.cpp
@@ -20,20 +20,9 @@
 static inline bool get_monitor(gs_device_t *device, int monitor_idx,
 		IDXGIOutput **dxgiOutput)
 {
-	ComPtr<IDXGIAdapter> dxgiAdapter;
-	ComPtr<IDXGIDevice> dxgiDevice;
 	HRESULT hr;
 
-	hr = device->device->QueryInterface(__uuidof(IDXGIDevice),
-			(void**)dxgiDevice.Assign());
-	if (FAILED(hr))
-		throw HRError("Failed to query IDXGIDevice", hr);
-
-	hr = dxgiDevice->GetAdapter(dxgiAdapter.Assign());
-	if (FAILED(hr))
-		throw HRError("Failed to get adapter", hr);
-
-	hr = dxgiAdapter->EnumOutputs(monitor_idx, dxgiOutput);
+	hr = device->adapter->EnumOutputs(monitor_idx, dxgiOutput);
 	if (FAILED(hr)) {
 		if (hr == DXGI_ERROR_NOT_FOUND)
 			return false;
@@ -44,14 +33,13 @@ static inline bool get_monitor(gs_device_t *device, int monitor_idx,
 	return true;
 }
 
-gs_duplicator::gs_duplicator(gs_device_t *device_, int monitor_idx)
-	: texture(nullptr), device(device_)
+void gs_duplicator::Start()
 {
 	ComPtr<IDXGIOutput1> output1;
 	ComPtr<IDXGIOutput> output;
 	HRESULT hr;
 
-	if (!get_monitor(device, monitor_idx, output.Assign()))
+	if (!get_monitor(device, idx, output.Assign()))
 		throw "Invalid monitor index";
 
 	hr = output->QueryInterface(__uuidof(IDXGIOutput1),
@@ -64,6 +52,14 @@ gs_duplicator::gs_duplicator(gs_device_t *device_, int monitor_idx)
 		throw HRError("Failed to duplicate output", hr);
 }
 
+gs_duplicator::gs_duplicator(gs_device_t *device_, int monitor_idx)
+	: gs_obj  (device_, gs_type::gs_duplicator),
+	  texture (nullptr),
+	  idx     (monitor_idx)
+{
+	Start();
+}
+
 gs_duplicator::~gs_duplicator()
 {
 	delete texture;
diff --git a/libobs-d3d11/d3d11-indexbuffer.cpp b/libobs-d3d11/d3d11-indexbuffer.cpp
index ccb92a8..d95139a 100644
--- a/libobs-d3d11/d3d11-indexbuffer.cpp
+++ b/libobs-d3d11/d3d11-indexbuffer.cpp
@@ -19,8 +19,6 @@
 
 void gs_index_buffer::InitBuffer()
 {
-	D3D11_BUFFER_DESC bd;
-	D3D11_SUBRESOURCE_DATA srd;
 	HRESULT hr;
 
 	memset(&bd,  0, sizeof(bd));
@@ -39,7 +37,7 @@ void gs_index_buffer::InitBuffer()
 
 gs_index_buffer::gs_index_buffer(gs_device_t *device, enum gs_index_type type,
 		void *indices, size_t num, uint32_t flags)
-	: device  (device),
+	: gs_obj  (device, gs_type::gs_index_buffer),
 	  dynamic ((flags & GS_DYNAMIC) != 0),
 	  type    (type),
 	  num     (num),
diff --git a/libobs-d3d11/d3d11-rebuild.cpp b/libobs-d3d11/d3d11-rebuild.cpp
new file mode 100644
index 0000000..c0b1c13
--- /dev/null
+++ b/libobs-d3d11/d3d11-rebuild.cpp
@@ -0,0 +1,348 @@
+/******************************************************************************
+    Copyright (C) 2016 by Hugh Bailey <obs.jim at gmail.com>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+******************************************************************************/
+
+#include "d3d11-subsystem.hpp"
+
+inline void gs_vertex_buffer::Rebuild()
+{
+	uvBuffers.clear();
+	uvSizes.clear();
+	BuildBuffers();
+}
+
+inline void gs_index_buffer::Rebuild(ID3D11Device *dev)
+{
+	HRESULT hr = dev->CreateBuffer(&bd, &srd, &indexBuffer);
+	if (FAILED(hr))
+		throw HRError("Failed to create buffer", hr);
+}
+
+void gs_texture_2d::RebuildSharedTextureFallback()
+{
+	td                  = {};
+	td.Width            = 2;
+	td.Height           = 2;
+	td.MipLevels        = 1;
+	td.Format           = DXGI_FORMAT_B8G8R8A8_UNORM;
+	td.ArraySize        = 1;
+	td.SampleDesc.Count = 1;
+
+	width      = td.Width;
+	height     = td.Height;
+	dxgiFormat = td.Format;
+	levels     = 1;
+
+	resourceDesc = {};
+	resourceDesc.Format              = td.Format;
+	resourceDesc.ViewDimension       = D3D11_SRV_DIMENSION_TEXTURE2D;
+	resourceDesc.Texture2D.MipLevels = 1;
+
+	isShared = false;
+}
+
+inline void gs_texture_2d::Rebuild(ID3D11Device *dev)
+{
+	HRESULT hr;
+	if (isShared) {
+		hr = dev->OpenSharedResource((HANDLE)(uintptr_t)sharedHandle,
+				__uuidof(ID3D11Texture2D), (void**)&texture);
+		if (FAILED(hr)) {
+			blog(LOG_WARNING, "Failed to rebuild shared texture: ",
+					"0x%08lX", hr);
+			RebuildSharedTextureFallback();
+		}
+	}
+
+	if (!isShared) {
+		hr = dev->CreateTexture2D(&td,
+				data.size() ? srd.data() : nullptr,
+				&texture);
+		if (FAILED(hr))
+			throw HRError("Failed to create 2D texture", hr);
+	}
+
+	hr = dev->CreateShaderResourceView(texture, &resourceDesc, &shaderRes);
+	if (FAILED(hr))
+		throw HRError("Failed to create resource view", hr);
+
+	if (isRenderTarget)
+		InitRenderTargets();
+
+	if (isGDICompatible) {
+		hr = texture->QueryInterface(__uuidof(IDXGISurface1),
+				(void**)&gdiSurface);
+		if (FAILED(hr))
+			throw HRError("Failed to create GDI surface", hr);
+	}
+}
+
+inline void gs_zstencil_buffer::Rebuild(ID3D11Device *dev)
+{
+	HRESULT hr;
+	hr = dev->CreateTexture2D(&td, nullptr, &texture);
+	if (FAILED(hr))
+		throw HRError("Failed to create depth stencil texture", hr);
+
+	hr = dev->CreateDepthStencilView(texture, &dsvd, &view);
+	if (FAILED(hr))
+		throw HRError("Failed to create depth stencil view", hr);
+}
+
+inline void gs_stage_surface::Rebuild(ID3D11Device *dev)
+{
+	HRESULT hr = dev->CreateTexture2D(&td, nullptr, &texture);
+	if (FAILED(hr))
+		throw HRError("Failed to create staging surface", hr);
+}
+
+inline void gs_sampler_state::Rebuild(ID3D11Device *dev)
+{
+	HRESULT hr = dev->CreateSamplerState(&sd, state.Assign());
+	if (FAILED(hr))
+		throw HRError("Failed to create sampler state", hr);
+}
+
+inline void gs_vertex_shader::Rebuild(ID3D11Device *dev)
+{
+	HRESULT hr;
+	hr = dev->CreateVertexShader(data.data(), data.size(), nullptr, &shader);
+	if (FAILED(hr))
+		throw HRError("Failed to create vertex shader", hr);
+
+	hr = dev->CreateInputLayout(layoutData.data(), (UINT)layoutData.size(),
+			data.data(), data.size(), &layout);
+	if (FAILED(hr))
+		throw HRError("Failed to create input layout", hr);
+
+	if (constantSize) {
+		hr = dev->CreateBuffer(&bd, NULL, &constants);
+		if (FAILED(hr))
+			throw HRError("Failed to create constant buffer", hr);
+	}
+
+	for (gs_shader_param &param : params) {
+		param.nextSampler = nullptr;
+		param.curValue.clear();
+		gs_shader_set_default(&param);
+	}
+}
+
+inline void gs_pixel_shader::Rebuild(ID3D11Device *dev)
+{
+	HRESULT hr;
+	
+	hr = dev->CreatePixelShader(data.data(), data.size(), nullptr,
+			&shader);
+	if (FAILED(hr))
+		throw HRError("Failed to create pixel shader", hr);
+
+	if (constantSize) {
+		hr = dev->CreateBuffer(&bd, NULL, &constants);
+		if (FAILED(hr))
+			throw HRError("Failed to create constant buffer", hr);
+	}
+
+	for (gs_shader_param &param : params) {
+		param.nextSampler = nullptr;
+		param.curValue.clear();
+		gs_shader_set_default(&param);
+	}
+}
+
+inline void gs_swap_chain::Rebuild(ID3D11Device *dev)
+{
+	HRESULT hr = device->factory->CreateSwapChain(dev, &swapDesc, &swap);
+	if (FAILED(hr))
+		throw HRError("Failed to create swap chain", hr);
+	Init();
+}
+
+inline void SavedBlendState::Rebuild(ID3D11Device *dev)
+{
+	HRESULT hr = dev->CreateBlendState(&bd, &state);
+	if (FAILED(hr))
+		throw HRError("Failed to create blend state", hr);
+}
+
+inline void SavedZStencilState::Rebuild(ID3D11Device *dev)
+{
+	HRESULT hr = dev->CreateDepthStencilState(&dsd, &state);
+	if (FAILED(hr))
+		throw HRError("Failed to create depth stencil state", hr);
+}
+
+inline void SavedRasterState::Rebuild(ID3D11Device *dev)
+{
+	HRESULT hr = dev->CreateRasterizerState(&rd, &state);
+	if (FAILED(hr))
+		throw HRError("Failed to create rasterizer state", hr);
+}
+
+const static D3D_FEATURE_LEVEL featureLevels[] =
+{
+	D3D_FEATURE_LEVEL_11_0,
+	D3D_FEATURE_LEVEL_10_1,
+	D3D_FEATURE_LEVEL_10_0,
+	D3D_FEATURE_LEVEL_9_3,
+};
+
+void gs_device::RebuildDevice()
+try {
+	ID3D11Device *dev = nullptr;
+	HRESULT hr;
+
+	blog(LOG_WARNING, "Device Remove/Reset!  Rebuilding all assets...");
+
+	/* ----------------------------------------------------------------- */
+
+	gs_obj *obj = first_obj;
+
+	while (obj) {
+		switch (obj->obj_type) {
+		case gs_type::gs_vertex_buffer:
+			((gs_vertex_buffer*)obj)->Release();
+			break;
+		case gs_type::gs_index_buffer:
+			((gs_index_buffer*)obj)->Release();
+			break;
+		case gs_type::gs_texture_2d:
+			((gs_texture_2d*)obj)->Release();
+			break;
+		case gs_type::gs_zstencil_buffer:
+			((gs_zstencil_buffer*)obj)->Release();
+			break;
+		case gs_type::gs_stage_surface:
+			((gs_stage_surface*)obj)->Release();
+			break;
+		case gs_type::gs_sampler_state:
+			((gs_sampler_state*)obj)->Release();
+			break;
+		case gs_type::gs_vertex_shader:
+			((gs_vertex_shader*)obj)->Release();
+			break;
+		case gs_type::gs_pixel_shader:
+			((gs_pixel_shader*)obj)->Release();
+			break;
+		case gs_type::gs_duplicator:
+			((gs_duplicator*)obj)->Release();
+			break;
+		case gs_type::gs_swap_chain:
+			((gs_swap_chain*)obj)->Release();
+			break;
+		}
+
+		obj = obj->next;
+	}
+
+	for (auto &state : zstencilStates)
+		state.Release();
+	for (auto &state : rasterStates)
+		state.Release();
+	for (auto &state : blendStates)
+		state.Release();
+
+	context->ClearState();
+
+	context.Release();
+	device.Release();
+	adapter.Release();
+	factory.Release();
+
+	/* ----------------------------------------------------------------- */
+
+	InitFactory(adpIdx);
+
+	uint32_t createFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+	hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN,
+			nullptr, createFlags, featureLevels,
+			sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL),
+			D3D11_SDK_VERSION, &device, nullptr, &context);
+	if (FAILED(hr))
+		throw HRError("Failed to create device", hr);
+
+	dev = device;
+
+	obj = first_obj;
+	while (obj) {
+		switch (obj->obj_type) {
+		case gs_type::gs_vertex_buffer:
+			((gs_vertex_buffer*)obj)->Rebuild();
+			break;
+		case gs_type::gs_index_buffer:
+			((gs_index_buffer*)obj)->Rebuild(dev);
+			break;
+		case gs_type::gs_texture_2d:
+			((gs_texture_2d*)obj)->Rebuild(dev);
+			break;
+		case gs_type::gs_zstencil_buffer:
+			((gs_zstencil_buffer*)obj)->Rebuild(dev);
+			break;
+		case gs_type::gs_stage_surface:
+			((gs_stage_surface*)obj)->Rebuild(dev);
+			break;
+		case gs_type::gs_sampler_state:
+			((gs_sampler_state*)obj)->Rebuild(dev);
+			break;
+		case gs_type::gs_vertex_shader:
+			((gs_vertex_shader*)obj)->Rebuild(dev);
+			break;
+		case gs_type::gs_pixel_shader:
+			((gs_pixel_shader*)obj)->Rebuild(dev);
+			break;
+		case gs_type::gs_duplicator:
+			((gs_duplicator*)obj)->Start();
+			break;
+		case gs_type::gs_swap_chain:
+			((gs_swap_chain*)obj)->Rebuild(dev);
+			break;
+		}
+
+		obj = obj->next;
+	}
+
+	curRenderTarget = nullptr;
+	curZStencilBuffer = nullptr;
+	curRenderSide = 0;
+	memset(&curTextures, 0, sizeof(curTextures));
+	memset(&curSamplers, 0, sizeof(curSamplers));
+	curVertexBuffer = nullptr;
+	curIndexBuffer = nullptr;
+	curVertexShader = nullptr;
+	curPixelShader = nullptr;
+	curSwapChain = nullptr;
+	zstencilStateChanged = true;
+	rasterStateChanged = true;
+	blendStateChanged = true;
+	curDepthStencilState = nullptr;
+	curRasterState = nullptr;
+	curBlendState = nullptr;
+	curToplogy = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
+
+	for (auto &state : zstencilStates)
+		state.Rebuild(dev);
+	for (auto &state : rasterStates)
+		state.Rebuild(dev);
+	for (auto &state : blendStates)
+		state.Rebuild(dev);
+
+} catch (const char *error) {
+	bcrash("Failed to recreate D3D11: %s", error);
+
+} catch (HRError error) {
+	bcrash("Failed to recreate D3D11: %s (%08lX)",
+			error.str, error.hr);
+}
diff --git a/libobs-d3d11/d3d11-samplerstate.cpp b/libobs-d3d11/d3d11-samplerstate.cpp
index 9e5b2fc..67b4005 100644
--- a/libobs-d3d11/d3d11-samplerstate.cpp
+++ b/libobs-d3d11/d3d11-samplerstate.cpp
@@ -62,10 +62,9 @@ static inline D3D11_FILTER ConvertGSFilter( gs_sample_filter filter)
 
 gs_sampler_state::gs_sampler_state(gs_device_t *device,
 		const gs_sampler_info *info)
-	: device (device),
+	: gs_obj (device, gs_type::gs_sampler_state),
 	  info   (*info)
 {
-	D3D11_SAMPLER_DESC sd;
 	HRESULT hr;
 	vec4 v4;
 
diff --git a/libobs-d3d11/d3d11-shader.cpp b/libobs-d3d11/d3d11-shader.cpp
index 95cfbb0..fc3159f 100644
--- a/libobs-d3d11/d3d11-shader.cpp
+++ b/libobs-d3d11/d3d11-shader.cpp
@@ -40,13 +40,12 @@ void gs_vertex_shader::GetBuffersExpected(
 
 gs_vertex_shader::gs_vertex_shader(gs_device_t *device, const char *file,
 		const char *shaderString)
-	: gs_shader   (device, GS_SHADER_VERTEX),
+	: gs_shader   (device, gs_type::gs_vertex_shader, GS_SHADER_VERTEX),
 	  hasNormals  (false),
 	  hasColors   (false),
 	  hasTangents (false),
 	  nTexUnits   (0)
 {
-	vector<D3D11_INPUT_ELEMENT_DESC> inputs;
 	ShaderProcessor    processor(device);
 	ComPtr<ID3D10Blob> shaderBlob;
 	string             outputString;
@@ -55,20 +54,23 @@ gs_vertex_shader::gs_vertex_shader(gs_device_t *device, const char *file,
 	processor.Process(shaderString, file);
 	processor.BuildString(outputString);
 	processor.BuildParams(params);
-	processor.BuildInputLayout(inputs);
-	GetBuffersExpected(inputs);
+	processor.BuildInputLayout(layoutData);
+	GetBuffersExpected(layoutData);
 	BuildConstantBuffer();
 
 	Compile(outputString.c_str(), file, "vs_4_0", shaderBlob.Assign());
 
-	hr = device->device->CreateVertexShader(shaderBlob->GetBufferPointer(),
-			shaderBlob->GetBufferSize(), NULL, shader.Assign());
+	data.resize(shaderBlob->GetBufferSize());
+	memcpy(&data[0], shaderBlob->GetBufferPointer(), data.size());
+
+	hr = device->device->CreateVertexShader(data.data(), data.size(),
+			NULL, shader.Assign());
 	if (FAILED(hr))
 		throw HRError("Failed to create vertex shader", hr);
 
-	hr = device->device->CreateInputLayout(inputs.data(),
-			(UINT)inputs.size(), shaderBlob->GetBufferPointer(),
-			shaderBlob->GetBufferSize(), layout.Assign());
+	hr = device->device->CreateInputLayout(layoutData.data(),
+			(UINT)layoutData.size(),
+			data.data(), data.size(), layout.Assign());
 	if (FAILED(hr))
 		throw HRError("Failed to create input layout", hr);
 
@@ -78,7 +80,7 @@ gs_vertex_shader::gs_vertex_shader(gs_device_t *device, const char *file,
 
 gs_pixel_shader::gs_pixel_shader(gs_device_t *device, const char *file,
 		const char *shaderString)
-	: gs_shader(device, GS_SHADER_PIXEL)
+	: gs_shader(device, gs_type::gs_pixel_shader, GS_SHADER_PIXEL)
 {
 	ShaderProcessor    processor(device);
 	ComPtr<ID3D10Blob> shaderBlob;
@@ -93,10 +95,13 @@ gs_pixel_shader::gs_pixel_shader(gs_device_t *device, const char *file,
 
 	Compile(outputString.c_str(), file, "ps_4_0", shaderBlob.Assign());
 
-	hr = device->device->CreatePixelShader(shaderBlob->GetBufferPointer(),
-			shaderBlob->GetBufferSize(), NULL, shader.Assign());
+	data.resize(shaderBlob->GetBufferSize());
+	memcpy(&data[0], shaderBlob->GetBufferPointer(), data.size());
+
+	hr = device->device->CreatePixelShader(data.data(), data.size(),
+			NULL, shader.Assign());
 	if (FAILED(hr))
-		throw HRError("Failed to create vertex shader", hr);
+		throw HRError("Failed to create pixel shader", hr);
 }
 
 /*
@@ -157,11 +162,11 @@ void gs_shader::BuildConstantBuffer()
 		constantSize += size;
 	}
 
+	memset(&bd, 0, sizeof(bd));
+
 	if (constantSize) {
-		D3D11_BUFFER_DESC bd;
 		HRESULT hr;
 
-		memset(&bd, 0, sizeof(bd));
 		bd.ByteWidth      = (constantSize+15)&0xFFFFFFF0; /* align */
 		bd.Usage          = D3D11_USAGE_DYNAMIC;
 		bd.BindFlags      = D3D11_BIND_CONSTANT_BUFFER;
@@ -196,6 +201,22 @@ void gs_shader::Compile(const char *shaderString, const char *file,
 		else
 			throw HRError("Failed to compile shader", hr);
 	}
+
+#ifdef DISASSEMBLE_SHADERS
+	ComPtr<ID3D10Blob> asmBlob;
+
+	if (!device->d3dDisassemble)
+		return;
+
+	hr = device->d3dDisassemble((*shader)->GetBufferPointer(),
+			(*shader)->GetBufferSize(), 0, nullptr, &asmBlob);
+
+	if (SUCCEEDED(hr) && !!asmBlob && asmBlob->GetBufferSize()) {
+		blog(LOG_INFO, "=============================================");
+		blog(LOG_INFO, "Disassembly output for shader '%s':\n%s",
+				file, asmBlob->GetBufferPointer());
+	}
+#endif
 }
 
 inline void gs_shader::UpdateParam(vector<uint8_t> &constData,
diff --git a/libobs-d3d11/d3d11-shaderprocessor.cpp b/libobs-d3d11/d3d11-shaderprocessor.cpp
index 9bee687..7b0b14d 100644
--- a/libobs-d3d11/d3d11-shaderprocessor.cpp
+++ b/libobs-d3d11/d3d11-shaderprocessor.cpp
@@ -181,14 +181,14 @@ void ShaderProcessor::BuildParams(vector<gs_shader_param> &params)
 }
 
 static inline void AddSampler(gs_device_t *device, shader_sampler &sampler,
-		vector<ShaderSampler> &samplers)
+		vector<unique_ptr<ShaderSampler>> &samplers)
 {
 	gs_sampler_info si;
 	shader_sampler_convert(&sampler, &si);
-	samplers.push_back(ShaderSampler(sampler.name, device, &si));
+	samplers.emplace_back(new ShaderSampler(sampler.name, device, &si));
 }
 
-void ShaderProcessor::BuildSamplers(vector<ShaderSampler> &samplers)
+void ShaderProcessor::BuildSamplers(vector<unique_ptr<ShaderSampler>> &samplers)
 {
 	for (size_t i = 0; i < parser.samplers.num; i++)
 		AddSampler(device, parser.samplers.array[i], samplers);
diff --git a/libobs-d3d11/d3d11-shaderprocessor.hpp b/libobs-d3d11/d3d11-shaderprocessor.hpp
index c432d57..afc939c 100644
--- a/libobs-d3d11/d3d11-shaderprocessor.hpp
+++ b/libobs-d3d11/d3d11-shaderprocessor.hpp
@@ -30,7 +30,7 @@ struct ShaderProcessor {
 
 	void BuildInputLayout(vector<D3D11_INPUT_ELEMENT_DESC> &inputs);
 	void BuildParams(vector<gs_shader_param> &params);
-	void BuildSamplers(vector<ShaderSampler> &samplers);
+	void BuildSamplers(vector<unique_ptr<ShaderSampler>> &samplers);
 	void BuildString(string &outputString);
 	void Process(const char *shader_string, const char *file);
 
diff --git a/libobs-d3d11/d3d11-stagesurf.cpp b/libobs-d3d11/d3d11-stagesurf.cpp
index dfe702b..c08b462 100644
--- a/libobs-d3d11/d3d11-stagesurf.cpp
+++ b/libobs-d3d11/d3d11-stagesurf.cpp
@@ -19,13 +19,12 @@
 
 gs_stage_surface::gs_stage_surface(gs_device_t *device, uint32_t width,
 		uint32_t height, gs_color_format colorFormat)
-	: device     (device),
+	: gs_obj     (device, gs_type::gs_stage_surface),
 	  width      (width),
 	  height     (height),
 	  format     (colorFormat),
 	  dxgiFormat (ConvertGSTextureFormat(colorFormat))
 {
-	D3D11_TEXTURE2D_DESC td;
 	HRESULT hr;
 
 	memset(&td, 0, sizeof(td));
@@ -40,5 +39,5 @@ gs_stage_surface::gs_stage_surface(gs_device_t *device, uint32_t width,
 
 	hr = device->device->CreateTexture2D(&td, NULL, texture.Assign());
 	if (FAILED(hr))
-		throw HRError("Failed to create 2D texture", hr);
+		throw HRError("Failed to create staging surface", hr);
 }
diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp
index 08a7337..8760a9d 100644
--- a/libobs-d3d11/d3d11-subsystem.cpp
+++ b/libobs-d3d11/d3d11-subsystem.cpp
@@ -33,9 +33,39 @@ struct UnsupportedHWError : HRError {
 #pragma warning (disable : 4316)
 #endif
 
+static inline void LogD3D11ErrorDetails(HRError error, gs_device_t *device)
+{
+	if (error.hr == DXGI_ERROR_DEVICE_REMOVED) {
+		HRESULT DeviceRemovedReason =
+				device->device->GetDeviceRemovedReason();
+		blog(LOG_ERROR, "  Device Removed Reason: %08lX",
+				DeviceRemovedReason);
+	}
+}
+
 static const IID dxgiFactory2 =
 {0x50c83a1c, 0xe072, 0x4c48, {0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0}};
 
+
+gs_obj::gs_obj(gs_device_t *device_, gs_type type) :
+	device    (device_),
+	obj_type  (type)
+{
+	prev_next = &device->first_obj;
+	next = device->first_obj;
+	device->first_obj = this;
+	if (next)
+		next->prev_next = &next;
+}
+
+gs_obj::~gs_obj()
+{
+	if (prev_next)
+		*prev_next = next;
+	if (next)
+		next->prev_next = prev_next;
+}
+
 static inline void make_swap_desc(DXGI_SWAP_CHAIN_DESC &desc,
 		const gs_init_data *data)
 {
@@ -91,6 +121,9 @@ void gs_swap_chain::Resize(uint32_t cx, uint32_t cy)
 	zs.texture.Clear();
 	zs.view.Clear();
 
+	initData.cx = cx;
+	initData.cy = cy;
+
 	if (cx == 0 || cy == 0) {
 		GetClientRect(hwnd, &clientRect);
 		if (cx == 0) cx = clientRect.right;
@@ -105,27 +138,27 @@ void gs_swap_chain::Resize(uint32_t cx, uint32_t cy)
 	InitZStencilBuffer(cx, cy);
 }
 
-void gs_swap_chain::Init(const gs_init_data *data)
+void gs_swap_chain::Init()
 {
 	target.device         = device;
 	target.isRenderTarget = true;
-	target.format         = data->format;
-	target.dxgiFormat     = ConvertGSTextureFormat(data->format);
-	InitTarget(data->cx, data->cy);
+	target.format         = initData.format;
+	target.dxgiFormat     = ConvertGSTextureFormat(initData.format);
+	InitTarget(initData.cx, initData.cy);
 
 	zs.device     = device;
-	zs.format     = data->zsformat;
-	zs.dxgiFormat = ConvertGSZStencilFormat(data->zsformat);
-	InitZStencilBuffer(data->cx, data->cy);
+	zs.format     = initData.zsformat;
+	zs.dxgiFormat = ConvertGSZStencilFormat(initData.zsformat);
+	InitZStencilBuffer(initData.cx, initData.cy);
 }
 
 gs_swap_chain::gs_swap_chain(gs_device *device, const gs_init_data *data)
-	: device     (device),
+	: gs_obj     (device, gs_type::gs_swap_chain),
 	  numBuffers (data->num_backbuffers),
-	  hwnd       ((HWND)data->window.hwnd)
+	  hwnd       ((HWND)data->window.hwnd),
+	  initData   (*data)
 {
 	HRESULT hr;
-	DXGI_SWAP_CHAIN_DESC swapDesc;
 
 	make_swap_desc(swapDesc, data);
 	hr = device->factory->CreateSwapChain(device->device, &swapDesc,
@@ -133,7 +166,7 @@ gs_swap_chain::gs_swap_chain(gs_device *device, const gs_init_data *data)
 	if (FAILED(hr))
 		throw HRError("Failed to create swap chain", hr);
 
-	Init(data);
+	Init();
 }
 
 void gs_device::InitCompiler()
@@ -148,6 +181,11 @@ void gs_device::InitCompiler()
 		if (module) {
 			d3dCompile = (pD3DCompile)GetProcAddress(module,
 					"D3DCompile");
+
+#ifdef DISASSEMBLE_SHADERS
+			d3dDisassemble = (pD3DDisassemble)GetProcAddress(
+					module, "D3DDisassemble");
+#endif
 			if (d3dCompile) {
 				return;
 			}
@@ -161,7 +199,7 @@ void gs_device::InitCompiler()
 	throw "Could not find any D3DCompiler libraries";
 }
 
-void gs_device::InitFactory(uint32_t adapterIdx, IDXGIAdapter1 **padapter)
+void gs_device::InitFactory(uint32_t adapterIdx)
 {
 	HRESULT hr;
 	IID factoryIID = (GetWinVer() >= 0x602) ? dxgiFactory2 :
@@ -171,7 +209,7 @@ void gs_device::InitFactory(uint32_t adapterIdx, IDXGIAdapter1 **padapter)
 	if (FAILED(hr))
 		throw UnsupportedHWError("Failed to create DXGIFactory", hr);
 
-	hr = factory->EnumAdapters1(adapterIdx, padapter);
+	hr = factory->EnumAdapters1(adapterIdx, &adapter);
 	if (FAILED(hr))
 		throw UnsupportedHWError("Failed to enumerate DXGIAdapter", hr);
 }
@@ -184,13 +222,15 @@ const static D3D_FEATURE_LEVEL featureLevels[] =
 	D3D_FEATURE_LEVEL_9_3,
 };
 
-void gs_device::InitDevice(uint32_t adapterIdx, IDXGIAdapter *adapter)
+void gs_device::InitDevice(uint32_t adapterIdx)
 {
 	wstring adapterName;
 	DXGI_ADAPTER_DESC desc;
 	D3D_FEATURE_LEVEL levelUsed = D3D_FEATURE_LEVEL_9_3;
 	HRESULT hr = 0;
 
+	adpIdx = adapterIdx;
+
 	uint32_t createFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
 #ifdef _DEBUG
 	//createFlags |= D3D11_CREATE_DEVICE_DEBUG;
@@ -230,7 +270,6 @@ ID3D11DepthStencilState *gs_device::AddZStencilState()
 {
 	HRESULT hr;
 	D3D11_DEPTH_STENCIL_DESC dsd;
-	SavedZStencilState savedState(zstencilState);
 	ID3D11DepthStencilState *state;
 
 	dsd.DepthEnable      = zstencilState.depthEnabled;
@@ -244,6 +283,7 @@ ID3D11DepthStencilState *gs_device::AddZStencilState()
 	ConvertStencilSide(dsd.FrontFace, zstencilState.stencilFront);
 	ConvertStencilSide(dsd.BackFace,  zstencilState.stencilBack);
 
+	SavedZStencilState savedState(zstencilState, dsd);
 	hr = device->CreateDepthStencilState(&dsd, savedState.state.Assign());
 	if (FAILED(hr))
 		throw HRError("Failed to create depth stencil state", hr);
@@ -258,7 +298,6 @@ ID3D11RasterizerState *gs_device::AddRasterState()
 {
 	HRESULT hr;
 	D3D11_RASTERIZER_DESC rd;
-	SavedRasterState savedState(rasterState);
 	ID3D11RasterizerState *state;
 
 	memset(&rd, 0, sizeof(rd));
@@ -269,6 +308,7 @@ ID3D11RasterizerState *gs_device::AddRasterState()
 	rd.DepthClipEnable       = true;
 	rd.ScissorEnable         = rasterState.scissorEnabled;
 
+	SavedRasterState savedState(rasterState, rd);
 	hr = device->CreateRasterizerState(&rd, savedState.state.Assign());
 	if (FAILED(hr))
 		throw HRError("Failed to create rasterizer state", hr);
@@ -283,7 +323,6 @@ ID3D11BlendState *gs_device::AddBlendState()
 {
 	HRESULT hr;
 	D3D11_BLEND_DESC bd;
-	SavedBlendState savedState(blendState);
 	ID3D11BlendState *state;
 
 	memset(&bd, 0, sizeof(bd));
@@ -303,9 +342,10 @@ ID3D11BlendState *gs_device::AddBlendState()
 			D3D11_COLOR_WRITE_ENABLE_ALL;
 	}
 
+	SavedBlendState savedState(blendState, bd);
 	hr = device->CreateBlendState(&bd, savedState.state.Assign());
 	if (FAILED(hr))
-		throw HRError("Failed to create disabled blend state", hr);
+		throw HRError("Failed to create blend state", hr);
 
 	state = savedState.state;
 	blendStates.push_back(savedState);
@@ -413,8 +453,6 @@ void gs_device::UpdateViewProjMatrix()
 gs_device::gs_device(uint32_t adapterIdx)
 	: curToplogy           (D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED)
 {
-	ComPtr<IDXGIAdapter1> adapter;
-
 	matrix4_identity(&curProjMatrix);
 	matrix4_identity(&curViewMatrix);
 	matrix4_identity(&curViewProjMatrix);
@@ -427,11 +465,16 @@ gs_device::gs_device(uint32_t adapterIdx)
 	}
 
 	InitCompiler();
-	InitFactory(adapterIdx, adapter.Assign());
-	InitDevice(adapterIdx, adapter);
+	InitFactory(adapterIdx);
+	InitDevice(adapterIdx);
 	device_set_render_target(this, NULL, NULL);
 }
 
+gs_device::~gs_device()
+{
+	context->ClearState();
+}
+
 const char *device_get_name(void)
 {
 	return "Direct3D 11";
@@ -612,6 +655,7 @@ gs_swapchain_t *device_swapchain_create(gs_device_t *device,
 	} catch (HRError error) {
 		blog(LOG_ERROR, "device_swapchain_create (D3D11): %s (%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 	}
 
 	return swap;
@@ -641,6 +685,7 @@ void device_resize(gs_device_t *device, uint32_t cx, uint32_t cy)
 	} catch (HRError error) {
 		blog(LOG_ERROR, "device_resize (D3D11): %s (%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 	}
 }
 
@@ -688,6 +733,7 @@ gs_texture_t *device_texture_create(gs_device_t *device, uint32_t width,
 	} catch (HRError error) {
 		blog(LOG_ERROR, "device_texture_create (D3D11): %s (%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 	} catch (const char *error) {
 		blog(LOG_ERROR, "device_texture_create (D3D11): %s", error);
 	}
@@ -708,6 +754,7 @@ gs_texture_t *device_cubetexture_create(gs_device_t *device, uint32_t size,
 		blog(LOG_ERROR, "device_cubetexture_create (D3D11): %s "
 		                "(%08lX)",
 		                error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 	} catch (const char *error) {
 		blog(LOG_ERROR, "device_cubetexture_create (D3D11): %s",
 				error);
@@ -743,6 +790,7 @@ gs_zstencil_t *device_zstencil_create(gs_device_t *device, uint32_t width,
 	} catch (HRError error) {
 		blog(LOG_ERROR, "device_zstencil_create (D3D11): %s (%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 	}
 
 	return zstencil;
@@ -759,6 +807,7 @@ gs_stagesurf_t *device_stagesurface_create(gs_device_t *device, uint32_t width,
 		blog(LOG_ERROR, "device_stagesurface_create (D3D11): %s "
 		                "(%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 	}
 
 	return surf;
@@ -774,6 +823,7 @@ gs_samplerstate_t *device_samplerstate_create(gs_device_t *device,
 		blog(LOG_ERROR, "device_samplerstate_create (D3D11): %s "
 		                "(%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 	}
 
 	return ss;
@@ -791,6 +841,7 @@ gs_shader_t *device_vertexshader_create(gs_device_t *device,
 		blog(LOG_ERROR, "device_vertexshader_create (D3D11): %s "
 		                "(%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 
 	} catch (ShaderError error) {
 		const char *buf = (const char*)error.errors->GetBufferPointer();
@@ -820,6 +871,7 @@ gs_shader_t *device_pixelshader_create(gs_device_t *device,
 		blog(LOG_ERROR, "device_pixelshader_create (D3D11): %s "
 		                "(%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 
 	} catch (ShaderError error) {
 		const char *buf = (const char*)error.errors->GetBufferPointer();
@@ -847,6 +899,7 @@ gs_vertbuffer_t *device_vertexbuffer_create(gs_device_t *device,
 		blog(LOG_ERROR, "device_vertexbuffer_create (D3D11): %s "
 		                "(%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 	} catch (const char *error) {
 		blog(LOG_ERROR, "device_vertexbuffer_create (D3D11): %s",
 				error);
@@ -865,6 +918,7 @@ gs_indexbuffer_t *device_indexbuffer_create(gs_device_t *device,
 	} catch (HRError error) {
 		blog(LOG_ERROR, "device_indexbuffer_create (D3D11): %s (%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 	}
 
 	return buffer;
@@ -1308,6 +1362,7 @@ void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode,
 	} catch (HRError error) {
 		blog(LOG_ERROR, "device_draw (D3D11): %s (%08lX)", error.str,
 				error.hr);
+		LogD3D11ErrorDetails(error, device);
 		return;
 	}
 
@@ -1382,8 +1437,14 @@ void device_clear(gs_device_t *device, uint32_t clear_flags,
 
 void device_present(gs_device_t *device)
 {
+	HRESULT hr;
+
 	if (device->curSwapChain) {
-		device->curSwapChain->swap->Present(0, 0);
+		hr = device->curSwapChain->swap->Present(0, 0);
+		if (hr == DXGI_ERROR_DEVICE_REMOVED ||
+		    hr == DXGI_ERROR_DEVICE_RESET) {
+			device->RebuildDevice();
+		}
 	} else {
 		blog(LOG_WARNING, "device_present (D3D11): No active swap");
 	}
@@ -1964,6 +2025,7 @@ extern "C" EXPORT gs_texture_t *device_texture_create_gdi(gs_device_t *device,
 	} catch (HRError error) {
 		blog(LOG_ERROR, "device_texture_create_gdi (D3D11): %s (%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 	} catch (const char *error) {
 		blog(LOG_ERROR, "device_texture_create_gdi (D3D11): %s", error);
 	}
@@ -1993,6 +2055,9 @@ extern "C" EXPORT void *gs_texture_get_dc(gs_texture_t *tex)
 	if (!TextureGDICompatible(tex2d, "gs_texture_get_dc"))
 		return nullptr;
 
+	if (!tex2d->gdiSurface)
+		return nullptr;
+
 	tex2d->gdiSurface->GetDC(true, &hDC);
 	return hDC;
 }
@@ -2018,6 +2083,7 @@ extern "C" EXPORT gs_texture_t *device_texture_open_shared(gs_device_t *device,
 	} catch (HRError error) {
 		blog(LOG_ERROR, "gs_texture_open_shared (D3D11): %s (%08lX)",
 				error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
 	} catch (const char *error) {
 		blog(LOG_ERROR, "gs_texture_open_shared (D3D11): %s", error);
 	}
diff --git a/libobs-d3d11/d3d11-subsystem.hpp b/libobs-d3d11/d3d11-subsystem.hpp
index d413508..1cec188 100644
--- a/libobs-d3d11/d3d11-subsystem.hpp
+++ b/libobs-d3d11/d3d11-subsystem.hpp
@@ -22,6 +22,7 @@
 
 #include <vector>
 #include <string>
+#include <memory>
 
 #include <windows.h>
 #include <dxgi.h>
@@ -36,6 +37,8 @@
 #include <util/windows/ComPtr.hpp>
 #include <util/windows/HRError.hpp>
 
+// #define DISASSEMBLE_SHADERS
+
 struct shader_var;
 struct shader_sampler;
 struct gs_vertex_shader;
@@ -197,20 +200,46 @@ static inline D3D11_PRIMITIVE_TOPOLOGY ConvertGSTopology(gs_draw_mode mode)
 struct VBDataPtr {
 	gs_vb_data *data;
 
-	inline void Clear() {gs_vbdata_destroy(data); data = nullptr;}
-
 	inline VBDataPtr(gs_vb_data *data) : data(data) {}
 	inline ~VBDataPtr() {gs_vbdata_destroy(data);}
 };
 
-struct gs_vertex_buffer {
+enum class gs_type {
+	gs_vertex_buffer,
+	gs_index_buffer,
+	gs_texture_2d,
+	gs_zstencil_buffer,
+	gs_stage_surface,
+	gs_sampler_state,
+	gs_vertex_shader,
+	gs_pixel_shader,
+	gs_duplicator,
+	gs_swap_chain,
+};
+
+struct gs_obj {
+	gs_device_t *device;
+	gs_type obj_type;
+	gs_obj *next;
+	gs_obj **prev_next;
+
+	inline gs_obj() :
+		device(nullptr),
+		next(nullptr),
+		prev_next(nullptr)
+	{}
+
+	gs_obj(gs_device_t *device, gs_type type);
+	virtual ~gs_obj();
+};
+
+struct gs_vertex_buffer : gs_obj {
 	ComPtr<ID3D11Buffer>         vertexBuffer;
 	ComPtr<ID3D11Buffer>         normalBuffer;
 	ComPtr<ID3D11Buffer>         colorBuffer;
 	ComPtr<ID3D11Buffer>         tangentBuffer;
 	vector<ComPtr<ID3D11Buffer>> uvBuffers;
 
-	gs_device_t    *device;
 	bool           dynamic;
 	VBDataPtr      vbd;
 	size_t         numVerts;
@@ -223,10 +252,23 @@ struct gs_vertex_buffer {
 			vector<ID3D11Buffer*> &buffers,
 			vector<uint32_t> &strides);
 
-	inline void InitBuffer(const size_t elementSize,
+	void InitBuffer(const size_t elementSize,
 			const size_t numVerts, void *array,
 			ID3D11Buffer **buffer);
 
+	void BuildBuffers();
+
+	inline void Release()
+	{
+		vertexBuffer.Release();
+		normalBuffer.Release();
+		colorBuffer.Release();
+		tangentBuffer.Release();
+		uvBuffers.clear();
+	}
+
+	inline void Rebuild();
+
 	gs_vertex_buffer(gs_device_t *device, struct gs_vb_data *data,
 			uint32_t flags);
 };
@@ -239,41 +281,61 @@ struct DataPtr {
 	inline ~DataPtr() {bfree(data);}
 };
 
-struct gs_index_buffer {
+struct gs_index_buffer : gs_obj {
 	ComPtr<ID3D11Buffer> indexBuffer;
-	gs_device_t          *device;
 	bool                 dynamic;
 	gs_index_type        type;
 	size_t               indexSize;
 	size_t               num;
 	DataPtr              indices;
 
+	D3D11_BUFFER_DESC bd = {};
+	D3D11_SUBRESOURCE_DATA srd = {};
+
 	void InitBuffer();
 
+	inline void Rebuild(ID3D11Device *dev);
+
+	inline void Release() {indexBuffer.Release();}
+
 	gs_index_buffer(gs_device_t *device, enum gs_index_type type,
 			void *indices, size_t num, uint32_t flags);
 };
 
-struct gs_texture {
+struct gs_texture : gs_obj {
 	gs_texture_type type;
-	gs_device       *device;
 	uint32_t        levels;
 	gs_color_format format;
 
 	ComPtr<ID3D11ShaderResourceView> shaderRes;
+	D3D11_SHADER_RESOURCE_VIEW_DESC resourceDesc = {};
 
-	inline gs_texture() {}
+	inline void Rebuild(ID3D11Device *dev);
 
-	inline gs_texture(gs_device *device, gs_texture_type type,
-			uint32_t levels, gs_color_format format)
+	inline gs_texture(gs_texture_type type, uint32_t levels,
+			gs_color_format format)
 		: type   (type),
-		  device (device),
 		  levels (levels),
 		  format (format)
 	{
 	}
 
-	virtual ~gs_texture() {}
+	inline gs_texture(gs_device *device, gs_type obj_type,
+			gs_texture_type type)
+		: gs_obj (device, obj_type),
+		  type   (type)
+	{
+	}
+
+	inline gs_texture(gs_device *device, gs_type obj_type,
+			gs_texture_type type,
+			uint32_t levels, gs_color_format format)
+		: gs_obj (device, obj_type),
+		  type   (type),
+		  levels (levels),
+		  format (format)
+	{
+	}
 };
 
 struct gs_texture_2d : gs_texture {
@@ -290,13 +352,30 @@ struct gs_texture_2d : gs_texture {
 	bool            genMipmaps = false;
 	uint32_t        sharedHandle = 0;
 
-	void InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd, const uint8_t **data);
+	vector<vector<uint8_t>> data;
+	vector<D3D11_SUBRESOURCE_DATA> srd;
+	D3D11_TEXTURE2D_DESC td = {};
+
+	void InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd);
 	void InitTexture(const uint8_t **data);
 	void InitResourceView();
 	void InitRenderTargets();
+	void BackupTexture(const uint8_t **data);
+
+	void RebuildSharedTextureFallback();
+	inline void Rebuild(ID3D11Device *dev);
+
+	inline void Release()
+	{
+		texture.Release();
+		for (auto &rt : renderTarget)
+			rt.Release();
+		gdiSurface.Release();
+		shaderRes.Release();
+	}
 
 	inline gs_texture_2d()
-		: gs_texture (NULL, GS_TEXTURE_2D, 0, GS_UNKNOWN)
+		: gs_texture (GS_TEXTURE_2D, 0, GS_UNKNOWN)
 	{
 	}
 
@@ -308,20 +387,29 @@ struct gs_texture_2d : gs_texture {
 	gs_texture_2d(gs_device_t *device, uint32_t handle);
 };
 
-struct gs_zstencil_buffer {
+struct gs_zstencil_buffer : gs_obj {
 	ComPtr<ID3D11Texture2D>        texture;
 	ComPtr<ID3D11DepthStencilView> view;
 
-	gs_device          *device;
 	uint32_t           width, height;
 	gs_zstencil_format format;
 	DXGI_FORMAT        dxgiFormat;
 
+	D3D11_TEXTURE2D_DESC td = {};
+	D3D11_DEPTH_STENCIL_VIEW_DESC dsvd = {};
+
 	void InitBuffer();
 
+	inline void Rebuild(ID3D11Device *dev);
+
+	inline void Release()
+	{
+		texture.Release();
+		view.Release();
+	}
+
 	inline gs_zstencil_buffer()
-		: device     (NULL),
-		  width      (0),
+		: width      (0),
 		  height     (0),
 		  dxgiFormat (DXGI_FORMAT_UNKNOWN)
 	{
@@ -331,23 +419,34 @@ struct gs_zstencil_buffer {
 			gs_zstencil_format format);
 };
 
-struct gs_stage_surface {
+struct gs_stage_surface : gs_obj {
 	ComPtr<ID3D11Texture2D> texture;
+	D3D11_TEXTURE2D_DESC td = {};
 
-	gs_device       *device;
 	uint32_t        width, height;
 	gs_color_format format;
 	DXGI_FORMAT     dxgiFormat;
 
+	inline void Rebuild(ID3D11Device *dev);
+
+	inline void Release()
+	{
+		texture.Release();
+	}
+
 	gs_stage_surface(gs_device_t *device, uint32_t width, uint32_t height,
 			gs_color_format colorFormat);
 };
 
-struct gs_sampler_state {
+struct gs_sampler_state : gs_obj {
 	ComPtr<ID3D11SamplerState> state;
-	gs_device_t                *device;
+	D3D11_SAMPLER_DESC         sd = {};
 	gs_sampler_info            info;
 
+	inline void Rebuild(ID3D11Device *dev);
+
+	inline void Release() {state.Release();}
+
 	gs_sampler_state(gs_device_t *device, const gs_sampler_info *info);
 };
 
@@ -380,13 +479,15 @@ struct ShaderError {
 	}
 };
 
-struct gs_shader {
-	gs_device_t             *device;
+struct gs_shader : gs_obj {
 	gs_shader_type          type;
 	vector<gs_shader_param> params;
 	ComPtr<ID3D11Buffer>    constants;
 	size_t                  constantSize;
 
+	D3D11_BUFFER_DESC       bd = {};
+	vector<uint8_t>         data;
+
 	inline void UpdateParam(vector<uint8_t> &constData,
 			gs_shader_param &param, bool &upload);
 	void UploadParams();
@@ -395,8 +496,9 @@ struct gs_shader {
 	void Compile(const char *shaderStr, const char *file,
 			const char *target, ID3D10Blob **shader);
 
-	inline gs_shader(gs_device_t *device, gs_shader_type type)
-		: device       (device),
+	inline gs_shader(gs_device_t *device, gs_type obj_type,
+			gs_shader_type type)
+		: gs_obj       (device, obj_type),
 		  type         (type),
 		  constantSize (0)
 	{
@@ -423,11 +525,22 @@ struct gs_vertex_shader : gs_shader {
 
 	gs_shader_param *world, *viewProj;
 
+	vector<D3D11_INPUT_ELEMENT_DESC> layoutData;
+
 	bool     hasNormals;
 	bool     hasColors;
 	bool     hasTangents;
 	uint32_t nTexUnits;
 
+	inline void Rebuild(ID3D11Device *dev);
+
+	inline void Release()
+	{
+		shader.Release();
+		layout.Release();
+		constants.Release();
+	}
+
 	inline uint32_t NumBuffersExpected() const
 	{
 		uint32_t count = nTexUnits+1;
@@ -444,10 +557,17 @@ struct gs_vertex_shader : gs_shader {
 			const char *shaderString);
 };
 
-struct gs_duplicator {
+struct gs_duplicator : gs_obj {
 	ComPtr<IDXGIOutputDuplication> duplicator;
 	gs_texture_2d *texture;
-	gs_device_t *device;
+	int idx;
+
+	void Start();
+
+	inline void Release()
+	{
+		duplicator.Release();
+	}
 
 	gs_duplicator(gs_device_t *device, int monitor_idx);
 	~gs_duplicator();
@@ -455,13 +575,21 @@ struct gs_duplicator {
 
 struct gs_pixel_shader : gs_shader {
 	ComPtr<ID3D11PixelShader> shader;
-	vector<ShaderSampler>     samplers;
+	vector<unique_ptr<ShaderSampler>> samplers;
+
+	inline void Rebuild(ID3D11Device *dev);
+
+	inline void Release()
+	{
+		shader.Release();
+		constants.Release();
+	}
 
 	inline void GetSamplerStates(ID3D11SamplerState **states)
 	{
 		size_t i;
 		for (i = 0; i < samplers.size(); i++)
-			states[i] = samplers[i].sampler.state;
+			states[i] = samplers[i]->sampler.state;
 		for (; i < GS_MAX_TEXTURES; i++)
 			states[i] = NULL;
 	}
@@ -470,10 +598,11 @@ struct gs_pixel_shader : gs_shader {
 			const char *shaderString);
 };
 
-struct gs_swap_chain {
-	gs_device                      *device;
+struct gs_swap_chain : gs_obj {
 	uint32_t                       numBuffers;
 	HWND                           hwnd;
+	gs_init_data                   initData;
+	DXGI_SWAP_CHAIN_DESC           swapDesc = {};
 
 	gs_texture_2d                  target;
 	gs_zstencil_buffer             zs;
@@ -482,13 +611,15 @@ struct gs_swap_chain {
 	void InitTarget(uint32_t cx, uint32_t cy);
 	void InitZStencilBuffer(uint32_t cx, uint32_t cy);
 	void Resize(uint32_t cx, uint32_t cy);
-	void Init(const gs_init_data *data);
+	void Init();
+
+	inline void Rebuild(ID3D11Device *dev);
 
-	inline gs_swap_chain()
-		: device     (NULL),
-		  numBuffers (0),
-		  hwnd       (NULL)
+	inline void Release()
 	{
+		target.Release();
+		zs.Release();
+		swap.Release();
 	}
 
 	gs_swap_chain(gs_device *device, const gs_init_data *data);
@@ -527,8 +658,17 @@ struct BlendState {
 
 struct SavedBlendState : BlendState {
 	ComPtr<ID3D11BlendState> state;
+	D3D11_BLEND_DESC         bd;
 
-	inline SavedBlendState(const BlendState &val) : BlendState(val)
+	inline void Rebuild(ID3D11Device *dev);
+
+	inline void Release()
+	{
+		state.Release();
+	}
+
+	inline SavedBlendState(const BlendState &val, D3D11_BLEND_DESC &desc)
+		: BlendState(val), bd(desc)
 	{
 	}
 };
@@ -575,9 +715,19 @@ struct ZStencilState {
 
 struct SavedZStencilState : ZStencilState {
 	ComPtr<ID3D11DepthStencilState> state;
+	D3D11_DEPTH_STENCIL_DESC        dsd;
 
-	inline SavedZStencilState(const ZStencilState &val)
-		: ZStencilState (val)
+	inline void Rebuild(ID3D11Device *dev);
+
+	inline void Release()
+	{
+		state.Release();
+	}
+
+	inline SavedZStencilState(const ZStencilState &val,
+			D3D11_DEPTH_STENCIL_DESC desc)
+		: ZStencilState (val),
+		  dsd           (desc)
 	{
 	}
 };
@@ -600,9 +750,19 @@ struct RasterState {
 
 struct SavedRasterState : RasterState {
 	ComPtr<ID3D11RasterizerState> state;
+	D3D11_RASTERIZER_DESC         rd;
+
+	inline void Rebuild(ID3D11Device *dev);
+
+	inline void Release()
+	{
+		state.Release();
+	}
 
-	inline SavedRasterState(const RasterState &val)
-	       : RasterState (val)
+	inline SavedRasterState(const RasterState &val,
+			D3D11_RASTERIZER_DESC &desc)
+	       : RasterState (val),
+	         rd          (desc)
 	{
 	}
 };
@@ -613,8 +773,10 @@ struct mat4float {
 
 struct gs_device {
 	ComPtr<IDXGIFactory1>       factory;
+	ComPtr<IDXGIAdapter1>       adapter;
 	ComPtr<ID3D11Device>        device;
 	ComPtr<ID3D11DeviceContext> context;
+	uint32_t                    adpIdx = 0;
 
 	gs_texture_2d               *curRenderTarget = nullptr;
 	gs_zstencil_buffer          *curZStencilBuffer = nullptr;
@@ -642,6 +804,9 @@ struct gs_device {
 	D3D11_PRIMITIVE_TOPOLOGY    curToplogy;
 
 	pD3DCompile                 d3dCompile = nullptr;
+#ifdef DISASSEMBLE_SHADERS
+	pD3DDisassemble             d3dDisassemble = nullptr;
+#endif
 
 	gs_rect                     viewport;
 
@@ -651,9 +816,11 @@ struct gs_device {
 	matrix4                     curViewMatrix;
 	matrix4                     curViewProjMatrix;
 
+	gs_obj                      *first_obj = nullptr;
+
 	void InitCompiler();
-	void InitFactory(uint32_t adapterIdx, IDXGIAdapter1 **adapter);
-	void InitDevice(uint32_t adapterIdx, IDXGIAdapter *adapter);
+	void InitFactory(uint32_t adapterIdx);
+	void InitDevice(uint32_t adapterIdx);
 
 	ID3D11DepthStencilState *AddZStencilState();
 	ID3D11RasterizerState   *AddRasterState();
@@ -669,5 +836,8 @@ struct gs_device {
 
 	void UpdateViewProjMatrix();
 
+	void RebuildDevice();
+
 	gs_device(uint32_t adapterIdx);
+	~gs_device();
 };
diff --git a/libobs-d3d11/d3d11-texture2d.cpp b/libobs-d3d11/d3d11-texture2d.cpp
index 7e151af..9855466 100644
--- a/libobs-d3d11/d3d11-texture2d.cpp
+++ b/libobs-d3d11/d3d11-texture2d.cpp
@@ -18,13 +18,13 @@
 #include <util/base.h>
 #include "d3d11-subsystem.hpp"
 
-void gs_texture_2d::InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd,
-		const uint8_t **data)
+void gs_texture_2d::InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd)
 {
 	uint32_t rowSizeBytes  = width  * gs_get_format_bpp(format);
 	uint32_t texSizeBytes  = height * rowSizeBytes / 8;
 	size_t   textures      = type == GS_TEXTURE_2D ? 1 : 6;
 	uint32_t actual_levels = levels;
+	size_t   curTex = 0;
 
 	if (!actual_levels)
 		actual_levels = gs_get_total_levels(width, height);
@@ -37,22 +37,42 @@ void gs_texture_2d::InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd,
 
 		for (uint32_t j = 0; j < actual_levels; j++) {
 			D3D11_SUBRESOURCE_DATA newSRD;
-			newSRD.pSysMem          = *data;
+			newSRD.pSysMem          = data[curTex++].data();
 			newSRD.SysMemPitch      = newRowSize;
 			newSRD.SysMemSlicePitch = newTexSize;
 			srd.push_back(newSRD);
 
 			newRowSize /= 2;
 			newTexSize /= 4;
-			data++;
 		}
 	}
 }
 
+void gs_texture_2d::BackupTexture(const uint8_t **data)
+{
+	this->data.resize(levels);
+
+	uint32_t w = width;
+	uint32_t h = height;
+	uint32_t bbp = gs_get_format_bpp(format);
+
+	for (uint32_t i = 0; i < levels; i++) {
+		if (!data[i])
+			break;
+
+		uint32_t texSize = bbp * w * h / 8;
+		this->data[i].resize(texSize);
+
+		vector<uint8_t> &subData = this->data[i];
+		memcpy(&subData[0], data[i], texSize);
+
+		w /= 2;
+		h /= 2;
+	}
+}
+
 void gs_texture_2d::InitTexture(const uint8_t **data)
 {
-	vector<D3D11_SUBRESOURCE_DATA> srd;
-	D3D11_TEXTURE2D_DESC td;
 	HRESULT hr;
 
 	memset(&td, 0, sizeof(td));
@@ -76,8 +96,10 @@ void gs_texture_2d::InitTexture(const uint8_t **data)
 	if (isGDICompatible)
 		td.MiscFlags |= D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
 
-	if (data)
-		InitSRD(srd, data);
+	if (data) {
+		BackupTexture(data);
+		InitSRD(srd);
+	}
 
 	hr = device->device->CreateTexture2D(&td, data ? srd.data() : NULL,
 			texture.Assign());
@@ -94,7 +116,6 @@ void gs_texture_2d::InitTexture(const uint8_t **data)
 
 void gs_texture_2d::InitResourceView()
 {
-	D3D11_SHADER_RESOURCE_VIEW_DESC resourceDesc;
 	HRESULT hr;
 
 	memset(&resourceDesc, 0, sizeof(resourceDesc));
@@ -145,7 +166,8 @@ gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t width,
 		uint32_t height, gs_color_format colorFormat, uint32_t levels,
 		const uint8_t **data, uint32_t flags, gs_texture_type type,
 		bool gdiCompatible, bool shared)
-	: gs_texture      (device, type, levels, colorFormat),
+	: gs_texture      (device, gs_type::gs_texture_2d, type, levels,
+	                   colorFormat),
 	  width           (width),
 	  height          (height),
 	  dxgiFormat      (ConvertGSTextureFormat(format)),
@@ -163,29 +185,30 @@ gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t width,
 }
 
 gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t handle)
-	: isShared        (true),
+	: gs_texture      (device, gs_type::gs_texture_2d,
+	                   GS_TEXTURE_2D),
+	  isShared        (true),
 	  sharedHandle    (handle)
 {
 	HRESULT hr;
 	hr = device->device->OpenSharedResource((HANDLE)(uintptr_t)handle,
 			__uuidof(ID3D11Texture2D), (void**)texture.Assign());
 	if (FAILED(hr))
-		throw HRError("Failed to open resource", hr);
+		throw HRError("Failed to open shared 2D texture", hr);
 
-	D3D11_TEXTURE2D_DESC desc;
-	texture->GetDesc(&desc);
+	texture->GetDesc(&td);
 
 	this->type       = GS_TEXTURE_2D;
-	this->format     = ConvertDXGITextureFormat(desc.Format);
+	this->format     = ConvertDXGITextureFormat(td.Format);
 	this->levels     = 1;
 	this->device     = device;
 
-	this->width      = desc.Width;
-	this->height     = desc.Height;
-	this->dxgiFormat = desc.Format;
+	this->width      = td.Width;
+	this->height     = td.Height;
+	this->dxgiFormat = td.Format;
 
-	D3D11_SHADER_RESOURCE_VIEW_DESC resourceDesc = {};
-	resourceDesc.Format              = desc.Format;
+	memset(&resourceDesc, 0, sizeof(resourceDesc));
+	resourceDesc.Format              = td.Format;
 	resourceDesc.ViewDimension       = D3D11_SRV_DIMENSION_TEXTURE2D;
 	resourceDesc.Texture2D.MipLevels = 1;
 
diff --git a/libobs-d3d11/d3d11-vertexbuffer.cpp b/libobs-d3d11/d3d11-vertexbuffer.cpp
index 4d15a88..580aad6 100644
--- a/libobs-d3d11/d3d11-vertexbuffer.cpp
+++ b/libobs-d3d11/d3d11-vertexbuffer.cpp
@@ -72,7 +72,7 @@ void gs_vertex_buffer::MakeBufferList(gs_vertex_shader *shader,
 	}
 }
 
-inline void gs_vertex_buffer::InitBuffer(const size_t elementSize,
+void gs_vertex_buffer::InitBuffer(const size_t elementSize,
 		const size_t numVerts, void *array, ID3D11Buffer **buffer)
 {
 	D3D11_BUFFER_DESC bd;
@@ -93,35 +93,25 @@ inline void gs_vertex_buffer::InitBuffer(const size_t elementSize,
 		throw HRError("Failed to create buffer", hr);
 }
 
-gs_vertex_buffer::gs_vertex_buffer(gs_device_t *device, struct gs_vb_data *data,
-		uint32_t flags)
-	: device   (device),
-	  dynamic  ((flags & GS_DYNAMIC) != 0),
-	  vbd      (data),
-	  numVerts (data->num)
+void gs_vertex_buffer::BuildBuffers()
 {
-	if (!data->num)
-		throw "Cannot initialize vertex buffer with 0 vertices";
-	if (!data->points)
-		throw "No points specified for vertex buffer";
+	InitBuffer(sizeof(vec3), vbd.data->num, vbd.data->points,
+			&vertexBuffer);
 
-	InitBuffer(sizeof(vec3), data->num, data->points,
-			vertexBuffer.Assign());
+	if (vbd.data->normals)
+		InitBuffer(sizeof(vec3), vbd.data->num, vbd.data->normals,
+				&normalBuffer);
 
-	if (data->normals)
-		InitBuffer(sizeof(vec3), data->num, data->normals,
-				normalBuffer.Assign());
+	if (vbd.data->tangents)
+		InitBuffer(sizeof(vec3), vbd.data->num, vbd.data->tangents,
+				&tangentBuffer);
 
-	if (data->tangents)
-		InitBuffer(sizeof(vec3), data->num, data->tangents,
-				tangentBuffer.Assign());
+	if (vbd.data->colors)
+		InitBuffer(sizeof(uint32_t), vbd.data->num, vbd.data->colors,
+				&colorBuffer);
 
-	if (data->colors)
-		InitBuffer(sizeof(uint32_t), data->num, data->colors,
-				colorBuffer.Assign());
-
-	for (size_t i = 0; i < data->num_tex; i++) {
-		struct gs_tvertarray *tverts = data->tvarray+i;
+	for (size_t i = 0; i < vbd.data->num_tex; i++) {
+		struct gs_tvertarray *tverts = vbd.data->tvarray+i;
 
 		if (tverts->width != 2 && tverts->width != 4)
 			throw "Invalid texture vertex size specified";
@@ -129,13 +119,25 @@ gs_vertex_buffer::gs_vertex_buffer(gs_device_t *device, struct gs_vb_data *data,
 			throw "No texture vertices specified";
 
 		ComPtr<ID3D11Buffer> buffer;
-		InitBuffer(tverts->width * sizeof(float), data->num,
-				tverts->array, buffer.Assign());
+		InitBuffer(tverts->width * sizeof(float), vbd.data->num,
+				tverts->array, &buffer);
 
 		uvBuffers.push_back(buffer);
 		uvSizes.push_back(tverts->width * sizeof(float));
 	}
+}
+
+gs_vertex_buffer::gs_vertex_buffer(gs_device_t *device, struct gs_vb_data *data,
+		uint32_t flags)
+	: gs_obj   (device, gs_type::gs_vertex_buffer),
+	  dynamic  ((flags & GS_DYNAMIC) != 0),
+	  vbd      (data),
+	  numVerts (data->num)
+{
+	if (!data->num)
+		throw "Cannot initialize vertex buffer with 0 vertices";
+	if (!data->points)
+		throw "No points specified for vertex buffer";
 
-	if (!dynamic)
-		vbd.Clear();
+	BuildBuffers();
 }
diff --git a/libobs-d3d11/d3d11-zstencilbuffer.cpp b/libobs-d3d11/d3d11-zstencilbuffer.cpp
index 5b2732d..8c077d1 100644
--- a/libobs-d3d11/d3d11-zstencilbuffer.cpp
+++ b/libobs-d3d11/d3d11-zstencilbuffer.cpp
@@ -19,8 +19,6 @@
 
 void gs_zstencil_buffer::InitBuffer()
 {
-	D3D11_TEXTURE2D_DESC td;
-	D3D11_DEPTH_STENCIL_VIEW_DESC dsvd;
 	HRESULT hr;
 
 	memset(&td, 0, sizeof(td));
@@ -50,7 +48,7 @@ void gs_zstencil_buffer::InitBuffer()
 gs_zstencil_buffer::gs_zstencil_buffer(gs_device_t *device,
 		uint32_t width, uint32_t height,
 		gs_zstencil_format format)
-	: device     (device),
+	: gs_obj     (device, gs_type::gs_zstencil_buffer),
 	  width      (width),
 	  height     (height),
 	  format     (format),
diff --git a/libobs-opengl/gl-subsystem.c b/libobs-opengl/gl-subsystem.c
index 3ce12e2..32b99f0 100644
--- a/libobs-opengl/gl-subsystem.c
+++ b/libobs-opengl/gl-subsystem.c
@@ -221,6 +221,14 @@ int device_create(gs_device_t **p_device, uint32_t adapter)
 	device_leave_context(device);
 	device->cur_swap = NULL;
 
+#ifdef _WIN32
+	blog(LOG_INFO, "Warning: The OpenGL renderer is currently in use.  "
+			"On windows, the OpenGL renderer can decrease "
+			"capture performance due to the lack of specific "
+			"features used to maximize capture performance.  "
+			"The Direct3D 11 renderer is recommended instead.");
+#endif
+
 	*p_device = device;
 	return GS_SUCCESS;
 
@@ -447,7 +455,7 @@ void device_load_texture(gs_device_t *device, gs_texture_t *tex, int unit)
 
 	/* need a pixel shader to properly bind textures */
 	if (!device->cur_pixel_shader)
-		tex = NULL;
+		goto fail;
 
 	if (cur_tex == tex)
 		return;
diff --git a/libobs-opengl/gl-x11.c b/libobs-opengl/gl-x11.c
index 7720b8f..e53279d 100644
--- a/libobs-opengl/gl-x11.c
+++ b/libobs-opengl/gl-x11.c
@@ -587,7 +587,12 @@ extern void device_present(gs_device_t *device)
 		initialized = true;
 	}
 
-	/* TODO: Handle XCB events. */
+	xcb_connection_t *xcb_conn = XGetXCBConnection(display);
+	xcb_generic_event_t *xcb_event;
+	while((xcb_event = xcb_poll_for_event(xcb_conn))) {
+		/* TODO: Handle XCB events. */
+		free(xcb_event);
+	}
 
 	switch (swap_type) {
 	case SWAP_TYPE_EXT:    glXSwapIntervalEXT(display, window, 0); break;
diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt
index fa19fd9..cd2b80e 100644
--- a/libobs/CMakeLists.txt
+++ b/libobs/CMakeLists.txt
@@ -68,6 +68,13 @@ if(WIN32)
 		util/windows/CoTaskMemPtr.hpp
 		util/windows/HRError.hpp
 		util/windows/WinHandle.hpp)
+	set(libobs_audio_monitoring_SOURCES
+		audio-monitoring/win32/wasapi-output.c
+		audio-monitoring/win32/wasapi-enum-devices.c
+		)
+	set(libobs_audio_monitoring_HEADERS
+		audio-monitoring/win32/wasapi-output.h
+		)
 	set(libobs_PLATFORM_DEPS winmm)
 	if(MSVC)
 		set(libobs_PLATFORM_DEPS
@@ -83,6 +90,13 @@ elseif(APPLE)
 		util/platform-cocoa.m)
 	set(libobs_PLATFORM_HEADERS
 		util/threading-posix.h)
+	set(libobs_audio_monitoring_SOURCES
+		audio-monitoring/osx/coreaudio-enum-devices.c
+		audio-monitoring/osx/coreaudio-output.c
+		)
+	set(libobs_audio_monitoring_HEADERS
+		audio-monitoring/osx/mac-helpers.h
+		)
 
 	set_source_files_properties(${libobs_PLATFORM_SOURCES}
 		PROPERTIES
@@ -93,6 +107,18 @@ elseif(APPLE)
 	mark_as_advanced(COCOA)
 	include_directories(${COCOA})
 
+	find_library(COREAUDIO CoreAudio)
+	mark_as_advanced(COREAUDIO)
+	include_directories(${COREAUDIO})
+
+	find_library(AUDIOTOOLBOX AudioToolbox)
+	mark_as_advanced(AUDIOTOOLBOX)
+	include_directories(${AUDIOTOOLBOX})
+
+	find_library(AUDIOUNIT AudioUnit)
+	mark_as_advanced(AUDIOUNIT)
+	include_directories(${AUDIOUNIT})
+
 	find_library(APPKIT AppKit)
 	mark_as_advanced(APPKIT)
 	include_directories(${APPKIT})
@@ -107,6 +133,9 @@ elseif(APPLE)
 
 	set(libobs_PLATFORM_DEPS
 		${COCOA}
+		${COREAUDIO}
+		${AUDIOUNIT}
+		${AUDIOTOOLBOX}
 		${APPKIT}
 		${IOKIT}
 		${CARBON})
@@ -118,6 +147,9 @@ elseif(UNIX)
 		util/platform-nix.c)
 	set(libobs_PLATFORM_HEADERS
 		util/threading-posix.h)
+	set(libobs_audio_monitoring_SOURCES
+		audio-monitoring/null/null-audio-monitoring.c
+		)
 
 	if(DBUS_FOUND)
 		set(libobs_PLATFORM_SOURCES ${libobs_PLATFORM_SOURCES}
@@ -334,7 +366,10 @@ set(libobs_HEADERS
 	${libobs_graphics_HEADERS}
 	${libobs_mediaio_HEADERS}
 	${libobs_util_HEADERS}
-	${libobs_libobs_HEADERS})
+	${libobs_libobs_HEADERS}
+	${libobs_audio_monitoring_SOURCES}
+	${libobs_audio_monitoring_HEADERS}
+	)
 
 source_group("callback\\Source Files" FILES ${libobs_callback_SOURCES})
 source_group("callback\\Header Files" FILES ${libobs_callback_HEADERS})
@@ -346,7 +381,15 @@ source_group("media-io\\Source Files" FILES ${libobs_mediaio_SOURCES})
 source_group("media-io\\Header Files" FILES ${libobs_mediaio_HEADERS})
 source_group("util\\Source Files" FILES ${libobs_util_SOURCES})
 source_group("util\\Header Files" FILES ${libobs_util_HEADERS})
+source_group("audio-monitoring\\Source Files" FILES ${libobs_audio_monitoring_SOURCES})
+source_group("audio-monitoring\\Header Files" FILES ${libobs_audio_monitoring_HEADERS})
 
+if(BUILD_CAPTIONS)
+	include_directories(${CMAKE_SOURCE_DIR}/deps/libcaption)
+	set(libobs_PLATFORM_DEPS
+		${libobs_PLATFORM_DEPS}
+		caption)
+endif()
 
 add_library(libobs SHARED ${libobs_SOURCES} ${libobs_HEADERS})
 
diff --git a/libobs/audio-monitoring/null/null-audio-monitoring.c b/libobs/audio-monitoring/null/null-audio-monitoring.c
new file mode 100644
index 0000000..9d7b2a4
--- /dev/null
+++ b/libobs/audio-monitoring/null/null-audio-monitoring.c
@@ -0,0 +1,23 @@
+#include "../../obs-internal.h"
+
+void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, void *data)
+{
+	UNUSED_PARAMETER(cb);
+	UNUSED_PARAMETER(data);
+}
+
+struct audio_monitor *audio_monitor_create(obs_source_t *source)
+{
+	UNUSED_PARAMETER(source);
+	return NULL;
+}
+
+void audio_monitor_reset(struct audio_monitor *monitor)
+{
+	UNUSED_PARAMETER(monitor);
+}
+
+void audio_monitor_destroy(struct audio_monitor *monitor)
+{
+	UNUSED_PARAMETER(monitor);
+}
diff --git a/libobs/audio-monitoring/osx/coreaudio-enum-devices.c b/libobs/audio-monitoring/osx/coreaudio-enum-devices.c
new file mode 100644
index 0000000..5fd591b
--- /dev/null
+++ b/libobs/audio-monitoring/osx/coreaudio-enum-devices.c
@@ -0,0 +1,96 @@
+#include <CoreFoundation/CFString.h>
+#include <CoreAudio/CoreAudio.h>
+
+#include "../../obs-internal.h"
+#include "../../util/dstr.h"
+
+#include "mac-helpers.h"
+
+static inline bool cf_to_cstr(CFStringRef ref, char *buf, size_t size)
+{
+	if (!ref) return false;
+	return (bool)CFStringGetCString(ref, buf, size, kCFStringEncodingUTF8);
+}
+
+static void obs_enum_audio_monitoring_device(obs_enum_audio_device_cb cb,
+		void *data, AudioDeviceID id)
+{
+	UInt32      size    = 0;
+	CFStringRef cf_name = NULL;
+	CFStringRef cf_uid  = NULL;
+	char        name[1024];
+	char        uid[1024];
+	OSStatus    stat;
+
+	AudioObjectPropertyAddress addr = {
+		kAudioDevicePropertyStreams,
+		kAudioDevicePropertyScopeInput,
+		kAudioObjectPropertyElementMaster
+	};
+
+	/* check to see if it's a mac input device */
+	AudioObjectGetPropertyDataSize(id, &addr, 0, NULL, &size);
+	if (!size)
+		return;
+
+	size = sizeof(CFStringRef);
+
+	addr.mSelector = kAudioDevicePropertyDeviceUID;
+	stat = AudioObjectGetPropertyData(id, &addr, 0, NULL, &size, &cf_uid);
+	if (!success(stat, "get audio device UID"))
+		return;
+
+	addr.mSelector = kAudioDevicePropertyDeviceNameCFString;
+	stat = AudioObjectGetPropertyData(id, &addr, 0, NULL, &size, &cf_name);
+	if (!success(stat, "get audio device name"))
+		goto fail;
+
+	if (!cf_to_cstr(cf_name, name, sizeof(name))) {
+		blog(LOG_WARNING, "%s: failed to convert name", __FUNCTION__);
+		goto fail;
+	}
+
+	if (!cf_to_cstr(cf_uid, uid, sizeof(uid))) {
+		blog(LOG_WARNING, "%s: failed to convert uid", __FUNCTION__);
+		goto fail;
+	}
+
+	cb(data, name, uid);
+
+fail:
+	if (cf_name)
+		CFRelease(cf_name);
+	if (cf_uid)
+		CFRelease(cf_uid);
+}
+
+void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, void *data)
+{
+	AudioObjectPropertyAddress addr = {
+		kAudioHardwarePropertyDevices,
+		kAudioObjectPropertyScopeGlobal,
+		kAudioObjectPropertyElementMaster
+	};
+
+	UInt32        size = 0;
+	UInt32        count;
+	OSStatus      stat;
+	AudioDeviceID *ids;
+
+	stat = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr,
+						0, NULL, &size);
+	if (!success(stat, "get data size"))
+		return;
+
+	ids   = malloc(size);
+	count = size / sizeof(AudioDeviceID);
+
+	stat = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
+						0, NULL, &size, ids);
+	if (success(stat, "get data")) {
+		for (UInt32 i = 0; i < count; i++)
+			obs_enum_audio_monitoring_device(cb, data, ids[i]);
+	}
+
+	free(ids);
+}
diff --git a/libobs/audio-monitoring/osx/coreaudio-output.c b/libobs/audio-monitoring/osx/coreaudio-output.c
new file mode 100644
index 0000000..52ff672
--- /dev/null
+++ b/libobs/audio-monitoring/osx/coreaudio-output.c
@@ -0,0 +1,322 @@
+#include <AudioUnit/AudioUnit.h>
+#include <AudioToolBox/AudioQueue.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreAudio/CoreAudio.h>
+
+#include "../../media-io/audio-resampler.h"
+#include "../../util/circlebuf.h"
+#include "../../util/threading.h"
+#include "../../util/platform.h"
+#include "../../obs-internal.h"
+#include "../../util/darray.h"
+
+#include "mac-helpers.h"
+
+struct audio_monitor {
+	obs_source_t          *source;
+	AudioQueueRef         queue;
+	AudioQueueBufferRef   buffers[3];
+
+	pthread_mutex_t       mutex;
+	struct circlebuf      empty_buffers;
+	struct circlebuf      new_data;
+	audio_resampler_t     *resampler;
+	size_t                buffer_size;
+	size_t                wait_size;
+	uint32_t              channels;
+
+	volatile bool         active;
+	bool                  paused;
+};
+
+static inline bool fill_buffer(struct audio_monitor *monitor)
+{
+	AudioQueueBufferRef buf;
+	OSStatus stat;
+
+	if (monitor->new_data.size < monitor->buffer_size) {
+		return false;
+	}
+
+	circlebuf_pop_front(&monitor->empty_buffers, &buf, sizeof(buf));
+	circlebuf_pop_front(&monitor->new_data, buf->mAudioData,
+			monitor->buffer_size);
+
+	buf->mAudioDataByteSize = monitor->buffer_size;
+
+	stat = AudioQueueEnqueueBuffer(monitor->queue, buf, 0, NULL);
+	if (!success(stat, "AudioQueueEnqueueBuffer")) {
+		blog(LOG_WARNING, "%s: %s", __FUNCTION__,
+				"Failed to enqueue buffer");
+		AudioQueueStop(monitor->queue, false);
+	}
+	return true;
+}
+
+static void on_audio_playback(void *param, obs_source_t *source,
+		const struct audio_data *audio_data, bool muted)
+{
+	struct audio_monitor *monitor = param;
+	float vol = source->user_volume;
+	uint32_t bytes;
+
+	UNUSED_PARAMETER(source);
+
+	if (!os_atomic_load_bool(&monitor->active)) {
+		return;
+	}
+
+	uint8_t *resample_data[MAX_AV_PLANES];
+	uint32_t resample_frames;
+	uint64_t ts_offset;
+	bool success;
+
+	success = audio_resampler_resample(monitor->resampler, resample_data,
+			&resample_frames, &ts_offset,
+			(const uint8_t *const *)audio_data->data,
+			(uint32_t)audio_data->frames);
+	if (!success) {
+		return;
+	}
+
+	bytes = sizeof(float) * monitor->channels * resample_frames;
+
+	if (muted) {
+		memset(resample_data[0], 0, bytes);
+	} else {
+		/* apply volume */
+		if (!close_float(vol, 1.0f, EPSILON)) {
+			register float *cur = (float*)resample_data[0];
+			register float *end = cur +
+				resample_frames * monitor->channels;
+
+			while (cur < end)
+				*(cur++) *= vol;
+		}
+	}
+
+	pthread_mutex_lock(&monitor->mutex);
+	circlebuf_push_back(&monitor->new_data, resample_data[0], bytes);
+
+	if (monitor->new_data.size >= monitor->wait_size) {
+		monitor->wait_size = 0;
+
+		while (monitor->empty_buffers.size > 0) {
+			if (!fill_buffer(monitor)) {
+				break;
+			}
+		}
+
+		if (monitor->paused) {
+			AudioQueueStart(monitor->queue, NULL);
+			monitor->paused = false;
+		}
+	}
+
+	pthread_mutex_unlock(&monitor->mutex);
+}
+
+static void buffer_audio(void *data, AudioQueueRef aq, AudioQueueBufferRef buf)
+{
+	struct audio_monitor *monitor = data;
+
+	pthread_mutex_lock(&monitor->mutex);
+	circlebuf_push_back(&monitor->empty_buffers, &buf, sizeof(buf));
+	while (monitor->empty_buffers.size > 0) {
+		if (!fill_buffer(monitor)) {
+			break;
+		}
+	}
+	if (monitor->empty_buffers.size == sizeof(buf) * 3) {
+		monitor->paused = true;
+		monitor->wait_size = monitor->buffer_size * 3;
+		AudioQueuePause(monitor->queue);
+	}
+	pthread_mutex_unlock(&monitor->mutex);
+
+	UNUSED_PARAMETER(aq);
+}
+
+static bool audio_monitor_init(struct audio_monitor *monitor)
+{
+	const struct audio_output_info *info = audio_output_get_info(
+			obs->audio.audio);
+	uint32_t channels = get_audio_channels(info->speakers);
+	OSStatus stat;
+
+	AudioStreamBasicDescription desc = {
+		.mSampleRate = (Float64)info->samples_per_sec,
+		.mFormatID = kAudioFormatLinearPCM,
+		.mFormatFlags = kAudioFormatFlagIsFloat |
+		                kAudioFormatFlagIsPacked,
+		.mBytesPerPacket = sizeof(float) * channels,
+		.mFramesPerPacket = 1,
+		.mBytesPerFrame = sizeof(float) * channels,
+		.mChannelsPerFrame = channels,
+		.mBitsPerChannel = sizeof(float) * 8
+	};
+
+	monitor->channels = channels;
+	monitor->buffer_size =
+		channels * sizeof(float) * info->samples_per_sec / 100 * 3;
+	monitor->wait_size = monitor->buffer_size * 3;
+
+	pthread_mutex_init_value(&monitor->mutex);
+
+	stat = AudioQueueNewOutput(&desc, buffer_audio, monitor, NULL, NULL, 0,
+			&monitor->queue);
+	if (!success(stat, "AudioStreamBasicDescription")) {
+		return false;
+	}
+
+	const char *uid = obs->audio.monitoring_device_id;
+	if (!uid || !*uid) {
+		return false;
+	}
+
+	if (strcmp(uid, "default") != 0) {
+		CFStringRef cf_uid = CFStringCreateWithBytesNoCopy(NULL,
+				(const UInt8*)uid, strlen(uid),
+				kCFStringEncodingUTF8,
+				false, NULL);
+
+		stat = AudioQueueSetProperty(monitor->queue,
+				kAudioQueueProperty_CurrentDevice,
+				cf_uid, sizeof(cf_uid));
+		CFRelease(cf_uid);
+
+		if (!success(stat, "set current device")) {
+			return false;
+		}
+	}
+
+	stat = AudioQueueSetParameter(monitor->queue,
+			kAudioQueueParam_Volume, 1.0);
+	if (!success(stat, "set volume")) {
+		return false;
+	}
+
+	for (size_t i = 0; i < 3; i++) {
+		stat = AudioQueueAllocateBuffer(monitor->queue,
+				monitor->buffer_size, &monitor->buffers[i]);
+		if (!success(stat, "allocation of buffer")) {
+			return false;
+		}
+
+		circlebuf_push_back(&monitor->empty_buffers,
+				&monitor->buffers[i],
+				sizeof(monitor->buffers[i]));
+	}
+
+	if (pthread_mutex_init(&monitor->mutex, NULL) != 0) {
+		blog(LOG_WARNING, "%s: %s", __FUNCTION__,
+				"Failed to init mutex");
+		return false;
+	}
+
+	struct resample_info from = {
+		.samples_per_sec = info->samples_per_sec,
+		.speakers = info->speakers,
+		.format = AUDIO_FORMAT_FLOAT_PLANAR
+	};
+	struct resample_info to = {
+		.samples_per_sec = info->samples_per_sec,
+		.speakers = info->speakers,
+		.format = AUDIO_FORMAT_FLOAT
+	};
+
+	monitor->resampler = audio_resampler_create(&to, &from);
+	if (!monitor->resampler) {
+		blog(LOG_WARNING, "%s: %s", __FUNCTION__,
+				"Failed to create resampler");
+		return false;
+	}
+
+	stat = AudioQueueStart(monitor->queue, NULL);
+	if (!success(stat, "start")) {
+		return false;
+	}
+
+	monitor->active = true;
+	return true;
+}
+
+static void audio_monitor_free(struct audio_monitor *monitor)
+{
+	if (monitor->source) {
+		obs_source_remove_audio_capture_callback(
+				monitor->source, on_audio_playback, monitor);
+	}
+	if (monitor->active) {
+		AudioQueueStop(monitor->queue, true);
+	}
+	for (size_t i = 0; i < 3; i++) {
+		if (monitor->buffers[i]) {
+			AudioQueueFreeBuffer(monitor->queue,
+					monitor->buffers[i]);
+		}
+	}
+	if (monitor->queue) {
+		AudioQueueDispose(monitor->queue, true);
+	}
+
+	audio_resampler_destroy(monitor->resampler);
+	circlebuf_free(&monitor->empty_buffers);
+	circlebuf_free(&monitor->new_data);
+	pthread_mutex_destroy(&monitor->mutex);
+}
+
+static void audio_monitor_init_final(struct audio_monitor *monitor,
+		obs_source_t *source)
+{
+	monitor->source = source;
+	obs_source_add_audio_capture_callback(source, on_audio_playback,
+			monitor);
+}
+
+struct audio_monitor *audio_monitor_create(obs_source_t *source)
+{
+	struct audio_monitor *monitor = bzalloc(sizeof(*monitor));
+
+	if (!audio_monitor_init(monitor)) {
+		goto fail;
+	}
+
+	pthread_mutex_lock(&obs->audio.monitoring_mutex);
+	da_push_back(obs->audio.monitors, &monitor);
+	pthread_mutex_unlock(&obs->audio.monitoring_mutex);
+
+	audio_monitor_init_final(monitor, source);
+	return monitor;
+
+fail:
+	audio_monitor_free(monitor);
+	bfree(monitor);
+	return NULL;
+}
+
+void audio_monitor_reset(struct audio_monitor *monitor)
+{
+	bool success;
+
+	obs_source_t *source = monitor->source;
+	audio_monitor_free(monitor);
+	memset(monitor, 0, sizeof(*monitor));
+
+	success = audio_monitor_init(monitor);
+	if (success)
+		audio_monitor_init_final(monitor, source);
+}
+
+void audio_monitor_destroy(struct audio_monitor *monitor)
+{
+	if (monitor) {
+		audio_monitor_free(monitor);
+
+		pthread_mutex_lock(&obs->audio.monitoring_mutex);
+		da_erase_item(obs->audio.monitors, &monitor);
+		pthread_mutex_unlock(&obs->audio.monitoring_mutex);
+
+		bfree(monitor);
+	}
+}
diff --git a/libobs/audio-monitoring/osx/mac-helpers.h b/libobs/audio-monitoring/osx/mac-helpers.h
new file mode 100644
index 0000000..f995990
--- /dev/null
+++ b/libobs/audio-monitoring/osx/mac-helpers.h
@@ -0,0 +1,15 @@
+#pragma once
+
+static bool success_(OSStatus stat, const char *func, const char *call)
+{
+	if (stat != noErr) {
+		blog(LOG_WARNING, "%s: %s failed: %d",
+				func, call, (int)stat);
+		return false;
+	}
+
+	return true;
+}
+
+#define success(stat, call) \
+	success_(stat, __FUNCTION__, call)
diff --git a/libobs/audio-monitoring/win32/wasapi-enum-devices.c b/libobs/audio-monitoring/win32/wasapi-enum-devices.c
new file mode 100644
index 0000000..98ed93a
--- /dev/null
+++ b/libobs/audio-monitoring/win32/wasapi-enum-devices.c
@@ -0,0 +1,105 @@
+#include "../../obs-internal.h"
+
+#include "wasapi-output.h"
+
+#include <propsys.h>
+
+#ifdef __MINGW32__
+
+#ifdef DEFINE_PROPERTYKEY
+#undef DEFINE_PROPERTYKEY
+#endif
+#define DEFINE_PROPERTYKEY(id, a, b, c, d, e, f, g, h, i, j, k, l) \
+	const PROPERTYKEY id = { { a,b,c, { d,e,f,g,h,i,j,k, } }, l };
+DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, \
+	0xa45c254e, 0xdf1c, 0x4efd, 0x80, \
+	0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
+
+#else
+
+#include <functiondiscoverykeys_devpkey.h>
+
+#endif
+
+static bool get_device_info(obs_enum_audio_device_cb cb, void *data,
+		IMMDeviceCollection *collection, UINT idx)
+{
+	IPropertyStore *store = NULL;
+	IMMDevice *device = NULL;
+	PROPVARIANT name_var;
+	char utf8_name[512];
+	WCHAR *w_id = NULL;
+	char utf8_id[512];
+	bool cont = true;
+	HRESULT hr;
+
+	hr = collection->lpVtbl->Item(collection, idx, &device);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	hr = device->lpVtbl->GetId(device, &w_id);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	hr = device->lpVtbl->OpenPropertyStore(device, STGM_READ, &store);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	PropVariantInit(&name_var);
+	hr = store->lpVtbl->GetValue(store, &PKEY_Device_FriendlyName,
+			&name_var);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	os_wcs_to_utf8(w_id, 0, utf8_id, 512);
+	os_wcs_to_utf8(name_var.pwszVal, 0, utf8_name, 512);
+
+	cont = cb(data, utf8_name, utf8_id);
+
+fail:
+	safe_release(store);
+	safe_release(device);
+	if (w_id)
+		CoTaskMemFree(w_id);
+	return cont;
+}
+
+void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb,
+		void *data)
+{
+	IMMDeviceEnumerator *enumerator = NULL;
+	IMMDeviceCollection *collection = NULL;
+	UINT count;
+	HRESULT hr;
+
+	hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
+			&IID_IMMDeviceEnumerator, &enumerator);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	hr = enumerator->lpVtbl->EnumAudioEndpoints(enumerator, eRender,
+			DEVICE_STATE_ACTIVE, &collection);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	hr = collection->lpVtbl->GetCount(collection, &count);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	for (UINT i = 0; i < count; i++) {
+		if (!get_device_info(cb, data, collection, i)) {
+			break;
+		}
+	}
+
+fail:
+	safe_release(enumerator);
+	safe_release(collection);
+}
diff --git a/libobs/audio-monitoring/win32/wasapi-output.c b/libobs/audio-monitoring/win32/wasapi-output.c
new file mode 100644
index 0000000..c1ffd4e
--- /dev/null
+++ b/libobs/audio-monitoring/win32/wasapi-output.c
@@ -0,0 +1,418 @@
+#include "../../media-io/audio-resampler.h"
+#include "../../util/circlebuf.h"
+#include "../../util/platform.h"
+#include "../../util/darray.h"
+#include "../../obs-internal.h"
+
+#include "wasapi-output.h"
+
+#define ACTUALLY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+        EXTERN_C const GUID DECLSPEC_SELECTANY name \
+                = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
+
+ACTUALLY_DEFINE_GUID(CLSID_MMDeviceEnumerator,
+	0xBCDE0395, 0xE52F, 0x467C,
+	0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E);
+ACTUALLY_DEFINE_GUID(IID_IMMDeviceEnumerator,
+	0xA95664D2, 0x9614, 0x4F35,
+	0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6);
+ACTUALLY_DEFINE_GUID(IID_IAudioClient,
+	0x1CB9AD4C, 0xDBFA, 0x4C32,
+	0xB1, 0x78, 0xC2, 0xF5, 0x68, 0xA7, 0x03, 0xB2);
+ACTUALLY_DEFINE_GUID(IID_IAudioRenderClient,
+	0xF294ACFC, 0x3146, 0x4483,
+	0xA7, 0xBF, 0xAD, 0xDC, 0xA7, 0xC2, 0x60, 0xE2);
+
+struct audio_monitor {
+	obs_source_t       *source;
+	IMMDevice          *device;
+	IAudioClient       *client;
+	IAudioRenderClient *render;
+
+	uint64_t           last_recv_time;
+	uint64_t           prev_video_ts;
+	uint64_t           time_since_prev;
+	audio_resampler_t  *resampler;
+	uint32_t           sample_rate;
+	uint32_t           channels;
+	bool               source_has_video : 1;
+
+	int64_t            lowest_audio_offset;
+	struct circlebuf   delay_buffer;
+	uint32_t           delay_size;
+
+	DARRAY(float)      buf;
+	pthread_mutex_t    playback_mutex;
+};
+
+/* #define DEBUG_AUDIO */
+
+static bool process_audio_delay(struct audio_monitor *monitor,
+		float **data, uint32_t *frames, uint64_t ts, uint32_t pad)
+{
+	obs_source_t *s = monitor->source;
+	uint64_t last_frame_ts = s->last_frame_ts;
+	uint64_t cur_time = os_gettime_ns();
+	uint64_t front_ts;
+	uint64_t cur_ts;
+	int64_t diff;
+	uint32_t blocksize = monitor->channels * sizeof(float);
+
+	/* cut off audio if long-since leftover audio in delay buffer */
+	if (cur_time - monitor->last_recv_time > 1000000000)
+		circlebuf_free(&monitor->delay_buffer);
+	monitor->last_recv_time = cur_time;
+
+	ts += monitor->source->sync_offset;
+
+	circlebuf_push_back(&monitor->delay_buffer, &ts, sizeof(ts));
+	circlebuf_push_back(&monitor->delay_buffer, frames, sizeof(*frames));
+	circlebuf_push_back(&monitor->delay_buffer, *data,
+			*frames * blocksize);
+
+	if (!monitor->prev_video_ts) {
+		monitor->prev_video_ts = last_frame_ts;
+
+	} else if (monitor->prev_video_ts == last_frame_ts) {
+		monitor->time_since_prev += (uint64_t)*frames *
+			1000000000ULL / (uint64_t)monitor->sample_rate;
+	} else {
+		monitor->time_since_prev = 0;
+	}
+
+	while (monitor->delay_buffer.size != 0) {
+		size_t size;
+		bool bad_diff;
+
+		circlebuf_peek_front(&monitor->delay_buffer, &cur_ts,
+				sizeof(ts));
+		front_ts = cur_ts -
+			((uint64_t)pad * 1000000000ULL /
+			 (uint64_t)monitor->sample_rate);
+		diff = (int64_t)front_ts - (int64_t)last_frame_ts;
+		bad_diff = !last_frame_ts ||
+		           llabs(diff) > 5000000000 ||
+		           monitor->time_since_prev > 100000000ULL;
+
+		/* delay audio if rushing */
+		if (!bad_diff && diff > 75000000) {
+#ifdef DEBUG_AUDIO
+			blog(LOG_INFO, "audio rushing, cutting audio, "
+					"diff: %lld, delay buffer size: %lu, "
+					"v: %llu: a: %llu",
+					diff, (int)monitor->delay_buffer.size,
+					last_frame_ts, front_ts);
+#endif
+			return false;
+		}
+
+		circlebuf_pop_front(&monitor->delay_buffer, NULL, sizeof(ts));
+		circlebuf_pop_front(&monitor->delay_buffer, frames,
+				sizeof(*frames));
+
+		size = *frames * blocksize;
+		da_resize(monitor->buf, size);
+		circlebuf_pop_front(&monitor->delay_buffer,
+				monitor->buf.array, size);
+
+		/* cut audio if dragging */
+		if (!bad_diff && diff < -75000000 && monitor->delay_buffer.size > 0) {
+#ifdef DEBUG_AUDIO
+			blog(LOG_INFO, "audio dragging, cutting audio, "
+					"diff: %lld, delay buffer size: %lu, "
+					"v: %llu: a: %llu",
+					diff, (int)monitor->delay_buffer.size,
+					last_frame_ts, front_ts);
+#endif
+			continue;
+		}
+
+		*data = monitor->buf.array;
+		return true;
+	}
+
+	return false;
+}
+
+static void on_audio_playback(void *param, obs_source_t *source,
+		const struct audio_data *audio_data, bool muted)
+{
+	struct audio_monitor *monitor = param;
+	IAudioRenderClient *render = monitor->render;
+	uint8_t *resample_data[MAX_AV_PLANES];
+	float vol = source->user_volume;
+	uint32_t resample_frames;
+	uint64_t ts_offset;
+	bool success;
+	BYTE *output;
+
+	if (pthread_mutex_trylock(&monitor->playback_mutex) != 0) {
+		return;
+	}
+	if (os_atomic_load_long(&source->activate_refs) == 0) {
+		goto unlock;
+	}
+
+	success = audio_resampler_resample(monitor->resampler, resample_data,
+			&resample_frames, &ts_offset,
+			(const uint8_t *const *)audio_data->data,
+			(uint32_t)audio_data->frames);
+	if (!success) {
+		goto unlock;
+	}
+
+	UINT32 pad = 0;
+	monitor->client->lpVtbl->GetCurrentPadding(monitor->client, &pad);
+
+	if (monitor->source_has_video) {
+		uint64_t ts = audio_data->timestamp - ts_offset;
+
+		if (!process_audio_delay(monitor, (float**)(&resample_data[0]),
+					&resample_frames, ts, pad)) {
+			goto unlock;
+		}
+	}
+
+	HRESULT hr = render->lpVtbl->GetBuffer(render, resample_frames,
+			&output);
+	if (FAILED(hr)) {
+		goto unlock;
+	}
+
+	if (!muted) {
+		/* apply volume */
+		if (!close_float(vol, 1.0f, EPSILON)) {
+			register float *cur = (float*)resample_data[0];
+			register float *end = cur +
+				resample_frames * monitor->channels;
+
+			while (cur < end)
+				*(cur++) *= vol;
+		}
+		memcpy(output, resample_data[0],
+				resample_frames * monitor->channels *
+				sizeof(float));
+	}
+
+	render->lpVtbl->ReleaseBuffer(render, resample_frames,
+			muted ? AUDCLNT_BUFFERFLAGS_SILENT : 0);
+
+unlock:
+	pthread_mutex_unlock(&monitor->playback_mutex);
+}
+
+static inline void audio_monitor_free(struct audio_monitor *monitor)
+{
+	if (monitor->source) {
+		obs_source_remove_audio_capture_callback(
+				monitor->source, on_audio_playback, monitor);
+	}
+
+	if (monitor->client)
+		monitor->client->lpVtbl->Stop(monitor->client);
+
+	safe_release(monitor->device);
+	safe_release(monitor->client);
+	safe_release(monitor->render);
+	audio_resampler_destroy(monitor->resampler);
+	circlebuf_free(&monitor->delay_buffer);
+	da_free(monitor->buf);
+}
+
+static enum speaker_layout convert_speaker_layout(DWORD layout, WORD channels)
+{
+	switch (layout) {
+	case KSAUDIO_SPEAKER_QUAD:             return SPEAKERS_QUAD;
+	case KSAUDIO_SPEAKER_2POINT1:          return SPEAKERS_2POINT1;
+	case KSAUDIO_SPEAKER_4POINT1:          return SPEAKERS_4POINT1;
+	case KSAUDIO_SPEAKER_SURROUND:         return SPEAKERS_SURROUND;
+	case KSAUDIO_SPEAKER_5POINT1:          return SPEAKERS_5POINT1;
+	case KSAUDIO_SPEAKER_5POINT1_SURROUND: return SPEAKERS_5POINT1_SURROUND;
+	case KSAUDIO_SPEAKER_7POINT1:          return SPEAKERS_7POINT1;
+	case KSAUDIO_SPEAKER_7POINT1_SURROUND: return SPEAKERS_7POINT1_SURROUND;
+	}
+
+	return (enum speaker_layout)channels;
+}
+
+static bool audio_monitor_init(struct audio_monitor *monitor)
+{
+	IMMDeviceEnumerator *immde = NULL;
+	WAVEFORMATEX *wfex = NULL;
+	bool success = false;
+	UINT32 frames;
+	HRESULT hr;
+
+	const char *id = obs->audio.monitoring_device_id;
+	if (!id) {
+		return false;
+	}
+
+	pthread_mutex_init_value(&monitor->playback_mutex);
+
+	/* ------------------------------------------ *
+	 * Init device                                */
+
+	hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
+			&IID_IMMDeviceEnumerator, (void**)&immde);
+	if (FAILED(hr)) {
+		return false;
+	}
+
+	if (strcmp(id, "default") == 0) {
+		hr = immde->lpVtbl->GetDefaultAudioEndpoint(immde,
+				eRender, eConsole, &monitor->device);
+	} else {
+		wchar_t w_id[512];
+		os_utf8_to_wcs(id, 0, w_id, 512);
+
+		hr = immde->lpVtbl->GetDevice(immde, w_id, &monitor->device);
+	}
+
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	/* ------------------------------------------ *
+	 * Init client                                */
+
+	hr = monitor->device->lpVtbl->Activate(monitor->device,
+			&IID_IAudioClient, CLSCTX_ALL, NULL,
+			(void**)&monitor->client);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	hr = monitor->client->lpVtbl->GetMixFormat(monitor->client, &wfex);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	hr = monitor->client->lpVtbl->Initialize(monitor->client,
+			AUDCLNT_SHAREMODE_SHARED, 0,
+			10000000, 0, wfex, NULL);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	/* ------------------------------------------ *
+	 * Init resampler                             */
+
+	const struct audio_output_info *info = audio_output_get_info(
+			obs->audio.audio);
+	WAVEFORMATEXTENSIBLE *ext = (WAVEFORMATEXTENSIBLE*)wfex;
+	struct resample_info from;
+	struct resample_info to;
+
+	from.samples_per_sec = info->samples_per_sec;
+	from.speakers = info->speakers;
+	from.format = AUDIO_FORMAT_FLOAT_PLANAR;
+
+	to.samples_per_sec = (uint32_t)wfex->nSamplesPerSec;
+	to.speakers = convert_speaker_layout(ext->dwChannelMask,
+			wfex->nChannels);
+	to.format = AUDIO_FORMAT_FLOAT;
+
+	monitor->sample_rate = (uint32_t)wfex->nSamplesPerSec;
+	monitor->channels = wfex->nChannels;
+	monitor->resampler = audio_resampler_create(&to, &from);
+	if (!monitor->resampler) {
+		goto fail;
+	}
+
+	/* ------------------------------------------ *
+	 * Init client                                */
+
+	hr = monitor->client->lpVtbl->GetBufferSize(monitor->client, &frames);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	hr = monitor->client->lpVtbl->GetService(monitor->client,
+			&IID_IAudioRenderClient, (void**)&monitor->render);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	if (pthread_mutex_init(&monitor->playback_mutex, NULL) != 0) {
+		goto fail;
+	}
+
+	hr = monitor->client->lpVtbl->Start(monitor->client);
+	if (FAILED(hr)) {
+		goto fail;
+	}
+
+	success = true;
+
+fail:
+	safe_release(immde);
+	if (wfex)
+		CoTaskMemFree(wfex);
+	return success;
+}
+
+static void audio_monitor_init_final(struct audio_monitor *monitor,
+		obs_source_t *source)
+{
+	monitor->source = source;
+	monitor->source_has_video =
+		(source->info.output_flags & OBS_SOURCE_VIDEO) != 0;
+	obs_source_add_audio_capture_callback(source, on_audio_playback,
+			monitor);
+}
+
+struct audio_monitor *audio_monitor_create(obs_source_t *source)
+{
+	struct audio_monitor monitor = {0};
+	struct audio_monitor *out;
+
+	if (!audio_monitor_init(&monitor)) {
+		goto fail;
+	}
+
+	out = bmemdup(&monitor, sizeof(monitor));
+
+	pthread_mutex_lock(&obs->audio.monitoring_mutex);
+	da_push_back(obs->audio.monitors, &out);
+	pthread_mutex_unlock(&obs->audio.monitoring_mutex);
+
+	audio_monitor_init_final(out, source);
+	return out;
+
+fail:
+	audio_monitor_free(&monitor);
+	return NULL;
+}
+
+void audio_monitor_reset(struct audio_monitor *monitor)
+{
+	struct audio_monitor new_monitor = {0};
+	bool success;
+
+	pthread_mutex_lock(&monitor->playback_mutex);
+	success = audio_monitor_init(&new_monitor);
+	pthread_mutex_unlock(&monitor->playback_mutex);
+
+	if (success) {
+		obs_source_t *source = monitor->source;
+		audio_monitor_free(monitor);
+		*monitor = new_monitor;
+		audio_monitor_init_final(monitor, source);
+	} else {
+		audio_monitor_free(&new_monitor);
+	}
+}
+
+void audio_monitor_destroy(struct audio_monitor *monitor)
+{
+	if (monitor) {
+		audio_monitor_free(monitor);
+
+		pthread_mutex_lock(&obs->audio.monitoring_mutex);
+		da_erase_item(obs->audio.monitors, &monitor);
+		pthread_mutex_unlock(&obs->audio.monitoring_mutex);
+
+		bfree(monitor);
+	}
+}
diff --git a/libobs/audio-monitoring/win32/wasapi-output.h b/libobs/audio-monitoring/win32/wasapi-output.h
new file mode 100644
index 0000000..d43a418
--- /dev/null
+++ b/libobs/audio-monitoring/win32/wasapi-output.h
@@ -0,0 +1,13 @@
+#include <windows.h>
+#include <mmdeviceapi.h>
+#include <audioclient.h>
+
+#define KSAUDIO_SPEAKER_4POINT1 (KSAUDIO_SPEAKER_QUAD|SPEAKER_LOW_FREQUENCY)
+#define KSAUDIO_SPEAKER_2POINT1 (KSAUDIO_SPEAKER_STEREO|SPEAKER_LOW_FREQUENCY)
+
+#define safe_release(ptr) \
+	do { \
+		if (ptr) { \
+			ptr->lpVtbl->Release(ptr); \
+		} \
+	} while (false)
diff --git a/libobs/callback/decl.h b/libobs/callback/decl.h
index 9dc0295..1e955dc 100644
--- a/libobs/callback/decl.h
+++ b/libobs/callback/decl.h
@@ -31,7 +31,7 @@ struct decl_param {
 
 static inline void decl_param_free(struct decl_param *param)
 {
-	if (param)
+	if (param->name)
 		bfree(param->name);
 	memset(param, 0, sizeof(struct decl_param));
 }
diff --git a/libobs/data/bicubic_scale.effect b/libobs/data/bicubic_scale.effect
index 2bd5910..67ebb89 100644
--- a/libobs/data/bicubic_scale.effect
+++ b/libobs/data/bicubic_scale.effect
@@ -10,6 +10,7 @@ uniform float4x4 color_matrix;
 uniform float3 color_range_min = {0.0, 0.0, 0.0};
 uniform float3 color_range_max = {1.0, 1.0, 1.0};
 uniform float2 base_dimension_i;
+uniform float undistort_factor = 1.0;
 
 sampler_state textureSampler {
 	Filter    = Linear;
@@ -63,21 +64,41 @@ float4 weight4(float x)
 		weight(x + 1.0));
 }
 
-float4 pixel(float xpos, float ypos)
+float AspectUndistortX(float x, float a)
 {
-	return image.Sample(textureSampler, float2(xpos, ypos));
+	// The higher the power, the longer the linear part will be.
+	return (1.0 - a) * (x * x * x * x * x) + a * x;
 }
 
-float4 get_line(float ypos, float4 xpos, float4 linetaps)
+float AspectUndistortU(float u)
+{
+	// Normalize texture coord to -1.0 to 1.0 range, and back.
+	return AspectUndistortX((u - 0.5) * 2.0, undistort_factor) * 0.5 + 0.5;
+}
+
+float2 pixel_coord(float xpos, float ypos)
+{
+	return float2(AspectUndistortU(xpos), ypos);
+}
+
+float4 pixel(float xpos, float ypos, bool undistort)
+{
+	if (undistort)
+		return image.Sample(textureSampler, pixel_coord(xpos, ypos));
+	else
+		return image.Sample(textureSampler, float2(xpos, ypos));
+}
+
+float4 get_line(float ypos, float4 xpos, float4 linetaps, bool undistort)
 {
 	return
-		pixel(xpos.r, ypos) * linetaps.r +
-		pixel(xpos.g, ypos) * linetaps.g +
-		pixel(xpos.b, ypos) * linetaps.b +
-		pixel(xpos.a, ypos) * linetaps.a;
+		pixel(xpos.r, ypos, undistort) * linetaps.r +
+		pixel(xpos.g, ypos, undistort) * linetaps.g +
+		pixel(xpos.b, ypos, undistort) * linetaps.b +
+		pixel(xpos.a, ypos, undistort) * linetaps.a;
 }
 
-float4 DrawBicubic(VertData v_in)
+float4 DrawBicubic(VertData v_in, bool undistort)
 {
 	float2 stepxy = base_dimension_i;
 	float2 pos = v_in.uv + stepxy * 0.5;
@@ -100,20 +121,20 @@ float4 DrawBicubic(VertData v_in)
 	);
 
 	return
-		get_line(xystart.y                 , xpos, rowtaps) * coltaps.r +
-		get_line(xystart.y + stepxy.y      , xpos, rowtaps) * coltaps.g +
-		get_line(xystart.y + stepxy.y * 2.0, xpos, rowtaps) * coltaps.b +
-		get_line(xystart.y + stepxy.y * 3.0, xpos, rowtaps) * coltaps.a;
+		get_line(xystart.y                 , xpos, rowtaps, undistort) * coltaps.r +
+		get_line(xystart.y + stepxy.y      , xpos, rowtaps, undistort) * coltaps.g +
+		get_line(xystart.y + stepxy.y * 2.0, xpos, rowtaps, undistort) * coltaps.b +
+		get_line(xystart.y + stepxy.y * 3.0, xpos, rowtaps, undistort) * coltaps.a;
 }
 
-float4 PSDrawBicubicRGBA(VertData v_in) : TARGET
+float4 PSDrawBicubicRGBA(VertData v_in, bool undistort) : TARGET
 {
-	return DrawBicubic(v_in);
+	return DrawBicubic(v_in, undistort);
 }
 
 float4 PSDrawBicubicMatrix(VertData v_in) : TARGET
 {
-	float4 rgba = DrawBicubic(v_in);
+	float4 rgba = DrawBicubic(v_in, false);
 	float4 yuv;
 
 	yuv.xyz = clamp(rgba.xyz, color_range_min, color_range_max);
@@ -125,7 +146,16 @@ technique Draw
 	pass
 	{
 		vertex_shader = VSDefault(v_in);
-		pixel_shader  = PSDrawBicubicRGBA(v_in);
+		pixel_shader  = PSDrawBicubicRGBA(v_in, false);
+	}
+}
+
+technique DrawUndistort
+{
+	pass
+	{
+		vertex_shader = VSDefault(v_in);
+		pixel_shader  = PSDrawBicubicRGBA(v_in, true);
 	}
 }
 
diff --git a/libobs/data/lanczos_scale.effect b/libobs/data/lanczos_scale.effect
index b10034c..4fc6453 100644
--- a/libobs/data/lanczos_scale.effect
+++ b/libobs/data/lanczos_scale.effect
@@ -10,6 +10,7 @@ uniform float4x4 color_matrix;
 uniform float3 color_range_min = {0.0, 0.0, 0.0};
 uniform float3 color_range_max = {1.0, 1.0, 1.0};
 uniform float2 base_dimension_i;
+uniform float undistort_factor = 1.0;
 
 sampler_state textureSampler
 {
@@ -64,24 +65,44 @@ float3 weight3(float x, float scale)
 		weight((x * 2.0 + 2.0 * 2.0 - 3.0) * scale, 3.0));
 }
 
-float4 pixel(float xpos, float ypos)
+float AspectUndistortX(float x, float a)
 {
-	return image.Sample(textureSampler, float2(xpos, ypos));
+	// The higher the power, the longer the linear part will be.
+	return (1.0 - a) * (x * x * x * x * x) + a * x;
+}
+
+float AspectUndistortU(float u)
+{
+	// Normalize texture coord to -1.0 to 1.0 range, and back.
+	return AspectUndistortX((u - 0.5) * 2.0, undistort_factor) * 0.5 + 0.5;
+}
+
+float2 pixel_coord(float xpos, float ypos)
+{
+	return float2(AspectUndistortU(xpos), ypos);
+}
+
+float4 pixel(float xpos, float ypos, bool undistort)
+{
+	if (undistort)
+		return image.Sample(textureSampler, pixel_coord(xpos, ypos));
+	else
+		return image.Sample(textureSampler, float2(xpos, ypos));
 }
 
 float4 get_line(float ypos, float3 xpos1, float3 xpos2, float3 rowtap1,
-		float3 rowtap2)
+		float3 rowtap2, bool undistort)
 {
 	return
-		pixel(xpos1.r, ypos) * rowtap1.r +
-		pixel(xpos1.g, ypos) * rowtap2.r +
-		pixel(xpos1.b, ypos) * rowtap1.g +
-		pixel(xpos2.r, ypos) * rowtap2.g +
-		pixel(xpos2.g, ypos) * rowtap1.b +
-		pixel(xpos2.b, ypos) * rowtap2.b;
+		pixel(xpos1.r, ypos, undistort) * rowtap1.r +
+		pixel(xpos1.g, ypos, undistort) * rowtap2.r +
+		pixel(xpos1.b, ypos, undistort) * rowtap1.g +
+		pixel(xpos2.r, ypos, undistort) * rowtap2.g +
+		pixel(xpos2.g, ypos, undistort) * rowtap1.b +
+		pixel(xpos2.b, ypos, undistort) * rowtap2.b;
 }
 
-float4 DrawLanczos(FragData v_in)
+float4 DrawLanczos(FragData v_in, bool undistort)
 {
 	float2 stepxy = base_dimension_i;
 	float2 pos = v_in.uv + stepxy * 0.5;
@@ -106,22 +127,22 @@ float4 DrawLanczos(FragData v_in)
 	float3 xpos2 = float3(xystart.x + stepxy.x * 3.0, xystart.x + stepxy.x * 4.0, xystart.x + stepxy.x * 5.0);
 
 	return
-		get_line(xystart.y                 , xpos1, xpos2, rowtap1, rowtap2) * coltap1.r +
-		get_line(xystart.y + stepxy.y      , xpos1, xpos2, rowtap1, rowtap2) * coltap2.r +
-		get_line(xystart.y + stepxy.y * 2.0, xpos1, xpos2, rowtap1, rowtap2) * coltap1.g +
-		get_line(xystart.y + stepxy.y * 3.0, xpos1, xpos2, rowtap1, rowtap2) * coltap2.g +
-		get_line(xystart.y + stepxy.y * 4.0, xpos1, xpos2, rowtap1, rowtap2) * coltap1.b +
-		get_line(xystart.y + stepxy.y * 5.0, xpos1, xpos2, rowtap1, rowtap2) * coltap2.b;
+		get_line(xystart.y                 , xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap1.r +
+		get_line(xystart.y + stepxy.y      , xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap2.r +
+		get_line(xystart.y + stepxy.y * 2.0, xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap1.g +
+		get_line(xystart.y + stepxy.y * 3.0, xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap2.g +
+		get_line(xystart.y + stepxy.y * 4.0, xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap1.b +
+		get_line(xystart.y + stepxy.y * 5.0, xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap2.b;
 }
 
-float4 PSDrawLanczosRGBA(FragData v_in) : TARGET
+float4 PSDrawLanczosRGBA(FragData v_in, bool undistort) : TARGET
 {
-	return DrawLanczos(v_in);
+	return DrawLanczos(v_in, undistort);
 }
 
 float4 PSDrawLanczosMatrix(FragData v_in) : TARGET
 {
-	float4 rgba = DrawLanczos(v_in);
+	float4 rgba = DrawLanczos(v_in, false);
 	float4 yuv;
 
 	yuv.xyz = clamp(rgba.xyz, color_range_min, color_range_max);
@@ -133,7 +154,16 @@ technique Draw
 	pass
 	{
 		vertex_shader = VSDefault(v_in);
-		pixel_shader  = PSDrawLanczosRGBA(v_in);
+		pixel_shader  = PSDrawLanczosRGBA(v_in, false);
+	}
+}
+
+technique DrawUndistort
+{
+	pass
+	{
+		vertex_shader = VSDefault(v_in);
+		pixel_shader  = PSDrawLanczosRGBA(v_in, true);
 	}
 }
 
diff --git a/libobs/graphics/vec2.h b/libobs/graphics/vec2.h
index 8806577..f06bc80 100644
--- a/libobs/graphics/vec2.h
+++ b/libobs/graphics/vec2.h
@@ -106,7 +106,7 @@ static inline void vec2_neg(struct vec2 *dst, const struct vec2 *v)
 
 static inline float vec2_dot(const struct vec2 *v1, const struct vec2 *v2)
 {
-	return (v1->x+v2->x) * (v1->y+v2->y);
+	return v1->x*v2->x + v1->y*v2->y;
 }
 
 static inline float vec2_len(const struct vec2 *v)
diff --git a/libobs/media-io/audio-io.h b/libobs/media-io/audio-io.h
index 48a30f2..407749e 100644
--- a/libobs/media-io/audio-io.h
+++ b/libobs/media-io/audio-io.h
@@ -25,7 +25,7 @@
 extern "C" {
 #endif
 
-#define MAX_AUDIO_MIXES     4
+#define MAX_AUDIO_MIXES     6
 #define MAX_AUDIO_CHANNELS  2
 #define AUDIO_OUTPUT_FRAMES 1024
 
diff --git a/libobs/obs-avc.c b/libobs/obs-avc.c
index 647427a..8dd6459 100644
--- a/libobs/obs-avc.c
+++ b/libobs/obs-avc.c
@@ -132,15 +132,17 @@ void obs_parse_avc_packet(struct encoder_packet *avc_packet,
 {
 	struct array_output_data output;
 	struct serializer s;
+	long ref = 1;
 
 	array_output_serializer_init(&s, &output);
 	*avc_packet = *src;
 
+	serialize(&s, &ref, sizeof(ref));
 	serialize_avc_data(&s, src->data, src->size, &avc_packet->keyframe,
 			&avc_packet->priority);
 
-	avc_packet->data          = output.bytes.array;
-	avc_packet->size          = output.bytes.num;
+	avc_packet->data          = output.bytes.array + sizeof(ref);
+	avc_packet->size          = output.bytes.num - sizeof(ref);
 	avc_packet->drop_priority = get_drop_priority(avc_packet->priority);
 }
 
diff --git a/libobs/obs-config.h b/libobs/obs-config.h
index 3636e76..c1e05b2 100644
--- a/libobs/obs-config.h
+++ b/libobs/obs-config.h
@@ -27,21 +27,21 @@
 /*
  * Increment if major breaking API changes
  */
-#define LIBOBS_API_MAJOR_VER  0 /* 0 means development, anything can break */
+#define LIBOBS_API_MAJOR_VER  18
 
 /*
  * Increment if backward-compatible additions
  *
  * Reset to zero each major version
  */
-#define LIBOBS_API_MINOR_VER  16
+#define LIBOBS_API_MINOR_VER  0
 
 /*
  * Increment if backward-compatible bug fix
  *
  * Reset to zero each major or minor version
  */
-#define LIBOBS_API_PATCH_VER  2
+#define LIBOBS_API_PATCH_VER  1
 
 #define MAKE_SEMANTIC_VERSION(major, minor, patch) \
                              ((major << 24) | \
diff --git a/libobs/obs-display.c b/libobs/obs-display.c
index 2226afc..f5d01ab 100644
--- a/libobs/obs-display.c
+++ b/libobs/obs-display.c
@@ -23,6 +23,7 @@ bool obs_display_init(struct obs_display *display,
 		const struct gs_init_data *graphics_data)
 {
 	pthread_mutex_init_value(&display->draw_callbacks_mutex);
+	pthread_mutex_init_value(&display->draw_info_mutex);
 
 	if (graphics_data) {
 		display->swap = gs_swapchain_create(graphics_data);
@@ -40,6 +41,10 @@ bool obs_display_init(struct obs_display *display,
 		blog(LOG_ERROR, "obs_display_init: Failed to create mutex");
 		return false;
 	}
+	if (pthread_mutex_init(&display->draw_info_mutex, NULL) != 0) {
+		blog(LOG_ERROR, "obs_display_init: Failed to create mutex");
+		return false;
+	}
 
 	display->background_color = 0x4C4C4C;
 	display->enabled = true;
@@ -73,6 +78,7 @@ obs_display_t *obs_display_create(const struct gs_init_data *graphics_data)
 void obs_display_free(obs_display_t *display)
 {
 	pthread_mutex_destroy(&display->draw_callbacks_mutex);
+	pthread_mutex_destroy(&display->draw_info_mutex);
 	da_free(display->draw_callbacks);
 
 	if (display->swap) {
@@ -103,13 +109,13 @@ void obs_display_resize(obs_display_t *display, uint32_t cx, uint32_t cy)
 {
 	if (!display) return;
 
-	pthread_mutex_lock(&display->draw_callbacks_mutex);
+	pthread_mutex_lock(&display->draw_info_mutex);
 
 	display->cx = cx;
 	display->cy = cy;
 	display->size_changed = true;
 
-	pthread_mutex_unlock(&display->draw_callbacks_mutex);
+	pthread_mutex_unlock(&display->draw_info_mutex);
 }
 
 void obs_display_add_draw_callback(obs_display_t *display,
@@ -138,16 +144,15 @@ void obs_display_remove_draw_callback(obs_display_t *display,
 	pthread_mutex_unlock(&display->draw_callbacks_mutex);
 }
 
-static inline void render_display_begin(struct obs_display *display)
+static inline void render_display_begin(struct obs_display *display,
+		uint32_t cx, uint32_t cy, bool size_changed)
 {
 	struct vec4 clear_color;
 
-	gs_load_swapchain(display ? display->swap : NULL);
+	gs_load_swapchain(display->swap);
 
-	if (display->size_changed) {
-		gs_resize(display->cx, display->cy);
-		display->size_changed = false;
-	}
+	if (size_changed)
+		gs_resize(cx, cy);
 
 	gs_begin_scene();
 
@@ -161,9 +166,8 @@ static inline void render_display_begin(struct obs_display *display)
 	/* gs_enable_blending(false); */
 	gs_set_cull_mode(GS_NEITHER);
 
-	gs_ortho(0.0f, (float)display->cx,
-			0.0f, (float)display->cy, -100.0f, 100.0f);
-	gs_set_viewport(0, 0, display->cx, display->cy);
+	gs_ortho(0.0f, (float)cx, 0.0f, (float)cy, -100.0f, 100.0f);
+	gs_set_viewport(0, 0, cx, cy);
 }
 
 static inline void render_display_end()
@@ -174,9 +178,27 @@ static inline void render_display_end()
 
 void render_display(struct obs_display *display)
 {
+	uint32_t cx, cy;
+	bool size_changed;
+
 	if (!display || !display->enabled) return;
 
-	render_display_begin(display);
+	/* -------------------------------------------- */
+
+	pthread_mutex_lock(&display->draw_info_mutex);
+
+	cx = display->cx;
+	cy = display->cy;
+	size_changed = display->size_changed;
+
+	if (size_changed)
+		display->size_changed = false;
+
+	pthread_mutex_unlock(&display->draw_info_mutex);
+
+	/* -------------------------------------------- */
+
+	render_display_begin(display, cx, cy, size_changed);
 
 	pthread_mutex_lock(&display->draw_callbacks_mutex);
 
@@ -184,7 +206,7 @@ void render_display(struct obs_display *display)
 		struct draw_callback *callback;
 		callback = display->draw_callbacks.array+i;
 
-		callback->draw(callback->param, display->cx, display->cy);
+		callback->draw(callback->param, cx, cy);
 	}
 
 	pthread_mutex_unlock(&display->draw_callbacks_mutex);
diff --git a/libobs/obs-encoder.c b/libobs/obs-encoder.c
index e1ce46f..4fd84bb 100644
--- a/libobs/obs-encoder.c
+++ b/libobs/obs-encoder.c
@@ -796,7 +796,7 @@ static inline void do_encode(struct obs_encoder *encoder,
 		full_stop(encoder);
 		blog(LOG_ERROR, "Error encoding with encoder '%s'",
 				encoder->context.name);
-		return;
+		goto error;
 	}
 
 	if (received) {
@@ -822,6 +822,7 @@ static inline void do_encode(struct obs_encoder *encoder,
 		pthread_mutex_unlock(&encoder->callbacks_mutex);
 	}
 
+error:
 	profile_end(do_encode_name);
 }
 
@@ -1034,17 +1035,55 @@ void obs_encoder_remove_output(struct obs_encoder *encoder,
 	pthread_mutex_unlock(&encoder->outputs_mutex);
 }
 
-void obs_duplicate_encoder_packet(struct encoder_packet *dst,
+void obs_encoder_packet_create_instance(struct encoder_packet *dst,
 		const struct encoder_packet *src)
 {
+	long *p_refs;
+
 	*dst = *src;
-	dst->data = bmemdup(src->data, src->size);
+	p_refs = bmalloc(src->size + sizeof(long));
+	dst->data = (void*)(p_refs + 1);
+	*p_refs = 1;
+	memcpy(dst->data, src->data, src->size);
+}
+
+void obs_duplicate_encoder_packet(struct encoder_packet *dst,
+		const struct encoder_packet *src)
+{
+	obs_encoder_packet_create_instance(dst, src);
 }
 
 void obs_free_encoder_packet(struct encoder_packet *packet)
 {
-	bfree(packet->data);
-	memset(packet, 0, sizeof(struct encoder_packet));
+	obs_encoder_packet_release(packet);
+}
+
+void obs_encoder_packet_ref(struct encoder_packet *dst,
+		struct encoder_packet *src)
+{
+	if (!src)
+		return;
+
+	if (src->data) {
+		long *p_refs = ((long*)src->data) - 1;
+		os_atomic_inc_long(p_refs);
+	}
+
+	*dst = *src;
+}
+
+void obs_encoder_packet_release(struct encoder_packet *pkt)
+{
+	if (!pkt)
+		return;
+
+	if (pkt->data) {
+		long *p_refs = ((long*)pkt->data) - 1;
+		if (os_atomic_dec_long(p_refs) == 0)
+			bfree(p_refs);
+	}
+
+	memset(pkt, 0, sizeof(struct encoder_packet));
 }
 
 void obs_encoder_set_preferred_video_format(obs_encoder_t *encoder,
diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h
index 07d720b..f6f2450 100644
--- a/libobs/obs-internal.h
+++ b/libobs/obs-internal.h
@@ -199,6 +199,7 @@ struct obs_display {
 	uint32_t                        background_color;
 	gs_swapchain_t                  *swap;
 	pthread_mutex_t                 draw_callbacks_mutex;
+	pthread_mutex_t                 draw_info_mutex;
 	DARRAY(struct draw_callback)    draw_callbacks;
 
 	struct obs_display              *next;
@@ -276,8 +277,9 @@ struct obs_core_video {
 	gs_effect_t                     *deinterlace_yadif_2x_effect;
 };
 
+struct audio_monitor;
+
 struct obs_core_audio {
-	/* TODO: sound output subsystem */
 	audio_t                         *audio;
 
 	DARRAY(struct obs_source*)      render_order;
@@ -289,6 +291,11 @@ struct obs_core_audio {
 	int                             total_buffering_ticks;
 
 	float                           user_volume;
+
+	pthread_mutex_t                 monitoring_mutex;
+	DARRAY(struct audio_monitor*)   monitors;
+	char                            *monitoring_device_name;
+	char                            *monitoring_device_id;
 };
 
 /* user sources, output channels, and displays */
@@ -545,6 +552,7 @@ struct obs_source {
 	volatile bool                   timing_set;
 	volatile uint64_t               timing_adjust;
 	uint64_t                        resample_offset;
+	uint64_t                        last_audio_ts;
 	uint64_t                        next_audio_ts_min;
 	uint64_t                        next_audio_sys_ts_min;
 	uint64_t                        last_frame_ts;
@@ -593,6 +601,7 @@ struct obs_source {
 	int                             async_plane_offset[2];
 	bool                            async_flip;
 	bool                            async_active;
+	bool                            async_update_texture;
 	DARRAY(struct async_frame)      async_cache;
 	DARRAY(struct obs_source_frame*)async_frames;
 	pthread_mutex_t                 async_mutex;
@@ -659,6 +668,9 @@ struct obs_source {
 	enum obs_transition_mode        transition_mode;
 	enum obs_transition_scale_type  transition_scale_type;
 	struct matrix4                  transition_matrices[2];
+
+	struct audio_monitor            *monitor;
+	enum obs_monitoring_type        monitoring_type;
 };
 
 extern const struct obs_source_info *get_source_info(const char *id);
@@ -677,6 +689,10 @@ extern void obs_transition_enum_sources(obs_source_t *transition,
 extern void obs_transition_save(obs_source_t *source, obs_data_t *data);
 extern void obs_transition_load(obs_source_t *source, obs_data_t *data);
 
+struct audio_monitor *audio_monitor_create(obs_source_t *source);
+void audio_monitor_reset(struct audio_monitor *monitor);
+extern void audio_monitor_destroy(struct audio_monitor *monitor);
+
 extern void obs_source_destroy(struct obs_source *source);
 
 enum view_type {
@@ -717,8 +733,6 @@ static inline enum gs_color_format convert_video_format(
 		return GS_RGBA;
 	else if (format == VIDEO_FORMAT_BGRA)
 		return GS_BGRA;
-	else if (format == VIDEO_FORMAT_Y800)
-		return GS_R8;
 
 	return GS_BGRX;
 }
@@ -773,6 +787,13 @@ struct obs_weak_output {
 	struct obs_output *output;
 };
 
+#define CAPTION_LINE_CHARS (32)
+#define CAPTION_LINE_BYTES (4*CAPTION_LINE_CHARS)
+struct caption_text {
+	char text[CAPTION_LINE_BYTES+1];
+	struct caption_text *next;
+};
+
 struct obs_output {
 	struct obs_context_data         context;
 	struct obs_output_info          info;
@@ -827,6 +848,11 @@ struct obs_output {
 	struct video_scale_info         video_conversion;
 	struct audio_convert_info       audio_conversion;
 
+	pthread_mutex_t                 caption_mutex;
+	double                          caption_timestamp;
+	struct caption_text             *caption_head;
+	struct caption_text             *caption_tail;
+
 	bool                            valid;
 
 	uint64_t                        active_delay_ns;
@@ -863,6 +889,8 @@ extern const struct obs_output_info *find_output(const char *id);
 extern void obs_output_remove_encoder(struct obs_output *output,
 		struct obs_encoder *encoder);
 
+extern void obs_encoder_packet_create_instance(struct encoder_packet *dst,
+		const struct encoder_packet *src);
 void obs_output_destroy(obs_output_t *output);
 
 
diff --git a/libobs/obs-output-delay.c b/libobs/obs-output-delay.c
index 2bcc6bb..cfd3c57 100644
--- a/libobs/obs-output-delay.c
+++ b/libobs/obs-output-delay.c
@@ -35,7 +35,7 @@ static inline void push_packet(struct obs_output *output,
 
 	dd.msg = DELAY_MSG_PACKET;
 	dd.ts  = t;
-	obs_duplicate_encoder_packet(&dd.packet, packet);
+	obs_encoder_packet_create_instance(&dd.packet, packet);
 
 	pthread_mutex_lock(&output->delay_mutex);
 	circlebuf_push_back(&output->delay_data, &dd, sizeof(dd));
@@ -48,7 +48,7 @@ static inline void process_delay_data(struct obs_output *output,
 	switch (dd->msg) {
 	case DELAY_MSG_PACKET:
 		if (!delay_active(output) || !delay_capturing(output))
-			obs_free_encoder_packet(&dd->packet);
+			obs_encoder_packet_release(&dd->packet);
 		else
 			output->delay_callback(output, &dd->packet);
 		break;
@@ -68,7 +68,7 @@ void obs_output_cleanup_delay(obs_output_t *output)
 	while (output->delay_data.size) {
 		circlebuf_pop_front(&output->delay_data, &dd, sizeof(dd));
 		if (dd.msg == DELAY_MSG_PACKET) {
-			obs_free_encoder_packet(&dd.packet);
+			obs_encoder_packet_release(&dd.packet);
 		}
 	}
 
diff --git a/libobs/obs-output.c b/libobs/obs-output.c
index db84cd6..0d73665 100644
--- a/libobs/obs-output.c
+++ b/libobs/obs-output.c
@@ -20,6 +20,11 @@
 #include "obs.h"
 #include "obs-internal.h"
 
+#if BUILD_CAPTIONS
+#include <caption/caption.h>
+#include <caption/avc.h>
+#endif
+
 static inline bool active(const struct obs_output *output)
 {
 	return os_atomic_load_bool(&output->active);
@@ -99,11 +104,14 @@ obs_output_t *obs_output_create(const char *id, const char *name,
 	output = bzalloc(sizeof(struct obs_output));
 	pthread_mutex_init_value(&output->interleaved_mutex);
 	pthread_mutex_init_value(&output->delay_mutex);
+	pthread_mutex_init_value(&output->caption_mutex);
 
 	if (pthread_mutex_init(&output->interleaved_mutex, NULL) != 0)
 		goto fail;
 	if (pthread_mutex_init(&output->delay_mutex, NULL) != 0)
 		goto fail;
+	if (pthread_mutex_init(&output->caption_mutex, NULL) != 0)
+		goto fail;
 	if (os_event_init(&output->stopping_event, OS_EVENT_TYPE_MANUAL) != 0)
 		goto fail;
 	if (!init_output_handlers(output, name, settings, hotkey_data))
@@ -129,12 +137,6 @@ obs_output_t *obs_output_create(const char *id, const char *name,
 	if (ret < 0)
 		goto fail;
 
-	if (info)
-		output->context.data = info->create(output->context.settings,
-				output);
-	if (!output->context.data)
-		blog(LOG_ERROR, "Failed to create output '%s'!", name);
-
 	output->reconnect_retry_sec = 2;
 	output->reconnect_retry_max = 20;
 	output->valid               = true;
@@ -146,6 +148,12 @@ obs_output_t *obs_output_create(const char *id, const char *name,
 			&obs->data.outputs_mutex,
 			&obs->data.first_output);
 
+	if (info)
+		output->context.data = info->create(output->context.settings,
+				output);
+	if (!output->context.data)
+		blog(LOG_ERROR, "Failed to create output '%s'!", name);
+
 	blog(LOG_DEBUG, "output '%s' (%s) created", name, id);
 	return output;
 
@@ -157,7 +165,7 @@ fail:
 static inline void free_packets(struct obs_output *output)
 {
 	for (size_t i = 0; i < output->interleaved_packets.num; i++)
-		obs_free_encoder_packet(output->interleaved_packets.array+i);
+		obs_encoder_packet_release(output->interleaved_packets.array+i);
 	da_free(output->interleaved_packets);
 }
 
@@ -196,6 +204,7 @@ void obs_output_destroy(obs_output_t *output)
 		}
 
 		os_event_destroy(output->stopping_event);
+		pthread_mutex_destroy(&output->caption_mutex);
 		pthread_mutex_destroy(&output->interleaved_mutex);
 		pthread_mutex_destroy(&output->delay_mutex);
 		os_event_destroy(output->reconnect_stop_event);
@@ -235,6 +244,7 @@ bool obs_output_actual_start(obs_output_t *output)
 	if (os_atomic_load_long(&output->delay_restart_refs))
 		os_atomic_dec_long(&output->delay_restart_refs);
 
+	output->caption_timestamp = 0;
 	return success;
 }
 
@@ -356,6 +366,12 @@ void obs_output_actual_stop(obs_output_t *output, bool force, uint64_t ts)
 		signal_stop(output);
 		os_event_signal(output->stopping_event);
 	}
+
+	while (output->caption_head) {
+		output->caption_tail = output->caption_head->next;
+		bfree(output->caption_head);
+		output->caption_head = output->caption_tail;
+	}
 }
 
 void obs_output_stop(obs_output_t *output)
@@ -942,6 +958,56 @@ static inline bool has_higher_opposing_ts(struct obs_output *output,
 		return output->highest_video_ts > packet->dts_usec;
 }
 
+#if BUILD_CAPTIONS
+static const uint8_t nal_start[4] = {0, 0, 0, 1};
+
+static bool add_caption(struct obs_output *output, struct encoder_packet *out)
+{
+	struct encoder_packet backup = *out;
+	caption_frame_t cf;
+	sei_t sei;
+	uint8_t *data;
+	size_t size;
+	long ref = 1;
+
+	DARRAY(uint8_t) out_data;
+
+	if (out->priority > 1)
+		return false;
+
+	sei_init(&sei);
+
+	da_init(out_data);
+	da_push_back_array(out_data, &ref, sizeof(ref));
+	da_push_back_array(out_data, out->data, out->size);
+
+	caption_frame_init(&cf);
+	caption_frame_from_text(&cf, &output->caption_head->text[0]);
+
+	sei_from_caption_frame(&sei, &cf);
+
+	data = malloc(sei_render_size(&sei));
+	size = sei_render(&sei, data);
+	/* TODO SEI should come after AUD/SPS/PPS, but before any VCL */
+	da_push_back_array(out_data, nal_start, 4);
+	da_push_back_array(out_data, data, size);
+	free(data);
+
+	obs_encoder_packet_release(out);
+
+	*out = backup;
+	out->data = (uint8_t*)out_data.array + sizeof(ref);
+	out->size = out_data.num - sizeof(ref);
+
+	sei_free(&sei);
+
+	struct caption_text *next = output->caption_head->next;
+	bfree(output->caption_head);
+	output->caption_head = next;
+	return true;
+}
+#endif
+
 static inline void send_interleaved(struct obs_output *output)
 {
 	struct encoder_packet out = output->interleaved_packets.array[0];
@@ -952,12 +1018,37 @@ static inline void send_interleaved(struct obs_output *output)
 	if (!has_higher_opposing_ts(output, &out))
 		return;
 
-	if (out.type == OBS_ENCODER_VIDEO)
+	da_erase(output->interleaved_packets, 0);
+
+	if (out.type == OBS_ENCODER_VIDEO) {
 		output->total_frames++;
 
-	da_erase(output->interleaved_packets, 0);
+#if BUILD_CAPTIONS
+		pthread_mutex_lock(&output->caption_mutex);
+
+		double frame_timestamp = (out.pts * out.timebase_num) /
+			(double)out.timebase_den;
+
+		/* TODO if output->caption_timestamp is more than 5 seconds
+		 * old, send empty frame */
+		if (output->caption_head &&
+		    output->caption_timestamp <= frame_timestamp) {
+			blog(LOG_INFO,"Sending caption: %f \"%s\"",
+					frame_timestamp,
+					&output->caption_head->text[0]);
+
+			if (add_caption(output, &out)) {
+				output->caption_timestamp =
+					frame_timestamp + 2.0;
+			}
+		}
+
+		pthread_mutex_unlock(&output->caption_mutex);
+#endif
+	}
+
 	output->info.encoded_packet(output->context.data, &out);
-	obs_free_encoder_packet(&out);
+	obs_encoder_packet_release(&out);
 }
 
 static inline void set_higher_ts(struct obs_output *output,
@@ -1056,7 +1147,7 @@ static void discard_to_idx(struct obs_output *output, size_t idx)
 	for (size_t i = 0; i < idx; i++) {
 		struct encoder_packet *packet =
 			&output->interleaved_packets.array[i];
-		obs_free_encoder_packet(packet);
+		obs_encoder_packet_release(packet);
 	}
 
 	da_erase_range(output->interleaved_packets, 0, idx);
@@ -1304,7 +1395,7 @@ static void interleave_packets(void *data, struct encoder_packet *packet)
 		pthread_mutex_unlock(&output->interleaved_mutex);
 
 		if (output->active_delay_ns)
-			obs_free_encoder_packet(packet);
+			obs_encoder_packet_release(packet);
 		return;
 	}
 
@@ -1313,7 +1404,7 @@ static void interleave_packets(void *data, struct encoder_packet *packet)
 	if (output->active_delay_ns)
 		out = *packet;
 	else
-		obs_duplicate_encoder_packet(&out, packet);
+		obs_encoder_packet_create_instance(&out, packet);
 
 	if (was_started)
 		apply_interleaved_packet_offset(output, &out);
@@ -1356,7 +1447,7 @@ static void default_encoded_callback(void *param, struct encoder_packet *packet)
 	}
 
 	if (output->active_delay_ns)
-		obs_free_encoder_packet(packet);
+		obs_encoder_packet_release(packet);
 }
 
 static void default_raw_video_callback(void *param, struct video_data *frame)
@@ -1954,3 +2045,75 @@ const char *obs_output_get_id(const obs_output_t *output)
 	return obs_output_valid(output, "obs_output_get_id")
 		? output->info.id : NULL;
 }
+
+#if BUILD_CAPTIONS
+static struct caption_text *caption_text_new(const char *text, size_t bytes,
+		struct caption_text *tail, struct caption_text **head)
+{
+	struct caption_text *next = bzalloc(sizeof(struct caption_text));
+	snprintf(&next->text[0], CAPTION_LINE_BYTES + 1, "%.*s", bytes, text);
+
+	if (!*head) {
+		*head = next;
+	} else {
+		tail->next = next;
+	}
+
+	return next;
+}
+
+void obs_output_output_caption_text1(obs_output_t *output, const char *text)
+{
+	if (!obs_output_valid(output, "obs_output_output_caption_text1"))
+		return;
+	if (!active(output))
+		return;
+
+	// split text into  32 charcter strings
+	int size = (int)strlen(text);
+	int r;
+	size_t char_count;
+	size_t line_length = 0;
+	size_t trimmed_length = 0;
+
+	blog(LOG_DEBUG, "Caption text: %s", text);
+
+	pthread_mutex_lock(&output->caption_mutex);
+
+	for (r = 0 ; 0 < size && CAPTION_LINE_CHARS > r; ++r) {
+		line_length = utf8_line_length(text);
+		trimmed_length = utf8_trimmed_length(text, line_length);
+		char_count = utf8_char_count(text, trimmed_length);
+
+		if (SCREEN_COLS < char_count) {
+			char_count = utf8_wrap_length(text, CAPTION_LINE_CHARS);
+			line_length = utf8_string_length(text, char_count + 1);
+		}
+
+		output->caption_tail = caption_text_new(
+				text,
+				line_length,
+				output->caption_tail,
+				&output->caption_head);
+
+		text += line_length;
+		size -= (int)line_length;
+	}
+
+	pthread_mutex_unlock(&output->caption_mutex);
+}
+#endif
+
+float obs_output_get_congestion(obs_output_t *output)
+{
+	if (!obs_output_valid(output, "obs_output_get_congestion"))
+		return 0;
+
+	if (output->info.get_congestion) {
+		float val = output->info.get_congestion(output->context.data);
+		if (val < 0.0f) val = 0.0f;
+		else if (val > 1.0f) val = 1.0f;
+		return val;
+	}
+	return 0;
+}
diff --git a/libobs/obs-output.h b/libobs/obs-output.h
index 1b42530..9d00108 100644
--- a/libobs/obs-output.h
+++ b/libobs/obs-output.h
@@ -64,6 +64,8 @@ struct obs_output_info {
 
 	void *type_data;
 	void (*free_type_data)(void *type_data);
+
+	float (*get_congestion)(void *data);
 };
 
 EXPORT void obs_register_output_s(const struct obs_output_info *info,
diff --git a/libobs/obs-properties.c b/libobs/obs-properties.c
index 1533bee..6f6b2fc 100644
--- a/libobs/obs-properties.c
+++ b/libobs/obs-properties.c
@@ -551,7 +551,7 @@ static inline struct list_data *get_list_fmt_data(struct obs_property *p,
 		enum obs_combo_format format)
 {
 	struct list_data *data = get_list_data(p);
-	return (data->format == format) ? data : NULL;
+	return (data && data->format == format) ? data : NULL;
 }
 
 /* ------------------------------------------------------------------------- */
diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c
index d12eabc..28babb3 100644
--- a/libobs/obs-scene.c
+++ b/libobs/obs-scene.c
@@ -162,7 +162,7 @@ static void scene_destroy(void *data)
 
 static void scene_enum_sources(void *data,
 		obs_source_enum_proc_t enum_callback,
-		void *param)
+		void *param, bool active)
 {
 	struct obs_scene *scene = data;
 	struct obs_scene_item *item;
@@ -175,7 +175,7 @@ static void scene_enum_sources(void *data,
 		next = item->next;
 
 		obs_sceneitem_addref(item);
-		if (os_atomic_load_long(&item->active_refs) > 0)
+		if (!active || os_atomic_load_long(&item->active_refs) > 0)
 			enum_callback(scene->source, item->source, param);
 		obs_sceneitem_release(item);
 
@@ -185,6 +185,20 @@ static void scene_enum_sources(void *data,
 	full_unlock(scene);
 }
 
+static void scene_enum_active_sources(void *data,
+		obs_source_enum_proc_t enum_callback,
+		void *param)
+{
+	scene_enum_sources(data, enum_callback, param, true);
+}
+
+static void scene_enum_all_sources(void *data,
+		obs_source_enum_proc_t enum_callback,
+		void *param)
+{
+	scene_enum_sources(data, enum_callback, param, false);
+}
+
 static inline void detach_sceneitem(struct obs_scene_item *item)
 {
 	if (item->prev)
@@ -741,11 +755,13 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item,
 	bool cur_visible = item->visible;
 	uint64_t frame_num = 0;
 	size_t deref_count = 0;
-	float *buf;
+	float *buf = NULL;
 
-	if (!*p_buf)
-		*p_buf = malloc(AUDIO_OUTPUT_FRAMES * sizeof(float));
-	buf = *p_buf;
+	if (p_buf) {
+		if (!*p_buf)
+			*p_buf = malloc(AUDIO_OUTPUT_FRAMES * sizeof(float));
+		buf = *p_buf;
+	}
 
 	pthread_mutex_lock(&item->actions_mutex);
 
@@ -760,7 +776,7 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item,
 		new_frame_num = (timestamp - ts) * (uint64_t)sample_rate /
 			1000000000ULL;
 
-		if (new_frame_num >= AUDIO_OUTPUT_FRAMES)
+		if (ts && new_frame_num >= AUDIO_OUTPUT_FRAMES)
 			break;
 
 		da_erase(item->audio_actions, i--);
@@ -769,7 +785,7 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item,
 		if (!item->visible)
 			deref_count++;
 
-		if (new_frame_num > frame_num) {
+		if (buf && new_frame_num > frame_num) {
 			for (; frame_num < new_frame_num; frame_num++)
 				buf[frame_num] = cur_visible ? 1.0f : 0.0f;
 		}
@@ -777,8 +793,10 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item,
 		cur_visible = item->visible;
 	}
 
-	for (; frame_num < AUDIO_OUTPUT_FRAMES; frame_num++)
-		buf[frame_num] = cur_visible ? 1.0f : 0.0f;
+	if (buf) {
+		for (; frame_num < AUDIO_OUTPUT_FRAMES; frame_num++)
+			buf[frame_num] = cur_visible ? 1.0f : 0.0f;
+	}
 
 	pthread_mutex_unlock(&item->actions_mutex);
 
@@ -790,7 +808,7 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item,
 	}
 }
 
-static inline bool apply_scene_item_volume(struct obs_scene_item *item,
+static bool apply_scene_item_volume(struct obs_scene_item *item,
 		float **buf, uint64_t ts, size_t sample_rate)
 {
 	bool actions_pending;
@@ -808,7 +826,7 @@ static inline bool apply_scene_item_volume(struct obs_scene_item *item,
 		uint64_t duration = (uint64_t)AUDIO_OUTPUT_FRAMES *
 			1000000000ULL / (uint64_t)sample_rate;
 
-		if (action.timestamp < (ts + duration)) {
+		if (!ts || action.timestamp < (ts + duration)) {
 			apply_scene_item_audio_actions(item, buf, ts,
 					sample_rate);
 			return true;
@@ -818,6 +836,12 @@ static inline bool apply_scene_item_volume(struct obs_scene_item *item,
 	return false;
 }
 
+static void process_all_audio_actions(struct obs_scene_item *item,
+		size_t sample_rate)
+{
+	while (apply_scene_item_volume(item, NULL, 0, sample_rate));
+}
+
 static void mix_audio_with_buf(float *p_out, float *p_in, float *buf_in,
 		size_t pos, size_t count)
 {
@@ -859,7 +883,7 @@ static bool scene_audio_render(void *data, uint64_t *ts_out,
 			uint64_t source_ts =
 				obs_source_get_audio_timestamp(item->source);
 
-			if (!timestamp || source_ts < timestamp)
+			if (source_ts && (!timestamp || source_ts < timestamp))
 				timestamp = source_ts;
 		}
 
@@ -867,6 +891,14 @@ static bool scene_audio_render(void *data, uint64_t *ts_out,
 	}
 
 	if (!timestamp) {
+		/* just process all pending audio actions if no audio playing,
+		 * otherwise audio actions will just never be processed */
+		item = scene->first_item;
+		while (item) {
+			process_all_audio_actions(item, sample_rate);
+			item = item->next;
+		}
+
 		audio_unlock(scene);
 		return false;
 	}
@@ -886,6 +918,11 @@ static bool scene_audio_render(void *data, uint64_t *ts_out,
 		}
 
 		source_ts = obs_source_get_audio_timestamp(item->source);
+		if (!source_ts) {
+			item = item->next;
+			continue;
+		}
+
 		pos = (size_t)ns_to_audio_frames(sample_rate,
 				source_ts - timestamp);
 		count = AUDIO_OUTPUT_FRAMES - pos;
@@ -939,7 +976,8 @@ const struct obs_source_info scene_info =
 	.get_height    = scene_getheight,
 	.load          = scene_load,
 	.save          = scene_save,
-	.enum_active_sources = scene_enum_sources
+	.enum_active_sources = scene_enum_active_sources,
+	.enum_all_sources = scene_enum_all_sources
 };
 
 obs_scene_t *obs_scene_create(const char *name)
@@ -1054,6 +1092,8 @@ obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name,
 			new_item->align = item->align;
 			new_item->last_width = item->last_width;
 			new_item->last_height = item->last_height;
+			new_item->output_scale = item->output_scale;
+			new_item->scale_filter = item->scale_filter;
 			new_item->box_transform = item->box_transform;
 			new_item->draw_transform = item->draw_transform;
 			new_item->bounds_type = item->bounds_type;
@@ -1360,8 +1400,7 @@ void obs_sceneitem_remove(obs_sceneitem_t *item)
 
 	scene = item->parent;
 
-	if (scene)
-		full_lock(scene);
+	full_lock(scene);
 
 	if (item->removed) {
 		if (scene)
diff --git a/libobs/obs-source-deinterlace.c b/libobs/obs-source-deinterlace.c
index 319a1be..c655405 100644
--- a/libobs/obs-source-deinterlace.c
+++ b/libobs/obs-source-deinterlace.c
@@ -37,6 +37,7 @@ static bool ready_deinterlace_frames(obs_source_t *source, uint64_t sys_time)
 		if (source->async_frames.num == 2)
 			source->async_frames.array[0]->prev_frame = true;
 		source->deinterlace_offset = 0;
+		source->last_frame_ts = next_frame->timestamp;
 		return true;
 	}
 
diff --git a/libobs/obs-source.c b/libobs/obs-source.c
index 044e688..4b3539a 100644
--- a/libobs/obs-source.c
+++ b/libobs/obs-source.c
@@ -174,7 +174,7 @@ bool obs_source_init(struct obs_source *source)
 	source->control = bzalloc(sizeof(obs_weak_source_t));
 	source->deinterlace_top_first = true;
 	source->control->source = source;
-	source->audio_mixers = 0xF;
+	source->audio_mixers = 0xFF;
 
 	if (is_audio_source(source)) {
 		pthread_mutex_lock(&obs->data.audio_sources_mutex);
@@ -410,7 +410,9 @@ obs_source_t *obs_source_duplicate(obs_source_t *source,
 		obs_scene_t *new_scene = obs_scene_duplicate(scene, new_name,
 				create_private ? OBS_SCENE_DUP_PRIVATE_COPY :
 					OBS_SCENE_DUP_COPY);
-		return obs_scene_get_source(new_scene);
+		obs_source_t *new_source = obs_scene_get_source(new_scene);
+		duplicate_filters(new_source, source, create_private);
+		return new_source;
 	}
 
 	settings = obs_data_create();
@@ -501,6 +503,8 @@ void obs_source_destroy(struct obs_source *source)
 		source->context.data = NULL;
 	}
 
+	audio_monitor_destroy(source->monitor);
+
 	obs_hotkey_unregister(source->push_to_talk_key);
 	obs_hotkey_unregister(source->push_to_mute_key);
 	obs_hotkey_pair_unregister(source->mute_unmute_key);
@@ -919,6 +923,35 @@ void obs_source_deactivate(obs_source_t *source, enum view_type type)
 
 static inline struct obs_source_frame *get_closest_frame(obs_source_t *source,
 		uint64_t sys_time);
+bool set_async_texture_size(struct obs_source *source,
+		const struct obs_source_frame *frame);
+
+static void async_tick(obs_source_t *source)
+{
+	uint64_t sys_time = obs->video.video_time;
+
+	pthread_mutex_lock(&source->async_mutex);
+
+	if (deinterlacing_enabled(source)) {
+		deinterlace_process_last_frame(source, sys_time);
+	} else {
+		if (source->cur_async_frame) {
+			remove_async_frame(source,
+					source->cur_async_frame);
+			source->cur_async_frame = NULL;
+		}
+
+		source->cur_async_frame = get_closest_frame(source,
+				sys_time);
+	}
+
+	source->last_sys_timestamp = sys_time;
+	pthread_mutex_unlock(&source->async_mutex);
+
+	if (source->cur_async_frame)
+		source->async_update_texture = set_async_texture_size(source,
+				source->cur_async_frame);
+}
 
 void obs_source_video_tick(obs_source_t *source, float seconds)
 {
@@ -930,27 +963,8 @@ void obs_source_video_tick(obs_source_t *source, float seconds)
 	if (source->info.type == OBS_SOURCE_TYPE_TRANSITION)
 		obs_transition_tick(source);
 
-	if ((source->info.output_flags & OBS_SOURCE_ASYNC) != 0) {
-		uint64_t sys_time = obs->video.video_time;
-
-		pthread_mutex_lock(&source->async_mutex);
-
-		if (deinterlacing_enabled(source)) {
-			deinterlace_process_last_frame(source, sys_time);
-		} else {
-			if (source->cur_async_frame) {
-				remove_async_frame(source,
-						source->cur_async_frame);
-				source->cur_async_frame = NULL;
-			}
-
-			source->cur_async_frame = get_closest_frame(source,
-					sys_time);
-		}
-
-		source->last_sys_timestamp = sys_time;
-		pthread_mutex_unlock(&source->async_mutex);
-	}
+	if ((source->info.output_flags & OBS_SOURCE_ASYNC) != 0)
+		async_tick(source);
 
 	if (source->defer_update)
 		obs_source_deferred_update(source);
@@ -1038,7 +1052,7 @@ static void handle_ts_jump(obs_source_t *source, uint64_t expected,
 }
 
 static void source_signal_audio_data(obs_source_t *source,
-		struct audio_data *in, bool muted)
+		const struct audio_data *in, bool muted)
 {
 	pthread_mutex_lock(&source->audio_cb_mutex);
 
@@ -1172,6 +1186,7 @@ static void source_output_audio_data(obs_source_t *source,
 			in.timestamp = source->next_audio_ts_min;
 	}
 
+	source->last_audio_ts = in.timestamp;
 	source->next_audio_ts_min = in.timestamp +
 		conv_frames_to_time(sample_rate, in.frames);
 
@@ -1214,14 +1229,16 @@ static void source_output_audio_data(obs_source_t *source,
 		source->last_sync_offset = sync_offset;
 	}
 
-	if (push_back && source->audio_ts)
-		source_output_audio_push_back(source, &in);
-	else
-		source_output_audio_place(source, &in);
+	if (source->monitoring_type != OBS_MONITORING_TYPE_MONITOR_ONLY) {
+		if (push_back && source->audio_ts)
+			source_output_audio_push_back(source, &in);
+		else
+			source_output_audio_place(source, &in);
+	}
 
 	pthread_mutex_unlock(&source->audio_buf_mutex);
 
-	source_signal_audio_data(source, &in, source_muted(source, os_time));
+	source_signal_audio_data(source, data, source_muted(source, os_time));
 }
 
 enum convert_type {
@@ -1331,6 +1348,8 @@ bool set_async_texture_size(struct obs_source *source,
 	source->async_height = frame->height;
 	source->async_format = frame->format;
 
+	gs_enter_context(obs->video.graphics);
+
 	gs_texture_destroy(source->async_texture);
 	gs_texture_destroy(source->async_prev_texture);
 	gs_texrender_destroy(source->async_texrender);
@@ -1365,6 +1384,8 @@ bool set_async_texture_size(struct obs_source *source,
 	if (deinterlacing_enabled(source))
 		set_deinterlace_texture_size(source);
 
+	gs_leave_context();
+
 	return !!source->async_texture;
 }
 
@@ -1612,10 +1633,11 @@ static void obs_source_update_async_video(obs_source_t *source)
 				os_gettime_ns() - frame->timestamp;
 			source->timing_set = true;
 
-			if (set_async_texture_size(source, frame)) {
+			if (source->async_update_texture) {
 				update_async_texture(source, frame,
 						source->async_texture,
 						source->async_texrender);
+				source->async_update_texture = false;
 			}
 
 			obs_source_release_frame(source, frame);
@@ -1862,10 +1884,9 @@ void obs_source_filter_add(obs_source_t *source, obs_source_t *filter)
 
 	signal_handler_signal(source->context.signals, "filter_add", &cd);
 
-	if (source && filter)
-		blog(LOG_DEBUG, "- filter '%s' (%s) added to source '%s'",
-				filter->context.name, filter->info.id,
-				source->context.name);
+	blog(LOG_DEBUG, "- filter '%s' (%s) added to source '%s'",
+			filter->context.name, filter->info.id,
+			source->context.name);
 }
 
 static bool obs_source_filter_remove_refless(obs_source_t *source,
@@ -1898,10 +1919,9 @@ static bool obs_source_filter_remove_refless(obs_source_t *source,
 
 	signal_handler_signal(source->context.signals, "filter_remove", &cd);
 
-	if (source && filter)
-		blog(LOG_DEBUG, "- filter '%s' (%s) removed from source '%s'",
-				filter->context.name, filter->info.id,
-				source->context.name);
+	blog(LOG_DEBUG, "- filter '%s' (%s) removed from source '%s'",
+			filter->context.name, filter->info.id,
+			source->context.name);
 
 	if (filter->info.filter_remove)
 		filter->info.filter_remove(filter->context.data,
@@ -2081,6 +2101,41 @@ static inline void copy_frame_data_plane(struct obs_source_frame *dst,
 				dst->linesize[plane] * lines);
 }
 
+static void copy_frame_data_line_y800(uint32_t *dst, uint8_t *src, uint8_t *end)
+{
+	while (src < end) {
+		register uint32_t val = *(src++);
+		val |= (val << 8);
+		val |= (val << 16);
+		*(dst++) = val;
+	}
+}
+
+static inline void copy_frame_data_y800(struct obs_source_frame *dst,
+		const struct obs_source_frame *src)
+{
+	uint32_t *ptr_dst;
+	uint8_t  *ptr_src;
+	uint8_t  *src_end;
+
+	if ((src->linesize[0] * 4) != dst->linesize[0]) {
+		for (uint32_t cy = 0; cy < src->height; cy++) {
+			ptr_dst = (uint32_t*)
+				(dst->data[0] + cy * dst->linesize[0]);
+			ptr_src = (src->data[0] + cy * src->linesize[0]);
+			src_end = ptr_src + src->width;
+
+			copy_frame_data_line_y800(ptr_dst, ptr_src, src_end);
+		}
+	} else {
+		ptr_dst = (uint32_t*)dst->data[0];
+		ptr_src = (uint8_t *)src->data[0];
+		src_end = ptr_src + src->height * src->linesize[0];
+
+		copy_frame_data_line_y800(ptr_dst, ptr_src, src_end);
+	}
+}
+
 static void copy_frame_data(struct obs_source_frame *dst,
 		const struct obs_source_frame *src)
 {
@@ -2094,7 +2149,7 @@ static void copy_frame_data(struct obs_source_frame *dst,
 		memcpy(dst->color_range_max, src->color_range_max, size);
 	}
 
-	switch (dst->format) {
+	switch (src->format) {
 	case VIDEO_FORMAT_I420:
 		copy_frame_data_plane(dst, src, 0, dst->height);
 		copy_frame_data_plane(dst, src, 1, dst->height/2);
@@ -2115,12 +2170,16 @@ static void copy_frame_data(struct obs_source_frame *dst,
 	case VIDEO_FORMAT_YVYU:
 	case VIDEO_FORMAT_YUY2:
 	case VIDEO_FORMAT_UYVY:
-	case VIDEO_FORMAT_Y800:
 	case VIDEO_FORMAT_NONE:
 	case VIDEO_FORMAT_RGBA:
 	case VIDEO_FORMAT_BGRA:
 	case VIDEO_FORMAT_BGRX:
 		copy_frame_data_plane(dst, src, 0, dst->height);
+		break;
+
+	case VIDEO_FORMAT_Y800:
+		copy_frame_data_y800(dst, src);
+		break;
 	}
 }
 
@@ -2201,8 +2260,12 @@ static inline struct obs_source_frame *cache_video(struct obs_source *source,
 
 	if (!new_frame) {
 		struct async_frame new_af;
+		enum video_format format = frame->format;
+
+		if (format == VIDEO_FORMAT_Y800)
+			format = VIDEO_FORMAT_BGRX;
 
-		new_frame = obs_source_frame_create(frame->format,
+		new_frame = obs_source_frame_create(format,
 				frame->width, frame->height);
 		new_af.frame = new_frame;
 		new_af.used = true;
@@ -2453,6 +2516,7 @@ static bool ready_async_frame(obs_source_t *source, uint64_t sys_time)
 			next_frame = source->async_frames.array[0];
 		}
 
+		source->last_frame_ts = next_frame->timestamp;
 		return true;
 	}
 
@@ -2908,19 +2972,19 @@ struct source_enum_data {
 	void *param;
 };
 
-static void enum_source_tree_callback(obs_source_t *parent, obs_source_t *child,
-		void *param)
+static void enum_source_active_tree_callback(obs_source_t *parent,
+		obs_source_t *child, void *param)
 {
 	struct source_enum_data *data = param;
 	bool is_transition = child->info.type == OBS_SOURCE_TYPE_TRANSITION;
 
 	if (is_transition)
 		obs_transition_enum_sources(child,
-				enum_source_tree_callback, param);
+				enum_source_active_tree_callback, param);
 	if (child->info.enum_active_sources) {
 		if (child->context.data) {
 			child->info.enum_active_sources(child->context.data,
-					enum_source_tree_callback, data);
+					enum_source_active_tree_callback, data);
 		}
 	}
 
@@ -2967,11 +3031,67 @@ void obs_source_enum_active_tree(obs_source_t *source,
 	obs_source_addref(source);
 
 	if (source->info.type == OBS_SOURCE_TYPE_TRANSITION)
-		obs_transition_enum_sources(source, enum_source_tree_callback,
-				&data);
+		obs_transition_enum_sources(source,
+				enum_source_active_tree_callback, &data);
 	if (source->info.enum_active_sources)
 		source->info.enum_active_sources(source->context.data,
-				enum_source_tree_callback, &data);
+				enum_source_active_tree_callback, &data);
+
+	obs_source_release(source);
+}
+
+static void enum_source_full_tree_callback(obs_source_t *parent,
+		obs_source_t *child, void *param)
+{
+	struct source_enum_data *data = param;
+	bool is_transition = child->info.type == OBS_SOURCE_TYPE_TRANSITION;
+
+	if (is_transition)
+		obs_transition_enum_sources(child,
+				enum_source_full_tree_callback, param);
+	if (child->info.enum_all_sources) {
+		if (child->context.data) {
+			child->info.enum_active_sources(child->context.data,
+					enum_source_full_tree_callback, data);
+		}
+	} else if (child->info.enum_active_sources) {
+		if (child->context.data) {
+			child->info.enum_active_sources(child->context.data,
+					enum_source_full_tree_callback, data);
+		}
+	}
+
+	data->enum_callback(parent, child, data->param);
+}
+
+static void obs_source_enum_full_tree(obs_source_t *source,
+		obs_source_enum_proc_t enum_callback,
+		void *param)
+{
+	struct source_enum_data data = {enum_callback, param};
+	bool is_transition;
+
+	if (!data_valid(source, "obs_source_enum_active_tree"))
+		return;
+
+	is_transition = source->info.type == OBS_SOURCE_TYPE_TRANSITION;
+	if (!is_transition && !source->info.enum_active_sources)
+		return;
+
+	obs_source_addref(source);
+
+	if (source->info.type == OBS_SOURCE_TYPE_TRANSITION)
+		obs_transition_enum_sources(source,
+				enum_source_full_tree_callback, &data);
+
+	if (source->info.enum_all_sources) {
+		source->info.enum_all_sources(source->context.data,
+				enum_source_full_tree_callback, &data);
+
+	} else if (source->info.enum_active_sources) {
+		source->info.enum_active_sources(source->context.data,
+				enum_source_full_tree_callback, &data);
+	}
 
 	obs_source_release(source);
 }
@@ -3003,7 +3123,7 @@ bool obs_source_add_active_child(obs_source_t *parent, obs_source_t *child)
 		return false;
 	}
 
-	obs_source_enum_active_tree(child, check_descendant, &info);
+	obs_source_enum_full_tree(child, check_descendant, &info);
 	if (info.exists)
 		return false;
 
@@ -3774,3 +3894,38 @@ void obs_source_remove_audio_capture_callback(obs_source_t *source,
 	da_erase_item(source->audio_cb_list, &info);
 	pthread_mutex_unlock(&source->audio_cb_mutex);
 }
+
+void obs_source_set_monitoring_type(obs_source_t *source,
+		enum obs_monitoring_type type)
+{
+	bool was_on;
+	bool now_on;
+
+	if (!obs_source_valid(source, "obs_source_set_monitoring_type"))
+		return;
+	if (source->info.output_flags & OBS_SOURCE_DO_NOT_MONITOR)
+		return;
+	if (source->monitoring_type == type)
+		return;
+
+	was_on = source->monitoring_type != OBS_MONITORING_TYPE_NONE;
+	now_on = type != OBS_MONITORING_TYPE_NONE;
+
+	if (was_on != now_on) {
+		if (!was_on) {
+			source->monitor = audio_monitor_create(source);
+		} else {
+			audio_monitor_destroy(source->monitor);
+			source->monitor = NULL;
+		}
+	}
+
+	source->monitoring_type = type;
+}
+
+enum obs_monitoring_type obs_source_get_monitoring_type(
+		const obs_source_t *source)
+{
+	return obs_source_valid(source, "obs_source_get_monitoring_type") ?
+		source->monitoring_type : OBS_MONITORING_TYPE_NONE;
+}
diff --git a/libobs/obs-source.h b/libobs/obs-source.h
index 42efacc..bb3ae3c 100644
--- a/libobs/obs-source.h
+++ b/libobs/obs-source.h
@@ -120,6 +120,14 @@ enum obs_source_type {
  */
 #define OBS_SOURCE_DEPRECATED (1<<8)
 
+/**
+ * Source cannot have its audio monitored
+ *
+ * Specifies that this source may cause a feedback loop if audio is monitored.
+ * This is used primarily with desktop audio capture sources.
+ */
+#define OBS_SOURCE_DO_NOT_MONITOR (1<<9)
+
 /** @} */
 
 typedef void (*obs_source_enum_proc_t)(obs_source_t *parent,
@@ -400,6 +408,21 @@ struct obs_source_info {
 	bool (*audio_render)(void *data, uint64_t *ts_out,
 			struct obs_source_audio_mix *audio_output,
 			uint32_t mixers, size_t channels, size_t sample_rate);
+
+	/**
+	 * Called to enumerate all active and inactive sources being used
+	 * within this source.  If this callback isn't implemented,
+	 * enum_active_sources will be called instead.
+	 *
+	 * This is typically used if a source can have inactive child sources.
+	 *
+	 * @param  data           Filter data
+	 * @param  enum_callback  Enumeration callback
+	 * @param  param          User data to pass to callback
+	 */
+	void (*enum_all_sources)(void *data,
+			obs_source_enum_proc_t enum_callback,
+			void *param);
 };
 
 EXPORT void obs_register_source_s(const struct obs_source_info *info,
diff --git a/libobs/obs-win-crash-handler.c b/libobs/obs-win-crash-handler.c
index 51e2199..41987dd 100644
--- a/libobs/obs-win-crash-handler.c
+++ b/libobs/obs-win-crash-handler.c
@@ -16,6 +16,7 @@
 ******************************************************************************/
 
 #include <windows.h>
+#include <time.h>
 #include <dbghelp.h>
 #include <shellapi.h>
 #include <tlhelp32.h>
@@ -248,16 +249,26 @@ static inline void init_module_info(struct exception_handler_data *data)
 
 static inline void write_header(struct exception_handler_data *data)
 {
+	char date_time[80];
+	time_t now = time(0);
+	struct tm ts;
+	ts = *localtime(&now);
+	strftime(date_time, sizeof(date_time), "%Y-%m-%d, %X", &ts);
+
 	dstr_catf(&data->str, "Unhandled exception: %x\r\n"
+			"Date/Time: %s\r\n"
 			"Fault address: %"PRIX64" (%s)\r\n"
 			"libobs version: "OBS_VERSION"\r\n"
-			"Windows version: %d.%d build %d (revision %d)\r\n"
+			"Windows version: %d.%d build %d (revision: %d; "
+				"%s-bit)\r\n"
 			"CPU: %s\r\n\r\n",
 			data->exception->ExceptionRecord->ExceptionCode,
+			date_time,
 			data->main_trace.instruction_ptr,
 			data->module_name.array,
 			data->win_version.major, data->win_version.minor,
 			data->win_version.build, data->win_version.revis,
+			is_64_bit_windows() ? "64" : "32",
 			data->cpu_info.array);
 }
 
diff --git a/libobs/obs-windows.c b/libobs/obs-windows.c
index a56a7bd..e2c19c8 100644
--- a/libobs/obs-windows.c
+++ b/libobs/obs-windows.c
@@ -157,31 +157,23 @@ static void log_processor_cores(void)
 
 static void log_available_memory(void)
 {
-	MEMORYSTATUS ms;
-	GlobalMemoryStatus(&ms);
+	MEMORYSTATUSEX ms;
+	ms.dwLength = sizeof(ms);
+
+	GlobalMemoryStatusEx(&ms);
 
 #ifdef _WIN64
 	const char *note = "";
 #else
-	const char *note = " (NOTE: 2 or 4 gigs max is normal for 32bit programs)";
+	const char *note = " (NOTE: 32bit programs cannot use more than 3gb)";
 #endif
 
 	blog(LOG_INFO, "Physical Memory: %luMB Total, %luMB Free%s",
-			(DWORD)(ms.dwTotalPhys / 1048576),
-			(DWORD)(ms.dwAvailPhys / 1048576),
+			(DWORD)(ms.ullTotalPhys / 1048576),
+			(DWORD)(ms.ullAvailPhys / 1048576),
 			note);
 }
 
-static bool is_64_bit_windows(void)
-{
-#if defined(_WIN64)
-	return true;
-#elif defined(_WIN32)
-	BOOL b64 = false;
-	return IsWow64Process(GetCurrentProcess(), &b64) && b64;
-#endif
-}
-
 static void log_windows_version(void)
 {
 	struct win_version_info ver;
diff --git a/libobs/obs.c b/libobs/obs.c
index 685d892..de01ed7 100644
--- a/libobs/obs.c
+++ b/libobs/obs.c
@@ -488,10 +488,22 @@ static bool obs_init_audio(struct audio_output_info *ai)
 	struct obs_core_audio *audio = &obs->audio;
 	int errorcode;
 
-	/* TODO: sound subsystem */
+	pthread_mutexattr_t attr;
+
+	pthread_mutex_init_value(&audio->monitoring_mutex);
+
+	if (pthread_mutexattr_init(&attr) != 0)
+		return false;
+	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
+		return false;
+	if (pthread_mutex_init(&audio->monitoring_mutex, &attr) != 0)
+		return false;
 
 	audio->user_volume    = 1.0f;
 
+	audio->monitoring_device_name = bstrdup("Default");
+	audio->monitoring_device_id = bstrdup("default");
+
 	errorcode = audio_output_open(&audio->audio, ai);
 	if (errorcode == AUDIO_OUTPUT_SUCCESS)
 		return true;
@@ -513,6 +525,11 @@ static void obs_free_audio(void)
 	da_free(audio->render_order);
 	da_free(audio->root_nodes);
 
+	da_free(audio->monitors);
+	bfree(audio->monitoring_device_name);
+	bfree(audio->monitoring_device_id);
+	pthread_mutex_destroy(&audio->monitoring_mutex);
+
 	memset(audio, 0, sizeof(struct obs_core_audio));
 }
 
@@ -725,6 +742,8 @@ static bool obs_init(const char *locale, const char *module_config_path,
 {
 	obs = bzalloc(sizeof(struct obs_core));
 
+	pthread_mutex_init_value(&obs->audio.monitoring_mutex);
+
 	obs->name_store_owned = !store;
 	obs->name_store = store ? store : profiler_name_store_create();
 	if (!obs->name_store) {
@@ -908,11 +927,6 @@ int obs_reset_video(struct obs_video_info *ovi)
 	stop_video();
 	obs_free_video();
 
-	if (!ovi) {
-		obs_free_graphics();
-		return OBS_VIDEO_SUCCESS;
-	}
-
 	/* align to multiple-of-two and SSE alignment sizes */
 	ovi->output_width  &= 0xFFFFFFFC;
 	ovi->output_height &= 0xFFFFFFFE;
@@ -1454,6 +1468,7 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data)
 	uint32_t     mixers;
 	int          di_order;
 	int          di_mode;
+	int          monitoring_type;
 
 	source = obs_source_create(id, name, settings, hotkeys);
 
@@ -1505,6 +1520,10 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data)
 	obs_source_set_deinterlace_field_order(source,
 			(enum obs_deinterlace_field_order)di_order);
 
+	monitoring_type = (int)obs_data_get_int(source_data, "monitoring_type");
+	obs_source_set_monitoring_type(source,
+			(enum obs_monitoring_type)monitoring_type);
+
 	if (filters) {
 		size_t count = obs_data_array_count(filters);
 
@@ -1601,6 +1620,7 @@ obs_data_t *obs_save_source(obs_source_t *source)
 	uint64_t   ptm_delay   = obs_source_get_push_to_mute_delay(source);
 	bool       push_to_talk= obs_source_push_to_talk_enabled(source);
 	uint64_t   ptt_delay   = obs_source_get_push_to_talk_delay(source);
+	int        m_type      = (int)obs_source_get_monitoring_type(source);
 	int        di_mode     = (int)obs_source_get_deinterlace_mode(source);
 	int        di_order    =
 		(int)obs_source_get_deinterlace_field_order(source);
@@ -1630,6 +1650,7 @@ obs_data_t *obs_save_source(obs_source_t *source)
 	obs_data_set_obj   (source_data, "hotkeys",  hotkey_data);
 	obs_data_set_int   (source_data, "deinterlace_mode", di_mode);
 	obs_data_set_int   (source_data, "deinterlace_field_order", di_order);
+	obs_data_set_int   (source_data, "monitoring_type", m_type);
 
 	if (source->info.type == OBS_SOURCE_TYPE_TRANSITION)
 		obs_transition_save(source, source_data);
@@ -1876,3 +1897,47 @@ bool obs_obj_invalid(void *obj)
 
 	return !context->data;
 }
+
+bool obs_set_audio_monitoring_device(const char *name, const char *id)
+{
+	if (!obs || !name || !id || !*name || !*id)
+		return false;
+
+#ifdef _WIN32
+	pthread_mutex_lock(&obs->audio.monitoring_mutex);
+
+	if (strcmp(id, obs->audio.monitoring_device_id) == 0) {
+		pthread_mutex_unlock(&obs->audio.monitoring_mutex);
+		return true;
+	}
+
+	if (obs->audio.monitoring_device_name)
+		bfree(obs->audio.monitoring_device_name);
+	if (obs->audio.monitoring_device_id)
+		bfree(obs->audio.monitoring_device_id);
+
+	obs->audio.monitoring_device_name = bstrdup(name);
+	obs->audio.monitoring_device_id = bstrdup(id);
+
+	for (size_t i = 0; i < obs->audio.monitors.num; i++) {
+		struct audio_monitor *monitor = obs->audio.monitors.array[i];
+		audio_monitor_reset(monitor);
+	}
+
+	pthread_mutex_unlock(&obs->audio.monitoring_mutex);
+	return true;
+#else
+	return false;
+#endif
+}
+
+void obs_get_audio_monitoring_device(const char **name, const char **id)
+{
+	if (!obs)
+		return;
+
+	if (name)
+		*name = obs->audio.monitoring_device_name;
+	if (id)
+		*id = obs->audio.monitoring_device_id;
+}
diff --git a/libobs/obs.h b/libobs/obs.h
index 3064680..cf9cd36 100644
--- a/libobs/obs.h
+++ b/libobs/obs.h
@@ -533,8 +533,8 @@ enum obs_base_effect {
 EXPORT gs_effect_t *obs_get_base_effect(enum obs_base_effect effect);
 
 /* DEPRECATED: gets texture_rect default effect */
-DEPRECATED_START EXPORT gs_effect_t *obs_get_default_rect_effect(void)
-	DEPRECATED_END;
+DEPRECATED
+EXPORT gs_effect_t *obs_get_default_rect_effect(void);
 
 /** Returns the primary obs signal handler */
 EXPORT signal_handler_t *obs_get_signal_handler(void);
@@ -582,6 +582,15 @@ EXPORT enum obs_obj_type obs_obj_get_type(void *obj);
 EXPORT const char *obs_obj_get_id(void *obj);
 EXPORT bool obs_obj_invalid(void *obj);
 
+typedef bool (*obs_enum_audio_device_cb)(void *data, const char *name,
+		const char *id);
+
+EXPORT void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb,
+		void *data);
+
+EXPORT bool obs_set_audio_monitoring_device(const char *name, const char *id);
+EXPORT void obs_get_audio_monitoring_device(const char **name, const char **id);
+
 
 /* ------------------------------------------------------------------------- */
 /* View context */
@@ -914,6 +923,17 @@ EXPORT void obs_source_set_deinterlace_field_order(obs_source_t *source,
 EXPORT enum obs_deinterlace_field_order obs_source_get_deinterlace_field_order(
 		const obs_source_t *source);
 
+enum obs_monitoring_type {
+	OBS_MONITORING_TYPE_NONE,
+	OBS_MONITORING_TYPE_MONITOR_ONLY,
+	OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT
+};
+
+EXPORT void obs_source_set_monitoring_type(obs_source_t *source,
+		enum obs_monitoring_type type);
+EXPORT enum obs_monitoring_type obs_source_get_monitoring_type(
+		const obs_source_t *source);
+
 /* ------------------------------------------------------------------------- */
 /* Functions used by sources */
 
@@ -1460,6 +1480,13 @@ EXPORT uint32_t obs_output_get_height(const obs_output_t *output);
 
 EXPORT const char *obs_output_get_id(const obs_output_t *output);
 
+#if BUILD_CAPTIONS
+EXPORT void obs_output_output_caption_text1(obs_output_t *output,
+		const char *text);
+#endif
+
+EXPORT float obs_output_get_congestion(obs_output_t *output);
+
 /* ------------------------------------------------------------------------- */
 /* Functions used by outputs */
 
@@ -1651,11 +1678,17 @@ EXPORT const char *obs_encoder_get_id(const obs_encoder_t *encoder);
 EXPORT uint32_t obs_get_encoder_caps(const char *encoder_id);
 
 /** Duplicates an encoder packet */
+DEPRECATED
 EXPORT void obs_duplicate_encoder_packet(struct encoder_packet *dst,
 		const struct encoder_packet *src);
 
+DEPRECATED
 EXPORT void obs_free_encoder_packet(struct encoder_packet *packet);
 
+EXPORT void obs_encoder_packet_ref(struct encoder_packet *dst,
+		struct encoder_packet *src);
+EXPORT void obs_encoder_packet_release(struct encoder_packet *packet);
+
 
 /* ------------------------------------------------------------------------- */
 /* Stream Services */
diff --git a/libobs/obsconfig.h.in b/libobs/obsconfig.h.in
index 7a7833c..f86962d 100644
--- a/libobs/obsconfig.h.in
+++ b/libobs/obsconfig.h.in
@@ -1,10 +1,19 @@
 
 #pragma once
 
+#ifndef ON
+#define ON 1
+#endif
+
+#ifndef OFF
+#define OFF 0
+#endif
+
 #define OBS_VERSION "@OBS_VERSION@"
 #define OBS_DATA_PATH "@OBS_DATA_PATH@"
 #define OBS_INSTALL_PREFIX "@OBS_INSTALL_PREFIX@"
 #define OBS_PLUGIN_DESTINATION "@OBS_PLUGIN_DESTINATION@"
 #define OBS_RELATIVE_PREFIX "@OBS_RELATIVE_PREFIX@"
 #define OBS_UNIX_STRUCTURE @OBS_UNIX_STRUCTURE@
+#define BUILD_CAPTIONS @BUILD_CAPTIONS@
 #define HAVE_DBUS @HAVE_DBUS@
diff --git a/libobs/util/c99defs.h b/libobs/util/c99defs.h
index ddd6d2a..43d52c8 100644
--- a/libobs/util/c99defs.h
+++ b/libobs/util/c99defs.h
@@ -24,19 +24,15 @@
 #define UNUSED_PARAMETER(param) (void)param
 
 #ifdef _MSC_VER
-#define DEPRECATED_START __declspec(deprecated)
-#define DEPRECATED_END
+#define DEPRECATED __declspec(deprecated)
 #define FORCE_INLINE __forceinline
 #else
-#define DEPRECATED_START
-#define DEPRECATED_END __attribute__ ((deprecated))
+#define DEPRECATED __attribute__ ((deprecated))
 #define FORCE_INLINE inline __attribute__((always_inline))
 #endif
 
 #ifdef _MSC_VER
 
-#pragma warning (disable : 4996)
-
 /* Microsoft is one of the most inept companies on the face of the planet.
  * The fact that even visual studio 2013 doesn't support the standard 'inline'
  * keyword is so incredibly stupid that I just can't imagine what sort of
diff --git a/libobs/util/circlebuf.h b/libobs/util/circlebuf.h
index eddf464..111f17a 100644
--- a/libobs/util/circlebuf.h
+++ b/libobs/util/circlebuf.h
@@ -254,6 +254,20 @@ static inline void circlebuf_pop_back(struct circlebuf *cb, void *data,
 		cb->end_pos -= size;
 }
 
+static inline void *circlebuf_data(struct circlebuf *cb, size_t idx)
+{
+	uint8_t *ptr = (uint8_t*)cb->data;
+	size_t offset = cb->start_pos + idx;
+
+	if (idx > cb->size)
+		return NULL;
+
+	if (offset >= cb->capacity)
+		offset -= cb->capacity;
+
+	return ptr + offset;
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libobs/util/config-file.c b/libobs/util/config-file.c
index 735afee..98d8807 100644
--- a/libobs/util/config-file.c
+++ b/libobs/util/config-file.c
@@ -18,6 +18,7 @@
 #include <stdio.h>
 #include <wchar.h>
 #include "config-file.h"
+#include "threading.h"
 #include "platform.h"
 #include "base.h"
 #include "bmem.h"
@@ -57,8 +58,19 @@ struct config_data {
 	char *file;
 	struct darray sections; /* struct config_section */
 	struct darray defaults; /* struct config_section */
+	pthread_mutex_t mutex;
 };
 
+static inline bool init_mutex(config_t *config)
+{
+	pthread_mutexattr_t attr;
+	if (pthread_mutexattr_init(&attr) != 0)
+		return false;
+	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
+		return false;
+	return pthread_mutex_init(&config->mutex, &attr) == 0;
+}
+
 config_t *config_create(const char *file)
 {
 	struct config_data *config;
@@ -70,6 +82,12 @@ config_t *config_create(const char *file)
 	fclose(f);
 
 	config = bzalloc(sizeof(struct config_data));
+
+	if (!init_mutex(config)) {
+		bfree(config);
+		return NULL;
+	}
+
 	config->file = bstrdup(file);
 	return config;
 }
@@ -278,6 +296,11 @@ int config_open(config_t **config, const char *file,
 	if (!*config)
 		return CONFIG_ERROR;
 
+	if (!init_mutex(*config)) {
+		bfree(*config);
+		return CONFIG_ERROR;
+	}
+
 	(*config)->file = bstrdup(file);
 
 	errorcode = config_parse_file(&(*config)->sections, file, always_open);
@@ -301,6 +324,11 @@ int config_open_string(config_t **config, const char *str)
 	if (!*config)
 		return CONFIG_ERROR;
 
+	if (!init_mutex(*config)) {
+		bfree(*config);
+		return CONFIG_ERROR;
+	}
+
 	(*config)->file = NULL;
 
 	lexer_init(&lex);
@@ -333,9 +361,13 @@ int config_save(config_t *config)
 	dstr_init(&str);
 	dstr_init(&tmp);
 
+	pthread_mutex_lock(&config->mutex);
+
 	f = os_fopen(config->file, "wb");
-	if (!f)
+	if (!f) {
+		pthread_mutex_unlock(&config->mutex);
 		return CONFIG_FILENOTFOUND;
+	}
 
 	for (i = 0; i < config->sections.num; i++) {
 		struct config_section *section = darray_item(
@@ -371,6 +403,8 @@ int config_save(config_t *config)
 	fwrite(str.array, 1, str.len, f);
 	fclose(f);
 
+	pthread_mutex_unlock(&config->mutex);
+
 	dstr_free(&tmp);
 	dstr_free(&str);
 
@@ -391,6 +425,8 @@ int config_save_safe(config_t *config, const char *temp_ext,
 		return CONFIG_ERROR;
 	}
 
+	pthread_mutex_lock(&config->mutex);
+
 	dstr_copy(&temp_file, config->file);
 	if (*temp_ext != '.')
 		dstr_cat(&temp_file, ".");
@@ -419,6 +455,7 @@ int config_save_safe(config_t *config, const char *temp_ext,
 	os_rename(temp_file.array, file);
 
 cleanup:
+	pthread_mutex_unlock(&config->mutex);
 	dstr_free(&temp_file);
 	dstr_free(&backup_file);
 	return ret;
@@ -442,6 +479,7 @@ void config_close(config_t *config)
 	darray_free(&config->defaults);
 	darray_free(&config->sections);
 	bfree(config->file);
+	pthread_mutex_destroy(&config->mutex);
 	bfree(config);
 }
 
@@ -453,14 +491,20 @@ size_t config_num_sections(config_t *config)
 const char *config_get_section(config_t *config, size_t idx)
 {
 	struct config_section *section;
+	const char *name = NULL;
+
+	pthread_mutex_lock(&config->mutex);
 
 	if (idx >= config->sections.num)
-		return NULL;
+		goto unlock;
 
 	section = darray_item(sizeof(struct config_section), &config->sections,
 			idx);
+	name = section->name;
 
-	return section->name;
+unlock:
+	pthread_mutex_unlock(&config->mutex);
+	return name;
 }
 
 static const struct config_item *config_find_item(const struct darray *sections,
@@ -487,14 +531,16 @@ static const struct config_item *config_find_item(const struct darray *sections,
 	return NULL;
 }
 
-static void config_set_item(struct darray *sections, const char *section,
-		const char *name, char *value)
+static void config_set_item(config_t *config, struct darray *sections,
+		const char *section, const char *name, char *value)
 {
 	struct config_section *sec = NULL;
 	struct config_section *array = sections->array;
 	struct config_item *item;
 	size_t i, j;
 
+	pthread_mutex_lock(&config->mutex);
+
 	for (i = 0; i < sections->num; i++) {
 		struct config_section *cur_sec = array+i;
 		struct config_item *items = cur_sec->items.array;
@@ -506,7 +552,7 @@ static void config_set_item(struct darray *sections, const char *section,
 				if (astrcmpi(item->name, name) == 0) {
 					bfree(item->value);
 					item->value = value;
-					return;
+					goto unlock;
 				}
 			}
 
@@ -524,6 +570,9 @@ static void config_set_item(struct darray *sections, const char *section,
 	item = darray_push_back_new(sizeof(struct config_item), &sec->items);
 	item->name  = bstrdup(name);
 	item->value = value;
+
+unlock:
+	pthread_mutex_unlock(&config->mutex);
 }
 
 void config_set_string(config_t *config, const char *section,
@@ -531,7 +580,8 @@ void config_set_string(config_t *config, const char *section,
 {
 	if (!value)
 		value = "";
-	config_set_item(&config->sections, section, name, bstrdup(value));
+	config_set_item(config, &config->sections, section, name,
+			bstrdup(value));
 }
 
 void config_set_int(config_t *config, const char *section,
@@ -540,7 +590,7 @@ void config_set_int(config_t *config, const char *section,
 	struct dstr str;
 	dstr_init(&str);
 	dstr_printf(&str, "%"PRId64, value);
-	config_set_item(&config->sections, section, name, str.array);
+	config_set_item(config, &config->sections, section, name, str.array);
 }
 
 void config_set_uint(config_t *config, const char *section,
@@ -549,14 +599,14 @@ void config_set_uint(config_t *config, const char *section,
 	struct dstr str;
 	dstr_init(&str);
 	dstr_printf(&str, "%"PRIu64, value);
-	config_set_item(&config->sections, section, name, str.array);
+	config_set_item(config, &config->sections, section, name, str.array);
 }
 
 void config_set_bool(config_t *config, const char *section,
 		const char *name, bool value)
 {
 	char *str = bstrdup(value ? "true" : "false");
-	config_set_item(&config->sections, section, name, str);
+	config_set_item(config, &config->sections, section, name, str);
 }
 
 void config_set_double(config_t *config, const char *section,
@@ -564,7 +614,7 @@ void config_set_double(config_t *config, const char *section,
 {
 	char *str = bzalloc(64);
 	os_dtostr(value, str, 64);
-	config_set_item(&config->sections, section, name, str);
+	config_set_item(config, &config->sections, section, name, str);
 }
 
 void config_set_default_string(config_t *config, const char *section,
@@ -572,7 +622,8 @@ void config_set_default_string(config_t *config, const char *section,
 {
 	if (!value)
 		value = "";
-	config_set_item(&config->defaults, section, name, bstrdup(value));
+	config_set_item(config, &config->defaults, section, name,
+			bstrdup(value));
 }
 
 void config_set_default_int(config_t *config, const char *section,
@@ -581,7 +632,7 @@ void config_set_default_int(config_t *config, const char *section,
 	struct dstr str;
 	dstr_init(&str);
 	dstr_printf(&str, "%"PRId64, value);
-	config_set_item(&config->defaults, section, name, str.array);
+	config_set_item(config, &config->defaults, section, name, str.array);
 }
 
 void config_set_default_uint(config_t *config, const char *section,
@@ -590,14 +641,14 @@ void config_set_default_uint(config_t *config, const char *section,
 	struct dstr str;
 	dstr_init(&str);
 	dstr_printf(&str, "%"PRIu64, value);
-	config_set_item(&config->defaults, section, name, str.array);
+	config_set_item(config, &config->defaults, section, name, str.array);
 }
 
 void config_set_default_bool(config_t *config, const char *section,
 		const char *name, bool value)
 {
 	char *str = bstrdup(value ? "true" : "false");
-	config_set_item(&config->defaults, section, name, str);
+	config_set_item(config, &config->defaults, section, name, str);
 }
 
 void config_set_default_double(config_t *config, const char *section,
@@ -606,20 +657,25 @@ void config_set_default_double(config_t *config, const char *section,
 	struct dstr str;
 	dstr_init(&str);
 	dstr_printf(&str, "%g", value);
-	config_set_item(&config->defaults, section, name, str.array);
+	config_set_item(config, &config->defaults, section, name, str.array);
 }
 
-const char *config_get_string(const config_t *config, const char *section,
+const char *config_get_string(config_t *config, const char *section,
 		const char *name)
 {
-	const struct config_item *item = config_find_item(&config->sections,
-			section, name);
+	const struct config_item *item;
+	const char *value = NULL;
+
+	pthread_mutex_lock(&config->mutex);
+
+	item = config_find_item(&config->sections, section, name);
 	if (!item)
 		item = config_find_item(&config->defaults, section, name);
-	if (!item)
-		return NULL;
+	if (item)
+		value = item->value;
 
-	return item->value;
+	pthread_mutex_unlock(&config->mutex);
+	return value;
 }
 
 static inline int64_t str_to_int64(const char *str)
@@ -644,7 +700,7 @@ static inline uint64_t str_to_uint64(const char *str)
 		return strtoull(str, NULL, 10);
 }
 
-int64_t config_get_int(const config_t *config, const char *section,
+int64_t config_get_int(config_t *config, const char *section,
 		const char *name)
 {
 	const char *value = config_get_string(config, section, name);
@@ -654,7 +710,7 @@ int64_t config_get_int(const config_t *config, const char *section,
 	return 0;
 }
 
-uint64_t config_get_uint(const config_t *config, const char *section,
+uint64_t config_get_uint(config_t *config, const char *section,
 		const char *name)
 {
 	const char *value = config_get_string(config, section, name);
@@ -664,7 +720,7 @@ uint64_t config_get_uint(const config_t *config, const char *section,
 	return 0;
 }
 
-bool config_get_bool(const config_t *config, const char *section,
+bool config_get_bool(config_t *config, const char *section,
 		const char *name)
 {
 	const char *value = config_get_string(config, section, name);
@@ -675,7 +731,7 @@ bool config_get_bool(const config_t *config, const char *section,
 	return false;
 }
 
-double config_get_double(const config_t *config, const char *section,
+double config_get_double(config_t *config, const char *section,
 		const char *name)
 {
 	const char *value = config_get_string(config, section, name);
@@ -689,6 +745,9 @@ bool config_remove_value(config_t *config, const char *section,
 		const char *name)
 {
 	struct darray *sections = &config->sections;
+	bool success = false;
+
+	pthread_mutex_lock(&config->mutex);
 
 	for (size_t i = 0; i < sections->num; i++) {
 		struct config_section *sec = darray_item(
@@ -706,27 +765,34 @@ bool config_remove_value(config_t *config, const char *section,
 				config_item_free(item);
 				darray_erase(sizeof(struct config_item),
 						&sec->items, j);
-				return true;
+				success = true;
+				goto unlock;
 			}
 		}
 	}
 
-	return false;
+unlock:
+	pthread_mutex_unlock(&config->mutex);
+	return success;
 }
 
-const char *config_get_default_string(const config_t *config,
+const char *config_get_default_string(config_t *config,
 		const char *section, const char *name)
 {
 	const struct config_item *item;
+	const char *value = NULL;
+
+	pthread_mutex_lock(&config->mutex);
 
 	item = config_find_item(&config->defaults, section, name);
-	if (!item)
-		return NULL;
+	if (item)
+		value = item->value;
 
-	return item->value;
+	pthread_mutex_unlock(&config->mutex);
+	return value;
 }
 
-int64_t config_get_default_int(const config_t *config, const char *section,
+int64_t config_get_default_int(config_t *config, const char *section,
 		const char *name)
 {
 	const char *value = config_get_default_string(config, section, name);
@@ -736,7 +802,7 @@ int64_t config_get_default_int(const config_t *config, const char *section,
 	return 0;
 }
 
-uint64_t config_get_default_uint(const config_t *config, const char *section,
+uint64_t config_get_default_uint(config_t *config, const char *section,
 		const char *name)
 {
 	const char *value = config_get_default_string(config, section, name);
@@ -746,7 +812,7 @@ uint64_t config_get_default_uint(const config_t *config, const char *section,
 	return 0;
 }
 
-bool config_get_default_bool(const config_t *config, const char *section,
+bool config_get_default_bool(config_t *config, const char *section,
 		const char *name)
 {
 	const char *value = config_get_default_string(config, section, name);
@@ -757,7 +823,7 @@ bool config_get_default_bool(const config_t *config, const char *section,
 	return false;
 }
 
-double config_get_default_double(const config_t *config, const char *section,
+double config_get_default_double(config_t *config, const char *section,
 		const char *name)
 {
 	const char *value = config_get_default_string(config, section, name);
@@ -767,15 +833,23 @@ double config_get_default_double(const config_t *config, const char *section,
 	return 0.0;
 }
 
-bool config_has_user_value(const config_t *config, const char *section,
+bool config_has_user_value(config_t *config, const char *section,
 		const char *name)
 {
-	return config_find_item(&config->sections, section, name) != NULL;
+	bool success;
+	pthread_mutex_lock(&config->mutex);
+	success = config_find_item(&config->sections, section, name) != NULL;
+	pthread_mutex_unlock(&config->mutex);
+	return success;
 }
 
-bool config_has_default_value(const config_t *config, const char *section,
+bool config_has_default_value(config_t *config, const char *section,
 		const char *name)
 {
-	return config_find_item(&config->defaults, section, name) != NULL;
+	bool success;
+	pthread_mutex_lock(&config->mutex);
+	success = config_find_item(&config->defaults, section, name) != NULL;
+	pthread_mutex_unlock(&config->mutex);
+	return success;
 }
 
diff --git a/libobs/util/config-file.h b/libobs/util/config-file.h
index f9002d0..c8bc31a 100644
--- a/libobs/util/config-file.h
+++ b/libobs/util/config-file.h
@@ -64,15 +64,15 @@ EXPORT void config_set_bool(config_t *config, const char *section,
 EXPORT void config_set_double(config_t *config, const char *section,
 		const char *name, double value);
 
-EXPORT const char *config_get_string(const config_t *config,
+EXPORT const char *config_get_string(config_t *config,
 		const char *section, const char *name);
-EXPORT int64_t config_get_int(const config_t *config, const char *section,
+EXPORT int64_t config_get_int(config_t *config, const char *section,
 		const char *name);
-EXPORT uint64_t config_get_uint(const config_t *config, const char *section,
+EXPORT uint64_t config_get_uint(config_t *config, const char *section,
 		const char *name);
-EXPORT bool config_get_bool(const config_t *config, const char *section,
+EXPORT bool config_get_bool(config_t *config, const char *section,
 		const char *name);
-EXPORT double config_get_double(const config_t *config, const char *section,
+EXPORT double config_get_double(config_t *config, const char *section,
 		const char *name);
 
 EXPORT bool config_remove_value(config_t *config, const char *section,
@@ -107,20 +107,20 @@ EXPORT void config_set_default_double(config_t *config, const char *section,
 
 /* These functions allow you to get the current default values rather than get
  * the actual values.  Probably almost never really needed */
-EXPORT const char *config_get_default_string(const config_t *config,
+EXPORT const char *config_get_default_string(config_t *config,
 		const char *section, const char *name);
-EXPORT int64_t config_get_default_int(const config_t *config,
+EXPORT int64_t config_get_default_int(config_t *config,
 		const char *section, const char *name);
-EXPORT uint64_t config_get_default_uint(const config_t *config,
+EXPORT uint64_t config_get_default_uint(config_t *config,
 		const char *section, const char *name);
-EXPORT bool config_get_default_bool(const config_t *config,
+EXPORT bool config_get_default_bool(config_t *config,
 		const char *section, const char *name);
-EXPORT double config_get_default_double(const config_t *config,
+EXPORT double config_get_default_double(config_t *config,
 		const char *section, const char *name);
 
-EXPORT bool config_has_user_value(const config_t *config,
+EXPORT bool config_has_user_value(config_t *config,
 		const char *section, const char *name);
-EXPORT bool config_has_default_value(const config_t *config,
+EXPORT bool config_has_default_value(config_t *config,
 		const char *section, const char *name);
 
 #ifdef __cplusplus
diff --git a/libobs/util/platform-windows.c b/libobs/util/platform-windows.c
index faadf62..74c9fa9 100644
--- a/libobs/util/platform-windows.c
+++ b/libobs/util/platform-windows.c
@@ -719,28 +719,31 @@ bool get_dll_ver(const wchar_t *lib, struct win_version_info *ver_info)
 	BOOL success;
 	LPVOID data;
 	DWORD size;
+	char utf8_lib[512];
 
 	if (!ver_initialized && !initialize_version_functions())
 		return false;
 	if (!ver_initialize_success)
 		return false;
 
+	os_wcs_to_utf8(lib, 0, utf8_lib, sizeof(utf8_lib));
+
 	size = get_file_version_info_size(lib, NULL);
 	if (!size) {
-		blog(LOG_ERROR, "Failed to get windows version info size");
+		blog(LOG_ERROR, "Failed to get %s version info size", utf8_lib);
 		return false;
 	}
 
 	data = bmalloc(size);
 	if (!get_file_version_info(lib, 0, size, data)) {
-		blog(LOG_ERROR, "Failed to get windows version info");
+		blog(LOG_ERROR, "Failed to get %s version info", utf8_lib);
 		bfree(data);
 		return false;
 	}
 
 	success = ver_query_value(data, L"\\", (LPVOID*)&info, &len);
 	if (!success || !info || !len) {
-		blog(LOG_ERROR, "Failed to get windows version info value");
+		blog(LOG_ERROR, "Failed to get %s version info value", utf8_lib);
 		bfree(data);
 		return false;
 	}
@@ -754,6 +757,16 @@ bool get_dll_ver(const wchar_t *lib, struct win_version_info *ver_info)
 	return true;
 }
 
+bool is_64_bit_windows(void)
+{
+#if defined(_WIN64)
+	return true;
+#elif defined(_WIN32)
+	BOOL b64 = false;
+	return IsWow64Process(GetCurrentProcess(), &b64) && b64;
+#endif
+}
+
 #define WINVER_REG_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
 
 void get_win_ver(struct win_version_info *info)
diff --git a/libobs/util/platform.c b/libobs/util/platform.c
index 8d8669e..cfed355 100644
--- a/libobs/util/platform.c
+++ b/libobs/util/platform.c
@@ -16,6 +16,7 @@
 
 #define _FILE_OFFSET_BITS 64
 
+#include <time.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <locale.h>
@@ -657,3 +658,123 @@ const char *os_get_path_extension(const char *path)
 
 	return path + pos;
 }
+
+static inline bool valid_string(const char *str)
+{
+	while (str && *str) {
+		if (*(str++) != ' ')
+			return true;
+	}
+
+	return false;
+}
+
+static void replace_text(struct dstr *str, size_t pos, size_t len,
+		const char *new_text)
+{
+	struct dstr front = {0};
+	struct dstr back = {0};
+
+	dstr_left(&front, str, pos);
+	dstr_right(&back, str, pos + len);
+	dstr_copy_dstr(str, &front);
+	dstr_cat(str, new_text);
+	dstr_cat_dstr(str, &back);
+	dstr_free(&front);
+	dstr_free(&back);
+}
+
+static void erase_ch(struct dstr *str, size_t pos)
+{
+	struct dstr new_str = {0};
+	dstr_left(&new_str, str, pos);
+	dstr_cat(&new_str, str->array + pos + 1);
+	dstr_free(str);
+	*str = new_str;
+}
+
+char *os_generate_formatted_filename(const char *extension, bool space,
+		const char *format)
+{
+	time_t now = time(0);
+	struct tm *cur_time;
+	cur_time = localtime(&now);
+
+	const size_t spec_count = 23;
+	static const char *spec[][2] = {
+		{"%CCYY", "%Y"},
+		{"%YY",   "%y"},
+		{"%MM",   "%m"},
+		{"%DD",   "%d"},
+		{"%hh",   "%H"},
+		{"%mm",   "%M"},
+		{"%ss",   "%S"},
+		{"%%",    "%%"},
+
+		{"%a",    ""},
+		{"%A",    ""},
+		{"%b",    ""},
+		{"%B",    ""},
+		{"%d",    ""},
+		{"%H",    ""},
+		{"%I",    ""},
+		{"%m",    ""},
+		{"%M",    ""},
+		{"%p",    ""},
+		{"%S",    ""},
+		{"%y",    ""},
+		{"%Y",    ""},
+		{"%z",    ""},
+		{"%Z",    ""},
+	};
+
+	char convert[128] = {0};
+	struct dstr sf;
+	struct dstr c = {0};
+	size_t pos = 0;
+
+	dstr_init_copy(&sf, format);
+
+	while (pos < sf.len) {
+		for (size_t i = 0; i < spec_count && !convert[0]; i++) {
+			size_t len = strlen(spec[i][0]);
+
+			const char *cmp = sf.array + pos;
+
+			if (astrcmp_n(cmp, spec[i][0], len) == 0) {
+				if (strlen(spec[i][1]))
+					strftime(convert, sizeof(convert),
+							spec[i][1], cur_time);
+				else
+					strftime(convert, sizeof(convert),
+							spec[i][0], cur_time);
+
+
+				dstr_copy(&c, convert);
+				if (c.len && valid_string(c.array))
+					replace_text(&sf, pos, len, convert);
+			}
+		}
+
+		if (convert[0]) {
+			pos += strlen(convert);
+			convert[0] = 0;
+		} else if (!convert[0] && sf.array[pos] == '%') {
+			erase_ch(&sf, pos);
+		} else {
+			pos++;
+		}
+	}
+
+	if (!space)
+		dstr_replace(&sf, " ", "_");
+
+	dstr_cat_ch(&sf, '.');
+	dstr_cat(&sf, extension);
+	dstr_free(&c);
+
+	if (sf.len > 255)
+		dstr_mid(&sf, &sf, 0, 255);
+
+	return sf.array;
+}
diff --git a/libobs/util/platform.h b/libobs/util/platform.h
index b08c40a..77d0ea6 100644
--- a/libobs/util/platform.h
+++ b/libobs/util/platform.h
@@ -162,6 +162,9 @@ EXPORT int os_mkdirs(const char *path);
 EXPORT int os_rename(const char *old_path, const char *new_path);
 EXPORT int os_copyfile(const char *file_in, const char *file_out);
 
+EXPORT char *os_generate_formatted_filename(const char *extension, bool space,
+		const char *format);
+
 struct os_inhibit_info;
 typedef struct os_inhibit_info os_inhibit_t;
 
diff --git a/libobs/util/windows/CoTaskMemPtr.hpp b/libobs/util/windows/CoTaskMemPtr.hpp
index d9830d1..ff607de 100644
--- a/libobs/util/windows/CoTaskMemPtr.hpp
+++ b/libobs/util/windows/CoTaskMemPtr.hpp
@@ -29,6 +29,8 @@ public:
 	inline operator T*() const               {return ptr;}
 	inline T *operator->() const             {return ptr;}
 
+	inline const T *Get() const {return ptr;}
+
 	inline CoTaskMemPtr& operator=(T* val)
 	{
 		Clear();
diff --git a/libobs/util/windows/win-version.h b/libobs/util/windows/win-version.h
index b2a4a32..c855448 100644
--- a/libobs/util/windows/win-version.h
+++ b/libobs/util/windows/win-version.h
@@ -29,6 +29,7 @@ struct win_version_info {
 	int revis;
 };
 
+EXPORT bool is_64_bit_windows(void);
 EXPORT bool get_dll_ver(const wchar_t *lib, struct win_version_info *info);
 EXPORT void get_win_ver(struct win_version_info *info);
 
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index e728c34..8e90662 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -19,6 +19,9 @@ if(WIN32)
 			message(STATUS "enc-amf submodule not found!  Please fetch submodules.  enc-amf plugin disabled.")
 		endif()
 	endif()
+	if (MSVC)
+		add_subdirectory(win-ivcam)
+	endif()
 elseif(APPLE)
 	add_subdirectory(coreaudio-encoder)
 	add_subdirectory(mac-avcapture)
@@ -52,6 +55,12 @@ if(WIN32 OR APPLE)
 			message(STATUS "obs-browser submodule not found!  Please fetch submodules.  obs-browser plugin disabled.")
 		endif()
 	endif()
+
+	if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/obs-vst/CMakeLists.txt")
+		add_subdirectory(obs-vst)
+	else()
+		message(STATUS "obs-vst submodule not found!  Please fetch/update submodules.  obs-vst plugin disabled.")
+	endif()
 endif()
 
 add_subdirectory(image-source)
diff --git a/plugins/coreaudio-encoder/data/locale/de-DE.ini b/plugins/coreaudio-encoder/data/locale/de-DE.ini
index 5425f0e..44895bd 100644
--- a/plugins/coreaudio-encoder/data/locale/de-DE.ini
+++ b/plugins/coreaudio-encoder/data/locale/de-DE.ini
@@ -1,4 +1,4 @@
-CoreAudioAAC="CoreAudio AAC encoder"
+CoreAudioAAC="CoreAudio AAC Codierer"
 Bitrate="Bitrate"
 AllowHEAAC="Erlaube HE-AAC"
 OutputSamplerate="Ausgabe-Abtastrate"
diff --git a/plugins/coreaudio-encoder/data/locale/et-EE.ini b/plugins/coreaudio-encoder/data/locale/et-EE.ini
new file mode 100644
index 0000000..df9bac4
--- /dev/null
+++ b/plugins/coreaudio-encoder/data/locale/et-EE.ini
@@ -0,0 +1,6 @@
+CoreAudioAAC="CoreAudio AAC kodeerija"
+Bitrate="Bitikiirus"
+AllowHEAAC="Luba HE-AAC"
+OutputSamplerate="Väljundi diskreetimissagedus"
+UseInputSampleRate="Kasuta sisendi (OBS) diskreetimissagedust (võib loetleda toeta bitikiirusi)"
+
diff --git a/plugins/coreaudio-encoder/data/locale/hu-HU.ini b/plugins/coreaudio-encoder/data/locale/hu-HU.ini
index 4cb1545..6eb0b07 100644
--- a/plugins/coreaudio-encoder/data/locale/hu-HU.ini
+++ b/plugins/coreaudio-encoder/data/locale/hu-HU.ini
@@ -1,6 +1,6 @@
 CoreAudioAAC="CoreAudio AAC kódoló"
-Bitrate="Bitráta"
+Bitrate="Bitsebesség"
 AllowHEAAC="HE-AAC engedélyezése"
 OutputSamplerate="Kimeneti mintavételráta"
-UseInputSampleRate="Beviteli (OBS) mintaráta használata (kilistázza a nem támogatott bitrátákat)"
+UseInputSampleRate="Beviteli (OBS) mintaráta használata (kilistázza a nem támogatott bitsebességeket)"
 
diff --git a/plugins/coreaudio-encoder/data/locale/ms-MY.ini b/plugins/coreaudio-encoder/data/locale/ms-MY.ini
new file mode 100644
index 0000000..bc6299a
--- /dev/null
+++ b/plugins/coreaudio-encoder/data/locale/ms-MY.ini
@@ -0,0 +1,3 @@
+Bitrate="Nilai Bit"
+AllowHEAAC="Benarkan HE-AAC"
+
diff --git a/plugins/coreaudio-encoder/data/locale/tr-TR.ini b/plugins/coreaudio-encoder/data/locale/tr-TR.ini
index e9082d4..cac33c0 100644
--- a/plugins/coreaudio-encoder/data/locale/tr-TR.ini
+++ b/plugins/coreaudio-encoder/data/locale/tr-TR.ini
@@ -2,4 +2,5 @@ CoreAudioAAC="CoreAudio AAC kodlayıcısı"
 Bitrate="Bit hızı"
 AllowHEAAC="HE-ACC'ye izin ver"
 OutputSamplerate="Çıkış örnek hızı"
+UseInputSampleRate="Giriş (OBS) Örnekleme Hızını Kullan (desteklenmeyen bit hızları listelenebilir)"
 
diff --git a/plugins/decklink/data/locale/et-EE.ini b/plugins/decklink/data/locale/et-EE.ini
new file mode 100644
index 0000000..c707d4c
--- /dev/null
+++ b/plugins/decklink/data/locale/et-EE.ini
@@ -0,0 +1,6 @@
+BlackmagicDevice="Blackmagic seade"
+Device="Seade"
+Mode="Režiim"
+Buffering="Kasutada puhverdamist"
+PixelFormat="Piksli formaat"
+
diff --git a/plugins/decklink/data/locale/tr-TR.ini b/plugins/decklink/data/locale/tr-TR.ini
index 0491e00..4520346 100644
--- a/plugins/decklink/data/locale/tr-TR.ini
+++ b/plugins/decklink/data/locale/tr-TR.ini
@@ -2,4 +2,5 @@ BlackmagicDevice="Blackmagic Aygıtı"
 Device="Aygıt"
 Mode="Mod"
 Buffering="ArabelleÄŸi Kullan"
+PixelFormat="Piksel Biçimi"
 
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI.h
index ef1da3f..2eed7b7 100644
--- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI.h
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -57,23 +57,31 @@
 
 BMD_CONST REFIID IID_IDeckLinkVideoOutputCallback                 = /* 20AA5225-1958-47CB-820B-80A8D521A6EE */ {0x20,0xAA,0x52,0x25,0x19,0x58,0x47,0xCB,0x82,0x0B,0x80,0xA8,0xD5,0x21,0xA6,0xEE};
 BMD_CONST REFIID IID_IDeckLinkInputCallback                       = /* DD04E5EC-7415-42AB-AE4A-E80C4DFC044A */ {0xDD,0x04,0xE5,0xEC,0x74,0x15,0x42,0xAB,0xAE,0x4A,0xE8,0x0C,0x4D,0xFC,0x04,0x4A};
+BMD_CONST REFIID IID_IDeckLinkEncoderInputCallback                = /* ACF13E61-F4A0-4974-A6A7-59AFF6268B31 */ {0xAC,0xF1,0x3E,0x61,0xF4,0xA0,0x49,0x74,0xA6,0xA7,0x59,0xAF,0xF6,0x26,0x8B,0x31};
 BMD_CONST REFIID IID_IDeckLinkMemoryAllocator                     = /* B36EB6E7-9D29-4AA8-92EF-843B87A289E8 */ {0xB3,0x6E,0xB6,0xE7,0x9D,0x29,0x4A,0xA8,0x92,0xEF,0x84,0x3B,0x87,0xA2,0x89,0xE8};
 BMD_CONST REFIID IID_IDeckLinkAudioOutputCallback                 = /* 403C681B-7F46-4A12-B993-2BB127084EE6 */ {0x40,0x3C,0x68,0x1B,0x7F,0x46,0x4A,0x12,0xB9,0x93,0x2B,0xB1,0x27,0x08,0x4E,0xE6};
 BMD_CONST REFIID IID_IDeckLinkIterator                            = /* 50FB36CD-3063-4B73-BDBB-958087F2D8BA */ {0x50,0xFB,0x36,0xCD,0x30,0x63,0x4B,0x73,0xBD,0xBB,0x95,0x80,0x87,0xF2,0xD8,0xBA};
 BMD_CONST REFIID IID_IDeckLinkAPIInformation                      = /* 7BEA3C68-730D-4322-AF34-8A7152B532A4 */ {0x7B,0xEA,0x3C,0x68,0x73,0x0D,0x43,0x22,0xAF,0x34,0x8A,0x71,0x52,0xB5,0x32,0xA4};
 BMD_CONST REFIID IID_IDeckLinkOutput                              = /* CC5C8A6E-3F2F-4B3A-87EA-FD78AF300564 */ {0xCC,0x5C,0x8A,0x6E,0x3F,0x2F,0x4B,0x3A,0x87,0xEA,0xFD,0x78,0xAF,0x30,0x05,0x64};
 BMD_CONST REFIID IID_IDeckLinkInput                               = /* AF22762B-DFAC-4846-AA79-FA8883560995 */ {0xAF,0x22,0x76,0x2B,0xDF,0xAC,0x48,0x46,0xAA,0x79,0xFA,0x88,0x83,0x56,0x09,0x95};
+BMD_CONST REFIID IID_IDeckLinkEncoderInput                        = /* 270587DA-6B7D-42E7-A1F0-6D853F581185 */ {0x27,0x05,0x87,0xDA,0x6B,0x7D,0x42,0xE7,0xA1,0xF0,0x6D,0x85,0x3F,0x58,0x11,0x85};
 BMD_CONST REFIID IID_IDeckLinkVideoFrame                          = /* 3F716FE0-F023-4111-BE5D-EF4414C05B17 */ {0x3F,0x71,0x6F,0xE0,0xF0,0x23,0x41,0x11,0xBE,0x5D,0xEF,0x44,0x14,0xC0,0x5B,0x17};
 BMD_CONST REFIID IID_IDeckLinkMutableVideoFrame                   = /* 69E2639F-40DA-4E19-B6F2-20ACE815C390 */ {0x69,0xE2,0x63,0x9F,0x40,0xDA,0x4E,0x19,0xB6,0xF2,0x20,0xAC,0xE8,0x15,0xC3,0x90};
 BMD_CONST REFIID IID_IDeckLinkVideoFrame3DExtensions              = /* DA0F7E4A-EDC7-48A8-9CDD-2DB51C729CD7 */ {0xDA,0x0F,0x7E,0x4A,0xED,0xC7,0x48,0xA8,0x9C,0xDD,0x2D,0xB5,0x1C,0x72,0x9C,0xD7};
+BMD_CONST REFIID IID_IDeckLinkVideoFrameMetadataExtensions        = /* D5973DC9-6432-46D0-8F0B-2496F8A1238F */ {0xD5,0x97,0x3D,0xC9,0x64,0x32,0x46,0xD0,0x8F,0x0B,0x24,0x96,0xF8,0xA1,0x23,0x8F};
 BMD_CONST REFIID IID_IDeckLinkVideoInputFrame                     = /* 05CFE374-537C-4094-9A57-680525118F44 */ {0x05,0xCF,0xE3,0x74,0x53,0x7C,0x40,0x94,0x9A,0x57,0x68,0x05,0x25,0x11,0x8F,0x44};
 BMD_CONST REFIID IID_IDeckLinkVideoFrameAncillary                 = /* 732E723C-D1A4-4E29-9E8E-4A88797A0004 */ {0x73,0x2E,0x72,0x3C,0xD1,0xA4,0x4E,0x29,0x9E,0x8E,0x4A,0x88,0x79,0x7A,0x00,0x04};
+BMD_CONST REFIID IID_IDeckLinkEncoderPacket                       = /* B693F36C-316E-4AF1-B6C2-F389A4BCA620 */ {0xB6,0x93,0xF3,0x6C,0x31,0x6E,0x4A,0xF1,0xB6,0xC2,0xF3,0x89,0xA4,0xBC,0xA6,0x20};
+BMD_CONST REFIID IID_IDeckLinkEncoderVideoPacket                  = /* 4E7FD944-E8C7-4EAC-B8C0-7B77F80F5AE0 */ {0x4E,0x7F,0xD9,0x44,0xE8,0xC7,0x4E,0xAC,0xB8,0xC0,0x7B,0x77,0xF8,0x0F,0x5A,0xE0};
+BMD_CONST REFIID IID_IDeckLinkEncoderAudioPacket                  = /* 49E8EDC8-693B-4E14-8EF6-12C658F5A07A */ {0x49,0xE8,0xED,0xC8,0x69,0x3B,0x4E,0x14,0x8E,0xF6,0x12,0xC6,0x58,0xF5,0xA0,0x7A};
+BMD_CONST REFIID IID_IDeckLinkH265NALPacket                       = /* 639C8E0B-68D5-4BDE-A6D4-95F3AEAFF2E7 */ {0x63,0x9C,0x8E,0x0B,0x68,0xD5,0x4B,0xDE,0xA6,0xD4,0x95,0xF3,0xAE,0xAF,0xF2,0xE7};
 BMD_CONST REFIID IID_IDeckLinkAudioInputPacket                    = /* E43D5870-2894-11DE-8C30-0800200C9A66 */ {0xE4,0x3D,0x58,0x70,0x28,0x94,0x11,0xDE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66};
 BMD_CONST REFIID IID_IDeckLinkScreenPreviewCallback               = /* B1D3F49A-85FE-4C5D-95C8-0B5D5DCCD438 */ {0xB1,0xD3,0xF4,0x9A,0x85,0xFE,0x4C,0x5D,0x95,0xC8,0x0B,0x5D,0x5D,0xCC,0xD4,0x38};
 BMD_CONST REFIID IID_IDeckLinkGLScreenPreviewHelper               = /* 504E2209-CAC7-4C1A-9FB4-C5BB6274D22F */ {0x50,0x4E,0x22,0x09,0xCA,0xC7,0x4C,0x1A,0x9F,0xB4,0xC5,0xBB,0x62,0x74,0xD2,0x2F};
 BMD_CONST REFIID IID_IDeckLinkNotificationCallback                = /* B002A1EC-070D-4288-8289-BD5D36E5FF0D */ {0xB0,0x02,0xA1,0xEC,0x07,0x0D,0x42,0x88,0x82,0x89,0xBD,0x5D,0x36,0xE5,0xFF,0x0D};
 BMD_CONST REFIID IID_IDeckLinkNotification                        = /* 0A1FB207-E215-441B-9B19-6FA1575946C5 */ {0x0A,0x1F,0xB2,0x07,0xE2,0x15,0x44,0x1B,0x9B,0x19,0x6F,0xA1,0x57,0x59,0x46,0xC5};
 BMD_CONST REFIID IID_IDeckLinkAttributes                          = /* ABC11843-D966-44CB-96E2-A1CB5D3135C4 */ {0xAB,0xC1,0x18,0x43,0xD9,0x66,0x44,0xCB,0x96,0xE2,0xA1,0xCB,0x5D,0x31,0x35,0xC4};
+BMD_CONST REFIID IID_IDeckLinkStatus                              = /* 5F558200-4028-49BC-BEAC-DB3FA4A96E46 */ {0x5F,0x55,0x82,0x00,0x40,0x28,0x49,0xBC,0xBE,0xAC,0xDB,0x3F,0xA4,0xA9,0x6E,0x46};
 BMD_CONST REFIID IID_IDeckLinkKeyer                               = /* 89AFCAF5-65F8-421E-98F7-96FE5F5BFBA3 */ {0x89,0xAF,0xCA,0xF5,0x65,0xF8,0x42,0x1E,0x98,0xF7,0x96,0xFE,0x5F,0x5B,0xFB,0xA3};
 BMD_CONST REFIID IID_IDeckLinkVideoConversion                     = /* 3BBCB8A2-DA2C-42D9-B5D8-88083644E99A */ {0x3B,0xBC,0xB8,0xA2,0xDA,0x2C,0x42,0xD9,0xB5,0xD8,0x88,0x08,0x36,0x44,0xE9,0x9A};
 BMD_CONST REFIID IID_IDeckLinkDeviceNotificationCallback          = /* 4997053B-0ADF-4CC8-AC70-7A50C4BE728F */ {0x49,0x97,0x05,0x3B,0x0A,0xDF,0x4C,0xC8,0xAC,0x70,0x7A,0x50,0xC4,0xBE,0x72,0x8F};
@@ -90,12 +98,21 @@ enum _BMDVideoOutputFlags {
     bmdVideoOutputDualStream3D                                   = 1 << 4
 };
 
+/* Enum BMDPacketType - Type of packet */
+
+typedef uint32_t BMDPacketType;
+enum _BMDPacketType {
+    bmdPacketTypeStreamInterruptedMarker                         = /* 'sint' */ 0x73696E74,	// A packet of this type marks the time when a video stream was interrupted, for example by a disconnected cable
+    bmdPacketTypeStreamData                                      = /* 'sdat' */ 0x73646174	// Regular stream data
+};
+
 /* Enum BMDFrameFlags - Frame flags */
 
 typedef uint32_t BMDFrameFlags;
 enum _BMDFrameFlags {
     bmdFrameFlagDefault                                          = 0,
     bmdFrameFlagFlipVertical                                     = 1 << 0,
+    bmdFrameContainsHDRMetadata                                  = 1 << 1,
 
     /* Flags that are applicable only to instances of IDeckLinkVideoInputFrame */
 
@@ -133,6 +150,7 @@ enum _BMDDetectedVideoInputFormatFlags {
 
 typedef uint32_t BMDDeckLinkCapturePassthroughMode;
 enum _BMDDeckLinkCapturePassthroughMode {
+    bmdDeckLinkCapturePassthroughModeDisabled                    = /* 'pdis' */ 0x70646973,
     bmdDeckLinkCapturePassthroughModeDirect                      = /* 'pdir' */ 0x70646972,
     bmdDeckLinkCapturePassthroughModeCleanSwitch                 = /* 'pcln' */ 0x70636C6E
 };
@@ -155,6 +173,13 @@ enum _BMDReferenceStatus {
     bmdReferenceLocked                                           = 1 << 1
 };
 
+/* Enum BMDAudioFormat - Audio Format */
+
+typedef uint32_t BMDAudioFormat;
+enum _BMDAudioFormat {
+    bmdAudioFormatPCM                                            = /* 'lpcm' */ 0x6C70636D	// Linear signed PCM samples
+};
+
 /* Enum BMDAudioSampleRate - Audio sample rates supported for output/input */
 
 typedef uint32_t BMDAudioSampleRate;
@@ -267,8 +292,71 @@ enum _BMDVideo3DPackingFormat {
 typedef uint32_t BMDIdleVideoOutputOperation;
 enum _BMDIdleVideoOutputOperation {
     bmdIdleVideoOutputBlack                                      = /* 'blac' */ 0x626C6163,
-    bmdIdleVideoOutputLastFrame                                  = /* 'lafa' */ 0x6C616661,
-    bmdIdleVideoOutputDesktop                                    = /* 'desk' */ 0x6465736B
+    bmdIdleVideoOutputLastFrame                                  = /* 'lafa' */ 0x6C616661
+};
+
+/* Enum BMDVideoEncoderFrameCodingMode - Video frame coding mode */
+
+typedef uint32_t BMDVideoEncoderFrameCodingMode;
+enum _BMDVideoEncoderFrameCodingMode {
+    bmdVideoEncoderFrameCodingModeInter                          = /* 'inte' */ 0x696E7465,
+    bmdVideoEncoderFrameCodingModeIntra                          = /* 'intr' */ 0x696E7472
+};
+
+/* Enum BMDDNxHRLevel - DNxHR Levels */
+
+typedef uint32_t BMDDNxHRLevel;
+enum _BMDDNxHRLevel {
+    bmdDNxHRLevelSQ                                              = /* 'dnsq' */ 0x646E7371,
+    bmdDNxHRLevelLB                                              = /* 'dnlb' */ 0x646E6C62,
+    bmdDNxHRLevelHQ                                              = /* 'dnhq' */ 0x646E6871,
+    bmdDNxHRLevelHQX                                             = /* 'dhqx' */ 0x64687178,
+    bmdDNxHRLevel444                                             = /* 'd444' */ 0x64343434
+};
+
+/* Enum BMDLinkConfiguration - Video link configuration */
+
+typedef uint32_t BMDLinkConfiguration;
+enum _BMDLinkConfiguration {
+    bmdLinkConfigurationSingleLink                               = /* 'lcsl' */ 0x6C63736C,
+    bmdLinkConfigurationDualLink                                 = /* 'lcdl' */ 0x6C63646C,
+    bmdLinkConfigurationQuadLink                                 = /* 'lcql' */ 0x6C63716C
+};
+
+/* Enum BMDDeviceInterface - Device interface type */
+
+typedef uint32_t BMDDeviceInterface;
+enum _BMDDeviceInterface {
+    bmdDeviceInterfacePCI                                        = /* 'pci ' */ 0x70636920,
+    bmdDeviceInterfaceUSB                                        = /* 'usb ' */ 0x75736220,
+    bmdDeviceInterfaceThunderbolt                                = /* 'thun' */ 0x7468756E
+};
+
+/* Enum BMDDeckLinkFrameMetadataID - DeckLink Frame Metadata ID */
+
+typedef uint32_t BMDDeckLinkFrameMetadataID;
+enum _BMDDeckLinkFrameMetadataID {
+    bmdDeckLinkFrameMetadataHDRElectroOpticalTransferFunc        = /* 'eotf' */ 0x656F7466,	// EOTF in range 0-7 as per CEA 861.3
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedX              = /* 'hdrx' */ 0x68647278,	// Red display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedY              = /* 'hdry' */ 0x68647279,	// Red display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenX            = /* 'hdgx' */ 0x68646778,	// Green display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenY            = /* 'hdgy' */ 0x68646779,	// Green display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueX             = /* 'hdbx' */ 0x68646278,	// Blue display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueY             = /* 'hdby' */ 0x68646279,	// Blue display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRWhitePointX                       = /* 'hdwx' */ 0x68647778,	// White point in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRWhitePointY                       = /* 'hdwy' */ 0x68647779,	// White point in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRMaxDisplayMasteringLuminance      = /* 'hdml' */ 0x68646D6C,	// Max display mastering luminance in range 1 cd/m2 - 65535 cd/m2
+    bmdDeckLinkFrameMetadataHDRMinDisplayMasteringLuminance      = /* 'hmil' */ 0x686D696C,	// Min display mastering luminance in range 0.0001 cd/m2 - 6.5535 cd/m2
+    bmdDeckLinkFrameMetadataHDRMaximumContentLightLevel          = /* 'mcll' */ 0x6D636C6C,	// Maximum Content Light Level in range 1 cd/m2 - 65535 cd/m2
+    bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel     = /* 'fall' */ 0x66616C6C	// Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2
+};
+
+/* Enum BMDDuplexMode - Duplex for configurable ports */
+
+typedef uint32_t BMDDuplexMode;
+enum _BMDDuplexMode {
+    bmdDuplexModeFull                                            = /* 'fdup' */ 0x66647570,
+    bmdDuplexModeHalf                                            = /* 'hdup' */ 0x68647570
 };
 
 /* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */
@@ -288,10 +376,16 @@ enum _BMDDeckLinkAttributeID {
     BMDDeckLinkCanOnlyAdjustOverallVideoOutputGain               = /* 'ovog' */ 0x6F766F67,
     BMDDeckLinkHasVideoInputAntiAliasingFilter                   = /* 'aafl' */ 0x6161666C,
     BMDDeckLinkHasBypass                                         = /* 'byps' */ 0x62797073,
-    BMDDeckLinkSupportsDesktopDisplay                            = /* 'extd' */ 0x65787464,
     BMDDeckLinkSupportsClockTimingAdjustment                     = /* 'ctad' */ 0x63746164,
     BMDDeckLinkSupportsFullDuplex                                = /* 'fdup' */ 0x66647570,
     BMDDeckLinkSupportsFullFrameReferenceInputTimingOffset       = /* 'frin' */ 0x6672696E,
+    BMDDeckLinkSupportsSMPTELevelAOutput                         = /* 'lvla' */ 0x6C766C61,
+    BMDDeckLinkSupportsDualLinkSDI                               = /* 'sdls' */ 0x73646C73,
+    BMDDeckLinkSupportsQuadLinkSDI                               = /* 'sqls' */ 0x73716C73,
+    BMDDeckLinkSupportsIdleOutput                                = /* 'idou' */ 0x69646F75,
+    BMDDeckLinkHasLTCTimecodeInput                               = /* 'hltc' */ 0x686C7463,
+    BMDDeckLinkSupportsDuplexModeConfiguration                   = /* 'dupx' */ 0x64757078,
+    BMDDeckLinkSupportsHDRMetadata                               = /* 'hdrm' */ 0x6864726D,
 
     /* Integers */
 
@@ -300,13 +394,20 @@ enum _BMDDeckLinkAttributeID {
     BMDDeckLinkNumberOfSubDevices                                = /* 'nsbd' */ 0x6E736264,
     BMDDeckLinkSubDeviceIndex                                    = /* 'subi' */ 0x73756269,
     BMDDeckLinkPersistentID                                      = /* 'peid' */ 0x70656964,
+    BMDDeckLinkDeviceGroupID                                     = /* 'dgid' */ 0x64676964,
     BMDDeckLinkTopologicalID                                     = /* 'toid' */ 0x746F6964,
     BMDDeckLinkVideoOutputConnections                            = /* 'vocn' */ 0x766F636E,
     BMDDeckLinkVideoInputConnections                             = /* 'vicn' */ 0x7669636E,
     BMDDeckLinkAudioOutputConnections                            = /* 'aocn' */ 0x616F636E,
     BMDDeckLinkAudioInputConnections                             = /* 'aicn' */ 0x6169636E,
-    BMDDeckLinkDeviceBusyState                                   = /* 'dbst' */ 0x64627374,
     BMDDeckLinkVideoIOSupport                                    = /* 'vios' */ 0x76696F73,	// Returns a BMDVideoIOSupport bit field
+    BMDDeckLinkDeckControlConnections                            = /* 'dccn' */ 0x6463636E,
+    BMDDeckLinkDeviceInterface                                   = /* 'dbus' */ 0x64627573,	// Returns a BMDDeviceInterface
+    BMDDeckLinkAudioInputRCAChannelCount                         = /* 'airc' */ 0x61697263,
+    BMDDeckLinkAudioInputXLRChannelCount                         = /* 'aixc' */ 0x61697863,
+    BMDDeckLinkAudioOutputRCAChannelCount                        = /* 'aorc' */ 0x616F7263,
+    BMDDeckLinkAudioOutputXLRChannelCount                        = /* 'aoxc' */ 0x616F7863,
+    BMDDeckLinkPairedDevicePersistentID                          = /* 'ppid' */ 0x70706964,
 
     /* Floats */
 
@@ -314,10 +415,16 @@ enum _BMDDeckLinkAttributeID {
     BMDDeckLinkVideoInputGainMaximum                             = /* 'vigx' */ 0x76696778,
     BMDDeckLinkVideoOutputGainMinimum                            = /* 'vogm' */ 0x766F676D,
     BMDDeckLinkVideoOutputGainMaximum                            = /* 'vogx' */ 0x766F6778,
+    BMDDeckLinkMicrophoneInputGainMinimum                        = /* 'migm' */ 0x6D69676D,
+    BMDDeckLinkMicrophoneInputGainMaximum                        = /* 'migx' */ 0x6D696778,
 
     /* Strings */
 
-    BMDDeckLinkSerialPortDeviceName                              = /* 'slpn' */ 0x736C706E
+    BMDDeckLinkSerialPortDeviceName                              = /* 'slpn' */ 0x736C706E,
+    BMDDeckLinkVendorName                                        = /* 'vndr' */ 0x766E6472,
+    BMDDeckLinkDisplayName                                       = /* 'dspn' */ 0x6473706E,
+    BMDDeckLinkModelName                                         = /* 'mdln' */ 0x6D646C6E,
+    BMDDeckLinkDeviceHandle                                      = /* 'devh' */ 0x64657668
 };
 
 /* Enum BMDDeckLinkAPIInformationID - DeckLinkAPI information ID */
@@ -327,6 +434,52 @@ enum _BMDDeckLinkAPIInformationID {
     BMDDeckLinkAPIVersion                                        = /* 'vers' */ 0x76657273
 };
 
+/* Enum BMDDeckLinkStatusID - DeckLink Status ID */
+
+typedef uint32_t BMDDeckLinkStatusID;
+enum _BMDDeckLinkStatusID {
+
+    /* Integers */
+
+    bmdDeckLinkStatusDetectedVideoInputMode                      = /* 'dvim' */ 0x6476696D,
+    bmdDeckLinkStatusDetectedVideoInputFlags                     = /* 'dvif' */ 0x64766966,
+    bmdDeckLinkStatusCurrentVideoInputMode                       = /* 'cvim' */ 0x6376696D,
+    bmdDeckLinkStatusCurrentVideoInputPixelFormat                = /* 'cvip' */ 0x63766970,
+    bmdDeckLinkStatusCurrentVideoInputFlags                      = /* 'cvif' */ 0x63766966,
+    bmdDeckLinkStatusCurrentVideoOutputMode                      = /* 'cvom' */ 0x63766F6D,
+    bmdDeckLinkStatusCurrentVideoOutputFlags                     = /* 'cvof' */ 0x63766F66,
+    bmdDeckLinkStatusPCIExpressLinkWidth                         = /* 'pwid' */ 0x70776964,
+    bmdDeckLinkStatusPCIExpressLinkSpeed                         = /* 'plnk' */ 0x706C6E6B,
+    bmdDeckLinkStatusLastVideoOutputPixelFormat                  = /* 'opix' */ 0x6F706978,
+    bmdDeckLinkStatusReferenceSignalMode                         = /* 'refm' */ 0x7265666D,
+    bmdDeckLinkStatusReferenceSignalFlags                        = /* 'reff' */ 0x72656666,
+    bmdDeckLinkStatusDuplexMode                                  = /* 'dupx' */ 0x64757078,
+    bmdDeckLinkStatusBusy                                        = /* 'busy' */ 0x62757379,
+
+    /* Flags */
+
+    bmdDeckLinkStatusVideoInputSignalLocked                      = /* 'visl' */ 0x7669736C,
+    bmdDeckLinkStatusReferenceSignalLocked                       = /* 'refl' */ 0x7265666C
+};
+
+/* Enum BMDDeckLinkVideoStatusFlags -  */
+
+typedef uint32_t BMDDeckLinkVideoStatusFlags;
+enum _BMDDeckLinkVideoStatusFlags {
+    bmdDeckLinkVideoStatusPsF                                    = 1 << 0,
+    bmdDeckLinkVideoStatusDualStream3D                           = 1 << 1
+};
+
+/* Enum BMDDuplexStatus - Duplex status of the device */
+
+typedef uint32_t BMDDuplexStatus;
+enum _BMDDuplexStatus {
+    bmdDuplexStatusFullDuplex                                    = /* 'fdup' */ 0x66647570,
+    bmdDuplexStatusHalfDuplex                                    = /* 'hdup' */ 0x68647570,
+    bmdDuplexStatusSimplex                                       = /* 'splx' */ 0x73706C78,
+    bmdDuplexStatusInactive                                      = /* 'inac' */ 0x696E6163
+};
+
 /* Enum BMDDeviceBusyState - Current device busy state */
 
 typedef uint32_t BMDDeviceBusyState;
@@ -359,7 +512,8 @@ enum _BMD3DPreviewFormat {
 
 typedef uint32_t BMDNotifications;
 enum _BMDNotifications {
-    bmdPreferencesChanged                                        = /* 'pref' */ 0x70726566
+    bmdPreferencesChanged                                        = /* 'pref' */ 0x70726566,
+    bmdStatusChanged                                             = /* 'stat' */ 0x73746174
 };
 
 #if defined(__cplusplus)
@@ -368,23 +522,31 @@ enum _BMDNotifications {
 
 class IDeckLinkVideoOutputCallback;
 class IDeckLinkInputCallback;
+class IDeckLinkEncoderInputCallback;
 class IDeckLinkMemoryAllocator;
 class IDeckLinkAudioOutputCallback;
 class IDeckLinkIterator;
 class IDeckLinkAPIInformation;
 class IDeckLinkOutput;
 class IDeckLinkInput;
+class IDeckLinkEncoderInput;
 class IDeckLinkVideoFrame;
 class IDeckLinkMutableVideoFrame;
 class IDeckLinkVideoFrame3DExtensions;
+class IDeckLinkVideoFrameMetadataExtensions;
 class IDeckLinkVideoInputFrame;
 class IDeckLinkVideoFrameAncillary;
+class IDeckLinkEncoderPacket;
+class IDeckLinkEncoderVideoPacket;
+class IDeckLinkEncoderAudioPacket;
+class IDeckLinkH265NALPacket;
 class IDeckLinkAudioInputPacket;
 class IDeckLinkScreenPreviewCallback;
 class IDeckLinkGLScreenPreviewHelper;
 class IDeckLinkNotificationCallback;
 class IDeckLinkNotification;
 class IDeckLinkAttributes;
+class IDeckLinkStatus;
 class IDeckLinkKeyer;
 class IDeckLinkVideoConversion;
 class IDeckLinkDeviceNotificationCallback;
@@ -414,6 +576,19 @@ protected:
     virtual ~IDeckLinkInputCallback () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkEncoderInputCallback - Frame arrival callback. */
+
+class IDeckLinkEncoderInputCallback : public IUnknown
+{
+public:
+    virtual HRESULT VideoInputSignalChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0;
+    virtual HRESULT VideoPacketArrived (/* in */ IDeckLinkEncoderVideoPacket* videoPacket) = 0;
+    virtual HRESULT AudioPacketArrived (/* in */ IDeckLinkEncoderAudioPacket* audioPacket) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderInputCallback () {} // call Release method to drop reference count
+};
+
 /* Interface IDeckLinkMemoryAllocator - Memory allocator for video frames. */
 
 class IDeckLinkMemoryAllocator : public IUnknown
@@ -552,6 +727,43 @@ protected:
     virtual ~IDeckLinkInput () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkEncoderInput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkEncoderInput : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0;
+
+    /* Video Input */
+
+    virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0;
+    virtual HRESULT DisableVideoInput (void) = 0;
+    virtual HRESULT GetAvailablePacketsCount (/* out */ uint32_t *availablePacketsCount) = 0;
+    virtual HRESULT SetMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0;
+
+    /* Audio Input */
+
+    virtual HRESULT EnableAudioInput (/* in */ BMDAudioFormat audioFormat, /* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0;
+    virtual HRESULT DisableAudioInput (void) = 0;
+    virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0;
+
+    /* Input Control */
+
+    virtual HRESULT StartStreams (void) = 0;
+    virtual HRESULT StopStreams (void) = 0;
+    virtual HRESULT PauseStreams (void) = 0;
+    virtual HRESULT FlushStreams (void) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkEncoderInputCallback *theCallback) = 0;
+
+    /* Hardware Timing */
+
+    virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderInput () {} // call Release method to drop reference count
+};
+
 /* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */
 
 class IDeckLinkVideoFrame : public IUnknown
@@ -599,6 +811,20 @@ protected:
     virtual ~IDeckLinkVideoFrame3DExtensions () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkVideoFrameMetadataExtensions - Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDMI HDR information */
+
+class IDeckLinkVideoFrameMetadataExtensions : public IUnknown
+{
+public:
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ int64_t *value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ double *value) = 0;
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ bool* value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ const char **value) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoFrameMetadataExtensions () {} // call Release method to drop reference count
+};
+
 /* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */
 
 class IDeckLinkVideoInputFrame : public IDeckLinkVideoFrame
@@ -625,6 +851,58 @@ protected:
     virtual ~IDeckLinkVideoFrameAncillary () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkEncoderPacket - Interface to encapsulate an encoded packet. */
+
+class IDeckLinkEncoderPacket : public IUnknown
+{
+public:
+    virtual HRESULT GetBytes (/* out */ void **buffer) = 0;
+    virtual long GetSize (void) = 0;
+    virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* in */ BMDTimeScale timeScale) = 0;
+    virtual BMDPacketType GetPacketType (void) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderPacket () {} // call Release method to drop reference count
+};
+
+/* Interface IDeckLinkEncoderVideoPacket - Provided by the IDeckLinkEncoderInput video packet arrival callback. */
+
+class IDeckLinkEncoderVideoPacket : public IDeckLinkEncoderPacket
+{
+public:
+    virtual BMDPixelFormat GetPixelFormat (void) = 0;
+    virtual HRESULT GetHardwareReferenceTimestamp (/* in */ BMDTimeScale timeScale, /* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration) = 0;
+
+    virtual HRESULT GetTimecode (/* in */ BMDTimecodeFormat format, /* out */ IDeckLinkTimecode **timecode) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderVideoPacket () {} // call Release method to drop reference count
+};
+
+/* Interface IDeckLinkEncoderAudioPacket - Provided by the IDeckLinkEncoderInput audio packet arrival callback. */
+
+class IDeckLinkEncoderAudioPacket : public IDeckLinkEncoderPacket
+{
+public:
+    virtual BMDAudioFormat GetAudioFormat (void) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderAudioPacket () {} // call Release method to drop reference count
+};
+
+/* Interface IDeckLinkH265NALPacket - Obtained through QueryInterface() on an IDeckLinkEncoderVideoPacket object */
+
+class IDeckLinkH265NALPacket : public IDeckLinkEncoderVideoPacket
+{
+public:
+    virtual HRESULT GetUnitType (/* out */ uint8_t *unitType) = 0;
+    virtual HRESULT GetBytesNoPrefix (/* out */ void **buffer) = 0;
+    virtual long GetSizeNoPrefix (void) = 0;
+
+protected:
+    virtual ~IDeckLinkH265NALPacket () {} // call Release method to drop reference count
+};
+
 /* Interface IDeckLinkAudioInputPacket - Provided by the IDeckLinkInput callback. */
 
 class IDeckLinkAudioInputPacket : public IUnknown
@@ -697,6 +975,21 @@ protected:
     virtual ~IDeckLinkAttributes () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkStatus - DeckLink Status interface */
+
+class IDeckLinkStatus : public IUnknown
+{
+public:
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkStatusID statusID, /* out */ bool *value) = 0;
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkStatusID statusID, /* out */ int64_t *value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkStatusID statusID, /* out */ double *value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkStatusID statusID, /* out */ const char **value) = 0;
+    virtual HRESULT GetBytes (/* in */ BMDDeckLinkStatusID statusID, /* out */ void *buffer, /* in, out */ uint32_t *bufferSize) = 0;
+
+protected:
+    virtual ~IDeckLinkStatus () {} // call Release method to drop reference count
+};
+
 /* Interface IDeckLinkKeyer - DeckLink Keyer interface */
 
 class IDeckLinkKeyer : public IUnknown
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration.h
index 3eb6148..dedf15e 100644
--- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration.h
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -42,7 +42,8 @@
 
 // Interface ID Declarations
 
-BMD_CONST REFIID IID_IDeckLinkConfiguration                       = /* 1E69FCF6-4203-4936-8076-2A9F4CFD50CB */ {0x1E,0x69,0xFC,0xF6,0x42,0x03,0x49,0x36,0x80,0x76,0x2A,0x9F,0x4C,0xFD,0x50,0xCB};
+BMD_CONST REFIID IID_IDeckLinkConfiguration                       = /* CB71734A-FE37-4E8D-8E13-802133A1C3F2 */ {0xCB,0x71,0x73,0x4A,0xFE,0x37,0x4E,0x8D,0x8E,0x13,0x80,0x21,0x33,0xA1,0xC3,0xF2};
+BMD_CONST REFIID IID_IDeckLinkEncoderConfiguration                = /* 138050E5-C60A-4552-BF3F-0F358049327E */ {0x13,0x80,0x50,0xE5,0xC6,0x0A,0x45,0x52,0xBF,0x3F,0x0F,0x35,0x80,0x49,0x32,0x7E};
 
 /* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */
 
@@ -62,6 +63,7 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigHDMI3DPackingFormat                         = /* '3dpf' */ 0x33647066,
     bmdDeckLinkConfigBypass                                      = /* 'byps' */ 0x62797073,
     bmdDeckLinkConfigClockTimingAdjustment                       = /* 'ctad' */ 0x63746164,
+    bmdDeckLinkConfigDuplexMode                                  = /* 'dupx' */ 0x64757078,
 
     /* Audio Input/Output Flags */
 
@@ -72,9 +74,10 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigFieldFlickerRemoval                         = /* 'fdfr' */ 0x66646672,
     bmdDeckLinkConfigHD1080p24ToHD1080i5994Conversion            = /* 'to59' */ 0x746F3539,
     bmdDeckLinkConfig444SDIVideoOutput                           = /* '444o' */ 0x3434346F,
-    bmdDeckLinkConfigSingleLinkVideoOutput                       = /* 'sglo' */ 0x73676C6F,
     bmdDeckLinkConfigBlackVideoOutputDuringCapture               = /* 'bvoc' */ 0x62766F63,
     bmdDeckLinkConfigLowLatencyVideoOutput                       = /* 'llvo' */ 0x6C6C766F,
+    bmdDeckLinkConfigDownConversionOnAllAnalogOutput             = /* 'caao' */ 0x6361616F,
+    bmdDeckLinkConfigSMPTELevelAOutput                           = /* 'smta' */ 0x736D7461,
 
     /* Video Output Integers */
 
@@ -85,6 +88,7 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigVideoOutputIdleOperation                    = /* 'voio' */ 0x766F696F,
     bmdDeckLinkConfigDefaultVideoOutputMode                      = /* 'dvom' */ 0x64766F6D,
     bmdDeckLinkConfigDefaultVideoOutputModeFlags                 = /* 'dvof' */ 0x64766F66,
+    bmdDeckLinkConfigSDIOutputLinkConfiguration                  = /* 'solc' */ 0x736F6C63,
 
     /* Video Output Floats */
 
@@ -100,6 +104,7 @@ enum _BMDDeckLinkConfigurationID {
 
     bmdDeckLinkConfigVideoInputScanning                          = /* 'visc' */ 0x76697363,	// Applicable to H264 Pro Recorder only
     bmdDeckLinkConfigUseDedicatedLTCInput                        = /* 'dltc' */ 0x646C7463,	// Use timecode from LTC input instead of SDI stream
+    bmdDeckLinkConfigSDIInput3DPayloadOverride                   = /* '3dds' */ 0x33646473,
 
     /* Video Input Integers */
 
@@ -122,6 +127,10 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigVideoInputSVideoLumaGain                    = /* 'islg' */ 0x69736C67,
     bmdDeckLinkConfigVideoInputSVideoChromaGain                  = /* 'iscg' */ 0x69736367,
 
+    /* Audio Input Flags */
+
+    bmdDeckLinkConfigMicrophonePhantomPower                      = /* 'mphp' */ 0x6D706870,
+
     /* Audio Input Integers */
 
     bmdDeckLinkConfigAudioInputConnection                        = /* 'aicn' */ 0x6169636E,
@@ -133,6 +142,7 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigAnalogAudioInputScaleChannel3               = /* 'ais3' */ 0x61697333,
     bmdDeckLinkConfigAnalogAudioInputScaleChannel4               = /* 'ais4' */ 0x61697334,
     bmdDeckLinkConfigDigitalAudioInputScale                      = /* 'dais' */ 0x64616973,
+    bmdDeckLinkConfigMicrophoneInputGain                         = /* 'micg' */ 0x6D696367,
 
     /* Audio Output Integers */
 
@@ -144,12 +154,55 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigAnalogAudioOutputScaleChannel2              = /* 'aos2' */ 0x616F7332,
     bmdDeckLinkConfigAnalogAudioOutputScaleChannel3              = /* 'aos3' */ 0x616F7333,
     bmdDeckLinkConfigAnalogAudioOutputScaleChannel4              = /* 'aos4' */ 0x616F7334,
-    bmdDeckLinkConfigDigitalAudioOutputScale                     = /* 'daos' */ 0x64616F73
+    bmdDeckLinkConfigDigitalAudioOutputScale                     = /* 'daos' */ 0x64616F73,
+    bmdDeckLinkConfigHeadphoneVolume                             = /* 'hvol' */ 0x68766F6C,
+
+    /* Device Information Strings */
+
+    bmdDeckLinkConfigDeviceInformationLabel                      = /* 'dila' */ 0x64696C61,
+    bmdDeckLinkConfigDeviceInformationSerialNumber               = /* 'disn' */ 0x6469736E,
+    bmdDeckLinkConfigDeviceInformationCompany                    = /* 'dico' */ 0x6469636F,
+    bmdDeckLinkConfigDeviceInformationPhone                      = /* 'diph' */ 0x64697068,
+    bmdDeckLinkConfigDeviceInformationEmail                      = /* 'diem' */ 0x6469656D,
+    bmdDeckLinkConfigDeviceInformationDate                       = /* 'dida' */ 0x64696461,
+
+    /* Deck Control Integers */
+
+    bmdDeckLinkConfigDeckControlConnection                       = /* 'dcco' */ 0x6463636F
+};
+
+/* Enum BMDDeckLinkEncoderConfigurationID - DeckLink Encoder Configuration ID */
+
+typedef uint32_t BMDDeckLinkEncoderConfigurationID;
+enum _BMDDeckLinkEncoderConfigurationID {
+
+    /* Video Encoder Integers */
+
+    bmdDeckLinkEncoderConfigPreferredBitDepth                    = /* 'epbr' */ 0x65706272,
+    bmdDeckLinkEncoderConfigFrameCodingMode                      = /* 'efcm' */ 0x6566636D,
+
+    /* HEVC/H.265 Encoder Integers */
+
+    bmdDeckLinkEncoderConfigH265TargetBitrate                    = /* 'htbr' */ 0x68746272,
+
+    /* DNxHR/DNxHD Compression ID */
+
+    bmdDeckLinkEncoderConfigDNxHRCompressionID                   = /* 'dcid' */ 0x64636964,
+
+    /* DNxHR/DNxHD Level */
+
+    bmdDeckLinkEncoderConfigDNxHRLevel                           = /* 'dlev' */ 0x646C6576,
+
+    /* Encoded Sample Decriptions */
+
+    bmdDeckLinkEncoderConfigMPEG4SampleDescription               = /* 'stsE' */ 0x73747345,	// Full MPEG4 sample description (aka SampleEntry of an 'stsd' atom-box). Useful for MediaFoundation, QuickTime, MKV and more
+    bmdDeckLinkEncoderConfigMPEG4CodecSpecificDesc               = /* 'esds' */ 0x65736473	// Sample description extensions only (atom stream, each with size and fourCC header). Useful for AVFoundation, VideoToolbox, MKV and more
 };
 
 // Forward Declarations
 
 class IDeckLinkConfiguration;
+class IDeckLinkEncoderConfiguration;
 
 /* Interface IDeckLinkConfiguration - DeckLink Configuration interface */
 
@@ -170,6 +223,25 @@ protected:
     virtual ~IDeckLinkConfiguration () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkEncoderConfiguration - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */
+
+class IDeckLinkEncoderConfiguration : public IUnknown
+{
+public:
+    virtual HRESULT SetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ bool value) = 0;
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ bool *value) = 0;
+    virtual HRESULT SetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ int64_t value) = 0;
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ int64_t *value) = 0;
+    virtual HRESULT SetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ double value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ double *value) = 0;
+    virtual HRESULT SetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ const char *value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ const char **value) = 0;
+    virtual HRESULT GetBytes (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ void *buffer /* optional */, /* in, out */ uint32_t *bufferSize) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderConfiguration () {} // call Release method to drop reference count
+};
+
 /* Functions */
 
 extern "C" {
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h
new file mode 100644
index 0000000..30bd5ae
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h
@@ -0,0 +1,60 @@
+/* -LICENSE-START-
+** Copyright (c) 2014 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPICONFIGURATION_v10_2_H
+#define BMD_DECKLINKAPICONFIGURATION_v10_2_H
+
+#include "DeckLinkAPIConfiguration.h"
+
+// Interface ID Declarations
+
+BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_2                = /* C679A35B-610C-4D09-B748-1D0478100FC0 */ {0xC6,0x79,0xA3,0x5B,0x61,0x0C,0x4D,0x09,0xB7,0x48,0x1D,0x04,0x78,0x10,0x0F,0xC0};
+
+// Forward Declarations
+
+class IDeckLinkConfiguration_v10_2;
+
+/* Interface IDeckLinkConfiguration_v10_2 - DeckLink Configuration interface */
+
+class IDeckLinkConfiguration_v10_2 : public IUnknown
+{
+public:
+    virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0;
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0;
+    virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0;
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0;
+    virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0;
+    virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ const char *value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ const char **value) = 0;
+    virtual HRESULT WriteConfigurationToPreferences (void) = 0;
+
+protected:
+    virtual ~IDeckLinkConfiguration_v10_2 () {} // call Release method to drop reference count
+};
+
+#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_2_H) */
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_4.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_4.h
new file mode 100644
index 0000000..750387f
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_4.h
@@ -0,0 +1,63 @@
+/* -LICENSE-START-
+** Copyright (c) 2015 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPICONFIGURATION_v10_4_H
+#define BMD_DECKLINKAPICONFIGURATION_v10_4_H
+
+#include "DeckLinkAPIConfiguration.h"
+
+// Interface ID Declarations
+
+BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_4                       = /* 1E69FCF6-4203-4936-8076-2A9F4CFD50CB */ {0x1E,0x69,0xFC,0xF6,0x42,0x03,0x49,0x36,0x80,0x76,0x2A,0x9F,0x4C,0xFD,0x50,0xCB};
+
+
+//
+// Forward Declarations
+
+class IDeckLinkConfiguration_v10_4;
+
+/* Interface IDeckLinkConfiguration_v10_4 - DeckLink Configuration interface */
+
+class IDeckLinkConfiguration_v10_4 : public IUnknown
+{
+public:
+    virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0;
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0;
+    virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0;
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0;
+    virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0;
+    virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ const char *value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ const char **value) = 0;
+    virtual HRESULT WriteConfigurationToPreferences (void) = 0;
+
+protected:
+    virtual ~IDeckLinkConfiguration_v10_4 () {} // call Release method to drop reference count
+};
+
+
+#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_4_H) */
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h
new file mode 100644
index 0000000..da36e50
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h
@@ -0,0 +1,60 @@
+/* -LICENSE-START-
+** Copyright (c) 2015 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPICONFIGURATION_v10_5_H
+#define BMD_DECKLINKAPICONFIGURATION_v10_5_H
+
+#include "DeckLinkAPIConfiguration.h"
+
+// Interface ID Declarations
+
+BMD_CONST REFIID IID_IDeckLinkEncoderConfiguration_v10_5          = /* 67455668-0848-45DF-8D8E-350A77C9A028 */ {0x67,0x45,0x56,0x68,0x08,0x48,0x45,0xDF,0x8D,0x8E,0x35,0x0A,0x77,0xC9,0xA0,0x28};
+
+// Forward Declarations
+
+class IDeckLinkEncoderConfiguration_v10_5;
+
+/* Interface IDeckLinkEncoderConfiguration_v10_5 - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */
+
+class IDeckLinkEncoderConfiguration_v10_5 : public IUnknown
+{
+public:
+    virtual HRESULT SetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ bool value) = 0;
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ bool *value) = 0;
+    virtual HRESULT SetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ int64_t value) = 0;
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ int64_t *value) = 0;
+    virtual HRESULT SetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ double value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ double *value) = 0;
+    virtual HRESULT SetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ const char *value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ const char **value) = 0;
+    virtual HRESULT GetDecoderConfigurationInfo (/* out */ void *buffer, /* in */ long bufferSize, /* out */ long *returnedSize) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderConfiguration_v10_5 () {} // call Release method to drop reference count
+};
+
+#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_5_H) */
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDeckControl.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDeckControl.h
index 77827e1..8dc069c 100644
--- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDeckControl.h
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDeckControl.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDiscovery.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDiscovery.h
index 042f85e..d9253ff 100644
--- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDiscovery.h
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDiscovery.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp
new file mode 100644
index 0000000..4963060
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp
@@ -0,0 +1,109 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+**/
+
+#include <stdio.h>
+#include <pthread.h>
+#include <dlfcn.h>
+
+#include "DeckLinkAPI_v7_6.h"
+
+#define kDeckLinkAPI_Name "libDeckLinkAPI.so"
+#define KDeckLinkPreviewAPI_Name "libDeckLinkPreviewAPI.so"
+
+typedef IDeckLinkIterator* (*CreateIteratorFunc_v7_6)(void);
+typedef IDeckLinkGLScreenPreviewHelper_v7_6* (*CreateOpenGLScreenPreviewHelperFunc_v7_6)(void);
+typedef IDeckLinkVideoConversion_v7_6* (*CreateVideoConversionInstanceFunc_v7_6)(void);
+
+static pthread_once_t					gDeckLinkOnceControl = PTHREAD_ONCE_INIT;
+static pthread_once_t					gPreviewOnceControl = PTHREAD_ONCE_INIT;
+
+static CreateIteratorFunc_v7_6						gCreateIteratorFunc			= NULL;
+static CreateOpenGLScreenPreviewHelperFunc_v7_6		gCreateOpenGLPreviewFunc	= NULL;
+static CreateVideoConversionInstanceFunc_v7_6		gCreateVideoConversionFunc	= NULL;
+
+void	InitDeckLinkAPI_v7_6 (void)
+{
+	void *libraryHandle;
+
+	libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW|RTLD_GLOBAL);
+	if (!libraryHandle)
+	{
+		fprintf(stderr, "%s\n", dlerror());
+		return;
+	}
+
+	gCreateIteratorFunc = (CreateIteratorFunc_v7_6)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance");
+	if (!gCreateIteratorFunc)
+		fprintf(stderr, "%s\n", dlerror());
+	gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc_v7_6)dlsym(libraryHandle, "CreateVideoConversionInstance");
+	if (!gCreateVideoConversionFunc)
+		fprintf(stderr, "%s\n", dlerror());
+}
+
+void	InitDeckLinkPreviewAPI_v7_6 (void)
+{
+	void *libraryHandle;
+
+	libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW|RTLD_GLOBAL);
+	if (!libraryHandle)
+	{
+		fprintf(stderr, "%s\n", dlerror());
+		return;
+	}
+	gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc_v7_6)dlsym(libraryHandle, "CreateOpenGLScreenPreviewHelper");
+	if (!gCreateOpenGLPreviewFunc)
+		fprintf(stderr, "%s\n", dlerror());
+}
+
+IDeckLinkIterator*		CreateDeckLinkIteratorInstance_v7_6 (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6);
+
+	if (gCreateIteratorFunc == NULL)
+		return NULL;
+	return gCreateIteratorFunc();
+}
+
+IDeckLinkGLScreenPreviewHelper_v7_6*		CreateOpenGLScreenPreviewHelper_v7_6 (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6);
+	pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI_v7_6);
+
+	if (gCreateOpenGLPreviewFunc == NULL)
+		return NULL;
+	return gCreateOpenGLPreviewFunc();
+}
+
+IDeckLinkVideoConversion_v7_6* CreateVideoConversionInstance_v7_6 (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6);
+
+	if (gCreateVideoConversionFunc == NULL)
+		return NULL;
+	return gCreateVideoConversionFunc();
+}
+
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp
new file mode 100644
index 0000000..770f143
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp
@@ -0,0 +1,133 @@
+/* -LICENSE-START-
+** Copyright (c) 2011 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+**/
+
+#include <stdio.h>
+#include <pthread.h>
+#include <dlfcn.h>
+
+#include "DeckLinkAPI_v8_0.h"
+
+#define kDeckLinkAPI_Name "libDeckLinkAPI.so"
+#define KDeckLinkPreviewAPI_Name "libDeckLinkPreviewAPI.so"
+
+typedef IDeckLinkIterator_v8_0* (*CreateIteratorFunc)(void);
+typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void);
+typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void);
+typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void);
+
+static pthread_once_t					gDeckLinkOnceControl = PTHREAD_ONCE_INIT;
+static pthread_once_t					gPreviewOnceControl = PTHREAD_ONCE_INIT;
+
+static bool								gLoadedDeckLinkAPI = false;
+
+static CreateIteratorFunc					gCreateIteratorFunc = NULL;
+static CreateAPIInformationFunc				gCreateAPIInformationFunc = NULL;
+static CreateOpenGLScreenPreviewHelperFunc	gCreateOpenGLPreviewFunc = NULL;
+static CreateVideoConversionInstanceFunc	gCreateVideoConversionFunc	= NULL;
+
+void	InitDeckLinkAPI (void)
+{
+	void *libraryHandle;
+
+	libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW|RTLD_GLOBAL);
+	if (!libraryHandle)
+	{
+		fprintf(stderr, "%s\n", dlerror());
+		return;
+	}
+
+	gLoadedDeckLinkAPI = true;
+
+	gCreateIteratorFunc = (CreateIteratorFunc)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance_0001");
+	if (!gCreateIteratorFunc)
+		fprintf(stderr, "%s\n", dlerror());
+	gCreateAPIInformationFunc = (CreateAPIInformationFunc)dlsym(libraryHandle, "CreateDeckLinkAPIInformationInstance_0001");
+	if (!gCreateAPIInformationFunc)
+		fprintf(stderr, "%s\n", dlerror());
+	gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)dlsym(libraryHandle, "CreateVideoConversionInstance_0001");
+	if (!gCreateVideoConversionFunc)
+		fprintf(stderr, "%s\n", dlerror());
+}
+
+void	InitDeckLinkPreviewAPI (void)
+{
+	void *libraryHandle;
+
+	libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW|RTLD_GLOBAL);
+	if (!libraryHandle)
+	{
+		fprintf(stderr, "%s\n", dlerror());
+		return;
+	}
+	gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)dlsym(libraryHandle, "CreateOpenGLScreenPreviewHelper_0001");
+	if (!gCreateOpenGLPreviewFunc)
+		fprintf(stderr, "%s\n", dlerror());
+}
+
+bool		IsDeckLinkAPIPresent (void)
+{
+	// If the DeckLink API dynamic library was successfully loaded, return this knowledge to the caller
+	return gLoadedDeckLinkAPI;
+}
+
+IDeckLinkIterator_v8_0*		CreateDeckLinkIteratorInstance (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+	if (gCreateIteratorFunc == NULL)
+		return NULL;
+	return gCreateIteratorFunc();
+}
+
+IDeckLinkAPIInformation*	CreateDeckLinkAPIInformationInstance (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+	if (gCreateAPIInformationFunc == NULL)
+		return NULL;
+	return gCreateAPIInformationFunc();
+}
+
+IDeckLinkGLScreenPreviewHelper*		CreateOpenGLScreenPreviewHelper (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+	pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI);
+
+	if (gCreateOpenGLPreviewFunc == NULL)
+		return NULL;
+	return gCreateOpenGLPreviewFunc();
+}
+
+IDeckLinkVideoConversion* CreateVideoConversionInstance (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+	if (gCreateVideoConversionFunc == NULL)
+		return NULL;
+	return gCreateVideoConversionFunc();
+}
+
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIModes.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIModes.h
index b73174c..6c52051 100644
--- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIModes.h
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIModes.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -135,7 +135,12 @@ enum _BMDPixelFormat {
     bmdFormat12BitRGB                                            = /* 'R12B' */ 0x52313242,	// Big-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component
     bmdFormat12BitRGBLE                                          = /* 'R12L' */ 0x5231324C,	// Little-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component
     bmdFormat10BitRGBXLE                                         = /* 'R10l' */ 0x5231306C,	// Little-endian 10-bit RGB with SMPTE video levels (64-940)
-    bmdFormat10BitRGBX                                           = /* 'R10b' */ 0x52313062	// Big-endian 10-bit RGB with SMPTE video levels (64-940)
+    bmdFormat10BitRGBX                                           = /* 'R10b' */ 0x52313062,	// Big-endian 10-bit RGB with SMPTE video levels (64-940)
+    bmdFormatH265                                                = /* 'hev1' */ 0x68657631,	// High Efficiency Video Coding (HEVC/h.265)
+
+    /* AVID DNxHR */
+
+    bmdFormatDNxHR                                               = /* 'AVdh' */ 0x41566468
 };
 
 /* Enum BMDDisplayModeFlags - Flags to describe the characteristics of an IDeckLinkDisplayMode. */
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPITypes.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPITypes.h
index 59a0a47..979a9aa 100644
--- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPITypes.h
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPITypes.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -77,7 +77,17 @@ enum _BMDAudioConnection {
     bmdAudioConnectionAESEBU                                     = 1 << 1,
     bmdAudioConnectionAnalog                                     = 1 << 2,
     bmdAudioConnectionAnalogXLR                                  = 1 << 3,
-    bmdAudioConnectionAnalogRCA                                  = 1 << 4
+    bmdAudioConnectionAnalogRCA                                  = 1 << 4,
+    bmdAudioConnectionMicrophone                                 = 1 << 5,
+    bmdAudioConnectionHeadphones                                 = 1 << 6
+};
+
+/* Enum BMDDeckControlConnection - Deck control connections */
+
+typedef uint32_t BMDDeckControlConnection;
+enum _BMDDeckControlConnection {
+    bmdDeckControlConnectionRS422Remote1                         = 1 << 0,
+    bmdDeckControlConnectionRS422Remote2                         = 1 << 1
 };
 
 // Forward Declarations
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIVersion.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIVersion.h
index 719ae2b..dfd1799 100644
--- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIVersion.h
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIVersion.h
@@ -30,7 +30,8 @@
 #ifndef __DeckLink_API_Version_h__
 #define __DeckLink_API_Version_h__
 
-#define BLACKMAGIC_DECKLINK_API_VERSION					0x0a030100
-#define BLACKMAGIC_DECKLINK_API_VERSION_STRING			"10.3.1"
+#define BLACKMAGIC_DECKLINK_API_VERSION					0x0a080000
+#define BLACKMAGIC_DECKLINK_API_VERSION_STRING			"10.8"
 
 #endif	// __DeckLink_API_Version_h__
+
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_2.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_2.h
new file mode 100644
index 0000000..a465133
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_2.h
@@ -0,0 +1,55 @@
+/* -LICENSE-START-
+** Copyright (c) 2014 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v10_2_H
+#define BMD_DECKLINKAPI_v10_2_H
+
+#include "DeckLinkAPI.h"
+
+// Type Declarations
+
+/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */
+
+typedef uint32_t BMDDeckLinkConfigurationID_v10_2;
+enum  _BMDDeckLinkConfigurationID_v10_2 {
+    /* Video output flags */
+
+    bmdDeckLinkConfig3GBpsVideoOutput_v10_2                      = '3gbs',
+};
+
+/* Enum BMDAudioConnection_v10_2 - Audio connection types */
+
+typedef uint32_t BMDAudioConnection_v10_2;
+enum _BMDAudioConnection_v10_2 {
+    bmdAudioConnectionEmbedded_v10_2                             = /* 'embd' */ 0x656D6264,
+    bmdAudioConnectionAESEBU_v10_2                               = /* 'aes ' */ 0x61657320,
+    bmdAudioConnectionAnalog_v10_2                               = /* 'anlg' */ 0x616E6C67,
+    bmdAudioConnectionAnalogXLR_v10_2                            = /* 'axlr' */ 0x61786C72,
+    bmdAudioConnectionAnalogRCA_v10_2                            = /* 'arca' */ 0x61726361
+};
+
+#endif /* defined(BMD_DECKLINKAPI_v10_2_H) */
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_4.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_4.h
new file mode 100644
index 0000000..7e5019c
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_4.h
@@ -0,0 +1,45 @@
+/* -LICENSE-START-
+** Copyright (c) 2015 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v10_4_H
+#define BMD_DECKLINKAPI_v10_4_H
+
+#include "DeckLinkAPI.h"
+
+// Type Declarations
+
+/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */
+
+typedef uint32_t BMDDeckLinkConfigurationID_v10_4;
+enum _BMDDeckLinkConfigurationID_v10_4 {
+
+    /* Video output flags */
+
+    bmdDeckLinkConfigSingleLinkVideoOutput_v10_4                       = /* 'sglo' */ 0x73676C6F,
+};
+
+#endif /* defined(BMD_DECKLINKAPI_v10_4_H) */
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_5.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_5.h
new file mode 100644
index 0000000..4439dae
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_5.h
@@ -0,0 +1,46 @@
+/* -LICENSE-START-
+** Copyright (c) 2015 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v10_5_H
+#define BMD_DECKLINKAPI_v10_5_H
+
+#include "DeckLinkAPI.h"
+
+// Type Declarations
+
+/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */
+
+typedef uint32_t BMDDeckLinkAttributeID_v10_5;
+enum _BMDDeckLinkAttributeID_v10_5 {
+
+    /* Integers */
+
+    BMDDeckLinkDeviceBusyState_v10_5                             = /* 'dbst' */ 0x64627374,
+};
+
+#endif /* defined(BMD_DECKLINKAPI_v10_5_H) */
+
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_6.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_6.h
new file mode 100644
index 0000000..3c93578
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_6.h
@@ -0,0 +1,50 @@
+/* -LICENSE-START-
+** Copyright (c) 2016 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v10_6_H
+#define BMD_DECKLINKAPI_v10_6_H
+
+#include "DeckLinkAPI.h"
+
+// Type Declarations
+
+/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */
+
+typedef uint32_t BMDDeckLinkAttributeID_c10_6;
+enum _BMDDeckLinkAttributeID_v10_6 {
+
+    /* Flags */
+
+    BMDDeckLinkSupportsDesktopDisplay_v10_6                      = /* 'extd' */ 0x65787464,
+};
+
+typedef uint32_t BMDIdleVideoOutputOperation_v10_6;
+enum _BMDIdleVideoOutputOperation_v10_6 {
+    bmdIdleVideoOutputDesktop_v10_6                              = /* 'desk' */ 0x6465736B
+};
+
+#endif /* defined(BMD_DECKLINKAPI_v10_6_H) */
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_1.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_1.h
new file mode 100644
index 0000000..1602d6a
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_1.h
@@ -0,0 +1,198 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPI_v7_1.h */
+
+#ifndef __DeckLink_API_v7_1_h__
+#define __DeckLink_API_v7_1_h__
+
+#include "DeckLinkAPI.h"
+
+// "B28131B6-59AC-4857-B5AC-CD75D5883E2F"
+#define IID_IDeckLinkDisplayModeIterator_v7_1	(REFIID){0xB2,0x81,0x31,0xB6,0x59,0xAC,0x48,0x57,0xB5,0xAC,0xCD,0x75,0xD5,0x88,0x3E,0x2F}
+
+// "AF0CD6D5-8376-435E-8433-54F9DD530AC3"
+#define IID_IDeckLinkDisplayMode_v7_1			(REFIID){0xAF,0x0C,0xD6,0xD5,0x83,0x76,0x43,0x5E,0x84,0x33,0x54,0xF9,0xDD,0x53,0x0A,0xC3}
+
+// "EBD01AFA-E4B0-49C6-A01D-EDB9D1B55FD9"
+#define IID_IDeckLinkVideoOutputCallback_v7_1	(REFIID){0xEB,0xD0,0x1A,0xFA,0xE4,0xB0,0x49,0xC6,0xA0,0x1D,0xED,0xB9,0xD1,0xB5,0x5F,0xD9}
+
+// "7F94F328-5ED4-4E9F-9729-76A86BDC99CC"
+#define IID_IDeckLinkInputCallback_v7_1			(REFIID){0x7F,0x94,0xF3,0x28,0x5E,0xD4,0x4E,0x9F,0x97,0x29,0x76,0xA8,0x6B,0xDC,0x99,0xCC}
+
+// "AE5B3E9B-4E1E-4535-B6E8-480FF52F6CE5"
+#define IID_IDeckLinkOutput_v7_1				(REFIID){0xAE,0x5B,0x3E,0x9B,0x4E,0x1E,0x45,0x35,0xB6,0xE8,0x48,0x0F,0xF5,0x2F,0x6C,0xE5}
+
+// "2B54EDEF-5B32-429F-BA11-BB990596EACD"
+#define IID_IDeckLinkInput_v7_1					(REFIID){0x2B,0x54,0xED,0xEF,0x5B,0x32,0x42,0x9F,0xBA,0x11,0xBB,0x99,0x05,0x96,0xEA,0xCD}
+
+// "333F3A10-8C2D-43CF-B79D-46560FEEA1CE"
+#define IID_IDeckLinkVideoFrame_v7_1			(REFIID){0x33,0x3F,0x3A,0x10,0x8C,0x2D,0x43,0xCF,0xB7,0x9D,0x46,0x56,0x0F,0xEE,0xA1,0xCE}
+
+// "C8B41D95-8848-40EE-9B37-6E3417FB114B"
+#define IID_IDeckLinkVideoInputFrame_v7_1		(REFIID){0xC8,0xB4,0x1D,0x95,0x88,0x48,0x40,0xEE,0x9B,0x37,0x6E,0x34,0x17,0xFB,0x11,0x4B}
+
+// "C86DE4F6-A29F-42E3-AB3A-1363E29F0788"
+#define IID_IDeckLinkAudioInputPacket_v7_1		(REFIID){0xC8,0x6D,0xE4,0xF6,0xA2,0x9F,0x42,0xE3,0xAB,0x3A,0x13,0x63,0xE2,0x9F,0x07,0x88}
+
+#if defined(__cplusplus)
+
+class IDeckLinkDisplayModeIterator_v7_1;
+class IDeckLinkDisplayMode_v7_1;
+class IDeckLinkVideoFrame_v7_1;
+class IDeckLinkVideoInputFrame_v7_1;
+class IDeckLinkAudioInputPacket_v7_1;
+
+class IDeckLinkDisplayModeIterator_v7_1 : public IUnknown
+{
+public:
+	virtual	HRESULT	STDMETHODCALLTYPE	Next (IDeckLinkDisplayMode_v7_1* *deckLinkDisplayMode) = 0;
+};
+
+
+class IDeckLinkDisplayMode_v7_1 : public IUnknown
+{
+public:
+	virtual	HRESULT			STDMETHODCALLTYPE	GetName (const char **name) = 0;
+	virtual	BMDDisplayMode	STDMETHODCALLTYPE	GetDisplayMode () = 0;
+	virtual	long			STDMETHODCALLTYPE	GetWidth () = 0;
+	virtual	long			STDMETHODCALLTYPE	GetHeight () = 0;
+	virtual	HRESULT			STDMETHODCALLTYPE	GetFrameRate (BMDTimeValue *frameDuration, BMDTimeScale *timeScale) = 0;
+};
+
+class IDeckLinkVideoOutputCallback_v7_1 : public IUnknown
+{
+public:
+	virtual HRESULT STDMETHODCALLTYPE	ScheduledFrameCompleted (IDeckLinkVideoFrame_v7_1* completedFrame, BMDOutputFrameCompletionResult result) = 0;
+};
+
+class IDeckLinkInputCallback_v7_1 : public IUnknown
+{
+public:
+	virtual HRESULT STDMETHODCALLTYPE	VideoInputFrameArrived (IDeckLinkVideoInputFrame_v7_1* videoFrame, IDeckLinkAudioInputPacket_v7_1* audioPacket) = 0;
+};
+
+// IDeckLinkOutput_v7_1.  Created by QueryInterface from IDeckLink.
+class IDeckLinkOutput_v7_1 : public IUnknown
+{
+public:
+	// Display mode predicates
+	virtual	HRESULT	STDMETHODCALLTYPE	DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport *result) = 0;
+	virtual HRESULT	STDMETHODCALLTYPE	GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1* *iterator) = 0;
+
+
+	// Video output
+	virtual HRESULT STDMETHODCALLTYPE	EnableVideoOutput (BMDDisplayMode displayMode) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	DisableVideoOutput () = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	SetVideoOutputFrameMemoryAllocator (IDeckLinkMemoryAllocator* theAllocator) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	CreateVideoFrame (int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	CreateVideoFrameFromBuffer (void* buffer, int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	DisplayVideoFrameSync (IDeckLinkVideoFrame_v7_1* theFrame) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	ScheduleVideoFrame (IDeckLinkVideoFrame_v7_1* theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	SetScheduledFrameCompletionCallback (IDeckLinkVideoOutputCallback_v7_1* theCallback) = 0;
+
+
+	// Audio output
+	virtual HRESULT STDMETHODCALLTYPE	EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	DisableAudioOutput () = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	WriteAudioSamplesSync (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesWritten) = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	BeginAudioPreroll () = 0;
+	virtual HRESULT STDMETHODCALLTYPE	EndAudioPreroll () = 0;
+	virtual HRESULT STDMETHODCALLTYPE	ScheduleAudioSamples (void* buffer, uint32_t sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, uint32_t *sampleFramesWritten) = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	FlushBufferedAudioSamples () = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	SetAudioCallback (IDeckLinkAudioOutputCallback* theCallback) = 0;
+
+
+	// Output control
+	virtual HRESULT STDMETHODCALLTYPE	StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, BMDTimeValue *actualStopTime, BMDTimeScale timeScale) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0;
+};
+
+// IDeckLinkInput_v7_1.  Created by QueryInterface from IDeckLink.
+class IDeckLinkInput_v7_1 : public IUnknown
+{
+public:
+	virtual	HRESULT	STDMETHODCALLTYPE	DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport *result) = 0;
+	virtual HRESULT	STDMETHODCALLTYPE	GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1 **iterator) = 0;
+
+	// Video input
+	virtual HRESULT STDMETHODCALLTYPE	EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	DisableVideoInput () = 0;
+
+	// Audio input
+	virtual HRESULT STDMETHODCALLTYPE	EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	DisableAudioInput () = 0;
+	virtual HRESULT STDMETHODCALLTYPE	ReadAudioSamples (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesRead, BMDTimeValue *audioPacketTime, BMDTimeScale timeScale) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0;
+
+	// Input control
+	virtual HRESULT	STDMETHODCALLTYPE	StartStreams () = 0;
+	virtual HRESULT	STDMETHODCALLTYPE	StopStreams () = 0;
+	virtual HRESULT	STDMETHODCALLTYPE	PauseStreams () = 0;
+	virtual HRESULT STDMETHODCALLTYPE	SetCallback (IDeckLinkInputCallback_v7_1* theCallback) = 0;
+};
+
+// IDeckLinkVideoFrame_v7_1.  Created by IDeckLinkOutput::CreateVideoFrame.
+class IDeckLinkVideoFrame_v7_1 : public IUnknown
+{
+public:
+	virtual long STDMETHODCALLTYPE					GetWidth () = 0;
+	virtual long STDMETHODCALLTYPE					GetHeight () = 0;
+	virtual long STDMETHODCALLTYPE					GetRowBytes () = 0;
+	virtual BMDPixelFormat STDMETHODCALLTYPE		GetPixelFormat () = 0;
+	virtual BMDFrameFlags STDMETHODCALLTYPE			GetFlags () = 0;
+	virtual HRESULT STDMETHODCALLTYPE				GetBytes (void* *buffer) = 0;
+};
+
+// IDeckLinkVideoInputFrame_v7_1.  Provided by the IDeckLinkInput_v7_1 frame arrival callback.
+class IDeckLinkVideoInputFrame_v7_1 : public IDeckLinkVideoFrame_v7_1
+{
+public:
+	virtual HRESULT STDMETHODCALLTYPE			GetFrameTime (BMDTimeValue *frameTime, BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0;
+};
+
+// IDeckLinkAudioInputPacket_v7_1.  Provided by the IDeckLinkInput_v7_1 callback.
+class IDeckLinkAudioInputPacket_v7_1 : public IUnknown
+{
+public:
+	virtual long STDMETHODCALLTYPE				GetSampleCount () = 0;
+	virtual HRESULT STDMETHODCALLTYPE			GetBytes (void* *buffer) = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE			GetAudioPacketTime (BMDTimeValue *packetTime, BMDTimeScale timeScale) = 0;
+};
+
+#endif		// defined(__cplusplus)
+
+#endif		// __DeckLink_API_v7_1_h__
+
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_3.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_3.h
new file mode 100644
index 0000000..c8b3da8
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_3.h
@@ -0,0 +1,173 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* DeckLinkAPI_v7_3.h */
+
+#ifndef __DeckLink_API_v7_3_h__
+#define __DeckLink_API_v7_3_h__
+
+#include "DeckLinkAPI.h"
+#include "DeckLinkAPI_v7_6.h"
+
+/* Interface ID Declarations */
+
+#define IID_IDeckLinkInputCallback_v7_3                  /* FD6F311D-4D00-444B-9ED4-1F25B5730AD0 */ (REFIID){0xFD,0x6F,0x31,0x1D,0x4D,0x00,0x44,0x4B,0x9E,0xD4,0x1F,0x25,0xB5,0x73,0x0A,0xD0}
+#define IID_IDeckLinkOutput_v7_3                         /* 271C65E3-C323-4344-A30F-D908BCB20AA3 */ (REFIID){0x27,0x1C,0x65,0xE3,0xC3,0x23,0x43,0x44,0xA3,0x0F,0xD9,0x08,0xBC,0xB2,0x0A,0xA3}
+#define IID_IDeckLinkInput_v7_3                          /* 4973F012-9925-458C-871C-18774CDBBECB */ (REFIID){0x49,0x73,0xF0,0x12,0x99,0x25,0x45,0x8C,0x87,0x1C,0x18,0x77,0x4C,0xDB,0xBE,0xCB}
+#define IID_IDeckLinkVideoInputFrame_v7_3                /* CF317790-2894-11DE-8C30-0800200C9A66 */ (REFIID){0xCF,0x31,0x77,0x90,0x28,0x94,0x11,0xDE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66}
+
+/* End Interface ID Declarations */
+
+#if defined(__cplusplus)
+
+/* Forward Declarations */
+
+class IDeckLinkVideoInputFrame_v7_3;
+
+/* End Forward Declarations */
+
+
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkOutput_v7_3 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;
+
+    /* Video Output */
+
+    virtual HRESULT EnableVideoOutput (BMDDisplayMode displayMode, BMDVideoOutputFlags flags) = 0;
+    virtual HRESULT DisableVideoOutput (void) = 0;
+
+    virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0;
+    virtual HRESULT CreateVideoFrame (int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame_v7_6 **outFrame) = 0;
+    virtual HRESULT CreateAncillaryData (BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0;
+
+    virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0;
+    virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale) = 0;
+    virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0;
+    virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0;
+
+    /* Audio Output */
+
+    virtual HRESULT EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount, BMDAudioOutputStreamType streamType) = 0;
+    virtual HRESULT DisableAudioOutput (void) = 0;
+
+    virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT BeginAudioPreroll (void) = 0;
+    virtual HRESULT EndAudioPreroll (void) = 0;
+    virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, uint32_t sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0;
+    virtual HRESULT FlushBufferedAudioSamples (void) = 0;
+
+    virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0;
+
+    /* Output Control */
+
+    virtual HRESULT StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed) = 0;
+    virtual HRESULT StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, BMDTimeScale timeScale) = 0;
+    virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0;
+    virtual HRESULT GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0;
+
+protected:
+    virtual ~IDeckLinkOutput_v7_3 () {}; // call Release method to drop reference count
+};
+
+/* End Interface IDeckLinkOutput */
+
+
+/* Interface IDeckLinkInputCallback - Frame arrival callback. */
+
+class IDeckLinkInputCallback_v7_3 : public IUnknown
+{
+public:
+    virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode_v7_6 *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0;
+    virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame_v7_3 *videoFrame, /* in */ IDeckLinkAudioInputPacket *audioPacket) = 0;
+
+protected:
+    virtual ~IDeckLinkInputCallback_v7_3 () {}; // call Release method to drop reference count
+};
+
+/* End Interface IDeckLinkInputCallback */
+
+
+/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkInput_v7_3 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;
+
+    /* Video Input */
+
+    virtual HRESULT EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags) = 0;
+    virtual HRESULT DisableVideoInput (void) = 0;
+    virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0;
+
+    /* Audio Input */
+
+    virtual HRESULT EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0;
+    virtual HRESULT DisableAudioInput (void) = 0;
+    virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0;
+
+    /* Input Control */
+
+    virtual HRESULT StartStreams (void) = 0;
+    virtual HRESULT StopStreams (void) = 0;
+    virtual HRESULT PauseStreams (void) = 0;
+    virtual HRESULT FlushStreams (void) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v7_3 *theCallback) = 0;
+
+protected:
+    virtual ~IDeckLinkInput_v7_3 () {}; // call Release method to drop reference count
+};
+
+/* End Interface IDeckLinkInput */
+
+/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */
+
+class IDeckLinkVideoInputFrame_v7_3 : public IDeckLinkVideoFrame_v7_6
+{
+public:
+    virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoInputFrame_v7_3 () {}; // call Release method to drop reference count
+};
+
+/* End Interface IDeckLinkVideoInputFrame */
+
+#endif      // defined(__cplusplus)
+#endif      // __DeckLink_API_v7_3_h__
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_6.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_6.h
new file mode 100644
index 0000000..8bc9329
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_6.h
@@ -0,0 +1,404 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* DeckLinkAPI_v7_6.h */
+
+#ifndef __DeckLink_API_v7_6_h__
+#define __DeckLink_API_v7_6_h__
+
+#include "DeckLinkAPI.h"
+
+// Interface ID Declarations
+
+#define IID_IDeckLinkVideoOutputCallback_v7_6            /* E763A626-4A3C-49D1-BF13-E7AD3692AE52 */ (REFIID){0xE7,0x63,0xA6,0x26,0x4A,0x3C,0x49,0xD1,0xBF,0x13,0xE7,0xAD,0x36,0x92,0xAE,0x52}
+#define IID_IDeckLinkInputCallback_v7_6                  /* 31D28EE7-88B6-4CB1-897A-CDBF79A26414 */ (REFIID){0x31,0xD2,0x8E,0xE7,0x88,0xB6,0x4C,0xB1,0x89,0x7A,0xCD,0xBF,0x79,0xA2,0x64,0x14}
+#define IID_IDeckLinkDisplayModeIterator_v7_6            /* 455D741F-1779-4800-86F5-0B5D13D79751 */ (REFIID){0x45,0x5D,0x74,0x1F,0x17,0x79,0x48,0x00,0x86,0xF5,0x0B,0x5D,0x13,0xD7,0x97,0x51}
+#define IID_IDeckLinkDisplayMode_v7_6                    /* 87451E84-2B7E-439E-A629-4393EA4A8550 */ (REFIID){0x87,0x45,0x1E,0x84,0x2B,0x7E,0x43,0x9E,0xA6,0x29,0x43,0x93,0xEA,0x4A,0x85,0x50}
+#define IID_IDeckLinkOutput_v7_6                         /* 29228142-EB8C-4141-A621-F74026450955 */ (REFIID){0x29,0x22,0x81,0x42,0xEB,0x8C,0x41,0x41,0xA6,0x21,0xF7,0x40,0x26,0x45,0x09,0x55}
+#define IID_IDeckLinkInput_v7_6                          /* 300C135A-9F43-48E2-9906-6D7911D93CF1 */ (REFIID){0x30,0x0C,0x13,0x5A,0x9F,0x43,0x48,0xE2,0x99,0x06,0x6D,0x79,0x11,0xD9,0x3C,0xF1}
+#define IID_IDeckLinkTimecode_v7_6                       /* EFB9BCA6-A521-44F7-BD69-2332F24D9EE6 */ (REFIID){0xEF,0xB9,0xBC,0xA6,0xA5,0x21,0x44,0xF7,0xBD,0x69,0x23,0x32,0xF2,0x4D,0x9E,0xE6}
+#define IID_IDeckLinkVideoFrame_v7_6                     /* A8D8238E-6B18-4196-99E1-5AF717B83D32 */ (REFIID){0xA8,0xD8,0x23,0x8E,0x6B,0x18,0x41,0x96,0x99,0xE1,0x5A,0xF7,0x17,0xB8,0x3D,0x32}
+#define IID_IDeckLinkMutableVideoFrame_v7_6              /* 46FCEE00-B4E6-43D0-91C0-023A7FCEB34F */ (REFIID){0x46,0xFC,0xEE,0x00,0xB4,0xE6,0x43,0xD0,0x91,0xC0,0x02,0x3A,0x7F,0xCE,0xB3,0x4F}
+#define IID_IDeckLinkVideoInputFrame_v7_6                /* 9A74FA41-AE9F-47AC-8CF4-01F42DD59965 */ (REFIID){0x9A,0x74,0xFA,0x41,0xAE,0x9F,0x47,0xAC,0x8C,0xF4,0x01,0xF4,0x2D,0xD5,0x99,0x65}
+#define IID_IDeckLinkScreenPreviewCallback_v7_6          /* 373F499D-4B4D-4518-AD22-6354E5A5825E */ (REFIID){0x37,0x3F,0x49,0x9D,0x4B,0x4D,0x45,0x18,0xAD,0x22,0x63,0x54,0xE5,0xA5,0x82,0x5E}
+#define IID_IDeckLinkGLScreenPreviewHelper_v7_6          /* BA575CD9-A15E-497B-B2C2-F9AFE7BE4EBA */ (REFIID){0xBA,0x57,0x5C,0xD9,0xA1,0x5E,0x49,0x7B,0xB2,0xC2,0xF9,0xAF,0xE7,0xBE,0x4E,0xBA}
+#define IID_IDeckLinkVideoConversion_v7_6                /* 3EB504C9-F97D-40FE-A158-D407D48CB53B */ (REFIID){0x3E,0xB5,0x04,0xC9,0xF9,0x7D,0x40,0xFE,0xA1,0x58,0xD4,0x07,0xD4,0x8C,0xB5,0x3B}
+#define IID_IDeckLinkConfiguration_v7_6                  /* B8EAD569-B764-47F0-A73F-AE40DF6CBF10 */ (REFIID){0xB8,0xEA,0xD5,0x69,0xB7,0x64,0x47,0xF0,0xA7,0x3F,0xAE,0x40,0xDF,0x6C,0xBF,0x10}
+
+
+#if defined(__cplusplus)
+
+/* Enum BMDVideoConnection - Video connection types */
+
+typedef uint32_t BMDVideoConnection_v7_6;
+enum _BMDVideoConnection_v7_6 {
+    bmdVideoConnectionSDI_v7_6                              = 'sdi ',
+    bmdVideoConnectionHDMI_v7_6                             = 'hdmi',
+    bmdVideoConnectionOpticalSDI_v7_6                       = 'opti',
+    bmdVideoConnectionComponent_v7_6                        = 'cpnt',
+    bmdVideoConnectionComposite_v7_6                        = 'cmst',
+    bmdVideoConnectionSVideo_v7_6                           = 'svid'
+};
+
+// Forward Declarations
+
+class IDeckLinkVideoOutputCallback_v7_6;
+class IDeckLinkInputCallback_v7_6;
+class IDeckLinkDisplayModeIterator_v7_6;
+class IDeckLinkDisplayMode_v7_6;
+class IDeckLinkOutput_v7_6;
+class IDeckLinkInput_v7_6;
+class IDeckLinkTimecode_v7_6;
+class IDeckLinkVideoFrame_v7_6;
+class IDeckLinkMutableVideoFrame_v7_6;
+class IDeckLinkVideoInputFrame_v7_6;
+class IDeckLinkScreenPreviewCallback_v7_6;
+class IDeckLinkGLScreenPreviewHelper_v7_6;
+class IDeckLinkVideoConversion_v7_6;
+
+
+/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */
+
+class IDeckLinkVideoOutputCallback_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT ScheduledFrameCompleted (/* in */ IDeckLinkVideoFrame_v7_6 *completedFrame, /* in */ BMDOutputFrameCompletionResult result) = 0;
+    virtual HRESULT ScheduledPlaybackHasStopped (void) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoOutputCallback_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkInputCallback - Frame arrival callback. */
+
+class IDeckLinkInputCallback_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode_v7_6 *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0;
+    virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame_v7_6* videoFrame, /* in */ IDeckLinkAudioInputPacket* audioPacket) = 0;
+
+protected:
+    virtual ~IDeckLinkInputCallback_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */
+
+class IDeckLinkDisplayModeIterator_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT Next (/* out */ IDeckLinkDisplayMode_v7_6 **deckLinkDisplayMode) = 0;
+
+protected:
+    virtual ~IDeckLinkDisplayModeIterator_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkDisplayMode - represents a display mode */
+
+class IDeckLinkDisplayMode_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT GetName (/* out */ const char **name) = 0;
+    virtual BMDDisplayMode GetDisplayMode (void) = 0;
+    virtual long GetWidth (void) = 0;
+    virtual long GetHeight (void) = 0;
+    virtual HRESULT GetFrameRate (/* out */ BMDTimeValue *frameDuration, /* out */ BMDTimeScale *timeScale) = 0;
+    virtual BMDFieldDominance GetFieldDominance (void) = 0;
+
+protected:
+    virtual ~IDeckLinkDisplayMode_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkOutput_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback_v7_6 *previewCallback) = 0;
+
+    /* Video Output */
+
+    virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0;
+    virtual HRESULT DisableVideoOutput (void) = 0;
+
+    virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0;
+    virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame_v7_6 **outFrame) = 0;
+    virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0;
+
+    virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0;
+    virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0;
+    virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback_v7_6 *theCallback) = 0;
+    virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0;
+
+    /* Audio Output */
+
+    virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0;
+    virtual HRESULT DisableAudioOutput (void) = 0;
+
+    virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT BeginAudioPreroll (void) = 0;
+    virtual HRESULT EndAudioPreroll (void) = 0;
+    virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0;
+    virtual HRESULT FlushBufferedAudioSamples (void) = 0;
+
+    virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0;
+
+    /* Output Control */
+
+    virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0;
+    virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0;
+    virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0;
+    virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0;
+
+    /* Hardware Timing */
+
+    virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkOutput_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkInput_v7_6 - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkInput_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback_v7_6 *previewCallback) = 0;
+
+    /* Video Input */
+
+    virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0;
+    virtual HRESULT DisableVideoInput (void) = 0;
+    virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0;
+
+    /* Audio Input */
+
+    virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0;
+    virtual HRESULT DisableAudioInput (void) = 0;
+    virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0;
+
+    /* Input Control */
+
+    virtual HRESULT StartStreams (void) = 0;
+    virtual HRESULT StopStreams (void) = 0;
+    virtual HRESULT PauseStreams (void) = 0;
+    virtual HRESULT FlushStreams (void) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v7_6 *theCallback) = 0;
+
+    /* Hardware Timing */
+
+    virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkInput_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkTimecode - Used for video frame timecode representation. */
+
+class IDeckLinkTimecode_v7_6 : public IUnknown
+{
+public:
+    virtual BMDTimecodeBCD GetBCD (void) = 0;
+    virtual HRESULT GetComponents (/* out */ uint8_t *hours, /* out */ uint8_t *minutes, /* out */ uint8_t *seconds, /* out */ uint8_t *frames) = 0;
+    virtual HRESULT GetString (/* out */ const char **timecode) = 0;
+    virtual BMDTimecodeFlags GetFlags (void) = 0;
+
+protected:
+    virtual ~IDeckLinkTimecode_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */
+
+class IDeckLinkVideoFrame_v7_6 : public IUnknown
+{
+public:
+    virtual long GetWidth (void) = 0;
+    virtual long GetHeight (void) = 0;
+    virtual long GetRowBytes (void) = 0;
+    virtual BMDPixelFormat GetPixelFormat (void) = 0;
+    virtual BMDFrameFlags GetFlags (void) = 0;
+    virtual HRESULT GetBytes (/* out */ void **buffer) = 0;
+
+    virtual HRESULT GetTimecode (BMDTimecodeFormat format, /* out */ IDeckLinkTimecode_v7_6 **timecode) = 0;
+    virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary **ancillary) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoFrame_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */
+
+class IDeckLinkMutableVideoFrame_v7_6 : public IDeckLinkVideoFrame_v7_6
+{
+public:
+    virtual HRESULT SetFlags (BMDFrameFlags newFlags) = 0;
+
+    virtual HRESULT SetTimecode (BMDTimecodeFormat format, /* in */ IDeckLinkTimecode_v7_6 *timecode) = 0;
+    virtual HRESULT SetTimecodeFromComponents (BMDTimecodeFormat format, uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t frames, BMDTimecodeFlags flags) = 0;
+    virtual HRESULT SetAncillaryData (/* in */ IDeckLinkVideoFrameAncillary *ancillary) = 0;
+
+protected:
+    virtual ~IDeckLinkMutableVideoFrame_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */
+
+class IDeckLinkVideoInputFrame_v7_6 : public IDeckLinkVideoFrame_v7_6
+{
+public:
+    virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0;
+    virtual HRESULT GetHardwareReferenceTimestamp (BMDTimeScale timeScale, /* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoInputFrame_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */
+
+class IDeckLinkScreenPreviewCallback_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT DrawFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkScreenPreviewCallback_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */
+
+class IDeckLinkGLScreenPreviewHelper_v7_6 : public IUnknown
+{
+public:
+
+    /* Methods must be called with OpenGL context set */
+
+    virtual HRESULT InitializeGL (void) = 0;
+    virtual HRESULT PaintGL (void) = 0;
+    virtual HRESULT SetFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkGLScreenPreviewHelper_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkVideoConversion - Created with CoCreateInstance(). */
+
+class IDeckLinkVideoConversion_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT ConvertFrame (/* in */ IDeckLinkVideoFrame_v7_6* srcFrame, /* in */ IDeckLinkVideoFrame_v7_6* dstFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoConversion_v7_6 () {}; // call Release method to drop reference count
+};
+
+/* Interface IDeckLinkConfiguration - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkConfiguration_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT GetConfigurationValidator (/* out */ IDeckLinkConfiguration_v7_6 **configObject) = 0;
+    virtual HRESULT WriteConfigurationToPreferences (void) = 0;
+
+    /* Video Output Configuration */
+
+    virtual HRESULT SetVideoOutputFormat (/* in */ BMDVideoConnection_v7_6 videoOutputConnection) = 0;
+    virtual HRESULT IsVideoOutputActive (/* in */ BMDVideoConnection_v7_6 videoOutputConnection, /* out */ bool *active) = 0;
+
+    virtual HRESULT SetAnalogVideoOutputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0;
+    virtual HRESULT GetAnalogVideoOutputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0;
+
+    virtual HRESULT EnableFieldFlickerRemovalWhenPaused (/* in */ bool enable) = 0;
+    virtual HRESULT IsEnabledFieldFlickerRemovalWhenPaused (/* out */ bool *enabled) = 0;
+
+    virtual HRESULT Set444And3GBpsVideoOutput (/* in */ bool enable444VideoOutput, /* in */ bool enable3GbsOutput) = 0;
+    virtual HRESULT Get444And3GBpsVideoOutput (/* out */ bool *is444VideoOutputEnabled, /* out */ bool *threeGbsOutputEnabled) = 0;
+
+    virtual HRESULT SetVideoOutputConversionMode (/* in */ BMDVideoOutputConversionMode conversionMode) = 0;
+    virtual HRESULT GetVideoOutputConversionMode (/* out */ BMDVideoOutputConversionMode *conversionMode) = 0;
+
+    virtual HRESULT Set_HD1080p24_to_HD1080i5994_Conversion (/* in */ bool enable) = 0;
+    virtual HRESULT Get_HD1080p24_to_HD1080i5994_Conversion (/* out */ bool *enabled) = 0;
+
+    /* Video Input Configuration */
+
+    virtual HRESULT SetVideoInputFormat (/* in */ BMDVideoConnection_v7_6 videoInputFormat) = 0;
+    virtual HRESULT GetVideoInputFormat (/* out */ BMDVideoConnection_v7_6 *videoInputFormat) = 0;
+
+    virtual HRESULT SetAnalogVideoInputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0;
+    virtual HRESULT GetAnalogVideoInputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0;
+
+    virtual HRESULT SetVideoInputConversionMode (/* in */ BMDVideoInputConversionMode conversionMode) = 0;
+    virtual HRESULT GetVideoInputConversionMode (/* out */ BMDVideoInputConversionMode *conversionMode) = 0;
+
+    virtual HRESULT SetBlackVideoOutputDuringCapture (/* in */ bool blackOutInCapture) = 0;
+    virtual HRESULT GetBlackVideoOutputDuringCapture (/* out */ bool *blackOutInCapture) = 0;
+
+    virtual HRESULT Set32PulldownSequenceInitialTimecodeFrame (/* in */ uint32_t aFrameTimecode) = 0;
+    virtual HRESULT Get32PulldownSequenceInitialTimecodeFrame (/* out */ uint32_t *aFrameTimecode) = 0;
+
+    virtual HRESULT SetVancSourceLineMapping (/* in */ uint32_t activeLine1VANCsource, /* in */ uint32_t activeLine2VANCsource, /* in */ uint32_t activeLine3VANCsource) = 0;
+    virtual HRESULT GetVancSourceLineMapping (/* out */ uint32_t *activeLine1VANCsource, /* out */ uint32_t *activeLine2VANCsource, /* out */ uint32_t *activeLine3VANCsource) = 0;
+
+    /* Audio Input Configuration */
+
+    virtual HRESULT SetAudioInputFormat (/* in */ BMDAudioConnection audioInputFormat) = 0;
+    virtual HRESULT GetAudioInputFormat (/* out */ BMDAudioConnection *audioInputFormat) = 0;
+};
+
+/* Functions */
+
+extern "C" {
+
+	IDeckLinkIterator*							CreateDeckLinkIteratorInstance_v7_6 (void);
+	IDeckLinkGLScreenPreviewHelper_v7_6*		CreateOpenGLScreenPreviewHelper_v7_6 (void);
+    IDeckLinkVideoConversion_v7_6*				CreateVideoConversionInstance_v7_6 (void);
+
+};
+
+
+#endif      // defined(__cplusplus)
+#endif      // __DeckLink_API_v7_6_h__
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_9.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_9.h
new file mode 100644
index 0000000..406ce0a
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_9.h
@@ -0,0 +1,88 @@
+/* -LICENSE-START-
+** Copyright (c) 2010 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* DeckLinkAPI_v7_9.h */
+
+#ifndef __DeckLink_API_v7_9_h__
+#define __DeckLink_API_v7_9_h__
+
+#include "DeckLinkAPI.h"
+
+// Interface ID Declarations
+#define IID_IDeckLinkDeckControl_v7_9                    /* A4D81043-0619-42B7-8ED6-602D29041DF7 */ (REFIID){0xA4,0xD8,0x10,0x43,0x06,0x19,0x42,0xB7,0x8E,0xD6,0x60,0x2D,0x29,0x04,0x1D,0xF7}
+
+#if defined(__cplusplus)
+
+
+// Forward Declarations
+class IDeckLinkDeckControl_v7_9;
+
+/* Interface IDeckLinkDeckControl_v7_9 - Deck Control main interface */
+class IDeckLinkDeckControl_v7_9 : public IUnknown
+{
+public:
+    virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Close (/* in */ bool standbyOn) = 0;
+    virtual HRESULT GetCurrentState (/* out */ BMDDeckControlMode *mode, /* out */ BMDDeckControlVTRControlState *vtrControlState, /* out */ BMDDeckControlStatusFlags *flags) = 0;
+    virtual HRESULT SetStandby (/* in */ bool standbyOn) = 0;
+    virtual HRESULT Play (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Stop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT TogglePlayStop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Eject (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GoToTimecode (/* in */ BMDTimecodeBCD timecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT FastForward (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Rewind (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StepForward (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StepBack (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Jog (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Shuttle (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecodeString (/* out */ const char **currentTimeCode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecode (/* out */ IDeckLinkTimecode **currentTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecodeBCD (/* out */ BMDTimecodeBCD *currentTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT SetPreroll (/* in */ uint32_t prerollSeconds) = 0;
+    virtual HRESULT GetPreroll (/* out */ uint32_t *prerollSeconds) = 0;
+    virtual HRESULT SetExportOffset (/* in */ int32_t exportOffsetFields) = 0;
+    virtual HRESULT GetExportOffset (/* out */ int32_t *exportOffsetFields) = 0;
+    virtual HRESULT GetManualExportOffset (/* out */ int32_t *deckManualExportOffsetFields) = 0;
+    virtual HRESULT SetCaptureOffset (/* in */ int32_t captureOffsetFields) = 0;
+    virtual HRESULT GetCaptureOffset (/* out */ int32_t *captureOffsetFields) = 0;
+    virtual HRESULT StartExport (/* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* in */ BMDDeckControlExportModeOpsFlags exportModeOps, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StartCapture (/* in */ bool useVITC, /* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetDeviceID (/* out */ uint16_t *deviceId, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Abort (void) = 0;
+    virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback *callback) = 0;
+
+protected:
+    virtual ~IDeckLinkDeckControl_v7_9 () {}; // call Release method to drop reference count
+};
+
+
+
+#endif      // defined(__cplusplus)
+#endif      // __DeckLink_API_v7_9_h__
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_0.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_0.h
new file mode 100644
index 0000000..832664c
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_0.h
@@ -0,0 +1,63 @@
+/* -LICENSE-START-
+** Copyright (c) 2011 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v8_0_H
+#define BMD_DECKLINKAPI_v8_0_H
+
+#include "DeckLinkAPI.h"
+
+// Interface ID Declarations
+
+#define IID_IDeckLink_v8_0                                    /* 62BFF75D-6569-4E55-8D4D-66AA03829ABC */ (REFIID){0x62,0xBF,0xF7,0x5D,0x65,0x69,0x4E,0x55,0x8D,0x4D,0x66,0xAA,0x03,0x82,0x9A,0xBC}
+#define IID_IDeckLinkIterator_v8_0                            /* 74E936FC-CC28-4A67-81A0-1E94E52D4E69 */ (REFIID){0x74,0xE9,0x36,0xFC,0xCC,0x28,0x4A,0x67,0x81,0xA0,0x1E,0x94,0xE5,0x2D,0x4E,0x69}
+
+#if defined (__cplusplus)
+
+/* Interface IDeckLink_v8_0 - represents a DeckLink device */
+
+class IDeckLink_v8_0 : public IUnknown
+{
+public:
+    virtual HRESULT GetModelName (/* out */ const char **modelName) = 0;
+};
+
+/* Interface IDeckLinkIterator_v8_0 - enumerates installed DeckLink hardware */
+
+class IDeckLinkIterator_v8_0 : public IUnknown
+{
+public:
+    virtual HRESULT Next (/* out */ IDeckLink_v8_0 **deckLinkInstance) = 0;
+};
+
+extern "C" {
+    IDeckLinkIterator_v8_0*                     CreateDeckLinkIteratorInstance_v8_0 (void);
+};
+
+#endif	// defined __cplusplus
+
+#endif /* defined(BMD_DECKLINKAPI_v8_0_H) */
+
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_1.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_1.h
new file mode 100644
index 0000000..7f68919
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_1.h
@@ -0,0 +1,111 @@
+/* -LICENSE-START-
+ ** Copyright (c) 2011 Blackmagic Design
+ **
+ ** Permission is hereby granted, free of charge, to any person or organization
+ ** obtaining a copy of the software and accompanying documentation covered by
+ ** this license (the "Software") to use, reproduce, display, distribute,
+ ** execute, and transmit the Software, and to prepare derivative works of the
+ ** Software, and to permit third-parties to whom the Software is furnished to
+ ** do so, all subject to the following:
+ **
+ ** The copyright notices in the Software and this entire statement, including
+ ** the above license grant, this restriction and the following disclaimer,
+ ** must be included in all copies of the Software, in whole or in part, and
+ ** all derivative works of the Software, unless such copies or derivative
+ ** works are solely in the form of machine-executable object code generated by
+ ** a source language processor.
+ **
+ ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ ** DEALINGS IN THE SOFTWARE.
+ ** -LICENSE-END-
+ */
+
+#ifndef BMD_DECKLINKAPI_v8_1_H
+#define BMD_DECKLINKAPI_v8_1_H
+
+#include "DeckLinkAPI.h"
+
+
+// Interface ID Declarations
+
+#define IID_IDeckLinkDeckControlStatusCallback_v8_1           /* E5F693C1-4283-4716-B18F-C1431521955B */ (REFIID){0xE5,0xF6,0x93,0xC1,0x42,0x83,0x47,0x16,0xB1,0x8F,0xC1,0x43,0x15,0x21,0x95,0x5B}
+#define IID_IDeckLinkDeckControl_v8_1                         /* 522A9E39-0F3C-4742-94EE-D80DE335DA1D */ (REFIID){0x52,0x2A,0x9E,0x39,0x0F,0x3C,0x47,0x42,0x94,0xEE,0xD8,0x0D,0xE3,0x35,0xDA,0x1D}
+
+
+/* Enum BMDDeckControlVTRControlState_v8_1 - VTR Control state */
+
+typedef uint32_t BMDDeckControlVTRControlState_v8_1;
+enum _BMDDeckControlVTRControlState_v8_1 {
+    bmdDeckControlNotInVTRControlMode_v8_1                            = 'nvcm',
+    bmdDeckControlVTRControlPlaying_v8_1                              = 'vtrp',
+    bmdDeckControlVTRControlRecording_v8_1                            = 'vtrr',
+    bmdDeckControlVTRControlStill_v8_1                                = 'vtra',
+    bmdDeckControlVTRControlSeeking_v8_1                              = 'vtrs',
+    bmdDeckControlVTRControlStopped_v8_1                              = 'vtro'
+};
+
+
+/* Interface IDeckLinkDeckControlStatusCallback_v8_1 - Deck control state change callback. */
+
+class IDeckLinkDeckControlStatusCallback_v8_1 : public IUnknown
+{
+public:
+    virtual HRESULT TimecodeUpdate (/* in */ BMDTimecodeBCD currentTimecode) = 0;
+    virtual HRESULT VTRControlStateChanged (/* in */ BMDDeckControlVTRControlState_v8_1 newState, /* in */ BMDDeckControlError error) = 0;
+    virtual HRESULT DeckControlEventReceived (/* in */ BMDDeckControlEvent event, /* in */ BMDDeckControlError error) = 0;
+    virtual HRESULT DeckControlStatusChanged (/* in */ BMDDeckControlStatusFlags flags, /* in */ uint32_t mask) = 0;
+
+protected:
+    virtual ~IDeckLinkDeckControlStatusCallback_v8_1 () {}; // call Release method to drop reference count
+};
+
+/* Interface IDeckLinkDeckControl_v8_1 - Deck Control main interface */
+
+class IDeckLinkDeckControl_v8_1 : public IUnknown
+{
+public:
+    virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Close (/* in */ bool standbyOn) = 0;
+    virtual HRESULT GetCurrentState (/* out */ BMDDeckControlMode *mode, /* out */ BMDDeckControlVTRControlState_v8_1 *vtrControlState, /* out */ BMDDeckControlStatusFlags *flags) = 0;
+    virtual HRESULT SetStandby (/* in */ bool standbyOn) = 0;
+    virtual HRESULT SendCommand (/* in */ uint8_t *inBuffer, /* in */ uint32_t inBufferSize, /* out */ uint8_t *outBuffer, /* out */ uint32_t *outDataSize, /* in */ uint32_t outBufferSize, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Play (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Stop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT TogglePlayStop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Eject (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GoToTimecode (/* in */ BMDTimecodeBCD timecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT FastForward (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Rewind (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StepForward (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StepBack (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Jog (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Shuttle (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecodeString (/* out */ const char **currentTimeCode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecode (/* out */ IDeckLinkTimecode **currentTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecodeBCD (/* out */ BMDTimecodeBCD *currentTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT SetPreroll (/* in */ uint32_t prerollSeconds) = 0;
+    virtual HRESULT GetPreroll (/* out */ uint32_t *prerollSeconds) = 0;
+    virtual HRESULT SetExportOffset (/* in */ int32_t exportOffsetFields) = 0;
+    virtual HRESULT GetExportOffset (/* out */ int32_t *exportOffsetFields) = 0;
+    virtual HRESULT GetManualExportOffset (/* out */ int32_t *deckManualExportOffsetFields) = 0;
+    virtual HRESULT SetCaptureOffset (/* in */ int32_t captureOffsetFields) = 0;
+    virtual HRESULT GetCaptureOffset (/* out */ int32_t *captureOffsetFields) = 0;
+    virtual HRESULT StartExport (/* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* in */ BMDDeckControlExportModeOpsFlags exportModeOps, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StartCapture (/* in */ bool useVITC, /* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetDeviceID (/* out */ uint16_t *deviceId, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Abort (void) = 0;
+    virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback_v8_1 *callback) = 0;
+
+protected:
+    virtual ~IDeckLinkDeckControl_v8_1 () {}; // call Release method to drop reference count
+};
+
+
+#endif	// BMD_DECKLINKAPI_v8_1_H
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_2.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_2.h
new file mode 100644
index 0000000..236d182
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_2.h
@@ -0,0 +1,81 @@
+/* -LICENSE-START-
+** Copyright (c) 2012 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v9_2_H
+#define BMD_DECKLINKAPI_v9_2_H
+
+#include "DeckLinkAPI.h"
+
+
+// Interface ID Declarations
+
+#define IID_IDeckLinkInput_v9_2                          /* 6D40EF78-28B9-4E21-990D-95BB7750A04F */ (REFIID){0x6D,0x40,0xEF,0x78,0x28,0xB9,0x4E,0x21,0x99,0x0D,0x95,0xBB,0x77,0x50,0xA0,0x4F}
+
+
+#if defined(__cplusplus)
+
+/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkInput_v9_2 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;
+
+    /* Video Input */
+
+    virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0;
+    virtual HRESULT DisableVideoInput (void) = 0;
+    virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0;
+
+    /* Audio Input */
+
+    virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0;
+    virtual HRESULT DisableAudioInput (void) = 0;
+    virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0;
+
+    /* Input Control */
+
+    virtual HRESULT StartStreams (void) = 0;
+    virtual HRESULT StopStreams (void) = 0;
+    virtual HRESULT PauseStreams (void) = 0;
+    virtual HRESULT FlushStreams (void) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback *theCallback) = 0;
+
+    /* Hardware Timing */
+
+    virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkInput_v9_2 () {}; // call Release method to drop reference count
+};
+
+
+#endif      // defined(__cplusplus)
+#endif	// BMD_DECKLINKAPI_v9_2_H
diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_9.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_9.h
new file mode 100644
index 0000000..98d115d
--- /dev/null
+++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_9.h
@@ -0,0 +1,98 @@
+/* -LICENSE-START-
+** Copyright (c) 2013 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v9_9_H
+#define BMD_DECKLINKAPI_v9_9_H
+
+#include "DeckLinkAPI.h"
+
+
+// Interface ID Declarations
+
+#define IID_IDeckLinkOutput_v9_9                         /* A3EF0963-0862-44ED-92A9-EE89ABF431C7 */ (REFIID){0xA3,0xEF,0x09,0x63,0x08,0x62,0x44,0xED,0x92,0xA9,0xEE,0x89,0xAB,0xF4,0x31,0xC7}
+
+
+#if defined(__cplusplus)
+
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkOutput_v9_9 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoOutputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;
+
+    /* Video Output */
+
+    virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0;
+    virtual HRESULT DisableVideoOutput (void) = 0;
+
+    virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0;
+    virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame **outFrame) = 0;
+    virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0;
+
+    virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame *theFrame) = 0;
+    virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0;
+    virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0;
+    virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0;
+
+    /* Audio Output */
+
+    virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0;
+    virtual HRESULT DisableAudioOutput (void) = 0;
+
+    virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT BeginAudioPreroll (void) = 0;
+    virtual HRESULT EndAudioPreroll (void) = 0;
+    virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0;
+    virtual HRESULT FlushBufferedAudioSamples (void) = 0;
+
+    virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0;
+
+    /* Output Control */
+
+    virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0;
+    virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0;
+    virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0;
+    virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0;
+    virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus *referenceStatus) = 0;
+
+    /* Hardware Timing */
+
+    virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkOutput_v9_9 () {}; // call Release method to drop reference count
+};
+
+#endif      // defined(__cplusplus)
+#endif	// BMD_DECKLINKAPI_v9_9_H
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI.h
index 3b13526..3b0fc11 100644
--- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI.h
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -60,17 +60,24 @@
 
 BMD_CONST REFIID IID_IDeckLinkVideoOutputCallback                 = /* 20AA5225-1958-47CB-820B-80A8D521A6EE */ {0x20,0xAA,0x52,0x25,0x19,0x58,0x47,0xCB,0x82,0x0B,0x80,0xA8,0xD5,0x21,0xA6,0xEE};
 BMD_CONST REFIID IID_IDeckLinkInputCallback                       = /* DD04E5EC-7415-42AB-AE4A-E80C4DFC044A */ {0xDD,0x04,0xE5,0xEC,0x74,0x15,0x42,0xAB,0xAE,0x4A,0xE8,0x0C,0x4D,0xFC,0x04,0x4A};
+BMD_CONST REFIID IID_IDeckLinkEncoderInputCallback                = /* ACF13E61-F4A0-4974-A6A7-59AFF6268B31 */ {0xAC,0xF1,0x3E,0x61,0xF4,0xA0,0x49,0x74,0xA6,0xA7,0x59,0xAF,0xF6,0x26,0x8B,0x31};
 BMD_CONST REFIID IID_IDeckLinkMemoryAllocator                     = /* B36EB6E7-9D29-4AA8-92EF-843B87A289E8 */ {0xB3,0x6E,0xB6,0xE7,0x9D,0x29,0x4A,0xA8,0x92,0xEF,0x84,0x3B,0x87,0xA2,0x89,0xE8};
 BMD_CONST REFIID IID_IDeckLinkAudioOutputCallback                 = /* 403C681B-7F46-4A12-B993-2BB127084EE6 */ {0x40,0x3C,0x68,0x1B,0x7F,0x46,0x4A,0x12,0xB9,0x93,0x2B,0xB1,0x27,0x08,0x4E,0xE6};
 BMD_CONST REFIID IID_IDeckLinkIterator                            = /* 50FB36CD-3063-4B73-BDBB-958087F2D8BA */ {0x50,0xFB,0x36,0xCD,0x30,0x63,0x4B,0x73,0xBD,0xBB,0x95,0x80,0x87,0xF2,0xD8,0xBA};
 BMD_CONST REFIID IID_IDeckLinkAPIInformation                      = /* 7BEA3C68-730D-4322-AF34-8A7152B532A4 */ {0x7B,0xEA,0x3C,0x68,0x73,0x0D,0x43,0x22,0xAF,0x34,0x8A,0x71,0x52,0xB5,0x32,0xA4};
 BMD_CONST REFIID IID_IDeckLinkOutput                              = /* CC5C8A6E-3F2F-4B3A-87EA-FD78AF300564 */ {0xCC,0x5C,0x8A,0x6E,0x3F,0x2F,0x4B,0x3A,0x87,0xEA,0xFD,0x78,0xAF,0x30,0x05,0x64};
 BMD_CONST REFIID IID_IDeckLinkInput                               = /* AF22762B-DFAC-4846-AA79-FA8883560995 */ {0xAF,0x22,0x76,0x2B,0xDF,0xAC,0x48,0x46,0xAA,0x79,0xFA,0x88,0x83,0x56,0x09,0x95};
+BMD_CONST REFIID IID_IDeckLinkEncoderInput                        = /* 270587DA-6B7D-42E7-A1F0-6D853F581185 */ {0x27,0x05,0x87,0xDA,0x6B,0x7D,0x42,0xE7,0xA1,0xF0,0x6D,0x85,0x3F,0x58,0x11,0x85};
 BMD_CONST REFIID IID_IDeckLinkVideoFrame                          = /* 3F716FE0-F023-4111-BE5D-EF4414C05B17 */ {0x3F,0x71,0x6F,0xE0,0xF0,0x23,0x41,0x11,0xBE,0x5D,0xEF,0x44,0x14,0xC0,0x5B,0x17};
 BMD_CONST REFIID IID_IDeckLinkMutableVideoFrame                   = /* 69E2639F-40DA-4E19-B6F2-20ACE815C390 */ {0x69,0xE2,0x63,0x9F,0x40,0xDA,0x4E,0x19,0xB6,0xF2,0x20,0xAC,0xE8,0x15,0xC3,0x90};
 BMD_CONST REFIID IID_IDeckLinkVideoFrame3DExtensions              = /* DA0F7E4A-EDC7-48A8-9CDD-2DB51C729CD7 */ {0xDA,0x0F,0x7E,0x4A,0xED,0xC7,0x48,0xA8,0x9C,0xDD,0x2D,0xB5,0x1C,0x72,0x9C,0xD7};
+BMD_CONST REFIID IID_IDeckLinkVideoFrameMetadataExtensions        = /* D5973DC9-6432-46D0-8F0B-2496F8A1238F */ {0xD5,0x97,0x3D,0xC9,0x64,0x32,0x46,0xD0,0x8F,0x0B,0x24,0x96,0xF8,0xA1,0x23,0x8F};
 BMD_CONST REFIID IID_IDeckLinkVideoInputFrame                     = /* 05CFE374-537C-4094-9A57-680525118F44 */ {0x05,0xCF,0xE3,0x74,0x53,0x7C,0x40,0x94,0x9A,0x57,0x68,0x05,0x25,0x11,0x8F,0x44};
 BMD_CONST REFIID IID_IDeckLinkVideoFrameAncillary                 = /* 732E723C-D1A4-4E29-9E8E-4A88797A0004 */ {0x73,0x2E,0x72,0x3C,0xD1,0xA4,0x4E,0x29,0x9E,0x8E,0x4A,0x88,0x79,0x7A,0x00,0x04};
+BMD_CONST REFIID IID_IDeckLinkEncoderPacket                       = /* B693F36C-316E-4AF1-B6C2-F389A4BCA620 */ {0xB6,0x93,0xF3,0x6C,0x31,0x6E,0x4A,0xF1,0xB6,0xC2,0xF3,0x89,0xA4,0xBC,0xA6,0x20};
+BMD_CONST REFIID IID_IDeckLinkEncoderVideoPacket                  = /* 4E7FD944-E8C7-4EAC-B8C0-7B77F80F5AE0 */ {0x4E,0x7F,0xD9,0x44,0xE8,0xC7,0x4E,0xAC,0xB8,0xC0,0x7B,0x77,0xF8,0x0F,0x5A,0xE0};
+BMD_CONST REFIID IID_IDeckLinkEncoderAudioPacket                  = /* 49E8EDC8-693B-4E14-8EF6-12C658F5A07A */ {0x49,0xE8,0xED,0xC8,0x69,0x3B,0x4E,0x14,0x8E,0xF6,0x12,0xC6,0x58,0xF5,0xA0,0x7A};
+BMD_CONST REFIID IID_IDeckLinkH265NALPacket                       = /* 639C8E0B-68D5-4BDE-A6D4-95F3AEAFF2E7 */ {0x63,0x9C,0x8E,0x0B,0x68,0xD5,0x4B,0xDE,0xA6,0xD4,0x95,0xF3,0xAE,0xAF,0xF2,0xE7};
 BMD_CONST REFIID IID_IDeckLinkAudioInputPacket                    = /* E43D5870-2894-11DE-8C30-0800200C9A66 */ {0xE4,0x3D,0x58,0x70,0x28,0x94,0x11,0xDE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66};
 BMD_CONST REFIID IID_IDeckLinkScreenPreviewCallback               = /* B1D3F49A-85FE-4C5D-95C8-0B5D5DCCD438 */ {0xB1,0xD3,0xF4,0x9A,0x85,0xFE,0x4C,0x5D,0x95,0xC8,0x0B,0x5D,0x5D,0xCC,0xD4,0x38};
 BMD_CONST REFIID IID_IDeckLinkCocoaScreenPreviewCallback          = /* D174152F-8F96-4C07-83A5-DD5F5AF0A2AA */ {0xD1,0x74,0x15,0x2F,0x8F,0x96,0x4C,0x07,0x83,0xA5,0xDD,0x5F,0x5A,0xF0,0xA2,0xAA};
@@ -78,6 +85,7 @@ BMD_CONST REFIID IID_IDeckLinkGLScreenPreviewHelper               = /* 504E2209-
 BMD_CONST REFIID IID_IDeckLinkNotificationCallback                = /* B002A1EC-070D-4288-8289-BD5D36E5FF0D */ {0xB0,0x02,0xA1,0xEC,0x07,0x0D,0x42,0x88,0x82,0x89,0xBD,0x5D,0x36,0xE5,0xFF,0x0D};
 BMD_CONST REFIID IID_IDeckLinkNotification                        = /* 0A1FB207-E215-441B-9B19-6FA1575946C5 */ {0x0A,0x1F,0xB2,0x07,0xE2,0x15,0x44,0x1B,0x9B,0x19,0x6F,0xA1,0x57,0x59,0x46,0xC5};
 BMD_CONST REFIID IID_IDeckLinkAttributes                          = /* ABC11843-D966-44CB-96E2-A1CB5D3135C4 */ {0xAB,0xC1,0x18,0x43,0xD9,0x66,0x44,0xCB,0x96,0xE2,0xA1,0xCB,0x5D,0x31,0x35,0xC4};
+BMD_CONST REFIID IID_IDeckLinkStatus                              = /* 5F558200-4028-49BC-BEAC-DB3FA4A96E46 */ {0x5F,0x55,0x82,0x00,0x40,0x28,0x49,0xBC,0xBE,0xAC,0xDB,0x3F,0xA4,0xA9,0x6E,0x46};
 BMD_CONST REFIID IID_IDeckLinkKeyer                               = /* 89AFCAF5-65F8-421E-98F7-96FE5F5BFBA3 */ {0x89,0xAF,0xCA,0xF5,0x65,0xF8,0x42,0x1E,0x98,0xF7,0x96,0xFE,0x5F,0x5B,0xFB,0xA3};
 BMD_CONST REFIID IID_IDeckLinkVideoConversion                     = /* 3BBCB8A2-DA2C-42D9-B5D8-88083644E99A */ {0x3B,0xBC,0xB8,0xA2,0xDA,0x2C,0x42,0xD9,0xB5,0xD8,0x88,0x08,0x36,0x44,0xE9,0x9A};
 BMD_CONST REFIID IID_IDeckLinkDeviceNotificationCallback          = /* 4997053B-0ADF-4CC8-AC70-7A50C4BE728F */ {0x49,0x97,0x05,0x3B,0x0A,0xDF,0x4C,0xC8,0xAC,0x70,0x7A,0x50,0xC4,0xBE,0x72,0x8F};
@@ -94,12 +102,21 @@ enum _BMDVideoOutputFlags {
     bmdVideoOutputDualStream3D                                   = 1 << 4
 };
 
+/* Enum BMDPacketType - Type of packet */
+
+typedef uint32_t BMDPacketType;
+enum _BMDPacketType {
+    bmdPacketTypeStreamInterruptedMarker                         = 'sint',	// A packet of this type marks the time when a video stream was interrupted, for example by a disconnected cable
+    bmdPacketTypeStreamData                                      = 'sdat'	// Regular stream data
+};
+
 /* Enum BMDFrameFlags - Frame flags */
 
 typedef uint32_t BMDFrameFlags;
 enum _BMDFrameFlags {
     bmdFrameFlagDefault                                          = 0,
     bmdFrameFlagFlipVertical                                     = 1 << 0,
+    bmdFrameContainsHDRMetadata                                  = 1 << 1,
 
     /* Flags that are applicable only to instances of IDeckLinkVideoInputFrame */
 
@@ -137,6 +154,7 @@ enum _BMDDetectedVideoInputFormatFlags {
 
 typedef uint32_t BMDDeckLinkCapturePassthroughMode;
 enum _BMDDeckLinkCapturePassthroughMode {
+    bmdDeckLinkCapturePassthroughModeDisabled                    = 'pdis',
     bmdDeckLinkCapturePassthroughModeDirect                      = 'pdir',
     bmdDeckLinkCapturePassthroughModeCleanSwitch                 = 'pcln'
 };
@@ -159,6 +177,13 @@ enum _BMDReferenceStatus {
     bmdReferenceLocked                                           = 1 << 1
 };
 
+/* Enum BMDAudioFormat - Audio Format */
+
+typedef uint32_t BMDAudioFormat;
+enum _BMDAudioFormat {
+    bmdAudioFormatPCM                                            = 'lpcm'	// Linear signed PCM samples
+};
+
 /* Enum BMDAudioSampleRate - Audio sample rates supported for output/input */
 
 typedef uint32_t BMDAudioSampleRate;
@@ -271,8 +296,71 @@ enum _BMDVideo3DPackingFormat {
 typedef uint32_t BMDIdleVideoOutputOperation;
 enum _BMDIdleVideoOutputOperation {
     bmdIdleVideoOutputBlack                                      = 'blac',
-    bmdIdleVideoOutputLastFrame                                  = 'lafa',
-    bmdIdleVideoOutputDesktop                                    = 'desk'
+    bmdIdleVideoOutputLastFrame                                  = 'lafa'
+};
+
+/* Enum BMDVideoEncoderFrameCodingMode - Video frame coding mode */
+
+typedef uint32_t BMDVideoEncoderFrameCodingMode;
+enum _BMDVideoEncoderFrameCodingMode {
+    bmdVideoEncoderFrameCodingModeInter                          = 'inte',
+    bmdVideoEncoderFrameCodingModeIntra                          = 'intr'
+};
+
+/* Enum BMDDNxHRLevel - DNxHR Levels */
+
+typedef uint32_t BMDDNxHRLevel;
+enum _BMDDNxHRLevel {
+    bmdDNxHRLevelSQ                                              = 'dnsq',
+    bmdDNxHRLevelLB                                              = 'dnlb',
+    bmdDNxHRLevelHQ                                              = 'dnhq',
+    bmdDNxHRLevelHQX                                             = 'dhqx',
+    bmdDNxHRLevel444                                             = 'd444'
+};
+
+/* Enum BMDLinkConfiguration - Video link configuration */
+
+typedef uint32_t BMDLinkConfiguration;
+enum _BMDLinkConfiguration {
+    bmdLinkConfigurationSingleLink                               = 'lcsl',
+    bmdLinkConfigurationDualLink                                 = 'lcdl',
+    bmdLinkConfigurationQuadLink                                 = 'lcql'
+};
+
+/* Enum BMDDeviceInterface - Device interface type */
+
+typedef uint32_t BMDDeviceInterface;
+enum _BMDDeviceInterface {
+    bmdDeviceInterfacePCI                                        = 'pci ',
+    bmdDeviceInterfaceUSB                                        = 'usb ',
+    bmdDeviceInterfaceThunderbolt                                = 'thun'
+};
+
+/* Enum BMDDeckLinkFrameMetadataID - DeckLink Frame Metadata ID */
+
+typedef uint32_t BMDDeckLinkFrameMetadataID;
+enum _BMDDeckLinkFrameMetadataID {
+    bmdDeckLinkFrameMetadataHDRElectroOpticalTransferFunc        = 'eotf',	// EOTF in range 0-7 as per CEA 861.3
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedX              = 'hdrx',	// Red display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedY              = 'hdry',	// Red display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenX            = 'hdgx',	// Green display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenY            = 'hdgy',	// Green display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueX             = 'hdbx',	// Blue display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueY             = 'hdby',	// Blue display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRWhitePointX                       = 'hdwx',	// White point in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRWhitePointY                       = 'hdwy',	// White point in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRMaxDisplayMasteringLuminance      = 'hdml',	// Max display mastering luminance in range 1 cd/m2 - 65535 cd/m2
+    bmdDeckLinkFrameMetadataHDRMinDisplayMasteringLuminance      = 'hmil',	// Min display mastering luminance in range 0.0001 cd/m2 - 6.5535 cd/m2
+    bmdDeckLinkFrameMetadataHDRMaximumContentLightLevel          = 'mcll',	// Maximum Content Light Level in range 1 cd/m2 - 65535 cd/m2
+    bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel     = 'fall'	// Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2
+};
+
+/* Enum BMDDuplexMode - Duplex for configurable ports */
+
+typedef uint32_t BMDDuplexMode;
+enum _BMDDuplexMode {
+    bmdDuplexModeFull                                            = 'fdup',
+    bmdDuplexModeHalf                                            = 'hdup'
 };
 
 /* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */
@@ -292,10 +380,16 @@ enum _BMDDeckLinkAttributeID {
     BMDDeckLinkCanOnlyAdjustOverallVideoOutputGain               = 'ovog',
     BMDDeckLinkHasVideoInputAntiAliasingFilter                   = 'aafl',
     BMDDeckLinkHasBypass                                         = 'byps',
-    BMDDeckLinkSupportsDesktopDisplay                            = 'extd',
     BMDDeckLinkSupportsClockTimingAdjustment                     = 'ctad',
     BMDDeckLinkSupportsFullDuplex                                = 'fdup',
     BMDDeckLinkSupportsFullFrameReferenceInputTimingOffset       = 'frin',
+    BMDDeckLinkSupportsSMPTELevelAOutput                         = 'lvla',
+    BMDDeckLinkSupportsDualLinkSDI                               = 'sdls',
+    BMDDeckLinkSupportsQuadLinkSDI                               = 'sqls',
+    BMDDeckLinkSupportsIdleOutput                                = 'idou',
+    BMDDeckLinkHasLTCTimecodeInput                               = 'hltc',
+    BMDDeckLinkSupportsDuplexModeConfiguration                   = 'dupx',
+    BMDDeckLinkSupportsHDRMetadata                               = 'hdrm',
 
     /* Integers */
 
@@ -304,13 +398,20 @@ enum _BMDDeckLinkAttributeID {
     BMDDeckLinkNumberOfSubDevices                                = 'nsbd',
     BMDDeckLinkSubDeviceIndex                                    = 'subi',
     BMDDeckLinkPersistentID                                      = 'peid',
+    BMDDeckLinkDeviceGroupID                                     = 'dgid',
     BMDDeckLinkTopologicalID                                     = 'toid',
     BMDDeckLinkVideoOutputConnections                            = 'vocn',
     BMDDeckLinkVideoInputConnections                             = 'vicn',
     BMDDeckLinkAudioOutputConnections                            = 'aocn',
     BMDDeckLinkAudioInputConnections                             = 'aicn',
-    BMDDeckLinkDeviceBusyState                                   = 'dbst',
     BMDDeckLinkVideoIOSupport                                    = 'vios',	// Returns a BMDVideoIOSupport bit field
+    BMDDeckLinkDeckControlConnections                            = 'dccn',
+    BMDDeckLinkDeviceInterface                                   = 'dbus',	// Returns a BMDDeviceInterface
+    BMDDeckLinkAudioInputRCAChannelCount                         = 'airc',
+    BMDDeckLinkAudioInputXLRChannelCount                         = 'aixc',
+    BMDDeckLinkAudioOutputRCAChannelCount                        = 'aorc',
+    BMDDeckLinkAudioOutputXLRChannelCount                        = 'aoxc',
+    BMDDeckLinkPairedDevicePersistentID                          = 'ppid',
 
     /* Floats */
 
@@ -318,10 +419,16 @@ enum _BMDDeckLinkAttributeID {
     BMDDeckLinkVideoInputGainMaximum                             = 'vigx',
     BMDDeckLinkVideoOutputGainMinimum                            = 'vogm',
     BMDDeckLinkVideoOutputGainMaximum                            = 'vogx',
+    BMDDeckLinkMicrophoneInputGainMinimum                        = 'migm',
+    BMDDeckLinkMicrophoneInputGainMaximum                        = 'migx',
 
     /* Strings */
 
-    BMDDeckLinkSerialPortDeviceName                              = 'slpn'
+    BMDDeckLinkSerialPortDeviceName                              = 'slpn',
+    BMDDeckLinkVendorName                                        = 'vndr',
+    BMDDeckLinkDisplayName                                       = 'dspn',
+    BMDDeckLinkModelName                                         = 'mdln',
+    BMDDeckLinkDeviceHandle                                      = 'devh'
 };
 
 /* Enum BMDDeckLinkAPIInformationID - DeckLinkAPI information ID */
@@ -331,6 +438,52 @@ enum _BMDDeckLinkAPIInformationID {
     BMDDeckLinkAPIVersion                                        = 'vers'
 };
 
+/* Enum BMDDeckLinkStatusID - DeckLink Status ID */
+
+typedef uint32_t BMDDeckLinkStatusID;
+enum _BMDDeckLinkStatusID {
+
+    /* Integers */
+
+    bmdDeckLinkStatusDetectedVideoInputMode                      = 'dvim',
+    bmdDeckLinkStatusDetectedVideoInputFlags                     = 'dvif',
+    bmdDeckLinkStatusCurrentVideoInputMode                       = 'cvim',
+    bmdDeckLinkStatusCurrentVideoInputPixelFormat                = 'cvip',
+    bmdDeckLinkStatusCurrentVideoInputFlags                      = 'cvif',
+    bmdDeckLinkStatusCurrentVideoOutputMode                      = 'cvom',
+    bmdDeckLinkStatusCurrentVideoOutputFlags                     = 'cvof',
+    bmdDeckLinkStatusPCIExpressLinkWidth                         = 'pwid',
+    bmdDeckLinkStatusPCIExpressLinkSpeed                         = 'plnk',
+    bmdDeckLinkStatusLastVideoOutputPixelFormat                  = 'opix',
+    bmdDeckLinkStatusReferenceSignalMode                         = 'refm',
+    bmdDeckLinkStatusReferenceSignalFlags                        = 'reff',
+    bmdDeckLinkStatusDuplexMode                                  = 'dupx',
+    bmdDeckLinkStatusBusy                                        = 'busy',
+
+    /* Flags */
+
+    bmdDeckLinkStatusVideoInputSignalLocked                      = 'visl',
+    bmdDeckLinkStatusReferenceSignalLocked                       = 'refl'
+};
+
+/* Enum BMDDeckLinkVideoStatusFlags -  */
+
+typedef uint32_t BMDDeckLinkVideoStatusFlags;
+enum _BMDDeckLinkVideoStatusFlags {
+    bmdDeckLinkVideoStatusPsF                                    = 1 << 0,
+    bmdDeckLinkVideoStatusDualStream3D                           = 1 << 1
+};
+
+/* Enum BMDDuplexStatus - Duplex status of the device */
+
+typedef uint32_t BMDDuplexStatus;
+enum _BMDDuplexStatus {
+    bmdDuplexStatusFullDuplex                                    = 'fdup',
+    bmdDuplexStatusHalfDuplex                                    = 'hdup',
+    bmdDuplexStatusSimplex                                       = 'splx',
+    bmdDuplexStatusInactive                                      = 'inac'
+};
+
 /* Enum BMDDeviceBusyState - Current device busy state */
 
 typedef uint32_t BMDDeviceBusyState;
@@ -363,7 +516,8 @@ enum _BMD3DPreviewFormat {
 
 typedef uint32_t BMDNotifications;
 enum _BMDNotifications {
-    bmdPreferencesChanged                                        = 'pref'
+    bmdPreferencesChanged                                        = 'pref',
+    bmdStatusChanged                                             = 'stat'
 };
 
 #if defined(__cplusplus)
@@ -372,17 +526,24 @@ enum _BMDNotifications {
 
 class IDeckLinkVideoOutputCallback;
 class IDeckLinkInputCallback;
+class IDeckLinkEncoderInputCallback;
 class IDeckLinkMemoryAllocator;
 class IDeckLinkAudioOutputCallback;
 class IDeckLinkIterator;
 class IDeckLinkAPIInformation;
 class IDeckLinkOutput;
 class IDeckLinkInput;
+class IDeckLinkEncoderInput;
 class IDeckLinkVideoFrame;
 class IDeckLinkMutableVideoFrame;
 class IDeckLinkVideoFrame3DExtensions;
+class IDeckLinkVideoFrameMetadataExtensions;
 class IDeckLinkVideoInputFrame;
 class IDeckLinkVideoFrameAncillary;
+class IDeckLinkEncoderPacket;
+class IDeckLinkEncoderVideoPacket;
+class IDeckLinkEncoderAudioPacket;
+class IDeckLinkH265NALPacket;
 class IDeckLinkAudioInputPacket;
 class IDeckLinkScreenPreviewCallback;
 class IDeckLinkCocoaScreenPreviewCallback;
@@ -390,6 +551,7 @@ class IDeckLinkGLScreenPreviewHelper;
 class IDeckLinkNotificationCallback;
 class IDeckLinkNotification;
 class IDeckLinkAttributes;
+class IDeckLinkStatus;
 class IDeckLinkKeyer;
 class IDeckLinkVideoConversion;
 class IDeckLinkDeviceNotificationCallback;
@@ -419,6 +581,19 @@ protected:
     virtual ~IDeckLinkInputCallback () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkEncoderInputCallback - Frame arrival callback. */
+
+class IDeckLinkEncoderInputCallback : public IUnknown
+{
+public:
+    virtual HRESULT VideoInputSignalChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0;
+    virtual HRESULT VideoPacketArrived (/* in */ IDeckLinkEncoderVideoPacket* videoPacket) = 0;
+    virtual HRESULT AudioPacketArrived (/* in */ IDeckLinkEncoderAudioPacket* audioPacket) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderInputCallback () {} // call Release method to drop reference count
+};
+
 /* Interface IDeckLinkMemoryAllocator - Memory allocator for video frames. */
 
 class IDeckLinkMemoryAllocator : public IUnknown
@@ -557,6 +732,43 @@ protected:
     virtual ~IDeckLinkInput () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkEncoderInput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkEncoderInput : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0;
+
+    /* Video Input */
+
+    virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0;
+    virtual HRESULT DisableVideoInput (void) = 0;
+    virtual HRESULT GetAvailablePacketsCount (/* out */ uint32_t *availablePacketsCount) = 0;
+    virtual HRESULT SetMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0;
+
+    /* Audio Input */
+
+    virtual HRESULT EnableAudioInput (/* in */ BMDAudioFormat audioFormat, /* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0;
+    virtual HRESULT DisableAudioInput (void) = 0;
+    virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0;
+
+    /* Input Control */
+
+    virtual HRESULT StartStreams (void) = 0;
+    virtual HRESULT StopStreams (void) = 0;
+    virtual HRESULT PauseStreams (void) = 0;
+    virtual HRESULT FlushStreams (void) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkEncoderInputCallback *theCallback) = 0;
+
+    /* Hardware Timing */
+
+    virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderInput () {} // call Release method to drop reference count
+};
+
 /* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */
 
 class IDeckLinkVideoFrame : public IUnknown
@@ -604,6 +816,20 @@ protected:
     virtual ~IDeckLinkVideoFrame3DExtensions () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkVideoFrameMetadataExtensions - Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDMI HDR information */
+
+class IDeckLinkVideoFrameMetadataExtensions : public IUnknown
+{
+public:
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ int64_t *value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ double *value) = 0;
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ bool* value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ CFStringRef *value) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoFrameMetadataExtensions () {} // call Release method to drop reference count
+};
+
 /* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */
 
 class IDeckLinkVideoInputFrame : public IDeckLinkVideoFrame
@@ -630,6 +856,58 @@ protected:
     virtual ~IDeckLinkVideoFrameAncillary () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkEncoderPacket - Interface to encapsulate an encoded packet. */
+
+class IDeckLinkEncoderPacket : public IUnknown
+{
+public:
+    virtual HRESULT GetBytes (/* out */ void **buffer) = 0;
+    virtual long GetSize (void) = 0;
+    virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* in */ BMDTimeScale timeScale) = 0;
+    virtual BMDPacketType GetPacketType (void) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderPacket () {} // call Release method to drop reference count
+};
+
+/* Interface IDeckLinkEncoderVideoPacket - Provided by the IDeckLinkEncoderInput video packet arrival callback. */
+
+class IDeckLinkEncoderVideoPacket : public IDeckLinkEncoderPacket
+{
+public:
+    virtual BMDPixelFormat GetPixelFormat (void) = 0;
+    virtual HRESULT GetHardwareReferenceTimestamp (/* in */ BMDTimeScale timeScale, /* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration) = 0;
+
+    virtual HRESULT GetTimecode (/* in */ BMDTimecodeFormat format, /* out */ IDeckLinkTimecode **timecode) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderVideoPacket () {} // call Release method to drop reference count
+};
+
+/* Interface IDeckLinkEncoderAudioPacket - Provided by the IDeckLinkEncoderInput audio packet arrival callback. */
+
+class IDeckLinkEncoderAudioPacket : public IDeckLinkEncoderPacket
+{
+public:
+    virtual BMDAudioFormat GetAudioFormat (void) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderAudioPacket () {} // call Release method to drop reference count
+};
+
+/* Interface IDeckLinkH265NALPacket - Obtained through QueryInterface() on an IDeckLinkEncoderVideoPacket object */
+
+class IDeckLinkH265NALPacket : public IDeckLinkEncoderVideoPacket
+{
+public:
+    virtual HRESULT GetUnitType (/* out */ uint8_t *unitType) = 0;
+    virtual HRESULT GetBytesNoPrefix (/* out */ void **buffer) = 0;
+    virtual long GetSizeNoPrefix (void) = 0;
+
+protected:
+    virtual ~IDeckLinkH265NALPacket () {} // call Release method to drop reference count
+};
+
 /* Interface IDeckLinkAudioInputPacket - Provided by the IDeckLinkInput callback. */
 
 class IDeckLinkAudioInputPacket : public IUnknown
@@ -712,6 +990,21 @@ protected:
     virtual ~IDeckLinkAttributes () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkStatus - DeckLink Status interface */
+
+class IDeckLinkStatus : public IUnknown
+{
+public:
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkStatusID statusID, /* out */ bool *value) = 0;
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkStatusID statusID, /* out */ int64_t *value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkStatusID statusID, /* out */ double *value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkStatusID statusID, /* out */ CFStringRef *value) = 0;
+    virtual HRESULT GetBytes (/* in */ BMDDeckLinkStatusID statusID, /* out */ void *buffer, /* in, out */ uint32_t *bufferSize) = 0;
+
+protected:
+    virtual ~IDeckLinkStatus () {} // call Release method to drop reference count
+};
+
 /* Interface IDeckLinkKeyer - DeckLink Keyer interface */
 
 class IDeckLinkKeyer : public IUnknown
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration.h
index 10a1d6e..31b652b 100644
--- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration.h
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -42,7 +42,8 @@
 
 // Interface ID Declarations
 
-BMD_CONST REFIID IID_IDeckLinkConfiguration                       = /* 1E69FCF6-4203-4936-8076-2A9F4CFD50CB */ {0x1E,0x69,0xFC,0xF6,0x42,0x03,0x49,0x36,0x80,0x76,0x2A,0x9F,0x4C,0xFD,0x50,0xCB};
+BMD_CONST REFIID IID_IDeckLinkConfiguration                       = /* CB71734A-FE37-4E8D-8E13-802133A1C3F2 */ {0xCB,0x71,0x73,0x4A,0xFE,0x37,0x4E,0x8D,0x8E,0x13,0x80,0x21,0x33,0xA1,0xC3,0xF2};
+BMD_CONST REFIID IID_IDeckLinkEncoderConfiguration                = /* 138050E5-C60A-4552-BF3F-0F358049327E */ {0x13,0x80,0x50,0xE5,0xC6,0x0A,0x45,0x52,0xBF,0x3F,0x0F,0x35,0x80,0x49,0x32,0x7E};
 
 /* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */
 
@@ -62,6 +63,7 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigHDMI3DPackingFormat                         = '3dpf',
     bmdDeckLinkConfigBypass                                      = 'byps',
     bmdDeckLinkConfigClockTimingAdjustment                       = 'ctad',
+    bmdDeckLinkConfigDuplexMode                                  = 'dupx',
 
     /* Audio Input/Output Flags */
 
@@ -72,9 +74,10 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigFieldFlickerRemoval                         = 'fdfr',
     bmdDeckLinkConfigHD1080p24ToHD1080i5994Conversion            = 'to59',
     bmdDeckLinkConfig444SDIVideoOutput                           = '444o',
-    bmdDeckLinkConfigSingleLinkVideoOutput                       = 'sglo',
     bmdDeckLinkConfigBlackVideoOutputDuringCapture               = 'bvoc',
     bmdDeckLinkConfigLowLatencyVideoOutput                       = 'llvo',
+    bmdDeckLinkConfigDownConversionOnAllAnalogOutput             = 'caao',
+    bmdDeckLinkConfigSMPTELevelAOutput                           = 'smta',
 
     /* Video Output Integers */
 
@@ -85,6 +88,7 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigVideoOutputIdleOperation                    = 'voio',
     bmdDeckLinkConfigDefaultVideoOutputMode                      = 'dvom',
     bmdDeckLinkConfigDefaultVideoOutputModeFlags                 = 'dvof',
+    bmdDeckLinkConfigSDIOutputLinkConfiguration                  = 'solc',
 
     /* Video Output Floats */
 
@@ -100,6 +104,7 @@ enum _BMDDeckLinkConfigurationID {
 
     bmdDeckLinkConfigVideoInputScanning                          = 'visc',	// Applicable to H264 Pro Recorder only
     bmdDeckLinkConfigUseDedicatedLTCInput                        = 'dltc',	// Use timecode from LTC input instead of SDI stream
+    bmdDeckLinkConfigSDIInput3DPayloadOverride                   = '3dds',
 
     /* Video Input Integers */
 
@@ -122,6 +127,10 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigVideoInputSVideoLumaGain                    = 'islg',
     bmdDeckLinkConfigVideoInputSVideoChromaGain                  = 'iscg',
 
+    /* Audio Input Flags */
+
+    bmdDeckLinkConfigMicrophonePhantomPower                      = 'mphp',
+
     /* Audio Input Integers */
 
     bmdDeckLinkConfigAudioInputConnection                        = 'aicn',
@@ -133,6 +142,7 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigAnalogAudioInputScaleChannel3               = 'ais3',
     bmdDeckLinkConfigAnalogAudioInputScaleChannel4               = 'ais4',
     bmdDeckLinkConfigDigitalAudioInputScale                      = 'dais',
+    bmdDeckLinkConfigMicrophoneInputGain                         = 'micg',
 
     /* Audio Output Integers */
 
@@ -144,12 +154,55 @@ enum _BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigAnalogAudioOutputScaleChannel2              = 'aos2',
     bmdDeckLinkConfigAnalogAudioOutputScaleChannel3              = 'aos3',
     bmdDeckLinkConfigAnalogAudioOutputScaleChannel4              = 'aos4',
-    bmdDeckLinkConfigDigitalAudioOutputScale                     = 'daos'
+    bmdDeckLinkConfigDigitalAudioOutputScale                     = 'daos',
+    bmdDeckLinkConfigHeadphoneVolume                             = 'hvol',
+
+    /* Device Information Strings */
+
+    bmdDeckLinkConfigDeviceInformationLabel                      = 'dila',
+    bmdDeckLinkConfigDeviceInformationSerialNumber               = 'disn',
+    bmdDeckLinkConfigDeviceInformationCompany                    = 'dico',
+    bmdDeckLinkConfigDeviceInformationPhone                      = 'diph',
+    bmdDeckLinkConfigDeviceInformationEmail                      = 'diem',
+    bmdDeckLinkConfigDeviceInformationDate                       = 'dida',
+
+    /* Deck Control Integers */
+
+    bmdDeckLinkConfigDeckControlConnection                       = 'dcco'
+};
+
+/* Enum BMDDeckLinkEncoderConfigurationID - DeckLink Encoder Configuration ID */
+
+typedef uint32_t BMDDeckLinkEncoderConfigurationID;
+enum _BMDDeckLinkEncoderConfigurationID {
+
+    /* Video Encoder Integers */
+
+    bmdDeckLinkEncoderConfigPreferredBitDepth                    = 'epbr',
+    bmdDeckLinkEncoderConfigFrameCodingMode                      = 'efcm',
+
+    /* HEVC/H.265 Encoder Integers */
+
+    bmdDeckLinkEncoderConfigH265TargetBitrate                    = 'htbr',
+
+    /* DNxHR/DNxHD Compression ID */
+
+    bmdDeckLinkEncoderConfigDNxHRCompressionID                   = 'dcid',
+
+    /* DNxHR/DNxHD Level */
+
+    bmdDeckLinkEncoderConfigDNxHRLevel                           = 'dlev',
+
+    /* Encoded Sample Decriptions */
+
+    bmdDeckLinkEncoderConfigMPEG4SampleDescription               = 'stsE',	// Full MPEG4 sample description (aka SampleEntry of an 'stsd' atom-box). Useful for MediaFoundation, QuickTime, MKV and more
+    bmdDeckLinkEncoderConfigMPEG4CodecSpecificDesc               = 'esds'	// Sample description extensions only (atom stream, each with size and fourCC header). Useful for AVFoundation, VideoToolbox, MKV and more
 };
 
 // Forward Declarations
 
 class IDeckLinkConfiguration;
+class IDeckLinkEncoderConfiguration;
 
 /* Interface IDeckLinkConfiguration - DeckLink Configuration interface */
 
@@ -170,6 +223,25 @@ protected:
     virtual ~IDeckLinkConfiguration () {} // call Release method to drop reference count
 };
 
+/* Interface IDeckLinkEncoderConfiguration - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */
+
+class IDeckLinkEncoderConfiguration : public IUnknown
+{
+public:
+    virtual HRESULT SetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ bool value) = 0;
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ bool *value) = 0;
+    virtual HRESULT SetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ int64_t value) = 0;
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ int64_t *value) = 0;
+    virtual HRESULT SetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ double value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ double *value) = 0;
+    virtual HRESULT SetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ CFStringRef value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ CFStringRef *value) = 0;
+    virtual HRESULT GetBytes (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ void *buffer /* optional */, /* in, out */ uint32_t *bufferSize) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderConfiguration () {} // call Release method to drop reference count
+};
+
 /* Functions */
 
 extern "C" {
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h
new file mode 100644
index 0000000..ca7f815
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h
@@ -0,0 +1,60 @@
+/* -LICENSE-START-
+** Copyright (c) 2014 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPICONFIGURATION_v10_2_H
+#define BMD_DECKLINKAPICONFIGURATION_v10_2_H
+
+#include "DeckLinkAPIConfiguration.h"
+
+// Interface ID Declarations
+
+BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_2                = /* C679A35B-610C-4D09-B748-1D0478100FC0 */ {0xC6,0x79,0xA3,0x5B,0x61,0x0C,0x4D,0x09,0xB7,0x48,0x1D,0x04,0x78,0x10,0x0F,0xC0};
+
+// Forward Declarations
+
+class IDeckLinkConfiguration_v10_2;
+
+/* Interface IDeckLinkConfiguration_v10_2 - DeckLink Configuration interface */
+
+class IDeckLinkConfiguration_v10_2 : public IUnknown
+{
+public:
+    virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0;
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0;
+    virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0;
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0;
+    virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0;
+    virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ CFStringRef value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ CFStringRef *value) = 0;
+    virtual HRESULT WriteConfigurationToPreferences (void) = 0;
+
+protected:
+    virtual ~IDeckLinkConfiguration_v10_2 () {} // call Release method to drop reference count
+};
+
+#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_2_H) */
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_4.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_4.h
new file mode 100644
index 0000000..21e02ee
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_4.h
@@ -0,0 +1,62 @@
+/* -LICENSE-START-
+** Copyright (c) 2015 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPICONFIGURATION_v10_4_H
+#define BMD_DECKLINKAPICONFIGURATION_v10_4_H
+
+#include "DeckLinkAPIConfiguration.h"
+
+// Interface ID Declarations
+
+BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_4                       = /* 1E69FCF6-4203-4936-8076-2A9F4CFD50CB */ {0x1E,0x69,0xFC,0xF6,0x42,0x03,0x49,0x36,0x80,0x76,0x2A,0x9F,0x4C,0xFD,0x50,0xCB};
+
+//
+// Forward Declarations
+
+class IDeckLinkConfiguration_v10_4;
+
+/* Interface IDeckLinkConfiguration_v10_4 - DeckLink Configuration interface */
+
+class IDeckLinkConfiguration_v10_4 : public IUnknown
+{
+public:
+    virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0;
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0;
+    virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0;
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0;
+    virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0;
+    virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ CFStringRef value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ CFStringRef *value) = 0;
+    virtual HRESULT WriteConfigurationToPreferences (void) = 0;
+
+protected:
+    virtual ~IDeckLinkConfiguration_v10_4 () {} // call Release method to drop reference count
+};
+
+
+#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_4_H) */
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h
new file mode 100644
index 0000000..29695cf
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h
@@ -0,0 +1,60 @@
+/* -LICENSE-START-
+** Copyright (c) 2015 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPICONFIGURATION_v10_5_H
+#define BMD_DECKLINKAPICONFIGURATION_v10_5_H
+
+#include "DeckLinkAPIConfiguration.h"
+
+// Interface ID Declarations
+
+BMD_CONST REFIID IID_IDeckLinkEncoderConfiguration_v10_5          = /* 67455668-0848-45DF-8D8E-350A77C9A028 */ {0x67,0x45,0x56,0x68,0x08,0x48,0x45,0xDF,0x8D,0x8E,0x35,0x0A,0x77,0xC9,0xA0,0x28};
+
+// Forward Declarations
+
+class IDeckLinkConfiguration_v10_5;
+
+/* Interface IDeckLinkEncoderConfiguration_v10_5 - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */
+
+class IDeckLinkEncoderConfiguration_v10_5 : public IUnknown
+{
+public:
+    virtual HRESULT SetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ bool value) = 0;
+    virtual HRESULT GetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ bool *value) = 0;
+    virtual HRESULT SetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ int64_t value) = 0;
+    virtual HRESULT GetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ int64_t *value) = 0;
+    virtual HRESULT SetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ double value) = 0;
+    virtual HRESULT GetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ double *value) = 0;
+    virtual HRESULT SetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ CFStringRef value) = 0;
+    virtual HRESULT GetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ CFStringRef *value) = 0;
+    virtual HRESULT GetDecoderConfigurationInfo (/* out */ void *buffer, /* in */ long bufferSize, /* out */ long *returnedSize) = 0;
+
+protected:
+    virtual ~IDeckLinkEncoderConfiguration_v10_5 () {} // call Release method to drop reference count
+};
+
+#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_5_H) */
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDeckControl.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDeckControl.h
index 886f632..6237ab7 100644
--- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDeckControl.h
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDeckControl.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDiscovery.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDiscovery.h
index 016750e..3715a03 100644
--- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDiscovery.h
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDiscovery.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp
new file mode 100644
index 0000000..8b0c0cc
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp
@@ -0,0 +1,105 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPIDispatch_v7_6.cpp */
+
+#include "DeckLinkAPI_v7_6.h"
+#include <pthread.h>
+
+#define kDeckLinkAPI_BundlePath "/Library/Frameworks/DeckLinkAPI.framework"
+
+typedef IDeckLinkIterator* (*CreateIteratorFunc_v7_6)(void);
+typedef IDeckLinkGLScreenPreviewHelper_v7_6* (*CreateOpenGLScreenPreviewHelperFunc_v7_6)(void);
+typedef IDeckLinkCocoaScreenPreviewCallback_v7_6* (*CreateCocoaScreenPreviewFunc_v7_6)(void*);
+typedef IDeckLinkVideoConversion_v7_6* (*CreateVideoConversionInstanceFunc_v7_6)(void);
+
+static pthread_once_t								gDeckLinkOnceControl		= PTHREAD_ONCE_INIT;
+static CFBundleRef									gBundleRef					= NULL;
+static CreateIteratorFunc_v7_6						gCreateIteratorFunc			= NULL;
+static CreateOpenGLScreenPreviewHelperFunc_v7_6		gCreateOpenGLPreviewFunc	= NULL;
+static CreateCocoaScreenPreviewFunc_v7_6			gCreateCocoaPreviewFunc		= NULL;
+static CreateVideoConversionInstanceFunc_v7_6		gCreateVideoConversionFunc	= NULL;
+
+
+void	InitDeckLinkAPI_v7_6 (void)
+{
+	CFURLRef		bundleURL;
+
+	bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kDeckLinkAPI_BundlePath), kCFURLPOSIXPathStyle, true);
+	if (bundleURL != NULL)
+	{
+		gBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL);
+		if (gBundleRef != NULL)
+		{
+			gCreateIteratorFunc = (CreateIteratorFunc_v7_6)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateDeckLinkIteratorInstance"));
+			gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc_v7_6)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper"));
+			gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc_v7_6)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateCocoaScreenPreview"));
+			gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc_v7_6)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateVideoConversionInstance"));
+		}
+		CFRelease(bundleURL);
+	}
+}
+
+IDeckLinkIterator*		CreateDeckLinkIteratorInstance_v7_6 (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6);
+
+	if (gCreateIteratorFunc == NULL)
+		return NULL;
+
+	return gCreateIteratorFunc();
+}
+
+IDeckLinkGLScreenPreviewHelper_v7_6*		CreateOpenGLScreenPreviewHelper_v7_6 (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6);
+
+	if (gCreateOpenGLPreviewFunc == NULL)
+		return NULL;
+
+	return gCreateOpenGLPreviewFunc();
+}
+
+IDeckLinkCocoaScreenPreviewCallback_v7_6*	CreateCocoaScreenPreview_v7_6 (void* parentView)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6);
+
+	if (gCreateCocoaPreviewFunc == NULL)
+		return NULL;
+
+	return gCreateCocoaPreviewFunc(parentView);
+}
+
+IDeckLinkVideoConversion_v7_6* CreateVideoConversionInstance_v7_6 (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6);
+
+	if (gCreateVideoConversionFunc == NULL)
+		return NULL;
+
+	return gCreateVideoConversionFunc();
+}
+
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp
new file mode 100644
index 0000000..898d739
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp
@@ -0,0 +1,131 @@
+/* -LICENSE-START-
+** Copyright (c) 2011 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPIDispatch.cpp */
+
+#include "DeckLinkAPI_v8_0.h"
+#include <pthread.h>
+
+#if BLACKMAGIC_DECKLINK_API_MAGIC != 1
+	#error The DeckLink API version of DeckLinkAPIDispatch.cpp is not the same version as DeckLinkAPI.h
+#endif
+
+#define kDeckLinkAPI_BundlePath "/Library/Frameworks/DeckLinkAPI.framework"
+
+typedef IDeckLinkIterator_v8_0* (*CreateIteratorFunc)(void);
+typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void);
+typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void);
+typedef IDeckLinkCocoaScreenPreviewCallback* (*CreateCocoaScreenPreviewFunc)(void*);
+typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void);
+
+static pthread_once_t						gDeckLinkOnceControl		= PTHREAD_ONCE_INIT;
+static CFBundleRef							gDeckLinkAPIBundleRef		= NULL;
+static CreateIteratorFunc					gCreateIteratorFunc			= NULL;
+static CreateAPIInformationFunc				gCreateAPIInformationFunc	= NULL;
+static CreateOpenGLScreenPreviewHelperFunc	gCreateOpenGLPreviewFunc	= NULL;
+static CreateCocoaScreenPreviewFunc			gCreateCocoaPreviewFunc		= NULL;
+static CreateVideoConversionInstanceFunc	gCreateVideoConversionFunc	= NULL;
+
+
+void	InitDeckLinkAPI (void)
+{
+	CFURLRef		bundleURL;
+
+	bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kDeckLinkAPI_BundlePath), kCFURLPOSIXPathStyle, true);
+	if (bundleURL != NULL)
+	{
+		gDeckLinkAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL);
+		if (gDeckLinkAPIBundleRef != NULL)
+		{
+			gCreateIteratorFunc = (CreateIteratorFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkIteratorInstance_0001"));
+			gCreateAPIInformationFunc = (CreateAPIInformationFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkAPIInformationInstance_0001"));
+			gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper_0001"));
+			gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateCocoaScreenPreview_0001"));
+			gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoConversionInstance_0001"));
+		}
+		CFRelease(bundleURL);
+	}
+}
+
+bool		IsDeckLinkAPIPresent (void)
+{
+	// If the DeckLink API bundle was successfully loaded, return this knowledge to the caller
+	if (gDeckLinkAPIBundleRef != NULL)
+		return true;
+
+	return false;
+}
+
+IDeckLinkIterator_v8_0*		CreateDeckLinkIteratorInstance (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+	if (gCreateIteratorFunc == NULL)
+		return NULL;
+
+	return gCreateIteratorFunc();
+}
+
+IDeckLinkAPIInformation*	CreateDeckLinkAPIInformationInstance (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+	if (gCreateAPIInformationFunc == NULL)
+		return NULL;
+
+	return gCreateAPIInformationFunc();
+}
+
+IDeckLinkGLScreenPreviewHelper*		CreateOpenGLScreenPreviewHelper (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+	if (gCreateOpenGLPreviewFunc == NULL)
+		return NULL;
+
+	return gCreateOpenGLPreviewFunc();
+}
+
+IDeckLinkCocoaScreenPreviewCallback*	CreateCocoaScreenPreview (void* parentView)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+	if (gCreateCocoaPreviewFunc == NULL)
+		return NULL;
+
+	return gCreateCocoaPreviewFunc(parentView);
+}
+
+IDeckLinkVideoConversion* CreateVideoConversionInstance (void)
+{
+	pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
+
+	if (gCreateVideoConversionFunc == NULL)
+		return NULL;
+
+	return gCreateVideoConversionFunc();
+}
+
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIModes.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIModes.h
index c61b1d4..3bc3429 100644
--- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIModes.h
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIModes.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -135,7 +135,12 @@ enum _BMDPixelFormat {
     bmdFormat12BitRGB                                            = 'R12B',	// Big-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component
     bmdFormat12BitRGBLE                                          = 'R12L',	// Little-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component
     bmdFormat10BitRGBXLE                                         = 'R10l',	// Little-endian 10-bit RGB with SMPTE video levels (64-940)
-    bmdFormat10BitRGBX                                           = 'R10b'	// Big-endian 10-bit RGB with SMPTE video levels (64-940)
+    bmdFormat10BitRGBX                                           = 'R10b',	// Big-endian 10-bit RGB with SMPTE video levels (64-940)
+    bmdFormatH265                                                = 'hev1',	// High Efficiency Video Coding (HEVC/h.265)
+
+    /* AVID DNxHR */
+
+    bmdFormatDNxHR                                               = 'AVdh'
 };
 
 /* Enum BMDDisplayModeFlags - Flags to describe the characteristics of an IDeckLinkDisplayMode. */
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIStreaming.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIStreaming.h
index 875ec06..6bb5168 100644
--- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIStreaming.h
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIStreaming.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPITypes.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPITypes.h
index 58f87e6..04da49f 100644
--- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPITypes.h
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPITypes.h
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -77,7 +77,17 @@ enum _BMDAudioConnection {
     bmdAudioConnectionAESEBU                                     = 1 << 1,
     bmdAudioConnectionAnalog                                     = 1 << 2,
     bmdAudioConnectionAnalogXLR                                  = 1 << 3,
-    bmdAudioConnectionAnalogRCA                                  = 1 << 4
+    bmdAudioConnectionAnalogRCA                                  = 1 << 4,
+    bmdAudioConnectionMicrophone                                 = 1 << 5,
+    bmdAudioConnectionHeadphones                                 = 1 << 6
+};
+
+/* Enum BMDDeckControlConnection - Deck control connections */
+
+typedef uint32_t BMDDeckControlConnection;
+enum _BMDDeckControlConnection {
+    bmdDeckControlConnectionRS422Remote1                         = 1 << 0,
+    bmdDeckControlConnectionRS422Remote2                         = 1 << 1
 };
 
 // Forward Declarations
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIVersion.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIVersion.h
index 719ae2b..55b24b1 100644
--- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIVersion.h
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIVersion.h
@@ -30,7 +30,7 @@
 #ifndef __DeckLink_API_Version_h__
 #define __DeckLink_API_Version_h__
 
-#define BLACKMAGIC_DECKLINK_API_VERSION					0x0a030100
-#define BLACKMAGIC_DECKLINK_API_VERSION_STRING			"10.3.1"
+#define BLACKMAGIC_DECKLINK_API_VERSION					0x0a080000
+#define BLACKMAGIC_DECKLINK_API_VERSION_STRING			"10.8"
 
 #endif	// __DeckLink_API_Version_h__
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_2.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_2.h
new file mode 100644
index 0000000..29ff820
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_2.h
@@ -0,0 +1,55 @@
+/* -LICENSE-START-
+** Copyright (c) 2014 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v10_2_H
+#define BMD_DECKLINKAPI_v10_2_H
+
+#include "DeckLinkAPI.h"
+
+// Type Declarations
+
+/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */
+
+typedef uint32_t BMDDeckLinkConfigurationID_v10_2;
+enum  _BMDDeckLinkConfigurationID_v10_2 {
+    /* Video output flags */
+
+    bmdDeckLinkConfig3GBpsVideoOutput_v10_2                      = '3gbs',
+};
+
+/* Enum BMDAudioConnection_v10_2 - Audio connection types */
+
+typedef uint32_t BMDAudioConnection_v10_2;
+enum _BMDAudioConnection_v10_2 {
+    bmdAudioConnectionEmbedded_v10_2                             = 'embd',
+    bmdAudioConnectionAESEBU_v10_2                               = 'aes ',
+    bmdAudioConnectionAnalog_v10_2                               = 'anlg',
+    bmdAudioConnectionAnalogXLR_v10_2                            = 'axlr',
+    bmdAudioConnectionAnalogRCA_v10_2                            = 'arca'
+};
+
+#endif /* defined(BMD_DECKLINKAPI_v10_2_H) */
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_4.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_4.h
new file mode 100644
index 0000000..7e5019c
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_4.h
@@ -0,0 +1,45 @@
+/* -LICENSE-START-
+** Copyright (c) 2015 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v10_4_H
+#define BMD_DECKLINKAPI_v10_4_H
+
+#include "DeckLinkAPI.h"
+
+// Type Declarations
+
+/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */
+
+typedef uint32_t BMDDeckLinkConfigurationID_v10_4;
+enum _BMDDeckLinkConfigurationID_v10_4 {
+
+    /* Video output flags */
+
+    bmdDeckLinkConfigSingleLinkVideoOutput_v10_4                       = /* 'sglo' */ 0x73676C6F,
+};
+
+#endif /* defined(BMD_DECKLINKAPI_v10_4_H) */
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_5.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_5.h
new file mode 100644
index 0000000..4439dae
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_5.h
@@ -0,0 +1,46 @@
+/* -LICENSE-START-
+** Copyright (c) 2015 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v10_5_H
+#define BMD_DECKLINKAPI_v10_5_H
+
+#include "DeckLinkAPI.h"
+
+// Type Declarations
+
+/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */
+
+typedef uint32_t BMDDeckLinkAttributeID_v10_5;
+enum _BMDDeckLinkAttributeID_v10_5 {
+
+    /* Integers */
+
+    BMDDeckLinkDeviceBusyState_v10_5                             = /* 'dbst' */ 0x64627374,
+};
+
+#endif /* defined(BMD_DECKLINKAPI_v10_5_H) */
+
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_6.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_6.h
new file mode 100644
index 0000000..7f78e53
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_6.h
@@ -0,0 +1,51 @@
+/* -LICENSE-START-
+** Copyright (c) 2016 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v10_6_H
+#define BMD_DECKLINKAPI_v10_6_H
+
+#include "DeckLinkAPI.h"
+
+// Type Declarations
+
+/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */
+
+typedef uint32_t BMDDeckLinkAttributeID_c10_6;
+enum _BMDDeckLinkAttributeID_v10_6 {
+
+    /* Flags */
+
+    BMDDeckLinkSupportsDesktopDisplay_v10_6                      = 'extd',
+};
+
+typedef uint32_t BMDIdleVideoOutputOperation_v10_6;
+enum _BMDIdleVideoOutputOperation_v10_6 {
+    bmdIdleVideoOutputDesktop_v10_6                              = 'desk'
+};
+
+
+#endif /* defined(BMD_DECKLINKAPI_v10_6_H) */
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_1.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_1.h
new file mode 100644
index 0000000..50e0d11
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_1.h
@@ -0,0 +1,198 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPI_v7_1.h */
+
+#ifndef __DeckLink_API_v7_1_h__
+#define __DeckLink_API_v7_1_h__
+
+#include "DeckLinkAPI.h"
+
+// "B28131B6-59AC-4857-B5AC-CD75D5883E2F"
+#define IID_IDeckLinkDisplayModeIterator_v7_1	(REFIID){0xB2,0x81,0x31,0xB6,0x59,0xAC,0x48,0x57,0xB5,0xAC,0xCD,0x75,0xD5,0x88,0x3E,0x2F}
+
+// "AF0CD6D5-8376-435E-8433-54F9DD530AC3"
+#define IID_IDeckLinkDisplayMode_v7_1			(REFIID){0xAF,0x0C,0xD6,0xD5,0x83,0x76,0x43,0x5E,0x84,0x33,0x54,0xF9,0xDD,0x53,0x0A,0xC3}
+
+// "EBD01AFA-E4B0-49C6-A01D-EDB9D1B55FD9"
+#define IID_IDeckLinkVideoOutputCallback_v7_1	(REFIID){0xEB,0xD0,0x1A,0xFA,0xE4,0xB0,0x49,0xC6,0xA0,0x1D,0xED,0xB9,0xD1,0xB5,0x5F,0xD9}
+
+// "7F94F328-5ED4-4E9F-9729-76A86BDC99CC"
+#define IID_IDeckLinkInputCallback_v7_1			(REFIID){0x7F,0x94,0xF3,0x28,0x5E,0xD4,0x4E,0x9F,0x97,0x29,0x76,0xA8,0x6B,0xDC,0x99,0xCC}
+
+// "AE5B3E9B-4E1E-4535-B6E8-480FF52F6CE5"
+#define IID_IDeckLinkOutput_v7_1				(REFIID){0xAE,0x5B,0x3E,0x9B,0x4E,0x1E,0x45,0x35,0xB6,0xE8,0x48,0x0F,0xF5,0x2F,0x6C,0xE5}
+
+// "2B54EDEF-5B32-429F-BA11-BB990596EACD"
+#define IID_IDeckLinkInput_v7_1					(REFIID){0x2B,0x54,0xED,0xEF,0x5B,0x32,0x42,0x9F,0xBA,0x11,0xBB,0x99,0x05,0x96,0xEA,0xCD}
+
+// "333F3A10-8C2D-43CF-B79D-46560FEEA1CE"
+#define IID_IDeckLinkVideoFrame_v7_1			(REFIID){0x33,0x3F,0x3A,0x10,0x8C,0x2D,0x43,0xCF,0xB7,0x9D,0x46,0x56,0x0F,0xEE,0xA1,0xCE}
+
+// "C8B41D95-8848-40EE-9B37-6E3417FB114B"
+#define IID_IDeckLinkVideoInputFrame_v7_1		(REFIID){0xC8,0xB4,0x1D,0x95,0x88,0x48,0x40,0xEE,0x9B,0x37,0x6E,0x34,0x17,0xFB,0x11,0x4B}
+
+// "C86DE4F6-A29F-42E3-AB3A-1363E29F0788"
+#define IID_IDeckLinkAudioInputPacket_v7_1		(REFIID){0xC8,0x6D,0xE4,0xF6,0xA2,0x9F,0x42,0xE3,0xAB,0x3A,0x13,0x63,0xE2,0x9F,0x07,0x88}
+
+#if defined(__cplusplus)
+
+class IDeckLinkVideoFrame_v7_1;
+class IDeckLinkDisplayModeIterator_v7_1;
+class IDeckLinkDisplayMode_v7_1;
+class IDeckLinkVideoInputFrame_v7_1;
+class IDeckLinkAudioInputPacket_v7_1;
+
+class IDeckLinkDisplayModeIterator_v7_1 : public IUnknown
+{
+public:
+	virtual	HRESULT	STDMETHODCALLTYPE	Next (IDeckLinkDisplayMode_v7_1* *deckLinkDisplayMode) = 0;
+};
+
+
+class IDeckLinkDisplayMode_v7_1 : public IUnknown
+{
+public:
+	virtual	HRESULT			STDMETHODCALLTYPE	GetName (CFStringRef* name) = 0;
+	virtual	BMDDisplayMode	STDMETHODCALLTYPE	GetDisplayMode () = 0;
+	virtual	long			STDMETHODCALLTYPE	GetWidth () = 0;
+	virtual	long			STDMETHODCALLTYPE	GetHeight () = 0;
+	virtual	HRESULT			STDMETHODCALLTYPE	GetFrameRate (BMDTimeValue *frameDuration, BMDTimeScale *timeScale) = 0;
+};
+
+class IDeckLinkVideoOutputCallback_v7_1 : public IUnknown
+{
+public:
+	virtual HRESULT STDMETHODCALLTYPE	ScheduledFrameCompleted (IDeckLinkVideoFrame_v7_1* completedFrame, BMDOutputFrameCompletionResult result) = 0;
+};
+
+class IDeckLinkInputCallback_v7_1 : public IUnknown
+{
+public:
+	virtual HRESULT STDMETHODCALLTYPE	VideoInputFrameArrived (IDeckLinkVideoInputFrame_v7_1* videoFrame, IDeckLinkAudioInputPacket_v7_1* audioPacket) = 0;
+};
+
+// IDeckLinkOutput_v7_1.  Created by QueryInterface from IDeckLink.
+class IDeckLinkOutput_v7_1 : public IUnknown
+{
+public:
+	// Display mode predicates
+	virtual	HRESULT	STDMETHODCALLTYPE	DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport *result) = 0;
+	virtual HRESULT	STDMETHODCALLTYPE	GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1* *iterator) = 0;
+
+
+	// Video output
+	virtual HRESULT STDMETHODCALLTYPE	EnableVideoOutput (BMDDisplayMode displayMode) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	DisableVideoOutput () = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	SetVideoOutputFrameMemoryAllocator (IDeckLinkMemoryAllocator* theAllocator) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	CreateVideoFrame (int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	CreateVideoFrameFromBuffer (void* buffer, int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	DisplayVideoFrameSync (IDeckLinkVideoFrame_v7_1* theFrame) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	ScheduleVideoFrame (IDeckLinkVideoFrame_v7_1* theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	SetScheduledFrameCompletionCallback (IDeckLinkVideoOutputCallback_v7_1* theCallback) = 0;
+
+
+	// Audio output
+	virtual HRESULT STDMETHODCALLTYPE	EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	DisableAudioOutput () = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	WriteAudioSamplesSync (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesWritten) = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	BeginAudioPreroll () = 0;
+	virtual HRESULT STDMETHODCALLTYPE	EndAudioPreroll () = 0;
+	virtual HRESULT STDMETHODCALLTYPE	ScheduleAudioSamples (void* buffer, uint32_t sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, uint32_t *sampleFramesWritten) = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	FlushBufferedAudioSamples () = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE	SetAudioCallback (IDeckLinkAudioOutputCallback* theCallback) = 0;
+
+
+	// Output control
+	virtual HRESULT STDMETHODCALLTYPE	StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, BMDTimeValue *actualStopTime, BMDTimeScale timeScale) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0;
+};
+
+// IDeckLinkInput_v7_1.  Created by QueryInterface from IDeckLink.
+class IDeckLinkInput_v7_1 : public IUnknown
+{
+public:
+	virtual	HRESULT	STDMETHODCALLTYPE	DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport *result) = 0;
+	virtual HRESULT	STDMETHODCALLTYPE	GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1 **iterator) = 0;
+
+	// Video input
+	virtual HRESULT STDMETHODCALLTYPE	EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	DisableVideoInput () = 0;
+
+	// Audio input
+	virtual HRESULT STDMETHODCALLTYPE	EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	DisableAudioInput () = 0;
+	virtual HRESULT STDMETHODCALLTYPE	ReadAudioSamples (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesRead, BMDTimeValue *audioPacketTime, BMDTimeScale timeScale) = 0;
+	virtual HRESULT STDMETHODCALLTYPE	GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0;
+
+	// Input control
+	virtual HRESULT	STDMETHODCALLTYPE	StartStreams () = 0;
+	virtual HRESULT	STDMETHODCALLTYPE	StopStreams () = 0;
+	virtual HRESULT	STDMETHODCALLTYPE	PauseStreams () = 0;
+	virtual HRESULT STDMETHODCALLTYPE	SetCallback (IDeckLinkInputCallback_v7_1* theCallback) = 0;
+};
+
+// IDeckLinkVideoFrame_v7_1.  Created by IDeckLinkOutput::CreateVideoFrame.
+class IDeckLinkVideoFrame_v7_1 : public IUnknown
+{
+public:
+	virtual long STDMETHODCALLTYPE					GetWidth () = 0;
+	virtual long STDMETHODCALLTYPE					GetHeight () = 0;
+	virtual long STDMETHODCALLTYPE					GetRowBytes () = 0;
+	virtual BMDPixelFormat STDMETHODCALLTYPE		GetPixelFormat () = 0;
+	virtual BMDFrameFlags STDMETHODCALLTYPE			GetFlags () = 0;
+	virtual HRESULT STDMETHODCALLTYPE				GetBytes (void* *buffer) = 0;
+};
+
+// IDeckLinkVideoInputFrame_v7_1.  Provided by the IDeckLinkInput_v7_1 frame arrival callback.
+class IDeckLinkVideoInputFrame_v7_1 : public IDeckLinkVideoFrame_v7_1
+{
+public:
+	virtual HRESULT STDMETHODCALLTYPE			GetFrameTime (BMDTimeValue *frameTime, BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0;
+};
+
+// IDeckLinkAudioInputPacket_v7_1.  Provided by the IDeckLinkInput_v7_1 callback.
+class IDeckLinkAudioInputPacket_v7_1 : public IUnknown
+{
+public:
+	virtual long STDMETHODCALLTYPE				GetSampleCount () = 0;
+	virtual HRESULT STDMETHODCALLTYPE			GetBytes (void* *buffer) = 0;
+
+	virtual HRESULT STDMETHODCALLTYPE			GetAudioPacketTime (BMDTimeValue *packetTime, BMDTimeScale timeScale) = 0;
+};
+
+#endif		// defined(__cplusplus)
+
+#endif		// __DeckLink_API_v7_1_h__
+
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_3.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_3.h
new file mode 100644
index 0000000..c8b3da8
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_3.h
@@ -0,0 +1,173 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* DeckLinkAPI_v7_3.h */
+
+#ifndef __DeckLink_API_v7_3_h__
+#define __DeckLink_API_v7_3_h__
+
+#include "DeckLinkAPI.h"
+#include "DeckLinkAPI_v7_6.h"
+
+/* Interface ID Declarations */
+
+#define IID_IDeckLinkInputCallback_v7_3                  /* FD6F311D-4D00-444B-9ED4-1F25B5730AD0 */ (REFIID){0xFD,0x6F,0x31,0x1D,0x4D,0x00,0x44,0x4B,0x9E,0xD4,0x1F,0x25,0xB5,0x73,0x0A,0xD0}
+#define IID_IDeckLinkOutput_v7_3                         /* 271C65E3-C323-4344-A30F-D908BCB20AA3 */ (REFIID){0x27,0x1C,0x65,0xE3,0xC3,0x23,0x43,0x44,0xA3,0x0F,0xD9,0x08,0xBC,0xB2,0x0A,0xA3}
+#define IID_IDeckLinkInput_v7_3                          /* 4973F012-9925-458C-871C-18774CDBBECB */ (REFIID){0x49,0x73,0xF0,0x12,0x99,0x25,0x45,0x8C,0x87,0x1C,0x18,0x77,0x4C,0xDB,0xBE,0xCB}
+#define IID_IDeckLinkVideoInputFrame_v7_3                /* CF317790-2894-11DE-8C30-0800200C9A66 */ (REFIID){0xCF,0x31,0x77,0x90,0x28,0x94,0x11,0xDE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66}
+
+/* End Interface ID Declarations */
+
+#if defined(__cplusplus)
+
+/* Forward Declarations */
+
+class IDeckLinkVideoInputFrame_v7_3;
+
+/* End Forward Declarations */
+
+
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkOutput_v7_3 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;
+
+    /* Video Output */
+
+    virtual HRESULT EnableVideoOutput (BMDDisplayMode displayMode, BMDVideoOutputFlags flags) = 0;
+    virtual HRESULT DisableVideoOutput (void) = 0;
+
+    virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0;
+    virtual HRESULT CreateVideoFrame (int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame_v7_6 **outFrame) = 0;
+    virtual HRESULT CreateAncillaryData (BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0;
+
+    virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0;
+    virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale) = 0;
+    virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0;
+    virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0;
+
+    /* Audio Output */
+
+    virtual HRESULT EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount, BMDAudioOutputStreamType streamType) = 0;
+    virtual HRESULT DisableAudioOutput (void) = 0;
+
+    virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT BeginAudioPreroll (void) = 0;
+    virtual HRESULT EndAudioPreroll (void) = 0;
+    virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, uint32_t sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0;
+    virtual HRESULT FlushBufferedAudioSamples (void) = 0;
+
+    virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0;
+
+    /* Output Control */
+
+    virtual HRESULT StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed) = 0;
+    virtual HRESULT StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, BMDTimeScale timeScale) = 0;
+    virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0;
+    virtual HRESULT GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0;
+
+protected:
+    virtual ~IDeckLinkOutput_v7_3 () {}; // call Release method to drop reference count
+};
+
+/* End Interface IDeckLinkOutput */
+
+
+/* Interface IDeckLinkInputCallback - Frame arrival callback. */
+
+class IDeckLinkInputCallback_v7_3 : public IUnknown
+{
+public:
+    virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode_v7_6 *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0;
+    virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame_v7_3 *videoFrame, /* in */ IDeckLinkAudioInputPacket *audioPacket) = 0;
+
+protected:
+    virtual ~IDeckLinkInputCallback_v7_3 () {}; // call Release method to drop reference count
+};
+
+/* End Interface IDeckLinkInputCallback */
+
+
+/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkInput_v7_3 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;
+
+    /* Video Input */
+
+    virtual HRESULT EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags) = 0;
+    virtual HRESULT DisableVideoInput (void) = 0;
+    virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0;
+
+    /* Audio Input */
+
+    virtual HRESULT EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0;
+    virtual HRESULT DisableAudioInput (void) = 0;
+    virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0;
+
+    /* Input Control */
+
+    virtual HRESULT StartStreams (void) = 0;
+    virtual HRESULT StopStreams (void) = 0;
+    virtual HRESULT PauseStreams (void) = 0;
+    virtual HRESULT FlushStreams (void) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v7_3 *theCallback) = 0;
+
+protected:
+    virtual ~IDeckLinkInput_v7_3 () {}; // call Release method to drop reference count
+};
+
+/* End Interface IDeckLinkInput */
+
+/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */
+
+class IDeckLinkVideoInputFrame_v7_3 : public IDeckLinkVideoFrame_v7_6
+{
+public:
+    virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoInputFrame_v7_3 () {}; // call Release method to drop reference count
+};
+
+/* End Interface IDeckLinkVideoInputFrame */
+
+#endif      // defined(__cplusplus)
+#endif      // __DeckLink_API_v7_3_h__
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_6.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_6.h
new file mode 100644
index 0000000..93d7c04
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_6.h
@@ -0,0 +1,421 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* DeckLinkAPI_v7_6.h */
+
+#ifndef __DeckLink_API_v7_6_h__
+#define __DeckLink_API_v7_6_h__
+
+#include "DeckLinkAPI.h"
+
+// Interface ID Declarations
+
+#define IID_IDeckLinkVideoOutputCallback_v7_6            /* E763A626-4A3C-49D1-BF13-E7AD3692AE52 */ (REFIID){0xE7,0x63,0xA6,0x26,0x4A,0x3C,0x49,0xD1,0xBF,0x13,0xE7,0xAD,0x36,0x92,0xAE,0x52}
+#define IID_IDeckLinkInputCallback_v7_6                  /* 31D28EE7-88B6-4CB1-897A-CDBF79A26414 */ (REFIID){0x31,0xD2,0x8E,0xE7,0x88,0xB6,0x4C,0xB1,0x89,0x7A,0xCD,0xBF,0x79,0xA2,0x64,0x14}
+#define IID_IDeckLinkDisplayModeIterator_v7_6            /* 455D741F-1779-4800-86F5-0B5D13D79751 */ (REFIID){0x45,0x5D,0x74,0x1F,0x17,0x79,0x48,0x00,0x86,0xF5,0x0B,0x5D,0x13,0xD7,0x97,0x51}
+#define IID_IDeckLinkDisplayMode_v7_6                    /* 87451E84-2B7E-439E-A629-4393EA4A8550 */ (REFIID){0x87,0x45,0x1E,0x84,0x2B,0x7E,0x43,0x9E,0xA6,0x29,0x43,0x93,0xEA,0x4A,0x85,0x50}
+#define IID_IDeckLinkOutput_v7_6                         /* 29228142-EB8C-4141-A621-F74026450955 */ (REFIID){0x29,0x22,0x81,0x42,0xEB,0x8C,0x41,0x41,0xA6,0x21,0xF7,0x40,0x26,0x45,0x09,0x55}
+#define IID_IDeckLinkInput_v7_6                          /* 300C135A-9F43-48E2-9906-6D7911D93CF1 */ (REFIID){0x30,0x0C,0x13,0x5A,0x9F,0x43,0x48,0xE2,0x99,0x06,0x6D,0x79,0x11,0xD9,0x3C,0xF1}
+#define IID_IDeckLinkTimecode_v7_6                       /* EFB9BCA6-A521-44F7-BD69-2332F24D9EE6 */ (REFIID){0xEF,0xB9,0xBC,0xA6,0xA5,0x21,0x44,0xF7,0xBD,0x69,0x23,0x32,0xF2,0x4D,0x9E,0xE6}
+#define IID_IDeckLinkVideoFrame_v7_6                     /* A8D8238E-6B18-4196-99E1-5AF717B83D32 */ (REFIID){0xA8,0xD8,0x23,0x8E,0x6B,0x18,0x41,0x96,0x99,0xE1,0x5A,0xF7,0x17,0xB8,0x3D,0x32}
+#define IID_IDeckLinkMutableVideoFrame_v7_6              /* 46FCEE00-B4E6-43D0-91C0-023A7FCEB34F */ (REFIID){0x46,0xFC,0xEE,0x00,0xB4,0xE6,0x43,0xD0,0x91,0xC0,0x02,0x3A,0x7F,0xCE,0xB3,0x4F}
+#define IID_IDeckLinkVideoInputFrame_v7_6                /* 9A74FA41-AE9F-47AC-8CF4-01F42DD59965 */ (REFIID){0x9A,0x74,0xFA,0x41,0xAE,0x9F,0x47,0xAC,0x8C,0xF4,0x01,0xF4,0x2D,0xD5,0x99,0x65}
+#define IID_IDeckLinkScreenPreviewCallback_v7_6          /* 373F499D-4B4D-4518-AD22-6354E5A5825E */ (REFIID){0x37,0x3F,0x49,0x9D,0x4B,0x4D,0x45,0x18,0xAD,0x22,0x63,0x54,0xE5,0xA5,0x82,0x5E}
+#define IID_IDeckLinkCocoaScreenPreviewCallback_v7_6     /* D174152F-8F96-4C07-83A5-DD5F5AF0A2AA */ (REFIID){0xD1,0x74,0x15,0x2F,0x8F,0x96,0x4C,0x07,0x83,0xA5,0xDD,0x5F,0x5A,0xF0,0xA2,0xAA}
+#define IID_IDeckLinkGLScreenPreviewHelper_v7_6          /* BA575CD9-A15E-497B-B2C2-F9AFE7BE4EBA */ (REFIID){0xBA,0x57,0x5C,0xD9,0xA1,0x5E,0x49,0x7B,0xB2,0xC2,0xF9,0xAF,0xE7,0xBE,0x4E,0xBA}
+#define IID_IDeckLinkVideoConversion_v7_6                /* 3EB504C9-F97D-40FE-A158-D407D48CB53B */ (REFIID){0x3E,0xB5,0x04,0xC9,0xF9,0x7D,0x40,0xFE,0xA1,0x58,0xD4,0x07,0xD4,0x8C,0xB5,0x3B}
+#define IID_IDeckLinkConfiguration_v7_6                  /* B8EAD569-B764-47F0-A73F-AE40DF6CBF10 */ (REFIID){0xB8,0xEA,0xD5,0x69,0xB7,0x64,0x47,0xF0,0xA7,0x3F,0xAE,0x40,0xDF,0x6C,0xBF,0x10}
+
+
+#if defined(__cplusplus)
+
+/* Enum BMDVideoConnection - Video connection types */
+
+typedef uint32_t BMDVideoConnection_v7_6;
+enum _BMDVideoConnection_v7_6 {
+    bmdVideoConnectionSDI_v7_6                              = 'sdi ',
+    bmdVideoConnectionHDMI_v7_6                             = 'hdmi',
+    bmdVideoConnectionOpticalSDI_v7_6                       = 'opti',
+    bmdVideoConnectionComponent_v7_6                        = 'cpnt',
+    bmdVideoConnectionComposite_v7_6                        = 'cmst',
+    bmdVideoConnectionSVideo_v7_6                           = 'svid'
+};
+
+
+// Forward Declarations
+
+class IDeckLinkVideoOutputCallback_v7_6;
+class IDeckLinkInputCallback_v7_6;
+class IDeckLinkDisplayModeIterator_v7_6;
+class IDeckLinkDisplayMode_v7_6;
+class IDeckLinkOutput_v7_6;
+class IDeckLinkInput_v7_6;
+class IDeckLinkTimecode_v7_6;
+class IDeckLinkVideoFrame_v7_6;
+class IDeckLinkMutableVideoFrame_v7_6;
+class IDeckLinkVideoInputFrame_v7_6;
+class IDeckLinkScreenPreviewCallback_v7_6;
+class IDeckLinkCocoaScreenPreviewCallback_v7_6;
+class IDeckLinkGLScreenPreviewHelper_v7_6;
+class IDeckLinkVideoConversion_v7_6;
+
+
+/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */
+
+class IDeckLinkVideoOutputCallback_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT ScheduledFrameCompleted (/* in */ IDeckLinkVideoFrame_v7_6 *completedFrame, /* in */ BMDOutputFrameCompletionResult result) = 0;
+    virtual HRESULT ScheduledPlaybackHasStopped (void) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoOutputCallback_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkInputCallback - Frame arrival callback. */
+
+class IDeckLinkInputCallback_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode_v7_6 *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0;
+    virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame_v7_6* videoFrame, /* in */ IDeckLinkAudioInputPacket* audioPacket) = 0;
+
+protected:
+    virtual ~IDeckLinkInputCallback_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */
+
+class IDeckLinkDisplayModeIterator_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT Next (/* out */ IDeckLinkDisplayMode_v7_6 **deckLinkDisplayMode) = 0;
+
+protected:
+    virtual ~IDeckLinkDisplayModeIterator_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkDisplayMode - represents a display mode */
+
+class IDeckLinkDisplayMode_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT GetName (/* out */ CFStringRef *name) = 0;
+    virtual BMDDisplayMode GetDisplayMode (void) = 0;
+    virtual long GetWidth (void) = 0;
+    virtual long GetHeight (void) = 0;
+    virtual HRESULT GetFrameRate (/* out */ BMDTimeValue *frameDuration, /* out */ BMDTimeScale *timeScale) = 0;
+    virtual BMDFieldDominance GetFieldDominance (void) = 0;
+
+protected:
+    virtual ~IDeckLinkDisplayMode_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkOutput_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback_v7_6 *previewCallback) = 0;
+
+    /* Video Output */
+
+    virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0;
+    virtual HRESULT DisableVideoOutput (void) = 0;
+
+    virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0;
+    virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame_v7_6 **outFrame) = 0;
+    virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0;
+
+    virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0;
+    virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0;
+    virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback_v7_6 *theCallback) = 0;
+    virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0;
+
+    /* Audio Output */
+
+    virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0;
+    virtual HRESULT DisableAudioOutput (void) = 0;
+
+    virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT BeginAudioPreroll (void) = 0;
+    virtual HRESULT EndAudioPreroll (void) = 0;
+    virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0;
+    virtual HRESULT FlushBufferedAudioSamples (void) = 0;
+
+    virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0;
+
+    /* Output Control */
+
+    virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0;
+    virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0;
+    virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0;
+    virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0;
+
+    /* Hardware Timing */
+
+    virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkOutput_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkInput_v7_6 - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkInput_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback_v7_6 *previewCallback) = 0;
+
+    /* Video Input */
+
+    virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0;
+    virtual HRESULT DisableVideoInput (void) = 0;
+    virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0;
+
+    /* Audio Input */
+
+    virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0;
+    virtual HRESULT DisableAudioInput (void) = 0;
+    virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0;
+
+    /* Input Control */
+
+    virtual HRESULT StartStreams (void) = 0;
+    virtual HRESULT StopStreams (void) = 0;
+    virtual HRESULT PauseStreams (void) = 0;
+    virtual HRESULT FlushStreams (void) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v7_6 *theCallback) = 0;
+
+    /* Hardware Timing */
+
+    virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkInput_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkTimecode - Used for video frame timecode representation. */
+
+class IDeckLinkTimecode_v7_6 : public IUnknown
+{
+public:
+    virtual BMDTimecodeBCD GetBCD (void) = 0;
+    virtual HRESULT GetComponents (/* out */ uint8_t *hours, /* out */ uint8_t *minutes, /* out */ uint8_t *seconds, /* out */ uint8_t *frames) = 0;
+    virtual HRESULT GetString (/* out */ CFStringRef *timecode) = 0;
+    virtual BMDTimecodeFlags GetFlags (void) = 0;
+
+protected:
+    virtual ~IDeckLinkTimecode_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */
+
+class IDeckLinkVideoFrame_v7_6 : public IUnknown
+{
+public:
+    virtual long GetWidth (void) = 0;
+    virtual long GetHeight (void) = 0;
+    virtual long GetRowBytes (void) = 0;
+    virtual BMDPixelFormat GetPixelFormat (void) = 0;
+    virtual BMDFrameFlags GetFlags (void) = 0;
+    virtual HRESULT GetBytes (/* out */ void **buffer) = 0;
+
+    virtual HRESULT GetTimecode (BMDTimecodeFormat format, /* out */ IDeckLinkTimecode_v7_6 **timecode) = 0;
+    virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary **ancillary) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoFrame_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */
+
+class IDeckLinkMutableVideoFrame_v7_6 : public IDeckLinkVideoFrame_v7_6
+{
+public:
+    virtual HRESULT SetFlags (BMDFrameFlags newFlags) = 0;
+
+    virtual HRESULT SetTimecode (BMDTimecodeFormat format, /* in */ IDeckLinkTimecode_v7_6 *timecode) = 0;
+    virtual HRESULT SetTimecodeFromComponents (BMDTimecodeFormat format, uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t frames, BMDTimecodeFlags flags) = 0;
+    virtual HRESULT SetAncillaryData (/* in */ IDeckLinkVideoFrameAncillary *ancillary) = 0;
+
+protected:
+    virtual ~IDeckLinkMutableVideoFrame_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */
+
+class IDeckLinkVideoInputFrame_v7_6 : public IDeckLinkVideoFrame_v7_6
+{
+public:
+    virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0;
+    virtual HRESULT GetHardwareReferenceTimestamp (BMDTimeScale timeScale, /* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoInputFrame_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */
+
+class IDeckLinkScreenPreviewCallback_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT DrawFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkScreenPreviewCallback_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkCocoaScreenPreviewCallback - Screen preview callback for Cocoa-based applications */
+
+class IDeckLinkCocoaScreenPreviewCallback_v7_6 : public IDeckLinkScreenPreviewCallback_v7_6
+{
+public:
+
+protected:
+    virtual ~IDeckLinkCocoaScreenPreviewCallback_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */
+
+class IDeckLinkGLScreenPreviewHelper_v7_6 : public IUnknown
+{
+public:
+
+    /* Methods must be called with OpenGL context set */
+
+    virtual HRESULT InitializeGL (void) = 0;
+    virtual HRESULT PaintGL (void) = 0;
+    virtual HRESULT SetFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkGLScreenPreviewHelper_v7_6 () {}; // call Release method to drop reference count
+};
+
+
+/* Interface IDeckLinkVideoConversion - Created with CoCreateInstance(). */
+
+class IDeckLinkVideoConversion_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT ConvertFrame (/* in */ IDeckLinkVideoFrame_v7_6* srcFrame, /* in */ IDeckLinkVideoFrame_v7_6* dstFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkVideoConversion_v7_6 () {}; // call Release method to drop reference count
+};
+
+/* Interface IDeckLinkConfiguration - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkConfiguration_v7_6 : public IUnknown
+{
+public:
+    virtual HRESULT GetConfigurationValidator (/* out */ IDeckLinkConfiguration_v7_6 **configObject) = 0;
+    virtual HRESULT WriteConfigurationToPreferences (void) = 0;
+
+    /* Video Output Configuration */
+
+    virtual HRESULT SetVideoOutputFormat (/* in */ BMDVideoConnection_v7_6 videoOutputConnection) = 0;
+    virtual HRESULT IsVideoOutputActive (/* in */ BMDVideoConnection_v7_6 videoOutputConnection, /* out */ bool *active) = 0;
+
+    virtual HRESULT SetAnalogVideoOutputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0;
+    virtual HRESULT GetAnalogVideoOutputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0;
+
+    virtual HRESULT EnableFieldFlickerRemovalWhenPaused (/* in */ bool enable) = 0;
+    virtual HRESULT IsEnabledFieldFlickerRemovalWhenPaused (/* out */ bool *enabled) = 0;
+
+    virtual HRESULT Set444And3GBpsVideoOutput (/* in */ bool enable444VideoOutput, /* in */ bool enable3GbsOutput) = 0;
+    virtual HRESULT Get444And3GBpsVideoOutput (/* out */ bool *is444VideoOutputEnabled, /* out */ bool *threeGbsOutputEnabled) = 0;
+
+    virtual HRESULT SetVideoOutputConversionMode (/* in */ BMDVideoOutputConversionMode conversionMode) = 0;
+    virtual HRESULT GetVideoOutputConversionMode (/* out */ BMDVideoOutputConversionMode *conversionMode) = 0;
+
+    virtual HRESULT Set_HD1080p24_to_HD1080i5994_Conversion (/* in */ bool enable) = 0;
+    virtual HRESULT Get_HD1080p24_to_HD1080i5994_Conversion (/* out */ bool *enabled) = 0;
+
+    /* Video Input Configuration */
+
+    virtual HRESULT SetVideoInputFormat (/* in */ BMDVideoConnection_v7_6 videoInputFormat) = 0;
+    virtual HRESULT GetVideoInputFormat (/* out */ BMDVideoConnection_v7_6 *videoInputFormat) = 0;
+
+    virtual HRESULT SetAnalogVideoInputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0;
+    virtual HRESULT GetAnalogVideoInputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0;
+
+    virtual HRESULT SetVideoInputConversionMode (/* in */ BMDVideoInputConversionMode conversionMode) = 0;
+    virtual HRESULT GetVideoInputConversionMode (/* out */ BMDVideoInputConversionMode *conversionMode) = 0;
+
+    virtual HRESULT SetBlackVideoOutputDuringCapture (/* in */ bool blackOutInCapture) = 0;
+    virtual HRESULT GetBlackVideoOutputDuringCapture (/* out */ bool *blackOutInCapture) = 0;
+
+    virtual HRESULT Set32PulldownSequenceInitialTimecodeFrame (/* in */ uint32_t aFrameTimecode) = 0;
+    virtual HRESULT Get32PulldownSequenceInitialTimecodeFrame (/* out */ uint32_t *aFrameTimecode) = 0;
+
+    virtual HRESULT SetVancSourceLineMapping (/* in */ uint32_t activeLine1VANCsource, /* in */ uint32_t activeLine2VANCsource, /* in */ uint32_t activeLine3VANCsource) = 0;
+    virtual HRESULT GetVancSourceLineMapping (/* out */ uint32_t *activeLine1VANCsource, /* out */ uint32_t *activeLine2VANCsource, /* out */ uint32_t *activeLine3VANCsource) = 0;
+
+    /* Audio Input Configuration */
+
+    virtual HRESULT SetAudioInputFormat (/* in */ BMDAudioConnection audioInputFormat) = 0;
+    virtual HRESULT GetAudioInputFormat (/* out */ BMDAudioConnection *audioInputFormat) = 0;
+};
+
+
+
+/* Functions */
+
+extern "C" {
+
+	IDeckLinkIterator*							CreateDeckLinkIteratorInstance_v7_6 (void);
+	IDeckLinkGLScreenPreviewHelper_v7_6*		CreateOpenGLScreenPreviewHelper_v7_6 (void);
+    IDeckLinkCocoaScreenPreviewCallback_v7_6*	CreateCocoaScreenPreview_v7_6 (void* /* (NSView*) */ parentView);
+    IDeckLinkVideoConversion_v7_6*				CreateVideoConversionInstance_v7_6 (void);
+
+};
+
+
+#endif      // defined(__cplusplus)
+#endif      // __DeckLink_API_v7_6_h__
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_9.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_9.h
new file mode 100644
index 0000000..327a382
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_9.h
@@ -0,0 +1,91 @@
+/* -LICENSE-START-
+** Copyright (c) 2010 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* DeckLinkAPI_v7_9.h */
+
+#ifndef __DeckLink_API_v7_9_h__
+#define __DeckLink_API_v7_9_h__
+
+#include "DeckLinkAPI.h"
+
+// Interface ID Declarations
+
+#define IID_IDeckLinkDeckControl_v7_9                    /* A4D81043-0619-42B7-8ED6-602D29041DF7 */ (REFIID){0xA4,0xD8,0x10,0x43,0x06,0x19,0x42,0xB7,0x8E,0xD6,0x60,0x2D,0x29,0x04,0x1D,0xF7}
+
+
+#if defined(__cplusplus)
+
+// Forward Declarations
+
+class IDeckLinkDeckControl_v7_9;
+
+
+/* Interface IDeckLinkDeckControl_v7_9 - Deck Control main interface */
+
+class IDeckLinkDeckControl_v7_9 : public IUnknown
+{
+public:
+    virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Close (/* in */ bool standbyOn) = 0;
+    virtual HRESULT GetCurrentState (/* out */ BMDDeckControlMode *mode, /* out */ BMDDeckControlVTRControlState *vtrControlState, /* out */ BMDDeckControlStatusFlags *flags) = 0;
+    virtual HRESULT SetStandby (/* in */ bool standbyOn) = 0;
+    virtual HRESULT Play (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Stop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT TogglePlayStop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Eject (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GoToTimecode (/* in */ BMDTimecodeBCD timecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT FastForward (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Rewind (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StepForward (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StepBack (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Jog (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Shuttle (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecodeString (/* out */ BMDstring *currentTimeCode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecode (/* out */ IDeckLinkTimecode **currentTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecodeBCD (/* out */ BMDTimecodeBCD *currentTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT SetPreroll (/* in */ uint32_t prerollSeconds) = 0;
+    virtual HRESULT GetPreroll (/* out */ uint32_t *prerollSeconds) = 0;
+    virtual HRESULT SetExportOffset (/* in */ int32_t exportOffsetFields) = 0;
+    virtual HRESULT GetExportOffset (/* out */ int32_t *exportOffsetFields) = 0;
+    virtual HRESULT GetManualExportOffset (/* out */ int32_t *deckManualExportOffsetFields) = 0;
+    virtual HRESULT SetCaptureOffset (/* in */ int32_t captureOffsetFields) = 0;
+    virtual HRESULT GetCaptureOffset (/* out */ int32_t *captureOffsetFields) = 0;
+    virtual HRESULT StartExport (/* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* in */ BMDDeckControlExportModeOpsFlags exportModeOps, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StartCapture (/* in */ bool useVITC, /* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetDeviceID (/* out */ uint16_t *deviceId, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Abort (void) = 0;
+    virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback *callback) = 0;
+
+protected:
+    virtual ~IDeckLinkDeckControl_v7_9 () {}; // call Release method to drop reference count
+};
+
+
+#endif      // defined(__cplusplus)
+#endif      // __DeckLink_API_v7_9_h__
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_0.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_0.h
new file mode 100644
index 0000000..b4e8f21
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_0.h
@@ -0,0 +1,63 @@
+/* -LICENSE-START-
+** Copyright (c) 2011 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v8_0_H
+#define BMD_DECKLINKAPI_v8_0_H
+
+#include "DeckLinkAPI.h"
+
+// Interface ID Declarations
+
+#define IID_IDeckLink_v8_0                                    /* 62BFF75D-6569-4E55-8D4D-66AA03829ABC */ (REFIID){0x62,0xBF,0xF7,0x5D,0x65,0x69,0x4E,0x55,0x8D,0x4D,0x66,0xAA,0x03,0x82,0x9A,0xBC}
+#define IID_IDeckLinkIterator_v8_0                            /* 74E936FC-CC28-4A67-81A0-1E94E52D4E69 */ (REFIID){0x74,0xE9,0x36,0xFC,0xCC,0x28,0x4A,0x67,0x81,0xA0,0x1E,0x94,0xE5,0x2D,0x4E,0x69}
+
+#if defined (__cplusplus)
+
+/* Interface IDeckLink_v8_0 - represents a DeckLink device */
+
+class IDeckLink_v8_0 : public IUnknown
+{
+public:
+    virtual HRESULT GetModelName (/* out */ CFStringRef *modelName) = 0;
+};
+
+/* Interface IDeckLinkIterator_v8_0 - enumerates installed DeckLink hardware */
+
+class IDeckLinkIterator_v8_0 : public IUnknown
+{
+public:
+    virtual HRESULT Next (/* out */ IDeckLink_v8_0 **deckLinkInstance) = 0;
+};
+
+extern "C" {
+    IDeckLinkIterator_v8_0*                     CreateDeckLinkIteratorInstance_v8_0 (void);
+};
+
+
+#endif	// defined __cplusplus
+
+#endif /* defined(BMD_DECKLINKAPI_v8_0_H) */
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_1.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_1.h
new file mode 100644
index 0000000..e1444cd
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_1.h
@@ -0,0 +1,111 @@
+/* -LICENSE-START-
+ ** Copyright (c) 2011 Blackmagic Design
+ **
+ ** Permission is hereby granted, free of charge, to any person or organization
+ ** obtaining a copy of the software and accompanying documentation covered by
+ ** this license (the "Software") to use, reproduce, display, distribute,
+ ** execute, and transmit the Software, and to prepare derivative works of the
+ ** Software, and to permit third-parties to whom the Software is furnished to
+ ** do so, all subject to the following:
+ **
+ ** The copyright notices in the Software and this entire statement, including
+ ** the above license grant, this restriction and the following disclaimer,
+ ** must be included in all copies of the Software, in whole or in part, and
+ ** all derivative works of the Software, unless such copies or derivative
+ ** works are solely in the form of machine-executable object code generated by
+ ** a source language processor.
+ **
+ ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ ** DEALINGS IN THE SOFTWARE.
+ ** -LICENSE-END-
+ */
+
+#ifndef BMD_DECKLINKAPI_v8_1_H
+#define BMD_DECKLINKAPI_v8_1_H
+
+#include "DeckLinkAPI.h"
+
+
+// Interface ID Declarations
+
+#define IID_IDeckLinkDeckControlStatusCallback_v8_1           /* E5F693C1-4283-4716-B18F-C1431521955B */ (REFIID){0xE5,0xF6,0x93,0xC1,0x42,0x83,0x47,0x16,0xB1,0x8F,0xC1,0x43,0x15,0x21,0x95,0x5B}
+#define IID_IDeckLinkDeckControl_v8_1                         /* 522A9E39-0F3C-4742-94EE-D80DE335DA1D */ (REFIID){0x52,0x2A,0x9E,0x39,0x0F,0x3C,0x47,0x42,0x94,0xEE,0xD8,0x0D,0xE3,0x35,0xDA,0x1D}
+
+
+/* Enum BMDDeckControlVTRControlState_v8_1 - VTR Control state */
+
+typedef uint32_t BMDDeckControlVTRControlState_v8_1;
+enum _BMDDeckControlVTRControlState_v8_1 {
+    bmdDeckControlNotInVTRControlMode_v8_1                            = 'nvcm',
+    bmdDeckControlVTRControlPlaying_v8_1                              = 'vtrp',
+    bmdDeckControlVTRControlRecording_v8_1                            = 'vtrr',
+    bmdDeckControlVTRControlStill_v8_1                                = 'vtra',
+    bmdDeckControlVTRControlSeeking_v8_1                              = 'vtrs',
+    bmdDeckControlVTRControlStopped_v8_1                              = 'vtro'
+};
+
+
+/* Interface IDeckLinkDeckControlStatusCallback_v8_1 - Deck control state change callback. */
+
+class IDeckLinkDeckControlStatusCallback_v8_1 : public IUnknown
+{
+public:
+    virtual HRESULT TimecodeUpdate (/* in */ BMDTimecodeBCD currentTimecode) = 0;
+    virtual HRESULT VTRControlStateChanged (/* in */ BMDDeckControlVTRControlState_v8_1 newState, /* in */ BMDDeckControlError error) = 0;
+    virtual HRESULT DeckControlEventReceived (/* in */ BMDDeckControlEvent event, /* in */ BMDDeckControlError error) = 0;
+    virtual HRESULT DeckControlStatusChanged (/* in */ BMDDeckControlStatusFlags flags, /* in */ uint32_t mask) = 0;
+
+protected:
+    virtual ~IDeckLinkDeckControlStatusCallback_v8_1 () {}; // call Release method to drop reference count
+};
+
+/* Interface IDeckLinkDeckControl_v8_1 - Deck Control main interface */
+
+class IDeckLinkDeckControl_v8_1 : public IUnknown
+{
+public:
+    virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Close (/* in */ bool standbyOn) = 0;
+    virtual HRESULT GetCurrentState (/* out */ BMDDeckControlMode *mode, /* out */ BMDDeckControlVTRControlState_v8_1 *vtrControlState, /* out */ BMDDeckControlStatusFlags *flags) = 0;
+    virtual HRESULT SetStandby (/* in */ bool standbyOn) = 0;
+    virtual HRESULT SendCommand (/* in */ uint8_t *inBuffer, /* in */ uint32_t inBufferSize, /* out */ uint8_t *outBuffer, /* out */ uint32_t *outDataSize, /* in */ uint32_t outBufferSize, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Play (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Stop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT TogglePlayStop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Eject (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GoToTimecode (/* in */ BMDTimecodeBCD timecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT FastForward (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Rewind (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StepForward (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StepBack (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Jog (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Shuttle (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecodeString (/* out */ CFStringRef *currentTimeCode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecode (/* out */ IDeckLinkTimecode **currentTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetTimecodeBCD (/* out */ BMDTimecodeBCD *currentTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT SetPreroll (/* in */ uint32_t prerollSeconds) = 0;
+    virtual HRESULT GetPreroll (/* out */ uint32_t *prerollSeconds) = 0;
+    virtual HRESULT SetExportOffset (/* in */ int32_t exportOffsetFields) = 0;
+    virtual HRESULT GetExportOffset (/* out */ int32_t *exportOffsetFields) = 0;
+    virtual HRESULT GetManualExportOffset (/* out */ int32_t *deckManualExportOffsetFields) = 0;
+    virtual HRESULT SetCaptureOffset (/* in */ int32_t captureOffsetFields) = 0;
+    virtual HRESULT GetCaptureOffset (/* out */ int32_t *captureOffsetFields) = 0;
+    virtual HRESULT StartExport (/* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* in */ BMDDeckControlExportModeOpsFlags exportModeOps, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT StartCapture (/* in */ bool useVITC, /* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT GetDeviceID (/* out */ uint16_t *deviceId, /* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT Abort (void) = 0;
+    virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback_v8_1 *callback) = 0;
+
+protected:
+    virtual ~IDeckLinkDeckControl_v8_1 () {}; // call Release method to drop reference count
+};
+
+
+#endif	// BMD_DECKLINKAPI_v8_1_H
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_2.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_2.h
new file mode 100644
index 0000000..236d182
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_2.h
@@ -0,0 +1,81 @@
+/* -LICENSE-START-
+** Copyright (c) 2012 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v9_2_H
+#define BMD_DECKLINKAPI_v9_2_H
+
+#include "DeckLinkAPI.h"
+
+
+// Interface ID Declarations
+
+#define IID_IDeckLinkInput_v9_2                          /* 6D40EF78-28B9-4E21-990D-95BB7750A04F */ (REFIID){0x6D,0x40,0xEF,0x78,0x28,0xB9,0x4E,0x21,0x99,0x0D,0x95,0xBB,0x77,0x50,0xA0,0x4F}
+
+
+#if defined(__cplusplus)
+
+/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkInput_v9_2 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;
+
+    /* Video Input */
+
+    virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0;
+    virtual HRESULT DisableVideoInput (void) = 0;
+    virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0;
+
+    /* Audio Input */
+
+    virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0;
+    virtual HRESULT DisableAudioInput (void) = 0;
+    virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0;
+
+    /* Input Control */
+
+    virtual HRESULT StartStreams (void) = 0;
+    virtual HRESULT StopStreams (void) = 0;
+    virtual HRESULT PauseStreams (void) = 0;
+    virtual HRESULT FlushStreams (void) = 0;
+    virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback *theCallback) = 0;
+
+    /* Hardware Timing */
+
+    virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkInput_v9_2 () {}; // call Release method to drop reference count
+};
+
+
+#endif      // defined(__cplusplus)
+#endif	// BMD_DECKLINKAPI_v9_2_H
diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_9.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_9.h
new file mode 100644
index 0000000..3fa3a50
--- /dev/null
+++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_9.h
@@ -0,0 +1,101 @@
+/* -LICENSE-START-
+** Copyright (c) 2013 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+#ifndef BMD_DECKLINKAPI_v9_9_H
+#define BMD_DECKLINKAPI_v9_9_H
+
+#include "DeckLinkAPI.h"
+
+// Interface ID Declarations
+
+BMD_CONST REFIID IID_IDeckLinkOutput_v9_9                              = /* A3EF0963-0862-44ED-92A9-EE89ABF431C7 */ {0xA3,0xEF,0x09,0x63,0x08,0x62,0x44,0xED,0x92,0xA9,0xEE,0x89,0xAB,0xF4,0x31,0xC7};
+
+
+#if defined(__cplusplus)
+
+// Forward Declarations
+class IDeckLinkOutput_v9_9;
+
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */
+
+class IDeckLinkOutput_v9_9 : public IUnknown
+{
+public:
+    virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoOutputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0;
+    virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0;
+
+    virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0;
+
+    /* Video Output */
+
+    virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0;
+    virtual HRESULT DisableVideoOutput (void) = 0;
+
+    virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0;
+    virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame **outFrame) = 0;
+    virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0;
+
+    virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame *theFrame) = 0;
+    virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0;
+    virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0;
+    virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0;
+
+    /* Audio Output */
+
+    virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0;
+    virtual HRESULT DisableAudioOutput (void) = 0;
+
+    virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT BeginAudioPreroll (void) = 0;
+    virtual HRESULT EndAudioPreroll (void) = 0;
+    virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0;
+
+    virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0;
+    virtual HRESULT FlushBufferedAudioSamples (void) = 0;
+
+    virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0;
+
+    /* Output Control */
+
+    virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0;
+    virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0;
+    virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0;
+    virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0;
+    virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus *referenceStatus) = 0;
+
+    /* Hardware Timing */
+
+    virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0;
+
+protected:
+    virtual ~IDeckLinkOutput_v9_9 () {}; // call Release method to drop reference count
+};
+
+#endif      // defined(__cplusplus)
+#endif /* defined(BMD_DECKLINKAPI_v9_9_H) */
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI.idl
index 706f4c9..786d68d 100644
--- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI.idl
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI.idl
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -55,13 +55,13 @@ library DeckLinkAPI
 
 // Enumeration Mapping
 
-cpp_quote("typedef unsigned long BMDFrameFlags;")
-cpp_quote("typedef unsigned long BMDVideoInputFlags;")
-cpp_quote("typedef unsigned long BMDVideoInputFormatChangedEvents;")
-cpp_quote("typedef unsigned long BMDDetectedVideoInputFormatFlags;")
-cpp_quote("typedef unsigned long BMDDeckLinkCapturePassthroughMode;")
-cpp_quote("typedef unsigned long BMDAnalogVideoFlags;")
-cpp_quote("typedef unsigned long BMDDeviceBusyState;")
+cpp_quote("typedef unsigned int BMDFrameFlags;")
+cpp_quote("typedef unsigned int BMDVideoInputFlags;")
+cpp_quote("typedef unsigned int BMDVideoInputFormatChangedEvents;")
+cpp_quote("typedef unsigned int BMDDetectedVideoInputFormatFlags;")
+cpp_quote("typedef unsigned int BMDDeckLinkCapturePassthroughMode;")
+cpp_quote("typedef unsigned int BMDAnalogVideoFlags;")
+cpp_quote("typedef unsigned int BMDDeviceBusyState;")
 cpp_quote("#if 0")
 typedef enum _BMDFrameFlags BMDFrameFlags;
 typedef enum _BMDVideoInputFlags BMDVideoInputFlags;
@@ -82,11 +82,19 @@ typedef [v1_enum] enum	_BMDVideoOutputFlags {
     bmdVideoOutputDualStream3D                                   = 1 << 4
 } BMDVideoOutputFlags;
 
+/* Enum BMDPacketType - Type of packet */
+
+typedef [v1_enum] enum	_BMDPacketType {
+    bmdPacketTypeStreamInterruptedMarker                         = /* 'sint' */ 0x73696E74,	// A packet of this type marks the time when a video stream was interrupted, for example by a disconnected cable
+    bmdPacketTypeStreamData                                      = /* 'sdat' */ 0x73646174	// Regular stream data
+} BMDPacketType;
+
 /* Enum BMDFrameFlags - Frame flags */
 
 [v1_enum] enum	_BMDFrameFlags {
     bmdFrameFlagDefault                                          = 0,
     bmdFrameFlagFlipVertical                                     = 1 << 0,
+    bmdFrameContainsHDRMetadata                                  = 1 << 1,
 
     /* Flags that are applicable only to instances of IDeckLinkVideoInputFrame */
 
@@ -120,6 +128,7 @@ typedef [v1_enum] enum	_BMDVideoOutputFlags {
 /* Enum BMDDeckLinkCapturePassthroughMode - Enumerates whether the video output is electrically connected to the video input or if the clean switching mode is enabled */
 
 [v1_enum] enum	_BMDDeckLinkCapturePassthroughMode {
+    bmdDeckLinkCapturePassthroughModeDisabled                    = /* 'pdis' */ 0x70646973,
     bmdDeckLinkCapturePassthroughModeDirect                      = /* 'pdir' */ 0x70646972,
     bmdDeckLinkCapturePassthroughModeCleanSwitch                 = /* 'pcln' */ 0x70636C6E
 };
@@ -140,6 +149,12 @@ typedef [v1_enum] enum	_BMDReferenceStatus {
     bmdReferenceLocked                                           = 1 << 1
 } BMDReferenceStatus;
 
+/* Enum BMDAudioFormat - Audio Format */
+
+typedef [v1_enum] enum	_BMDAudioFormat {
+    bmdAudioFormatPCM                                            = /* 'lpcm' */ 0x6C70636D	// Linear signed PCM samples
+} BMDAudioFormat;
+
 /* Enum BMDAudioSampleRate - Audio sample rates supported for output/input */
 
 typedef [v1_enum] enum	_BMDAudioSampleRate {
@@ -241,10 +256,67 @@ typedef [v1_enum] enum	_BMDVideo3DPackingFormat {
 
 typedef [v1_enum] enum	_BMDIdleVideoOutputOperation {
     bmdIdleVideoOutputBlack                                      = /* 'blac' */ 0x626C6163,
-    bmdIdleVideoOutputLastFrame                                  = /* 'lafa' */ 0x6C616661,
-    bmdIdleVideoOutputDesktop                                    = /* 'desk' */ 0x6465736B
+    bmdIdleVideoOutputLastFrame                                  = /* 'lafa' */ 0x6C616661
 } BMDIdleVideoOutputOperation;
 
+/* Enum BMDVideoEncoderFrameCodingMode - Video frame coding mode */
+
+typedef [v1_enum] enum	_BMDVideoEncoderFrameCodingMode {
+    bmdVideoEncoderFrameCodingModeInter                          = /* 'inte' */ 0x696E7465,
+    bmdVideoEncoderFrameCodingModeIntra                          = /* 'intr' */ 0x696E7472
+} BMDVideoEncoderFrameCodingMode;
+
+/* Enum BMDDNxHRLevel - DNxHR Levels */
+
+typedef [v1_enum] enum	_BMDDNxHRLevel {
+    bmdDNxHRLevelSQ                                              = /* 'dnsq' */ 0x646E7371,
+    bmdDNxHRLevelLB                                              = /* 'dnlb' */ 0x646E6C62,
+    bmdDNxHRLevelHQ                                              = /* 'dnhq' */ 0x646E6871,
+    bmdDNxHRLevelHQX                                             = /* 'dhqx' */ 0x64687178,
+    bmdDNxHRLevel444                                             = /* 'd444' */ 0x64343434
+} BMDDNxHRLevel;
+
+/* Enum BMDLinkConfiguration - Video link configuration */
+
+typedef [v1_enum] enum	_BMDLinkConfiguration {
+    bmdLinkConfigurationSingleLink                               = /* 'lcsl' */ 0x6C63736C,
+    bmdLinkConfigurationDualLink                                 = /* 'lcdl' */ 0x6C63646C,
+    bmdLinkConfigurationQuadLink                                 = /* 'lcql' */ 0x6C63716C
+} BMDLinkConfiguration;
+
+/* Enum BMDDeviceInterface - Device interface type */
+
+typedef [v1_enum] enum	_BMDDeviceInterface {
+    bmdDeviceInterfacePCI                                        = /* 'pci ' */ 0x70636920,
+    bmdDeviceInterfaceUSB                                        = /* 'usb ' */ 0x75736220,
+    bmdDeviceInterfaceThunderbolt                                = /* 'thun' */ 0x7468756E
+} BMDDeviceInterface;
+
+/* Enum BMDDeckLinkFrameMetadataID - DeckLink Frame Metadata ID */
+
+typedef [v1_enum] enum	_BMDDeckLinkFrameMetadataID {
+    bmdDeckLinkFrameMetadataHDRElectroOpticalTransferFunc        = /* 'eotf' */ 0x656F7466,	// EOTF in range 0-7 as per CEA 861.3
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedX              = /* 'hdrx' */ 0x68647278,	// Red display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedY              = /* 'hdry' */ 0x68647279,	// Red display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenX            = /* 'hdgx' */ 0x68646778,	// Green display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenY            = /* 'hdgy' */ 0x68646779,	// Green display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueX             = /* 'hdbx' */ 0x68646278,	// Blue display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueY             = /* 'hdby' */ 0x68646279,	// Blue display primaries in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRWhitePointX                       = /* 'hdwx' */ 0x68647778,	// White point in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRWhitePointY                       = /* 'hdwy' */ 0x68647779,	// White point in range 0.0 - 1.0
+    bmdDeckLinkFrameMetadataHDRMaxDisplayMasteringLuminance      = /* 'hdml' */ 0x68646D6C,	// Max display mastering luminance in range 1 cd/m2 - 65535 cd/m2
+    bmdDeckLinkFrameMetadataHDRMinDisplayMasteringLuminance      = /* 'hmil' */ 0x686D696C,	// Min display mastering luminance in range 0.0001 cd/m2 - 6.5535 cd/m2
+    bmdDeckLinkFrameMetadataHDRMaximumContentLightLevel          = /* 'mcll' */ 0x6D636C6C,	// Maximum Content Light Level in range 1 cd/m2 - 65535 cd/m2
+    bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel     = /* 'fall' */ 0x66616C6C	// Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2
+} BMDDeckLinkFrameMetadataID;
+
+/* Enum BMDDuplexMode - Duplex for configurable ports */
+
+typedef [v1_enum] enum	_BMDDuplexMode {
+    bmdDuplexModeFull                                            = /* 'fdup' */ 0x66647570,
+    bmdDuplexModeHalf                                            = /* 'hdup' */ 0x68647570
+} BMDDuplexMode;
+
 /* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */
 
 typedef [v1_enum] enum	_BMDDeckLinkAttributeID {
@@ -261,10 +333,16 @@ typedef [v1_enum] enum	_BMDDeckLinkAttributeID {
     BMDDeckLinkCanOnlyAdjustOverallVideoOutputGain               = /* 'ovog' */ 0x6F766F67,
     BMDDeckLinkHasVideoInputAntiAliasingFilter                   = /* 'aafl' */ 0x6161666C,
     BMDDeckLinkHasBypass                                         = /* 'byps' */ 0x62797073,
-    BMDDeckLinkSupportsDesktopDisplay                            = /* 'extd' */ 0x65787464,
     BMDDeckLinkSupportsClockTimingAdjustment                     = /* 'ctad' */ 0x63746164,
     BMDDeckLinkSupportsFullDuplex                                = /* 'fdup' */ 0x66647570,
     BMDDeckLinkSupportsFullFrameReferenceInputTimingOffset       = /* 'frin' */ 0x6672696E,
+    BMDDeckLinkSupportsSMPTELevelAOutput                         = /* 'lvla' */ 0x6C766C61,
+    BMDDeckLinkSupportsDualLinkSDI                               = /* 'sdls' */ 0x73646C73,
+    BMDDeckLinkSupportsQuadLinkSDI                               = /* 'sqls' */ 0x73716C73,
+    BMDDeckLinkSupportsIdleOutput                                = /* 'idou' */ 0x69646F75,
+    BMDDeckLinkHasLTCTimecodeInput                               = /* 'hltc' */ 0x686C7463,
+    BMDDeckLinkSupportsDuplexModeConfiguration                   = /* 'dupx' */ 0x64757078,
+    BMDDeckLinkSupportsHDRMetadata                               = /* 'hdrm' */ 0x6864726D,
 
     /* Integers */
 
@@ -273,13 +351,20 @@ typedef [v1_enum] enum	_BMDDeckLinkAttributeID {
     BMDDeckLinkNumberOfSubDevices                                = /* 'nsbd' */ 0x6E736264,
     BMDDeckLinkSubDeviceIndex                                    = /* 'subi' */ 0x73756269,
     BMDDeckLinkPersistentID                                      = /* 'peid' */ 0x70656964,
+    BMDDeckLinkDeviceGroupID                                     = /* 'dgid' */ 0x64676964,
     BMDDeckLinkTopologicalID                                     = /* 'toid' */ 0x746F6964,
     BMDDeckLinkVideoOutputConnections                            = /* 'vocn' */ 0x766F636E,
     BMDDeckLinkVideoInputConnections                             = /* 'vicn' */ 0x7669636E,
     BMDDeckLinkAudioOutputConnections                            = /* 'aocn' */ 0x616F636E,
     BMDDeckLinkAudioInputConnections                             = /* 'aicn' */ 0x6169636E,
-    BMDDeckLinkDeviceBusyState                                   = /* 'dbst' */ 0x64627374,
     BMDDeckLinkVideoIOSupport                                    = /* 'vios' */ 0x76696F73,	// Returns a BMDVideoIOSupport bit field
+    BMDDeckLinkDeckControlConnections                            = /* 'dccn' */ 0x6463636E,
+    BMDDeckLinkDeviceInterface                                   = /* 'dbus' */ 0x64627573,	// Returns a BMDDeviceInterface
+    BMDDeckLinkAudioInputRCAChannelCount                         = /* 'airc' */ 0x61697263,
+    BMDDeckLinkAudioInputXLRChannelCount                         = /* 'aixc' */ 0x61697863,
+    BMDDeckLinkAudioOutputRCAChannelCount                        = /* 'aorc' */ 0x616F7263,
+    BMDDeckLinkAudioOutputXLRChannelCount                        = /* 'aoxc' */ 0x616F7863,
+    BMDDeckLinkPairedDevicePersistentID                          = /* 'ppid' */ 0x70706964,
 
     /* Floats */
 
@@ -287,10 +372,16 @@ typedef [v1_enum] enum	_BMDDeckLinkAttributeID {
     BMDDeckLinkVideoInputGainMaximum                             = /* 'vigx' */ 0x76696778,
     BMDDeckLinkVideoOutputGainMinimum                            = /* 'vogm' */ 0x766F676D,
     BMDDeckLinkVideoOutputGainMaximum                            = /* 'vogx' */ 0x766F6778,
+    BMDDeckLinkMicrophoneInputGainMinimum                        = /* 'migm' */ 0x6D69676D,
+    BMDDeckLinkMicrophoneInputGainMaximum                        = /* 'migx' */ 0x6D696778,
 
     /* Strings */
 
-    BMDDeckLinkSerialPortDeviceName                              = /* 'slpn' */ 0x736C706E
+    BMDDeckLinkSerialPortDeviceName                              = /* 'slpn' */ 0x736C706E,
+    BMDDeckLinkVendorName                                        = /* 'vndr' */ 0x766E6472,
+    BMDDeckLinkDisplayName                                       = /* 'dspn' */ 0x6473706E,
+    BMDDeckLinkModelName                                         = /* 'mdln' */ 0x6D646C6E,
+    BMDDeckLinkDeviceHandle                                      = /* 'devh' */ 0x64657668
 } BMDDeckLinkAttributeID;
 
 /* Enum BMDDeckLinkAPIInformationID - DeckLinkAPI information ID */
@@ -299,6 +390,49 @@ typedef [v1_enum] enum	_BMDDeckLinkAPIInformationID {
     BMDDeckLinkAPIVersion                                        = /* 'vers' */ 0x76657273
 } BMDDeckLinkAPIInformationID;
 
+/* Enum BMDDeckLinkStatusID - DeckLink Status ID */
+
+typedef [v1_enum] enum	_BMDDeckLinkStatusID {
+
+    /* Integers */
+
+    bmdDeckLinkStatusDetectedVideoInputMode                      = /* 'dvim' */ 0x6476696D,
+    bmdDeckLinkStatusDetectedVideoInputFlags                     = /* 'dvif' */ 0x64766966,
+    bmdDeckLinkStatusCurrentVideoInputMode                       = /* 'cvim' */ 0x6376696D,
+    bmdDeckLinkStatusCurrentVideoInputPixelFormat                = /* 'cvip' */ 0x63766970,
+    bmdDeckLinkStatusCurrentVideoInputFlags                      = /* 'cvif' */ 0x63766966,
+    bmdDeckLinkStatusCurrentVideoOutputMode                      = /* 'cvom' */ 0x63766F6D,
+    bmdDeckLinkStatusCurrentVideoOutputFlags                     = /* 'cvof' */ 0x63766F66,
+    bmdDeckLinkStatusPCIExpressLinkWidth                         = /* 'pwid' */ 0x70776964,
+    bmdDeckLinkStatusPCIExpressLinkSpeed                         = /* 'plnk' */ 0x706C6E6B,
+    bmdDeckLinkStatusLastVideoOutputPixelFormat                  = /* 'opix' */ 0x6F706978,
+    bmdDeckLinkStatusReferenceSignalMode                         = /* 'refm' */ 0x7265666D,
+    bmdDeckLinkStatusReferenceSignalFlags                        = /* 'reff' */ 0x72656666,
+    bmdDeckLinkStatusDuplexMode                                  = /* 'dupx' */ 0x64757078,
+    bmdDeckLinkStatusBusy                                        = /* 'busy' */ 0x62757379,
+
+    /* Flags */
+
+    bmdDeckLinkStatusVideoInputSignalLocked                      = /* 'visl' */ 0x7669736C,
+    bmdDeckLinkStatusReferenceSignalLocked                       = /* 'refl' */ 0x7265666C
+} BMDDeckLinkStatusID;
+
+/* Enum BMDDeckLinkVideoStatusFlags -  */
+
+typedef [v1_enum] enum	_BMDDeckLinkVideoStatusFlags {
+    bmdDeckLinkVideoStatusPsF                                    = 1 << 0,
+    bmdDeckLinkVideoStatusDualStream3D                           = 1 << 1
+} BMDDeckLinkVideoStatusFlags;
+
+/* Enum BMDDuplexStatus - Duplex status of the device */
+
+typedef [v1_enum] enum	_BMDDuplexStatus {
+    bmdDuplexStatusFullDuplex                                    = /* 'fdup' */ 0x66647570,
+    bmdDuplexStatusHalfDuplex                                    = /* 'hdup' */ 0x68647570,
+    bmdDuplexStatusSimplex                                       = /* 'splx' */ 0x73706C78,
+    bmdDuplexStatusInactive                                      = /* 'inac' */ 0x696E6163
+} BMDDuplexStatus;
+
 /* Enum BMDDeviceBusyState - Current device busy state */
 
 [v1_enum] enum	_BMDDeviceBusyState {
@@ -327,24 +461,32 @@ typedef [v1_enum] enum	_BMD3DPreviewFormat {
 /* Enum BMDNotifications - Events that can be subscribed through IDeckLinkNotification */
 
 typedef [v1_enum] enum	_BMDNotifications {
-    bmdPreferencesChanged                                        = /* 'pref' */ 0x70726566
+    bmdPreferencesChanged                                        = /* 'pref' */ 0x70726566,
+    bmdStatusChanged                                             = /* 'stat' */ 0x73746174
 } BMDNotifications;
 
 // Forward Declarations
 
 interface IDeckLinkVideoOutputCallback;
 interface IDeckLinkInputCallback;
+interface IDeckLinkEncoderInputCallback;
 interface IDeckLinkMemoryAllocator;
 interface IDeckLinkAudioOutputCallback;
 interface IDeckLinkIterator;
 interface IDeckLinkAPIInformation;
 interface IDeckLinkOutput;
 interface IDeckLinkInput;
+interface IDeckLinkEncoderInput;
 interface IDeckLinkVideoFrame;
 interface IDeckLinkMutableVideoFrame;
 interface IDeckLinkVideoFrame3DExtensions;
+interface IDeckLinkVideoFrameMetadataExtensions;
 interface IDeckLinkVideoInputFrame;
 interface IDeckLinkVideoFrameAncillary;
+interface IDeckLinkEncoderPacket;
+interface IDeckLinkEncoderVideoPacket;
+interface IDeckLinkEncoderAudioPacket;
+interface IDeckLinkH265NALPacket;
 interface IDeckLinkAudioInputPacket;
 interface IDeckLinkScreenPreviewCallback;
 interface IDeckLinkGLScreenPreviewHelper;
@@ -352,6 +494,7 @@ interface IDeckLinkDX9ScreenPreviewHelper;
 interface IDeckLinkNotificationCallback;
 interface IDeckLinkNotification;
 interface IDeckLinkAttributes;
+interface IDeckLinkStatus;
 interface IDeckLinkKeyer;
 interface IDeckLinkVideoConversion;
 interface IDeckLinkDeviceNotificationCallback;
@@ -381,6 +524,19 @@ interface IDeckLinkDiscovery;
     HRESULT VideoInputFrameArrived([in] IDeckLinkVideoInputFrame* videoFrame, [in] IDeckLinkAudioInputPacket* audioPacket);
 };
 
+/* Interface IDeckLinkEncoderInputCallback - Frame arrival callback. */
+
+[
+    object,
+    uuid(ACF13E61-F4A0-4974-A6A7-59AFF6268B31),
+    helpstring("Frame arrival callback.")
+] interface IDeckLinkEncoderInputCallback : IUnknown
+{
+    HRESULT VideoInputSignalChanged([in] BMDVideoInputFormatChangedEvents notificationEvents, [in] IDeckLinkDisplayMode *newDisplayMode, [in] BMDDetectedVideoInputFormatFlags detectedSignalFlags);
+    HRESULT VideoPacketArrived([in] IDeckLinkEncoderVideoPacket* videoPacket);
+    HRESULT AudioPacketArrived([in] IDeckLinkEncoderAudioPacket* audioPacket);
+};
+
 /* Interface IDeckLinkMemoryAllocator - Memory allocator for video frames. */
 
 [
@@ -390,7 +546,7 @@ interface IDeckLinkDiscovery;
     helpstring("Memory allocator for video frames.")
 ] interface IDeckLinkMemoryAllocator : IUnknown
 {
-    HRESULT AllocateBuffer([in] unsigned long bufferSize, [out] void **allocatedBuffer);
+    HRESULT AllocateBuffer([in] unsigned int bufferSize, [out] void **allocatedBuffer);
     HRESULT ReleaseBuffer([in] void *buffer);
 
     HRESULT Commit(void);
@@ -454,26 +610,26 @@ interface IDeckLinkDiscovery;
     HRESULT DisableVideoOutput(void);
 
     HRESULT SetVideoOutputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator);
-    HRESULT CreateVideoFrame([in] long width, [in] long height, [in] long rowBytes, [in] BMDPixelFormat pixelFormat, [in] BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame **outFrame);
+    HRESULT CreateVideoFrame([in] int width, [in] int height, [in] int rowBytes, [in] BMDPixelFormat pixelFormat, [in] BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame **outFrame);
     HRESULT CreateAncillaryData([in] BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer);
 
     HRESULT DisplayVideoFrameSync([in] IDeckLinkVideoFrame *theFrame);
     HRESULT ScheduleVideoFrame([in] IDeckLinkVideoFrame *theFrame, [in] BMDTimeValue displayTime, [in] BMDTimeValue displayDuration, [in] BMDTimeScale timeScale);
     HRESULT SetScheduledFrameCompletionCallback([in] IDeckLinkVideoOutputCallback *theCallback);
-    HRESULT GetBufferedVideoFrameCount([out] unsigned long *bufferedFrameCount);
+    HRESULT GetBufferedVideoFrameCount([out] unsigned int *bufferedFrameCount);
 
     /* Audio Output */
 
-    HRESULT EnableAudioOutput([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned long channelCount, [in] BMDAudioOutputStreamType streamType);
+    HRESULT EnableAudioOutput([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount, [in] BMDAudioOutputStreamType streamType);
     HRESULT DisableAudioOutput(void);
 
-    HRESULT WriteAudioSamplesSync([in] void *buffer, [in] unsigned long sampleFrameCount, [out] unsigned long *sampleFramesWritten);
+    HRESULT WriteAudioSamplesSync([in] void *buffer, [in] unsigned int sampleFrameCount, [out] unsigned int *sampleFramesWritten);
 
     HRESULT BeginAudioPreroll(void);
     HRESULT EndAudioPreroll(void);
-    HRESULT ScheduleAudioSamples([in] void *buffer, [in] unsigned long sampleFrameCount, [in] BMDTimeValue streamTime, [in] BMDTimeScale timeScale, [out] unsigned long *sampleFramesWritten);
+    HRESULT ScheduleAudioSamples([in] void *buffer, [in] unsigned int sampleFrameCount, [in] BMDTimeValue streamTime, [in] BMDTimeScale timeScale, [out] unsigned int *sampleFramesWritten);
 
-    HRESULT GetBufferedAudioSampleFrameCount([out] unsigned long *bufferedSampleFrameCount);
+    HRESULT GetBufferedAudioSampleFrameCount([out] unsigned int *bufferedSampleFrameCount);
     HRESULT FlushBufferedAudioSamples(void);
 
     HRESULT SetAudioCallback([in] IDeckLinkAudioOutputCallback *theCallback);
@@ -509,14 +665,14 @@ interface IDeckLinkDiscovery;
 
     HRESULT EnableVideoInput([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags);
     HRESULT DisableVideoInput(void);
-    HRESULT GetAvailableVideoFrameCount([out] unsigned long *availableFrameCount);
+    HRESULT GetAvailableVideoFrameCount([out] unsigned int *availableFrameCount);
     HRESULT SetVideoInputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator);
 
     /* Audio Input */
 
-    HRESULT EnableAudioInput([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned long channelCount);
+    HRESULT EnableAudioInput([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount);
     HRESULT DisableAudioInput(void);
-    HRESULT GetAvailableAudioSampleFrameCount([out] unsigned long *availableSampleFrameCount);
+    HRESULT GetAvailableAudioSampleFrameCount([out] unsigned int *availableSampleFrameCount);
 
     /* Input Control */
 
@@ -531,6 +687,43 @@ interface IDeckLinkDiscovery;
     HRESULT GetHardwareReferenceClock([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame);
 };
 
+/* Interface IDeckLinkEncoderInput - Created by QueryInterface from IDeckLink. */
+
+[
+    object,
+    uuid(270587DA-6B7D-42E7-A1F0-6D853F581185),
+    helpstring("Created by QueryInterface from IDeckLink.")
+] interface IDeckLinkEncoderInput : IUnknown
+{
+    HRESULT DoesSupportVideoMode([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags, [out] BMDDisplayModeSupport *result, [out] IDeckLinkDisplayMode **resultDisplayMode);
+    HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator);
+
+    /* Video Input */
+
+    HRESULT EnableVideoInput([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags);
+    HRESULT DisableVideoInput(void);
+    HRESULT GetAvailablePacketsCount([out] unsigned int *availablePacketsCount);
+    HRESULT SetMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator);
+
+    /* Audio Input */
+
+    HRESULT EnableAudioInput([in] BMDAudioFormat audioFormat, [in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount);
+    HRESULT DisableAudioInput(void);
+    HRESULT GetAvailableAudioSampleFrameCount([out] unsigned int *availableSampleFrameCount);
+
+    /* Input Control */
+
+    HRESULT StartStreams(void);
+    HRESULT StopStreams(void);
+    HRESULT PauseStreams(void);
+    HRESULT FlushStreams(void);
+    HRESULT SetCallback([in] IDeckLinkEncoderInputCallback *theCallback);
+
+    /* Hardware Timing */
+
+    HRESULT GetHardwareReferenceClock([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame);
+};
+
 /* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */
 
 [
@@ -581,6 +774,21 @@ interface IDeckLinkDiscovery;
     HRESULT GetFrameForRightEye([out] IDeckLinkVideoFrame* *rightEyeFrame);
 };
 
+/* Interface IDeckLinkVideoFrameMetadataExtensions - Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDMI HDR information */
+
+[
+    object,
+    uuid(D5973DC9-6432-46D0-8F0B-2496F8A1238F),
+    local,
+    helpstring("Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDMI HDR information")
+] interface IDeckLinkVideoFrameMetadataExtensions : IUnknown
+{
+    HRESULT GetInt([in] BMDDeckLinkFrameMetadataID metadataID, [out] LONGLONG *value);
+    HRESULT GetFloat([in] BMDDeckLinkFrameMetadataID metadataID, [out] double *value);
+    HRESULT GetFlag([in] BMDDeckLinkFrameMetadataID metadataID, [out] BOOL* value);
+    HRESULT GetString([in] BMDDeckLinkFrameMetadataID metadataID, [out] BSTR *value);
+};
+
 /* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */
 
 [
@@ -604,11 +812,67 @@ interface IDeckLinkDiscovery;
 ] interface IDeckLinkVideoFrameAncillary : IUnknown
 {
 
-    HRESULT GetBufferForVerticalBlankingLine([in] unsigned long lineNumber, [out] void **buffer);
+    HRESULT GetBufferForVerticalBlankingLine([in] unsigned int lineNumber, [out] void **buffer);
     BMDPixelFormat GetPixelFormat(void);
     BMDDisplayMode GetDisplayMode(void);
 };
 
+/* Interface IDeckLinkEncoderPacket - Interface to encapsulate an encoded packet. */
+
+[
+    object,
+    uuid(B693F36C-316E-4AF1-B6C2-F389A4BCA620),
+    local,
+    helpstring("Interface to encapsulate an encoded packet.")
+] interface IDeckLinkEncoderPacket : IUnknown
+{
+    HRESULT GetBytes([out] void **buffer);
+    long GetSize(void);
+    HRESULT GetStreamTime([out] BMDTimeValue *frameTime, [in] BMDTimeScale timeScale);
+    BMDPacketType GetPacketType(void);
+};
+
+/* Interface IDeckLinkEncoderVideoPacket - Provided by the IDeckLinkEncoderInput video packet arrival callback. */
+
+[
+    object,
+    uuid(4E7FD944-E8C7-4EAC-B8C0-7B77F80F5AE0),
+    local,
+    helpstring("Provided by the IDeckLinkEncoderInput video packet arrival callback.")
+] interface IDeckLinkEncoderVideoPacket : IDeckLinkEncoderPacket
+{
+    BMDPixelFormat GetPixelFormat(void);
+    HRESULT GetHardwareReferenceTimestamp([in] BMDTimeScale timeScale, [out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration);
+
+    HRESULT GetTimecode([in] BMDTimecodeFormat format, [out] IDeckLinkTimecode **timecode);
+};
+
+/* Interface IDeckLinkEncoderAudioPacket - Provided by the IDeckLinkEncoderInput audio packet arrival callback. */
+
+[
+    object,
+    uuid(49E8EDC8-693B-4E14-8EF6-12C658F5A07A),
+    local,
+    helpstring("Provided by the IDeckLinkEncoderInput audio packet arrival callback.")
+] interface IDeckLinkEncoderAudioPacket : IDeckLinkEncoderPacket
+{
+    BMDAudioFormat GetAudioFormat(void);
+};
+
+/* Interface IDeckLinkH265NALPacket - Obtained through QueryInterface() on an IDeckLinkEncoderVideoPacket object */
+
+[
+    object,
+    uuid(639C8E0B-68D5-4BDE-A6D4-95F3AEAFF2E7),
+    local,
+    helpstring("Obtained through QueryInterface() on an IDeckLinkEncoderVideoPacket object")
+] interface IDeckLinkH265NALPacket : IDeckLinkEncoderVideoPacket
+{
+    HRESULT GetUnitType([out] unsigned char *unitType);
+    HRESULT GetBytesNoPrefix([out] void **buffer);
+    long GetSizeNoPrefix(void);
+};
+
 /* Interface IDeckLinkAudioInputPacket - Provided by the IDeckLinkInput callback. */
 
 [
@@ -708,6 +972,22 @@ interface IDeckLinkDiscovery;
     HRESULT GetString([in] BMDDeckLinkAttributeID cfgID, [out] BSTR *value);
 };
 
+/* Interface IDeckLinkStatus - DeckLink Status interface */
+
+[
+    object,
+    uuid(5F558200-4028-49BC-BEAC-DB3FA4A96E46),
+    local,
+    helpstring("DeckLink Status interface")
+] interface IDeckLinkStatus : IUnknown
+{
+    HRESULT GetFlag([in] BMDDeckLinkStatusID statusID, [out] BOOL *value);
+    HRESULT GetInt([in] BMDDeckLinkStatusID statusID, [out] LONGLONG *value);
+    HRESULT GetFloat([in] BMDDeckLinkStatusID statusID, [out] double *value);
+    HRESULT GetString([in] BMDDeckLinkStatusID statusID, [out] BSTR *value);
+    HRESULT GetBytes([in] BMDDeckLinkStatusID statusID, [out] void *buffer, [in, out] unsigned int *bufferSize);
+};
+
 /* Interface IDeckLinkKeyer - DeckLink Keyer interface */
 
 [
@@ -719,8 +999,8 @@ interface IDeckLinkDiscovery;
 {
     HRESULT Enable([in] BOOL isExternal);
     HRESULT SetLevel([in] unsigned char level);
-    HRESULT RampUp([in] unsigned long numberOfFrames);
-    HRESULT RampDown([in] unsigned long numberOfFrames);
+    HRESULT RampUp([in] unsigned int numberOfFrames);
+    HRESULT RampDown([in] unsigned int numberOfFrames);
     HRESULT Disable(void);
 };
 
@@ -762,6 +1042,8 @@ interface IDeckLinkDiscovery;
 
 /* Coclasses */
 
+importlib("stdole2.tlb");
+
 [
     uuid(1F2E109A-8F4F-49E4-9203-135595CB6FA5),
     helpstring("CDeckLinkIterator Class")
@@ -810,4 +1092,18 @@ interface IDeckLinkDiscovery;
     [default] interface IDeckLinkDiscovery;
 };
 
+
+// import deprecated interfaces
+#include "DeckLinkAPI_v10_6.idl"
+#include "DeckLinkAPI_v10_5.idl"
+#include "DeckLinkAPI_v10_4.idl"
+#include "DeckLinkAPI_v10_2.idl"
+#include "DeckLinkAPI_v9_9.idl"
+#include "DeckLinkAPI_v9_2.idl"
+#include "DeckLinkAPI_v8_1.idl"
+#include "DeckLinkAPI_v8_0.idl"
+#include "DeckLinkAPI_v7_9.idl"
+#include "DeckLinkAPI_v7_6.idl"
+#include "DeckLinkAPI_v7_3.idl"
+#include "DeckLinkAPI_v7_1.idl"
 };
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIConfiguration.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPIConfiguration.idl
index 8d4adf7..4e271e4 100644
--- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIConfiguration.idl
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIConfiguration.idl
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -59,6 +59,7 @@ typedef [v1_enum] enum	_BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigHDMI3DPackingFormat                         = /* '3dpf' */ 0x33647066,
     bmdDeckLinkConfigBypass                                      = /* 'byps' */ 0x62797073,
     bmdDeckLinkConfigClockTimingAdjustment                       = /* 'ctad' */ 0x63746164,
+    bmdDeckLinkConfigDuplexMode                                  = /* 'dupx' */ 0x64757078,
 
     /* Audio Input/Output Flags */
 
@@ -69,9 +70,10 @@ typedef [v1_enum] enum	_BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigFieldFlickerRemoval                         = /* 'fdfr' */ 0x66646672,
     bmdDeckLinkConfigHD1080p24ToHD1080i5994Conversion            = /* 'to59' */ 0x746F3539,
     bmdDeckLinkConfig444SDIVideoOutput                           = /* '444o' */ 0x3434346F,
-    bmdDeckLinkConfigSingleLinkVideoOutput                       = /* 'sglo' */ 0x73676C6F,
     bmdDeckLinkConfigBlackVideoOutputDuringCapture               = /* 'bvoc' */ 0x62766F63,
     bmdDeckLinkConfigLowLatencyVideoOutput                       = /* 'llvo' */ 0x6C6C766F,
+    bmdDeckLinkConfigDownConversionOnAllAnalogOutput             = /* 'caao' */ 0x6361616F,
+    bmdDeckLinkConfigSMPTELevelAOutput                           = /* 'smta' */ 0x736D7461,
 
     /* Video Output Integers */
 
@@ -82,6 +84,7 @@ typedef [v1_enum] enum	_BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigVideoOutputIdleOperation                    = /* 'voio' */ 0x766F696F,
     bmdDeckLinkConfigDefaultVideoOutputMode                      = /* 'dvom' */ 0x64766F6D,
     bmdDeckLinkConfigDefaultVideoOutputModeFlags                 = /* 'dvof' */ 0x64766F66,
+    bmdDeckLinkConfigSDIOutputLinkConfiguration                  = /* 'solc' */ 0x736F6C63,
 
     /* Video Output Floats */
 
@@ -97,6 +100,7 @@ typedef [v1_enum] enum	_BMDDeckLinkConfigurationID {
 
     bmdDeckLinkConfigVideoInputScanning                          = /* 'visc' */ 0x76697363,	// Applicable to H264 Pro Recorder only
     bmdDeckLinkConfigUseDedicatedLTCInput                        = /* 'dltc' */ 0x646C7463,	// Use timecode from LTC input instead of SDI stream
+    bmdDeckLinkConfigSDIInput3DPayloadOverride                   = /* '3dds' */ 0x33646473,
 
     /* Video Input Integers */
 
@@ -119,6 +123,10 @@ typedef [v1_enum] enum	_BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigVideoInputSVideoLumaGain                    = /* 'islg' */ 0x69736C67,
     bmdDeckLinkConfigVideoInputSVideoChromaGain                  = /* 'iscg' */ 0x69736367,
 
+    /* Audio Input Flags */
+
+    bmdDeckLinkConfigMicrophonePhantomPower                      = /* 'mphp' */ 0x6D706870,
+
     /* Audio Input Integers */
 
     bmdDeckLinkConfigAudioInputConnection                        = /* 'aicn' */ 0x6169636E,
@@ -130,6 +138,7 @@ typedef [v1_enum] enum	_BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigAnalogAudioInputScaleChannel3               = /* 'ais3' */ 0x61697333,
     bmdDeckLinkConfigAnalogAudioInputScaleChannel4               = /* 'ais4' */ 0x61697334,
     bmdDeckLinkConfigDigitalAudioInputScale                      = /* 'dais' */ 0x64616973,
+    bmdDeckLinkConfigMicrophoneInputGain                         = /* 'micg' */ 0x6D696367,
 
     /* Audio Output Integers */
 
@@ -141,18 +150,60 @@ typedef [v1_enum] enum	_BMDDeckLinkConfigurationID {
     bmdDeckLinkConfigAnalogAudioOutputScaleChannel2              = /* 'aos2' */ 0x616F7332,
     bmdDeckLinkConfigAnalogAudioOutputScaleChannel3              = /* 'aos3' */ 0x616F7333,
     bmdDeckLinkConfigAnalogAudioOutputScaleChannel4              = /* 'aos4' */ 0x616F7334,
-    bmdDeckLinkConfigDigitalAudioOutputScale                     = /* 'daos' */ 0x64616F73
+    bmdDeckLinkConfigDigitalAudioOutputScale                     = /* 'daos' */ 0x64616F73,
+    bmdDeckLinkConfigHeadphoneVolume                             = /* 'hvol' */ 0x68766F6C,
+
+    /* Device Information Strings */
+
+    bmdDeckLinkConfigDeviceInformationLabel                      = /* 'dila' */ 0x64696C61,
+    bmdDeckLinkConfigDeviceInformationSerialNumber               = /* 'disn' */ 0x6469736E,
+    bmdDeckLinkConfigDeviceInformationCompany                    = /* 'dico' */ 0x6469636F,
+    bmdDeckLinkConfigDeviceInformationPhone                      = /* 'diph' */ 0x64697068,
+    bmdDeckLinkConfigDeviceInformationEmail                      = /* 'diem' */ 0x6469656D,
+    bmdDeckLinkConfigDeviceInformationDate                       = /* 'dida' */ 0x64696461,
+
+    /* Deck Control Integers */
+
+    bmdDeckLinkConfigDeckControlConnection                       = /* 'dcco' */ 0x6463636F
 } BMDDeckLinkConfigurationID;
 
+/* Enum BMDDeckLinkEncoderConfigurationID - DeckLink Encoder Configuration ID */
+
+typedef [v1_enum] enum	_BMDDeckLinkEncoderConfigurationID {
+
+    /* Video Encoder Integers */
+
+    bmdDeckLinkEncoderConfigPreferredBitDepth                    = /* 'epbr' */ 0x65706272,
+    bmdDeckLinkEncoderConfigFrameCodingMode                      = /* 'efcm' */ 0x6566636D,
+
+    /* HEVC/H.265 Encoder Integers */
+
+    bmdDeckLinkEncoderConfigH265TargetBitrate                    = /* 'htbr' */ 0x68746272,
+
+    /* DNxHR/DNxHD Compression ID */
+
+    bmdDeckLinkEncoderConfigDNxHRCompressionID                   = /* 'dcid' */ 0x64636964,
+
+    /* DNxHR/DNxHD Level */
+
+    bmdDeckLinkEncoderConfigDNxHRLevel                           = /* 'dlev' */ 0x646C6576,
+
+    /* Encoded Sample Decriptions */
+
+    bmdDeckLinkEncoderConfigMPEG4SampleDescription               = /* 'stsE' */ 0x73747345,	// Full MPEG4 sample description (aka SampleEntry of an 'stsd' atom-box). Useful for MediaFoundation, QuickTime, MKV and more
+    bmdDeckLinkEncoderConfigMPEG4CodecSpecificDesc               = /* 'esds' */ 0x65736473	// Sample description extensions only (atom stream, each with size and fourCC header). Useful for AVFoundation, VideoToolbox, MKV and more
+} BMDDeckLinkEncoderConfigurationID;
+
 // Forward Declarations
 
 interface IDeckLinkConfiguration;
+interface IDeckLinkEncoderConfiguration;
 
 /* Interface IDeckLinkConfiguration - DeckLink Configuration interface */
 
 [
     object,
-    uuid(1E69FCF6-4203-4936-8076-2A9F4CFD50CB),
+    uuid(CB71734A-FE37-4E8D-8E13-802133A1C3F2),
     local,
     helpstring("DeckLink Configuration interface")
 ] interface IDeckLinkConfiguration : IUnknown
@@ -168,4 +219,28 @@ interface IDeckLinkConfiguration;
     HRESULT WriteConfigurationToPreferences(void);
 };
 
+/* Interface IDeckLinkEncoderConfiguration - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */
+
+[
+    object,
+    uuid(138050E5-C60A-4552-BF3F-0F358049327E),
+    local,
+    helpstring("DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput")
+] interface IDeckLinkEncoderConfiguration : IUnknown
+{
+    HRESULT SetFlag([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] BOOL value);
+    HRESULT GetFlag([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] BOOL *value);
+    HRESULT SetInt([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] LONGLONG value);
+    HRESULT GetInt([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] LONGLONG *value);
+    HRESULT SetFloat([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] double value);
+    HRESULT GetFloat([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] double *value);
+    HRESULT SetString([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] BSTR value);
+    HRESULT GetString([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] BSTR *value);
+    HRESULT GetBytes([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] void *buffer /* optional */, [in, out] unsigned int *bufferSize);
+};
+
 /* Coclasses */
+
+importlib("stdole2.tlb");
+
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIDeckControl.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPIDeckControl.idl
index ea4c099..cba3f2e 100644
--- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIDeckControl.idl
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIDeckControl.idl
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -39,8 +39,8 @@
 
 // Enumeration Mapping
 
-cpp_quote("typedef unsigned long BMDDeckControlStatusFlags;")
-cpp_quote("typedef unsigned long BMDDeckControlExportModeOpsFlags;")
+cpp_quote("typedef unsigned int BMDDeckControlStatusFlags;")
+cpp_quote("typedef unsigned int BMDDeckControlExportModeOpsFlags;")
 cpp_quote("#if 0")
 typedef enum _BMDDeckControlStatusFlags BMDDeckControlStatusFlags;
 typedef enum _BMDDeckControlExportModeOpsFlags BMDDeckControlExportModeOpsFlags;
@@ -153,7 +153,7 @@ interface IDeckLinkDeckControl;
     HRESULT TimecodeUpdate([in] BMDTimecodeBCD currentTimecode);
     HRESULT VTRControlStateChanged([in] BMDDeckControlVTRControlState newState, [in] BMDDeckControlError error);
     HRESULT DeckControlEventReceived([in] BMDDeckControlEvent event, [in] BMDDeckControlError error);
-    HRESULT DeckControlStatusChanged([in] BMDDeckControlStatusFlags flags, [in] unsigned long mask);
+    HRESULT DeckControlStatusChanged([in] BMDDeckControlStatusFlags flags, [in] unsigned int mask);
 };
 
 /* Interface IDeckLinkDeckControl - Deck Control main interface */
@@ -168,7 +168,7 @@ interface IDeckLinkDeckControl;
     HRESULT Close([in] BOOL standbyOn);
     HRESULT GetCurrentState([out] BMDDeckControlMode *mode, [out] BMDDeckControlVTRControlState *vtrControlState, [out] BMDDeckControlStatusFlags *flags);
     HRESULT SetStandby([in] BOOL standbyOn);
-    HRESULT SendCommand([in] unsigned char *inBuffer, [in] unsigned long inBufferSize, [out] unsigned char *outBuffer, [out] unsigned long *outDataSize, [in] unsigned long outBufferSize, [out] BMDDeckControlError *error);
+    HRESULT SendCommand([in] unsigned char *inBuffer, [in] unsigned int inBufferSize, [out] unsigned char *outBuffer, [out] unsigned int *outDataSize, [in] unsigned int outBufferSize, [out] BMDDeckControlError *error);
     HRESULT Play([out] BMDDeckControlError *error);
     HRESULT Stop([out] BMDDeckControlError *error);
     HRESULT TogglePlayStop([out] BMDDeckControlError *error);
@@ -183,13 +183,13 @@ interface IDeckLinkDeckControl;
     HRESULT GetTimecodeString([out] BSTR *currentTimeCode, [out] BMDDeckControlError *error);
     HRESULT GetTimecode([out] IDeckLinkTimecode **currentTimecode, [out] BMDDeckControlError *error);
     HRESULT GetTimecodeBCD([out] BMDTimecodeBCD *currentTimecode, [out] BMDDeckControlError *error);
-    HRESULT SetPreroll([in] unsigned long prerollSeconds);
-    HRESULT GetPreroll([out] unsigned long *prerollSeconds);
-    HRESULT SetExportOffset([in] long exportOffsetFields);
-    HRESULT GetExportOffset([out] long *exportOffsetFields);
-    HRESULT GetManualExportOffset([out] long *deckManualExportOffsetFields);
-    HRESULT SetCaptureOffset([in] long captureOffsetFields);
-    HRESULT GetCaptureOffset([out] long *captureOffsetFields);
+    HRESULT SetPreroll([in] unsigned int prerollSeconds);
+    HRESULT GetPreroll([out] unsigned int *prerollSeconds);
+    HRESULT SetExportOffset([in] int exportOffsetFields);
+    HRESULT GetExportOffset([out] int *exportOffsetFields);
+    HRESULT GetManualExportOffset([out] int *deckManualExportOffsetFields);
+    HRESULT SetCaptureOffset([in] int captureOffsetFields);
+    HRESULT GetCaptureOffset([out] int *captureOffsetFields);
     HRESULT StartExport([in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [in] BMDDeckControlExportModeOpsFlags exportModeOps, [out] BMDDeckControlError *error);
     HRESULT StartCapture([in] BOOL useVITC, [in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [out] BMDDeckControlError *error);
     HRESULT GetDeviceID([out] unsigned short *deviceId, [out] BMDDeckControlError *error);
@@ -200,3 +200,7 @@ interface IDeckLinkDeckControl;
 };
 
 /* Coclasses */
+
+importlib("stdole2.tlb");
+
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIDiscovery.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPIDiscovery.idl
index ea626c2..8b9db8e 100644
--- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIDiscovery.idl
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIDiscovery.idl
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -59,3 +59,7 @@ interface IDeckLink;
 };
 
 /* Coclasses */
+
+importlib("stdole2.tlb");
+
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIModes.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPIModes.idl
index 2282cb3..e4f4c35 100644
--- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIModes.idl
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIModes.idl
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -39,7 +39,7 @@
 
 // Enumeration Mapping
 
-cpp_quote("typedef unsigned long BMDDisplayModeFlags;")
+cpp_quote("typedef unsigned int BMDDisplayModeFlags;")
 cpp_quote("#if 0")
 typedef enum _BMDDisplayModeFlags BMDDisplayModeFlags;
 cpp_quote("#endif")
@@ -131,7 +131,12 @@ typedef [v1_enum] enum	_BMDPixelFormat {
     bmdFormat12BitRGB                                            = /* 'R12B' */ 0x52313242,	// Big-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component
     bmdFormat12BitRGBLE                                          = /* 'R12L' */ 0x5231324C,	// Little-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component
     bmdFormat10BitRGBXLE                                         = /* 'R10l' */ 0x5231306C,	// Little-endian 10-bit RGB with SMPTE video levels (64-940)
-    bmdFormat10BitRGBX                                           = /* 'R10b' */ 0x52313062	// Big-endian 10-bit RGB with SMPTE video levels (64-940)
+    bmdFormat10BitRGBX                                           = /* 'R10b' */ 0x52313062,	// Big-endian 10-bit RGB with SMPTE video levels (64-940)
+    bmdFormatH265                                                = /* 'hev1' */ 0x68657631,	// High Efficiency Video Coding (HEVC/h.265)
+
+    /* AVID DNxHR */
+
+    bmdFormatDNxHR                                               = /* 'AVdh' */ 0x41566468
 } BMDPixelFormat;
 
 /* Enum BMDDisplayModeFlags - Flags to describe the characteristics of an IDeckLinkDisplayMode. */
@@ -176,3 +181,7 @@ interface IDeckLinkDisplayMode;
 };
 
 /* Coclasses */
+
+importlib("stdole2.tlb");
+
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIStreaming.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPIStreaming.idl
index e78afc1..b609e5d 100644
--- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIStreaming.idl
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIStreaming.idl
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -237,8 +237,8 @@ interface IBMDStreamingH264NALParser;
     helpstring("Represents a mutable encoded video mode.")
 ] interface IBMDStreamingMutableVideoEncodingMode : IBMDStreamingVideoEncodingMode
 {
-    HRESULT SetSourceRect([in] unsigned long posX, [in] unsigned long posY, [in] unsigned long width, [in] unsigned long height);
-    HRESULT SetDestSize([in] unsigned long width, [in] unsigned long height);
+    HRESULT SetSourceRect([in] unsigned int posX, [in] unsigned int posY, [in] unsigned int width, [in] unsigned int height);
+    HRESULT SetDestSize([in] unsigned int width, [in] unsigned int height);
     HRESULT SetFlag([in] BMDStreamingEncodingModePropertyID cfgID, [in] BOOL value);
     HRESULT SetInt([in] BMDStreamingEncodingModePropertyID cfgID, [in] LONGLONG value);
     HRESULT SetFloat([in] BMDStreamingEncodingModePropertyID cfgID, [in] double value);
@@ -298,7 +298,7 @@ interface IBMDStreamingH264NALParser;
     HRESULT GetBytes([out] void** buffer);
     HRESULT GetBytesWithSizePrefix([out] void** buffer); // Contains a 32-bit unsigned big endian size prefix
     HRESULT GetDisplayTime([in] ULONGLONG requestedTimeScale, [out] ULONGLONG* displayTime);
-    HRESULT GetPacketIndex([out] unsigned long* packetIndex); // Deprecated
+    HRESULT GetPacketIndex([out] unsigned int* packetIndex); // Deprecated
 };
 
 /* Interface IBMDStreamingAudioPacket - Represents a chunk of audio data */
@@ -313,7 +313,7 @@ interface IBMDStreamingH264NALParser;
     long GetPayloadSize(void);
     HRESULT GetBytes([out] void** buffer);
     HRESULT GetPlayTime([in] ULONGLONG requestedTimeScale, [out] ULONGLONG* playTime);
-    HRESULT GetPacketIndex([out] unsigned long* packetIndex); // Deprecated
+    HRESULT GetPacketIndex([out] unsigned int* packetIndex); // Deprecated
 };
 
 /* Interface IBMDStreamingMPEG2TSPacket - Represent an MPEG2 Transport Stream packet */
@@ -338,11 +338,13 @@ interface IBMDStreamingH264NALParser;
 {
     HRESULT IsNALSequenceParameterSet([in] IBMDStreamingH264NALPacket* nal);
     HRESULT IsNALPictureParameterSet([in] IBMDStreamingH264NALPacket* nal);
-    HRESULT GetProfileAndLevelFromSPS([in] IBMDStreamingH264NALPacket* nal, [out] unsigned long* profileIdc, [out] unsigned long* profileCompatability, [out] unsigned long* levelIdc);
+    HRESULT GetProfileAndLevelFromSPS([in] IBMDStreamingH264NALPacket* nal, [out] unsigned int* profileIdc, [out] unsigned int* profileCompatability, [out] unsigned int* levelIdc);
 };
 
 /* Coclasses */
 
+importlib("stdole2.tlb");
+
 [
     uuid(0CAA31F6-8A26-40B0-86A4-BF58DCCA710C),
     helpstring("CBMDStreamingDiscovery Class")
@@ -358,3 +360,5 @@ interface IBMDStreamingH264NALParser;
 {
     [default] interface IBMDStreamingH264NALParser;
 };
+
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPITypes.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPITypes.idl
index 1be8556..35915b4 100644
--- a/plugins/decklink/win/decklink-sdk/DeckLinkAPITypes.idl
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPITypes.idl
@@ -1,5 +1,5 @@
 /* -LICENSE-START-
-** Copyright (c) 2014 Blackmagic Design
+** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
@@ -38,12 +38,12 @@
 
 typedef LONGLONG BMDTimeValue;
 typedef LONGLONG BMDTimeScale;
-typedef unsigned long BMDTimecodeBCD;
-typedef unsigned long BMDTimecodeUserBits;
+typedef unsigned int BMDTimecodeBCD;
+typedef unsigned int BMDTimecodeUserBits;
 
 // Enumeration Mapping
 
-cpp_quote("typedef unsigned long BMDTimecodeFlags;")
+cpp_quote("typedef unsigned int BMDTimecodeFlags;")
 cpp_quote("#if 0")
 typedef enum _BMDTimecodeFlags BMDTimecodeFlags;
 cpp_quote("#endif")
@@ -74,9 +74,18 @@ typedef [v1_enum] enum	_BMDAudioConnection {
     bmdAudioConnectionAESEBU                                     = 1 << 1,
     bmdAudioConnectionAnalog                                     = 1 << 2,
     bmdAudioConnectionAnalogXLR                                  = 1 << 3,
-    bmdAudioConnectionAnalogRCA                                  = 1 << 4
+    bmdAudioConnectionAnalogRCA                                  = 1 << 4,
+    bmdAudioConnectionMicrophone                                 = 1 << 5,
+    bmdAudioConnectionHeadphones                                 = 1 << 6
 } BMDAudioConnection;
 
+/* Enum BMDDeckControlConnection - Deck control connections */
+
+typedef [v1_enum] enum	_BMDDeckControlConnection {
+    bmdDeckControlConnectionRS422Remote1                         = 1 << 0,
+    bmdDeckControlConnectionRS422Remote2                         = 1 << 1
+} BMDDeckControlConnection;
+
 // Forward Declarations
 
 interface IDeckLinkTimecode;
@@ -97,3 +106,7 @@ interface IDeckLinkTimecode;
 };
 
 /* Coclasses */
+
+importlib("stdole2.tlb");
+
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIVersion.h b/plugins/decklink/win/decklink-sdk/DeckLinkAPIVersion.h
index 719ae2b..dfd1799 100644
--- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIVersion.h
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIVersion.h
@@ -30,7 +30,8 @@
 #ifndef __DeckLink_API_Version_h__
 #define __DeckLink_API_Version_h__
 
-#define BLACKMAGIC_DECKLINK_API_VERSION					0x0a030100
-#define BLACKMAGIC_DECKLINK_API_VERSION_STRING			"10.3.1"
+#define BLACKMAGIC_DECKLINK_API_VERSION					0x0a080000
+#define BLACKMAGIC_DECKLINK_API_VERSION_STRING			"10.8"
 
 #endif	// __DeckLink_API_Version_h__
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_2.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_2.idl
new file mode 100644
index 0000000..12b6250
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_2.idl
@@ -0,0 +1,73 @@
+/* -LICENSE-START-
+** Copyright (c) 2014 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPI_v10_2.idl */
+
+// Enumeration Mapping
+
+/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */
+
+typedef [v1_enum] enum  _BMDDeckLinkConfigurationID_v10_2 {
+
+    /* Video output flags */
+
+    bmdDeckLinkConfig3GBpsVideoOutput_v10_2                      = /* '3gbs' */ 0x33676273
+
+} BMDDeckLinkConfigurationID_v10_2;
+
+/* Enum BMDAudioConnection_v10_2 - Audio connection types */
+
+typedef [v1_enum] enum	_BMDAudioConnection_v10_2 {
+    bmdAudioConnectionEmbedded_v10_2                             = /* 'embd' */ 0x656D6264,
+    bmdAudioConnectionAESEBU_v10_2                               = /* 'aes ' */ 0x61657320,
+    bmdAudioConnectionAnalog_v10_2                               = /* 'anlg' */ 0x616E6C67,
+    bmdAudioConnectionAnalogXLR_v10_2                            = /* 'axlr' */ 0x61786C72,
+    bmdAudioConnectionAnalogRCA_v10_2                            = /* 'arca' */ 0x61726361
+} BMDAudioConnection_v10_2;
+
+// Forward Declarations
+
+interface IDeckLinkConfiguration_v10_2;
+
+/* Interface IDeckLinkConfiguration_v10_2 - DeckLink Configuration interface */
+
+[
+    object,
+    uuid(C679A35B-610C-4D09-B748-1D0478100FC0),
+    local,
+    helpstring("DeckLink Configuration interface")
+] interface IDeckLinkConfiguration_v10_2 : IUnknown
+{
+    HRESULT SetFlag([in] BMDDeckLinkConfigurationID cfgID, [in] BOOL value);
+    HRESULT GetFlag([in] BMDDeckLinkConfigurationID cfgID, [out] BOOL *value);
+    HRESULT SetInt([in] BMDDeckLinkConfigurationID cfgID, [in] LONGLONG value);
+    HRESULT GetInt([in] BMDDeckLinkConfigurationID cfgID, [out] LONGLONG *value);
+    HRESULT SetFloat([in] BMDDeckLinkConfigurationID cfgID, [in] double value);
+    HRESULT GetFloat([in] BMDDeckLinkConfigurationID cfgID, [out] double *value);
+    HRESULT SetString([in] BMDDeckLinkConfigurationID cfgID, [in] BSTR value);
+    HRESULT GetString([in] BMDDeckLinkConfigurationID cfgID, [out] BSTR *value);
+    HRESULT WriteConfigurationToPreferences(void);
+};
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_4.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_4.idl
new file mode 100644
index 0000000..8787e96
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_4.idl
@@ -0,0 +1,61 @@
+/* -LICENSE-START-
+** Copyright (c) 2015 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPI_v10_4.idl */
+
+/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */
+
+typedef [v1_enum] enum	_BMDDeckLinkConfigurationID_v10_4 {
+
+    /* Video output flags */
+
+    bmdDeckLinkConfigSingleLinkVideoOutput_v10_4                       = /* 'sglo' */ 0x73676C6F,
+
+} BMDDeckLinkConfigurationID_v10_4;
+
+// Forward Declarations
+
+interface IDeckLinkConfiguration_v10_4;
+
+/* Interface IDeckLinkConfiguration_v10_4 - DeckLink Configuration interface */
+
+[
+    object,
+    uuid(1E69FCF6-4203-4936-8076-2A9F4CFD50CB),
+    local,
+    helpstring("DeckLink Configuration interface")
+] interface IDeckLinkConfiguration_v10_4 : IUnknown
+{
+    HRESULT SetFlag([in] BMDDeckLinkConfigurationID cfgID, [in] BOOL value);
+    HRESULT GetFlag([in] BMDDeckLinkConfigurationID cfgID, [out] BOOL *value);
+    HRESULT SetInt([in] BMDDeckLinkConfigurationID cfgID, [in] LONGLONG value);
+    HRESULT GetInt([in] BMDDeckLinkConfigurationID cfgID, [out] LONGLONG *value);
+    HRESULT SetFloat([in] BMDDeckLinkConfigurationID cfgID, [in] double value);
+    HRESULT GetFloat([in] BMDDeckLinkConfigurationID cfgID, [out] double *value);
+    HRESULT SetString([in] BMDDeckLinkConfigurationID cfgID, [in] BSTR value);
+    HRESULT GetString([in] BMDDeckLinkConfigurationID cfgID, [out] BSTR *value);
+    HRESULT WriteConfigurationToPreferences(void);
+};
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_5.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_5.idl
new file mode 100644
index 0000000..7348e49
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_5.idl
@@ -0,0 +1,61 @@
+/* -LICENSE-START-
+** Copyright (c) 2015 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPI_v10_5.idl */
+
+/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */
+
+typedef [v1_enum] enum	_BMDDeckLinkAttributeID_v10_5 {
+
+    /* Integers */
+
+    BMDDeckLinkDeviceBusyState_v10_5                             = /* 'dbst' */ 0x64627374,
+
+} BMDDeckLinkAttributeID_v10_5;
+
+// Forward Declarations
+
+interface IDeckLinkEncoderConfiguration_v10_5;
+
+/* Interface IDeckLinkEncoderConfiguration_v10_5 - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */
+
+[
+    object,
+    uuid(67455668-0848-45DF-8D8E-350A77C9A028),
+    local,
+    helpstring("DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput")
+] interface IDeckLinkEncoderConfiguration_v10_5 : IUnknown
+{
+    HRESULT SetFlag([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] BOOL value);
+    HRESULT GetFlag([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] BOOL *value);
+    HRESULT SetInt([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] LONGLONG value);
+    HRESULT GetInt([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] LONGLONG *value);
+    HRESULT SetFloat([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] double value);
+    HRESULT GetFloat([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] double *value);
+    HRESULT SetString([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] BSTR value);
+    HRESULT GetString([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] BSTR *value);
+    HRESULT GetDecoderConfigurationInfo([out] void *buffer, [in] long bufferSize, [out] long *returnedSize);
+};
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_6.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_6.idl
new file mode 100644
index 0000000..1e43bd2
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_6.idl
@@ -0,0 +1,41 @@
+/* -LICENSE-START-
+** Copyright (c) 2016 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPI_v10_6.idl */
+
+/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */
+
+typedef [v1_enum] enum	_BMDDeckLinkAttributeID_v10_6 {
+
+    /* Flags */
+
+    BMDDeckLinkSupportsDesktopDisplay_v10_6                      = /* 'extd' */ 0x65787464,
+
+} BMDDeckLinkAttributeID_v10_6;
+
+typedef [v1_enum] enum _BMDIdleVideoOutputOperation_v10_6 {
+    bmdIdleVideoOutputDesktop_v10_6                              = /* 'desk' */ 0x6465736B
+} BMDIdleVideoOutputOperation_v10_6;
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_1.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_1.idl
new file mode 100644
index 0000000..e21b5a8
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_1.idl
@@ -0,0 +1,160 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPI_v7_1.idl */
+
+	interface IDeckLinkDisplayModeIterator_v7_1;
+	interface IDeckLinkDisplayMode_v7_1;
+	interface IDeckLinkVideoFrame_v7_1;
+	interface IDeckLinkVideoInputFrame_v7_1;
+	interface IDeckLinkAudioInputPacket_v7_1;
+
+	[object, uuid(B28131B6-59AC-4857-B5AC-CD75D5883E2F),
+	 helpstring("IDeckLinkDisplayModeIterator_v7_1 enumerates over supported input/output display modes.")]
+	interface IDeckLinkDisplayModeIterator_v7_1 : IUnknown
+	{
+		HRESULT		Next ([out] IDeckLinkDisplayMode_v7_1** deckLinkDisplayMode);
+	};
+
+
+	[object, uuid(AF0CD6D5-8376-435E-8433-54F9DD530AC3),
+	 helpstring("IDeckLinkDisplayMode_v7_1 represents a display mode")]
+	interface IDeckLinkDisplayMode_v7_1 : IUnknown
+	{
+		HRESULT				GetName ([out] BSTR* name);
+		BMDDisplayMode		GetDisplayMode ();
+		long				GetWidth ();
+		long				GetHeight ();
+		HRESULT				GetFrameRate ([out] BMDTimeValue *frameDuration, [out] BMDTimeScale *timeScale);
+	};
+
+	[object, uuid(EBD01AFA-E4B0-49C6-A01D-EDB9D1B55FD9),
+     helpstring("IDeckLinkVideoOutputCallback. Frame completion callback.")]
+    interface IDeckLinkVideoOutputCallback_v7_1 : IUnknown
+    {
+        HRESULT		ScheduledFrameCompleted ([in] IDeckLinkVideoFrame_v7_1* completedFrame, [in] BMDOutputFrameCompletionResult result);
+    };
+
+    [object, uuid(7F94F328-5ED4-4E9F-9729-76A86BDC99CC),
+     helpstring("IDeckLinkInputCallback_v7_1. Frame arrival callback.")]
+    interface IDeckLinkInputCallback_v7_1 : IUnknown
+    {
+        HRESULT		VideoInputFrameArrived ([in] IDeckLinkVideoInputFrame_v7_1* videoFrame, [in] IDeckLinkAudioInputPacket_v7_1* audioPacket);
+    };
+
+
+    [object, uuid(AE5B3E9B-4E1E-4535-B6E8-480FF52F6CE5), local,
+     helpstring("IDeckLinkOutput_v7_1.  Created by QueryInterface from IDeckLink.")]
+    interface IDeckLinkOutput_v7_1 : IUnknown
+    {
+		HRESULT		DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);
+		HRESULT		GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator_v7_1 **iterator);
+
+		// Video output
+        HRESULT		EnableVideoOutput (BMDDisplayMode displayMode);
+        HRESULT		DisableVideoOutput ();
+
+		HRESULT		SetVideoOutputFrameMemoryAllocator ([in] IDeckLinkMemoryAllocator* theAllocator);
+        HRESULT		CreateVideoFrame (int width, int height, int rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1** outFrame);
+        HRESULT		CreateVideoFrameFromBuffer (void* buffer, int width, int height, int rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1** outFrame);
+
+        HRESULT		DisplayVideoFrameSync (IDeckLinkVideoFrame_v7_1* theFrame);
+        HRESULT		ScheduleVideoFrame (IDeckLinkVideoFrame_v7_1* theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale);
+        HRESULT		SetScheduledFrameCompletionCallback ([in] IDeckLinkVideoOutputCallback_v7_1* theCallback);
+
+		// Audio output
+		HRESULT		EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount);
+		HRESULT		DisableAudioOutput ();
+
+		HRESULT		WriteAudioSamplesSync (void* buffer, unsigned int sampleFrameCount, [out] unsigned int *sampleFramesWritten);
+
+		HRESULT		BeginAudioPreroll ();
+		HRESULT		EndAudioPreroll ();
+		HRESULT		ScheduleAudioSamples (void* buffer, unsigned int sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, [out] unsigned int *sampleFramesWritten);
+
+		HRESULT		GetBufferedAudioSampleFrameCount ( [out] unsigned int *bufferedSampleCount);
+		HRESULT		FlushBufferedAudioSamples ();
+
+		HRESULT		SetAudioCallback ( [in] IDeckLinkAudioOutputCallback* theCallback);
+
+		// Output control
+        HRESULT		StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed);
+        HRESULT		StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, BMDTimeValue *actualStopTime, BMDTimeScale timeScale);
+        HRESULT		GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, BMDTimeValue *elapsedTimeSinceSchedulerBegan);
+    };
+
+    [object, uuid(2B54EDEF-5B32-429F-BA11-BB990596EACD),
+     helpstring("IDeckLinkInput_v7_1.  Created by QueryInterface from IDeckLink.")]
+    interface IDeckLinkInput_v7_1 : IUnknown
+    {
+		HRESULT		DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);
+		HRESULT		GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator_v7_1 **iterator);
+
+		// Video input
+		HRESULT		EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags);
+		HRESULT		DisableVideoInput ();
+
+		// Audio input
+		HRESULT		EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount);
+		HRESULT		DisableAudioInput ();
+		HRESULT		ReadAudioSamples (void* buffer, unsigned int sampleFrameCount, [out] unsigned int *sampleFramesRead, [out] BMDTimeValue *audioPacketTime, BMDTimeScale timeScale);
+		HRESULT		GetBufferedAudioSampleFrameCount ( [out] unsigned int *bufferedSampleCount);
+
+		// Input control
+		HRESULT		StartStreams ();
+		HRESULT		StopStreams ();
+		HRESULT		PauseStreams ();
+		HRESULT		SetCallback ([in] IDeckLinkInputCallback_v7_1* theCallback);
+    };
+
+	[object, uuid(333F3A10-8C2D-43CF-B79D-46560FEEA1CE), local,
+     helpstring("IDeckLinkVideoFrame_v7_1.  Created by IDeckLinkVideoOutput::CreateVideoFrame.")]
+    interface IDeckLinkVideoFrame_v7_1 : IUnknown
+    {
+        long				GetWidth ();
+        long				GetHeight ();
+        long				GetRowBytes ();
+        BMDPixelFormat		GetPixelFormat ();
+        BMDFrameFlags		GetFlags ();
+        HRESULT				GetBytes (void* *buffer);
+    };
+
+	[object, uuid(C8B41D95-8848-40EE-9B37-6E3417FB114B), local,
+     helpstring("IDeckLinkVideoInputFrame_v7_1.  Provided by the IDeckLinkVideoInput frame arrival callback.")]
+    interface IDeckLinkVideoInputFrame_v7_1 : IDeckLinkVideoFrame_v7_1
+    {
+        HRESULT				GetFrameTime (BMDTimeValue *frameTime, BMDTimeValue *frameDuration, BMDTimeScale timeScale);
+    };
+
+	[object, uuid(C86DE4F6-A29F-42E3-AB3A-1363E29F0788), local,
+     helpstring("IDeckLinkAudioInputPacket_v7_1.  Provided by the IDeckLinkInput callback.")]
+    interface IDeckLinkAudioInputPacket_v7_1 : IUnknown
+    {
+		long				GetSampleCount ();
+		HRESULT				GetBytes (void* *buffer);
+		HRESULT				GetAudioPacketTime (BMDTimeValue *packetTime, BMDTimeScale timeScale);
+    };
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_3.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_3.idl
new file mode 100644
index 0000000..9dfa497
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_3.idl
@@ -0,0 +1,157 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* Forward Declarations */
+
+interface IDeckLinkInputCallback_v7_3;
+interface IDeckLinkOutput_v7_3;
+interface IDeckLinkInput_v7_3;
+interface IDeckLinkVideoInputFrame_v7_3;
+
+/* End Forward Declarations */
+
+
+/* Interface IDeckLinkInputCallback - Frame arrival callback. */
+
+[
+    object,
+    uuid(FD6F311D-4D00-444B-9ED4-1F25B5730AD0),
+    helpstring("Frame arrival callback.")
+] interface IDeckLinkInputCallback_v7_3 : IUnknown
+{
+    HRESULT VideoInputFormatChanged([in] BMDVideoInputFormatChangedEvents notificationEvents, [in] IDeckLinkDisplayMode_v7_6 *newDisplayMode, [in] BMDDetectedVideoInputFormatFlags detectedSignalFlags);
+    HRESULT VideoInputFrameArrived([in] IDeckLinkVideoInputFrame_v7_3 *videoFrame, [in] IDeckLinkAudioInputPacket *audioPacket);
+};
+
+/* End Interface IDeckLinkInputCallback */
+
+
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */
+
+[
+    object,
+    uuid(271C65E3-C323-4344-A30F-D908BCB20AA3),
+    local,
+    helpstring("Created by QueryInterface from IDeckLink.")
+] interface IDeckLinkOutput_v7_3 : IUnknown
+{
+    HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);
+    HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator_v7_6 **iterator);
+
+    HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback);
+
+    /* Video Output */
+
+    HRESULT EnableVideoOutput(BMDDisplayMode displayMode, BMDVideoOutputFlags flags);
+    HRESULT DisableVideoOutput(void);
+
+    HRESULT SetVideoOutputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator);
+    HRESULT CreateVideoFrame(int width, int height, int rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame_v7_6 **outFrame);
+    HRESULT CreateAncillaryData(BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer);
+
+    HRESULT DisplayVideoFrameSync([in] IDeckLinkVideoFrame_v7_6 *theFrame);
+    HRESULT ScheduleVideoFrame([in] IDeckLinkVideoFrame_v7_6 *theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale);
+    HRESULT SetScheduledFrameCompletionCallback([in] IDeckLinkVideoOutputCallback *theCallback);
+    HRESULT GetBufferedVideoFrameCount([out] unsigned int *bufferedFrameCount);
+
+    /* Audio Output */
+
+    HRESULT EnableAudioOutput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount, BMDAudioOutputStreamType streamType);
+    HRESULT DisableAudioOutput(void);
+
+    HRESULT WriteAudioSamplesSync([in] void *buffer, unsigned int sampleFrameCount, [out] unsigned int *sampleFramesWritten);
+
+    HRESULT BeginAudioPreroll(void);
+    HRESULT EndAudioPreroll(void);
+    HRESULT ScheduleAudioSamples([in] void *buffer, unsigned int sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, [out] unsigned int *sampleFramesWritten);
+
+    HRESULT GetBufferedAudioSampleFrameCount([out] unsigned int *bufferedSampleFrameCount);
+    HRESULT FlushBufferedAudioSamples(void);
+
+    HRESULT SetAudioCallback([in] IDeckLinkAudioOutputCallback *theCallback);
+
+    /* Output Control */
+
+    HRESULT StartScheduledPlayback(BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed);
+    HRESULT StopScheduledPlayback(BMDTimeValue stopPlaybackAtTime, [out] BMDTimeValue *actualStopTime, BMDTimeScale timeScale);
+    HRESULT IsScheduledPlaybackRunning([out] BOOL *active);
+    HRESULT GetHardwareReferenceClock(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *elapsedTimeSinceSchedulerBegan);
+};
+
+/* End Interface IDeckLinkOutput */
+
+/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */
+
+[
+    object,
+    uuid(4973F012-9925-458C-871C-18774CDBBECB),
+    helpstring("Created by QueryInterface from IDeckLink.")
+] interface IDeckLinkInput_v7_3 : IUnknown
+{
+    HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);
+    HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator_v7_6 **iterator);
+
+    HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback);
+
+    /* Video Input */
+
+    HRESULT EnableVideoInput(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags);
+    HRESULT DisableVideoInput(void);
+    HRESULT GetAvailableVideoFrameCount([out] unsigned int *availableFrameCount);
+
+    /* Audio Input */
+
+    HRESULT EnableAudioInput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount);
+    HRESULT DisableAudioInput(void);
+    HRESULT GetAvailableAudioSampleFrameCount([out] unsigned int *availableSampleFrameCount);
+
+    /* Input Control */
+
+    HRESULT StartStreams(void);
+    HRESULT StopStreams(void);
+    HRESULT PauseStreams(void);
+    HRESULT FlushStreams(void);
+    HRESULT SetCallback([in] IDeckLinkInputCallback_v7_3 *theCallback);
+};
+
+/* End Interface IDeckLinkInput */
+
+
+/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */
+
+[
+    object,
+    uuid(CF317790-2894-11DE-8C30-0800200C9A66),
+    local,
+    helpstring("Provided by the IDeckLinkVideoInput frame arrival callback.")
+] interface IDeckLinkVideoInputFrame_v7_3 : IDeckLinkVideoFrame_v7_6
+{
+    HRESULT GetStreamTime([out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration, BMDTimeScale timeScale);
+};
+
+/* End Interface IDeckLinkVideoInputFrame */
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_6.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_6.idl
new file mode 100644
index 0000000..8ed7b73
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_6.idl
@@ -0,0 +1,396 @@
+/* -LICENSE-START-
+** Copyright (c) 2009 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* Enum BMDVideoConnection - Video connection types */
+
+typedef [v1_enum] enum  _BMDVideoConnection_v7_6 {
+    bmdVideoConnectionSDI_v7_6                              = /* 'sdi ' */ 0x73646920,
+    bmdVideoConnectionHDMI_v7_6                             = /* 'hdmi' */ 0x68646D69,
+    bmdVideoConnectionOpticalSDI_v7_6                       = /* 'opti' */ 0x6F707469,
+    bmdVideoConnectionComponent_v7_6                        = /* 'cpnt' */ 0x63706E74,
+    bmdVideoConnectionComposite_v7_6                        = /* 'cmst' */ 0x636D7374,
+    bmdVideoConnectionSVideo_v7_6                           = /* 'svid' */ 0x73766964
+} BMDVideoConnection_v7_6;
+
+
+
+/* Forward Declarations */
+
+interface IDeckLinkDisplayModeIterator_v7_6;
+interface IDeckLinkDisplayMode_v7_6;
+interface IDeckLinkOutput_v7_6;
+interface IDeckLinkInput_v7_6;
+interface IDeckLinkTimecode_v7_6;
+interface IDeckLinkVideoFrame_v7_6;
+interface IDeckLinkMutableVideoFrame_v7_6;
+interface IDeckLinkVideoInputFrame_v7_6;
+interface IDeckLinkScreenPreviewCallback_v7_6;
+interface IDeckLinkGLScreenPreviewHelper_v7_6;
+interface IDeckLinkVideoConversion_v7_6;
+interface IDeckLinkConfiguration_v7_6;
+
+
+/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */
+
+[
+    object,
+    uuid(E763A626-4A3C-49D1-BF13-E7AD3692AE52),
+    helpstring("Frame completion callback.")
+] interface IDeckLinkVideoOutputCallback_v7_6 : IUnknown
+{
+    HRESULT ScheduledFrameCompleted([in] IDeckLinkVideoFrame_v7_6 *completedFrame, [in] BMDOutputFrameCompletionResult result);
+    HRESULT ScheduledPlaybackHasStopped(void);
+};
+
+
+/* Interface IDeckLinkInputCallback - Frame arrival callback. */
+
+[
+    object,
+    uuid(31D28EE7-88B6-4CB1-897A-CDBF79A26414),
+    helpstring("Frame arrival callback.")
+] interface IDeckLinkInputCallback_v7_6 : IUnknown
+{
+    HRESULT VideoInputFormatChanged([in] BMDVideoInputFormatChangedEvents notificationEvents, [in] IDeckLinkDisplayMode_v7_6 *newDisplayMode, [in] BMDDetectedVideoInputFormatFlags detectedSignalFlags);
+    HRESULT VideoInputFrameArrived([in] IDeckLinkVideoInputFrame_v7_6* videoFrame, [in] IDeckLinkAudioInputPacket* audioPacket);
+};
+
+
+/* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */
+
+[
+    object,
+    uuid(455D741F-1779-4800-86F5-0B5D13D79751),
+    helpstring("enumerates over supported input/output display modes.")
+] interface IDeckLinkDisplayModeIterator_v7_6 : IUnknown
+{
+    HRESULT Next([out] IDeckLinkDisplayMode_v7_6 **deckLinkDisplayMode);
+};
+
+
+/* Interface IDeckLinkDisplayMode - represents a display mode */
+
+[
+    object,
+    uuid(87451E84-2B7E-439E-A629-4393EA4A8550),
+    helpstring("represents a display mode")
+] interface IDeckLinkDisplayMode_v7_6 : IUnknown
+{
+    HRESULT GetName([out] BSTR *name);
+    BMDDisplayMode GetDisplayMode(void);
+    long GetWidth(void);
+    long GetHeight(void);
+    HRESULT GetFrameRate([out] BMDTimeValue *frameDuration, [out] BMDTimeScale *timeScale);
+    BMDFieldDominance GetFieldDominance(void);
+};
+
+
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */
+
+[
+    object,
+    uuid(29228142-EB8C-4141-A621-F74026450955),
+    local,
+    helpstring("Created by QueryInterface from IDeckLink.")
+] interface IDeckLinkOutput_v7_6 : IUnknown
+{
+    HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);
+    HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator_v7_6 **iterator);
+
+    HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback_v7_6 *previewCallback);
+
+    /* Video Output */
+
+    HRESULT EnableVideoOutput(BMDDisplayMode displayMode, BMDVideoOutputFlags flags);
+    HRESULT DisableVideoOutput(void);
+
+    HRESULT SetVideoOutputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator);
+    HRESULT CreateVideoFrame(int width, int height, int rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame_v7_6 **outFrame);
+    HRESULT CreateAncillaryData(BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer);
+
+    HRESULT DisplayVideoFrameSync([in] IDeckLinkVideoFrame_v7_6 *theFrame);
+    HRESULT ScheduleVideoFrame([in] IDeckLinkVideoFrame_v7_6 *theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale);
+    HRESULT SetScheduledFrameCompletionCallback([in] IDeckLinkVideoOutputCallback_v7_6 *theCallback);
+    HRESULT GetBufferedVideoFrameCount([out] unsigned int *bufferedFrameCount);
+
+    /* Audio Output */
+
+    HRESULT EnableAudioOutput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount, BMDAudioOutputStreamType streamType);
+    HRESULT DisableAudioOutput(void);
+
+    HRESULT WriteAudioSamplesSync([in] void *buffer, unsigned int sampleFrameCount, [out] unsigned int *sampleFramesWritten);
+
+    HRESULT BeginAudioPreroll(void);
+    HRESULT EndAudioPreroll(void);
+    HRESULT ScheduleAudioSamples([in] void *buffer, unsigned int sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, [out] unsigned int *sampleFramesWritten);
+
+    HRESULT GetBufferedAudioSampleFrameCount([out] unsigned int *bufferedSampleFrameCount);
+    HRESULT FlushBufferedAudioSamples(void);
+
+    HRESULT SetAudioCallback([in] IDeckLinkAudioOutputCallback *theCallback);
+
+    /* Output Control */
+
+    HRESULT StartScheduledPlayback(BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed);
+    HRESULT StopScheduledPlayback(BMDTimeValue stopPlaybackAtTime, [out] BMDTimeValue *actualStopTime, BMDTimeScale timeScale);
+    HRESULT IsScheduledPlaybackRunning([out] BOOL *active);
+    HRESULT GetScheduledStreamTime(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *streamTime, [out] double *playbackSpeed);
+
+    /* Hardware Timing */
+
+    HRESULT GetHardwareReferenceClock(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame);
+};
+
+
+/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */
+
+[
+    object,
+    uuid(300C135A-9F43-48E2-9906-6D7911D93CF1),
+    helpstring("Created by QueryInterface from IDeckLink.")
+] interface IDeckLinkInput_v7_6 : IUnknown
+{
+    HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result);
+    HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator_v7_6 **iterator);
+
+    HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback_v7_6 *previewCallback);
+
+    /* Video Input */
+
+    HRESULT EnableVideoInput(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags);
+    HRESULT DisableVideoInput(void);
+    HRESULT GetAvailableVideoFrameCount([out] unsigned int *availableFrameCount);
+
+    /* Audio Input */
+
+    HRESULT EnableAudioInput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount);
+    HRESULT DisableAudioInput(void);
+    HRESULT GetAvailableAudioSampleFrameCount([out] unsigned int *availableSampleFrameCount);
+
+    /* Input Control */
+
+    HRESULT StartStreams(void);
+    HRESULT StopStreams(void);
+    HRESULT PauseStreams(void);
+    HRESULT FlushStreams(void);
+    HRESULT SetCallback([in] IDeckLinkInputCallback_v7_6 *theCallback);
+
+    /* Hardware Timing */
+
+    HRESULT GetHardwareReferenceClock(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame);
+};
+
+
+/* Interface IDeckLinkTimecode_v7_6 - Used for video frame timecode representation. */
+
+[
+    object,
+    uuid(EFB9BCA6-A521-44F7-BD69-2332F24D9EE6),
+    helpstring("Used for video frame timecode representation.")
+] interface IDeckLinkTimecode_v7_6 : IUnknown
+{
+    BMDTimecodeBCD GetBCD(void);
+    HRESULT GetComponents([out] unsigned char *hours, [out] unsigned char *minutes, [out] unsigned char *seconds, [out] unsigned char *frames);
+    HRESULT GetString([out] BSTR *timecode);
+    BMDTimecodeFlags GetFlags(void);
+};
+
+
+/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */
+
+[
+    object,
+    uuid(A8D8238E-6B18-4196-99E1-5AF717B83D32),
+    local,
+    helpstring("Interface to encapsulate a video frame; can be caller-implemented.")
+] interface IDeckLinkVideoFrame_v7_6 : IUnknown
+{
+    long GetWidth(void);
+    long GetHeight(void);
+    long GetRowBytes(void);
+    BMDPixelFormat GetPixelFormat(void);
+    BMDFrameFlags GetFlags(void);
+    HRESULT GetBytes([out] void **buffer);
+
+    HRESULT GetTimecode(BMDTimecodeFormat format, [out] IDeckLinkTimecode_v7_6 **timecode);
+    HRESULT GetAncillaryData([out] IDeckLinkVideoFrameAncillary **ancillary);
+};
+
+
+/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */
+
+[
+    object,
+    uuid(46FCEE00-B4E6-43D0-91C0-023A7FCEB34F),
+    local,
+    helpstring("Created by IDeckLinkOutput::CreateVideoFrame.")
+] interface IDeckLinkMutableVideoFrame_v7_6 : IDeckLinkVideoFrame_v7_6
+{
+    HRESULT SetFlags(BMDFrameFlags newFlags);
+
+    HRESULT SetTimecode(BMDTimecodeFormat format, [in] IDeckLinkTimecode_v7_6 *timecode);
+    HRESULT SetTimecodeFromComponents(BMDTimecodeFormat format, unsigned char hours, unsigned char minutes, unsigned char seconds, unsigned char frames, BMDTimecodeFlags flags);
+    HRESULT SetAncillaryData([in] IDeckLinkVideoFrameAncillary *ancillary);
+};
+
+
+/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */
+
+[
+    object,
+    uuid(9A74FA41-AE9F-47AC-8CF4-01F42DD59965),
+    local,
+    helpstring("Provided by the IDeckLinkVideoInput frame arrival callback.")
+] interface IDeckLinkVideoInputFrame_v7_6 : IDeckLinkVideoFrame_v7_6
+{
+    HRESULT GetStreamTime([out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration, BMDTimeScale timeScale);
+    HRESULT GetHardwareReferenceTimestamp(BMDTimeScale timeScale, [out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration);
+};
+
+
+/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */
+
+[
+    object,
+    uuid(373F499D-4B4D-4518-AD22-6354E5A5825E),
+    local,
+    helpstring("Screen preview callback")
+] interface IDeckLinkScreenPreviewCallback_v7_6 : IUnknown
+{
+    HRESULT DrawFrame([in] IDeckLinkVideoFrame_v7_6 *theFrame);
+};
+
+
+/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */
+
+[
+    object,
+    uuid(BA575CD9-A15E-497B-B2C2-F9AFE7BE4EBA),
+    local,
+    helpstring("Created with CoCreateInstance().")
+] interface IDeckLinkGLScreenPreviewHelper_v7_6 : IUnknown
+{
+
+    /* Methods must be called with OpenGL context set */
+
+    HRESULT InitializeGL(void);
+    HRESULT PaintGL(void);
+    HRESULT SetFrame([in] IDeckLinkVideoFrame_v7_6 *theFrame);
+};
+
+
+/* Interface IDeckLinkVideoConversion - Created with CoCreateInstance(). */
+
+[
+    object,
+    uuid(3EB504C9-F97D-40FE-A158-D407D48CB53B),
+    local,
+    helpstring("Created with CoCreateInstance().")
+] interface IDeckLinkVideoConversion_v7_6 : IUnknown
+{
+    HRESULT ConvertFrame([in] IDeckLinkVideoFrame_v7_6* srcFrame, [in] IDeckLinkVideoFrame_v7_6* dstFrame);
+};
+
+/* Interface IDeckLinkConfiguration_v7_6 - Created by QueryInterface from IDeckLink. */
+
+[
+    object,
+    uuid(B8EAD569-B764-47F0-A73F-AE40DF6CBF10),
+    helpstring("Created by QueryInterface from IDeckLink.")
+] interface IDeckLinkConfiguration_v7_6 : IUnknown
+{
+    HRESULT GetConfigurationValidator([out] IDeckLinkConfiguration_v7_6 **configObject);
+    HRESULT WriteConfigurationToPreferences(void);
+
+    /* Video Output Configuration */
+
+    HRESULT SetVideoOutputFormat([in] BMDVideoConnection_v7_6 videoOutputConnection);
+    HRESULT IsVideoOutputActive([in] BMDVideoConnection_v7_6 videoOutputConnection, [out] BOOL *active);
+
+    HRESULT SetAnalogVideoOutputFlags([in] BMDAnalogVideoFlags analogVideoFlags);
+    HRESULT GetAnalogVideoOutputFlags([out] BMDAnalogVideoFlags *analogVideoFlags);
+
+    HRESULT EnableFieldFlickerRemovalWhenPaused([in] BOOL enable);
+    HRESULT IsEnabledFieldFlickerRemovalWhenPaused([out] BOOL *enabled);
+
+    HRESULT Set444And3GBpsVideoOutput([in] BOOL enable444VideoOutput, [in] BOOL enable3GbsOutput);
+    HRESULT Get444And3GBpsVideoOutput([out] BOOL *is444VideoOutputEnabled, [out] BOOL *threeGbsOutputEnabled);
+
+    HRESULT SetVideoOutputConversionMode([in] BMDVideoOutputConversionMode conversionMode);
+    HRESULT GetVideoOutputConversionMode([out] BMDVideoOutputConversionMode *conversionMode);
+
+    HRESULT Set_HD1080p24_to_HD1080i5994_Conversion([in] BOOL enable);
+    HRESULT Get_HD1080p24_to_HD1080i5994_Conversion([out] BOOL *enabled);
+
+    /* Video Input Configuration */
+
+    HRESULT SetVideoInputFormat([in] BMDVideoConnection_v7_6 videoInputFormat);
+    HRESULT GetVideoInputFormat([out] BMDVideoConnection_v7_6 *videoInputFormat);
+
+    HRESULT SetAnalogVideoInputFlags([in] BMDAnalogVideoFlags analogVideoFlags);
+    HRESULT GetAnalogVideoInputFlags([out] BMDAnalogVideoFlags *analogVideoFlags);
+
+    HRESULT SetVideoInputConversionMode([in] BMDVideoInputConversionMode conversionMode);
+    HRESULT GetVideoInputConversionMode([out] BMDVideoInputConversionMode *conversionMode);
+
+    HRESULT SetBlackVideoOutputDuringCapture([in] BOOL blackOutInCapture);
+    HRESULT GetBlackVideoOutputDuringCapture([out] BOOL *blackOutInCapture);
+
+    HRESULT Set32PulldownSequenceInitialTimecodeFrame([in] unsigned int aFrameTimecode);
+    HRESULT Get32PulldownSequenceInitialTimecodeFrame([out] unsigned int *aFrameTimecode);
+
+    HRESULT SetVancSourceLineMapping([in] unsigned int activeLine1VANCsource, [in] unsigned int activeLine2VANCsource, [in] unsigned int activeLine3VANCsource);
+    HRESULT GetVancSourceLineMapping([out] unsigned int *activeLine1VANCsource, [out] unsigned int *activeLine2VANCsource, [out] unsigned int *activeLine3VANCsource);
+
+    /* Audio Input Configuration */
+
+    HRESULT SetAudioInputFormat([in] BMDAudioConnection_v10_2 audioInputFormat);
+    HRESULT GetAudioInputFormat([out] BMDAudioConnection_v10_2 *audioInputFormat);
+};
+
+
+
+/* Coclasses */
+
+importlib("stdole2.tlb");
+
+[
+    uuid(D398CEE7-4434-4CA3-9BA6-5AE34556B905),
+    helpstring("CDeckLinkGLScreenPreviewHelper Class (DeckLink API v7.6)")
+] coclass CDeckLinkGLScreenPreviewHelper_v7_6
+{
+    [default] interface IDeckLinkGLScreenPreviewHelper_v7_6;
+};
+
+[
+    uuid(FFA84F77-73BE-4FB7-B03E-B5E44B9F759B),
+    helpstring("CDeckLinkVideoConversion Class (DeckLink API v7.6)")
+] coclass CDeckLinkVideoConversion_v7_6
+{
+    [default] interface IDeckLinkVideoConversion_v7_6;
+};
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_9.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_9.idl
new file mode 100644
index 0000000..722984a
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_9.idl
@@ -0,0 +1,69 @@
+/* -LICENSE-START-
+** Copyright (c) 2010 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPI_v7_9.idl */
+
+/* Interface IDeckLinkDeckControl_v7_9 - Deck Control main interface */
+
+[
+	object,
+	uuid(A4D81043-0619-42B7-8ED6-602D29041DF7),
+	helpstring("Deck Control main interface")
+] interface IDeckLinkDeckControl_v7_9 : IUnknown
+{
+	HRESULT Open([in] BMDTimeScale timeScale, [in] BMDTimeValue timeValue, [in] BOOL timecodeIsDropFrame, [out] BMDDeckControlError *error);
+	HRESULT Close([in] BOOL standbyOn);
+	HRESULT GetCurrentState([out] BMDDeckControlMode *mode, [out] BMDDeckControlVTRControlState *vtrControlState, [out] BMDDeckControlStatusFlags *flags);
+	HRESULT SetStandby([in] BOOL standbyOn);
+	HRESULT Play([out] BMDDeckControlError *error);
+	HRESULT Stop([out] BMDDeckControlError *error);
+	HRESULT TogglePlayStop([out] BMDDeckControlError *error);
+	HRESULT Eject([out] BMDDeckControlError *error);
+	HRESULT GoToTimecode([in] BMDTimecodeBCD timecode, [out] BMDDeckControlError *error);
+	HRESULT FastForward([in] BOOL viewTape, [out] BMDDeckControlError *error);
+	HRESULT Rewind([in] BOOL viewTape, [out] BMDDeckControlError *error);
+	HRESULT StepForward([out] BMDDeckControlError *error);
+	HRESULT StepBack([out] BMDDeckControlError *error);
+	HRESULT Jog([in] double rate, [out] BMDDeckControlError *error);
+	HRESULT Shuttle([in] double rate, [out] BMDDeckControlError *error);
+	HRESULT GetTimecodeString([out] BSTR *currentTimeCode, [out] BMDDeckControlError *error);
+	HRESULT GetTimecode([out] IDeckLinkTimecode **currentTimecode, [out] BMDDeckControlError *error);
+	HRESULT GetTimecodeBCD([out] BMDTimecodeBCD *currentTimecode, [out] BMDDeckControlError *error);
+	HRESULT SetPreroll([in] unsigned int prerollSeconds);
+	HRESULT GetPreroll([out] unsigned int *prerollSeconds);
+	HRESULT SetExportOffset([in] int exportOffsetFields);
+	HRESULT GetExportOffset([out] int *exportOffsetFields);
+	HRESULT GetManualExportOffset([out] int *deckManualExportOffsetFields);
+	HRESULT SetCaptureOffset([in] int captureOffsetFields);
+	HRESULT GetCaptureOffset([out] int *captureOffsetFields);
+	HRESULT StartExport([in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [in] BMDDeckControlExportModeOpsFlags exportModeOps, [out] BMDDeckControlError *error);
+	HRESULT StartCapture([in] BOOL useVITC, [in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [out] BMDDeckControlError *error);
+	HRESULT GetDeviceID([out] unsigned short *deviceId, [out] BMDDeckControlError *error);
+	HRESULT Abort(void);
+	HRESULT CrashRecordStart([out] BMDDeckControlError *error);
+	HRESULT CrashRecordStop([out] BMDDeckControlError *error);
+	HRESULT SetCallback([in] IDeckLinkDeckControlStatusCallback *callback);
+};
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_0.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_0.idl
new file mode 100644
index 0000000..a2da181
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_0.idl
@@ -0,0 +1,62 @@
+/* -LICENSE-START-
+** Copyright (c) 2011 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPI_v8_0.idl */
+
+/* Interface IDeckLink_v8_0 - represents a DeckLink device */
+
+[
+    object,
+    uuid(62BFF75D-6569-4E55-8D4D-66AA03829ABC),
+    helpstring("represents a DeckLink device")
+] interface IDeckLink_v8_0 : IUnknown
+{
+    HRESULT GetModelName([out] BSTR *modelName);
+};
+
+/* Interface IDeckLinkIterator_v8_0 - enumerates installed DeckLink hardware */
+
+[
+    object,
+    uuid(74E936FC-CC28-4A67-81A0-1E94E52D4E69),
+    helpstring("enumerates installed DeckLink hardware")
+] interface IDeckLinkIterator_v8_0 : IUnknown
+{
+    HRESULT Next([out] IDeckLink_v8_0 **deckLinkInstance);
+};
+
+
+/* Coclasses */
+
+importlib("stdole2.tlb");
+
+[
+    uuid(D9EDA3B3-2887-41FA-B724-017CF1EB1D37),
+    helpstring("CDeckLinkIterator Class (DeckLink API v8.0)")
+] coclass CDeckLinkIterator_v8_0
+{
+    [default] interface IDeckLinkIterator_v8_0;
+};
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_1.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_1.idl
new file mode 100644
index 0000000..59b9a21
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_1.idl
@@ -0,0 +1,101 @@
+/* -LICENSE-START-
+** Copyright (c) 2011 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+/* DeckLinkAPI_v8_1.idl */
+
+/* Enum BMDDeckControlVTRControlState_v8_1 - VTR Control state */
+
+typedef [v1_enum] enum  _BMDDeckControlVTRControlState_v8_1 {
+    bmdDeckControlNotInVTRControlMode_v8_1                            = /* 'nvcm' */ 0x6E76636D,
+    bmdDeckControlVTRControlPlaying_v8_1                              = /* 'vtrp' */ 0x76747270,
+    bmdDeckControlVTRControlRecording_v8_1                            = /* 'vtrr' */ 0x76747272,
+    bmdDeckControlVTRControlStill_v8_1                                = /* 'vtra' */ 0x76747261,
+    bmdDeckControlVTRControlSeeking_v8_1                              = /* 'vtrs' */ 0x76747273,
+    bmdDeckControlVTRControlStopped_v8_1                              = /* 'vtro' */ 0x7674726F
+} BMDDeckControlVTRControlState_v8_1;
+
+
+interface IDeckLinkDeckControlStatusCallback;
+interface IDeckLinkDeckControl;
+
+/* Interface IDeckLinkDeckControlStatusCallback_v8_1 - Deck control state change callback. */
+
+[
+    object,
+    uuid(E5F693C1-4283-4716-B18F-C1431521955B),
+    helpstring("Deck control state change callback.")
+] interface IDeckLinkDeckControlStatusCallback_v8_1 : IUnknown
+{
+    HRESULT TimecodeUpdate([in] BMDTimecodeBCD currentTimecode);
+    HRESULT VTRControlStateChanged([in] BMDDeckControlVTRControlState_v8_1 newState, [in] BMDDeckControlError error);
+    HRESULT DeckControlEventReceived([in] BMDDeckControlEvent event, [in] BMDDeckControlError error);
+    HRESULT DeckControlStatusChanged([in] BMDDeckControlStatusFlags flags, [in] unsigned int mask);
+};
+
+/* Interface IDeckLinkDeckControl - Deck Control main interface */
+
+[
+    object,
+    uuid(522A9E39-0F3C-4742-94EE-D80DE335DA1D),
+    helpstring("Deck Control main interface")
+] interface IDeckLinkDeckControl_v8_1 : IUnknown
+{
+    HRESULT Open([in] BMDTimeScale timeScale, [in] BMDTimeValue timeValue, [in] BOOL timecodeIsDropFrame, [out] BMDDeckControlError *error);
+    HRESULT Close([in] BOOL standbyOn);
+    HRESULT GetCurrentState([out] BMDDeckControlMode *mode, [out] BMDDeckControlVTRControlState_v8_1 *vtrControlState, [out] BMDDeckControlStatusFlags *flags);
+    HRESULT SetStandby([in] BOOL standbyOn);
+    HRESULT SendCommand([in] unsigned char *inBuffer, [in] unsigned int inBufferSize, [out] unsigned char *outBuffer, [out] unsigned int *outDataSize, [in] unsigned int outBufferSize, [out] BMDDeckControlError *error);
+    HRESULT Play([out] BMDDeckControlError *error);
+    HRESULT Stop([out] BMDDeckControlError *error);
+    HRESULT TogglePlayStop([out] BMDDeckControlError *error);
+    HRESULT Eject([out] BMDDeckControlError *error);
+    HRESULT GoToTimecode([in] BMDTimecodeBCD timecode, [out] BMDDeckControlError *error);
+    HRESULT FastForward([in] BOOL viewTape, [out] BMDDeckControlError *error);
+    HRESULT Rewind([in] BOOL viewTape, [out] BMDDeckControlError *error);
+    HRESULT StepForward([out] BMDDeckControlError *error);
+    HRESULT StepBack([out] BMDDeckControlError *error);
+    HRESULT Jog([in] double rate, [out] BMDDeckControlError *error);
+    HRESULT Shuttle([in] double rate, [out] BMDDeckControlError *error);
+    HRESULT GetTimecodeString([out] BSTR *currentTimeCode, [out] BMDDeckControlError *error);
+    HRESULT GetTimecode([out] IDeckLinkTimecode **currentTimecode, [out] BMDDeckControlError *error);
+    HRESULT GetTimecodeBCD([out] BMDTimecodeBCD *currentTimecode, [out] BMDDeckControlError *error);
+    HRESULT SetPreroll([in] unsigned int prerollSeconds);
+    HRESULT GetPreroll([out] unsigned int *prerollSeconds);
+    HRESULT SetExportOffset([in] int exportOffsetFields);
+    HRESULT GetExportOffset([out] int *exportOffsetFields);
+    HRESULT GetManualExportOffset([out] int *deckManualExportOffsetFields);
+    HRESULT SetCaptureOffset([in] int captureOffsetFields);
+    HRESULT GetCaptureOffset([out] int *captureOffsetFields);
+    HRESULT StartExport([in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [in] BMDDeckControlExportModeOpsFlags exportModeOps, [out] BMDDeckControlError *error);
+    HRESULT StartCapture([in] BOOL useVITC, [in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [out] BMDDeckControlError *error);
+    HRESULT GetDeviceID([out] unsigned short *deviceId, [out] BMDDeckControlError *error);
+    HRESULT Abort(void);
+    HRESULT CrashRecordStart([out] BMDDeckControlError *error);
+    HRESULT CrashRecordStop([out] BMDDeckControlError *error);
+    HRESULT SetCallback([in] IDeckLinkDeckControlStatusCallback_v8_1 *callback);
+};
+
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_2.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_2.idl
new file mode 100644
index 0000000..e918e04
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_2.idl
@@ -0,0 +1,68 @@
+/* -LICENSE-START-
+** Copyright (c) 2012 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* DeckLinkAPI_v9_2.idl */
+
+
+/* Interface IDeckLinkInput_v9_2 - Created by QueryInterface from IDeckLink. */
+
+[
+    object,
+    uuid(6D40EF78-28B9-4E21-990D-95BB7750A04F),
+    helpstring("Created by QueryInterface from IDeckLink.")
+] interface IDeckLinkInput_v9_2 : IUnknown
+{
+    HRESULT DoesSupportVideoMode([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags, [out] BMDDisplayModeSupport *result, [out] IDeckLinkDisplayMode **resultDisplayMode);
+    HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator);
+
+    HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback);
+
+    /* Video Input */
+
+    HRESULT EnableVideoInput([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags);
+    HRESULT DisableVideoInput(void);
+    HRESULT GetAvailableVideoFrameCount([out] unsigned int *availableFrameCount);
+
+    /* Audio Input */
+
+    HRESULT EnableAudioInput([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount);
+    HRESULT DisableAudioInput(void);
+    HRESULT GetAvailableAudioSampleFrameCount([out] unsigned int *availableSampleFrameCount);
+
+    /* Input Control */
+
+    HRESULT StartStreams(void);
+    HRESULT StopStreams(void);
+    HRESULT PauseStreams(void);
+    HRESULT FlushStreams(void);
+    HRESULT SetCallback([in] IDeckLinkInputCallback *theCallback);
+
+    /* Hardware Timing */
+
+    HRESULT GetHardwareReferenceClock([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame);
+};
+
diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_9.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_9.idl
new file mode 100644
index 0000000..a5e1439
--- /dev/null
+++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_9.idl
@@ -0,0 +1,87 @@
+/* -LICENSE-START-
+** Copyright (c) 2012 Blackmagic Design
+**
+** Permission is hereby granted, free of charge, to any person or organization
+** obtaining a copy of the software and accompanying documentation covered by
+** this license (the "Software") to use, reproduce, display, distribute,
+** execute, and transmit the Software, and to prepare derivative works of the
+** Software, and to permit third-parties to whom the Software is furnished to
+** do so, all subject to the following:
+**
+** The copyright notices in the Software and this entire statement, including
+** the above license grant, this restriction and the following disclaimer,
+** must be included in all copies of the Software, in whole or in part, and
+** all derivative works of the Software, unless such copies or derivative
+** works are solely in the form of machine-executable object code generated by
+** a source language processor.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+** DEALINGS IN THE SOFTWARE.
+** -LICENSE-END-
+*/
+
+/* DeckLinkAPI_v9_9.idl */
+
+
+/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */
+
+[
+    object,
+    uuid(A3EF0963-0862-44ED-92A9-EE89ABF431C7),
+    local,
+    helpstring("Created by QueryInterface from IDeckLink.")
+] interface IDeckLinkOutput_v9_9 : IUnknown
+{
+    HRESULT DoesSupportVideoMode([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoOutputFlags flags, [out] BMDDisplayModeSupport *result, [out] IDeckLinkDisplayMode **resultDisplayMode);
+    HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator);
+
+    HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback);
+
+    /* Video Output */
+
+    HRESULT EnableVideoOutput([in] BMDDisplayMode displayMode, [in] BMDVideoOutputFlags flags);
+    HRESULT DisableVideoOutput(void);
+
+    HRESULT SetVideoOutputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator);
+    HRESULT CreateVideoFrame([in] int width, [in] int height, [in] int rowBytes, [in] BMDPixelFormat pixelFormat, [in] BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame **outFrame);
+    HRESULT CreateAncillaryData([in] BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer);
+
+    HRESULT DisplayVideoFrameSync([in] IDeckLinkVideoFrame *theFrame);
+    HRESULT ScheduleVideoFrame([in] IDeckLinkVideoFrame *theFrame, [in] BMDTimeValue displayTime, [in] BMDTimeValue displayDuration, [in] BMDTimeScale timeScale);
+    HRESULT SetScheduledFrameCompletionCallback([in] IDeckLinkVideoOutputCallback *theCallback);
+    HRESULT GetBufferedVideoFrameCount([out] unsigned int *bufferedFrameCount);
+
+    /* Audio Output */
+
+    HRESULT EnableAudioOutput([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount, [in] BMDAudioOutputStreamType streamType);
+    HRESULT DisableAudioOutput(void);
+
+    HRESULT WriteAudioSamplesSync([in] void *buffer, [in] unsigned int sampleFrameCount, [out] unsigned int *sampleFramesWritten);
+
+    HRESULT BeginAudioPreroll(void);
+    HRESULT EndAudioPreroll(void);
+    HRESULT ScheduleAudioSamples([in] void *buffer, [in] unsigned int sampleFrameCount, [in] BMDTimeValue streamTime, [in] BMDTimeScale timeScale, [out] unsigned int *sampleFramesWritten);
+
+    HRESULT GetBufferedAudioSampleFrameCount([out] unsigned int *bufferedSampleFrameCount);
+    HRESULT FlushBufferedAudioSamples(void);
+
+    HRESULT SetAudioCallback([in] IDeckLinkAudioOutputCallback *theCallback);
+
+    /* Output Control */
+
+    HRESULT StartScheduledPlayback([in] BMDTimeValue playbackStartTime, [in] BMDTimeScale timeScale, [in] double playbackSpeed);
+    HRESULT StopScheduledPlayback([in] BMDTimeValue stopPlaybackAtTime, [out] BMDTimeValue *actualStopTime, [in] BMDTimeScale timeScale);
+    HRESULT IsScheduledPlaybackRunning([out] BOOL *active);
+    HRESULT GetScheduledStreamTime([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *streamTime, [out] double *playbackSpeed);
+    HRESULT GetReferenceStatus([out] BMDReferenceStatus *referenceStatus);
+
+    /* Hardware Timing */
+
+    HRESULT GetHardwareReferenceClock([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame);
+};
+
diff --git a/plugins/image-source/CMakeLists.txt b/plugins/image-source/CMakeLists.txt
index 4159cf5..56eb5fc 100644
--- a/plugins/image-source/CMakeLists.txt
+++ b/plugins/image-source/CMakeLists.txt
@@ -7,6 +7,7 @@ endif()
 
 set(image-source_SOURCES
 	image-source.c
+	color-source.c
 	obs-slideshow.c)
 
 add_library(image-source MODULE
diff --git a/plugins/image-source/color-source.c b/plugins/image-source/color-source.c
new file mode 100644
index 0000000..14f3b01
--- /dev/null
+++ b/plugins/image-source/color-source.c
@@ -0,0 +1,120 @@
+#include <obs-module.h>
+
+struct color_source {
+	uint32_t color;
+
+	uint32_t width;
+	uint32_t height;
+
+	obs_source_t *src;
+};
+
+static const char *color_source_get_name(void *unused)
+{
+	UNUSED_PARAMETER(unused);
+	return obs_module_text("ColorSource");
+}
+
+static void color_source_update(void *data, obs_data_t *settings)
+{
+	struct color_source *context = data;
+	uint32_t color = (uint32_t)obs_data_get_int(settings, "color");
+	uint32_t width = (uint32_t)obs_data_get_int(settings, "width");
+	uint32_t height = (uint32_t)obs_data_get_int(settings, "height");
+
+	context->color = color;
+	context->width = width;
+	context->height = height;
+}
+
+static void *color_source_create(obs_data_t *settings, obs_source_t *source)
+{
+	UNUSED_PARAMETER(source);
+
+	struct color_source *context = bzalloc(sizeof(struct color_source));
+	context->src = source;
+
+	color_source_update(context, settings);
+
+	return context;
+}
+
+static void color_source_destroy(void *data)
+{
+	bfree(data);
+}
+
+static obs_properties_t *color_source_properties(void *unused)
+{
+	UNUSED_PARAMETER(unused);
+
+	obs_properties_t *props = obs_properties_create();
+
+	obs_properties_add_color(props, "color",
+		obs_module_text("ColorSource.Color"));
+
+	obs_properties_add_int(props, "width",
+		obs_module_text("ColorSource.Width"), 0, 4096, 1);
+
+	obs_properties_add_int(props, "height",
+		obs_module_text("ColorSource.Height"), 0, 4096, 1);
+
+	return props;
+}
+
+static void color_source_render(void *data, gs_effect_t *effect)
+{
+	UNUSED_PARAMETER(effect);
+
+	struct color_source *context = data;
+
+	gs_effect_t    *solid = obs_get_base_effect(OBS_EFFECT_SOLID);
+	gs_eparam_t    *color = gs_effect_get_param_by_name(solid, "color");
+	gs_technique_t *tech  = gs_effect_get_technique(solid, "Solid");
+
+	struct vec4 colorVal;
+	vec4_from_rgba(&colorVal, context->color);
+	gs_effect_set_vec4(color, &colorVal);
+
+	gs_technique_begin(tech);
+	gs_technique_begin_pass(tech, 0);
+
+	gs_draw_sprite(0, 0, context->width, context->height);
+
+	gs_technique_end_pass(tech);
+	gs_technique_end(tech);
+}
+
+static uint32_t color_source_getwidth(void *data)
+{
+	struct color_source *context = data;
+	return context->width;
+}
+
+static uint32_t color_source_getheight(void *data)
+{
+	struct color_source *context = data;
+	return context->height;
+}
+
+static void color_source_defaults(obs_data_t *settings)
+{
+	obs_data_set_default_int(settings, "color", 0xFFFFFFFF);
+	obs_data_set_default_int(settings, "width", 400);
+	obs_data_set_default_int(settings, "height", 400);
+}
+
+struct obs_source_info color_source_info = {
+	.id             = "color_source",
+	.type           = OBS_SOURCE_TYPE_INPUT,
+	.output_flags   = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW,
+	.create         = color_source_create,
+	.destroy        = color_source_destroy,
+	.update         = color_source_update,
+	.get_name       = color_source_get_name,
+	.get_defaults   = color_source_defaults,
+	.get_width      = color_source_getwidth,
+	.get_height     = color_source_getheight,
+	.video_render   = color_source_render,
+	.get_properties = color_source_properties
+};
diff --git a/plugins/image-source/data/locale/ar-SA.ini b/plugins/image-source/data/locale/ar-SA.ini
index cba4b29..cac5ca7 100644
--- a/plugins/image-source/data/locale/ar-SA.ini
+++ b/plugins/image-source/data/locale/ar-SA.ini
@@ -3,3 +3,4 @@ File="ملف الصورة"
 UnloadWhenNotShowing="إلغاء تحميل الصورة إذا لم تظهر"
 
 
+
diff --git a/plugins/image-source/data/locale/bg-BG.ini b/plugins/image-source/data/locale/bg-BG.ini
index 05cd321..44df8ff 100644
--- a/plugins/image-source/data/locale/bg-BG.ini
+++ b/plugins/image-source/data/locale/bg-BG.ini
@@ -2,3 +2,4 @@ ImageInput="Изображение"
 File="Файл с изображение"
 
 
+
diff --git a/plugins/image-source/data/locale/ca-ES.ini b/plugins/image-source/data/locale/ca-ES.ini
index e476e39..0da2942 100644
--- a/plugins/image-source/data/locale/ca-ES.ini
+++ b/plugins/image-source/data/locale/ca-ES.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Desaparèixer"
 SlideShow.Transition.Swipe="De cop"
 SlideShow.Transition.Slide="Diapositiva"
 
+ColorSource="Origen del color"
+ColorSource.Color="Color"
+ColorSource.Width="Amplada"
+ColorSource.Height="Alçada"
+
diff --git a/plugins/image-source/data/locale/cs-CZ.ini b/plugins/image-source/data/locale/cs-CZ.ini
index bcb8f60..66415cf 100644
--- a/plugins/image-source/data/locale/cs-CZ.ini
+++ b/plugins/image-source/data/locale/cs-CZ.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Slábnutí"
 SlideShow.Transition.Swipe="Tažení"
 SlideShow.Transition.Slide="Sklouznutí"
 
+ColorSource="Zdroj barvy"
+ColorSource.Color="Barva"
+ColorSource.Width="Šířka"
+ColorSource.Height="Výška"
+
diff --git a/plugins/image-source/data/locale/da-DK.ini b/plugins/image-source/data/locale/da-DK.ini
index 6c988c3..4995f7e 100644
--- a/plugins/image-source/data/locale/da-DK.ini
+++ b/plugins/image-source/data/locale/da-DK.ini
@@ -13,3 +13,4 @@ SlideShow.Transition.Fade="Overgang"
 SlideShow.Transition.Swipe="Stryg"
 SlideShow.Transition.Slide="Glide"
 
+
diff --git a/plugins/image-source/data/locale/de-DE.ini b/plugins/image-source/data/locale/de-DE.ini
index 1336cb7..47c37da 100644
--- a/plugins/image-source/data/locale/de-DE.ini
+++ b/plugins/image-source/data/locale/de-DE.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Ãœberblenden"
 SlideShow.Transition.Swipe="Swipe"
 SlideShow.Transition.Slide="Slide"
 
+ColorSource="Farbquelle"
+ColorSource.Color="Farbe"
+ColorSource.Width="Breite"
+ColorSource.Height="Höhe"
+
diff --git a/plugins/image-source/data/locale/el-GR.ini b/plugins/image-source/data/locale/el-GR.ini
index dd23c11..8d260a9 100644
--- a/plugins/image-source/data/locale/el-GR.ini
+++ b/plugins/image-source/data/locale/el-GR.ini
@@ -2,4 +2,6 @@ ImageInput="Εικόνα"
 File="Αρχείο εικόνας"
 UnloadWhenNotShowing="Ξεφόρτωση εικόνας όταν δεν εμφανίζεται"
 
+SlideShow.Files="Αρχεία φωτογραφίας"
+
 
diff --git a/plugins/image-source/data/locale/en-US.ini b/plugins/image-source/data/locale/en-US.ini
index eb5ab61..afec159 100644
--- a/plugins/image-source/data/locale/en-US.ini
+++ b/plugins/image-source/data/locale/en-US.ini
@@ -12,3 +12,8 @@ SlideShow.Transition.Cut="Cut"
 SlideShow.Transition.Fade="Fade"
 SlideShow.Transition.Swipe="Swipe"
 SlideShow.Transition.Slide="Slide"
+
+ColorSource="Color Source"
+ColorSource.Color="Color"
+ColorSource.Width="Width"
+ColorSource.Height="Height"
diff --git a/plugins/image-source/data/locale/es-ES.ini b/plugins/image-source/data/locale/es-ES.ini
index d5756b2..2bd466d 100644
--- a/plugins/image-source/data/locale/es-ES.ini
+++ b/plugins/image-source/data/locale/es-ES.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Desvanecimiento"
 SlideShow.Transition.Swipe="Deslizar Rapido"
 SlideShow.Transition.Slide="Deslizar"
 
+ColorSource="Origen de color"
+ColorSource.Color="Color"
+ColorSource.Width="Ancho"
+ColorSource.Height="Alto"
+
diff --git a/plugins/image-source/data/locale/et-EE.ini b/plugins/image-source/data/locale/et-EE.ini
new file mode 100644
index 0000000..e4b1792
--- /dev/null
+++ b/plugins/image-source/data/locale/et-EE.ini
@@ -0,0 +1,20 @@
+ImageInput="Pilt"
+File="Pildifail"
+UnloadWhenNotShowing="Laadi maha pilt kui ei ole nähtav"
+
+SlideShow="Piltide slaidiesitus"
+SlideShow.TransitionSpeed="Ãœlemineku kiirus (millisekundites)"
+SlideShow.SlideTime="Aeg slaidide vahel (millisekundites)"
+SlideShow.Files="Pildifailid"
+SlideShow.Randomize="Juhuslik taasesitus"
+SlideShow.Transition="Ãœleminek"
+SlideShow.Transition.Cut="Ilmuv"
+SlideShow.Transition.Fade="Hajuv"
+SlideShow.Transition.Swipe="Pühkiv"
+SlideShow.Transition.Slide="Sisselendav"
+
+ColorSource="Värvi allikas"
+ColorSource.Color="Värv"
+ColorSource.Width="Laius"
+ColorSource.Height="Kõrgus"
+
diff --git a/plugins/image-source/data/locale/eu-ES.ini b/plugins/image-source/data/locale/eu-ES.ini
index 725fd53..0e7f773 100644
--- a/plugins/image-source/data/locale/eu-ES.ini
+++ b/plugins/image-source/data/locale/eu-ES.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Iraungi"
 SlideShow.Transition.Swipe="Korritu"
 SlideShow.Transition.Slide="Irristatu"
 
+ColorSource="Kolorearen iturburua"
+ColorSource.Color="Kolorea"
+ColorSource.Width="Zabalera"
+ColorSource.Height="Altuera"
+
diff --git a/plugins/image-source/data/locale/fi-FI.ini b/plugins/image-source/data/locale/fi-FI.ini
index 3ccfcd7..fc989cf 100644
--- a/plugins/image-source/data/locale/fi-FI.ini
+++ b/plugins/image-source/data/locale/fi-FI.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Häivytä"
 SlideShow.Transition.Swipe="Pyyhkäise"
 SlideShow.Transition.Slide="Liu'uta"
 
+ColorSource="Värilähde"
+ColorSource.Color="Väri"
+ColorSource.Width="Leveys"
+ColorSource.Height="Korkeus"
+
diff --git a/plugins/image-source/data/locale/fr-FR.ini b/plugins/image-source/data/locale/fr-FR.ini
index c7f2b10..ba2b10b 100644
--- a/plugins/image-source/data/locale/fr-FR.ini
+++ b/plugins/image-source/data/locale/fr-FR.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Fondu"
 SlideShow.Transition.Swipe="Balayage"
 SlideShow.Transition.Slide="Glissement"
 
+ColorSource="Source de couleur"
+ColorSource.Color="Couleur"
+ColorSource.Width="Largeur"
+ColorSource.Height="Hauteur"
+
diff --git a/plugins/image-source/data/locale/gl-ES.ini b/plugins/image-source/data/locale/gl-ES.ini
index e197c31..5afd1f9 100644
--- a/plugins/image-source/data/locale/gl-ES.ini
+++ b/plugins/image-source/data/locale/gl-ES.ini
@@ -3,3 +3,4 @@ File="Ficheiro de imaxe"
 UnloadWhenNotShowing="Non descargar a imaxe cando non se mostre"
 
 
+
diff --git a/plugins/image-source/data/locale/he-IL.ini b/plugins/image-source/data/locale/he-IL.ini
index f482eba..c426b6d 100644
--- a/plugins/image-source/data/locale/he-IL.ini
+++ b/plugins/image-source/data/locale/he-IL.ini
@@ -13,3 +13,4 @@ SlideShow.Transition.Fade="עמעום"
 SlideShow.Transition.Swipe="החלקה"
 SlideShow.Transition.Slide="הסט"
 
+
diff --git a/plugins/image-source/data/locale/hr-HR.ini b/plugins/image-source/data/locale/hr-HR.ini
index 1a64603..579ba01 100644
--- a/plugins/image-source/data/locale/hr-HR.ini
+++ b/plugins/image-source/data/locale/hr-HR.ini
@@ -13,3 +13,4 @@ SlideShow.Transition.Fade="Zatamnjenje"
 SlideShow.Transition.Swipe="Prevlačenje"
 SlideShow.Transition.Slide="Klizanje"
 
+
diff --git a/plugins/image-source/data/locale/hu-HU.ini b/plugins/image-source/data/locale/hu-HU.ini
index 7bf84f2..0f84dcc 100644
--- a/plugins/image-source/data/locale/hu-HU.ini
+++ b/plugins/image-source/data/locale/hu-HU.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Áttűnés"
 SlideShow.Transition.Swipe="Lapozás"
 SlideShow.Transition.Slide="Csúsztatás"
 
+ColorSource="Színforrás"
+ColorSource.Color="Szín"
+ColorSource.Width="Szélesség"
+ColorSource.Height="Magasság"
+
diff --git a/plugins/image-source/data/locale/it-IT.ini b/plugins/image-source/data/locale/it-IT.ini
index 8824432..76be183 100644
--- a/plugins/image-source/data/locale/it-IT.ini
+++ b/plugins/image-source/data/locale/it-IT.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Dissolvenza"
 SlideShow.Transition.Swipe="Scorri"
 SlideShow.Transition.Slide="Scivola"
 
+ColorSource="Origine del colore"
+ColorSource.Color="Colore"
+ColorSource.Width="Larghezza"
+ColorSource.Height="Altezza"
+
diff --git a/plugins/image-source/data/locale/ja-JP.ini b/plugins/image-source/data/locale/ja-JP.ini
index 4fa9b81..5392d81 100644
--- a/plugins/image-source/data/locale/ja-JP.ini
+++ b/plugins/image-source/data/locale/ja-JP.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="フェード"
 SlideShow.Transition.Swipe="スワイプ"
 SlideShow.Transition.Slide="スライド"
 
+ColorSource="色ソース"
+ColorSource.Color="色"
+ColorSource.Width="å¹…"
+ColorSource.Height="高さ"
+
diff --git a/plugins/image-source/data/locale/ko-KR.ini b/plugins/image-source/data/locale/ko-KR.ini
index 47145cb..f73bb20 100644
--- a/plugins/image-source/data/locale/ko-KR.ini
+++ b/plugins/image-source/data/locale/ko-KR.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="서서히 사라지기"
 SlideShow.Transition.Swipe="밀어내기"
 SlideShow.Transition.Slide="슬라이드"
 
+ColorSource="색상 소스"
+ColorSource.Color="색상"
+ColorSource.Width="너비"
+ColorSource.Height="높이"
+
diff --git a/plugins/image-source/data/locale/ms-MY.ini b/plugins/image-source/data/locale/ms-MY.ini
new file mode 100644
index 0000000..da5fa8c
--- /dev/null
+++ b/plugins/image-source/data/locale/ms-MY.ini
@@ -0,0 +1,16 @@
+ImageInput="Imej"
+File="Fail Imej"
+UnloadWhenNotShowing="Nyahmuatkan imej apabila tidak ditunjukkan"
+
+SlideShow="Tayangan Slaid Imej"
+SlideShow.TransitionSpeed="Kelajuan Peralihan (milisaat)"
+SlideShow.SlideTime="Masa Antara Slaid (milisaat)"
+SlideShow.Files="Fail-fail Imej"
+SlideShow.Randomize="Rawakkan Main balik"
+SlideShow.Transition="Peralihan"
+SlideShow.Transition.Cut="Potong"
+SlideShow.Transition.Fade="Pudar"
+SlideShow.Transition.Swipe="Sapu"
+SlideShow.Transition.Slide="Slaid"
+
+
diff --git a/plugins/image-source/data/locale/nb-NO.ini b/plugins/image-source/data/locale/nb-NO.ini
index 4f5f101..1d66ae0 100644
--- a/plugins/image-source/data/locale/nb-NO.ini
+++ b/plugins/image-source/data/locale/nb-NO.ini
@@ -13,3 +13,4 @@ SlideShow.Transition.Fade="Forløpning"
 SlideShow.Transition.Swipe="Sveip"
 SlideShow.Transition.Slide="Skyv"
 
+
diff --git a/plugins/image-source/data/locale/nl-NL.ini b/plugins/image-source/data/locale/nl-NL.ini
index 282474b..89aa6be 100644
--- a/plugins/image-source/data/locale/nl-NL.ini
+++ b/plugins/image-source/data/locale/nl-NL.ini
@@ -13,3 +13,4 @@ SlideShow.Transition.Fade="Vervagen"
 SlideShow.Transition.Swipe="Vegen"
 SlideShow.Transition.Slide="Slide"
 
+
diff --git a/plugins/image-source/data/locale/pl-PL.ini b/plugins/image-source/data/locale/pl-PL.ini
index 61ba68a..27c1a8d 100644
--- a/plugins/image-source/data/locale/pl-PL.ini
+++ b/plugins/image-source/data/locale/pl-PL.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Zanikanie"
 SlideShow.Transition.Swipe="Przeciągnięcie"
 SlideShow.Transition.Slide="Przesunięcie"
 
+ColorSource="Kolor"
+ColorSource.Color="Kolor"
+ColorSource.Width="Szerokość"
+ColorSource.Height="Wysokość"
+
diff --git a/plugins/image-source/data/locale/pt-BR.ini b/plugins/image-source/data/locale/pt-BR.ini
index 570fbdc..acfbe7e 100644
--- a/plugins/image-source/data/locale/pt-BR.ini
+++ b/plugins/image-source/data/locale/pt-BR.ini
@@ -13,3 +13,4 @@ SlideShow.Transition.Fade="Esmaecer"
 SlideShow.Transition.Swipe="Arrastar"
 SlideShow.Transition.Slide="Deslizar"
 
+
diff --git a/plugins/image-source/data/locale/pt-PT.ini b/plugins/image-source/data/locale/pt-PT.ini
index 6ae3cb7..01eec59 100644
--- a/plugins/image-source/data/locale/pt-PT.ini
+++ b/plugins/image-source/data/locale/pt-PT.ini
@@ -13,3 +13,4 @@ SlideShow.Transition.Fade="Desvanecer"
 SlideShow.Transition.Swipe="Deslizar"
 SlideShow.Transition.Slide="Deslize"
 
+
diff --git a/plugins/image-source/data/locale/ro-RO.ini b/plugins/image-source/data/locale/ro-RO.ini
index 0a262c9..64afe87 100644
--- a/plugins/image-source/data/locale/ro-RO.ini
+++ b/plugins/image-source/data/locale/ro-RO.ini
@@ -2,4 +2,11 @@ ImageInput="Imagine"
 File="Fișier imagine"
 UnloadWhenNotShowing="Eliberează din memorie imaginea când nu este afișată"
 
+SlideShow="Slide Show de imagini"
+SlideShow.TransitionSpeed="Viteza de tranziție (milisecunde)"
+SlideShow.SlideTime="Timpul dintre diapozitive (milisecunde)"
+SlideShow.Transition="Tranziție"
+SlideShow.Transition.Cut="Decupare"
+SlideShow.Transition.Slide="Diapozitiv"
+
 
diff --git a/plugins/image-source/data/locale/ru-RU.ini b/plugins/image-source/data/locale/ru-RU.ini
index 562e412..c9a257b 100644
--- a/plugins/image-source/data/locale/ru-RU.ini
+++ b/plugins/image-source/data/locale/ru-RU.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Затухание"
 SlideShow.Transition.Swipe="Перемещение"
 SlideShow.Transition.Slide="Сдвиг"
 
+ColorSource="Фоновый цвет"
+ColorSource.Color="Цвет"
+ColorSource.Width="Ширина"
+ColorSource.Height="Высота"
+
diff --git a/plugins/image-source/data/locale/sk-SK.ini b/plugins/image-source/data/locale/sk-SK.ini
index e735524..96d90d6 100644
--- a/plugins/image-source/data/locale/sk-SK.ini
+++ b/plugins/image-source/data/locale/sk-SK.ini
@@ -2,4 +2,15 @@ ImageInput="Obrázok"
 File="Súbor s obrázkom"
 UnloadWhenNotShowing="Uvoľniť obrázok, ak nie je zobrazený"
 
+SlideShow="Prezentácia obrázkov"
+SlideShow.TransitionSpeed="Rýchlosť prechodu (v milisekundách)"
+SlideShow.SlideTime="Čas medzi snímkami (v milisekundách)"
+SlideShow.Files="Obrázky"
+SlideShow.Randomize="Náhodné prehrávanie"
+SlideShow.Transition="Prechod"
+SlideShow.Transition.Cut="Strih"
+SlideShow.Transition.Fade="Miznutie"
+SlideShow.Transition.Swipe="Potiahnite"
+SlideShow.Transition.Slide="Posunutie"
+
 
diff --git a/plugins/image-source/data/locale/sl-SI.ini b/plugins/image-source/data/locale/sl-SI.ini
index 1c579f1..e3f71a3 100644
--- a/plugins/image-source/data/locale/sl-SI.ini
+++ b/plugins/image-source/data/locale/sl-SI.ini
@@ -3,3 +3,4 @@ File="Slikovna datoteka"
 UnloadWhenNotShowing="Ne naloži slike, ko ni prikazana"
 
 
+
diff --git a/plugins/image-source/data/locale/sr-CS.ini b/plugins/image-source/data/locale/sr-CS.ini
index 1a64603..579ba01 100644
--- a/plugins/image-source/data/locale/sr-CS.ini
+++ b/plugins/image-source/data/locale/sr-CS.ini
@@ -13,3 +13,4 @@ SlideShow.Transition.Fade="Zatamnjenje"
 SlideShow.Transition.Swipe="Prevlačenje"
 SlideShow.Transition.Slide="Klizanje"
 
+
diff --git a/plugins/image-source/data/locale/sr-SP.ini b/plugins/image-source/data/locale/sr-SP.ini
index 46d20e8..1101941 100644
--- a/plugins/image-source/data/locale/sr-SP.ini
+++ b/plugins/image-source/data/locale/sr-SP.ini
@@ -13,3 +13,4 @@ SlideShow.Transition.Fade="Затамњење"
 SlideShow.Transition.Swipe="Превлачење"
 SlideShow.Transition.Slide="Клизање"
 
+
diff --git a/plugins/image-source/data/locale/sv-SE.ini b/plugins/image-source/data/locale/sv-SE.ini
index edd84ab..73c09b7 100644
--- a/plugins/image-source/data/locale/sv-SE.ini
+++ b/plugins/image-source/data/locale/sv-SE.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Tona"
 SlideShow.Transition.Swipe="Svep"
 SlideShow.Transition.Slide="Glid"
 
+ColorSource="Färgkälla"
+ColorSource.Color="Färg"
+ColorSource.Width="Bredd"
+ColorSource.Height="Höjd"
+
diff --git a/plugins/image-source/data/locale/th-TH.ini b/plugins/image-source/data/locale/th-TH.ini
index b2c3514..1af55f7 100644
--- a/plugins/image-source/data/locale/th-TH.ini
+++ b/plugins/image-source/data/locale/th-TH.ini
@@ -2,3 +2,4 @@ ImageInput="รูปภาพ"
 File="ไฟล์รูปภาพ"
 
 
+
diff --git a/plugins/image-source/data/locale/tr-TR.ini b/plugins/image-source/data/locale/tr-TR.ini
index d5ef434..e99d115 100644
--- a/plugins/image-source/data/locale/tr-TR.ini
+++ b/plugins/image-source/data/locale/tr-TR.ini
@@ -1,5 +1,20 @@
 ImageInput="Görüntü"
 File="Görüntü Dosyası"
-UnloadWhenNotShowing="Resim gösterilmediğinde bellekten kaldır"
+UnloadWhenNotShowing="Görüntü gösterilmediğinde bellekten kaldır"
 
+SlideShow="Resim Slayt Gösterisi"
+SlideShow.TransitionSpeed="Geçiş Hızı (milisaniye)"
+SlideShow.SlideTime="Slaytlar Arası Süre (milisaniye)"
+SlideShow.Files="Görüntü Dosyaları"
+SlideShow.Randomize="Rastgele Gösterim"
+SlideShow.Transition="Geçiş"
+SlideShow.Transition.Cut="Cut"
+SlideShow.Transition.Fade="Fade"
+SlideShow.Transition.Swipe="Swipe"
+SlideShow.Transition.Slide="Slide"
+
+ColorSource="Renk Kaynağı"
+ColorSource.Color="Renk"
+ColorSource.Width="GeniÅŸlik"
+ColorSource.Height="Yükseklik"
 
diff --git a/plugins/image-source/data/locale/uk-UA.ini b/plugins/image-source/data/locale/uk-UA.ini
index 28af61c..870f96a 100644
--- a/plugins/image-source/data/locale/uk-UA.ini
+++ b/plugins/image-source/data/locale/uk-UA.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="Fade"
 SlideShow.Transition.Swipe="Swipe"
 SlideShow.Transition.Slide="Slide"
 
+ColorSource="Щільний колір"
+ColorSource.Color="Колір"
+ColorSource.Width="Ширина"
+ColorSource.Height="Висота"
+
diff --git a/plugins/image-source/data/locale/zh-CN.ini b/plugins/image-source/data/locale/zh-CN.ini
index 14946c0..b9dae01 100644
--- a/plugins/image-source/data/locale/zh-CN.ini
+++ b/plugins/image-source/data/locale/zh-CN.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="淡出"
 SlideShow.Transition.Swipe="滑动"
 SlideShow.Transition.Slide="幻灯片"
 
+ColorSource="色源"
+ColorSource.Color="色彩"
+ColorSource.Width="宽度"
+ColorSource.Height="高度"
+
diff --git a/plugins/image-source/data/locale/zh-TW.ini b/plugins/image-source/data/locale/zh-TW.ini
index 6c40828..b56eaa2 100644
--- a/plugins/image-source/data/locale/zh-TW.ini
+++ b/plugins/image-source/data/locale/zh-TW.ini
@@ -13,3 +13,8 @@ SlideShow.Transition.Fade="淡入淡出"
 SlideShow.Transition.Swipe="滑出"
 SlideShow.Transition.Slide="推出"
 
+ColorSource="色彩來源"
+ColorSource.Color="色彩"
+ColorSource.Width="寬度"
+ColorSource.Height="高度"
+
diff --git a/plugins/image-source/image-source.c b/plugins/image-source/image-source.c
index 5986edd..ed87504 100644
--- a/plugins/image-source/image-source.c
+++ b/plugins/image-source/image-source.c
@@ -151,7 +151,6 @@ static void image_source_render(void *data, gs_effect_t *effect)
 	if (!context->image.texture)
 		return;
 
-	gs_reset_blend_state();
 	gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"),
 			context->image.texture);
 	gs_draw_sprite(context->image.texture, 0,
@@ -271,10 +270,12 @@ OBS_DECLARE_MODULE()
 OBS_MODULE_USE_DEFAULT_LOCALE("image-source", "en-US")
 
 extern struct obs_source_info slideshow_info;
+extern struct obs_source_info color_source_info;
 
 bool obs_module_load(void)
 {
 	obs_register_source(&image_source_info);
+	obs_register_source(&color_source_info);
 	obs_register_source(&slideshow_info);
 	return true;
 }
diff --git a/plugins/linux-alsa/data/locale/et-EE.ini b/plugins/linux-alsa/data/locale/et-EE.ini
new file mode 100644
index 0000000..d7fb74b
--- /dev/null
+++ b/plugins/linux-alsa/data/locale/et-EE.ini
@@ -0,0 +1,3 @@
+AlsaInput="Helihõive seade (ALSA)"
+Device="Seade"
+
diff --git a/plugins/linux-alsa/data/locale/sk-SK.ini b/plugins/linux-alsa/data/locale/sk-SK.ini
new file mode 100644
index 0000000..19b6455
--- /dev/null
+++ b/plugins/linux-alsa/data/locale/sk-SK.ini
@@ -0,0 +1,3 @@
+AlsaInput="Zariadenie na záznam zvuku (ALSA)"
+Device="Zariadenie"
+
diff --git a/plugins/linux-alsa/data/locale/vi-VN.ini b/plugins/linux-alsa/data/locale/vi-VN.ini
new file mode 100644
index 0000000..77e8a16
--- /dev/null
+++ b/plugins/linux-alsa/data/locale/vi-VN.ini
@@ -0,0 +1,3 @@
+AlsaInput="Thiết bị thu âm thanh (ALSA)"
+Device="Thiết bị"
+
diff --git a/plugins/linux-capture/data/locale/et-EE.ini b/plugins/linux-capture/data/locale/et-EE.ini
new file mode 100644
index 0000000..c9d3cc7
--- /dev/null
+++ b/plugins/linux-capture/data/locale/et-EE.ini
@@ -0,0 +1,15 @@
+X11SharedMemoryScreenInput="Ekraani hõive (XSHM)"
+Screen="Ekraan"
+CaptureCursor="Jäädvusta kursor"
+AdvancedSettings="Täpsemad sätted"
+XServer="X Server"
+XCCapture="Akna hõive (Xcomposite)"
+Window="Aken"
+CropTop="Kärbi ülevalt (pikslit)"
+CropLeft="Kärbi vasakult (pikslit)"
+CropRight="Kärbi paremalt (pikslit)"
+CropBottom="Kärbi alt (pikslit)"
+SwapRedBlue="Vaheta punane ja sinine"
+LockX="Lukusta X server salvestamise ajal"
+IncludeXBorder="Kaasa X piirjoon"
+
diff --git a/plugins/linux-capture/data/locale/sk-SK.ini b/plugins/linux-capture/data/locale/sk-SK.ini
index d68555b..5cc60c7 100644
--- a/plugins/linux-capture/data/locale/sk-SK.ini
+++ b/plugins/linux-capture/data/locale/sk-SK.ini
@@ -2,6 +2,7 @@ X11SharedMemoryScreenInput="Zachytávanie monitora (XSHM)"
 Screen="Monitor"
 CaptureCursor="Zachytávať kurzor"
 AdvancedSettings="Rozšírené nastavenia"
+XServer="X Server"
 XCCapture="Zachytávanie okna (Xcomposite)"
 Window="Okno"
 CropTop="Orezanie hore (pixely)"
@@ -10,4 +11,5 @@ CropRight="Orezanie vpravo (pixely)"
 CropBottom="Orezanie dole (pixely)"
 SwapRedBlue="Vymeniť červenú a modrú"
 LockX="Zamknúť X server počas snímania"
+IncludeXBorder="Zahŕňajú X okraj"
 
diff --git a/plugins/linux-capture/data/locale/sv-SE.ini b/plugins/linux-capture/data/locale/sv-SE.ini
index 406b10f..688168a 100644
--- a/plugins/linux-capture/data/locale/sv-SE.ini
+++ b/plugins/linux-capture/data/locale/sv-SE.ini
@@ -12,4 +12,5 @@ CropBottom="Beskär nedre kant (pixlar)"
 SwapRedBlue="Byt röd och blå"
 LockX="Lås X-servern medan källan är aktiv"
 IncludeXBorder="Inkludera X Border"
+ExcludeAlpha="Använd alfalöst texturformat (lösning för Mesa)"
 
diff --git a/plugins/linux-capture/data/locale/tr-TR.ini b/plugins/linux-capture/data/locale/tr-TR.ini
index 36b4c5a..6534cf7 100644
--- a/plugins/linux-capture/data/locale/tr-TR.ini
+++ b/plugins/linux-capture/data/locale/tr-TR.ini
@@ -12,4 +12,5 @@ CropBottom="Alttan Kırp (piksel)"
 SwapRedBlue="Kırmızı ve maviyi değiştir"
 LockX="Yakalama sırasında X sunucusunu kilitle"
 IncludeXBorder="X Çerçevesini Dahil Et"
+ExcludeAlpha="Alpha kanalı olmayan doku biçimi kullan (Mesa geçici çözüm)"
 
diff --git a/plugins/linux-capture/data/locale/vi-VN.ini b/plugins/linux-capture/data/locale/vi-VN.ini
new file mode 100644
index 0000000..484d009
--- /dev/null
+++ b/plugins/linux-capture/data/locale/vi-VN.ini
@@ -0,0 +1,16 @@
+X11SharedMemoryScreenInput="Quay màn hỉnh (XSHM)"
+Screen="Màn hình"
+CaptureCursor="Quay cả con trỏ"
+AdvancedSettings="Cài đặt nâng cao"
+XServer="X Server"
+XCCapture="Quay cửa sổ (Xcomposite)"
+Window="Cửa sổ"
+CropTop="Cắt bên trên (pixels)"
+CropLeft="Cắt bên trái (pixels)"
+CropRight="Cắt bên phải (pixels)"
+CropBottom="Cắt bên dưới (pixels)"
+SwapRedBlue="Đổi đỏ và xanh"
+LockX="Khóa X server khi quay"
+IncludeXBorder="Bao gồm X Border"
+ExcludeAlpha="Dùng texture format không có Alpha (Cách giải quyết với Mesa driver)"
+
diff --git a/plugins/linux-jack/data/locale/et-EE.ini b/plugins/linux-jack/data/locale/et-EE.ini
new file mode 100644
index 0000000..fa6c047
--- /dev/null
+++ b/plugins/linux-jack/data/locale/et-EE.ini
@@ -0,0 +1,4 @@
+StartJACKServer="Käivita JACK server"
+Channels="Kanalite arv"
+JACKInput="JACK sisend klient"
+
diff --git a/plugins/linux-jack/data/locale/vi-VN.ini b/plugins/linux-jack/data/locale/vi-VN.ini
new file mode 100644
index 0000000..11d5f2a
--- /dev/null
+++ b/plugins/linux-jack/data/locale/vi-VN.ini
@@ -0,0 +1,3 @@
+StartJACKServer="Bắt đầu JACK server"
+Channels="Số lượng các kênh"
+
diff --git a/plugins/linux-pulseaudio/data/locale/et-EE.ini b/plugins/linux-pulseaudio/data/locale/et-EE.ini
new file mode 100644
index 0000000..7a17b5f
--- /dev/null
+++ b/plugins/linux-pulseaudio/data/locale/et-EE.ini
@@ -0,0 +1,4 @@
+PulseInput="Helisisendi hõive (PulseAudio)"
+PulseOutput="Heliväljundi hõive (PulseAudio)"
+Device="Seade"
+
diff --git a/plugins/linux-pulseaudio/pulse-input.c b/plugins/linux-pulseaudio/pulse-input.c
index 463e0c2..26a44fc 100644
--- a/plugins/linux-pulseaudio/pulse-input.c
+++ b/plugins/linux-pulseaudio/pulse-input.c
@@ -537,7 +537,8 @@ struct obs_source_info pulse_output_capture = {
 	.id             = "pulse_output_capture",
 	.type           = OBS_SOURCE_TYPE_INPUT,
 	.output_flags   = OBS_SOURCE_AUDIO |
-	                  OBS_SOURCE_DO_NOT_DUPLICATE,
+	                  OBS_SOURCE_DO_NOT_DUPLICATE |
+	                  OBS_SOURCE_DO_NOT_MONITOR,
 	.get_name       = pulse_output_getname,
 	.create         = pulse_create,
 	.destroy        = pulse_destroy,
diff --git a/plugins/linux-v4l2/data/locale/et-EE.ini b/plugins/linux-v4l2/data/locale/et-EE.ini
new file mode 100644
index 0000000..82f570d
--- /dev/null
+++ b/plugins/linux-v4l2/data/locale/et-EE.ini
@@ -0,0 +1,11 @@
+V4L2Input="Videohõive seade (V4L2)"
+Device="Seade"
+Input="Sisend"
+VideoFormat="Video formaat"
+VideoStandard="Video standard"
+DVTiming="DV ajastus"
+Resolution="Resolutsioon"
+FrameRate="Kaadrisagedus"
+LeaveUnchanged="Jäta muutmata"
+UseBuffering="Kasuta puhverdamist"
+
diff --git a/plugins/mac-avcapture/data/locale/da-DK.ini b/plugins/mac-avcapture/data/locale/da-DK.ini
index f1eff88..921fb01 100644
--- a/plugins/mac-avcapture/data/locale/da-DK.ini
+++ b/plugins/mac-avcapture/data/locale/da-DK.ini
@@ -6,6 +6,7 @@ Buffering="Brug buffering"
 FrameRate="Billedfrekvens"
 InputFormat="Input format"
 ColorSpace="Farverum"
+VideoRange="Videoudstrækning"
 VideoRange.Partial="Delvis"
 VideoRange.Full="Fuld"
 Auto="Auto"
diff --git a/plugins/mac-avcapture/data/locale/et-EE.ini b/plugins/mac-avcapture/data/locale/et-EE.ini
new file mode 100644
index 0000000..ebeffc1
--- /dev/null
+++ b/plugins/mac-avcapture/data/locale/et-EE.ini
@@ -0,0 +1,14 @@
+AVCapture="Videohõive seade"
+Device="Seade"
+UsePreset="Kasuta eelseadistust"
+Preset="Eelseadistus"
+Buffering="Kasuta puhverdamist"
+FrameRate="Kaadrisagedus"
+InputFormat="Sisestus formaat"
+ColorSpace="Värviruum"
+VideoRange="Video vahemik"
+VideoRange.Partial="Osaliselt"
+VideoRange.Full="Täielik"
+Auto="Automaatne"
+Unknown="Teadmata ($1)"
+
diff --git a/plugins/mac-avcapture/data/locale/sk-SK.ini b/plugins/mac-avcapture/data/locale/sk-SK.ini
index 9437865..67b8d7a 100644
--- a/plugins/mac-avcapture/data/locale/sk-SK.ini
+++ b/plugins/mac-avcapture/data/locale/sk-SK.ini
@@ -3,4 +3,9 @@ Device="Zariadenie"
 UsePreset="Použiť prednastavené"
 Preset="Predvoľba"
 Buffering="Použiť vyrovnávaciu pamäť"
+FrameRate="Snímkovacia frekvencia"
+InputFormat="Vstupný formát"
+VideoRange.Full="Úplný"
+Auto="Automaticky"
+Unknown="Neznámy ($1)"
 
diff --git a/plugins/mac-avcapture/data/locale/tr-TR.ini b/plugins/mac-avcapture/data/locale/tr-TR.ini
index 5cf8767..ac8166d 100644
--- a/plugins/mac-avcapture/data/locale/tr-TR.ini
+++ b/plugins/mac-avcapture/data/locale/tr-TR.ini
@@ -4,6 +4,7 @@ UsePreset="Ön Tanımlı Kullan"
 Preset="Ön Tanımlı"
 Buffering="Arabelleğe Almayı Kullan"
 FrameRate="Kare hızı"
+InputFormat="Giriş biçimi"
 ColorSpace="Renk alanı"
 VideoRange="Video aralığı"
 VideoRange.Partial="Kısmi"
diff --git a/plugins/mac-capture/data/locale/et-EE.ini b/plugins/mac-capture/data/locale/et-EE.ini
new file mode 100644
index 0000000..1b7bc4c
--- /dev/null
+++ b/plugins/mac-capture/data/locale/et-EE.ini
@@ -0,0 +1,19 @@
+CoreAudio.InputCapture="Helisisendi hõive"
+CoreAudio.OutputCapture="Heliväljundi hõive"
+CoreAudio.Device="Seade"
+CoreAudio.Device.Default="Vaikeseade"
+DisplayCapture="Kuvari hõive"
+DisplayCapture.Display="Kuvar"
+DisplayCapture.ShowCursor="Näita kursorit"
+WindowCapture="Akna hõive"
+WindowCapture.ShowShadow="Näita akna varju"
+WindowUtils.Window="Aken"
+WindowUtils.ShowEmptyNames="Kuva nimetuid aknaid"
+CropMode="Kärbi"
+CropMode.None="Pole"
+CropMode.Manual="Manuaalne"
+Crop.origin.x="Kärbi vasakult"
+Crop.origin.y="Kärbi ülevalt"
+Crop.size.width="Kärbi paremalt"
+Crop.size.height="Kärbi alt"
+
diff --git a/plugins/mac-capture/data/locale/hu-HU.ini b/plugins/mac-capture/data/locale/hu-HU.ini
index b4420b4..ca42180 100644
--- a/plugins/mac-capture/data/locale/hu-HU.ini
+++ b/plugins/mac-capture/data/locale/hu-HU.ini
@@ -1,5 +1,5 @@
 CoreAudio.InputCapture="Bemeneti hangrögzítés"
-CoreAudio.OutputCapture="Kimeneti hangrögzítés"
+CoreAudio.OutputCapture="Kimeneti hangrögzítő"
 CoreAudio.Device="Eszköz"
 CoreAudio.Device.Default="Alapértelmezett"
 DisplayCapture="Kijelző felvétel"
diff --git a/plugins/mac-capture/data/locale/nl-NL.ini b/plugins/mac-capture/data/locale/nl-NL.ini
index 2c540af..1be3b06 100644
--- a/plugins/mac-capture/data/locale/nl-NL.ini
+++ b/plugins/mac-capture/data/locale/nl-NL.ini
@@ -1,5 +1,5 @@
-CoreAudio.InputCapture="Audioinvoer Capture"
-CoreAudio.OutputCapture="Audiouitvoer Capture"
+CoreAudio.InputCapture="Audioinvoer Opname"
+CoreAudio.OutputCapture="Audiouitvoer Opname"
 CoreAudio.Device="Apparaat"
 CoreAudio.Device.Default="Standaardinstellingen"
 DisplayCapture="Beeldschermcapture"
diff --git a/plugins/mac-capture/mac-audio.c b/plugins/mac-capture/mac-audio.c
index 6eba6fd..ed922d3 100644
--- a/plugins/mac-capture/mac-audio.c
+++ b/plugins/mac-capture/mac-audio.c
@@ -797,7 +797,8 @@ struct obs_source_info coreaudio_output_capture_info = {
 	.id             = "coreaudio_output_capture",
 	.type           = OBS_SOURCE_TYPE_INPUT,
 	.output_flags   = OBS_SOURCE_AUDIO |
-	                  OBS_SOURCE_DO_NOT_DUPLICATE,
+	                  OBS_SOURCE_DO_NOT_DUPLICATE |
+	                  OBS_SOURCE_DO_NOT_MONITOR,
 	.get_name       = coreaudio_output_getname,
 	.create         = coreaudio_create_output_capture,
 	.destroy        = coreaudio_destroy,
diff --git a/plugins/mac-syphon/data/locale/et-EE.ini b/plugins/mac-syphon/data/locale/et-EE.ini
new file mode 100644
index 0000000..456813f
--- /dev/null
+++ b/plugins/mac-syphon/data/locale/et-EE.ini
@@ -0,0 +1,13 @@
+Syphon="Mängu hõive (Syphon)"
+Source="Allikas"
+LaunchSyphonInject="Käivita SyphonInject"
+Inject="Sisesta"
+Application="Rakendus"
+SyphonLicense="Syphon litsentsi"
+Crop="Kärbi"
+Crop.origin.x="Kärbi vasakult"
+Crop.origin.y="Kärbi ülevalt"
+Crop.size.width="Kärbi paremalt"
+Crop.size.height="Kärbi alt"
+AllowTransparency="Luba läbipaistvus"
+
diff --git a/plugins/mac-syphon/data/locale/ms-MY.ini b/plugins/mac-syphon/data/locale/ms-MY.ini
new file mode 100644
index 0000000..009f81b
--- /dev/null
+++ b/plugins/mac-syphon/data/locale/ms-MY.ini
@@ -0,0 +1,6 @@
+Source="Sumber"
+LaunchSyphonInject="Lancarkan 'SyphonInject'"
+Application="Aplikasi"
+SyphonLicense="Lesen Syphon"
+AllowTransparency="Benarkan Ketelusan"
+
diff --git a/plugins/mac-syphon/data/locale/sk-SK.ini b/plugins/mac-syphon/data/locale/sk-SK.ini
index 0ded148..b714aa8 100644
--- a/plugins/mac-syphon/data/locale/sk-SK.ini
+++ b/plugins/mac-syphon/data/locale/sk-SK.ini
@@ -8,4 +8,5 @@ Crop.origin.x="Orezanie vľavo"
 Crop.origin.y="Orezanie hore"
 Crop.size.width="Orezanie vpravo"
 Crop.size.height="Orezanie dole"
+AllowTransparency="Povoliť transparentnosť"
 
diff --git a/plugins/mac-vth264/data/locale/da-DK.ini b/plugins/mac-vth264/data/locale/da-DK.ini
new file mode 100644
index 0000000..fbedef8
--- /dev/null
+++ b/plugins/mac-vth264/data/locale/da-DK.ini
@@ -0,0 +1,14 @@
+VTH264EncHW="Apple VT H264 Hardware Encoder"
+VTH264EncSW="Apple VT H264 Software Encoder"
+VTEncoder="VideoToolbox Encoder"
+Bitrate="Bit-hastighed"
+UseMaxBitrate="Begræns bit-hastighed"
+MaxBitrate="Maks. bit-hastighed"
+MaxBitrateWindow="Maks. bit-hastighedsvindue (sekunder)"
+KeyframeIntervalSec="Keyframe interval (sekunder, 0= auto)"
+Profile="Profil"
+None="(ingen)"
+DefaultEncoder="(Standard Encoder)"
+UseBFrames="Benyt B-frames"
+
+
diff --git a/plugins/mac-vth264/data/locale/de-DE.ini b/plugins/mac-vth264/data/locale/de-DE.ini
index 7463c30..b391d62 100644
--- a/plugins/mac-vth264/data/locale/de-DE.ini
+++ b/plugins/mac-vth264/data/locale/de-DE.ini
@@ -1,6 +1,6 @@
-VTH264EncHW="Apple VT H264 Hardware Encoder"
-VTH264EncSW="Apple VT H264 Software Encoder"
-VTEncoder="VideoToolbox Encoder"
+VTH264EncHW="Apple VT H264 Hardware Codierer"
+VTH264EncSW="Apple VT H264 Software Codierer"
+VTEncoder="VideoToolbox Codierer"
 Bitrate="Bitrate"
 UseMaxBitrate="Limitiere Bitrate"
 MaxBitrate="Maximale Bitrate"
@@ -8,7 +8,7 @@ MaxBitrateWindow="Maximale Bitrate Fenster (Sekunden)"
 KeyframeIntervalSec="Keyframeintervall (Sekunden, 0=auto)"
 Profile="Profil"
 None="(Nichts)"
-DefaultEncoder="(Standard-Encoder)"
+DefaultEncoder="(Standard-Codierer)"
 UseBFrames="B-Frames verwenden"
 
 
diff --git a/plugins/mac-vth264/data/locale/et-EE.ini b/plugins/mac-vth264/data/locale/et-EE.ini
new file mode 100644
index 0000000..d086781
--- /dev/null
+++ b/plugins/mac-vth264/data/locale/et-EE.ini
@@ -0,0 +1,12 @@
+VTH264EncHW="Apple VT H264 riistvara kodeerija"
+VTH264EncSW="Apple VT H264 tarkvara kodeerija"
+VTEncoder="VideoToolbox kodeerija"
+Bitrate="Bitikiirus"
+UseMaxBitrate="Piira bitikiirust"
+MaxBitrate="Maksimaalne bitikiirus"
+Profile="Profiil"
+None="(Määramata)"
+DefaultEncoder="(Vaikekodeering)"
+UseBFrames="Kasuta B-raame"
+
+
diff --git a/plugins/mac-vth264/data/locale/hu-HU.ini b/plugins/mac-vth264/data/locale/hu-HU.ini
index 9cf5d8c..611056f 100644
--- a/plugins/mac-vth264/data/locale/hu-HU.ini
+++ b/plugins/mac-vth264/data/locale/hu-HU.ini
@@ -1,10 +1,10 @@
 VTH264EncHW="Apple VT H264 hardveres kódoló"
 VTH264EncSW="Apple VT H264 szoftveres kódoló"
 VTEncoder="VideoToolbox H264 kódoló"
-Bitrate="Bitráta"
-UseMaxBitrate="Bitráta limit"
-MaxBitrate="Maximális bitráta"
-MaxBitrateWindow="Maximális bitrátaablak (másodperc)"
+Bitrate="Bitsebesség"
+UseMaxBitrate="Bitsebesség limit"
+MaxBitrate="Maximális bitsebesség"
+MaxBitrateWindow="Maximális bitsebességablak (másodperc)"
 KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)"
 Profile="Profil"
 None="(Nincs)"
diff --git a/plugins/mac-vth264/data/locale/ms-MY.ini b/plugins/mac-vth264/data/locale/ms-MY.ini
new file mode 100644
index 0000000..88648b2
--- /dev/null
+++ b/plugins/mac-vth264/data/locale/ms-MY.ini
@@ -0,0 +1,7 @@
+Bitrate="Nilai Bit"
+UseMaxBitrate="Had Nilai Bit"
+MaxBitrate="Nilai bit maksimum"
+None="(Tiada)"
+UseBFrames="Gunakan 'B-Frames'"
+
+
diff --git a/plugins/mac-vth264/data/locale/tr-TR.ini b/plugins/mac-vth264/data/locale/tr-TR.ini
index db89c21..83c022f 100644
--- a/plugins/mac-vth264/data/locale/tr-TR.ini
+++ b/plugins/mac-vth264/data/locale/tr-TR.ini
@@ -1,8 +1,13 @@
-Bitrate="Bithızı"
-MaxBitrate="Maks bit hızı"
-KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)"
+VTH264EncHW="Apple VT H264 Donanım Kodlayıcı"
+VTH264EncSW="Apple VT H264 Yazılım Kodlayıcı"
+VTEncoder="VideoToolbox Kodlayıcı"
+Bitrate="Bit hızı"
+UseMaxBitrate="Bit hızını sınırla"
+MaxBitrate="Maksimum bit hızı"
+KeyframeIntervalSec="Anahtar Kare Aralığı (saniye, 0=otomatik)"
 Profile="Profil"
 None="(Yok)"
 DefaultEncoder="(Varsayılan Kodlayıcı)"
+UseBFrames="B-Karelerini kullan"
 
 
diff --git a/plugins/mac-vth264/data/locale/vi-VN.ini b/plugins/mac-vth264/data/locale/vi-VN.ini
new file mode 100644
index 0000000..e21400c
--- /dev/null
+++ b/plugins/mac-vth264/data/locale/vi-VN.ini
@@ -0,0 +1,3 @@
+None="(Ingen)"
+
+
diff --git a/plugins/obs-ffmpeg/data/locale/ar-SA.ini b/plugins/obs-ffmpeg/data/locale/ar-SA.ini
index b7edd47..edb0781 100644
--- a/plugins/obs-ffmpeg/data/locale/ar-SA.ini
+++ b/plugins/obs-ffmpeg/data/locale/ar-SA.ini
@@ -3,6 +3,7 @@ FFmpegAAC="ترميز AAC الافتراضي لـFFmpeg"
 Bitrate="معدل النقل"
 Preset="الإعداد المسبق"
 
+
 NVENC.Preset.default="الإفتراضي"
 NVENC.Preset.hq="جودة عالية"
 NVENC.Preset.hp="أداء عالي"
@@ -25,3 +26,4 @@ MediaFileFilter.VideoFiles="ملفات الفيديو"
 MediaFileFilter.AudioFiles="ملفات الصوت"
 MediaFileFilter.AllFiles="‮كل الملفات"
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/bg-BG.ini b/plugins/obs-ffmpeg/data/locale/bg-BG.ini
index 10c4189..f4957f4 100644
--- a/plugins/obs-ffmpeg/data/locale/bg-BG.ini
+++ b/plugins/obs-ffmpeg/data/locale/bg-BG.ini
@@ -5,3 +5,5 @@ Bitrate="Битрейт"
 
 
 
+
+
diff --git a/plugins/obs-ffmpeg/data/locale/ca-ES.ini b/plugins/obs-ffmpeg/data/locale/ca-ES.ini
index 14ff28c..d7057ce 100644
--- a/plugins/obs-ffmpeg/data/locale/ca-ES.ini
+++ b/plugins/obs-ffmpeg/data/locale/ca-ES.ini
@@ -6,6 +6,8 @@ RateControl="Control de freqüència"
 KeyframeIntervalSec="Interval de fotograma clau (en segons, 0 = automàtic)"
 Lossless="Sense pèrdues"
 
+BFrames="B-frames"
+
 NVENC.Use2Pass="Utilitza codificació en dues passades"
 NVENC.Preset.default="Per defecte"
 NVENC.Preset.hq="Alta Qualitat"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Arxius de vídeo"
 MediaFileFilter.AudioFiles="Arxius d'àudio"
 MediaFileFilter.AllFiles="Tots els fitxers"
 
+ReplayBuffer="Memòria intermèdia de reproducció"
+ReplayBuffer.Save="Desa la repetició"
+
diff --git a/plugins/obs-ffmpeg/data/locale/cs-CZ.ini b/plugins/obs-ffmpeg/data/locale/cs-CZ.ini
index d06917f..ac3d601 100644
--- a/plugins/obs-ffmpeg/data/locale/cs-CZ.ini
+++ b/plugins/obs-ffmpeg/data/locale/cs-CZ.ini
@@ -6,6 +6,8 @@ RateControl="Řízení toku"
 KeyframeIntervalSec="Interval klíč. snímků (vteřiny, 0=auto)"
 Lossless="Lossless"
 
+BFrames="B-frames"
+
 NVENC.Use2Pass="Použít dvoustupňové enkódování"
 NVENC.Preset.default="Výchozí"
 NVENC.Preset.hq="Vysoká kvalita"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Video soubory"
 MediaFileFilter.AudioFiles="Zvukové soubory"
 MediaFileFilter.AllFiles="VÅ¡echny soubory"
 
+ReplayBuffer="Záznam do paměti"
+ReplayBuffer.Save="Uložit záznam"
+
diff --git a/plugins/obs-ffmpeg/data/locale/da-DK.ini b/plugins/obs-ffmpeg/data/locale/da-DK.ini
index 6c63f79..457e266 100644
--- a/plugins/obs-ffmpeg/data/locale/da-DK.ini
+++ b/plugins/obs-ffmpeg/data/locale/da-DK.ini
@@ -1,23 +1,54 @@
 FFmpegOutput="FFmpeg Output"
 FFmpegAAC="FFmpeg Standard AAC Encoder"
 Bitrate="Bitrate"
+Preset="Forudindstillet"
+RateControl="Tempokontrol"
+KeyframeIntervalSec="Keyframe-interval (sekunder, 0= auto)"
+Lossless="Tabsfri"
 
+BFrames="B-rammer"
+
+NVENC.Use2Pass="Benyt to-trins kodning"
+NVENC.Preset.default="Standard"
+NVENC.Preset.hq="Høj kvalitet"
+NVENC.Preset.hp="Høj ydeevne"
+NVENC.Preset.bd="BluRay"
+NVENC.Preset.ll="Lav latens"
+NVENC.Preset.llhq="Lav-latens høj kvalitet"
+NVENC.Preset.llhp="Lav latens høj ydeevne"
+NVENC.Level="Niveau"
 
 FFmpegSource="Mediekilde"
 LocalFile="Lokal fil"
 Looping="Gentagelse"
 Input="Input"
 InputFormat="Input format"
+ForceFormat="Gennemtving-formatkonvertering"
 HardwareDecode="Brug hardwareafkodning når tilgængelige"
 ClearOnMediaEnd="Skjul kilde når afspilning slutter"
 Advanced="Avanceret"
 AudioBufferSize="Audio bufferstørrelse (frames)"
 VideoBufferSize="Video bufferstørrelse (frames)"
+FrameDropping="Billedtabsniveau"
 DiscardNone="Ingen"
+DiscardDefault="Standard (ugyldige pakker)"
+DiscardNonRef="Ikke-reference billeder"
 DiscardBiDir="Tovejs frames"
 DiscardNonIntra="Non-Intra frames"
 DiscardNonKey="Non-Key Frames"
 DiscardAll="Alle frames (pas på!)"
+RestartWhenActivated="Genstart afspilning når kilde bliver aktiv"
+ColorRange="YUV-farveområde"
+ColorRange.Auto="Auto"
+ColorRange.Partial="Delvis"
+ColorRange.Full="Fuld"
+
 
+MediaFileFilter.AllMediaFiles="Alle mediefiler"
+MediaFileFilter.VideoFiles="Videofiler"
+MediaFileFilter.AudioFiles="Lydfiler"
+MediaFileFilter.AllFiles="Alle filer"
 
+ReplayBuffer="Genafspilningsbuffer"
+ReplayBuffer.Save="Gem Genafspilning"
 
diff --git a/plugins/obs-ffmpeg/data/locale/de-DE.ini b/plugins/obs-ffmpeg/data/locale/de-DE.ini
index cef2671..026d10d 100644
--- a/plugins/obs-ffmpeg/data/locale/de-DE.ini
+++ b/plugins/obs-ffmpeg/data/locale/de-DE.ini
@@ -1,11 +1,13 @@
 FFmpegOutput="FFmpeg Ausgabe"
-FFmpegAAC="FFmpeg Standard AAC Encoder"
+FFmpegAAC="FFmpeg Standard AAC Codierer"
 Bitrate="Bitrate"
 Preset="Voreinstellung"
 RateControl="Qualitäts Regulierungsmethode"
 KeyframeIntervalSec="Keyframeintervall (Sekunden, 0=auto)"
 Lossless="Verlustfrei"
 
+BFrames="B-frames"
+
 NVENC.Use2Pass="Benutze Two-Pass Encoding"
 NVENC.Preset.default="Standard"
 NVENC.Preset.hq="Hohe Qualität"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Video-Dateien"
 MediaFileFilter.AudioFiles="Audio-Dateien"
 MediaFileFilter.AllFiles="Alle Dateien"
 
+ReplayBuffer="Replaypuffer"
+ReplayBuffer.Save="Replay speichern"
+
diff --git a/plugins/obs-ffmpeg/data/locale/el-GR.ini b/plugins/obs-ffmpeg/data/locale/el-GR.ini
index d82c271..e13c43e 100644
--- a/plugins/obs-ffmpeg/data/locale/el-GR.ini
+++ b/plugins/obs-ffmpeg/data/locale/el-GR.ini
@@ -3,6 +3,8 @@ FFmpegAAC="FFmpeg προεπιλεγμένος κωδικοποιητής AAC"
 Bitrate="Ρυθμός μετάδοσης bit"
 
 
+NVENC.Preset.default="Προεπιλογή"
+
 LocalFile="Τοπικό αρχείο"
 Looping="Επανάληψη"
 Input="Είσοδος"
@@ -18,3 +20,4 @@ DiscardAll="Όλα τα καρέ (Προσοχή!)"
 
 
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/en-US.ini b/plugins/obs-ffmpeg/data/locale/en-US.ini
index 7dff1ce..d169833 100644
--- a/plugins/obs-ffmpeg/data/locale/en-US.ini
+++ b/plugins/obs-ffmpeg/data/locale/en-US.ini
@@ -48,3 +48,6 @@ MediaFileFilter.AllMediaFiles="All Media Files"
 MediaFileFilter.VideoFiles="Video Files"
 MediaFileFilter.AudioFiles="Audio Files"
 MediaFileFilter.AllFiles="All Files"
+
+ReplayBuffer="Replay Buffer"
+ReplayBuffer.Save="Save Replay"
diff --git a/plugins/obs-ffmpeg/data/locale/es-ES.ini b/plugins/obs-ffmpeg/data/locale/es-ES.ini
index 0702b35..15e431b 100644
--- a/plugins/obs-ffmpeg/data/locale/es-ES.ini
+++ b/plugins/obs-ffmpeg/data/locale/es-ES.ini
@@ -6,6 +6,8 @@ RateControl="Control de la frecuencia"
 KeyframeIntervalSec="Intervalo de keyframes (segundos, 0=auto)"
 Lossless="Sin pérdidas"
 
+BFrames="B-Frames"
+
 NVENC.Use2Pass="Usar codificación en dos pasadas"
 NVENC.Preset.default="Por defecto"
 NVENC.Preset.hq="Alta Calidad"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Archivos de vídeo"
 MediaFileFilter.AudioFiles="Archivos de audio"
 MediaFileFilter.AllFiles="Todos los Archivos"
 
+ReplayBuffer="Búfer de reproducción"
+ReplayBuffer.Save="Guardar repetición"
+
diff --git a/plugins/obs-ffmpeg/data/locale/et-EE.ini b/plugins/obs-ffmpeg/data/locale/et-EE.ini
new file mode 100644
index 0000000..188cf5d
--- /dev/null
+++ b/plugins/obs-ffmpeg/data/locale/et-EE.ini
@@ -0,0 +1,34 @@
+FFmpegOutput="FFmpeg väljund"
+Bitrate="Bitikiirus"
+
+
+NVENC.Preset.default="Vaikimisi"
+NVENC.Preset.hq="Kõrge kvaliteet"
+NVENC.Preset.hp="Suur jõudlus"
+NVENC.Preset.bd="Bluray"
+NVENC.Preset.ll="Madal-viivitus"
+NVENC.Preset.llhq="Madal-viivitus Kõrge kvaliteediga"
+NVENC.Preset.llhp="Madal-viivitus suure jõudlusega"
+NVENC.Level="Tase"
+
+FFmpegSource="Meedia allikas"
+LocalFile="Kohalik fail"
+Looping="Korda"
+Input="Sisend"
+InputFormat="Sisestus formaat"
+ClearOnMediaEnd="Peida allikas kui taasesitus lõppeb"
+AudioBufferSize="Audio puhvri suurus (kaadrit)"
+ColorRange="YUV värviruumi vahemik"
+ColorRange.Auto="Automaatne"
+ColorRange.Partial="Osaline"
+ColorRange.Full="Täielik"
+
+
+MediaFileFilter.AllMediaFiles="Kõik meediumifailid"
+MediaFileFilter.VideoFiles="Videofailid"
+MediaFileFilter.AudioFiles="Helifailid"
+MediaFileFilter.AllFiles="Kõik failid"
+
+ReplayBuffer="Taasesituse puhver"
+ReplayBuffer.Save="Salvesta Taasesitus"
+
diff --git a/plugins/obs-ffmpeg/data/locale/eu-ES.ini b/plugins/obs-ffmpeg/data/locale/eu-ES.ini
index b9f7b59..149ceec 100644
--- a/plugins/obs-ffmpeg/data/locale/eu-ES.ini
+++ b/plugins/obs-ffmpeg/data/locale/eu-ES.ini
@@ -6,6 +6,8 @@ RateControl="Tasaren kontrola"
 KeyframeIntervalSec="Gako-fotogramen tartea (segundoak, 0=auto)"
 Lossless="Galerarik gabe"
 
+BFrames="B-fotogramak"
+
 NVENC.Use2Pass="Erabili bi urratseko kodeketa"
 NVENC.Preset.default="Lehenetsia"
 NVENC.Preset.hq="Kalitate handia"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Bideo-fitxategiak"
 MediaFileFilter.AudioFiles="Audio-fitxategiak"
 MediaFileFilter.AllFiles="Fitxategi guztiak"
 
+ReplayBuffer="Erreprodukzio bufferra"
+ReplayBuffer.Save="Gorde erreprodukzioa"
+
diff --git a/plugins/obs-ffmpeg/data/locale/fi-FI.ini b/plugins/obs-ffmpeg/data/locale/fi-FI.ini
index 53cfea4..fc78791 100644
--- a/plugins/obs-ffmpeg/data/locale/fi-FI.ini
+++ b/plugins/obs-ffmpeg/data/locale/fi-FI.ini
@@ -6,6 +6,8 @@ RateControl="Rate Control -tila"
 KeyframeIntervalSec="Keyframe-väli (sekunteina, 0=automaattinen)"
 Lossless="Häviötön"
 
+BFrames="B-kehykset"
+
 NVENC.Use2Pass="Käytä Two-Pass enkoodausta"
 NVENC.Preset.default="Oletusarvo"
 NVENC.Preset.hq="Korkea laatu"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Videotiedostot"
 MediaFileFilter.AudioFiles="Äänitiedostot"
 MediaFileFilter.AllFiles="Kaikki tiedostot"
 
+ReplayBuffer="Toistopuskuri"
+ReplayBuffer.Save="Tallenna uusinta"
+
diff --git a/plugins/obs-ffmpeg/data/locale/fr-FR.ini b/plugins/obs-ffmpeg/data/locale/fr-FR.ini
index d1caf13..5e08037 100644
--- a/plugins/obs-ffmpeg/data/locale/fr-FR.ini
+++ b/plugins/obs-ffmpeg/data/locale/fr-FR.ini
@@ -6,6 +6,8 @@ RateControl="Contrôle du débit"
 KeyframeIntervalSec="Intervalle d'image-clé (en secondes, 0 = auto)"
 Lossless="Sans perte"
 
+BFrames="B-frames"
+
 NVENC.Use2Pass="Utiliser l'encodage double passe"
 NVENC.Preset.default="Défaut"
 NVENC.Preset.hq="Haute qualité"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Fichiers vidéo"
 MediaFileFilter.AudioFiles="Fichiers audio"
 MediaFileFilter.AllFiles="Tous les fichiers"
 
+ReplayBuffer="Tampon de relecture"
+ReplayBuffer.Save="Sauvegarder la relecture"
+
diff --git a/plugins/obs-ffmpeg/data/locale/gl-ES.ini b/plugins/obs-ffmpeg/data/locale/gl-ES.ini
index a3b620f..c8d54b6 100644
--- a/plugins/obs-ffmpeg/data/locale/gl-ES.ini
+++ b/plugins/obs-ffmpeg/data/locale/gl-ES.ini
@@ -2,6 +2,7 @@ FFmpegOutput="Saída de FFmpeg"
 FFmpegAAC="Codificador AAC FFmpeg predefinido"
 Bitrate="Velocidade de bits"
 
+
 NVENC.Level="Nivel"
 
 FFmpegSource="Fonte multimedia"
@@ -24,3 +25,4 @@ DiscardAll="Todos os marcos (con tino!)"
 
 
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/he-IL.ini b/plugins/obs-ffmpeg/data/locale/he-IL.ini
index e5ed371..255d8c5 100644
--- a/plugins/obs-ffmpeg/data/locale/he-IL.ini
+++ b/plugins/obs-ffmpeg/data/locale/he-IL.ini
@@ -6,6 +6,7 @@ RateControl="בקרת קצב"
 KeyframeIntervalSec="מרווח ערך ה keyframe בשניות (0=אוטומטי)"
 Lossless="ללא אובדן נתונים"
 
+
 NVENC.Use2Pass="השתמש בקידוד שני מעברים"
 NVENC.Preset.default="ברירת מחדל"
 NVENC.Preset.hq="איכות גבוהה"
@@ -47,3 +48,4 @@ MediaFileFilter.VideoFiles="קבצי וידאו"
 MediaFileFilter.AudioFiles="קבצי אודיו"
 MediaFileFilter.AllFiles="כל הקבצים"
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/hr-HR.ini b/plugins/obs-ffmpeg/data/locale/hr-HR.ini
index a5a2b9c..1e584a2 100644
--- a/plugins/obs-ffmpeg/data/locale/hr-HR.ini
+++ b/plugins/obs-ffmpeg/data/locale/hr-HR.ini
@@ -6,6 +6,7 @@ RateControl="Kontrola protoka"
 KeyframeIntervalSec="Interval ključnih frejmova (sekunde, 0=automatski)"
 Lossless="Bez gubitka"
 
+
 NVENC.Use2Pass="Koristi enkoding duplog prolaza"
 NVENC.Preset.default="Podrazumevani"
 NVENC.Preset.hq="Visoki kvalitet"
@@ -47,3 +48,4 @@ MediaFileFilter.VideoFiles="Video datoteke"
 MediaFileFilter.AudioFiles="Zvučne datoteke"
 MediaFileFilter.AllFiles="Sve datoteke"
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/hu-HU.ini b/plugins/obs-ffmpeg/data/locale/hu-HU.ini
index 284fbb0..e0aa725 100644
--- a/plugins/obs-ffmpeg/data/locale/hu-HU.ini
+++ b/plugins/obs-ffmpeg/data/locale/hu-HU.ini
@@ -1,11 +1,13 @@
 FFmpegOutput="FFmpeg kimenet"
 FFmpegAAC="FFmpeg alapértelmezett AAC kódoló"
-Bitrate="Bitráta"
+Bitrate="Bitsebesség"
 Preset="Készlet"
 RateControl="Sebesség Vezérlés"
 KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)"
 Lossless="Veszteségmentes"
 
+BFrames="B képkocka"
+
 NVENC.Use2Pass="Kétmenetes kódolás"
 NVENC.Preset.default="Alapértelmezett"
 NVENC.Preset.hq="Kiváló minőség"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Videofájlok"
 MediaFileFilter.AudioFiles="Hangfájlok"
 MediaFileFilter.AllFiles="Minden fájl"
 
+ReplayBuffer="Visszajátszás puffer"
+ReplayBuffer.Save="Visszajátszás mentése"
+
diff --git a/plugins/obs-ffmpeg/data/locale/it-IT.ini b/plugins/obs-ffmpeg/data/locale/it-IT.ini
index 2f7d252..193377d 100644
--- a/plugins/obs-ffmpeg/data/locale/it-IT.ini
+++ b/plugins/obs-ffmpeg/data/locale/it-IT.ini
@@ -6,6 +6,8 @@ RateControl="Controllo frequenza"
 KeyframeIntervalSec="Intervallo Keyframe (secondi, 0=automatico)"
 Lossless="Lossless"
 
+BFrames="B-frames"
+
 NVENC.Use2Pass="Usa codifica in due passaggi"
 NVENC.Preset.default="Predefinito"
 NVENC.Preset.hq="Alta Qualità"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="File video"
 MediaFileFilter.AudioFiles="File audio"
 MediaFileFilter.AllFiles="Tutti i file"
 
+ReplayBuffer="Buffer di Replay"
+ReplayBuffer.Save="Salva Replay"
+
diff --git a/plugins/obs-ffmpeg/data/locale/ja-JP.ini b/plugins/obs-ffmpeg/data/locale/ja-JP.ini
index 2b1e2ad..f53ab12 100644
--- a/plugins/obs-ffmpeg/data/locale/ja-JP.ini
+++ b/plugins/obs-ffmpeg/data/locale/ja-JP.ini
@@ -6,6 +6,8 @@ RateControl="レート制御"
 KeyframeIntervalSec="キーフレーム間隔 (秒, 0=自動)"
 Lossless="無損失"
 
+BFrames="B-フレーム"
+
 NVENC.Use2Pass="2パスエンコードを使用"
 NVENC.Preset.default="既定"
 NVENC.Preset.hq="高品質"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="ビデオファイル"
 MediaFileFilter.AudioFiles="オーディオファイル"
 MediaFileFilter.AllFiles="すべてのファイル"
 
+ReplayBuffer="リプレイバッファー"
+ReplayBuffer.Save="リプレイ保存"
+
diff --git a/plugins/obs-ffmpeg/data/locale/ko-KR.ini b/plugins/obs-ffmpeg/data/locale/ko-KR.ini
index c2a3b02..776b398 100644
--- a/plugins/obs-ffmpeg/data/locale/ko-KR.ini
+++ b/plugins/obs-ffmpeg/data/locale/ko-KR.ini
@@ -6,6 +6,8 @@ RateControl="데이터율 제어"
 KeyframeIntervalSec="키프레임 간격 (초 단위, 0=자동)"
 Lossless="무손실"
 
+BFrames="B-화면"
+
 NVENC.Use2Pass="2 패스 인코딩 사용"
 NVENC.Preset.default="기본"
 NVENC.Preset.hq="우수한 품질"
@@ -27,7 +29,7 @@ ClearOnMediaEnd="재생이 끝나면 소스를 숨기기"
 Advanced="고급"
 AudioBufferSize="오디오 버퍼 크기 (프레임)"
 VideoBufferSize="비디오 버퍼 크기 (프레임)"
-FrameDropping="프레임 드롭 수준"
+FrameDropping="프레임 손실 수준"
 DiscardNone="없음"
 DiscardDefault="기본 (유효하지 않은 패킷)"
 DiscardNonRef="비 참조 프레임"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="비디오 파일"
 MediaFileFilter.AudioFiles="오디오 파일"
 MediaFileFilter.AllFiles="모든 파일"
 
+ReplayBuffer="리플레이 버퍼"
+ReplayBuffer.Save="리플레이 저장"
+
diff --git a/plugins/obs-ffmpeg/data/locale/nb-NO.ini b/plugins/obs-ffmpeg/data/locale/nb-NO.ini
index 05c8d46..ab7f0ae 100644
--- a/plugins/obs-ffmpeg/data/locale/nb-NO.ini
+++ b/plugins/obs-ffmpeg/data/locale/nb-NO.ini
@@ -6,6 +6,7 @@ RateControl="Hastighetskontroll"
 KeyframeIntervalSec="Nøkkelbildeintervall (sekunder, 0 = automatisk)"
 Lossless="Tapsfri"
 
+
 NVENC.Use2Pass="Bruk tostegskoding"
 NVENC.Preset.default="Standard"
 NVENC.Preset.hq="Høy kvalitet"
@@ -47,3 +48,4 @@ MediaFileFilter.VideoFiles="Videofiler"
 MediaFileFilter.AudioFiles="Lydfiler"
 MediaFileFilter.AllFiles="Alle filer"
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/nl-NL.ini b/plugins/obs-ffmpeg/data/locale/nl-NL.ini
index 1c386af..480be4a 100644
--- a/plugins/obs-ffmpeg/data/locale/nl-NL.ini
+++ b/plugins/obs-ffmpeg/data/locale/nl-NL.ini
@@ -6,6 +6,8 @@ RateControl="Rate Control"
 KeyframeIntervalSec="Tijd tussen keyframes (seconden, 0=auto)"
 Lossless="Lossless"
 
+BFrames="B-frames"
+
 NVENC.Use2Pass="Gebruik two-pass encoding"
 NVENC.Preset.default="Standaard"
 NVENC.Preset.hq="Hoge kwaliteit"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Videobestanden"
 MediaFileFilter.AudioFiles="Audiobestanden"
 MediaFileFilter.AllFiles="Alle bestanden"
 
+ReplayBuffer="Replay Buffer"
+ReplayBuffer.Save="Replay Opslaan"
+
diff --git a/plugins/obs-ffmpeg/data/locale/pl-PL.ini b/plugins/obs-ffmpeg/data/locale/pl-PL.ini
index 01f1f76..250b3f7 100644
--- a/plugins/obs-ffmpeg/data/locale/pl-PL.ini
+++ b/plugins/obs-ffmpeg/data/locale/pl-PL.ini
@@ -6,6 +6,8 @@ RateControl="Typ przepływności"
 KeyframeIntervalSec="Odstęp między klatkami kluczowymi (sekundy, 0=automatyczny)"
 Lossless="Bezstratny"
 
+BFrames="B-ramki"
+
 NVENC.Use2Pass="Użyj enkodowania dwuprzebiegowego"
 NVENC.Preset.default="Domyślny"
 NVENC.Preset.hq="Wysoka jakość"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Pliki video"
 MediaFileFilter.AudioFiles="Pliki audio"
 MediaFileFilter.AllFiles="Wszystkie pliki"
 
+ReplayBuffer="Bufor replay"
+ReplayBuffer.Save="Zapisz replay"
+
diff --git a/plugins/obs-ffmpeg/data/locale/pt-BR.ini b/plugins/obs-ffmpeg/data/locale/pt-BR.ini
index d4e5435..ae80659 100644
--- a/plugins/obs-ffmpeg/data/locale/pt-BR.ini
+++ b/plugins/obs-ffmpeg/data/locale/pt-BR.ini
@@ -6,6 +6,8 @@ RateControl="Controle da Taxa de Bits"
 KeyframeIntervalSec="Intervalo de Keyframe (segundos, 0=auto)"
 Lossless="Sem perdas"
 
+BFrames="B-frames"
+
 NVENC.Use2Pass="Utilizar a codificação em dois passos"
 NVENC.Preset.default="Padrão"
 NVENC.Preset.hq="Alta Qualidade"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Arquivos de Vídeo"
 MediaFileFilter.AudioFiles="Arquivos de Áudio"
 MediaFileFilter.AllFiles="Todos os Arquivos"
 
+ReplayBuffer="Buffer do Replay"
+ReplayBuffer.Save="Salvar Replay"
+
diff --git a/plugins/obs-ffmpeg/data/locale/pt-PT.ini b/plugins/obs-ffmpeg/data/locale/pt-PT.ini
index 826d9ce..36e96f1 100644
--- a/plugins/obs-ffmpeg/data/locale/pt-PT.ini
+++ b/plugins/obs-ffmpeg/data/locale/pt-PT.ini
@@ -6,6 +6,7 @@ RateControl="Controle de Taxa"
 KeyframeIntervalSec="Intervalo do keyframe (segundos, 0=automático)"
 Lossless="Sem perdas"
 
+
 NVENC.Preset.default="Predefinido"
 NVENC.Preset.hq="Alta Qualidade"
 NVENC.Preset.hp="Alto Desempenho"
@@ -46,3 +47,4 @@ MediaFileFilter.VideoFiles="Arquivos de Vídeo"
 MediaFileFilter.AudioFiles="Arquivos de Áudio"
 MediaFileFilter.AllFiles="Todos os ficheiros"
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/ro-RO.ini b/plugins/obs-ffmpeg/data/locale/ro-RO.ini
index fae18b6..749198f 100644
--- a/plugins/obs-ffmpeg/data/locale/ro-RO.ini
+++ b/plugins/obs-ffmpeg/data/locale/ro-RO.ini
@@ -3,6 +3,7 @@ FFmpegAAC="Codificator AAC implicit FFmpeg"
 Bitrate="Rată de biți"
 Preset="Presetare"
 
+
 NVENC.Preset.default="Implicită"
 NVENC.Preset.bd="Bluray"
 NVENC.Level="Nivel"
@@ -38,3 +39,4 @@ MediaFileFilter.VideoFiles="Fișiere video"
 MediaFileFilter.AudioFiles="Fișiere audio"
 MediaFileFilter.AllFiles="Toate fișierele"
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/ru-RU.ini b/plugins/obs-ffmpeg/data/locale/ru-RU.ini
index 07b3941..92cb9fa 100644
--- a/plugins/obs-ffmpeg/data/locale/ru-RU.ini
+++ b/plugins/obs-ffmpeg/data/locale/ru-RU.ini
@@ -6,6 +6,8 @@ RateControl="Управление битрейтом"
 KeyframeIntervalSec="Интервал ключевых кадров (сек, 0=авто)"
 Lossless="Без потерь"
 
+BFrames="B-Кадры"
+
 NVENC.Use2Pass="Использовать двухпроходное кодирование"
 NVENC.Preset.default="По умолчанию"
 NVENC.Preset.hq="Высокое качество"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Видеофайлы"
 MediaFileFilter.AudioFiles="Аудиофайлы"
 MediaFileFilter.AllFiles="Все файлы"
 
+ReplayBuffer="Буфер повтора"
+ReplayBuffer.Save="Сохранить повтор"
+
diff --git a/plugins/obs-ffmpeg/data/locale/sk-SK.ini b/plugins/obs-ffmpeg/data/locale/sk-SK.ini
index 757cf2f..593adbe 100644
--- a/plugins/obs-ffmpeg/data/locale/sk-SK.ini
+++ b/plugins/obs-ffmpeg/data/locale/sk-SK.ini
@@ -3,9 +3,11 @@ FFmpegAAC="Predvolený FFmpeg AAC enkodér"
 Bitrate="Bitrate"
 
 
+
 Looping="Slučka"
 Advanced="Rozšírené"
 DiscardNone="Žiadny"
 
 
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/sl-SI.ini b/plugins/obs-ffmpeg/data/locale/sl-SI.ini
index 4094562..0004a8e 100644
--- a/plugins/obs-ffmpeg/data/locale/sl-SI.ini
+++ b/plugins/obs-ffmpeg/data/locale/sl-SI.ini
@@ -3,6 +3,7 @@ FFmpegAAC="FFmpeg Prevzeti AAC Encoder"
 Bitrate="Bitrate"
 
 
+
 FFmpegSource="Medijski Vir"
 LocalFile="Lokalna Datoteka"
 Looping="Ponavljaj"
@@ -25,3 +26,4 @@ DiscardAll="Vse Frame (Pazite!)"
 
 
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/sr-CS.ini b/plugins/obs-ffmpeg/data/locale/sr-CS.ini
index a5a2b9c..1e584a2 100644
--- a/plugins/obs-ffmpeg/data/locale/sr-CS.ini
+++ b/plugins/obs-ffmpeg/data/locale/sr-CS.ini
@@ -6,6 +6,7 @@ RateControl="Kontrola protoka"
 KeyframeIntervalSec="Interval ključnih frejmova (sekunde, 0=automatski)"
 Lossless="Bez gubitka"
 
+
 NVENC.Use2Pass="Koristi enkoding duplog prolaza"
 NVENC.Preset.default="Podrazumevani"
 NVENC.Preset.hq="Visoki kvalitet"
@@ -47,3 +48,4 @@ MediaFileFilter.VideoFiles="Video datoteke"
 MediaFileFilter.AudioFiles="Zvučne datoteke"
 MediaFileFilter.AllFiles="Sve datoteke"
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/sr-SP.ini b/plugins/obs-ffmpeg/data/locale/sr-SP.ini
index 1af21ed..db30444 100644
--- a/plugins/obs-ffmpeg/data/locale/sr-SP.ini
+++ b/plugins/obs-ffmpeg/data/locale/sr-SP.ini
@@ -6,6 +6,7 @@ RateControl="Контрола протока"
 KeyframeIntervalSec="Интервал кључних фрејмова (секунде, 0=аутоматски)"
 Lossless="Без губитка"
 
+
 NVENC.Use2Pass="Користи енкодинг дуплог пролаза"
 NVENC.Preset.default="Подразумевани"
 NVENC.Preset.hq="Високи квалитет"
@@ -47,3 +48,4 @@ MediaFileFilter.VideoFiles="Видео датотеке"
 MediaFileFilter.AudioFiles="Звучне датотеке"
 MediaFileFilter.AllFiles="Све датотеке"
 
+
diff --git a/plugins/obs-ffmpeg/data/locale/sv-SE.ini b/plugins/obs-ffmpeg/data/locale/sv-SE.ini
index d6435f5..4185cbd 100644
--- a/plugins/obs-ffmpeg/data/locale/sv-SE.ini
+++ b/plugins/obs-ffmpeg/data/locale/sv-SE.ini
@@ -6,6 +6,8 @@ RateControl="Hastighetskontroll"
 KeyframeIntervalSec="Intervall för keyframes (sekunder, 0=automatisk)"
 Lossless="Förlustfri"
 
+BFrames="B-bildrutor"
+
 NVENC.Use2Pass="Använd tvåpassavkodning"
 NVENC.Preset.default="Standard"
 NVENC.Preset.hq="Hög kvalitet"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Videofiler"
 MediaFileFilter.AudioFiles="Ljudfiler"
 MediaFileFilter.AllFiles="Alla filer"
 
+ReplayBuffer="Reprisbuffert"
+ReplayBuffer.Save="Spara repris"
+
diff --git a/plugins/obs-ffmpeg/data/locale/th-TH.ini b/plugins/obs-ffmpeg/data/locale/th-TH.ini
index 0eafac3..8e88f66 100644
--- a/plugins/obs-ffmpeg/data/locale/th-TH.ini
+++ b/plugins/obs-ffmpeg/data/locale/th-TH.ini
@@ -4,3 +4,5 @@ Bitrate="บิตเรท"
 
 
 
+
+
diff --git a/plugins/obs-ffmpeg/data/locale/tr-TR.ini b/plugins/obs-ffmpeg/data/locale/tr-TR.ini
index bce3260..051af38 100644
--- a/plugins/obs-ffmpeg/data/locale/tr-TR.ini
+++ b/plugins/obs-ffmpeg/data/locale/tr-TR.ini
@@ -2,11 +2,21 @@ FFmpegOutput="FFmpeg Çıkışı"
 FFmpegAAC="FFmpeg Varsayılan AAC Kodlayıcı"
 Bitrate="Bit hızı"
 Preset="Ön Tanımlı"
-KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)"
+RateControl="Oran Kontrolü"
+KeyframeIntervalSec="Anahtar Kare Aralığı (saniye, 0=otomatik)"
+Lossless="Kayıpsız"
 
+BFrames="B-Kareleri"
+
+NVENC.Use2Pass="İki Taramalı Kodlama Kullan"
 NVENC.Preset.default="Varsayılan"
 NVENC.Preset.hq="Yüksek Kalite"
 NVENC.Preset.hp="Yüksek Performans"
+NVENC.Preset.bd="Bluray"
+NVENC.Preset.ll="Düşük Gecikme"
+NVENC.Preset.llhq="Düşük Gecikme Yüksek Kalite"
+NVENC.Preset.llhp="Düşük Gecikme Yüksek Performans"
+NVENC.Level="Seviye"
 
 FFmpegSource="Ortam Kaynağı"
 LocalFile="Yerel Dosya"
@@ -27,6 +37,11 @@ DiscardBiDir="Çift-Yönlü Kareler"
 DiscardNonIntra="Intra Olmayan Kareler"
 DiscardNonKey="Anahtar Olmayan Kareler"
 DiscardAll="Tüm Kareler (Dikkatli Olun!)"
+RestartWhenActivated="Yeniden oynatmayı kaynak etkin olduğunda yeniden başlat"
+ColorRange="YUV Renk Aralığı"
+ColorRange.Auto="Otomatik"
+ColorRange.Partial="Kısmi"
+ColorRange.Full="Tam"
 
 
 MediaFileFilter.AllMediaFiles="Tüm Medya Dosyaları"
@@ -34,3 +49,6 @@ MediaFileFilter.VideoFiles="Video Dosyaları"
 MediaFileFilter.AudioFiles="Ses Dosyaları"
 MediaFileFilter.AllFiles="Tüm Dosyalar"
 
+ReplayBuffer="Tekrar Oynatma ArabelleÄŸi"
+ReplayBuffer.Save="Yeniden Oynatmayı Kaydet"
+
diff --git a/plugins/obs-ffmpeg/data/locale/uk-UA.ini b/plugins/obs-ffmpeg/data/locale/uk-UA.ini
index 4f4412e..1bb839a 100644
--- a/plugins/obs-ffmpeg/data/locale/uk-UA.ini
+++ b/plugins/obs-ffmpeg/data/locale/uk-UA.ini
@@ -6,6 +6,8 @@ RateControl="Керування потоком"
 KeyframeIntervalSec="Інтервал ключових кадрів (секунд, 0 = авто)"
 Lossless="Без втрат"
 
+BFrames="B-кадри"
+
 NVENC.Use2Pass="Використовувати двопрохідне кодування"
 NVENC.Preset.default="Стандартний"
 NVENC.Preset.hq="Висока якість"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="Відео"
 MediaFileFilter.AudioFiles="Аудіо"
 MediaFileFilter.AllFiles="Всі файли"
 
+ReplayBuffer="Запис Повторів"
+ReplayBuffer.Save="Зберегти Повтор"
+
diff --git a/plugins/obs-ffmpeg/data/locale/vi-VN.ini b/plugins/obs-ffmpeg/data/locale/vi-VN.ini
new file mode 100644
index 0000000..a8f714b
--- /dev/null
+++ b/plugins/obs-ffmpeg/data/locale/vi-VN.ini
@@ -0,0 +1,27 @@
+FFmpegOutput="FFmpeg đầu ra"
+FFmpegAAC="FFmpeg AAC Encoder mặc định"
+Bitrate="Bitrate"
+Preset="Mẫu thiết lập"
+RateControl="Cách kiểm soát bitrate"
+KeyframeIntervalSec="Thời gian đặt Keyframe (giây, 0=tự động)"
+Lossless="Lossless"
+
+
+NVENC.Use2Pass="Sử dụng 2-Pass Encoding"
+NVENC.Preset.default="Mặc định"
+NVENC.Preset.hq="Chất lượng cao"
+NVENC.Preset.hp="Hiệu suất cao"
+NVENC.Preset.bd="Bluray"
+NVENC.Preset.ll="Độ trễ thấp"
+NVENC.Preset.llhq="Độ trễ thấp chất lượng cao"
+NVENC.Preset.llhp="Độ trễ thấp hiệu suất cao"
+NVENC.Level="Cấp độ"
+
+LocalFile="Tập tin cục bộ"
+Looping="Lặp lại"
+Input="Nhập"
+InputFormat="Định dạng đầu vào"
+
+
+
+
diff --git a/plugins/obs-ffmpeg/data/locale/zh-CN.ini b/plugins/obs-ffmpeg/data/locale/zh-CN.ini
index 23077a7..ffe9e45 100644
--- a/plugins/obs-ffmpeg/data/locale/zh-CN.ini
+++ b/plugins/obs-ffmpeg/data/locale/zh-CN.ini
@@ -6,6 +6,8 @@ RateControl="速率控制"
 KeyframeIntervalSec="关键帧间隔(秒, 0=自动)"
 Lossless="无损"
 
+BFrames="B 帧"
+
 NVENC.Use2Pass="使用 Two-Pass 编码"
 NVENC.Preset.default="默认"
 NVENC.Preset.hq="高质量"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="视频文件"
 MediaFileFilter.AudioFiles="音频文件"
 MediaFileFilter.AllFiles="所有文件"
 
+ReplayBuffer="回放缓存"
+ReplayBuffer.Save="保存回放"
+
diff --git a/plugins/obs-ffmpeg/data/locale/zh-TW.ini b/plugins/obs-ffmpeg/data/locale/zh-TW.ini
index efe35cf..84149d4 100644
--- a/plugins/obs-ffmpeg/data/locale/zh-TW.ini
+++ b/plugins/obs-ffmpeg/data/locale/zh-TW.ini
@@ -6,6 +6,8 @@ RateControl="位元率控制"
 KeyframeIntervalSec="關鍵訊框間隔 (秒,0 = 自動)"
 Lossless="無損"
 
+BFrames="B 訊框"
+
 NVENC.Use2Pass="使用 Two-Pass 編碼"
 NVENC.Preset.default="預設"
 NVENC.Preset.hq="高品質"
@@ -47,3 +49,6 @@ MediaFileFilter.VideoFiles="影像檔"
 MediaFileFilter.AudioFiles="音效檔"
 MediaFileFilter.AllFiles="所有檔案"
 
+ReplayBuffer="重播緩衝"
+ReplayBuffer.Save="儲存重播"
+
diff --git a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
index 09fb3b6..56565ed 100644
--- a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
+++ b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
@@ -355,7 +355,8 @@ static void create_audio_stream(struct ffmpeg_mux *ffm, int idx)
 
 static bool init_streams(struct ffmpeg_mux *ffm)
 {
-	create_video_stream(ffm);
+	if (ffm->params.has_video)
+		create_video_stream(ffm);
 
 	if (ffm->params.tracks) {
 		ffm->audio_streams =
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-aac.c b/plugins/obs-ffmpeg/obs-ffmpeg-aac.c
index 6826686..f2c34c2 100644
--- a/plugins/obs-ffmpeg/obs-ffmpeg-aac.c
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-aac.c
@@ -170,7 +170,7 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder)
 		enc->context->cutoff = cutoff;
 	}
 
-	info("bitrate: %d, channels: %d",
+	info("bitrate: %" PRId64 ", channels: %d",
 			enc->context->bit_rate / 1000, enc->context->channels);
 
 	init_sizes(enc, audio);
@@ -259,7 +259,7 @@ static obs_properties_t *aac_properties(void *unused)
 	obs_properties_t *props = obs_properties_create();
 
 	obs_properties_add_int(props, "bitrate",
-			obs_module_text("Bitrate"), 32, 320, 32);
+			obs_module_text("Bitrate"), 64, 320, 32);
 	return props;
 }
 
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c
index 1c45d67..5d5d533 100644
--- a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c
@@ -16,9 +16,13 @@
 ******************************************************************************/
 
 #include <obs-module.h>
+#include <obs-hotkey.h>
 #include <obs-avc.h>
 #include <util/dstr.h>
 #include <util/pipe.h>
+#include <util/darray.h>
+#include <util/platform.h>
+#include <util/circlebuf.h>
 #include <util/threading.h>
 #include "ffmpeg-mux/ffmpeg-mux.h"
 
@@ -40,17 +44,55 @@ struct ffmpeg_muxer {
 	volatile bool     active;
 	volatile bool     stopping;
 	volatile bool     capturing;
+
+	/* replay buffer */
+	struct circlebuf  packets;
+	int64_t           cur_size;
+	int64_t           cur_time;
+	int64_t           max_size;
+	int64_t           max_time;
+	int64_t           save_ts;
+	int               keyframes;
+	obs_hotkey_id     hotkey;
+
+	DARRAY(struct encoder_packet) mux_packets;
+	pthread_t                     mux_thread;
+	bool                          mux_thread_joinable;
+	volatile bool                 muxing;
 };
 
-static const char *ffmpeg_mux_getname(void *unused)
+static const char *ffmpeg_mux_getname(void *type)
 {
-	UNUSED_PARAMETER(unused);
+	UNUSED_PARAMETER(type);
 	return obs_module_text("FFmpegMuxer");
 }
 
+static inline void replay_buffer_clear(struct ffmpeg_muxer *stream)
+{
+	while (stream->packets.size > 0) {
+		struct encoder_packet pkt;
+		circlebuf_pop_front(&stream->packets, &pkt, sizeof(pkt));
+		obs_encoder_packet_release(&pkt);
+	}
+
+	circlebuf_free(&stream->packets);
+	stream->cur_size = 0;
+	stream->cur_time = 0;
+	stream->max_size = 0;
+	stream->max_time = 0;
+	stream->save_ts = 0;
+	stream->keyframes = 0;
+}
+
 static void ffmpeg_mux_destroy(void *data)
 {
 	struct ffmpeg_muxer *stream = data;
+
+	replay_buffer_clear(stream);
+	if (stream->mux_thread_joinable)
+		pthread_join(stream->mux_thread, NULL);
+	da_free(stream->mux_packets);
+
 	os_process_pipe_destroy(stream->pipe);
 	dstr_free(&stream->path);
 	bfree(stream);
@@ -103,7 +145,7 @@ static void add_video_encoder_params(struct ffmpeg_muxer *stream,
 	obs_data_release(settings);
 
 	dstr_catf(cmd, "%s %d %d %d %d %d ",
-			"h264",
+			obs_encoder_get_codec(vencoder),
 			bitrate,
 			obs_output_get_width(stream->output),
 			obs_output_get_height(stream->output),
@@ -177,7 +219,8 @@ static void add_muxer_params(struct dstr *cmd, struct ffmpeg_muxer *stream)
 	dstr_free(&mux);
 }
 
-static void build_command_line(struct ffmpeg_muxer *stream, struct dstr *cmd)
+static void build_command_line(struct ffmpeg_muxer *stream, struct dstr *cmd,
+		const char *path)
 {
 	obs_encoder_t *vencoder = obs_output_get_video_encoder(stream->output);
 	obs_encoder_t *aencoders[MAX_AUDIO_MIXES];
@@ -196,7 +239,11 @@ static void build_command_line(struct ffmpeg_muxer *stream, struct dstr *cmd)
 	dstr_init_move_array(cmd, obs_module_file(FFMPEG_MUX));
 	dstr_insert_ch(cmd, 0, '\"');
 	dstr_cat(cmd, "\" \"");
+
+	dstr_copy(&stream->path, path);
+	dstr_replace(&stream->path, "\"", "\"\"");
 	dstr_cat_dstr(cmd, &stream->path);
+
 	dstr_catf(cmd, "\" %d %d ", vencoder ? 1 : 0, num_tracks);
 
 	if (vencoder)
@@ -213,11 +260,18 @@ static void build_command_line(struct ffmpeg_muxer *stream, struct dstr *cmd)
 	add_muxer_params(cmd, stream);
 }
 
+static inline void start_pipe(struct ffmpeg_muxer *stream, const char *path)
+{
+	struct dstr cmd;
+	build_command_line(stream, &cmd, path);
+	stream->pipe = os_process_pipe_create(cmd.array, "w");
+	dstr_free(&cmd);
+}
+
 static bool ffmpeg_mux_start(void *data)
 {
 	struct ffmpeg_muxer *stream = data;
 	obs_data_t *settings;
-	struct dstr cmd;
 	const char *path;
 
 	if (!obs_output_can_begin_data_capture(stream->output, 0))
@@ -227,14 +281,9 @@ static bool ffmpeg_mux_start(void *data)
 
 	settings = obs_output_get_settings(stream->output);
 	path = obs_data_get_string(settings, "path");
-	dstr_copy(&stream->path, path);
-	dstr_replace(&stream->path, "\"", "\"\"");
+	start_pipe(stream, path);
 	obs_data_release(settings);
 
-	build_command_line(stream, &cmd);
-	stream->pipe = os_process_pipe_create(cmd.array, "w");
-	dstr_free(&cmd);
-
 	if (!stream->pipe) {
 		warn("Failed to create process pipe");
 		return false;
@@ -424,3 +473,343 @@ struct obs_output_info ffmpeg_muxer = {
 	.encoded_packet = ffmpeg_mux_data,
 	.get_properties = ffmpeg_mux_properties
 };
+
+/* ------------------------------------------------------------------------ */
+
+static const char *replay_buffer_getname(void *type)
+{
+	UNUSED_PARAMETER(type);
+	return obs_module_text("ReplayBuffer");
+}
+
+static bool replay_buffer_hotkey(void *data, obs_hotkey_id id,
+		obs_hotkey_t *hotkey, bool pressed)
+{
+	UNUSED_PARAMETER(id);
+	UNUSED_PARAMETER(hotkey);
+	UNUSED_PARAMETER(pressed);
+
+	struct ffmpeg_muxer *stream = data;
+	if (os_atomic_load_bool(&stream->active))
+		stream->save_ts = os_gettime_ns() / 1000LL;
+	return true;
+}
+
+static void save_replay_proc(void *data, calldata_t *cd)
+{
+	replay_buffer_hotkey(data, 0, NULL, true);
+	UNUSED_PARAMETER(cd);
+}
+
+static void *replay_buffer_create(obs_data_t *settings, obs_output_t *output)
+{
+	struct ffmpeg_muxer *stream = bzalloc(sizeof(*stream));
+	stream->output = output;
+
+	stream->hotkey = obs_hotkey_register_output(output,
+			"ReplayBuffer.Save",
+			obs_module_text("ReplayBuffer.Save"),
+			replay_buffer_hotkey, stream);
+
+	proc_handler_t *ph = obs_output_get_proc_handler(output);
+	proc_handler_add(ph, "void save()", save_replay_proc, stream);
+
+	UNUSED_PARAMETER(settings);
+	return stream;
+}
+
+static void replay_buffer_destroy(void *data)
+{
+	struct ffmpeg_muxer *stream = data;
+	if (stream->hotkey)
+		obs_hotkey_unregister(stream->hotkey);
+	ffmpeg_mux_destroy(data);
+}
+
+static bool replay_buffer_start(void *data)
+{
+	struct ffmpeg_muxer *stream = data;
+
+	if (!obs_output_can_begin_data_capture(stream->output, 0))
+		return false;
+	if (!obs_output_initialize_encoders(stream->output, 0))
+		return false;
+
+	obs_data_t *s = obs_output_get_settings(stream->output);
+	stream->max_time = obs_data_get_int(s, "max_time_sec") * 1000000LL;
+	stream->max_size = obs_data_get_int(s, "max_size_mb") * (1024 * 1024);
+	obs_data_release(s);
+
+	os_atomic_set_bool(&stream->active, true);
+	os_atomic_set_bool(&stream->capturing, true);
+	obs_output_begin_data_capture(stream->output, 0);
+
+	return true;
+}
+
+static bool purge_front(struct ffmpeg_muxer *stream)
+{
+	struct encoder_packet pkt;
+	bool keyframe;
+
+	circlebuf_pop_front(&stream->packets, &pkt, sizeof(pkt));
+
+	keyframe = pkt.type == OBS_ENCODER_VIDEO && pkt.keyframe;
+
+	if (keyframe)
+		stream->keyframes--;
+
+	if (!stream->packets.size) {
+		stream->cur_size = 0;
+		stream->cur_time = 0;
+	} else {
+		struct encoder_packet first;
+		circlebuf_peek_front(&stream->packets, &first, sizeof(first));
+		stream->cur_time = first.dts_usec;
+		stream->cur_size -= (int64_t)pkt.size;
+	}
+
+	obs_encoder_packet_release(&pkt);
+	return keyframe;
+}
+
+static inline void purge(struct ffmpeg_muxer *stream)
+{
+	if (purge_front(stream)) {
+		struct encoder_packet pkt;
+
+		for (;;) {
+			circlebuf_peek_front(&stream->packets, &pkt,
+					sizeof(pkt));
+			if (pkt.type == OBS_ENCODER_VIDEO && pkt.keyframe)
+				return;
+
+			purge_front(stream);
+		}
+	}
+}
+
+static inline void replay_buffer_purge(struct ffmpeg_muxer *stream,
+		struct encoder_packet *pkt)
+{
+	if (stream->max_size) {
+		if (!stream->packets.size || stream->keyframes <= 2)
+			return;
+
+		while ((stream->cur_size + (int64_t)pkt->size) >
+				stream->max_size)
+			purge(stream);
+	}
+
+	if (!stream->packets.size || stream->keyframes <= 2)
+		return;
+
+	while ((pkt->dts_usec - stream->cur_time) > stream->max_time)
+		purge(stream);
+}
+
+static void insert_packet(struct darray *array, struct encoder_packet *packet,
+		int64_t video_offset, int64_t *audio_offsets,
+		int64_t video_dts_offset, int64_t *audio_dts_offsets)
+{
+	struct encoder_packet pkt;
+	DARRAY(struct encoder_packet) packets;
+	packets.da = *array;
+	size_t idx;
+
+	obs_encoder_packet_ref(&pkt, packet);
+
+	if (pkt.type == OBS_ENCODER_VIDEO) {
+		pkt.dts_usec -= video_offset;
+		pkt.dts -= video_dts_offset;
+		pkt.pts -= video_dts_offset;
+	} else {
+		pkt.dts_usec -= audio_offsets[pkt.track_idx];
+		pkt.dts -= audio_dts_offsets[pkt.track_idx];
+		pkt.pts -= audio_dts_offsets[pkt.track_idx];
+	}
+
+	for (idx = packets.num; idx > 0; idx--) {
+		struct encoder_packet *p = packets.array + (idx - 1);
+		if (p->dts_usec < pkt.dts_usec)
+			break;
+	}
+
+	da_insert(packets, idx, &pkt);
+	*array = packets.da;
+}
+
+static void *replay_buffer_mux_thread(void *data)
+{
+	struct ffmpeg_muxer *stream = data;
+
+	start_pipe(stream, stream->path.array);
+
+	if (!stream->pipe) {
+		warn("Failed to create process pipe");
+		goto error;
+	}
+
+	if (!send_headers(stream)) {
+		warn("Could not write headers for file '%s'",
+				stream->path.array);
+		goto error;
+	}
+
+	for (size_t i = 0; i < stream->mux_packets.num; i++) {
+		struct encoder_packet *pkt = &stream->mux_packets.array[i];
+		write_packet(stream, pkt);
+		obs_encoder_packet_release(pkt);
+	}
+
+	info("Wrote replay buffer to '%s'", stream->path.array);
+
+error:
+	os_process_pipe_destroy(stream->pipe);
+	stream->pipe = NULL;
+	da_free(stream->mux_packets);
+	os_atomic_set_bool(&stream->muxing, false);
+	return NULL;
+}
+
+static void replay_buffer_save(struct ffmpeg_muxer *stream)
+{
+	const size_t size = sizeof(struct encoder_packet);
+	size_t num_packets = stream->packets.size / size;
+
+	da_reserve(stream->mux_packets, num_packets);
+
+	/* ---------------------------- */
+	/* reorder packets */
+
+	bool found_video = false;
+	bool found_audio[MAX_AUDIO_MIXES] = {0};
+	int64_t video_offset = 0;
+	int64_t video_dts_offset = 0;
+	int64_t audio_offsets[MAX_AUDIO_MIXES] = {0};
+	int64_t audio_dts_offsets[MAX_AUDIO_MIXES] = {0};
+
+	for (size_t i = 0; i < num_packets; i++) {
+		struct encoder_packet *pkt;
+		pkt = circlebuf_data(&stream->packets, i * size);
+
+		if (pkt->type == OBS_ENCODER_VIDEO) {
+			if (!found_video) {
+				video_offset = pkt->dts_usec;
+				video_dts_offset = pkt->dts;
+				found_video = true;
+			}
+		} else {
+			if (!found_audio[pkt->track_idx]) {
+				found_audio[pkt->track_idx] = true;
+				audio_offsets[pkt->track_idx] = pkt->dts_usec;
+				audio_dts_offsets[pkt->track_idx] = pkt->dts;
+			}
+		}
+
+		insert_packet(&stream->mux_packets.da, pkt,
+				video_offset, audio_offsets,
+				video_dts_offset, audio_dts_offsets);
+	}
+
+	/* ---------------------------- */
+	/* generate filename */
+
+	obs_data_t *settings = obs_output_get_settings(stream->output);
+	const char *dir = obs_data_get_string(settings, "directory");
+	const char *fmt = obs_data_get_string(settings, "format");
+	const char *ext = obs_data_get_string(settings, "extension");
+	bool space = obs_data_get_bool(settings, "allow_spaces");
+
+	char *filename = os_generate_formatted_filename(ext, space, fmt);
+
+	dstr_copy(&stream->path, dir);
+	dstr_replace(&stream->path, "\\", "/");
+	if (dstr_end(&stream->path) != '/')
+		dstr_cat_ch(&stream->path, '/');
+	dstr_cat(&stream->path, filename);
+
+	bfree(filename);
+	obs_data_release(settings);
+
+	/* ---------------------------- */
+
+	os_atomic_set_bool(&stream->muxing, true);
+	stream->mux_thread_joinable = pthread_create(&stream->mux_thread, NULL,
+			replay_buffer_mux_thread, stream) == 0;
+}
+
+static void deactivate_replay_buffer(struct ffmpeg_muxer *stream)
+{
+	if (stopping(stream))
+		obs_output_end_data_capture(stream->output);
+
+	os_atomic_set_bool(&stream->active, false);
+	os_atomic_set_bool(&stream->sent_headers, false);
+	os_atomic_set_bool(&stream->stopping, false);
+	replay_buffer_clear(stream);
+}
+
+static void replay_buffer_data(void *data, struct encoder_packet *packet)
+{
+	struct ffmpeg_muxer *stream = data;
+	struct encoder_packet pkt;
+
+	if (!active(stream))
+		return;
+
+	if (stopping(stream)) {
+		if (packet->sys_dts_usec >= stream->stop_ts) {
+			deactivate_replay_buffer(stream);
+			return;
+		}
+	}
+
+	obs_encoder_packet_ref(&pkt, packet);
+	replay_buffer_purge(stream, &pkt);
+
+	if (!stream->packets.size)
+		stream->cur_time = pkt.dts_usec;
+	stream->cur_size += pkt.size;
+
+	circlebuf_push_back(&stream->packets, packet, sizeof(*packet));
+
+	if (packet->type == OBS_ENCODER_VIDEO && packet->keyframe)
+		stream->keyframes++;
+
+	if (stream->save_ts && packet->sys_dts_usec >= stream->save_ts) {
+		if (os_atomic_load_bool(&stream->muxing))
+			return;
+
+		if (stream->mux_thread_joinable) {
+			pthread_join(stream->mux_thread, NULL);
+			stream->mux_thread_joinable = false;
+		}
+
+		stream->save_ts = 0;
+		replay_buffer_save(stream);
+	}
+}
+
+static void replay_buffer_defaults(obs_data_t *s)
+{
+	obs_data_set_default_int(s, "max_time_sec", 15);
+	obs_data_set_default_int(s, "max_size_mb", 500);
+	obs_data_set_default_string(s, "format", "%CCYY-%MM-%DD %hh-%mm-%ss");
+	obs_data_set_default_string(s, "extension", "mp4");
+	obs_data_set_default_bool(s, "allow_spaces", true);
+}
+
+struct obs_output_info replay_buffer = {
+	.id             = "replay_buffer",
+	.flags          = OBS_OUTPUT_AV |
+	                  OBS_OUTPUT_ENCODED |
+	                  OBS_OUTPUT_MULTI_TRACK,
+	.get_name       = replay_buffer_getname,
+	.create         = replay_buffer_create,
+	.destroy        = replay_buffer_destroy,
+	.start          = replay_buffer_start,
+	.stop           = ffmpeg_mux_stop,
+	.encoded_packet = replay_buffer_data,
+	.get_defaults   = replay_buffer_defaults
+};
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
index 520c6e8..017d257 100644
--- a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
@@ -23,6 +23,7 @@
 #include <obs-avc.h>
 
 #include <libavutil/opt.h>
+#include <libavutil/pixdesc.h>
 #include <libavformat/avformat.h>
 
 #include "obs-ffmpeg-formats.h"
@@ -223,11 +224,13 @@ static bool nvenc_update(void *data, obs_data_t *settings)
 	     "\twidth:        %d\n"
 	     "\theight:       %d\n"
 	     "\t2-pass:       %s\n"
+	     "\tb-frames:     %d\n"
 	     "\tGPU:          %d\n",
 	     rc, bitrate, cqp, enc->context->gop_size,
 	     preset, profile, level,
 	     enc->context->width, enc->context->height,
 	     twopass ? "true" : "false",
+	     enc->context->max_b_frames,
 	     gpu);
 
 	return nvenc_init_codec(enc);
@@ -269,7 +272,9 @@ static void *nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
 
 	enc = bzalloc(sizeof(*enc));
 	enc->encoder = encoder;
-	enc->nvenc = avcodec_find_encoder_by_name("nvenc_h264");
+	enc->nvenc = avcodec_find_encoder_by_name("h264_nvenc");
+	if (!enc->nvenc)
+		enc->nvenc = avcodec_find_encoder_by_name("nvenc_h264");
 	enc->first_packet = true;
 
 	blog(LOG_INFO, "---------------------------------");
@@ -296,8 +301,10 @@ fail:
 }
 
 static inline void copy_data(AVPicture *pic, const struct encoder_frame *frame,
-		int height)
+		int height, enum AVPixelFormat format)
 {
+	int h_chroma_shift, v_chroma_shift;
+	av_pix_fmt_get_chroma_sub_sample(format, &h_chroma_shift, &v_chroma_shift);
 	for (int plane = 0; plane < MAX_AV_PLANES; plane++) {
 		if (!frame->data[plane])
 			continue;
@@ -306,7 +313,7 @@ static inline void copy_data(AVPicture *pic, const struct encoder_frame *frame,
 		int pic_rowsize   = pic->linesize[plane];
 		int bytes = frame_rowsize < pic_rowsize ?
 			frame_rowsize : pic_rowsize;
-		int plane_height = plane == 0 ? height : height/2;
+		int plane_height = height >> (plane ? v_chroma_shift : 0);
 
 		for (int y = 0; y < plane_height; y++) {
 			int pos_frame = y * frame_rowsize;
@@ -329,7 +336,7 @@ static bool nvenc_encode(void *data, struct encoder_frame *frame,
 
 	av_init_packet(&av_pkt);
 
-	copy_data(&enc->dst_picture, frame, enc->height);
+	copy_data(&enc->dst_picture, frame, enc->height, enc->context->pix_fmt);
 
 	enc->vframe->pts = frame->pts;
 	ret = avcodec_encode_video2(enc->context, &av_pkt, enc->vframe,
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-output.c b/plugins/obs-ffmpeg/obs-ffmpeg-output.c
index f08bd7c..fd200d3 100644
--- a/plugins/obs-ffmpeg/obs-ffmpeg-output.c
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-output.c
@@ -23,6 +23,7 @@
 #include <util/platform.h>
 
 #include <libavutil/opt.h>
+#include <libavutil/pixdesc.h>
 #include <libavformat/avformat.h>
 #include <libswscale/swscale.h>
 
@@ -35,6 +36,7 @@ struct ffmpeg_cfg {
 	const char         *format_name;
 	const char         *format_mime_type;
 	const char         *muxer_settings;
+	int                gop_size;
 	int                video_bitrate;
 	int                audio_bitrate;
 	const char         *video_encoder;
@@ -129,10 +131,12 @@ static bool new_stream(struct ffmpeg_data *data, AVStream **stream,
 	return true;
 }
 
-static void parse_params(AVCodecContext *context, char **opts)
+static bool parse_params(AVCodecContext *context, char **opts)
 {
+	bool ret = true;
+
 	if (!context || !context->priv_data)
-		return;
+		return true;
 
 	while (*opts) {
 		char *opt = *opts;
@@ -145,11 +149,16 @@ static void parse_params(AVCodecContext *context, char **opts)
 			*assign = 0;
 			value = assign+1;
 
-			av_opt_set(context->priv_data, name, value, 0);
+			if (av_opt_set(context->priv_data, name, value, 0)) {
+				blog(LOG_WARNING, "Failed to set %s=%s", name, value);
+				ret = false;
+			}
 		}
 
 		opts++;
 	}
+
+	return ret;
 }
 
 static bool open_video_codec(struct ffmpeg_data *data)
@@ -162,7 +171,9 @@ static bool open_video_codec(struct ffmpeg_data *data)
 		av_opt_set(context->priv_data, "preset", "veryfast", 0);
 
 	if (opts) {
-		parse_params(context, opts);
+		// libav requires x264 parameters in a special format which may be non-obvious
+		if (!parse_params(context, opts) && strcmp(data->vcodec->name, "libx264") == 0)
+			blog(LOG_WARNING, "If you're trying to set x264 parameters, use x264-params=name=value:name=value");
 		strlist_free(opts);
 	}
 
@@ -238,7 +249,7 @@ static bool create_video_stream(struct ffmpeg_data *data)
 	context->width          = data->config.scale_width;
 	context->height         = data->config.scale_height;
 	context->time_base      = (AVRational){ ovi.fps_den, ovi.fps_num };
-	context->gop_size       = 120;
+	context->gop_size       = data->config.gop_size;
 	context->pix_fmt        = closest_format;
 	context->colorspace     = data->config.color_space;
 	context->color_range    = data->config.color_range;
@@ -266,7 +277,7 @@ static bool create_video_stream(struct ffmpeg_data *data)
 static bool open_audio_codec(struct ffmpeg_data *data)
 {
 	AVCodecContext *context = data->audio->codec;
-	char **opts = strlist_split(data->config.video_settings, ' ', false);
+	char **opts = strlist_split(data->config.audio_settings, ' ', false);
 	int ret;
 
 	if (opts) {
@@ -620,8 +631,10 @@ static void ffmpeg_output_destroy(void *data)
 }
 
 static inline void copy_data(AVPicture *pic, const struct video_data *frame,
-		int height)
+		int height, enum AVPixelFormat format)
 {
+	int h_chroma_shift, v_chroma_shift;
+	av_pix_fmt_get_chroma_sub_sample(format, &h_chroma_shift, &v_chroma_shift);
 	for (int plane = 0; plane < MAX_AV_PLANES; plane++) {
 		if (!frame->data[plane])
 			continue;
@@ -630,7 +643,7 @@ static inline void copy_data(AVPicture *pic, const struct video_data *frame,
 		int pic_rowsize   = pic->linesize[plane];
 		int bytes = frame_rowsize < pic_rowsize ?
 			frame_rowsize : pic_rowsize;
-		int plane_height = plane == 0 ? height : height/2;
+		int plane_height = height >> (plane ? v_chroma_shift : 0);
 
 		for (int y = 0; y < plane_height; y++) {
 			int pos_frame = y * frame_rowsize;
@@ -669,7 +682,7 @@ static void receive_video(void *param, struct video_data *frame)
 				0, data->config.height, data->dst_picture.data,
 				data->dst_picture.linesize);
 	else
-		copy_data(&data->dst_picture, frame, context->height);
+		copy_data(&data->dst_picture, frame, context->height, context->pix_fmt);
 
 	if (data->output->flags & AVFMT_RAWPICTURE) {
 		packet.flags        |= AV_PKT_FLAG_KEY;
@@ -939,6 +952,9 @@ static bool try_connect(struct ffmpeg_output *output)
 	int ret;
 
 	settings = obs_output_get_settings(output->output);
+
+	obs_data_set_default_int(settings, "gop_size", 120);
+
 	config.url = obs_data_get_string(settings, "url");
 	config.format_name = get_string_or_null(settings, "format_name");
 	config.format_mime_type = get_string_or_null(settings,
@@ -946,6 +962,7 @@ static bool try_connect(struct ffmpeg_output *output)
 	config.muxer_settings = obs_data_get_string(settings, "muxer_settings");
 	config.video_bitrate = (int)obs_data_get_int(settings, "video_bitrate");
 	config.audio_bitrate = (int)obs_data_get_int(settings, "audio_bitrate");
+	config.gop_size = (int)obs_data_get_int(settings, "gop_size");
 	config.video_encoder = get_string_or_null(settings, "video_encoder");
 	config.video_encoder_id = (int)obs_data_get_int(settings,
 			"video_encoder_id");
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-source.c b/plugins/obs-ffmpeg/obs-ffmpeg-source.c
index c272ef5..ab026ff 100644
--- a/plugins/obs-ffmpeg/obs-ffmpeg-source.c
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-source.c
@@ -337,7 +337,7 @@ static void ffmpeg_source_defaults(obs_data_t *settings)
 	obs_data_set_default_bool(settings, "clear_on_media_end", true);
 	obs_data_set_default_bool(settings, "restart_on_activate", true);
 	obs_data_set_default_bool(settings, "force_scale", true);
-#if defined(_WIN32) || defined(__APPLE__)
+#if defined(_WIN32)
 	obs_data_set_default_bool(settings, "hw_decode", true);
 #endif
 }
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg.c b/plugins/obs-ffmpeg/obs-ffmpeg.c
index 943e6c5..ce6de77 100644
--- a/plugins/obs-ffmpeg/obs-ffmpeg.c
+++ b/plugins/obs-ffmpeg/obs-ffmpeg.c
@@ -11,6 +11,7 @@ OBS_MODULE_USE_DEFAULT_LOCALE("obs-ffmpeg", "en-US")
 extern struct obs_source_info  ffmpeg_source;
 extern struct obs_output_info  ffmpeg_output;
 extern struct obs_output_info  ffmpeg_muxer;
+extern struct obs_output_info  replay_buffer;
 extern struct obs_encoder_info aac_encoder_info;
 extern struct obs_encoder_info nvenc_encoder_info;
 
@@ -145,6 +146,7 @@ bool obs_module_load(void)
 	obs_register_source(&ffmpeg_source);
 	obs_register_output(&ffmpeg_output);
 	obs_register_output(&ffmpeg_muxer);
+	obs_register_output(&replay_buffer);
 	obs_register_encoder(&aac_encoder_info);
 	if (nvenc_supported()) {
 		blog(LOG_INFO, "NVENC supported");
diff --git a/plugins/obs-filters/CMakeLists.txt b/plugins/obs-filters/CMakeLists.txt
index 253be97..54b19e5 100644
--- a/plugins/obs-filters/CMakeLists.txt
+++ b/plugins/obs-filters/CMakeLists.txt
@@ -20,17 +20,19 @@ include_directories(${LIBSPEEXDSP_INCLUDE_DIRS}
 
 set(obs-filters_SOURCES
 	obs-filters.c
-	color-filter.c
+	color-correction-filter.c
 	async-delay-filter.c
 	crop-filter.c
 	scale-filter.c
 	scroll-filter.c
 	chroma-key-filter.c
 	color-key-filter.c
+	color-grade-filter.c
 	sharpness-filter.c
 	gain-filter.c
 	noise-gate-filter.c
-	mask-filter.c)
+	mask-filter.c
+	compressor-filter.c)
 
 add_library(obs-filters MODULE
 	${obs-filters_SOURCES}
diff --git a/plugins/obs-filters/color-correction-filter.c b/plugins/obs-filters/color-correction-filter.c
new file mode 100644
index 0000000..e418d23
--- /dev/null
+++ b/plugins/obs-filters/color-correction-filter.c
@@ -0,0 +1,413 @@
+/*****************************************************************************
+Copyright (C) 2016 by c3r1c3 <c3r1c3 at nevermindonline.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+#include <obs-module.h>
+#include <graphics/matrix4.h>
+#include <graphics/quat.h>
+
+
+#define SETTING_GAMMA                  "gamma"
+#define SETTING_CONTRAST               "contrast"
+#define SETTING_BRIGHTNESS             "brightness"
+#define SETTING_SATURATION             "saturation"
+#define SETTING_HUESHIFT               "hue_shift"
+#define SETTING_OPACITY                "opacity"
+#define SETTING_COLOR                  "color"
+
+#define TEXT_GAMMA                     obs_module_text("Gamma")
+#define TEXT_CONTRAST                  obs_module_text("Contrast")
+#define TEXT_BRIGHTNESS                obs_module_text("Brightness")
+#define TEXT_SATURATION                obs_module_text("Saturation")
+#define TEXT_HUESHIFT                  obs_module_text("HueShift")
+#define TEXT_OPACITY                   obs_module_text("Opacity")
+#define TEXT_COLOR                     obs_module_text("Color")
+
+struct color_correction_filter_data {
+	obs_source_t                   *context;
+
+	gs_effect_t                    *effect;
+
+	gs_eparam_t                    *gamma_param;
+	gs_eparam_t                    *final_matrix_param;
+
+	struct vec3                     gamma;
+	float                           contrast;
+	float                           brightness;
+	float                           saturation;
+	float                           hue_shift;
+	float                           opacity;
+	struct vec4                     color;
+
+	/* Pre-Computes */
+	struct matrix4                  con_matrix;
+	struct matrix4                  bright_matrix;
+	struct matrix4                  sat_matrix;
+	struct matrix4                  hue_op_matrix;
+	struct matrix4                  color_matrix;
+	struct matrix4                  final_matrix;
+
+	struct vec3                     rot_quaternion;
+	float                           rot_quaternion_w;
+	struct vec3                     cross;
+	struct vec3                     square;
+	struct vec3                     wimag;
+	struct vec3                     diag;
+	struct vec3                     a_line;
+	struct vec3                     b_line;
+	struct vec3                     half_unit;
+};
+
+static const float root3 = 0.57735f;
+static const float red_weight = 0.299f;
+static const float green_weight = 0.587f;
+static const float blue_weight = 0.114f;
+
+/*
+ * As the functions' namesake, this provides the internal name of your Filter,
+ * which is then translated/referenced in the "data/locale" files.
+ */
+static const char *color_correction_filter_name(void *unused)
+{
+	UNUSED_PARAMETER(unused);
+	return obs_module_text("ColorFilter");
+}
+
+/*
+ * This function is called (see bottom of this file for more details)
+ * whenever the OBS filter interface changes. So when the user is messing
+ * with a slider this function is called to update the internal settings
+ * in OBS, and hence the settings being passed to the CPU/GPU.
+ */
+static void color_correction_filter_update(void *data, obs_data_t *settings)
+{
+	struct color_correction_filter_data *filter = data;
+
+	/* Build our Gamma numbers. */
+	double gamma = obs_data_get_double(settings, SETTING_GAMMA);
+	gamma = (gamma < 0.0) ? (-gamma + 1.0) : (1.0 / (gamma + 1.0));
+	vec3_set(&filter->gamma, (float)gamma, (float)gamma, (float)gamma);
+
+	/* Build our contrast number. */
+	filter->contrast = (float)obs_data_get_double(settings,
+			SETTING_CONTRAST) + 1.0f;
+	float one_minus_con = (1.0f - filter->contrast) / 2.0f;
+
+	/* Now let's build our Contrast matrix. */
+	filter->con_matrix = (struct matrix4)
+	{
+		filter->contrast, 0.0f, 0.0f, 0.0f,
+		0.0f, filter->contrast, 0.0f, 0.0f,
+		0.0f, 0.0f, filter->contrast, 0.0f,
+		one_minus_con, one_minus_con, one_minus_con, 1.0f
+	};
+
+	/* Build our brightness number. */
+	filter->brightness = (float)obs_data_get_double(settings,
+			SETTING_BRIGHTNESS);
+
+	/*
+	 * Now let's build our Brightness matrix.
+	 * Earlier (in the function color_correction_filter_create) we set
+	 * this matrix to the identity matrix, so now we only need
+	 * to set the 3 variables that have changed.
+	 */
+	filter->bright_matrix.t.x = filter->brightness;
+	filter->bright_matrix.t.y = filter->brightness;
+	filter->bright_matrix.t.z = filter->brightness;
+
+	/* Build our Saturation number. */
+	filter->saturation = (float)obs_data_get_double(settings,
+			SETTING_SATURATION) + 1.0f;
+
+	/* Factor in the selected color weights. */
+	float one_minus_sat_red = (1.0f - filter->saturation) * red_weight;
+	float one_minus_sat_green = (1.0f - filter->saturation) * green_weight;
+	float one_minus_sat_blue = (1.0f - filter->saturation) * blue_weight;
+	float sat_val_red   = one_minus_sat_red + filter->saturation;
+	float sat_val_green = one_minus_sat_green + filter->saturation;
+	float sat_val_blue  = one_minus_sat_blue + filter->saturation;
+
+	/* Now we build our Saturation matrix. */
+	filter->sat_matrix = (struct matrix4)
+	{
+		sat_val_red, one_minus_sat_red, one_minus_sat_red, 0.0f,
+		one_minus_sat_green, sat_val_green, one_minus_sat_green, 0.0f,
+		one_minus_sat_blue, one_minus_sat_blue, sat_val_blue, 0.0f,
+		0.0f, 0.0f, 0.0f, 1.0f
+	};
+
+	/* Build our Hue number. */
+	filter->hue_shift = (float)obs_data_get_double(settings,
+			SETTING_HUESHIFT);
+
+	/* Build our Transparency number. */
+	filter->opacity = (float)obs_data_get_int(settings,
+			SETTING_OPACITY) * 0.01f;
+
+	/* Hue is the radian of 0 to 360 degrees. */
+	float half_angle = 0.5f * (float)(filter->hue_shift / (180.0f / M_PI));
+
+	/* Pseudo-Quaternion To Matrix. */
+	float rot_quad1 = root3 * (float)sin(half_angle);
+	vec3_set(&filter->rot_quaternion, rot_quad1, rot_quad1,
+			rot_quad1);
+	filter->rot_quaternion_w = (float)cos(half_angle);
+
+	vec3_mul(&filter->cross, &filter->rot_quaternion,
+			&filter->rot_quaternion);
+	vec3_mul(&filter->square, &filter->rot_quaternion,
+			&filter->rot_quaternion);
+	vec3_mulf(&filter->wimag, &filter->rot_quaternion,
+			filter->rot_quaternion_w);
+
+	vec3_mulf(&filter->square, &filter->square, 2.0f);
+	vec3_sub(&filter->diag, &filter->half_unit, &filter->square);
+	vec3_add(&filter->a_line, &filter->cross, &filter->wimag);
+	vec3_sub(&filter->b_line, &filter->cross, &filter->wimag);
+
+	/* Now we build our Hue and Opacity matrix. */
+	filter->hue_op_matrix = (struct matrix4)
+	{
+		filter->diag.x * 2.0f,
+		filter->b_line.z * 2.0f,
+		filter->a_line.y * 2.0f,
+		0.0f,
+
+		filter->a_line.z * 2.0f,
+		filter->diag.y * 2.0f,
+		filter->b_line.x * 2.0f,
+		0.0f,
+
+		filter->b_line.y * 2.0f,
+		filter->a_line.x * 2.0f,
+		filter->diag.z * 2.0f,
+		0.0f,
+
+		0.0f, 0.0f, 0.0f, filter->opacity
+	};
+
+	/* Now get the overlay color data. */
+	uint32_t color = (uint32_t)obs_data_get_int(settings,
+			SETTING_COLOR);
+	vec4_from_rgba(&filter->color, color);
+
+	/*
+	* Now let's build our Color 'overlay' matrix.
+	* Earlier (in the function color_correction_filter_create) we set
+	* this matrix to the identity matrix, so now we only need
+	* to set the 6 variables that have changed.
+	*/
+	filter->color_matrix.x.x = filter->color.x;
+	filter->color_matrix.y.y = filter->color.y;
+	filter->color_matrix.z.z = filter->color.z;
+
+	filter->color_matrix.t.x = filter->color.w *
+			filter->color.x;
+	filter->color_matrix.t.y = filter->color.w *
+			filter->color.y;
+	filter->color_matrix.t.z = filter->color.w *
+			filter->color.z;
+
+
+	/* First we apply the Contrast & Brightness matrix. */
+	matrix4_mul(&filter->final_matrix, &filter->bright_matrix,
+			&filter->con_matrix);
+	/* Now we apply the Saturation matrix. */
+	matrix4_mul(&filter->final_matrix, &filter->final_matrix,
+			&filter->sat_matrix);
+	/* Next we apply the Hue+Opacity matrix. */
+	matrix4_mul(&filter->final_matrix, &filter->final_matrix,
+			&filter->hue_op_matrix);
+	/* Lastly we apply the Color Wash matrix. */
+	matrix4_mul(&filter->final_matrix, &filter->final_matrix,
+			&filter->color_matrix);
+}
+
+/*
+ * Since this is C we have to be careful when destroying/removing items from
+ * OBS. Jim has added several useful functions to help keep memory leaks to
+ * a minimum, and handle the destruction and construction of these filters.
+ */
+static void color_correction_filter_destroy(void *data)
+{
+	struct color_correction_filter_data *filter = data;
+
+	if (filter->effect) {
+		obs_enter_graphics();
+		gs_effect_destroy(filter->effect);
+		obs_leave_graphics();
+	}
+
+	bfree(data);
+}
+
+/*
+ * When you apply a filter OBS creates it, and adds it to the source. OBS also
+ * starts rendering it immediately. This function doesn't just 'create' the
+ * filter, it also calls the render function (farther below) that contains the
+ * actual rendering code.
+ */
+static void *color_correction_filter_create(obs_data_t *settings,
+	obs_source_t *context)
+{
+	/*
+	* Because of limitations of pre-c99 compilers, you can't create an
+	* array that doesn't have a known size at compile time. The below
+	* function calculates the size needed and allocates memory to
+	* handle the source.
+	*/
+	struct color_correction_filter_data *filter =
+		bzalloc(sizeof(struct color_correction_filter_data));
+
+	/*
+	 * By default the effect file is stored in the ./data directory that
+	 * your filter resides in.
+	 */
+	char *effect_path = obs_module_file("color_correction_filter.effect");
+
+	filter->context = context;
+
+	/* Set/clear/assign for all necessary vectors. */
+	vec3_set(&filter->half_unit, 0.5f, 0.5f, 0.5f);
+	matrix4_identity(&filter->bright_matrix);
+	matrix4_identity(&filter->color_matrix);
+
+	/* Here we enter the GPU drawing/shader portion of our code. */
+	obs_enter_graphics();
+
+	/* Load the shader on the GPU. */
+	filter->effect = gs_effect_create_from_file(effect_path, NULL);
+
+	/* If the filter is active pass the parameters to the filter. */
+	if (filter->effect) {
+		filter->gamma_param = gs_effect_get_param_by_name(
+				filter->effect, SETTING_GAMMA);
+		filter->final_matrix_param = gs_effect_get_param_by_name(
+				filter->effect, "color_matrix");
+	}
+
+	obs_leave_graphics();
+
+	bfree(effect_path);
+
+	/*
+	 * If the filter has been removed/deactivated, destroy the filter
+	 * and exit out so we don't crash OBS by telling it to update
+	 * values that don't exist anymore.
+	 */
+	if (!filter->effect) {
+		color_correction_filter_destroy(filter);
+		return NULL;
+	}
+
+	/*
+	 * It's important to call the update function here. If we don't
+	 * we could end up with the user controlled sliders and values
+	 * updating, but the visuals not updating to match.
+	 */
+	color_correction_filter_update(filter, settings);
+	return filter;
+}
+
+/* This is where the actual rendering of the filter takes place. */
+static void color_correction_filter_render(void *data, gs_effect_t *effect)
+{
+	struct color_correction_filter_data *filter = data;
+
+	if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
+			OBS_ALLOW_DIRECT_RENDERING))
+		return;
+
+	/* Now pass the interface variables to the .effect file. */
+	gs_effect_set_vec3(filter->gamma_param, &filter->gamma);
+	gs_effect_set_matrix4(filter->final_matrix_param, &filter->final_matrix);
+
+	obs_source_process_filter_end(filter->context, filter->effect, 0, 0);
+
+	UNUSED_PARAMETER(effect);
+}
+
+/*
+ * This function sets the interface. the types (add_*_Slider), the type of
+ * data collected (int), the internal name, user-facing name, minimum,
+ * maximum and step values. While a custom interface can be built, for a
+ * simple filter like this it's better to use the supplied functions.
+ */
+static obs_properties_t *color_correction_filter_properties(void *data)
+{
+	obs_properties_t *props = obs_properties_create();
+
+	obs_properties_add_float_slider(props, SETTING_GAMMA,
+			TEXT_GAMMA, -3.0f, 3.0f, 0.01f);
+
+	obs_properties_add_float_slider(props, SETTING_CONTRAST,
+			TEXT_CONTRAST, -2.0f, 2.0f, 0.01f);
+	obs_properties_add_float_slider(props, SETTING_BRIGHTNESS,
+			TEXT_BRIGHTNESS, -1.0f, 1.0f, 0.01f);
+	obs_properties_add_float_slider(props, SETTING_SATURATION,
+			TEXT_SATURATION, -1.0f, 5.0f, 0.01f);
+	obs_properties_add_float_slider(props, SETTING_HUESHIFT,
+			TEXT_HUESHIFT, -180.0f, 180.0f, 0.01f);
+	obs_properties_add_int_slider(props, SETTING_OPACITY,
+			TEXT_OPACITY, 0, 100, 1);
+
+	obs_properties_add_color(props, SETTING_COLOR, TEXT_COLOR);
+
+	UNUSED_PARAMETER(data);
+	return props;
+}
+
+/*
+ * As the functions' namesake, this provides the default settings for any
+ * options you wish to provide a default for. Try to select defaults that
+ * make sense to the end user, or that don't effect the data.
+ * *NOTE* this function is completely optional, as is providing a default
+ * for any particular setting.
+ */
+static void color_correction_filter_defaults(obs_data_t *settings)
+{
+	obs_data_set_default_double(settings, SETTING_GAMMA, 0.0);
+	obs_data_set_default_double(settings, SETTING_CONTRAST, 0.0);
+	obs_data_set_default_double(settings, SETTING_BRIGHTNESS, 0.0);
+	obs_data_set_default_double(settings,
+			SETTING_SATURATION, 0.0);
+	obs_data_set_default_double(settings, SETTING_HUESHIFT, 0.0);
+	obs_data_set_default_double(settings, SETTING_OPACITY, 100.0);
+	obs_data_set_default_int(settings, SETTING_COLOR, 0xFFFFFF);
+}
+
+/*
+ * So how does OBS keep track of all these plug-ins/filters? How does OBS know
+ * which function to call when it needs to update a setting? Or a source? Or
+ * what type of source this is?
+ *
+ * OBS does it through the obs_source_info_struct. Notice how variables are
+ * assigned the name of a function? Notice how the function name has the
+ * variable name in it? While not mandatory, it helps a ton for you (and those
+ * reading your code) to follow this convention.
+ */
+struct obs_source_info color_filter = {
+	.id = "color_filter",
+	.type = OBS_SOURCE_TYPE_FILTER,
+	.output_flags = OBS_SOURCE_VIDEO,
+	.get_name = color_correction_filter_name,
+	.create = color_correction_filter_create,
+	.destroy = color_correction_filter_destroy,
+	.video_render = color_correction_filter_render,
+	.update = color_correction_filter_update,
+	.get_properties = color_correction_filter_properties,
+	.get_defaults = color_correction_filter_defaults
+};
diff --git a/plugins/obs-filters/color-filter.c b/plugins/obs-filters/color-filter.c
deleted file mode 100644
index 8238a59..0000000
--- a/plugins/obs-filters/color-filter.c
+++ /dev/null
@@ -1,174 +0,0 @@
-#include <obs-module.h>
-#include <graphics/vec4.h>
-
-#define SETTING_COLOR                  "color"
-#define SETTING_OPACITY                "opacity"
-#define SETTING_CONTRAST               "contrast"
-#define SETTING_BRIGHTNESS             "brightness"
-#define SETTING_GAMMA                  "gamma"
-
-#define TEXT_COLOR                     obs_module_text("Color")
-#define TEXT_OPACITY                   obs_module_text("Opacity")
-#define TEXT_CONTRAST                  obs_module_text("Contrast")
-#define TEXT_BRIGHTNESS                obs_module_text("Brightness")
-#define TEXT_GAMMA                     obs_module_text("Gamma")
-
-#define MIN_CONTRAST 0.5f
-#define MAX_CONTRAST 2.0f
-#define MIN_BRIGHTNESS -1.0
-#define MAX_BRIGHTNESS 1.0
-
-struct color_filter_data {
-	obs_source_t                   *context;
-
-	gs_effect_t                    *effect;
-
-	gs_eparam_t                    *color_param;
-	gs_eparam_t                    *contrast_param;
-	gs_eparam_t                    *brightness_param;
-	gs_eparam_t                    *gamma_param;
-
-	struct vec4                    color;
-	float                          contrast;
-	float                          brightness;
-	float                          gamma;
-};
-
-static const char *color_filter_name(void *unused)
-{
-	UNUSED_PARAMETER(unused);
-	return obs_module_text("ColorFilter");
-}
-
-static void color_filter_update(void *data, obs_data_t *settings)
-{
-	struct color_filter_data *filter = data;
-	uint32_t color = (uint32_t)obs_data_get_int(settings, SETTING_COLOR);
-	uint32_t opacity = (uint32_t)obs_data_get_int(settings,
-			SETTING_OPACITY);
-	double contrast = obs_data_get_double(settings, SETTING_CONTRAST);
-	double brightness = obs_data_get_double(settings, SETTING_BRIGHTNESS);
-	double gamma = obs_data_get_double(settings, SETTING_GAMMA);
-
-	color &= 0xFFFFFF;
-	color |= ((opacity * 255) / 100) << 24;
-
-	vec4_from_rgba(&filter->color, color);
-
-	contrast = (contrast < 0.0) ?
-		(1.0 / (-contrast + 1.0)) : (contrast + 1.0);
-
-	brightness *= 0.5;
-
-	gamma = (gamma < 0.0) ? (-gamma + 1.0) : (1.0 / (gamma + 1.0));
-
-	filter->contrast = (float)contrast;
-	filter->brightness = (float)brightness;
-	filter->gamma = (float)gamma;
-}
-
-static void color_filter_destroy(void *data)
-{
-	struct color_filter_data *filter = data;
-
-	if (filter->effect) {
-		obs_enter_graphics();
-		gs_effect_destroy(filter->effect);
-		obs_leave_graphics();
-	}
-
-	bfree(data);
-}
-
-static void *color_filter_create(obs_data_t *settings, obs_source_t *context)
-{
-	struct color_filter_data *filter =
-		bzalloc(sizeof(struct color_filter_data));
-	char *effect_path = obs_module_file("color_filter.effect");
-
-	filter->context = context;
-
-	obs_enter_graphics();
-
-	filter->effect = gs_effect_create_from_file(effect_path, NULL);
-	if (filter->effect) {
-		filter->color_param = gs_effect_get_param_by_name(
-				filter->effect, "color");
-		filter->contrast_param = gs_effect_get_param_by_name(
-				filter->effect, "contrast");
-		filter->brightness_param = gs_effect_get_param_by_name(
-				filter->effect, "brightness");
-		filter->gamma_param = gs_effect_get_param_by_name(
-				filter->effect, "gamma");
-	}
-
-	obs_leave_graphics();
-
-	bfree(effect_path);
-
-	if (!filter->effect) {
-		color_filter_destroy(filter);
-		return NULL;
-	}
-
-	color_filter_update(filter, settings);
-	return filter;
-}
-
-static void color_filter_render(void *data, gs_effect_t *effect)
-{
-	struct color_filter_data *filter = data;
-
-	if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
-				OBS_ALLOW_DIRECT_RENDERING))
-		return;
-
-	gs_effect_set_vec4(filter->color_param, &filter->color);
-	gs_effect_set_float(filter->contrast_param, filter->contrast);
-	gs_effect_set_float(filter->brightness_param, filter->brightness);
-	gs_effect_set_float(filter->gamma_param, filter->gamma);
-
-	obs_source_process_filter_end(filter->context, filter->effect, 0, 0);
-
-	UNUSED_PARAMETER(effect);
-}
-
-static obs_properties_t *color_filter_properties(void *data)
-{
-	obs_properties_t *props = obs_properties_create();
-
-	obs_properties_add_color(props, SETTING_COLOR, TEXT_COLOR);
-	obs_properties_add_int(props, SETTING_OPACITY, TEXT_OPACITY,
-			0, 100, 1);
-	obs_properties_add_float_slider(props, SETTING_CONTRAST,
-			TEXT_CONTRAST, -1.0, 1.0, 0.01);
-	obs_properties_add_float_slider(props, SETTING_BRIGHTNESS,
-			TEXT_BRIGHTNESS, -1.0, 1.0, 0.01);
-	obs_properties_add_float_slider(props, SETTING_GAMMA,
-			TEXT_GAMMA, -1.0, 1.0, 0.01);
-
-	UNUSED_PARAMETER(data);
-	return props;
-}
-
-static void color_filter_defaults(obs_data_t *settings)
-{
-	obs_data_set_default_int(settings, SETTING_COLOR, 0xFFFFFF);
-	obs_data_set_default_int(settings, SETTING_OPACITY, 100);
-	obs_data_set_default_double(settings, SETTING_CONTRAST, 0.0);
-	obs_data_set_default_double(settings, SETTING_BRIGHTNESS, 0.0);
-	obs_data_set_default_double(settings, SETTING_GAMMA, 0.0);
-}
-
-struct obs_source_info color_filter = {
-	.id                            = "color_filter",
-	.type                          = OBS_SOURCE_TYPE_FILTER,
-	.output_flags                  = OBS_SOURCE_VIDEO,
-	.get_name                      = color_filter_name,
-	.create                        = color_filter_create,
-	.destroy                       = color_filter_destroy,
-	.video_render                  = color_filter_render,
-	.update                        = color_filter_update,
-	.get_properties                = color_filter_properties,
-	.get_defaults                  = color_filter_defaults
-};
diff --git a/plugins/obs-filters/color-grade-filter.c b/plugins/obs-filters/color-grade-filter.c
new file mode 100644
index 0000000..8adfdbf
--- /dev/null
+++ b/plugins/obs-filters/color-grade-filter.c
@@ -0,0 +1,159 @@
+#include <obs-module.h>
+#include <graphics/image-file.h>
+#include <util/dstr.h>
+
+#define SETTING_IMAGE_PATH             "image_path"
+#define SETTING_CLUT_AMOUNT            "clut_amount"
+
+#define TEXT_IMAGE_PATH                obs_module_text("Path")
+#define TEXT_AMOUNT                    obs_module_text("Amount")
+
+struct lut_filter_data {
+	obs_source_t                   *context;
+	gs_effect_t                    *effect;
+	gs_texture_t                   *target;
+	gs_image_file_t                image;
+
+	char                           *file;
+	float                          clut_amount;
+};
+
+static const char *color_grade_filter_get_name(void *unused)
+{
+	UNUSED_PARAMETER(unused);
+	return obs_module_text("ColorGradeFilter");
+}
+
+static void color_grade_filter_update(void *data, obs_data_t *settings)
+{
+	struct lut_filter_data *filter = data;
+
+	const char *path = obs_data_get_string(settings, SETTING_IMAGE_PATH);
+	double clut_amount = obs_data_get_double(settings, SETTING_CLUT_AMOUNT);
+
+	bfree(filter->file);
+	if (path)
+		filter->file = bstrdup(path);
+
+	obs_enter_graphics();
+	gs_image_file_free(&filter->image);
+	obs_leave_graphics();
+
+	gs_image_file_init(&filter->image, path);
+
+	obs_enter_graphics();
+
+	gs_image_file_init_texture(&filter->image);
+
+	filter->target = filter->image.texture;
+	filter->clut_amount = (float)clut_amount;
+
+	char *effect_path = obs_module_file("color_grade_filter.effect");
+	gs_effect_destroy(filter->effect);
+	filter->effect = gs_effect_create_from_file(effect_path, NULL);
+	bfree(effect_path);
+
+	obs_leave_graphics();
+}
+
+static void color_grade_filter_defaults(obs_data_t *settings)
+{
+	obs_data_set_default_double(settings, SETTING_CLUT_AMOUNT, 1);
+}
+
+static obs_properties_t *color_grade_filter_properties(void *data)
+{
+	struct lut_filter_data *s = data;
+	struct dstr path = {0};
+	const char *slash;
+
+	obs_properties_t *props = obs_properties_create();
+	struct dstr filter_str = {0};
+
+	dstr_cat(&filter_str, "(*.png)");
+
+	if (s && s->file && *s->file) {
+		dstr_copy(&path, s->file);
+	} else {
+		dstr_copy(&path, obs_module_file("LUTs"));
+		dstr_cat_ch(&path, '/');
+	}
+
+	dstr_replace(&path, "\\", "/");
+	slash = strrchr(path.array, '/');
+	if (slash)
+		dstr_resize(&path, slash - path.array + 1);
+
+	obs_properties_add_path(props, SETTING_IMAGE_PATH, TEXT_IMAGE_PATH,
+			OBS_PATH_FILE, filter_str.array, path.array);
+	obs_properties_add_float_slider(props, SETTING_CLUT_AMOUNT,
+			TEXT_AMOUNT, 0, 1, 0.01);
+
+	dstr_free(&filter_str);
+
+	UNUSED_PARAMETER(data);
+	return props;
+}
+
+static void *color_grade_filter_create(
+		obs_data_t *settings, obs_source_t *context)
+{
+	struct lut_filter_data *filter =
+		bzalloc(sizeof(struct lut_filter_data));
+	filter->context = context;
+
+	obs_source_update(context, settings);
+	return filter;
+}
+
+static void color_grade_filter_destroy(void *data)
+{
+	struct lut_filter_data *filter = data;
+
+	obs_enter_graphics();
+	gs_effect_destroy(filter->effect);
+	gs_image_file_free(&filter->image);
+	obs_leave_graphics();
+
+	bfree(filter->file);
+	bfree(filter);
+}
+
+static void color_grade_filter_render(void *data, gs_effect_t *effect)
+{
+	struct lut_filter_data *filter = data;
+	obs_source_t *target = obs_filter_get_target(filter->context);
+	gs_eparam_t *param;
+
+	if (!target || !filter->target || !filter->effect) {
+		obs_source_skip_video_filter(filter->context);
+		return;
+	}
+
+	if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
+				OBS_ALLOW_DIRECT_RENDERING))
+		return;
+
+	param = gs_effect_get_param_by_name(filter->effect, "clut");
+	gs_effect_set_texture(param, filter->target);
+
+	param = gs_effect_get_param_by_name(filter->effect, "clut_amount");
+	gs_effect_set_float(param, filter->clut_amount);
+
+	obs_source_process_filter_end(filter->context, filter->effect, 0, 0);
+
+	UNUSED_PARAMETER(effect);
+}
+
+struct obs_source_info color_grade_filter = {
+	.id                            = "clut_filter",
+	.type                          = OBS_SOURCE_TYPE_FILTER,
+	.output_flags                  = OBS_SOURCE_VIDEO,
+	.get_name                      = color_grade_filter_get_name,
+	.create                        = color_grade_filter_create,
+	.destroy                       = color_grade_filter_destroy,
+	.update                        = color_grade_filter_update,
+	.get_defaults                  = color_grade_filter_defaults,
+	.get_properties                = color_grade_filter_properties,
+	.video_render                  = color_grade_filter_render
+};
diff --git a/plugins/obs-filters/compressor-filter.c b/plugins/obs-filters/compressor-filter.c
new file mode 100644
index 0000000..4d561a4
--- /dev/null
+++ b/plugins/obs-filters/compressor-filter.c
@@ -0,0 +1,231 @@
+#include <stdint.h>
+#include <inttypes.h>
+#include <math.h>
+
+#include <obs-module.h>
+#include <media-io/audio-math.h>
+
+/* -------------------------------------------------------- */
+
+#define do_log(level, format, ...) \
+	blog(level, "[compressor: '%s'] " format, \
+			obs_source_get_name(cd->context), ##__VA_ARGS__)
+
+#define warn(format, ...)  do_log(LOG_WARNING, format, ##__VA_ARGS__)
+#define info(format, ...)  do_log(LOG_INFO,    format, ##__VA_ARGS__)
+
+#ifdef _DEBUG
+#define debug(format, ...) do_log(LOG_DEBUG,   format, ##__VA_ARGS__)
+#else
+#define debug(format, ...)
+#endif
+
+/* -------------------------------------------------------- */
+
+#define S_RATIO                         "ratio"
+#define S_THRESHOLD                     "threshold"
+#define S_ATTACK_TIME                   "attack_time"
+#define S_RELEASE_TIME                  "release_time"
+#define S_OUTPUT_GAIN                   "output_gain"
+
+#define MT_ obs_module_text
+#define TEXT_RATIO                      MT_("Compressor.Ratio")
+#define TEXT_THRESHOLD                  MT_("Compressor.Threshold")
+#define TEXT_ATTACK_TIME                MT_("Compressor.AttackTime")
+#define TEXT_RELEASE_TIME               MT_("Compressor.ReleaseTime")
+#define TEXT_OUTPUT_GAIN                MT_("Compressor.OutputGain")
+
+#define MIN_RATIO                       1.0f
+#define MAX_RATIO                       32.0f
+#define MIN_THRESHOLD_DB                -60.0f
+#define MAX_THRESHOLD_DB                0.0f
+#define MIN_OUTPUT_GAIN_DB              -32.0f
+#define MAX_OUTPUT_GAIN_DB              32.0f
+#define MIN_ATK_RLS_MS                  1
+#define MAX_RLS_MS                      1000
+#define MAX_ATK_MS                      500
+#define DEFAULT_AUDIO_BUF_MS            10
+
+#define MS_IN_S                         1000
+#define MS_IN_S_F                       ((float)MS_IN_S)
+
+/* -------------------------------------------------------- */
+
+struct compressor_data {
+	obs_source_t *context;
+	float *envelope_buf;
+	size_t envelope_buf_len;
+
+	float ratio;
+	float threshold;
+	float attack_gain;
+	float release_gain;
+	float output_gain;
+
+	size_t num_channels;
+	float envelope;
+	float slope;
+};
+
+/* -------------------------------------------------------- */
+
+static inline void resize_env_buffer(struct compressor_data *cd, size_t len)
+{
+	cd->envelope_buf_len = len;
+	cd->envelope_buf = brealloc(cd->envelope_buf, len * sizeof(float));
+}
+
+static inline float gain_coefficient(uint32_t sample_rate, float time)
+{
+	return (float)exp(-1.0f / (sample_rate * time));
+}
+
+static const char *compressor_name(void *unused)
+{
+	UNUSED_PARAMETER(unused);
+	return obs_module_text("Compressor");
+}
+
+static void compressor_update(void *data, obs_data_t *s)
+{
+	struct compressor_data *cd = data;
+
+	const uint32_t sample_rate =
+		audio_output_get_sample_rate(obs_get_audio());
+	const size_t num_channels =
+		audio_output_get_channels(obs_get_audio());
+	const float attack_time_ms =
+		(float)obs_data_get_int(s, S_ATTACK_TIME);
+	const float release_time_ms =
+		(float)obs_data_get_int(s, S_RELEASE_TIME);
+	const float output_gain_db =
+		(float)obs_data_get_double(s, S_OUTPUT_GAIN);
+
+	if (cd->envelope_buf_len <= 0) {
+		resize_env_buffer(cd,
+				sample_rate * DEFAULT_AUDIO_BUF_MS / MS_IN_S);
+	}
+
+	cd->ratio = (float)obs_data_get_double(s, S_RATIO);
+	cd->threshold = (float)obs_data_get_double(s, S_THRESHOLD);
+	cd->attack_gain = gain_coefficient(sample_rate,
+			attack_time_ms / MS_IN_S_F);
+	cd->release_gain = gain_coefficient(sample_rate,
+			release_time_ms / MS_IN_S_F);
+	cd->output_gain = db_to_mul(output_gain_db);
+	cd->num_channels = num_channels;
+	cd->slope = 1.0f - (1.0f / cd->ratio);
+}
+
+static void *compressor_create(obs_data_t *settings, obs_source_t *filter)
+{
+	struct compressor_data *cd = bzalloc(sizeof(struct compressor_data));
+	cd->context = filter;
+	compressor_update(cd, settings);
+	return cd;
+}
+
+static void compressor_destroy(void *data)
+{
+	struct compressor_data *cd = data;
+	bfree(cd->envelope_buf);
+	bfree(cd);
+}
+
+static inline void analyze_envelope(struct compressor_data *cd,
+	const float **samples, const uint32_t num_samples)
+{
+	if (cd->envelope_buf_len < num_samples) {
+		resize_env_buffer(cd, num_samples);
+	}
+
+	memset(cd->envelope_buf, 0, num_samples * sizeof(cd->envelope_buf[0]));
+	for (size_t chan = 0; chan < cd->num_channels; ++chan) {
+		if (samples[chan]) {
+			float env = cd->envelope;
+			for (uint32_t i = 0; i < num_samples; ++i) {
+				const float env_in = fabsf(samples[chan][i]);
+				if (env < env_in) {
+					env = env_in + cd->attack_gain *
+						(env - env_in);
+				} else {
+					env = env_in + cd->release_gain *
+						(env - env_in);
+				}
+				cd->envelope_buf[i] = fmaxf(
+						cd->envelope_buf[i], env);
+			}
+		}
+	}
+	cd->envelope = cd->envelope_buf[num_samples - 1];
+}
+
+static inline void process_compression(const struct compressor_data *cd,
+	float **samples, uint32_t num_samples)
+{
+	for (size_t i = 0; i < num_samples; ++i) {
+		const float env_db = mul_to_db(cd->envelope_buf[i]);
+		float gain = cd->slope * (cd->threshold - env_db);
+		gain = db_to_mul(fminf(0, gain));
+
+		for (size_t c = 0; c < cd->num_channels; ++c) {
+			if (samples[c]) {
+				samples[c][i] *= gain * cd->output_gain;
+			}
+		}
+	}
+}
+
+static struct obs_audio_data *compressor_filter_audio(void *data,
+	struct obs_audio_data *audio)
+{
+	struct compressor_data *cd = data;
+	const uint32_t num_samples = audio->frames;
+	float **samples = (float**)audio->data;
+
+	analyze_envelope(cd, samples, num_samples);
+	process_compression(cd, samples, num_samples);
+
+	return audio;
+}
+
+static void compressor_defaults(obs_data_t *s)
+{
+	obs_data_set_default_double(s, S_RATIO, 10.0f);
+	obs_data_set_default_double(s, S_THRESHOLD, -18.0f);
+	obs_data_set_default_int(s, S_ATTACK_TIME, 6);
+	obs_data_set_default_int(s, S_RELEASE_TIME, 60);
+	obs_data_set_default_double(s, S_OUTPUT_GAIN, 0.0f);
+}
+
+static obs_properties_t *compressor_properties(void *data)
+{
+	obs_properties_t *props = obs_properties_create();
+
+	obs_properties_add_float_slider(props, S_RATIO,
+		TEXT_RATIO, MIN_RATIO, MAX_RATIO, 0.5f);
+	obs_properties_add_float_slider(props, S_THRESHOLD,
+		TEXT_THRESHOLD, MIN_THRESHOLD_DB, MAX_THRESHOLD_DB, 0.1f);
+	obs_properties_add_int_slider(props, S_ATTACK_TIME,
+		TEXT_ATTACK_TIME, MIN_ATK_RLS_MS, MAX_ATK_MS, 1);
+	obs_properties_add_int_slider(props, S_RELEASE_TIME,
+		TEXT_RELEASE_TIME, MIN_ATK_RLS_MS, MAX_RLS_MS, 1);
+	obs_properties_add_float_slider(props, S_OUTPUT_GAIN,
+		TEXT_OUTPUT_GAIN, MIN_OUTPUT_GAIN_DB, MAX_OUTPUT_GAIN_DB, 0.1f);
+
+	UNUSED_PARAMETER(data);
+	return props;
+}
+
+struct obs_source_info compressor_filter = {
+	.id = "compressor_filter",
+	.type = OBS_SOURCE_TYPE_FILTER,
+	.output_flags = OBS_SOURCE_AUDIO,
+	.get_name = compressor_name,
+	.create = compressor_create,
+	.destroy = compressor_destroy,
+	.update = compressor_update,
+	.filter_audio = compressor_filter_audio,
+	.get_defaults = compressor_defaults,
+	.get_properties = compressor_properties,
+};
diff --git a/plugins/obs-filters/data/LUTs/black_and_white.png b/plugins/obs-filters/data/LUTs/black_and_white.png
new file mode 100644
index 0000000..d55914c
Binary files /dev/null and b/plugins/obs-filters/data/LUTs/black_and_white.png differ
diff --git a/plugins/obs-filters/data/LUTs/original.png b/plugins/obs-filters/data/LUTs/original.png
new file mode 100644
index 0000000..ed814df
Binary files /dev/null and b/plugins/obs-filters/data/LUTs/original.png differ
diff --git a/plugins/obs-filters/data/LUTs/posterize.png b/plugins/obs-filters/data/LUTs/posterize.png
new file mode 100644
index 0000000..2ef1e1d
Binary files /dev/null and b/plugins/obs-filters/data/LUTs/posterize.png differ
diff --git a/plugins/obs-filters/data/LUTs/red_isolated.png b/plugins/obs-filters/data/LUTs/red_isolated.png
new file mode 100644
index 0000000..624dc97
Binary files /dev/null and b/plugins/obs-filters/data/LUTs/red_isolated.png differ
diff --git a/plugins/obs-filters/data/LUTs/teal_lows_orange_highs.png b/plugins/obs-filters/data/LUTs/teal_lows_orange_highs.png
new file mode 100644
index 0000000..abc162c
Binary files /dev/null and b/plugins/obs-filters/data/LUTs/teal_lows_orange_highs.png differ
diff --git a/plugins/obs-filters/data/color_correction_filter.effect b/plugins/obs-filters/data/color_correction_filter.effect
new file mode 100644
index 0000000..7d599b6
--- /dev/null
+++ b/plugins/obs-filters/data/color_correction_filter.effect
@@ -0,0 +1,71 @@
+/*****************************************************************************
+Copyright (C) 2016 by c3r1c3 <c3r1c3 at nevermindonline.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+uniform float4x4 ViewProj;
+uniform texture2d image;
+
+uniform float3 gamma;
+
+/* Pre-Compute variables. */
+uniform float4x4 color_matrix;
+
+
+sampler_state textureSampler {
+	Filter   = Linear;
+	AddressU = Clamp;
+	AddressV = Clamp;
+};
+
+struct VertData {
+	float4 pos : POSITION;
+	float2 uv : TEXCOORD0;
+};
+
+VertData VSDefault(VertData vert_in)
+{
+	VertData vert_out;
+	vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
+	vert_out.uv = vert_in.uv;
+	return vert_out;
+}
+
+float4 PSColorFilterRGBA(VertData vert_in) : TARGET
+{
+	/* Grab the current pixel to perform operations on. */
+	float4 currentPixel = image.Sample(textureSampler, vert_in.uv);
+
+	/* Always address the gamma first. */
+	currentPixel.rgb = pow(currentPixel.rgb, gamma);
+
+	/* Much easier to manipulate pixels for these types of operations
+	 * when in a matrix such as the below. See
+	 * http://www.graficaobscura.com/matrix/index.html and
+	 * https://docs.rainmeter.net/tips/colormatrix-guide/for more info.
+	 */
+	currentPixel = mul(color_matrix, currentPixel);
+
+	return currentPixel;
+}
+
+technique Draw
+{
+	pass
+	{
+		vertex_shader = VSDefault(vert_in);
+		pixel_shader = PSColorFilterRGBA(vert_in);
+	}
+}
diff --git a/plugins/obs-filters/data/color_filter.effect b/plugins/obs-filters/data/color_filter.effect
deleted file mode 100644
index 5f4eecd..0000000
--- a/plugins/obs-filters/data/color_filter.effect
+++ /dev/null
@@ -1,46 +0,0 @@
-uniform float4x4 ViewProj;
-uniform texture2d image;
-
-uniform float4 color;
-uniform float contrast;
-uniform float brightness;
-uniform float gamma;
-
-sampler_state textureSampler {
-	Filter    = Linear;
-	AddressU  = Clamp;
-	AddressV  = Clamp;
-};
-
-struct VertData {
-	float4 pos : POSITION;
-	float2 uv  : TEXCOORD0;
-};
-
-VertData VSDefault(VertData v_in)
-{
-	VertData vert_out;
-	vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
-	vert_out.uv  = v_in.uv;
-	return vert_out;
-}
-
-float4 CalcColor(float4 rgba)
-{
-	return float4(pow(rgba.rgb, float3(gamma, gamma, gamma)) * contrast + brightness, rgba.a);
-}
-
-float4 PSColorFilterRGBA(VertData v_in) : TARGET
-{
-	float4 rgba = image.Sample(textureSampler, v_in.uv) * color;
-	return CalcColor(rgba);
-}
-
-technique Draw
-{
-	pass
-	{
-		vertex_shader = VSDefault(v_in);
-		pixel_shader  = PSColorFilterRGBA(v_in);
-	}
-}
diff --git a/plugins/obs-filters/data/color_grade_filter.effect b/plugins/obs-filters/data/color_grade_filter.effect
new file mode 100644
index 0000000..bbc8b5e
--- /dev/null
+++ b/plugins/obs-filters/data/color_grade_filter.effect
@@ -0,0 +1,66 @@
+uniform float4x4 ViewProj;
+uniform texture2d image;
+
+uniform texture2d clut;
+uniform float clut_amount;
+
+sampler_state textureSampler {
+	Filter    = Linear;
+	AddressU  = Clamp;
+	AddressV  = Clamp;
+};
+
+struct VertDataIn {
+	float4 pos : POSITION;
+	float2 uv  : TEXCOORD0;
+};
+
+struct VertDataOut {
+	float4 pos : POSITION;
+	float2 uv  : TEXCOORD0;
+};
+
+VertDataOut VSDefault(VertDataIn v_in)
+{
+	VertDataOut vert_out;
+	vert_out.uv = v_in.uv;
+	vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
+	return vert_out;
+}
+
+float4 LUT(VertDataOut v_in) : TARGET
+{
+	float4 textureColor = image.Sample(textureSampler, v_in.uv);
+	float blueColor = textureColor.b * 63.0;
+
+	float2 quad1;
+	quad1.y = floor(floor(blueColor) / 8.0);
+	quad1.x = floor(blueColor) - (quad1.y * 8.0);
+
+	float2 quad2;
+	quad2.y = floor(ceil(blueColor) / 8.0);
+	quad2.x = ceil(blueColor) - (quad2.y * 8.0);
+
+	float2 texPos1;
+	texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
+	texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);
+
+	float2 texPos2;
+	texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
+	texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);
+
+	float4 newColor1 = clut.Sample(textureSampler, texPos1);
+	float4 newColor2 = clut.Sample(textureSampler, texPos2);
+	float4 luttedColor = lerp(newColor1, newColor2, frac(blueColor));
+
+	return lerp(textureColor, luttedColor, clut_amount);
+}
+
+technique Draw
+{
+	pass
+	{
+		vertex_shader = VSDefault(v_in);
+		pixel_shader  = LUT(v_in);
+	}
+}
diff --git a/plugins/obs-filters/data/locale/ca-ES.ini b/plugins/obs-filters/data/locale/ca-ES.ini
index 4c188e9..0229054 100644
--- a/plugins/obs-filters/data/locale/ca-ES.ini
+++ b/plugins/obs-filters/data/locale/ca-ES.ini
@@ -1,4 +1,5 @@
 ColorFilter="Correcció de color"
+ColorGradeFilter="Aplica LUT"
 MaskFilter="Màscara d'imatge o barreja"
 AsyncDelayFilter="Retard del vídeo (asíncron)"
 CropFilter="Escapça/Encoixinar"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Clau croma"
 ColorKeyFilter="Clau de color"
 SharpnessFilter="Agudesa"
 ScaleFilter="Escala/Relació d'Aspecte"
+UndistortCenter="No distorsionis el centre de la imatge en escalar des d'una ultrapanoràmica"
 NoiseGate="Porta de soroll"
 NoiseSuppress="Supressió de soroll"
 Gain="Guany"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="Bilineal"
 ScaleFiltering.Bicubic="Bicúbic"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Nivell de supressió (dB)"
+Saturation="Saturació"
+HueShift="Cavi de tonalitat"
+Amount="Quantitat"
+Compressor="Compressor"
+Compressor.Ratio="Proporció (X:1)"
+Compressor.Threshold="Llindar (dB)"
+Compressor.AttackTime="Atac (ms)"
+Compressor.ReleaseTime="Llançament (ms)"
+Compressor.OutputGain="Guany de sortida (dB)"
 
diff --git a/plugins/obs-filters/data/locale/cs-CZ.ini b/plugins/obs-filters/data/locale/cs-CZ.ini
index 15a2202..56d0741 100644
--- a/plugins/obs-filters/data/locale/cs-CZ.ini
+++ b/plugins/obs-filters/data/locale/cs-CZ.ini
@@ -1,4 +1,5 @@
 ColorFilter="Korekce barev"
+ColorGradeFilter="Použít LUT"
 MaskFilter="Maska obrazu/prolnutí"
 AsyncDelayFilter="Zpoždění obrazu"
 CropFilter="Oříznutí/odsazení"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Chroma Key"
 ColorKeyFilter="Klíč barvy"
 SharpnessFilter="Ostření"
 ScaleFilter="Škálování/poměr stran"
+UndistortCenter="Zlepší střed obrázku při škálování z ultra-širokého obrazu"
 NoiseGate="Šumová brána"
 NoiseSuppress="Potlačení šumu"
 Gain="Zisk"
@@ -61,4 +63,7 @@ ScaleFiltering.Bilinear="Bilineární"
 ScaleFiltering.Bicubic="Bikubický"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Úroveň potlačení (dB)"
+Saturation="Saturace"
+HueShift="Posun odstínu"
+Amount="Množství"
 
diff --git a/plugins/obs-filters/data/locale/da-DK.ini b/plugins/obs-filters/data/locale/da-DK.ini
index 11a7dec..6e4029c 100644
--- a/plugins/obs-filters/data/locale/da-DK.ini
+++ b/plugins/obs-filters/data/locale/da-DK.ini
@@ -1,11 +1,16 @@
 ColorFilter="Farvekorrektion"
+ColorGradeFilter="Anvend LUT"
 MaskFilter="Billede maske/blanding"
 AsyncDelayFilter="Video forsinkelse (asynkron)"
+CropFilter="Beskæring/Polstring"
 ScrollFilter="Rul"
 ChromaKeyFilter="Chroma nøgle"
 ColorKeyFilter="Farvenøgle"
 SharpnessFilter="Skarphed"
+ScaleFilter="Skalering/Formatforhold"
+UndistortCenter="Fjern forvrængning af billedets midte ved skalering fra ultrabred"
 NoiseGate="Noise Gate"
+NoiseSuppress="Støjundertrykkelse"
 Gain="Forstærkning"
 DelayMs="Forsinkelse (millisekunder)"
 Type="Type"
@@ -43,6 +48,22 @@ Red="Rød"
 Green="Grøn"
 Blue="Blå"
 Magenta="Magenta"
+NoiseGate.OpenThreshold="Åbne-tærskel (dB)"
+NoiseGate.CloseThreshold="Lukke-tærskel (dB)"
+NoiseGate.AttackTime="Effektueringstid (millisek.)"
+NoiseGate.HoldTime="Holdetid (millisek.)"
+NoiseGate.ReleaseTime="Frigivelsestid (millisek.)"
 Gain.GainDB="Forstærkning (dB)"
 StretchImage="Stræk billedet (ignorer størrelsesforhold)"
+Resolution="Opløsning"
+None="Ingen"
+ScaleFiltering="Skaleringsfilter"
+ScaleFiltering.Point="Punkt"
+ScaleFiltering.Bilinear="Bilineær"
+ScaleFiltering.Bicubic="Bikubisk"
+ScaleFiltering.Lanczos="Lanczos"
+NoiseSuppress.SuppressLevel="Undertrykkelsesniveau (dB)"
+Saturation="Mætning"
+HueShift="Nuanceskift"
+Amount="Værdi"
 
diff --git a/plugins/obs-filters/data/locale/de-DE.ini b/plugins/obs-filters/data/locale/de-DE.ini
index 7855d36..1686a36 100644
--- a/plugins/obs-filters/data/locale/de-DE.ini
+++ b/plugins/obs-filters/data/locale/de-DE.ini
@@ -1,4 +1,5 @@
 ColorFilter="Farbkorrektur"
+ColorGradeFilter="LUT anwenden"
 MaskFilter="Bild Maske/Blend"
 AsyncDelayFilter="Videoverzögerung (Asynchron)"
 CropFilter="Zuschneiden/Pad"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Chroma Key"
 ColorKeyFilter="Color Key"
 SharpnessFilter="Schärfen"
 ScaleFilter="Skalierung/Seitenverhältnis"
+UndistortCenter="Entzerre Mitte des Bildes bei der Skalierung von Ultraweitwinkel"
 NoiseGate="Noise Gate"
 NoiseSuppress="Rauschunterdrückung"
 Gain="Gain"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="Bilinear"
 ScaleFiltering.Bicubic="Bicubic"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Unterdrückungspegel (dB)"
+Saturation="Sättigung"
+HueShift="Farbtonverschiebung"
+Amount="Betrag"
+Compressor="Kompressor"
+Compressor.Ratio="Verhältnis (X:1)"
+Compressor.Threshold="Schwelle (dB)"
+Compressor.AttackTime="Angriff (ms)"
+Compressor.ReleaseTime="Freigabe (ms)"
+Compressor.OutputGain="Ausgangspegel (dB)"
 
diff --git a/plugins/obs-filters/data/locale/en-US.ini b/plugins/obs-filters/data/locale/en-US.ini
index 95b8c43..e183d03 100644
--- a/plugins/obs-filters/data/locale/en-US.ini
+++ b/plugins/obs-filters/data/locale/en-US.ini
@@ -1,4 +1,5 @@
 ColorFilter="Color Correction"
+ColorGradeFilter="Apply LUT"
 MaskFilter="Image Mask/Blend"
 AsyncDelayFilter="Video Delay (Async)"
 CropFilter="Crop/Pad"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Chroma Key"
 ColorKeyFilter="Color Key"
 SharpnessFilter="Sharpen"
 ScaleFilter="Scaling/Aspect Ratio"
+UndistortCenter="Undistort center of image when scaling from ultrawide"
 NoiseGate="Noise Gate"
 NoiseSuppress="Noise Suppression"
 Gain="Gain"
@@ -61,3 +63,12 @@ ScaleFiltering.Bilinear="Bilinear"
 ScaleFiltering.Bicubic="Bicubic"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Suppression Level (dB)"
+Saturation="Saturation"
+HueShift="Hue Shift"
+Amount="Amount"
+Compressor="Compressor"
+Compressor.Ratio="Ratio (X:1)"
+Compressor.Threshold="Threshold (dB)"
+Compressor.AttackTime="Attack (ms)"
+Compressor.ReleaseTime="Release (ms)"
+Compressor.OutputGain="Output Gain (dB)"
diff --git a/plugins/obs-filters/data/locale/es-ES.ini b/plugins/obs-filters/data/locale/es-ES.ini
index 506f1e3..f025a15 100644
--- a/plugins/obs-filters/data/locale/es-ES.ini
+++ b/plugins/obs-filters/data/locale/es-ES.ini
@@ -1,4 +1,5 @@
 ColorFilter="Corrección de color"
+ColorGradeFilter="Aplicar LUT"
 MaskFilter="Imagen máscara/mezcla"
 AsyncDelayFilter="Demora de Video (asincróno)"
 CropFilter="Recortar/Acolchar"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Fondro croma"
 ColorKeyFilter="Filtro de color"
 SharpnessFilter="Filtro de enfoque"
 ScaleFilter="Escala/Relación de Aspecto"
+UndistortCenter="No distorsionar el centro de la imagen en escalar des de una ultrapanorámica"
 NoiseGate="Puerta anti-ruidos"
 NoiseSuppress="Eliminación de ruido"
 Gain="Ganancia"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="Bilineal"
 ScaleFiltering.Bicubic="Bicúbico"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Nivel de eliminación de ruido (dB)"
+Saturation="Saturación"
+HueShift="Cambio de tonalidad"
+Amount="Cantidad"
+Compressor="Compresor"
+Compressor.Ratio="Relación (X:1)"
+Compressor.Threshold="Umbral (dB)"
+Compressor.AttackTime="Ataque (ms)"
+Compressor.ReleaseTime="Liberación (ms)"
+Compressor.OutputGain="Ganancia de salida (dB)"
 
diff --git a/plugins/obs-filters/data/locale/et-EE.ini b/plugins/obs-filters/data/locale/et-EE.ini
new file mode 100644
index 0000000..8cac372
--- /dev/null
+++ b/plugins/obs-filters/data/locale/et-EE.ini
@@ -0,0 +1,16 @@
+ColorFilter="Värvi korrektsioon"
+ColorGradeFilter="Lisa LUT"
+Gain="Võimendus"
+Contrast="Kontrast"
+Brightness="Heledus"
+Gamma="Gamma"
+BrowsePath.Images="Kõik pildifailid"
+Crop.Left="Vasakult"
+Crop.Right="Paremalt"
+Crop.Top="Ãœlevalt"
+Crop.Bottom="Alt"
+Crop.Width="Laius"
+Crop.Height="Kõrgus"
+Crop.Relative="Suhteline"
+Amount="Kogus"
+
diff --git a/plugins/obs-filters/data/locale/eu-ES.ini b/plugins/obs-filters/data/locale/eu-ES.ini
index 63525e4..6f18330 100644
--- a/plugins/obs-filters/data/locale/eu-ES.ini
+++ b/plugins/obs-filters/data/locale/eu-ES.ini
@@ -1,4 +1,5 @@
 ColorFilter="Kolore-zuzenketa"
+ColorGradeFilter="Aplikatu LUT"
 MaskFilter="Irudi maskara/nahasketa"
 AsyncDelayFilter="Bideo atzerapena (Async)"
 CropFilter="Moztu/Bete"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Kroma gakoa"
 ColorKeyFilter="Kolore gakoa"
 SharpnessFilter="Enfokea"
 ScaleFilter="Eskala/Aspektu-erlazioa"
+UndistortCenter="Ez distortsionatu irudiaren erdigunea ultra zabala eskalatzean"
 NoiseGate="Zarata atalasea"
 NoiseSuppress="Zarata kendu"
 Gain="Irabazia"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="Bilineala"
 ScaleFiltering.Bicubic="Bikubikoa"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Kenketaren maila (dB)"
+Saturation="Margoasetasuna"
+HueShift="Nabardura Aldaketa"
+Amount="Zenbatekoa"
+Compressor="Konprimitzailea"
+Compressor.Ratio="Erlazioa (X:1)"
+Compressor.Threshold="Atalasea (dB)"
+Compressor.AttackTime="Erasoa (ms)"
+Compressor.ReleaseTime="Askapena (ms)"
+Compressor.OutputGain="Irteerako irabazia (dB)"
 
diff --git a/plugins/obs-filters/data/locale/fi-FI.ini b/plugins/obs-filters/data/locale/fi-FI.ini
index 7622a47..8572128 100644
--- a/plugins/obs-filters/data/locale/fi-FI.ini
+++ b/plugins/obs-filters/data/locale/fi-FI.ini
@@ -1,4 +1,5 @@
 ColorFilter="Värinkorjaus"
+ColorGradeFilter="Käytä LUT"
 MaskFilter="Kuvamaski/Sekoitus"
 AsyncDelayFilter="Kuvan viive (Async)"
 CropFilter="Rajaa"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Läpinäkyvä tausta"
 ColorKeyFilter="Väriavain"
 SharpnessFilter="Terävöitä"
 ScaleFilter="Skaalaus/Kuvasuhde"
+UndistortCenter="Poista vääristymä keskeltä kuvaa skaalattaessa ultra-leveästä"
 NoiseGate="Noise Gate"
 NoiseSuppress="Melunvaimennus"
 Gain="Vahvistus"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="Bilinear"
 ScaleFiltering.Bicubic="Bicubic"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Vaimennustaso (dB)"
+Saturation="Värikylläisyys"
+HueShift="Värisävy"
+Amount="Määrä"
+Compressor="Kompressori"
+Compressor.Ratio="Suhde (X:1)"
+Compressor.Threshold="Kynnysarvo (dB)"
+Compressor.AttackTime="Attack-aika (ms)"
+Compressor.ReleaseTime="Vapautumisaika (ms)"
+Compressor.OutputGain="Signaalin vahvistus (dB)"
 
diff --git a/plugins/obs-filters/data/locale/fr-FR.ini b/plugins/obs-filters/data/locale/fr-FR.ini
index bdfedaf..64bed1e 100644
--- a/plugins/obs-filters/data/locale/fr-FR.ini
+++ b/plugins/obs-filters/data/locale/fr-FR.ini
@@ -1,4 +1,5 @@
 ColorFilter="Corrections colorimétrique"
+ColorGradeFilter="Appliquer LUT"
 MaskFilter="Masque d'image/mélange"
 AsyncDelayFilter="Retard vidéo (async.)"
 CropFilter="Rogner / Encadrer"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Clé chromatique"
 ColorKeyFilter="Couleur d'incrustation"
 SharpnessFilter="Accentuer"
 ScaleFilter="Mise à l’échelle / Ratio d'affichage"
+UndistortCenter="Ne pas déformer le centre de l'image lors d'une mise à l'échelle ultra large"
 NoiseGate="Noise Gate"
 NoiseSuppress="Suppression du bruit"
 Gain="Gain"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="Bilinéaire"
 ScaleFiltering.Bicubic="Bicubique"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Seuil de suppression (en dB)"
+Saturation="Saturation"
+HueShift="Décalage de teinte"
+Amount="Quantité"
+Compressor="Compresseur"
+Compressor.Ratio="Ratio (X:1)"
+Compressor.Threshold="Seuil (dB)"
+Compressor.AttackTime="Attaque (ms)"
+Compressor.ReleaseTime="Libération (ms)"
+Compressor.OutputGain="Sortie Gain (dB)"
 
diff --git a/plugins/obs-filters/data/locale/hu-HU.ini b/plugins/obs-filters/data/locale/hu-HU.ini
index 885f430..9f548bb 100644
--- a/plugins/obs-filters/data/locale/hu-HU.ini
+++ b/plugins/obs-filters/data/locale/hu-HU.ini
@@ -1,4 +1,5 @@
 ColorFilter="Színkorrekció"
+ColorGradeFilter="LUT alkalmazása"
 MaskFilter="Képmaszk/Keverés"
 AsyncDelayFilter="Videó késleltetés (Async)"
 CropFilter="Vágás/Margó"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Chroma kulcs"
 ColorKeyFilter="Színkulcs"
 SharpnessFilter="Élesítés"
 ScaleFilter="Méretezés/Képarány"
+UndistortCenter="Kép közepének zavarosságának a csökkentése ultraszélesről való skálázás esetén"
 NoiseGate="Zajgát"
 NoiseSuppress="Zajcsökkentés"
 Gain="Erősítés"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="Bilineáris"
 ScaleFiltering.Bicubic="Kettős köbös"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Csökkentési szint (dB)"
+Saturation="Telítettség"
+HueShift="Színezet váltása"
+Amount="Mennyiség"
+Compressor="Kompresszor"
+Compressor.Ratio="Arány (X:1)"
+Compressor.Threshold="Küszöb (dB)"
+Compressor.AttackTime="Aktiválás (ms)"
+Compressor.ReleaseTime="Felengedés (ms)"
+Compressor.OutputGain="Kimeneti erősítés (dB)"
 
diff --git a/plugins/obs-filters/data/locale/it-IT.ini b/plugins/obs-filters/data/locale/it-IT.ini
index 409cb00..028f31b 100644
--- a/plugins/obs-filters/data/locale/it-IT.ini
+++ b/plugins/obs-filters/data/locale/it-IT.ini
@@ -1,4 +1,5 @@
 ColorFilter="Correzione colore"
+ColorGradeFilter="Applica LUT"
 MaskFilter="Immagine maschera/miscela"
 AsyncDelayFilter="Ritardo video (Asincrono)"
 CropFilter="Crop/Pad"
@@ -61,4 +62,6 @@ ScaleFiltering.Bilinear="Bilineare"
 ScaleFiltering.Bicubic="Bicubico"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Livello di soppressione (dB)"
+Saturation="Saturazione"
+HueShift="Cambio di tonalità"
 
diff --git a/plugins/obs-filters/data/locale/ja-JP.ini b/plugins/obs-filters/data/locale/ja-JP.ini
index d91c48f..6827ced 100644
--- a/plugins/obs-filters/data/locale/ja-JP.ini
+++ b/plugins/obs-filters/data/locale/ja-JP.ini
@@ -1,4 +1,5 @@
 ColorFilter="色補正"
+ColorGradeFilter="LUT を適用"
 MaskFilter="イメージ マスク/ブレンド"
 AsyncDelayFilter="映像の遅延 (非同期)"
 CropFilter="クロップ/パッド"
@@ -7,6 +8,7 @@ ChromaKeyFilter="クロマキー"
 ColorKeyFilter="カラーキー"
 SharpnessFilter="シャープ"
 ScaleFilter="スケーリング/アスペクト比"
+UndistortCenter="超広角からスケーリングするときに画像の中心を歪めない"
 NoiseGate="ノイズゲート"
 NoiseSuppress="ノイズ抑制"
 Gain="ゲイン"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="バイリニア"
 ScaleFiltering.Bicubic="バイキュービック"
 ScaleFiltering.Lanczos="ランチョス"
 NoiseSuppress.SuppressLevel="抑制レベル (dB)"
+Saturation="彩度"
+HueShift="色相シフト"
+Amount="量"
+Compressor="コンプレッサー"
+Compressor.Ratio="比率 (X:1)"
+Compressor.Threshold="閾値 (dB)"
+Compressor.AttackTime="アタックタイム (ms)"
+Compressor.ReleaseTime="リリースタイム (ms)"
+Compressor.OutputGain="出力ゲイン (dB)"
 
diff --git a/plugins/obs-filters/data/locale/ko-KR.ini b/plugins/obs-filters/data/locale/ko-KR.ini
index 1470851..775008f 100644
--- a/plugins/obs-filters/data/locale/ko-KR.ini
+++ b/plugins/obs-filters/data/locale/ko-KR.ini
@@ -1,4 +1,5 @@
 ColorFilter="색상 보정"
+ColorGradeFilter="LUT 적용"
 MaskFilter="이미지 마스크/혼합"
 AsyncDelayFilter="비디오 지연 (비동기)"
 CropFilter="자르기/덧대기"
@@ -7,6 +8,7 @@ ChromaKeyFilter="크로마 키"
 ColorKeyFilter="색상 키"
 SharpnessFilter="선명하게"
 ScaleFilter="비례축소/가로세로 비율"
+UndistortCenter="울트라와이드에서 크기조정 시 이미지 중앙의 왜곡을 수정"
 NoiseGate="노이즈 게이트"
 NoiseSuppress="소음 억제"
 Gain="증폭"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="이중선형"
 ScaleFiltering.Bicubic="쌍삼차"
 ScaleFiltering.Lanczos="란초스"
 NoiseSuppress.SuppressLevel="억제 세기 (dB)"
+Saturation="채도"
+HueShift="색조 변화"
+Amount="ì–‘"
+Compressor="압축방식"
+Compressor.Ratio="비율 (X:1)"
+Compressor.Threshold="임계값 (dB)"
+Compressor.AttackTime="신호 감지 후 반응까지 걸리는 시간 (ms)"
+Compressor.ReleaseTime="신호 세기가 감퇴 이후 증폭이 회복하는 시간 (ms)"
+Compressor.OutputGain="출력 증폭 (dB)"
 
diff --git a/plugins/obs-filters/data/locale/nb-NO.ini b/plugins/obs-filters/data/locale/nb-NO.ini
index 2c517b3..eb1b94c 100644
--- a/plugins/obs-filters/data/locale/nb-NO.ini
+++ b/plugins/obs-filters/data/locale/nb-NO.ini
@@ -6,7 +6,9 @@ ScrollFilter="Rull"
 ChromaKeyFilter="Chromafilter"
 ColorKeyFilter="Fargefilter"
 SharpnessFilter="Skjerpe"
+ScaleFilter="Skalering/Aspekt Forhold"
 NoiseGate="Støyterskel"
+NoiseSuppress="Lyddemping"
 Gain="Forsterkning"
 DelayMs="Forsinkelse (millisekunder)"
 Type="Type"
@@ -51,4 +53,11 @@ NoiseGate.HoldTime="Holdetid (millisekunder)"
 NoiseGate.ReleaseTime="Løslatelsestid (millisekunder)"
 Gain.GainDB="Forsterkning (dB)"
 StretchImage="Strekk bilde (ignorer bildets sideforhold)"
+Resolution="Oppløsning"
+None="Ingen"
+ScaleFiltering="Skala Filtrering"
+ScaleFiltering.Point="Punkt"
+NoiseSuppress.SuppressLevel="Dempelse Nivå (dB)"
+Saturation="Metning"
+HueShift="Fargetone Skifte"
 
diff --git a/plugins/obs-filters/data/locale/nl-NL.ini b/plugins/obs-filters/data/locale/nl-NL.ini
index ae56ef9..4c1597c 100644
--- a/plugins/obs-filters/data/locale/nl-NL.ini
+++ b/plugins/obs-filters/data/locale/nl-NL.ini
@@ -1,4 +1,5 @@
 ColorFilter="Kleurcorrectie"
+ColorGradeFilter="LUT Toepassen"
 MaskFilter="Afbeeldingsmasker/Mengen"
 AsyncDelayFilter="Videovertraging (Async)"
 CropFilter="Bijsnijden/Aanvullen"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Chroma Key"
 ColorKeyFilter="Color Key"
 SharpnessFilter="Verscherpen"
 ScaleFilter="Schalen/Aspect Ratio"
+UndistortCenter="Verbeter beeldverhouding in het midden van bij schalen vanaf ultrawide"
 NoiseGate="Noise Gate"
 NoiseSuppress="Ruisonderdrukking"
 Gain="Gain"
@@ -61,4 +63,7 @@ ScaleFiltering.Bilinear="Bilinear"
 ScaleFiltering.Bicubic="Bicubic"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Onderdrukkingsniveau (dB)"
+Saturation="Verzadiging"
+HueShift="Tintverschuiving"
+Amount="Hoeveelheid"
 
diff --git a/plugins/obs-filters/data/locale/pl-PL.ini b/plugins/obs-filters/data/locale/pl-PL.ini
index 6025d8d..343aa4a 100644
--- a/plugins/obs-filters/data/locale/pl-PL.ini
+++ b/plugins/obs-filters/data/locale/pl-PL.ini
@@ -1,4 +1,5 @@
 ColorFilter="Korekcja Kolorów"
+ColorGradeFilter="Look-Up Tables (LUT)"
 MaskFilter="Maskowanie/nakładanie obrazu"
 AsyncDelayFilter="Opóźnienie wideo (asynchronicznie)"
 CropFilter="Przytnij/Uzupełnij"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Kluczowanie koloru (chroma key)"
 ColorKeyFilter="Kluczowanie koloru (kolor)"
 SharpnessFilter="Wyostrzanie"
 ScaleFilter="Skalowanie/proporcje"
+UndistortCenter="Usuń przekłamania przy skalowaniu źródeł o dużej szerokości"
 NoiseGate="Bramka szumów"
 NoiseSuppress="Tłumienie hałasu"
 Gain="Poziom"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="Dwuliniowe"
 ScaleFiltering.Bicubic="Dwusześcienne"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Poziom tłumienia (dB)"
+Saturation="Nasycenie"
+HueShift="Przesunięcie barwy"
+Amount="Pozion"
+Compressor="Kompresor"
+Compressor.Ratio="Stosunek (X:1)"
+Compressor.Threshold="Próg (dB)"
+Compressor.AttackTime="Atak (ms)"
+Compressor.ReleaseTime="Odpuszczenie (ms)"
+Compressor.OutputGain="Zysk na wyjściu (dB)"
 
diff --git a/plugins/obs-filters/data/locale/ro-RO.ini b/plugins/obs-filters/data/locale/ro-RO.ini
index 901947c..ee175a8 100644
--- a/plugins/obs-filters/data/locale/ro-RO.ini
+++ b/plugins/obs-filters/data/locale/ro-RO.ini
@@ -5,6 +5,7 @@ ScrollFilter="Derulare"
 ChromaKeyFilter="Cheie chroma"
 ColorKeyFilter="Culoare cheie"
 SharpnessFilter="Accentuare"
+ScaleFilter="Scalare/Rație Aspect"
 NoiseGate="Poartă de zgomot"
 Gain="Amplificare"
 DelayMs="Întârziere (milisecunde)"
@@ -50,4 +51,10 @@ NoiseGate.HoldTime="Timp de menținere (milisecunde)"
 NoiseGate.ReleaseTime="Timp de eliberare (milisecunde)"
 Gain.GainDB="Amplificare (dB)"
 StretchImage="Întinde imaginea (renunță la raportul de aspect al imaginii)"
+Resolution="Rezoluție"
+None="Fără"
+ScaleFiltering.Bilinear="Biliniar"
+ScaleFiltering.Bicubic="Bicubic"
+ScaleFiltering.Lanczos="Lanczos"
+Saturation="Saturație"
 
diff --git a/plugins/obs-filters/data/locale/ru-RU.ini b/plugins/obs-filters/data/locale/ru-RU.ini
index e9447a4..770e3cc 100644
--- a/plugins/obs-filters/data/locale/ru-RU.ini
+++ b/plugins/obs-filters/data/locale/ru-RU.ini
@@ -1,4 +1,5 @@
 ColorFilter="Коррекция цвета"
+ColorGradeFilter="Применить LUT"
 MaskFilter="Маска изображения/Смешивание"
 AsyncDelayFilter="Задержка видео (асинхронность)"
 CropFilter="Кадрировать"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Хромакей"
 ColorKeyFilter="Цветовой ключ"
 SharpnessFilter="Увеличить резкость"
 ScaleFilter="Коэффициент Масштабирования/Аспект"
+UndistortCenter="Не искривлять центр изображения при масштабировании Ultrawide разрешения"
 NoiseGate="Подавление шума"
 NoiseSuppress="Шумоподавление"
 Gain="Усиление"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="Билинейная"
 ScaleFiltering.Bicubic="Бикубическая"
 ScaleFiltering.Lanczos="Метод Ланцоша"
 NoiseSuppress.SuppressLevel="Уровень подавления (дБ)"
+Saturation="Насыщенность"
+HueShift="Сдвиг оттенка"
+Amount="Количество"
+Compressor="Компрессор"
+Compressor.Ratio="Степень сжатия (X:1)"
+Compressor.Threshold="Порог срабатывания (дБ)"
+Compressor.AttackTime="Атака (мс)"
+Compressor.ReleaseTime="Спад (мс)"
+Compressor.OutputGain="Выходное усиление (дБ)"
 
diff --git a/plugins/obs-filters/data/locale/sv-SE.ini b/plugins/obs-filters/data/locale/sv-SE.ini
index 00ad818..469056a 100644
--- a/plugins/obs-filters/data/locale/sv-SE.ini
+++ b/plugins/obs-filters/data/locale/sv-SE.ini
@@ -1,4 +1,5 @@
 ColorFilter="Färgkorrigering"
+ColorGradeFilter="Tillämpa LUT"
 MaskFilter="Bild Mask/Blandning"
 AsyncDelayFilter="Videofördröjning (Async)"
 CropFilter="Beskär/Fyll ut"
@@ -61,4 +62,13 @@ ScaleFiltering.Bilinear="Bilinjär"
 ScaleFiltering.Bicubic="Bikubisk"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="Brusreduceringsnivå (dB)"
+Saturation="Mättnad"
+HueShift="Nyansväxling"
+Amount="Mängd"
+Compressor="Kompressor"
+Compressor.Ratio="Förhållande (X:1)"
+Compressor.Threshold="Tröskel (dB)"
+Compressor.AttackTime="Attack (ms)"
+Compressor.ReleaseTime="Frigör (ms)"
+Compressor.OutputGain="Utmatningsförstärkning (dB)"
 
diff --git a/plugins/obs-filters/data/locale/tr-TR.ini b/plugins/obs-filters/data/locale/tr-TR.ini
index 30a9870..77472ac 100644
--- a/plugins/obs-filters/data/locale/tr-TR.ini
+++ b/plugins/obs-filters/data/locale/tr-TR.ini
@@ -1,11 +1,16 @@
 ColorFilter="Renk Düzeltme"
+ColorGradeFilter="LUT Uygula"
 MaskFilter="Görüntü Maskesi/Blend"
 AsyncDelayFilter="Görüntü Gecikmesi (Async)"
+CropFilter="Kes/Kaydır"
 ScrollFilter="Kaydır"
 ChromaKeyFilter="Chroma Anahtarı"
 ColorKeyFilter="Renk Anahtarı"
 SharpnessFilter="KeskinleÅŸtirme"
+ScaleFilter="Ölçeklendirme/Boy Oranı"
+UndistortCenter="Ultra genişten boyutlandırırken görüntü merkezindeki bozulmayı düzelt"
 NoiseGate="Gürültü Filtresi"
+NoiseSuppress="Gürültü Bastırma"
 Gain="Kazanç"
 DelayMs="Gecikme (milisaniye)"
 Type="Türü"
@@ -20,7 +25,7 @@ Opacity="Opaklık"
 Contrast="Karşıtlık"
 Brightness="Parlaklık"
 Gamma="Gama"
-BrowsePath.Images="Tüm Resim Dosyaları"
+BrowsePath.Images="Tüm Görüntü Dosyaları"
 BrowsePath.AllFiles="Tüm Dosyalar"
 KeyColorType="Anahtar Renk Türü"
 KeyColor="Anahtar Renk"
@@ -49,4 +54,22 @@ NoiseGate.AttackTime="Atak Süresi (milisaniye)"
 NoiseGate.HoldTime="Kavrama Süresi (milisaniye)"
 NoiseGate.ReleaseTime="Bırakma Süresi (milisaniye)"
 Gain.GainDB="Kazanç (dB)"
+StretchImage="Görüntüyü Uzat (görüntü boy oranını görmezden gelir)"
+Resolution="Çözünürlük"
+None="Hiçbiri"
+ScaleFiltering="Ölçek Filtreleme"
+ScaleFiltering.Point="Nokta"
+ScaleFiltering.Bilinear="Bilinear"
+ScaleFiltering.Bicubic="Bicubic"
+ScaleFiltering.Lanczos="Lanczos"
+NoiseSuppress.SuppressLevel="Bastırma Düzeyi (dB)"
+Saturation="Renk DoygunluÄŸu"
+HueShift="Ton Kayması"
+Amount="Miktar"
+Compressor="Sıkıştırma"
+Compressor.Ratio="Oran (X:1)"
+Compressor.Threshold="EÅŸik (dB)"
+Compressor.AttackTime="Atak (ms)"
+Compressor.ReleaseTime="Bırakma (ms)"
+Compressor.OutputGain="Çıkış Kazancı (dB)"
 
diff --git a/plugins/obs-filters/data/locale/uk-UA.ini b/plugins/obs-filters/data/locale/uk-UA.ini
index f861b57..f0736b3 100644
--- a/plugins/obs-filters/data/locale/uk-UA.ini
+++ b/plugins/obs-filters/data/locale/uk-UA.ini
@@ -1,4 +1,5 @@
 ColorFilter="Коригування кольору"
+ColorGradeFilter="Таблиці підстановки кольору"
 MaskFilter="Маска до зображення"
 AsyncDelayFilter="Затримка відео (асинхронна)"
 CropFilter="Кадрування"
@@ -7,6 +8,7 @@ ChromaKeyFilter="Зелений екран"
 ColorKeyFilter="Фільтрування за кольором"
 SharpnessFilter="Різкість"
 ScaleFilter="Масштабування/пропорції"
+UndistortCenter="Зменшити викривлення у центрі, якщо масштабувати з надширокоформатного"
 NoiseGate="Пороговий шумопонижувач"
 NoiseSuppress="Подавлення шуму"
 Gain="Підсилення"
@@ -49,7 +51,7 @@ Magenta="Пурпуровий"
 NoiseGate.OpenThreshold="Поріг відкриття (дБ)"
 NoiseGate.CloseThreshold="Поріг закриття (дБ)"
 NoiseGate.AttackTime="Тривалість фронту сигналу (мілісекунд)"
-NoiseGate.HoldTime="Тривалість сигналу (мілісекунд)"
+NoiseGate.HoldTime="Тривалість втримання сигналу (мілісекунд)"
 NoiseGate.ReleaseTime="Тривалість спаду сигналу (мілісекунд)"
 Gain.GainDB="Підсилення (дБ)"
 StretchImage="Розтягнути зображення (ігнорувати пропорції зображення)"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="Білінійний"
 ScaleFiltering.Bicubic="Бікубічний"
 ScaleFiltering.Lanczos="Ланцош"
 NoiseSuppress.SuppressLevel="Рівень подавлення (дБ)"
+Saturation="Насиченість"
+HueShift="Відтінок"
+Amount="Обсяг впливу"
+Compressor="Компресор"
+Compressor.Ratio="Відношення (X:1)"
+Compressor.Threshold="Поріг (дБ)"
+Compressor.AttackTime="Атака (мс)"
+Compressor.ReleaseTime="Затухання (мс)"
+Compressor.OutputGain="Підсилення виводу (dB)"
 
diff --git a/plugins/obs-filters/data/locale/zh-CN.ini b/plugins/obs-filters/data/locale/zh-CN.ini
index b818e37..4d31867 100644
--- a/plugins/obs-filters/data/locale/zh-CN.ini
+++ b/plugins/obs-filters/data/locale/zh-CN.ini
@@ -1,4 +1,5 @@
 ColorFilter="色彩校正"
+ColorGradeFilter="应用 LUT"
 MaskFilter="图像掩码/混合"
 AsyncDelayFilter="视频延迟(异步)"
 CropFilter="裁剪/填充"
@@ -7,6 +8,7 @@ ChromaKeyFilter="色度键"
 ColorKeyFilter="色值"
 SharpnessFilter="锐化"
 ScaleFilter="缩放比例"
+UndistortCenter="当从超宽扩展时, 让图片中心不失真"
 NoiseGate="噪音阈值"
 NoiseSuppress="噪声抑制"
 Gain="增益"
@@ -61,4 +63,13 @@ ScaleFiltering.Bilinear="双线性算法"
 ScaleFiltering.Bicubic="双立方算法"
 ScaleFiltering.Lanczos="兰索斯算法"
 NoiseSuppress.SuppressLevel="抑制程度 (dB)"
+Saturation="饱和度"
+HueShift="色调偏移"
+Amount="数值"
+Compressor="压缩器"
+Compressor.Ratio="比率 (X:1)"
+Compressor.Threshold="阈值 (dB)"
+Compressor.AttackTime="攻击 (ms)"
+Compressor.ReleaseTime="释放 (ms)"
+Compressor.OutputGain="输出增益 (dB)"
 
diff --git a/plugins/obs-filters/data/locale/zh-TW.ini b/plugins/obs-filters/data/locale/zh-TW.ini
index 6eb0f9d..41a8960 100644
--- a/plugins/obs-filters/data/locale/zh-TW.ini
+++ b/plugins/obs-filters/data/locale/zh-TW.ini
@@ -1,4 +1,5 @@
 ColorFilter="色彩校正"
+ColorGradeFilter="使用色彩對照表"
 MaskFilter="影像遮罩/混合"
 AsyncDelayFilter="視頻延遲 (非同步)"
 CropFilter="剪裁/填充"
@@ -7,6 +8,7 @@ ChromaKeyFilter="色度鍵"
 ColorKeyFilter="色彩鍵"
 SharpnessFilter="銳化"
 ScaleFilter="縮放/長寬比"
+UndistortCenter="從超寬影像縮放時彌補影像中心的畸變"
 NoiseGate="噪音閾"
 NoiseSuppress="雜訊抑制"
 Gain="增益"
@@ -61,4 +63,7 @@ ScaleFiltering.Bilinear="雙線性插值"
 ScaleFiltering.Bicubic="雙三次插值"
 ScaleFiltering.Lanczos="Lanczos"
 NoiseSuppress.SuppressLevel="抑制標準 (dB)"
+Saturation="飽合度"
+HueShift="色調偏移"
+Amount="影響總量"
 
diff --git a/plugins/obs-filters/obs-filters.c b/plugins/obs-filters/obs-filters.c
index fbcdb91..6c0e413 100644
--- a/plugins/obs-filters/obs-filters.c
+++ b/plugins/obs-filters/obs-filters.c
@@ -12,6 +12,7 @@ extern struct obs_source_info color_filter;
 extern struct obs_source_info scale_filter;
 extern struct obs_source_info scroll_filter;
 extern struct obs_source_info color_key_filter;
+extern struct obs_source_info color_grade_filter;
 extern struct obs_source_info sharpness_filter;
 extern struct obs_source_info chroma_key_filter;
 extern struct obs_source_info async_delay_filter;
@@ -19,6 +20,7 @@ extern struct obs_source_info async_delay_filter;
 extern struct obs_source_info noise_suppress_filter;
 #endif
 extern struct obs_source_info noise_gate_filter;
+extern struct obs_source_info compressor_filter;
 
 bool obs_module_load(void)
 {
@@ -29,6 +31,7 @@ bool obs_module_load(void)
 	obs_register_source(&scale_filter);
 	obs_register_source(&scroll_filter);
 	obs_register_source(&color_key_filter);
+	obs_register_source(&color_grade_filter);
 	obs_register_source(&sharpness_filter);
 	obs_register_source(&chroma_key_filter);
 	obs_register_source(&async_delay_filter);
@@ -36,5 +39,6 @@ bool obs_module_load(void)
 	obs_register_source(&noise_suppress_filter);
 #endif
 	obs_register_source(&noise_gate_filter);
+	obs_register_source(&compressor_filter);
 	return true;
 }
diff --git a/plugins/obs-filters/scale-filter.c b/plugins/obs-filters/scale-filter.c
index e8edfc5..29e42c4 100644
--- a/plugins/obs-filters/scale-filter.c
+++ b/plugins/obs-filters/scale-filter.c
@@ -8,6 +8,7 @@
 
 #define S_RESOLUTION                    "resolution"
 #define S_SAMPLING                      "sampling"
+#define S_UNDISTORT                     "undistort"
 
 #define T_RESOLUTION                    obs_module_text("Resolution")
 #define T_NONE                          obs_module_text("None")
@@ -16,6 +17,7 @@
 #define T_SAMPLING_BILINEAR             obs_module_text("ScaleFiltering.Bilinear")
 #define T_SAMPLING_BICUBIC              obs_module_text("ScaleFiltering.Bicubic")
 #define T_SAMPLING_LANCZOS              obs_module_text("ScaleFiltering.Lanczos")
+#define T_UNDISTORT                     obs_module_text("UndistortCenter")
 
 #define S_SAMPLING_POINT                "point"
 #define S_SAMPLING_BILINEAR             "bilinear"
@@ -27,7 +29,9 @@ struct scale_filter_data {
 	gs_effect_t                     *effect;
 	gs_eparam_t                     *image_param;
 	gs_eparam_t                     *dimension_param;
+	gs_eparam_t                     *undistort_factor_param;
 	struct vec2                     dimension_i;
+	double                          undistort_factor;
 	int                             cx_in;
 	int                             cy_in;
 	int                             cx_out;
@@ -37,6 +41,7 @@ struct scale_filter_data {
 	bool                            aspect_ratio_only : 1;
 	bool                            target_valid : 1;
 	bool                            valid : 1;
+	bool                            undistort : 1;
 };
 
 static const char *scale_filter_name(void *unused)
@@ -80,6 +85,8 @@ static void scale_filter_update(void *data, obs_data_t *settings)
 	} else { /* S_SAMPLING_BICUBIC */
 		filter->sampling = OBS_SCALE_BICUBIC;
 	}
+
+	filter->undistort = obs_data_get_bool(settings, S_UNDISTORT);
 }
 
 static void scale_filter_destroy(void *data)
@@ -146,11 +153,11 @@ static void scale_filter_tick(void *data, float seconds)
 	cx_f = (double)cx;
 	cy_f = (double)cy;
 
-	if (filter->aspect_ratio_only) {
-		double old_aspect = cx_f / cy_f;
-		double new_aspect =
-			(double)filter->cx_in / (double)filter->cy_in;
+	double old_aspect = cx_f / cy_f;
+	double new_aspect =
+		(double)filter->cx_in / (double)filter->cy_in;
 
+	if (filter->aspect_ratio_only) {
 		if (fabs(old_aspect - new_aspect) <= EPSILON) {
 			filter->target_valid = false;
 			return;
@@ -172,6 +179,12 @@ static void scale_filter_tick(void *data, float seconds)
 			1.0f / (float)cx,
 			1.0f / (float)cy);
 
+	if (filter->undistort) {
+		filter->undistort_factor = new_aspect / old_aspect;
+	} else {
+		filter->undistort_factor = 1.0;
+	}
+
 	/* ------------------------- */
 
 	lower_than_2x = filter->cx_out < cx / 2 || filter->cy_out < cy / 2;
@@ -199,12 +212,22 @@ static void scale_filter_tick(void *data, float seconds)
 		filter->dimension_param = NULL;
 	}
 
+	if (type == OBS_EFFECT_BICUBIC || type == OBS_EFFECT_LANCZOS) {
+		filter->undistort_factor_param = gs_effect_get_param_by_name(
+			filter->effect, "undistort_factor");
+	}
+	else {
+		filter->undistort_factor_param = NULL;
+	}
+
 	UNUSED_PARAMETER(seconds);
 }
 
 static void scale_filter_render(void *data, gs_effect_t *effect)
 {
 	struct scale_filter_data *filter = data;
+	const char *technique = filter->undistort ?
+		"DrawUndistort" : "Draw";
 
 	if (!filter->valid || !filter->target_valid) {
 		obs_source_skip_video_filter(filter->context);
@@ -219,12 +242,16 @@ static void scale_filter_render(void *data, gs_effect_t *effect)
 		gs_effect_set_vec2(filter->dimension_param,
 				&filter->dimension_i);
 
+	if (filter->undistort_factor_param)
+		gs_effect_set_float(filter->undistort_factor_param,
+			(float)filter->undistort_factor);
+
 	if (filter->sampling == OBS_SCALE_POINT)
 		gs_effect_set_next_sampler(filter->image_param,
 				filter->point_sampler);
 
-	obs_source_process_filter_end(filter->context, filter->effect,
-			filter->cx_out, filter->cy_out);
+	obs_source_process_filter_tech_end(filter->context, filter->effect,
+			filter->cx_out, filter->cy_out, technique);
 
 	UNUSED_PARAMETER(effect);
 }
@@ -254,6 +281,34 @@ static const char *aspects[] = {
 
 #define NUM_ASPECTS (sizeof(aspects) / sizeof(const char *))
 
+static bool sampling_modified(obs_properties_t *props, obs_property_t *p,
+	obs_data_t *settings)
+{
+	const char *sampling = obs_data_get_string(settings, S_SAMPLING);
+
+	bool has_undistort;
+	if (astrcmpi(sampling, S_SAMPLING_POINT) == 0) {
+		has_undistort = false;
+
+	}
+	else if (astrcmpi(sampling, S_SAMPLING_BILINEAR) == 0) {
+		has_undistort = false;
+
+	}
+	else if (astrcmpi(sampling, S_SAMPLING_LANCZOS) == 0) {
+		has_undistort = true;
+
+	}
+	else { /* S_SAMPLING_BICUBIC */
+		has_undistort = true;
+	}
+
+	obs_property_set_visible(obs_properties_get(props, S_UNDISTORT), has_undistort);
+
+	UNUSED_PARAMETER(p);
+	return true;
+}
+
 static obs_properties_t *scale_filter_properties(void *data)
 {
 	obs_properties_t *props = obs_properties_create();
@@ -280,6 +335,7 @@ static obs_properties_t *scale_filter_properties(void *data)
 
 	p = obs_properties_add_list(props, S_SAMPLING, T_SAMPLING,
 			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
+	obs_property_set_modified_callback(p, sampling_modified);
 	obs_property_list_add_string(p, T_SAMPLING_POINT,    S_SAMPLING_POINT);
 	obs_property_list_add_string(p, T_SAMPLING_BILINEAR, S_SAMPLING_BILINEAR);
 	obs_property_list_add_string(p, T_SAMPLING_BICUBIC,  S_SAMPLING_BICUBIC);
@@ -301,6 +357,8 @@ static obs_properties_t *scale_filter_properties(void *data)
 		obs_property_list_add_string(p, str, str);
 	}
 
+	obs_properties_add_bool(props, S_UNDISTORT, T_UNDISTORT);
+
 	/* ----------------- */
 
 	UNUSED_PARAMETER(data);
@@ -311,6 +369,7 @@ static void scale_filter_defaults(obs_data_t *settings)
 {
 	obs_data_set_default_string(settings, S_SAMPLING, S_SAMPLING_BICUBIC);
 	obs_data_set_default_string(settings, S_RESOLUTION, T_NONE);
+	obs_data_set_default_bool(settings, S_UNDISTORT, 0);
 }
 
 static uint32_t scale_filter_width(void *data)
diff --git a/plugins/obs-libfdk/data/locale/de-DE.ini b/plugins/obs-libfdk/data/locale/de-DE.ini
index 56c85ba..3ae777b 100644
--- a/plugins/obs-libfdk/data/locale/de-DE.ini
+++ b/plugins/obs-libfdk/data/locale/de-DE.ini
@@ -1,4 +1,4 @@
-LibFDK="Libfdk AAC Encoder"
+LibFDK="libfdk AAC Codierer"
 Bitrate="Bitrate"
 Afterburner="AAC Afterburner aktivieren"
 
diff --git a/plugins/obs-libfdk/data/locale/et-EE.ini b/plugins/obs-libfdk/data/locale/et-EE.ini
new file mode 100644
index 0000000..08ab058
--- /dev/null
+++ b/plugins/obs-libfdk/data/locale/et-EE.ini
@@ -0,0 +1,3 @@
+LibFDK="libfdk AAC kodeerija"
+Bitrate="Bitikiirus"
+
diff --git a/plugins/obs-libfdk/data/locale/hu-HU.ini b/plugins/obs-libfdk/data/locale/hu-HU.ini
index 0f6984c..904e1c8 100644
--- a/plugins/obs-libfdk/data/locale/hu-HU.ini
+++ b/plugins/obs-libfdk/data/locale/hu-HU.ini
@@ -1,4 +1,4 @@
 LibFDK="libfdk AAC kódoló"
-Bitrate="Bitráta"
+Bitrate="Bitsebesség"
 Afterburner="AAC Afterburner engedélyezése"
 
diff --git a/plugins/obs-outputs/CMakeLists.txt b/plugins/obs-outputs/CMakeLists.txt
index 1051974..0a0b114 100644
--- a/plugins/obs-outputs/CMakeLists.txt
+++ b/plugins/obs-outputs/CMakeLists.txt
@@ -62,6 +62,7 @@ endif()
 set(obs-outputs_HEADERS
 	obs-output-ver.h
 	rtmp-helpers.h
+	rtmp-stream.h
 	net-if.h
 	flv-mux.h
 	flv-output.h
@@ -69,6 +70,7 @@ set(obs-outputs_HEADERS
 set(obs-outputs_SOURCES
 	obs-outputs.c
 	rtmp-stream.c
+	rtmp-windows.c
 	flv-output.c
 	flv-mux.c
 	net-if.c)
diff --git a/plugins/obs-outputs/data/locale/da-DK.ini b/plugins/obs-outputs/data/locale/da-DK.ini
index 76d7818..292cbf0 100644
--- a/plugins/obs-outputs/data/locale/da-DK.ini
+++ b/plugins/obs-outputs/data/locale/da-DK.ini
@@ -2,4 +2,5 @@ RTMPStream="RTMP Strøm"
 RTMPStream.DropThreshold="Drop Tærskel (millisekunder)"
 FLVOutput="FLV File Output"
 FLVOutput.FilePath="Filsti"
+Default="Standard"
 
diff --git a/plugins/obs-outputs/data/locale/el-GR.ini b/plugins/obs-outputs/data/locale/el-GR.ini
index 465f038..e31000f 100644
--- a/plugins/obs-outputs/data/locale/el-GR.ini
+++ b/plugins/obs-outputs/data/locale/el-GR.ini
@@ -2,4 +2,5 @@ RTMPStream="Ροή RTMP"
 RTMPStream.DropThreshold="Όριο απωλειών (χιλιοστά δευτερολέπτου)"
 FLVOutput="FLV Αρχείο Εξόδου"
 FLVOutput.FilePath="Διαδρομή Αρχείου"
+Default="Προεπιλογή"
 
diff --git a/plugins/obs-outputs/data/locale/et-EE.ini b/plugins/obs-outputs/data/locale/et-EE.ini
new file mode 100644
index 0000000..dfca04e
--- /dev/null
+++ b/plugins/obs-outputs/data/locale/et-EE.ini
@@ -0,0 +1,2 @@
+RTMPStream="RTMP voogedastus"
+
diff --git a/plugins/obs-outputs/data/locale/nb-NO.ini b/plugins/obs-outputs/data/locale/nb-NO.ini
index ce20f13..7ad0194 100644
--- a/plugins/obs-outputs/data/locale/nb-NO.ini
+++ b/plugins/obs-outputs/data/locale/nb-NO.ini
@@ -2,4 +2,5 @@ RTMPStream="RTMP-strøm"
 RTMPStream.DropThreshold="Senk terskelen (millisekunder)"
 FLVOutput="FLV-filutgang"
 FLVOutput.FilePath="Filbane"
+Default="Standard"
 
diff --git a/plugins/obs-outputs/data/locale/sk-SK.ini b/plugins/obs-outputs/data/locale/sk-SK.ini
index e56f41b..4949ef4 100644
--- a/plugins/obs-outputs/data/locale/sk-SK.ini
+++ b/plugins/obs-outputs/data/locale/sk-SK.ini
@@ -1,4 +1,5 @@
 RTMPStream="RTMP stream"
 FLVOutput="Výstup do súboru FLV"
 FLVOutput.FilePath="Cesta k súboru"
+Default="Základné"
 
diff --git a/plugins/obs-outputs/data/locale/tr-TR.ini b/plugins/obs-outputs/data/locale/tr-TR.ini
index 9b713bb..6da5420 100644
--- a/plugins/obs-outputs/data/locale/tr-TR.ini
+++ b/plugins/obs-outputs/data/locale/tr-TR.ini
@@ -2,4 +2,5 @@ RTMPStream="RTMP Yayın"
 RTMPStream.DropThreshold="Düşürme Eşiği (milisaniye)"
 FLVOutput="FLV Dosyası Çıkışı"
 FLVOutput.FilePath="Dosya Yolu"
+Default="Varsayılan"
 
diff --git a/plugins/obs-outputs/data/locale/vi-VN.ini b/plugins/obs-outputs/data/locale/vi-VN.ini
new file mode 100644
index 0000000..8dc44d6
--- /dev/null
+++ b/plugins/obs-outputs/data/locale/vi-VN.ini
@@ -0,0 +1,3 @@
+FLVOutput.FilePath="Đường dẫn tệp"
+Default="Mặc định"
+
diff --git a/plugins/obs-outputs/flv-output.c b/plugins/obs-outputs/flv-output.c
index a0e803a..8f191b0 100644
--- a/plugins/obs-outputs/flv-output.c
+++ b/plugins/obs-outputs/flv-output.c
@@ -73,11 +73,12 @@ static void flv_output_stop(void *data, uint64_t ts)
 	struct flv_output *stream = data;
 
 	if (stream->active) {
-		if (stream->file)
+		if (stream->file) {
 			write_file_info(stream->file, stream->last_packet_ts,
 					os_ftelli64(stream->file));
 
-		fclose(stream->file);
+			fclose(stream->file);
+		}
 		obs_output_end_data_capture(stream->output);
 		stream->active = false;
 		stream->sent_headers = false;
@@ -100,7 +101,7 @@ static int write_packet(struct flv_output *stream,
 	flv_packet_mux(packet, &data, &size, is_header);
 	fwrite(data, 1, size, stream->file);
 	bfree(data);
-	obs_free_encoder_packet(packet);
+	obs_encoder_packet_release(packet);
 
 	return ret;
 }
@@ -200,7 +201,7 @@ static void flv_output_data(void *data, struct encoder_packet *packet)
 	if (packet->type == OBS_ENCODER_VIDEO) {
 		obs_parse_avc_packet(&parsed_packet, packet);
 		write_packet(stream, &parsed_packet, false);
-		obs_free_encoder_packet(&parsed_packet);
+		obs_encoder_packet_release(&parsed_packet);
 	} else {
 		write_packet(stream, packet, false);
 	}
diff --git a/plugins/obs-outputs/librtmp/rtmp.c b/plugins/obs-outputs/librtmp/rtmp.c
index 6b287a2..a017b07 100644
--- a/plugins/obs-outputs/librtmp/rtmp.c
+++ b/plugins/obs-outputs/librtmp/rtmp.c
@@ -650,7 +650,7 @@ int RTMP_AddStream(RTMP *r, const char *playpath)
 }
 
 static int
-add_addr_info(struct sockaddr_storage *service, socklen_t *addrlen, AVal *host, int port)
+add_addr_info(struct sockaddr_storage *service, socklen_t *addrlen, AVal *host, int port, socklen_t addrlen_hint)
 {
     char *hostname;
     int ret = TRUE;
@@ -698,7 +698,7 @@ add_addr_info(struct sockaddr_storage *service, socklen_t *addrlen, AVal *host,
     // prefer ipv4 results, since lots of ISPs have broken ipv6 connectivity
     for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
     {
-        if (ptr->ai_family == AF_INET)
+        if (ptr->ai_family == AF_INET && (!addrlen_hint || ptr->ai_addrlen == addrlen_hint))
         {
             memcpy(service, ptr->ai_addr, ptr->ai_addrlen);
             *addrlen = (socklen_t)ptr->ai_addrlen;
@@ -710,7 +710,7 @@ add_addr_info(struct sockaddr_storage *service, socklen_t *addrlen, AVal *host,
 	{
 		for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
 		{
-			if (ptr->ai_family == AF_INET6)
+            if (ptr->ai_family == AF_INET6 && (!addrlen_hint || ptr->ai_addrlen == addrlen_hint))
 			{
 				memcpy(service, ptr->ai_addr, ptr->ai_addrlen);
 				*addrlen = (socklen_t)ptr->ai_addrlen;
@@ -905,6 +905,7 @@ RTMP_Connect(RTMP *r, RTMPPacket *cp)
 #endif
     struct sockaddr_storage service;
     socklen_t addrlen = 0;
+    socklen_t addrlen_hint = 0;
     if (!r->Link.hostname.av_len)
         return FALSE;
 
@@ -920,16 +921,19 @@ RTMP_Connect(RTMP *r, RTMPPacket *cp)
 
     memset(&service, 0, sizeof(service));
 
+    if (r->m_bindIP.addrLen)
+        addrlen_hint = r->m_bindIP.addrLen;
+
     if (r->Link.socksport)
     {
         /* Connect via SOCKS */
-        if (!add_addr_info(&service, &addrlen, &r->Link.sockshost, r->Link.socksport))
+        if (!add_addr_info(&service, &addrlen, &r->Link.sockshost, r->Link.socksport, addrlen_hint))
             return FALSE;
     }
     else
     {
         /* Connect directly */
-        if (!add_addr_info(&service, &addrlen, &r->Link.hostname, r->Link.port))
+        if (!add_addr_info(&service, &addrlen, &r->Link.hostname, r->Link.port, addrlen_hint))
             return FALSE;
     }
 
@@ -949,7 +953,7 @@ SocksNegotiate(RTMP *r)
     socklen_t addrlen = 0;
     memset(&service, 0, sizeof(service));
 
-    add_addr_info(&service, &addrlen, &r->Link.hostname, r->Link.port);
+    add_addr_info(&service, &addrlen, &r->Link.hostname, r->Link.port, 0);
 
     // not doing IPv6 socks
     if (service.ss_family == AF_INET6)
@@ -4248,6 +4252,11 @@ RTMP_Close(RTMP *r)
         r->Link.lFlags ^= RTMP_LF_FTCU;
     }
 
+    memset (&r->m_bindIP, 0, sizeof(r->m_bindIP));
+    r->m_bCustomSend = 0;
+    r->m_customSendFunc = NULL;
+    r->m_customSendParam = NULL;
+
 #if defined(CRYPTO) || defined(USE_ONLY_MD5)
     if (!(r->Link.protocol & RTMP_FEATURE_WRITE) || (r->Link.pFlags & RTMP_PUB_CLEAN))
     {
diff --git a/plugins/obs-outputs/net-if.h b/plugins/obs-outputs/net-if.h
index 4ff1c76..3da69c0 100644
--- a/plugins/obs-outputs/net-if.h
+++ b/plugins/obs-outputs/net-if.h
@@ -29,6 +29,7 @@
 #  ifdef __linux__
 #    include <linux/if_link.h>
 #  elif __FreeBSD__
+#    include <netinet/in.h>
 #    ifndef _GNU_SOURCE
 #      define _GNU_SOURCE
 #      define __NET_IF_GNU_SOURCE__
diff --git a/plugins/obs-outputs/rtmp-stream.c b/plugins/obs-outputs/rtmp-stream.c
index 179bee5..25d3825 100644
--- a/plugins/obs-outputs/rtmp-stream.c
+++ b/plugins/obs-outputs/rtmp-stream.c
@@ -15,95 +15,7 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
 
-#include <obs-module.h>
-#include <obs-avc.h>
-#include <util/platform.h>
-#include <util/circlebuf.h>
-#include <util/dstr.h>
-#include <util/threading.h>
-#include <inttypes.h>
-#include "librtmp/rtmp.h"
-#include "librtmp/log.h"
-#include "flv-mux.h"
-#include "net-if.h"
-
-#ifdef _WIN32
-#include <Iphlpapi.h>
-#else
-#include <sys/ioctl.h>
-#endif
-
-#define do_log(level, format, ...) \
-	blog(level, "[rtmp stream: '%s'] " format, \
-			obs_output_get_name(stream->output), ##__VA_ARGS__)
-
-#define warn(format, ...)  do_log(LOG_WARNING, format, ##__VA_ARGS__)
-#define info(format, ...)  do_log(LOG_INFO,    format, ##__VA_ARGS__)
-#define debug(format, ...) do_log(LOG_DEBUG,   format, ##__VA_ARGS__)
-
-#define OPT_DROP_THRESHOLD "drop_threshold_ms"
-#define OPT_PFRAME_DROP_THRESHOLD "pframe_drop_threshold_ms"
-#define OPT_MAX_SHUTDOWN_TIME_SEC "max_shutdown_time_sec"
-#define OPT_BIND_IP "bind_ip"
-
-//#define TEST_FRAMEDROPS
-
-#ifdef TEST_FRAMEDROPS
-
-#define DROPTEST_MAX_KBPS 3000
-#define DROPTEST_MAX_BYTES (DROPTEST_MAX_KBPS * 1000 / 8)
-
-struct droptest_info {
-	uint64_t ts;
-	size_t size;
-};
-#endif
-
-struct rtmp_stream {
-	obs_output_t     *output;
-
-	pthread_mutex_t  packets_mutex;
-	struct circlebuf packets;
-	bool             sent_headers;
-
-	volatile bool    connecting;
-	pthread_t        connect_thread;
-
-	volatile bool    active;
-	volatile bool    disconnected;
-	pthread_t        send_thread;
-
-	int              max_shutdown_time_sec;
-
-	os_sem_t         *send_sem;
-	os_event_t       *stop_event;
-	uint64_t         stop_ts;
-	uint64_t         shutdown_timeout_ts;
-
-	struct dstr      path, key;
-	struct dstr      username, password;
-	struct dstr      encoder_name;
-	struct dstr      bind_ip;
-
-	/* frame drop variables */
-	int64_t          drop_threshold_usec;
-	int64_t          min_drop_dts_usec;
-	int64_t          pframe_drop_threshold_usec;
-	int64_t          pframe_min_drop_dts_usec;
-	int              min_priority;
-
-	int64_t          last_dts_usec;
-
-	uint64_t         total_bytes_sent;
-	int              dropped_frames;
-
-#ifdef TEST_FRAMEDROPS
-	struct circlebuf droptest_info;
-	size_t           droptest_size;
-#endif
-
-	RTMP             rtmp;
-};
+#include "rtmp-stream.h"
 
 static const char *rtmp_stream_getname(void *unused)
 {
@@ -134,7 +46,7 @@ static inline void free_packets(struct rtmp_stream *stream)
 	while (stream->packets.size) {
 		struct encoder_packet packet;
 		circlebuf_pop_front(&stream->packets, &packet, sizeof(packet));
-		obs_free_encoder_packet(&packet);
+		obs_encoder_packet_release(&packet);
 	}
 	pthread_mutex_unlock(&stream->packets_mutex);
 }
@@ -180,23 +92,30 @@ static void rtmp_stream_destroy(void *data)
 		}
 	}
 
-	if (stream) {
-		free_packets(stream);
-		dstr_free(&stream->path);
-		dstr_free(&stream->key);
-		dstr_free(&stream->username);
-		dstr_free(&stream->password);
-		dstr_free(&stream->encoder_name);
-		dstr_free(&stream->bind_ip);
-		os_event_destroy(stream->stop_event);
-		os_sem_destroy(stream->send_sem);
-		pthread_mutex_destroy(&stream->packets_mutex);
-		circlebuf_free(&stream->packets);
+	free_packets(stream);
+	dstr_free(&stream->path);
+	dstr_free(&stream->key);
+	dstr_free(&stream->username);
+	dstr_free(&stream->password);
+	dstr_free(&stream->encoder_name);
+	dstr_free(&stream->bind_ip);
+	os_event_destroy(stream->stop_event);
+	os_sem_destroy(stream->send_sem);
+	pthread_mutex_destroy(&stream->packets_mutex);
+	circlebuf_free(&stream->packets);
 #ifdef TEST_FRAMEDROPS
-		circlebuf_free(&stream->droptest_info);
+	circlebuf_free(&stream->droptest_info);
 #endif
-		bfree(stream);
-	}
+
+	os_event_destroy(stream->buffer_space_available_event);
+	os_event_destroy(stream->buffer_has_data_event);
+	os_event_destroy(stream->socket_available_event);
+	os_event_destroy(stream->send_thread_signaled_exit);
+	pthread_mutex_destroy(&stream->write_buf_mutex);
+
+	if (stream->write_buf)
+		bfree(stream->write_buf);
+	bfree(stream);
 }
 
 static void *rtmp_stream_create(obs_data_t *settings, obs_output_t *output)
@@ -214,6 +133,32 @@ static void *rtmp_stream_create(obs_data_t *settings, obs_output_t *output)
 	if (os_event_init(&stream->stop_event, OS_EVENT_TYPE_MANUAL) != 0)
 		goto fail;
 
+	if (pthread_mutex_init(&stream->write_buf_mutex, NULL) != 0) {
+		warn("Failed to initialize write buffer mutex");
+		goto fail;
+	}
+
+	if (os_event_init(&stream->buffer_space_available_event,
+		OS_EVENT_TYPE_AUTO) != 0) {
+		warn("Failed to initialize write buffer event");
+		goto fail;
+	}
+	if (os_event_init(&stream->buffer_has_data_event,
+		OS_EVENT_TYPE_AUTO) != 0) {
+		warn("Failed to initialize data buffer event");
+		goto fail;
+	}
+	if (os_event_init(&stream->socket_available_event,
+		OS_EVENT_TYPE_AUTO) != 0) {
+		warn("Failed to initialize socket buffer event");
+		goto fail;
+	}
+	if (os_event_init(&stream->send_thread_signaled_exit,
+		OS_EVENT_TYPE_MANUAL) != 0) {
+		warn("Failed to initialize socket exit event");
+		goto fail;
+	}
+
 	UNUSED_PARAMETER(settings);
 	return stream;
 
@@ -346,6 +291,38 @@ static void droptest_cap_data_rate(struct rtmp_stream *stream, size_t size)
 }
 #endif
 
+static int socket_queue_data(RTMPSockBuf *sb, const char *data, int len, void *arg)
+{
+	struct rtmp_stream *stream = arg;
+
+retry_send:
+
+	if (!RTMP_IsConnected(&stream->rtmp))
+		return 0;
+
+	pthread_mutex_lock(&stream->write_buf_mutex);
+
+	if (stream->write_buf_len + len > stream->write_buf_size) {
+
+		pthread_mutex_unlock(&stream->write_buf_mutex);
+
+		if (os_event_wait(stream->buffer_space_available_event)) {
+			return 0;
+		}
+
+		goto retry_send;
+	}
+
+	memcpy(stream->write_buf + stream->write_buf_len, data, len);
+	stream->write_buf_len += len;
+
+	pthread_mutex_unlock(&stream->write_buf_mutex);
+
+	os_event_signal (stream->buffer_has_data_event);
+
+	return len;
+}
+
 static int send_packet(struct rtmp_stream *stream,
 		struct encoder_packet *packet, bool is_header, size_t idx)
 {
@@ -354,16 +331,18 @@ static int send_packet(struct rtmp_stream *stream,
 	int     recv_size = 0;
 	int     ret = 0;
 
+	if (!stream->new_socket_loop) {
 #ifdef _WIN32
-	ret = ioctlsocket(stream->rtmp.m_sb.sb_socket, FIONREAD,
-			(u_long*)&recv_size);
+		ret = ioctlsocket(stream->rtmp.m_sb.sb_socket, FIONREAD,
+				(u_long*)&recv_size);
 #else
-	ret = ioctl(stream->rtmp.m_sb.sb_socket, FIONREAD, &recv_size);
+		ret = ioctl(stream->rtmp.m_sb.sb_socket, FIONREAD, &recv_size);
 #endif
 
-	if (ret >= 0 && recv_size > 0) {
-		if (!discard_recv_data(stream, (size_t)recv_size))
-			return -1;
+		if (ret >= 0 && recv_size > 0) {
+			if (!discard_recv_data(stream, (size_t)recv_size))
+				return -1;
+		}
 	}
 
 	flv_packet_mux(packet, &data, &size, is_header);
@@ -375,7 +354,10 @@ static int send_packet(struct rtmp_stream *stream,
 	ret = RTMP_Write(&stream->rtmp, (char*)data, (int)size, (int)idx);
 	bfree(data);
 
-	obs_free_encoder_packet(packet);
+	if (is_header)
+		bfree(packet->data);
+	else
+		obs_encoder_packet_release(packet);
 
 	stream->total_bytes_sent += size;
 	return ret;
@@ -414,7 +396,7 @@ static void *send_thread(void *data)
 
 		if (stopping(stream)) {
 			if (can_shutdown_stream(stream, &packet)) {
-				obs_free_encoder_packet(&packet);
+				obs_encoder_packet_release(&packet);
 				break;
 			}
 		}
@@ -438,6 +420,14 @@ static void *send_thread(void *data)
 		info("User stopped the stream");
 	}
 
+	if (stream->new_socket_loop) {
+		os_event_signal(stream->send_thread_signaled_exit);
+		os_event_signal(stream->buffer_has_data_event);
+		pthread_join(stream->socket_thread, NULL);
+		stream->socket_thread_active = false;
+		stream->rtmp.m_bCustomSend = false;
+	}
+
 	RTMP_Close(&stream->rtmp);
 
 	if (!stopping(stream)) {
@@ -577,6 +567,78 @@ static int init_send(struct rtmp_stream *stream)
 		return OBS_OUTPUT_ERROR;
 	}
 
+	if (stream->new_socket_loop) {
+		int one = 1;
+#ifdef _WIN32
+		if (ioctlsocket(stream->rtmp.m_sb.sb_socket, FIONBIO, &one)) {
+#else
+		if (ioctl(stream->rtmp.m_sb.sb_socket, FIONBIO, &one)) {
+#endif
+			warn("Failed to set non-blocking socket");
+			return OBS_OUTPUT_ERROR;
+		}
+
+		os_event_reset(stream->send_thread_signaled_exit);
+
+		info("New socket loop enabled by user");
+		if (stream->low_latency_mode)
+			info("Low latency mode enabled by user");
+
+		if (stream->write_buf)
+			bfree(stream->write_buf);
+
+		int total_bitrate = 0;
+		obs_output_t  *context  = stream->output;
+
+		obs_encoder_t *vencoder = obs_output_get_video_encoder(context);
+		if (vencoder) {
+			obs_data_t *params = obs_encoder_get_settings(vencoder);
+			if (params) {
+				int bitrate = obs_data_get_int(params, "bitrate");
+				total_bitrate += bitrate;
+				obs_data_release(params);
+			}
+		}
+
+		obs_encoder_t *aencoder = obs_output_get_audio_encoder(context, 0);
+		if (aencoder) {
+			obs_data_t *params = obs_encoder_get_settings(aencoder);
+			if (params) {
+				int bitrate = obs_data_get_int(params, "bitrate");
+				total_bitrate += bitrate;
+				obs_data_release(params);
+			}
+		}
+
+		// to bytes/sec
+		int ideal_buffer_size = total_bitrate * 128;
+
+		if (ideal_buffer_size < 131072)
+			ideal_buffer_size = 131072;
+
+		stream->write_buf_size = ideal_buffer_size;
+		stream->write_buf = bmalloc(ideal_buffer_size);
+
+#ifdef _WIN32
+		ret = pthread_create(&stream->socket_thread, NULL,
+				socket_thread_windows, stream);
+#else
+		warn("New socket loop not supported on this platform");
+		return OBS_OUTPUT_ERROR;
+#endif
+
+		if (ret != 0) {
+			RTMP_Close(&stream->rtmp);
+			warn("Failed to create socket thread");
+			return OBS_OUTPUT_ERROR;
+		}
+
+		stream->socket_thread_active = true;
+		stream->rtmp.m_bCustomSend = true;
+		stream->rtmp.m_customSendFunc = socket_queue_data;
+		stream->rtmp.m_customSendParam = stream;
+	}
+
 	os_atomic_set_bool(&stream->active, true);
 	while (next) {
 		if (!send_meta_data(stream, idx++, &next)) {
@@ -676,8 +738,11 @@ static int try_connect(struct rtmp_stream *stream)
 		bool success = netif_str_to_addr(&stream->rtmp.m_bindIP.addr,
 				&stream->rtmp.m_bindIP.addrLen,
 				stream->bind_ip.array);
-		if (success)
-			info("Binding to IP");
+		if (success) {
+			int len = stream->rtmp.m_bindIP.addrLen;
+			bool ipv6 = len == sizeof(struct sockaddr_in6);
+			info("Binding to IPv%d", ipv6 ? 6 : 4);
+		}
 	}
 
 	RTMP_AddStream(&stream->rtmp, stream->key.array);
@@ -720,8 +785,9 @@ static bool init_connect(struct rtmp_stream *stream)
 	int64_t drop_p;
 	int64_t drop_b;
 
-	if (stopping(stream))
+	if (stopping(stream)) {
 		pthread_join(stream->send_thread, NULL);
+	}
 
 	free_packets(stream);
 
@@ -756,6 +822,11 @@ static bool init_connect(struct rtmp_stream *stream)
 	bind_ip = obs_data_get_string(settings, OPT_BIND_IP);
 	dstr_copy(&stream->bind_ip, bind_ip);
 
+	stream->new_socket_loop = obs_data_get_bool(settings,
+			OPT_NEWSOCKETLOOP_ENABLED);
+	stream->low_latency_mode = obs_data_get_bool(settings,
+			OPT_LOWLATENCY_ENABLED);
+
 	obs_data_release(settings);
 	return true;
 }
@@ -842,7 +913,7 @@ static void drop_frames(struct rtmp_stream *stream, const char *name,
 
 		} else {
 			num_frames_dropped++;
-			obs_free_encoder_packet(&packet);
+			obs_encoder_packet_release(&packet);
 		}
 	}
 
@@ -878,8 +949,11 @@ static void check_to_drop_frames(struct rtmp_stream *stream, bool pframes)
 		stream->pframe_drop_threshold_usec :
 		stream->drop_threshold_usec;
 
-	if (num_packets < 5)
+	if (num_packets < 5) {
+		if (!pframes)
+			stream->congestion = 0.0f;
 		return;
+	}
 
 	circlebuf_peek_front(&stream->packets, &first, sizeof(first));
 
@@ -891,8 +965,13 @@ static void check_to_drop_frames(struct rtmp_stream *stream, bool pframes)
 	 * sent is higher than threshold, drop frames */
 	buffer_duration_usec = stream->last_dts_usec - first.dts_usec;
 
+	if (!pframes) {
+		stream->congestion = (float)buffer_duration_usec /
+			(float)drop_threshold;
+	}
+
 	if (buffer_duration_usec > drop_threshold) {
-		debug("buffer_duration_usec: %lld", buffer_duration_usec);
+		debug("buffer_duration_usec: %" PRId64, buffer_duration_usec);
 		drop_frames(stream, name, priority, p_min_dts_usec);
 	}
 }
@@ -905,7 +984,7 @@ static bool add_video_packet(struct rtmp_stream *stream,
 
 	/* if currently dropping frames, drop packets until it reaches the
 	 * desired priority */
-	if (packet->priority < stream->min_priority) {
+	if (packet->drop_priority < stream->min_priority) {
 		stream->dropped_frames++;
 		return false;
 	} else {
@@ -927,7 +1006,7 @@ static void rtmp_stream_data(void *data, struct encoder_packet *packet)
 	if (packet->type == OBS_ENCODER_VIDEO)
 		obs_parse_avc_packet(&new_packet, packet);
 	else
-		obs_duplicate_encoder_packet(&new_packet, packet);
+		obs_encoder_packet_ref(&new_packet, packet);
 
 	pthread_mutex_lock(&stream->packets_mutex);
 
@@ -942,15 +1021,17 @@ static void rtmp_stream_data(void *data, struct encoder_packet *packet)
 	if (added_packet)
 		os_sem_post(stream->send_sem);
 	else
-		obs_free_encoder_packet(&new_packet);
+		obs_encoder_packet_release(&new_packet);
 }
 
 static void rtmp_stream_defaults(obs_data_t *defaults)
 {
-	obs_data_set_default_int(defaults, OPT_DROP_THRESHOLD, 500);
-	obs_data_set_default_int(defaults, OPT_PFRAME_DROP_THRESHOLD, 800);
+	obs_data_set_default_int(defaults, OPT_DROP_THRESHOLD, 700);
+	obs_data_set_default_int(defaults, OPT_PFRAME_DROP_THRESHOLD, 900);
 	obs_data_set_default_int(defaults, OPT_MAX_SHUTDOWN_TIME_SEC, 30);
 	obs_data_set_default_string(defaults, OPT_BIND_IP, "default");
+	obs_data_set_default_bool(defaults, OPT_NEWSOCKETLOOP_ENABLED, false);
+	obs_data_set_default_bool(defaults, OPT_LOWLATENCY_ENABLED, false);
 }
 
 static obs_properties_t *rtmp_stream_properties(void *unused)
@@ -978,6 +1059,11 @@ static obs_properties_t *rtmp_stream_properties(void *unused)
 	}
 	netif_saddr_data_free(&addrs);
 
+	obs_properties_add_bool(props, OPT_NEWSOCKETLOOP_ENABLED,
+			obs_module_text("RTMPStream.NewSocketLoop"));
+	obs_properties_add_bool(props, OPT_LOWLATENCY_ENABLED,
+			obs_module_text("RTMPStream.LowLatencyMode"));
+
 	return props;
 }
 
@@ -993,6 +1079,17 @@ static int rtmp_stream_dropped_frames(void *data)
 	return stream->dropped_frames;
 }
 
+static float rtmp_stream_congestion(void *data)
+{
+	struct rtmp_stream *stream = data;
+
+	if (stream->new_socket_loop)
+		return (float)stream->write_buf_len /
+			(float)stream->write_buf_size;
+	else
+		return stream->min_priority > 0 ? 1.0f : stream->congestion;
+}
+
 struct obs_output_info rtmp_output_info = {
 	.id                 = "rtmp_output",
 	.flags              = OBS_OUTPUT_AV |
@@ -1008,5 +1105,6 @@ struct obs_output_info rtmp_output_info = {
 	.get_defaults       = rtmp_stream_defaults,
 	.get_properties     = rtmp_stream_properties,
 	.get_total_bytes    = rtmp_stream_total_bytes_sent,
+	.get_congestion     = rtmp_stream_congestion,
 	.get_dropped_frames = rtmp_stream_dropped_frames
 };
diff --git a/plugins/obs-outputs/rtmp-stream.h b/plugins/obs-outputs/rtmp-stream.h
new file mode 100644
index 0000000..38fd760
--- /dev/null
+++ b/plugins/obs-outputs/rtmp-stream.h
@@ -0,0 +1,110 @@
+#include <obs-module.h>
+#include <obs-avc.h>
+#include <util/platform.h>
+#include <util/circlebuf.h>
+#include <util/dstr.h>
+#include <util/threading.h>
+#include <inttypes.h>
+#include "librtmp/rtmp.h"
+#include "librtmp/log.h"
+#include "flv-mux.h"
+#include "net-if.h"
+
+#ifdef _WIN32
+#include <Iphlpapi.h>
+#else
+#include <sys/ioctl.h>
+#endif
+
+#define do_log(level, format, ...) \
+	blog(level, "[rtmp stream: '%s'] " format, \
+			obs_output_get_name(stream->output), ##__VA_ARGS__)
+
+#define warn(format, ...)  do_log(LOG_WARNING, format, ##__VA_ARGS__)
+#define info(format, ...)  do_log(LOG_INFO,    format, ##__VA_ARGS__)
+#define debug(format, ...) do_log(LOG_DEBUG,   format, ##__VA_ARGS__)
+
+#define OPT_DROP_THRESHOLD "drop_threshold_ms"
+#define OPT_PFRAME_DROP_THRESHOLD "pframe_drop_threshold_ms"
+#define OPT_MAX_SHUTDOWN_TIME_SEC "max_shutdown_time_sec"
+#define OPT_BIND_IP "bind_ip"
+#define OPT_NEWSOCKETLOOP_ENABLED "new_socket_loop_enabled"
+#define OPT_LOWLATENCY_ENABLED "low_latency_mode_enabled"
+
+//#define TEST_FRAMEDROPS
+
+#ifdef TEST_FRAMEDROPS
+
+#define DROPTEST_MAX_KBPS 3000
+#define DROPTEST_MAX_BYTES (DROPTEST_MAX_KBPS * 1000 / 8)
+
+struct droptest_info {
+	uint64_t ts;
+	size_t size;
+};
+#endif
+
+struct rtmp_stream {
+	obs_output_t     *output;
+
+	pthread_mutex_t  packets_mutex;
+	struct circlebuf packets;
+	bool             sent_headers;
+
+	volatile bool    connecting;
+	pthread_t        connect_thread;
+
+	volatile bool    active;
+	volatile bool    disconnected;
+	pthread_t        send_thread;
+
+	int              max_shutdown_time_sec;
+
+	os_sem_t         *send_sem;
+	os_event_t       *stop_event;
+	uint64_t         stop_ts;
+	uint64_t         shutdown_timeout_ts;
+
+	struct dstr      path, key;
+	struct dstr      username, password;
+	struct dstr      encoder_name;
+	struct dstr      bind_ip;
+
+	/* frame drop variables */
+	int64_t          drop_threshold_usec;
+	int64_t          min_drop_dts_usec;
+	int64_t          pframe_drop_threshold_usec;
+	int64_t          pframe_min_drop_dts_usec;
+	int              min_priority;
+	float            congestion;
+
+	int64_t          last_dts_usec;
+
+	uint64_t         total_bytes_sent;
+	int              dropped_frames;
+
+#ifdef TEST_FRAMEDROPS
+	struct circlebuf droptest_info;
+	size_t           droptest_size;
+#endif
+
+	RTMP             rtmp;
+
+	bool             new_socket_loop;
+	bool             low_latency_mode;
+	bool             disable_send_window_optimization;
+	bool             socket_thread_active;
+	pthread_t        socket_thread;
+	uint8_t          *write_buf;
+	size_t           write_buf_len;
+	size_t           write_buf_size;
+	pthread_mutex_t  write_buf_mutex;
+	os_event_t       *buffer_space_available_event;
+	os_event_t       *buffer_has_data_event;
+	os_event_t       *socket_available_event;
+	os_event_t       *send_thread_signaled_exit;
+};
+
+#ifdef _WIN32
+void *socket_thread_windows(void *data);
+#endif
diff --git a/plugins/obs-outputs/rtmp-windows.c b/plugins/obs-outputs/rtmp-windows.c
new file mode 100644
index 0000000..5a58753
--- /dev/null
+++ b/plugins/obs-outputs/rtmp-windows.c
@@ -0,0 +1,351 @@
+#ifdef _WIN32
+#include "rtmp-stream.h"
+#include <winsock2.h>
+
+static void fatal_sock_shutdown(struct rtmp_stream *stream)
+{
+	closesocket(stream->rtmp.m_sb.sb_socket);
+	stream->rtmp.m_sb.sb_socket = -1;
+	stream->write_buf_len = 0;
+	os_event_signal(stream->buffer_space_available_event);
+}
+
+static bool socket_event(struct rtmp_stream *stream, bool *can_write,
+		uint64_t last_send_time)
+{
+	WSANETWORKEVENTS net_events;
+	bool success;
+
+	success = !WSAEnumNetworkEvents(stream->rtmp.m_sb.sb_socket, NULL,
+			&net_events);
+	if (!success) {
+		blog(LOG_ERROR, "socket_thread_windows: Aborting due to "
+				"WSAEnumNetworkEvents failure, %d",
+				WSAGetLastError());
+		fatal_sock_shutdown(stream);
+		return false;
+	}
+
+	if (net_events.lNetworkEvents & FD_WRITE)
+		*can_write = true;
+
+	if (net_events.lNetworkEvents & FD_CLOSE) {
+		if (last_send_time) {
+			uint32_t diff =
+				(os_gettime_ns() / 1000000) - last_send_time;
+
+			blog(LOG_ERROR, "socket_thread_windows: Received "
+					"FD_CLOSE, %u ms since last send "
+					"(buffer: %d / %d)",
+					diff,
+					stream->write_buf_len,
+					stream->write_buf_size);
+		}
+
+		if (os_event_try(stream->stop_event) != EAGAIN)
+			blog(LOG_ERROR, "socket_thread_windows: Aborting due "
+					"to FD_CLOSE during shutdown, "
+					"%d bytes lost, error %d",
+					stream->write_buf_len,
+					net_events.iErrorCode[FD_CLOSE_BIT]);
+		else
+			blog(LOG_ERROR, "socket_thread_windows: Aborting due "
+					"to FD_CLOSE, error %d",
+					net_events.iErrorCode[FD_CLOSE_BIT]);
+
+		fatal_sock_shutdown(stream);
+		return false;
+	}
+
+	if (net_events.lNetworkEvents & FD_READ) {
+		char discard[16384];
+		int err_code;
+		bool fatal = false;
+
+		for (;;) {
+			int ret = recv(stream->rtmp.m_sb.sb_socket,
+					discard, sizeof(discard), 0);
+			if (ret == -1) {
+				err_code = WSAGetLastError();
+				if (err_code == WSAEWOULDBLOCK)
+					break;
+
+				fatal = true;
+			} else if (ret == 0) {
+				err_code = 0;
+				fatal = true;
+			}
+
+			if (fatal) {
+				blog(LOG_ERROR, "socket_thread_windows: "
+						"Socket error, recv() returned "
+						"%d, GetLastError() %d",
+						ret, err_code);
+				fatal_sock_shutdown(stream);
+				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
+static void ideal_send_backlog_event(struct rtmp_stream *stream,
+		bool *can_write)
+{
+	ULONG ideal_send_backlog;
+	int ret;
+
+	ret = idealsendbacklogquery(
+			stream->rtmp.m_sb.sb_socket,
+			&ideal_send_backlog);
+	if (ret == 0) {
+		int cur_tcp_bufsize;
+		int size = sizeof(cur_tcp_bufsize);
+
+		ret = getsockopt(stream->rtmp.m_sb.sb_socket,
+				SOL_SOCKET,
+				SO_SNDBUF,
+				(char *)&cur_tcp_bufsize,
+				&size);
+		if (ret == 0) {
+			if (cur_tcp_bufsize < (int)ideal_send_backlog) {
+				int bufsize = (int)ideal_send_backlog;
+				setsockopt(stream->rtmp.m_sb.sb_socket,
+						SOL_SOCKET,
+						SO_SNDBUF,
+						(const char *)&bufsize,
+						sizeof(bufsize));
+
+				blog(LOG_INFO, "socket_thread_windows: "
+						"Increasing send buffer to "
+						"ISB %d (buffer: %d / %d)",
+						ideal_send_backlog,
+						stream->write_buf_len,
+						stream->write_buf_size);
+			}
+		} else {
+			blog(LOG_ERROR, "socket_thread_windows: Got "
+					"send_backlog_event but "
+					"getsockopt() returned %d",
+					WSAGetLastError());
+		}
+	} else {
+		blog(LOG_ERROR, "socket_thread_windows: Got "
+				"send_backlog_event but WSAIoctl() "
+				"returned %d",
+				WSAGetLastError());
+	}
+}
+
+enum data_ret {
+	RET_BREAK,
+	RET_FATAL,
+	RET_CONTINUE
+};
+
+static enum data_ret write_data(struct rtmp_stream *stream, bool *can_write,
+		uint64_t *last_send_time, size_t latency_packet_size,
+		int delay_time)
+{
+	bool exit_loop = false;
+
+	pthread_mutex_lock(&stream->write_buf_mutex);
+
+	if (!stream->write_buf_len) {
+		/* this is now an expected occasional condition due to use of
+		 * auto-reset events, we could end up emptying the buffer as
+		 * it's filled in a previous loop cycle, especially if using
+		 * low latency mode. */
+		pthread_mutex_unlock(&stream->write_buf_mutex);
+		/* blog(LOG_DEBUG, "socket_thread_windows: Trying to send, "
+				"but no data available"); */
+		return RET_BREAK;
+	}
+
+	int ret;
+	if (stream->low_latency_mode) {
+		size_t send_len =
+			min(latency_packet_size, stream->write_buf_len);
+
+		ret = send(stream->rtmp.m_sb.sb_socket,
+				(const char *)stream->write_buf,
+				(int)send_len, 0);
+	} else {
+		ret = send(stream->rtmp.m_sb.sb_socket,
+				(const char *)stream->write_buf,
+				(int)stream->write_buf_len, 0);
+	}
+
+	if (ret > 0) {
+		if (stream->write_buf_len - ret)
+			memmove(stream->write_buf,
+					stream->write_buf + ret,
+					stream->write_buf_len - ret);
+		stream->write_buf_len -= ret;
+
+		*last_send_time = os_gettime_ns() / 1000000;
+
+		os_event_signal(stream->buffer_space_available_event);
+	} else {
+		int err_code;
+		bool fatal_err = false;
+
+		if (ret == -1) {
+			err_code = WSAGetLastError();
+
+			if (err_code == WSAEWOULDBLOCK) {
+				*can_write = false;
+				pthread_mutex_unlock(&stream->write_buf_mutex);
+				return RET_BREAK;
+			}
+
+			fatal_err = true;
+		} else if (ret == 0) {
+			err_code = 0;
+			fatal_err = true;
+		}
+
+		if (fatal_err) {
+			/* connection closed, or connection was aborted /
+			 * socket closed / etc, that's a fatal error. */
+			blog(LOG_ERROR, "socket_thread_windows: "
+					"Socket error, send() returned %d, "
+					"GetLastError() %d",
+					ret, err_code);
+
+			pthread_mutex_unlock(&stream->write_buf_mutex);
+			fatal_sock_shutdown(stream);
+			return RET_FATAL;
+		}
+	}
+
+	/* finish writing for now */
+	if (stream->write_buf_len <= 1000)
+		exit_loop = true;
+
+	pthread_mutex_unlock(&stream->write_buf_mutex);
+
+	if (delay_time)
+		os_sleep_ms(delay_time);
+
+	return exit_loop ? RET_BREAK : RET_CONTINUE;
+}
+
+#define LATENCY_FACTOR 20
+
+static inline void socket_thread_windows_internal(struct rtmp_stream *stream)
+{
+	bool can_write = false;
+
+	int delay_time;
+	size_t latency_packet_size;
+	uint64_t last_send_time = 0;
+
+	HANDLE send_backlog_event;
+	OVERLAPPED send_backlog_overlapped;
+
+	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
+
+	WSAEventSelect(stream->rtmp.m_sb.sb_socket,
+			stream->socket_available_event,
+			FD_READ|FD_WRITE|FD_CLOSE);
+
+	send_backlog_event = CreateEvent(NULL, true, false, NULL);
+
+	if (stream->low_latency_mode) {
+		delay_time = 1000 / LATENCY_FACTOR;
+		latency_packet_size = stream->write_buf_size / (LATENCY_FACTOR - 2);
+	} else {
+		latency_packet_size = stream->write_buf_size;
+		delay_time = 0;
+	}
+
+	if (!stream->disable_send_window_optimization) {
+		memset(&send_backlog_overlapped, 0,
+				sizeof(send_backlog_overlapped));
+		send_backlog_overlapped.hEvent = send_backlog_event;
+		idealsendbacklognotify(stream->rtmp.m_sb.sb_socket,
+				&send_backlog_overlapped, NULL);
+	} else {
+		blog(LOG_INFO, "socket_thread_windows: Send window "
+				"optimization disabled by user.");
+	}
+
+	HANDLE objs[3];
+
+	objs[0] = stream->socket_available_event;
+	objs[1] = stream->buffer_has_data_event;
+	objs[2] = send_backlog_event;
+
+	for (;;) {
+		if (os_event_try(stream->send_thread_signaled_exit) != EAGAIN) {
+			pthread_mutex_lock(&stream->write_buf_mutex);
+			if (stream->write_buf_len == 0) {
+				//blog(LOG_DEBUG, "Exiting on empty buffer");
+				pthread_mutex_unlock(&stream->write_buf_mutex);
+				os_event_reset(stream->send_thread_signaled_exit);
+				break;
+			}
+
+			pthread_mutex_unlock(&stream->write_buf_mutex);
+		}
+
+		int status = WaitForMultipleObjects(3, objs, false, INFINITE);
+		if (status == WAIT_ABANDONED || status == WAIT_FAILED) {
+			blog(LOG_ERROR, "socket_thread_windows: Aborting due "
+					"to WaitForMultipleObjects failure");
+			fatal_sock_shutdown(stream);
+			return;
+		}
+
+		if (status == WAIT_OBJECT_0) {
+			/* Socket event */
+			if (!socket_event(stream, &can_write, last_send_time))
+				return;
+
+		} else if (status == WAIT_OBJECT_0 + 2) {
+			/* Ideal send backlog event */
+			ideal_send_backlog_event(stream, &can_write);
+
+			ResetEvent(send_backlog_event);
+			idealsendbacklognotify(stream->rtmp.m_sb.sb_socket,
+					&send_backlog_overlapped, NULL);
+			continue;
+		}
+
+		if (can_write) {
+			for (;;) {
+				enum data_ret ret = write_data(
+						stream,
+						&can_write,
+						&last_send_time,
+						latency_packet_size,
+						delay_time);
+
+				switch (ret) {
+				case RET_BREAK:
+					goto exit_write_loop;
+				case RET_FATAL:
+					return;
+				case RET_CONTINUE:;
+				}
+			}
+		}
+		exit_write_loop:;
+	}
+
+	if (stream->rtmp.m_sb.sb_socket != INVALID_SOCKET)
+		WSAEventSelect(stream->rtmp.m_sb.sb_socket,
+			stream->socket_available_event, 0);
+
+	blog(LOG_INFO, "socket_thread_windows: Normal exit");
+}
+
+void *socket_thread_windows(void *data)
+{
+	struct rtmp_stream *stream = data;
+	socket_thread_windows_internal(stream);
+	return NULL;
+}
+#endif
diff --git a/plugins/obs-text/data/locale/ca-ES.ini b/plugins/obs-text/data/locale/ca-ES.ini
index 35586b5..0c81137 100644
--- a/plugins/obs-text/data/locale/ca-ES.ini
+++ b/plugins/obs-text/data/locale/ca-ES.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Arxius de text"
 Filter.AllFiles="Tots els fitxers"
 Color="Color"
 Opacity="Opacitat"
+Gradient="Gradient"
+Gradient.Color="Color del gradient"
+Gradient.Opacity="Opacitat del gradient"
+Gradient.Direction="Direcció del gradient"
 BkColor="Color de fons"
 BkOpacity="Opacitat del fons"
 Alignment="Alineació"
diff --git a/plugins/obs-text/data/locale/cs-CZ.ini b/plugins/obs-text/data/locale/cs-CZ.ini
index dd4bf7d..9a0d01c 100644
--- a/plugins/obs-text/data/locale/cs-CZ.ini
+++ b/plugins/obs-text/data/locale/cs-CZ.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Textové soubory"
 Filter.AllFiles="VÅ¡echny soubory"
 Color="Barva"
 Opacity="Krytí"
+Gradient="Přechod barvy"
+Gradient.Color="Barva přechodu"
+Gradient.Opacity="Průhlednost přechodu"
+Gradient.Direction="Směr přechodu"
 BkColor="Barva pozadí"
 BkOpacity="Průhlednost pozadí"
 Alignment="Zarovnání"
diff --git a/plugins/obs-text/data/locale/da-DK.ini b/plugins/obs-text/data/locale/da-DK.ini
new file mode 100644
index 0000000..f914eec
--- /dev/null
+++ b/plugins/obs-text/data/locale/da-DK.ini
@@ -0,0 +1,34 @@
+TextGDIPlus="Tekst (GDI+)"
+Font="Skrifttype"
+Text="Tekst"
+ReadFromFile="Indlæs fra fil"
+TextFile="Tekstfil (UTF-8)"
+Filter.TextFiles="Tekstfiler"
+Filter.AllFiles="Alle filer"
+Color="Farve"
+Opacity="Gennemsigtighed"
+Gradient="Gradient"
+Gradient.Color="Gradient farve"
+Gradient.Opacity="Gradient gennemsigtighed"
+Gradient.Direction="Gradient retning"
+BkColor="Baggrundsfarve"
+BkOpacity="Baggrunds gennemsigtighed"
+Alignment="Justering"
+Alignment.Left="Venstre"
+Alignment.Center="Centreret"
+Alignment.Right="Højre"
+Vertical="Vertikal"
+VerticalAlignment="Vertikal justering"
+VerticalAlignment.Top="Top"
+VerticalAlignment.Bottom="Bund"
+Outline="Kontur"
+Outline.Size="Kontur størrelse"
+Outline.Color="Kontur farve"
+Outline.Opacity="Kontur gennemsigtighed"
+ChatlogMode="Chatlog tilstand"
+ChatlogMode.Lines="Chatlog linebegrænsning"
+UseCustomExtents="Brug tilpasset tekstomfang"
+UseCustomExtents.Wrap="Ombryd"
+Width="Bredde"
+Height="Højde"
+
diff --git a/plugins/obs-text/data/locale/de-DE.ini b/plugins/obs-text/data/locale/de-DE.ini
index 36f8d77..b8980fc 100644
--- a/plugins/obs-text/data/locale/de-DE.ini
+++ b/plugins/obs-text/data/locale/de-DE.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Textdateien"
 Filter.AllFiles="Alle Dateien"
 Color="Farbe"
 Opacity="Deckkraft"
+Gradient="Farbverlauf"
+Gradient.Color="Verlaufsfarbe"
+Gradient.Opacity="Verlaufsdeckkraft"
+Gradient.Direction="Verlaufsrichtung"
 BkColor="Hintergrundfarbe"
 BkOpacity="Hintergrunddeckkraft"
 Alignment="Ausrichtung"
diff --git a/plugins/obs-text/data/locale/el-GR.ini b/plugins/obs-text/data/locale/el-GR.ini
new file mode 100644
index 0000000..b57170a
--- /dev/null
+++ b/plugins/obs-text/data/locale/el-GR.ini
@@ -0,0 +1,6 @@
+Text="Κείμενο"
+Filter.TextFiles="Αρχεία κειμένου"
+Filter.AllFiles="Όλα τα αρχεία"
+Color="Χρώμα"
+Alignment.Right="Δεξιά"
+
diff --git a/plugins/obs-text/data/locale/es-ES.ini b/plugins/obs-text/data/locale/es-ES.ini
index 2332182..35cea31 100644
--- a/plugins/obs-text/data/locale/es-ES.ini
+++ b/plugins/obs-text/data/locale/es-ES.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Archivos de texto"
 Filter.AllFiles="Todos los archivos"
 Color="Color"
 Opacity="Opacidad"
+Gradient="Degradado"
+Gradient.Color="Color del degradado"
+Gradient.Opacity="Opacidad del degradado"
+Gradient.Direction="Dirección del degradado"
 BkColor="Color del fondo"
 BkOpacity="Opacidad del fondo"
 Alignment="Alineamiento"
diff --git a/plugins/obs-text/data/locale/et-EE.ini b/plugins/obs-text/data/locale/et-EE.ini
new file mode 100644
index 0000000..a185cb1
--- /dev/null
+++ b/plugins/obs-text/data/locale/et-EE.ini
@@ -0,0 +1,13 @@
+TextGDIPlus="Tekst (GDI +)"
+Font="Font"
+Text="Tekst"
+ReadFromFile="Loe failist"
+Color="Värv"
+Opacity="Läbipaistvus"
+Alignment.Center="Keskele"
+Outline="Kontuur"
+Outline.Size="Kontuuri suurus"
+Outline.Color="Kontuuri värv"
+Width="Laius"
+Height="Kõrgus"
+
diff --git a/plugins/obs-text/data/locale/eu-ES.ini b/plugins/obs-text/data/locale/eu-ES.ini
index 3a75a66..6c998b0 100644
--- a/plugins/obs-text/data/locale/eu-ES.ini
+++ b/plugins/obs-text/data/locale/eu-ES.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Testu fitxategiak"
 Filter.AllFiles="Fitxategi guztiak"
 Color="Kolorea"
 Opacity="Opakutasuna"
+Gradient="Gradientea"
+Gradient.Color="Gradientearen kolorea"
+Gradient.Opacity="Gradientearen opakutasuna"
+Gradient.Direction="Gradientearen norabidea"
 BkColor="Atzeko planoaren kolorea"
 BkOpacity="Atzeko planoaren opakutasuna"
 Alignment="Lerrokatzea"
diff --git a/plugins/obs-text/data/locale/fi-FI.ini b/plugins/obs-text/data/locale/fi-FI.ini
index 912a4e1..1df85fd 100644
--- a/plugins/obs-text/data/locale/fi-FI.ini
+++ b/plugins/obs-text/data/locale/fi-FI.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Tekstitiedostot"
 Filter.AllFiles="Kaikki tiedostot"
 Color="Väri"
 Opacity="Läpinäkyvyys"
+Gradient="Liuku"
+Gradient.Color="Liukuväri"
+Gradient.Opacity="Liukuva läpinäkyvyys"
+Gradient.Direction="Liu'un suunta"
 BkColor="Taustaväri"
 BkOpacity="Taustan läpinäkyvyys"
 Alignment="Sijoittelu"
diff --git a/plugins/obs-text/data/locale/fr-FR.ini b/plugins/obs-text/data/locale/fr-FR.ini
index 9db7ed5..3a9bbca 100644
--- a/plugins/obs-text/data/locale/fr-FR.ini
+++ b/plugins/obs-text/data/locale/fr-FR.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Fichiers texte"
 Filter.AllFiles="Tous les fichiers"
 Color="Couleur"
 Opacity="Opacité"
+Gradient="Dégradé"
+Gradient.Color="Couleur du dégradé"
+Gradient.Opacity="Opacité du dégradé"
+Gradient.Direction="Direction du dégradé"
 BkColor="Couleur de l'arrière-plan"
 BkOpacity="Transparence de l'arrière-plan"
 Alignment="Alignement"
diff --git a/plugins/obs-text/data/locale/hr-HR.ini b/plugins/obs-text/data/locale/hr-HR.ini
new file mode 100644
index 0000000..148f12c
--- /dev/null
+++ b/plugins/obs-text/data/locale/hr-HR.ini
@@ -0,0 +1,34 @@
+TextGDIPlus="Tekst (GDI+)"
+Font="Font"
+Text="Tekst"
+ReadFromFile="Učitaj iz datoteke"
+TextFile="Tekstualne datoteka (UTF-8)"
+Filter.TextFiles="Tekstualne datoteke"
+Filter.AllFiles="Sve datoteke"
+Color="Boja"
+Opacity="Prozirnost"
+Gradient="Nijansa"
+Gradient.Color="Boja nijanse"
+Gradient.Opacity="Nijansa prozirnosti"
+Gradient.Direction="Pravac nijansi"
+BkColor="Pozadinska boja"
+BkOpacity="Prozirnost pozadine"
+Alignment="Poravnanje"
+Alignment.Left="Levo"
+Alignment.Center="Centrirano"
+Alignment.Right="Desno"
+Vertical="Uspravno"
+VerticalAlignment="Uspravno poravnanje"
+VerticalAlignment.Top="Vrh"
+VerticalAlignment.Bottom="Dno"
+Outline="Okvir"
+Outline.Size="Debljina okvira"
+Outline.Color="Boja okvira"
+Outline.Opacity="Prozirnost okvira"
+ChatlogMode="Režim zapisnika ćaskanja"
+ChatlogMode.Lines="Broj linija u zapisniku"
+UseCustomExtents="Koristi posebne dimenzije teksta"
+UseCustomExtents.Wrap="Prelom"
+Width="Å irina"
+Height="Visina"
+
diff --git a/plugins/obs-text/data/locale/hu-HU.ini b/plugins/obs-text/data/locale/hu-HU.ini
index e46508a..b5d5966 100644
--- a/plugins/obs-text/data/locale/hu-HU.ini
+++ b/plugins/obs-text/data/locale/hu-HU.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Szöveges fájlok"
 Filter.AllFiles="Minden fájl"
 Color="Szín"
 Opacity="Áttetszőség"
+Gradient="Színátmenet"
+Gradient.Color="Színátmenet színe"
+Gradient.Opacity="Színátmenet áttetszősége"
+Gradient.Direction="Színátmenet iránya"
 BkColor="Háttérszín"
 BkOpacity="Háttér áttetszőség"
 Alignment="Pozíció"
diff --git a/plugins/obs-text/data/locale/it-IT.ini b/plugins/obs-text/data/locale/it-IT.ini
new file mode 100644
index 0000000..5200095
--- /dev/null
+++ b/plugins/obs-text/data/locale/it-IT.ini
@@ -0,0 +1,34 @@
+TextGDIPlus="Testo (GDI+)"
+Font="Font"
+Text="Testo"
+ReadFromFile="Leggi da file"
+TextFile="File di testo (UTF-8)"
+Filter.TextFiles="File di testo"
+Filter.AllFiles="Tutti i file"
+Color="Colore"
+Opacity="Opacità"
+Gradient="Sfumato"
+Gradient.Color="Colore sfumatura"
+Gradient.Opacity="Opacità sfumatura"
+Gradient.Direction="Direzione sfumatura"
+BkColor="Colore dello sfondo"
+BkOpacity="Opacità Sfondo"
+Alignment="Allineamento"
+Alignment.Left="A sinistra"
+Alignment.Center="Al centro"
+Alignment.Right="A destra"
+Vertical="Verticale"
+VerticalAlignment="Allineamento verticale"
+VerticalAlignment.Top="Alto"
+VerticalAlignment.Bottom="Dal basso"
+Outline="Contorno"
+Outline.Size="Dimensione contorno"
+Outline.Color="Colore del contorno"
+Outline.Opacity="Opacità contorno"
+ChatlogMode="Modalità Chatlog"
+ChatlogMode.Lines="Limite linea Chatlog"
+UseCustomExtents="Usa personalizzazioni testo"
+UseCustomExtents.Wrap="A capo automatico"
+Width="Larghezza"
+Height="Altezza"
+
diff --git a/plugins/obs-text/data/locale/ja-JP.ini b/plugins/obs-text/data/locale/ja-JP.ini
index 7797aa0..386b4ce 100644
--- a/plugins/obs-text/data/locale/ja-JP.ini
+++ b/plugins/obs-text/data/locale/ja-JP.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="テキストファイル"
 Filter.AllFiles="すべてのファイル"
 Color="色"
 Opacity="不透明度"
+Gradient="グラデーション"
+Gradient.Color="グラデーションカラー"
+Gradient.Opacity="グラデーションの不透明度"
+Gradient.Direction="グラデーションの方向"
 BkColor="背景色"
 BkOpacity="背景の不透明度"
 Alignment="位置揃え"
diff --git a/plugins/obs-text/data/locale/ko-KR.ini b/plugins/obs-text/data/locale/ko-KR.ini
index 2547c75..ecc0e5f 100644
--- a/plugins/obs-text/data/locale/ko-KR.ini
+++ b/plugins/obs-text/data/locale/ko-KR.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="텍스트 파일"
 Filter.AllFiles="모든 파일"
 Color="색"
 Opacity="투명도"
+Gradient="바림"
+Gradient.Color="바림 색"
+Gradient.Opacity="발미 불투명도"
+Gradient.Direction="바림 방향"
 BkColor="배경 색상"
 BkOpacity="배경 불투명도"
 Alignment="ì •ë ¬"
diff --git a/plugins/obs-text/data/locale/nb-NO.ini b/plugins/obs-text/data/locale/nb-NO.ini
new file mode 100644
index 0000000..2366aa0
--- /dev/null
+++ b/plugins/obs-text/data/locale/nb-NO.ini
@@ -0,0 +1,25 @@
+TextGDIPlus="Tekst (GDI +)"
+Font="Skrifttype"
+Text="Tekst"
+ReadFromFile="Lese fra fil"
+TextFile="Tekstfil (UTF-8)"
+Filter.TextFiles="Tekstfiler"
+Filter.AllFiles="Alle filer"
+Color="Farge"
+Opacity="Gjennomsiktighet"
+BkColor="Bakgrunnsfarge"
+BkOpacity="Gjennomsiktighet bakgrunn"
+Alignment="Justering"
+Alignment.Left="Venstre"
+Alignment.Center="I midten"
+Alignment.Right="Høyre"
+Vertical="Vertikal"
+VerticalAlignment="Loddrett justering"
+VerticalAlignment.Top="Topp"
+VerticalAlignment.Bottom="Bunn"
+ChatlogMode="Chatlog modus"
+UseCustomExtents="Bruk egendefinerte tekst-utvidelser"
+UseCustomExtents.Wrap="Ordbrytning"
+Width="Bredde"
+Height="Høyde"
+
diff --git a/plugins/obs-text/data/locale/nl-NL.ini b/plugins/obs-text/data/locale/nl-NL.ini
index dc93904..098be9f 100644
--- a/plugins/obs-text/data/locale/nl-NL.ini
+++ b/plugins/obs-text/data/locale/nl-NL.ini
@@ -7,6 +7,12 @@ Filter.TextFiles="Tekstbestanden"
 Filter.AllFiles="Alle bestanden"
 Color="Kleur"
 Opacity="Dekking"
+Gradient="Kleurovergang"
+Gradient.Color="Overgangskleur"
+Gradient.Opacity="Kleurovergang Dekking"
+Gradient.Direction="Kleurovergang Richting"
+BkColor="Achtergrondkleur"
+BkOpacity="Achtergronddekking"
 Alignment="Uitlijning"
 Alignment.Left="Links"
 Alignment.Center="Midden"
diff --git a/plugins/obs-text/data/locale/pl-PL.ini b/plugins/obs-text/data/locale/pl-PL.ini
index 6298b53..384ca15 100644
--- a/plugins/obs-text/data/locale/pl-PL.ini
+++ b/plugins/obs-text/data/locale/pl-PL.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Pliki tekstowe"
 Filter.AllFiles="Wszystkie pliki"
 Color="Kolor"
 Opacity="Przezroczystość"
+Gradient="Gradient"
+Gradient.Color="Kolor gradientu"
+Gradient.Opacity="Przezroczystość gradientu"
+Gradient.Direction="Kierunek gradientu"
 BkColor="Kolor tła"
 BkOpacity="Przezroczystość tła"
 Alignment="Wyrównanie"
diff --git a/plugins/obs-text/data/locale/pt-BR.ini b/plugins/obs-text/data/locale/pt-BR.ini
new file mode 100644
index 0000000..64a966e
--- /dev/null
+++ b/plugins/obs-text/data/locale/pt-BR.ini
@@ -0,0 +1,34 @@
+TextGDIPlus="Texto (GDI+)"
+Font="Fonte"
+Text="Texto"
+ReadFromFile="Carregar do Arquivo"
+TextFile="Arquivo de Texto (UTF-8)"
+Filter.TextFiles="Arquivos de Texto"
+Filter.AllFiles="Todos os Arquivos"
+Color="Cor"
+Opacity="Opacidade"
+Gradient="Gradiente"
+Gradient.Color="Cor do Gradiente"
+Gradient.Opacity="Opacidade do Gradiente"
+Gradient.Direction="Direção do Gradiente"
+BkColor="Cor de Fundo"
+BkOpacity="Opacidade de Fundo"
+Alignment="Alinhamento"
+Alignment.Left="Esquerda"
+Alignment.Center="Centralizado"
+Alignment.Right="Direita"
+Vertical="Vertical"
+VerticalAlignment="Alinhamento Vertical"
+VerticalAlignment.Top="Em cima"
+VerticalAlignment.Bottom="Em baixo"
+Outline="Contorno"
+Outline.Size="Tamanho do Contorno"
+Outline.Color="Cor do Contorno"
+Outline.Opacity="Opacidade do Contorno"
+ChatlogMode="Modo de Chat"
+ChatlogMode.Lines="Limite de Linhas do Chat"
+UseCustomExtents="Usar extensões de texto personalizadas"
+UseCustomExtents.Wrap="Ajustar"
+Width="Largura"
+Height="Altura"
+
diff --git a/plugins/obs-text/data/locale/ro-RO.ini b/plugins/obs-text/data/locale/ro-RO.ini
new file mode 100644
index 0000000..1d46224
--- /dev/null
+++ b/plugins/obs-text/data/locale/ro-RO.ini
@@ -0,0 +1,23 @@
+TextGDIPlus="Text (GDI+)"
+Font="Font"
+Text="Text"
+ReadFromFile="Citește din fișier"
+TextFile="Fișier text (UTF-8)"
+Filter.TextFiles="Fișiere Text"
+Filter.AllFiles="Toate fișierele"
+Color="Culoare"
+Opacity="Opacitate"
+BkColor="Culoare Fundal"
+BkOpacity="Opacitate Fundal"
+Alignment="Aliniere"
+Alignment.Left="Stânga"
+Alignment.Center="Centru"
+Alignment.Right="Dreapta"
+Vertical="Vertical"
+Outline="Contur"
+Outline.Size="Dimensiune Contur"
+Outline.Color="Culoare Contur"
+Outline.Opacity="Opacitate Contur"
+Width="Lățime"
+Height="Înălțime"
+
diff --git a/plugins/obs-text/data/locale/ru-RU.ini b/plugins/obs-text/data/locale/ru-RU.ini
index 04d81ce..07dafec 100644
--- a/plugins/obs-text/data/locale/ru-RU.ini
+++ b/plugins/obs-text/data/locale/ru-RU.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Текстовые файлы"
 Filter.AllFiles="Все файлы"
 Color="Цвет"
 Opacity="Непрозрачность"
+Gradient="Градиент"
+Gradient.Color="Цвет градиента"
+Gradient.Opacity="Непрозрачность градиента"
+Gradient.Direction="Направление градиента"
 BkColor="Цвет фона"
 BkOpacity="Непрозрачность фона"
 Alignment="Выравнивание"
diff --git a/plugins/obs-text/data/locale/sk-SK.ini b/plugins/obs-text/data/locale/sk-SK.ini
new file mode 100644
index 0000000..4a9377a
--- /dev/null
+++ b/plugins/obs-text/data/locale/sk-SK.ini
@@ -0,0 +1,3 @@
+Color="Farba"
+Opacity="Priehľadnosť"
+
diff --git a/plugins/obs-text/data/locale/sr-CS.ini b/plugins/obs-text/data/locale/sr-CS.ini
new file mode 100644
index 0000000..148f12c
--- /dev/null
+++ b/plugins/obs-text/data/locale/sr-CS.ini
@@ -0,0 +1,34 @@
+TextGDIPlus="Tekst (GDI+)"
+Font="Font"
+Text="Tekst"
+ReadFromFile="Učitaj iz datoteke"
+TextFile="Tekstualne datoteka (UTF-8)"
+Filter.TextFiles="Tekstualne datoteke"
+Filter.AllFiles="Sve datoteke"
+Color="Boja"
+Opacity="Prozirnost"
+Gradient="Nijansa"
+Gradient.Color="Boja nijanse"
+Gradient.Opacity="Nijansa prozirnosti"
+Gradient.Direction="Pravac nijansi"
+BkColor="Pozadinska boja"
+BkOpacity="Prozirnost pozadine"
+Alignment="Poravnanje"
+Alignment.Left="Levo"
+Alignment.Center="Centrirano"
+Alignment.Right="Desno"
+Vertical="Uspravno"
+VerticalAlignment="Uspravno poravnanje"
+VerticalAlignment.Top="Vrh"
+VerticalAlignment.Bottom="Dno"
+Outline="Okvir"
+Outline.Size="Debljina okvira"
+Outline.Color="Boja okvira"
+Outline.Opacity="Prozirnost okvira"
+ChatlogMode="Režim zapisnika ćaskanja"
+ChatlogMode.Lines="Broj linija u zapisniku"
+UseCustomExtents="Koristi posebne dimenzije teksta"
+UseCustomExtents.Wrap="Prelom"
+Width="Å irina"
+Height="Visina"
+
diff --git a/plugins/obs-text/data/locale/sr-SP.ini b/plugins/obs-text/data/locale/sr-SP.ini
new file mode 100644
index 0000000..6ca784c
--- /dev/null
+++ b/plugins/obs-text/data/locale/sr-SP.ini
@@ -0,0 +1,34 @@
+TextGDIPlus="Текст (GDI+)"
+Font="Фонт"
+Text="Текст"
+ReadFromFile="Учитај из датотеке"
+TextFile="Текстуалне датотеке (UTF-8)"
+Filter.TextFiles="Текстуалне датотеке"
+Filter.AllFiles="Све датотеке"
+Color="Боја"
+Opacity="Прозирност"
+Gradient="Нијанса"
+Gradient.Color="Боја нијансе"
+Gradient.Opacity="Нијанса прозирности"
+Gradient.Direction="Правац нијанси"
+BkColor="Позадинска боја"
+BkOpacity="Прозирност позадине"
+Alignment="Поравнање"
+Alignment.Left="Лево"
+Alignment.Center="Центрирано"
+Alignment.Right="Десно"
+Vertical="Усправно"
+VerticalAlignment="Усправно поравнање"
+VerticalAlignment.Top="Врх"
+VerticalAlignment.Bottom="Дно"
+Outline="Оквир"
+Outline.Size="Дебљина оквира"
+Outline.Color="Боја оквира"
+Outline.Opacity="Прозирност оквира"
+ChatlogMode="Режим записника ћаскања"
+ChatlogMode.Lines="Број линија у записнику"
+UseCustomExtents="Користи посебне димензије текста"
+UseCustomExtents.Wrap="Прелом"
+Width="Ширина"
+Height="Висина"
+
diff --git a/plugins/obs-text/data/locale/sv-SE.ini b/plugins/obs-text/data/locale/sv-SE.ini
index 70fa8b9..7f108f8 100644
--- a/plugins/obs-text/data/locale/sv-SE.ini
+++ b/plugins/obs-text/data/locale/sv-SE.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Textfiler"
 Filter.AllFiles="Alla filer"
 Color="Färg"
 Opacity="Opacitet"
+Gradient="Gradient"
+Gradient.Color="Gradientfärg"
+Gradient.Opacity="Gradientopacitet"
+Gradient.Direction="Gradientriktning"
 BkColor="Bakgrundsfärg"
 BkOpacity="Bakgrundsopacitet"
 Alignment="Justering"
diff --git a/plugins/obs-text/data/locale/tr-TR.ini b/plugins/obs-text/data/locale/tr-TR.ini
new file mode 100644
index 0000000..289e570
--- /dev/null
+++ b/plugins/obs-text/data/locale/tr-TR.ini
@@ -0,0 +1,34 @@
+TextGDIPlus="Metin (GDI+)"
+Font="Yazı Tipi"
+Text="Metin"
+ReadFromFile="Dosyadan oku"
+TextFile="Metin Dosyası (UTF-8)"
+Filter.TextFiles="Metin Dosyaları"
+Filter.AllFiles="Tüm Dosyalar"
+Color="Renk"
+Opacity="Opaklık"
+Gradient="EÄŸim"
+Gradient.Color="EÄŸim Rengi"
+Gradient.Opacity="Eğim Saydamlığı"
+Gradient.Direction="Eğim Yönü"
+BkColor="Arka Plan Rengi"
+BkOpacity="Arkaplan Saydamlığı"
+Alignment="Hizalama"
+Alignment.Left="Sol"
+Alignment.Center="Ortala"
+Alignment.Right="SaÄŸ"
+Vertical="Dikey"
+VerticalAlignment="Dikey Hizalama"
+VerticalAlignment.Top="Ãœst"
+VerticalAlignment.Bottom="Alt"
+Outline="Anahat"
+Outline.Size="Anahat Boyutu"
+Outline.Color="Anahat Rengi"
+Outline.Opacity="Anahat Saydamlığı"
+ChatlogMode="Sohbet Günlük Modu"
+ChatlogMode.Lines="Sohbet Günlük Satır Sınırı"
+UseCustomExtents="İsteğe Bağlı Metin Boyutu Kullan"
+UseCustomExtents.Wrap="Metni Kaydır"
+Width="GeniÅŸlik"
+Height="Yükseklik"
+
diff --git a/plugins/obs-text/data/locale/uk-UA.ini b/plugins/obs-text/data/locale/uk-UA.ini
index 1ea325c..a6c9ba9 100644
--- a/plugins/obs-text/data/locale/uk-UA.ini
+++ b/plugins/obs-text/data/locale/uk-UA.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="Текстові файли"
 Filter.AllFiles="Всі файли"
 Color="Колір"
 Opacity="Непрозорість"
+Gradient="Градієнтна заливка"
+Gradient.Color="Колір градієнта"
+Gradient.Opacity="Непрозорость градієнта"
+Gradient.Direction="Напрямок градієнта (кут)"
 BkColor="Колір фону"
 BkOpacity="Непрозорість фону"
 Alignment="Вирівнювання"
diff --git a/plugins/obs-text/data/locale/zh-CN.ini b/plugins/obs-text/data/locale/zh-CN.ini
index d86290e..83d0361 100644
--- a/plugins/obs-text/data/locale/zh-CN.ini
+++ b/plugins/obs-text/data/locale/zh-CN.ini
@@ -7,6 +7,10 @@ Filter.TextFiles="文本文件"
 Filter.AllFiles="所有文件"
 Color="色彩"
 Opacity="不透明度"
+Gradient="渐变"
+Gradient.Color="渐变颜色"
+Gradient.Opacity="渐变不透明度"
+Gradient.Direction="渐变方向"
 BkColor="背景颜色"
 BkOpacity="背景不透明度"
 Alignment="对齐"
diff --git a/plugins/obs-text/data/locale/zh-TW.ini b/plugins/obs-text/data/locale/zh-TW.ini
index b883e91..8f18a35 100644
--- a/plugins/obs-text/data/locale/zh-TW.ini
+++ b/plugins/obs-text/data/locale/zh-TW.ini
@@ -7,6 +7,12 @@ Filter.TextFiles="文字檔案"
 Filter.AllFiles="所有檔案"
 Color="顏色"
 Opacity="不透明度"
+Gradient="漸層"
+Gradient.Color="漸層色彩"
+Gradient.Opacity="漸層不透明度"
+Gradient.Direction="漸層方向"
+BkColor="背景顏色"
+BkOpacity="背景不透明度"
 Alignment="對齊方式"
 Alignment.Left="靠左對齊"
 Alignment.Center="置中"
diff --git a/plugins/obs-text/gdiplus/obs-text.cpp b/plugins/obs-text/gdiplus/obs-text.cpp
index 2878b08..8a040be 100644
--- a/plugins/obs-text/gdiplus/obs-text.cpp
+++ b/plugins/obs-text/gdiplus/obs-text.cpp
@@ -288,6 +288,7 @@ void TextSource::UpdateFont()
 	lf.lfUnderline = underline;
 	lf.lfStrikeOut = strikeout;
 	lf.lfQuality = ANTIALIASED_QUALITY;
+	lf.lfCharSet = DEFAULT_CHARSET;
 
 	if (!face.empty()) {
 		wcscpy(lf.lfFaceName, face.c_str());
@@ -787,7 +788,6 @@ inline void TextSource::Render(gs_effect_t *effect)
 	if (!tex)
 		return;
 
-	gs_reset_blend_state();
 	gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), tex);
 	gs_draw_sprite(tex, 0, cx, cy);
 }
diff --git a/plugins/obs-transitions/data/fade_to_color_transition.effect b/plugins/obs-transitions/data/fade_to_color_transition.effect
index 4f06935..130d44a 100644
--- a/plugins/obs-transitions/data/fade_to_color_transition.effect
+++ b/plugins/obs-transitions/data/fade_to_color_transition.effect
@@ -14,6 +14,8 @@ struct VertData {
 	float2 uv  : TEXCOORD0;
 };
 
+#include "premultiplied.inc"
+
 VertData VSDefault(VertData v_in)
 {
 	VertData vert_out;
@@ -24,7 +26,7 @@ VertData VSDefault(VertData v_in)
 
 float4 PSFadeToColor(VertData v_in) : TARGET
 {
-	return lerp(tex.Sample(textureSampler, v_in.uv), color, swp);
+	return lerp(convert_pmalpha(tex.Sample(textureSampler, v_in.uv)), color, swp);
 }
 
 technique FadeToColor
diff --git a/plugins/obs-transitions/data/fade_transition.effect b/plugins/obs-transitions/data/fade_transition.effect
index f728f3a..bba5031 100644
--- a/plugins/obs-transitions/data/fade_transition.effect
+++ b/plugins/obs-transitions/data/fade_transition.effect
@@ -14,6 +14,8 @@ struct VertData {
 	float2 uv  : TEXCOORD0;
 };
 
+#include "premultiplied.inc"
+
 VertData VSDefault(VertData v_in)
 {
 	VertData vert_out;
@@ -24,8 +26,8 @@ VertData VSDefault(VertData v_in)
 
 float4 PSFade(VertData v_in) : TARGET
 {
-	float4 a_val = tex_a.Sample(textureSampler, v_in.uv);
-	float4 b_val = tex_b.Sample(textureSampler, v_in.uv);
+	float4 a_val = convert_pmalpha(tex_a.Sample(textureSampler, v_in.uv));
+	float4 b_val = convert_pmalpha(tex_b.Sample(textureSampler, v_in.uv));
 	return lerp(a_val, b_val, fade_val);
 }
 
diff --git a/plugins/obs-transitions/data/locale/da-DK.ini b/plugins/obs-transitions/data/locale/da-DK.ini
index 557b727..025f383 100644
--- a/plugins/obs-transitions/data/locale/da-DK.ini
+++ b/plugins/obs-transitions/data/locale/da-DK.ini
@@ -11,4 +11,42 @@ Direction.Down="Ned"
 SwipeIn="Swipe ind"
 Color="Farve"
 SwitchPoint="Farvepeakpunkt (procent)"
+LumaWipeTransition="Luma overgang"
+LumaWipe.Image="Billede"
+LumaWipe.Invert="Inverter"
+LumaWipe.Softness="Blødhed"
+LumaWipe.Type.BarndoorBottomLeft="Stalddør nederst til venstre"
+LumaWipe.Type.BarndoorHorizontal="Stalddør horisontal"
+LumaWipe.Type.BarndoorTopLeft="Stalddør øverst til venstre"
+LumaWipe.Type.BarndoorVertical="Stalddør vertikal"
+LumaWipe.Type.BlindsHorizontal="Persienne horisontal"
+LumaWipe.Type.BoxBottomLeft="Boks nederst til venstre"
+LumaWipe.Type.BoxBottomRight="Boks nederst til højre"
+LumaWipe.Type.BoxTopLeft="Boks øverst til venstre"
+LumaWipe.Type.BoxTopRight="Boks øverst til højre"
+LumaWipe.Type.Burst="Sprængning"
+LumaWipe.Type.CheckerboardSmall="Små skaktern"
+LumaWipe.Type.Circles="Cirkler"
+LumaWipe.Type.Clock="Ur"
+LumaWipe.Type.Cloud="Sky"
+LumaWipe.Type.Curtain="Gardin"
+LumaWipe.Type.Fan="Vifte"
+LumaWipe.Type.Fractal="Fraktal"
+LumaWipe.Type.Iris="Iris"
+LumaWipe.Type.LinearHorizontal="Lineær horisontal"
+LumaWipe.Type.LinearTopLeft="Lineær øverst til venstre"
+LumaWipe.Type.LinearTopRight="Lineær øverst til højre"
+LumaWipe.Type.LinearVertical="Lineær vertikal"
+LumaWipe.Type.ParallelZigzagHorizontal="Parallel zigzag horisontal"
+LumaWipe.Type.ParallelZigzagVertical="Parallel zigzag vertikal"
+LumaWipe.Type.Sinus9="Sinus 9"
+LumaWipe.Type.Spiral="Spiral"
+LumaWipe.Type.Square="Firkant"
+LumaWipe.Type.Squares="Firkanter"
+LumaWipe.Type.Stripes="Striber"
+LumaWipe.Type.StripsHorizontal="Strimmel horisontal"
+LumaWipe.Type.StripsVertical="Strimmel vertikal"
+LumaWipe.Type.Watercolor="Vandfarve"
+LumaWipe.Type.ZigzagHorizontal="Zigzag horisontal"
+LumaWipe.Type.ZigzagVertical="Zigzag vertical"
 
diff --git a/plugins/obs-transitions/data/locale/el-GR.ini b/plugins/obs-transitions/data/locale/el-GR.ini
index a23a5cf..f8b75f3 100644
--- a/plugins/obs-transitions/data/locale/el-GR.ini
+++ b/plugins/obs-transitions/data/locale/el-GR.ini
@@ -1,3 +1,6 @@
 FadeTransition="Ξεθώριασμα"
 CutTransition="Αποκοπή"
+Direction.Left="Αριστερά"
+Direction.Right="Δεξιά"
+Color="Χρώμα"
 
diff --git a/plugins/obs-transitions/data/locale/et-EE.ini b/plugins/obs-transitions/data/locale/et-EE.ini
new file mode 100644
index 0000000..1486d15
--- /dev/null
+++ b/plugins/obs-transitions/data/locale/et-EE.ini
@@ -0,0 +1,23 @@
+FadeTransition="Hajuv"
+CutTransition="Lõika"
+SwipeTransition="Pühkiv"
+SlideTransition="Lenda sisse"
+FadeToColorTransition="Haju värvi"
+Direction="Suunas"
+Direction.Left="Vasakule"
+Direction.Right="Paremale"
+Direction.Up="Ãœles"
+Direction.Down="Alla"
+SwipeIn="Pühi sisse"
+Color="Värv"
+LumaWipe.Image="Pilt"
+LumaWipe.Invert="Teistpidi"
+LumaWipe.Softness="Pehmus"
+LumaWipe.Type.BoxTopLeft="Kast üleval vasakul"
+LumaWipe.Type.BoxTopRight="Kast üleval paremal"
+LumaWipe.Type.Burst="Plahvatuse"
+LumaWipe.Type.Clock="Kell"
+LumaWipe.Type.Cloud="Pilv"
+LumaWipe.Type.Curtain="Kardin"
+LumaWipe.Type.Fan="Ventilaator"
+
diff --git a/plugins/obs-transitions/data/locale/nb-NO.ini b/plugins/obs-transitions/data/locale/nb-NO.ini
index 56d5b20..75b0b73 100644
--- a/plugins/obs-transitions/data/locale/nb-NO.ini
+++ b/plugins/obs-transitions/data/locale/nb-NO.ini
@@ -11,4 +11,7 @@ Direction.Down="Ned"
 SwipeIn="Sveip inn"
 Color="Farge"
 SwitchPoint="Farge ved høydepunkt (prosent)"
+LumaWipe.Image="Bilde"
+LumaWipe.Invert="Inverter"
+LumaWipe.Softness="Mykhet"
 
diff --git a/plugins/obs-transitions/data/locale/pt-BR.ini b/plugins/obs-transitions/data/locale/pt-BR.ini
index 8fce5f0..bec4e96 100644
--- a/plugins/obs-transitions/data/locale/pt-BR.ini
+++ b/plugins/obs-transitions/data/locale/pt-BR.ini
@@ -20,4 +20,24 @@ LumaWipe.Type.BarndoorHorizontal="Barndoor Horizontal"
 LumaWipe.Type.BarndoorTopLeft="Barndoor inferior esquerdo"
 LumaWipe.Type.BarndoorVertical="Barndoor Vertical"
 LumaWipe.Type.BlindsHorizontal="Persianas horizontais"
+LumaWipe.Type.Circles="Círculos"
+LumaWipe.Type.Clock="Relógio"
+LumaWipe.Type.Cloud="Nuvem"
+LumaWipe.Type.Curtain="Cortina"
+LumaWipe.Type.Fan="Ventilar"
+LumaWipe.Type.Fractal="Fractal"
+LumaWipe.Type.Iris="Iris"
+LumaWipe.Type.LinearHorizontal="Linear Horizontal"
+LumaWipe.Type.LinearTopLeft="Linear superior esquerdo"
+LumaWipe.Type.LinearTopRight="Linear superior direito"
+LumaWipe.Type.LinearVertical="Linear Vertical"
+LumaWipe.Type.Spiral="Espiral"
+LumaWipe.Type.Square="Quadrado"
+LumaWipe.Type.Squares="Quadrados"
+LumaWipe.Type.Stripes="Listras"
+LumaWipe.Type.StripsHorizontal="Listras horizontais"
+LumaWipe.Type.StripsVertical="Listras Verticais"
+LumaWipe.Type.Watercolor="Aquarela"
+LumaWipe.Type.ZigzagHorizontal="Zigue-zague Horizontal"
+LumaWipe.Type.ZigzagVertical="Zigue-zague Vertical"
 
diff --git a/plugins/obs-transitions/data/locale/ro-RO.ini b/plugins/obs-transitions/data/locale/ro-RO.ini
index 7c76c1f..c8f7860 100644
--- a/plugins/obs-transitions/data/locale/ro-RO.ini
+++ b/plugins/obs-transitions/data/locale/ro-RO.ini
@@ -11,4 +11,8 @@ Direction.Down="Jos"
 SwipeIn="Glisați înauntru"
 Color="Culoare"
 SwitchPoint="Punctul de vârf al culorii (procent)"
+LumaWipe.Image="Imagine"
+LumaWipe.Type.Cloud="Cloud"
+LumaWipe.Type.ZigzagHorizontal="Zigzag orizontal"
+LumaWipe.Type.ZigzagVertical="Zigzag Vertical"
 
diff --git a/plugins/obs-transitions/data/locale/sv-SE.ini b/plugins/obs-transitions/data/locale/sv-SE.ini
index 89e14e3..53b7383 100644
--- a/plugins/obs-transitions/data/locale/sv-SE.ini
+++ b/plugins/obs-transitions/data/locale/sv-SE.ini
@@ -10,6 +10,7 @@ Direction.Up="Upp"
 Direction.Down="Ned"
 SwipeIn="Svep in"
 Color="Färg"
+SwitchPoint="Maxpunkt för färg (procent)"
 LumaWipeTransition="Luma Wipe"
 LumaWipe.Image="Bild"
 LumaWipe.Invert="Invertera"
diff --git a/plugins/obs-transitions/data/locale/tr-TR.ini b/plugins/obs-transitions/data/locale/tr-TR.ini
index 77c90e9..8a1862d 100644
--- a/plugins/obs-transitions/data/locale/tr-TR.ini
+++ b/plugins/obs-transitions/data/locale/tr-TR.ini
@@ -2,10 +2,51 @@ FadeTransition="Soldur"
 CutTransition="Kes"
 SwipeTransition="Kaydır"
 SlideTransition="Kaydır"
+FadeToColorTransition="Fade to Color"
 Direction="Yönlendir"
 Direction.Left="Sol"
 Direction.Right="SaÄŸ"
 Direction.Up="Yukarı"
 Direction.Down="Aşağı"
+SwipeIn="İçeri Kaydır"
 Color="Renk"
+SwitchPoint="En yüksek Renk Noktası (yüzde)"
+LumaWipeTransition="Luma Wipe"
+LumaWipe.Image="Görüntü"
+LumaWipe.Invert="Ters Çevir"
+LumaWipe.Softness="Yumuşaklık"
+LumaWipe.Type.BarndoorBottomLeft="Barndoor Bottom Left"
+LumaWipe.Type.BarndoorHorizontal="Barndoor Horizontal"
+LumaWipe.Type.BarndoorTopLeft="Barndoor Top Left"
+LumaWipe.Type.BarndoorVertical="Barndoor Vertical"
+LumaWipe.Type.BlindsHorizontal="Blinds Horizontal"
+LumaWipe.Type.BoxBottomLeft="Box Bottom Left"
+LumaWipe.Type.BoxBottomRight="Box Bottom Right"
+LumaWipe.Type.BoxTopLeft="Box Top Left"
+LumaWipe.Type.BoxTopRight="Box Top Right"
+LumaWipe.Type.Burst="Burst"
+LumaWipe.Type.CheckerboardSmall="Checkerboard Small"
+LumaWipe.Type.Circles="Circles"
+LumaWipe.Type.Clock="Clock"
+LumaWipe.Type.Cloud="Cloud"
+LumaWipe.Type.Curtain="Curtain"
+LumaWipe.Type.Fan="Fan"
+LumaWipe.Type.Fractal="Fractal"
+LumaWipe.Type.Iris="Iris"
+LumaWipe.Type.LinearHorizontal="Linear Horizontal"
+LumaWipe.Type.LinearTopLeft="Linear Top Left"
+LumaWipe.Type.LinearTopRight="Linear Top Right"
+LumaWipe.Type.LinearVertical="Linear Vertical"
+LumaWipe.Type.ParallelZigzagHorizontal="Parallel Zigzag Horizontal"
+LumaWipe.Type.ParallelZigzagVertical="Parallel Zigzag Vertical"
+LumaWipe.Type.Sinus9="Sinus 9"
+LumaWipe.Type.Spiral="Spiral"
+LumaWipe.Type.Square="Square"
+LumaWipe.Type.Squares="Squares"
+LumaWipe.Type.Stripes="Stripes"
+LumaWipe.Type.StripsHorizontal="Strips Horizontal"
+LumaWipe.Type.StripsVertical="Strips Vertical"
+LumaWipe.Type.Watercolor="Watercolor"
+LumaWipe.Type.ZigzagHorizontal="Zigzag Horizontal"
+LumaWipe.Type.ZigzagVertical="Zigzag Vertical"
 
diff --git a/plugins/obs-transitions/data/luma_wipe_transition.effect b/plugins/obs-transitions/data/luma_wipe_transition.effect
index baab294..92fb318 100644
--- a/plugins/obs-transitions/data/luma_wipe_transition.effect
+++ b/plugins/obs-transitions/data/luma_wipe_transition.effect
@@ -20,6 +20,8 @@ struct VertData {
 	float2 uv  : TEXCOORD0;
 };
 
+#include "premultiplied.inc"
+
 VertData VSDefault(VertData v_in)
 {
 	VertData vert_out;
@@ -31,8 +33,8 @@ VertData VSDefault(VertData v_in)
 float4 PSLumaWipe(VertData v_in) : TARGET
 {
 	float2 uv = v_in.uv;
-	float4 a_color = a_tex.Sample(textureSampler, uv);
-	float4 b_color = b_tex.Sample(textureSampler, uv);
+	float4 a_color = convert_pmalpha(a_tex.Sample(textureSampler, uv));
+	float4 b_color = convert_pmalpha(b_tex.Sample(textureSampler, uv));
 	float luma     = l_tex.Sample(textureSampler, uv).x;
 
 	if (invert)
diff --git a/plugins/obs-transitions/data/premultiplied.inc b/plugins/obs-transitions/data/premultiplied.inc
new file mode 100644
index 0000000..450f6d4
--- /dev/null
+++ b/plugins/obs-transitions/data/premultiplied.inc
@@ -0,0 +1,9 @@
+float4 convert_pmalpha(float4 color)
+{
+	float4 ret = color;
+	if (color.a >= 0.001)
+		ret.xyz /= color.a;
+	else
+		ret = float4(0.0, 0.0, 0.0, 0.0);
+	return ret;
+}
diff --git a/plugins/obs-transitions/data/slide_transition.effect b/plugins/obs-transitions/data/slide_transition.effect
index 91a9b89..489ae7d 100644
--- a/plugins/obs-transitions/data/slide_transition.effect
+++ b/plugins/obs-transitions/data/slide_transition.effect
@@ -16,6 +16,8 @@ struct VertData {
 	float2 uv  : TEXCOORD0;
 };
 
+#include "premultiplied.inc"
+
 VertData VSDefault(VertData v_in)
 {
 	VertData vert_out;
@@ -28,11 +30,14 @@ float4 PSSlide(VertData v_in) : TARGET
 {
 	float2 tex_a_uv = v_in.uv + tex_a_dir;
 	float2 tex_b_uv = v_in.uv - tex_b_dir;
+	float4 outc;
 
-	return (tex_a_uv.x - saturate(tex_a_uv.x) != 0.0) ||
+	outc = (tex_a_uv.x - saturate(tex_a_uv.x) != 0.0) ||
 	       (tex_a_uv.y - saturate(tex_a_uv.y) != 0.0)
 		   ? tex_b.Sample(textureSampler, tex_b_uv)
 		   : tex_a.Sample(textureSampler, tex_a_uv);
+
+	return convert_pmalpha(outc);
 }
 
 technique Slide
diff --git a/plugins/obs-transitions/data/swipe_transition.effect b/plugins/obs-transitions/data/swipe_transition.effect
index 699db66..532399e 100644
--- a/plugins/obs-transitions/data/swipe_transition.effect
+++ b/plugins/obs-transitions/data/swipe_transition.effect
@@ -14,6 +14,8 @@ struct VertData {
 	float2 uv  : TEXCOORD0;
 };
 
+#include "premultiplied.inc"
+
 VertData VSDefault(VertData v_in)
 {
 	VertData vert_out;
@@ -25,11 +27,14 @@ VertData VSDefault(VertData v_in)
 float4 PSSwipe(VertData v_in) : TARGET
 {
 	float2 swipe_uv = v_in.uv + swipe_val;
+	float4 outc;
 
-	return (swipe_uv.x - saturate(swipe_uv.x) != 0.0) ||
+	outc = (swipe_uv.x - saturate(swipe_uv.x) != 0.0) ||
 	       (swipe_uv.y - saturate(swipe_uv.y) != 0.0)
 		   ? tex_b.Sample(textureSampler, v_in.uv)
 		   : tex_a.Sample(textureSampler, swipe_uv);
+
+	return convert_pmalpha(outc);
 }
 
 technique Swipe
diff --git a/plugins/obs-x264/data/locale/da-DK.ini b/plugins/obs-x264/data/locale/da-DK.ini
index 9e3bd79..6c22fff 100644
--- a/plugins/obs-x264/data/locale/da-DK.ini
+++ b/plugins/obs-x264/data/locale/da-DK.ini
@@ -1,6 +1,7 @@
 Bitrate="Bitrate"
 CustomBufsize="Brug brugerdefineret bufferstørrelse"
 BufferSize="Bufferstørrelsen"
+RateControl="Rate kontrol"
 CRF="CRF"
 KeyframeIntervalSec="Keyframe interval (sekunder, 0 = auto)"
 CPUPreset="CPU forbrug indstilling (højere = mindre CPU)"
diff --git a/plugins/obs-x264/data/locale/et-EE.ini b/plugins/obs-x264/data/locale/et-EE.ini
index 4976d32..84fda6f 100644
--- a/plugins/obs-x264/data/locale/et-EE.ini
+++ b/plugins/obs-x264/data/locale/et-EE.ini
@@ -1,4 +1,7 @@
 Bitrate="Bitikiirus"
 CustomBufsize="Kasuta kohandatud puhvri suurust"
 BufferSize="Puhvri suurus"
+Profile="Profiil"
+None="(Määramata)"
+EncoderOptions="x264 suvandid (eraldatud tühikutega)"
 
diff --git a/plugins/obs-x264/data/locale/hu-HU.ini b/plugins/obs-x264/data/locale/hu-HU.ini
index ccff1e3..4ca12b1 100644
--- a/plugins/obs-x264/data/locale/hu-HU.ini
+++ b/plugins/obs-x264/data/locale/hu-HU.ini
@@ -1,4 +1,4 @@
-Bitrate="Bitráta"
+Bitrate="Bitsebesség"
 CustomBufsize="Egyéni pufferméret használata"
 BufferSize="Pufferméret"
 RateControl="Sebesség Vezérlés"
diff --git a/plugins/obs-x264/data/locale/ko-KR.ini b/plugins/obs-x264/data/locale/ko-KR.ini
index 88a0b03..ee9a402 100644
--- a/plugins/obs-x264/data/locale/ko-KR.ini
+++ b/plugins/obs-x264/data/locale/ko-KR.ini
@@ -5,7 +5,7 @@ RateControl="데이터율 제어"
 CRF="CRF"
 KeyframeIntervalSec="키프레임 간격 (초 단위, 0=자동)"
 CPUPreset="CPU 사용량 사전설정 (높음 = 적은 CPU 부담)"
-Profile="프로필"
+Profile="프로파일"
 Tune="ì¡°ì •"
 None="(없음)"
 EncoderOptions="x264 설정 (공백으로 구분)"
diff --git a/plugins/obs-x264/data/locale/tr-TR.ini b/plugins/obs-x264/data/locale/tr-TR.ini
index 67a52e7..dcaeb4f 100644
--- a/plugins/obs-x264/data/locale/tr-TR.ini
+++ b/plugins/obs-x264/data/locale/tr-TR.ini
@@ -1,8 +1,9 @@
 Bitrate="Bit hızı"
 CustomBufsize="İsteğe Bağlı Arabellek Boyutu Kullan"
 BufferSize="Arabellek Boyutu"
+RateControl="Oran Kontrolü"
 CRF="CRF"
-KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)"
+KeyframeIntervalSec="Anahtar Kare Aralığı (saniye, 0=otomatik)"
 CPUPreset="CPU Kullanım Önayarı (yüksek = az CPU kullanımı)"
 Profile="Profil"
 Tune="Ayarla"
diff --git a/plugins/obs-x264/data/locale/vi-VN.ini b/plugins/obs-x264/data/locale/vi-VN.ini
new file mode 100644
index 0000000..5de7382
--- /dev/null
+++ b/plugins/obs-x264/data/locale/vi-VN.ini
@@ -0,0 +1,13 @@
+Bitrate="Bitrate"
+CustomBufsize="Sử dụng tùy chỉnh bộ đệm kích thước"
+BufferSize="Bộ nhớ đệm lớn nhất"
+RateControl="Cách kiểm soát bitrate"
+CRF="CRF"
+KeyframeIntervalSec="Keyframe Interval (giây, 0 = auto)"
+CPUPreset="CPU sử dụng (cao hơn = ít sử dụng CPU)"
+Profile="Hồ sơ"
+Tune="Điều chỉnh"
+None="(Trống)"
+EncoderOptions="x264 tùy chọn (phân cách bởi khoảng trống)"
+VFR="Framerate thay đổi được (VFR)"
+
diff --git a/plugins/obs-x264/obs-x264.c b/plugins/obs-x264/obs-x264.c
index 27bbe8a..5151c8c 100644
--- a/plugins/obs-x264/obs-x264.c
+++ b/plugins/obs-x264/obs-x264.c
@@ -288,6 +288,8 @@ static inline void override_base_params(struct obs_x264 *obsx264, char **params,
 				preset, profile, tune);
 }
 
+#define OPENCL_ALIAS "opencl_is_experimental_and_potentially_unstable"
+
 static inline void set_param(struct obs_x264 *obsx264, const char *param)
 {
 	char       *name;
@@ -300,7 +302,10 @@ static inline void set_param(struct obs_x264 *obsx264, const char *param)
 		    strcmp(name, "fps")       != 0 &&
 		    strcmp(name, "force-cfr") != 0 &&
 		    strcmp(name, "width")     != 0 &&
-		    strcmp(name, "height")    != 0) {
+		    strcmp(name, "height")    != 0 &&
+		    strcmp(name, "opencl")    != 0) {
+			if (strcmp(name, OPENCL_ALIAS) == 0)
+				strcpy(name, "opencl");
 			if (x264_param_parse(&obsx264->params, name, val) != 0)
 				warn("x264 param: %s failed", param);
 		}
diff --git a/plugins/rtmp-services/data/locale/et-EE.ini b/plugins/rtmp-services/data/locale/et-EE.ini
new file mode 100644
index 0000000..f052ff1
--- /dev/null
+++ b/plugins/rtmp-services/data/locale/et-EE.ini
@@ -0,0 +1,10 @@
+StreamingServices="Voogedastuse teenus"
+CustomStreamingServer="Kohandatud voogedastuse Server"
+Service="Teenus"
+Server="Server"
+StreamKey="Voogedastuse võti"
+UseAuth="Kasuta autentimist"
+Username="Kasutajanimi"
+Password="Salasõna"
+ShowAll="Näita kõiki teenuseid"
+
diff --git a/plugins/rtmp-services/data/package.json b/plugins/rtmp-services/data/package.json
index 99ef04c..a77c4d7 100644
--- a/plugins/rtmp-services/data/package.json
+++ b/plugins/rtmp-services/data/package.json
@@ -1,10 +1,10 @@
 {
 	"url": "https://obsproject.com/obs2_update/rtmp-services",
-	"version": 38,
+	"version": 52,
 	"files": [
 		{
 			"name": "services.json",
-			"version": 38
+			"version": 52
 		}
 	]
 }
diff --git a/plugins/rtmp-services/data/services.json b/plugins/rtmp-services/data/services.json
index 1133d56..50b6088 100644
--- a/plugins/rtmp-services/data/services.json
+++ b/plugins/rtmp-services/data/services.json
@@ -42,10 +42,18 @@
                     "url": "rtmp://live-fra.twitch.tv/app"
                 },
                 {
+                    "name": "EU: Lisbon, Portugal",
+                    "url": "rtmp://live-lis.twitch.tv/app"
+                },
+                {
                     "name": "EU: London, UK",
                     "url": "rtmp://live-lhr.twitch.tv/app"
                 },
                 {
+                    "name": "EU: Milan, Italy",
+                    "url": "rtmp://live-mil.twitch.tv/app"
+                },
+                {
                     "name": "EU: Paris, FR",
                     "url": "rtmp://live-cdg.twitch.tv/app"
                 },
@@ -62,6 +70,14 @@
                     "url": "rtmp://live-waw.twitch.tv/app"
                 },
                 {
+                    "name": "NA: Mexico City",
+                    "url": "rtmp://live-qro.twitch.tv/app"
+                },
+                {
+                    "name": "NA: Toronto, Canada",
+                    "url": "rtmp://live-yto.twitch.tv/app"
+                },
+                {
                     "name": "South America: Argentina",
                     "url": "rtmp://live-eze.twitch.tv/app"
                 },
@@ -70,6 +86,14 @@
                     "url": "rtmp://live-scl.twitch.tv/app"
                 },
                 {
+                    "name": "South America: Lima, Peru",
+                    "url": "rtmp://live-lim.twitch.tv/app"
+                },
+                {
+                    "name": "South America: Medellin, Columbia",
+                    "url": "rtmp://live-mde.twitch.tv/app"
+                },
+                {
                     "name": "South America: Rio de Janeiro, Brazil",
                     "url": "rtmp://live-gig.twitch.tv/app"
                 },
@@ -131,9 +155,8 @@
                 }
             ],
             "recommended": {
-                "keyint": 4,
-                "profile": "main",
-                "max video bitrate": 18000,
+                "keyint": 2,
+                "max video bitrate": 51000,
                 "max audio bitrate": 160
             }
         },
@@ -178,10 +201,6 @@
                     "url": "rtmp://live.dme.hitbox.tv/push"
                 },
                 {
-                    "name": "US-East: Washington",
-                    "url": "rtmp://live.vgn.hitbox.tv/push"
-                },
-                {
                     "name": "US-East: New York - 1",
                     "url": "rtmp://live.jfk.hitbox.tv/push"
                 },
@@ -274,6 +293,10 @@
                     "url": "rtmp://ingest-fra.beam.pro:1935/beam"
                 },
                 {
+                    "name": "EU: Oslo",
+                    "url": "rtmp://ingest-osl.beam.pro:1935/beam"
+                },
+                {
                     "name": "Brazil: Sao Paulo",
                     "url": "rtmp://ingest-sao.beam.pro:1935/beam"
                 },
@@ -296,12 +319,20 @@
                 {
                     "name": "Asia: Tokyo",
                     "url": "rtmp://ingest-tok.beam.pro:1935/beam"
+                },
+                {
+                    "name": "South Korea: Seoul",
+                    "url": "rtmp://ingest-seo.beam.pro:1935/beam"
+                },
+                {
+                    "name": "India: Chennai",
+                    "url": "rtmp://ingest-che.beam.pro:1935/beam"
                 }
             ],
             "recommended": {
                 "keyint": 1,
                 "max audio bitrate": 160,
-                "max video bitrate": 3500,
+                "max video bitrate": 10000,
                 "profile": "main"
             }
         },
@@ -326,10 +357,14 @@
                 {
                     "name": "EU",
                     "url": "rtmp://eumedia1.livecoding.tv/livecodingtv"
+                },
+                {
+                    "name": "Asia Pacific",
+                    "url": "rtmp://apmedia1.livecoding.tv/livecodingtv"
                 }
             ],
             "recommended": {
-                "max video bitrate": 1300
+                "max video bitrate": 2300
             }
         },
         {
@@ -342,13 +377,19 @@
             ]
         },
         {
-            "name": "mSportz",
+            "name": "Web.TV",
             "servers": [
                 {
                     "name": "Primary",
-                    "url": "rtmp://52.21.78.175/mSports"
+                    "url": "rtmp://live3.origins.web.tv/liveext"
                 }
-            ]
+            ],
+            "recommended": {
+                "keyint": 2,
+                "profile": "main",
+                "max video bitrate": 3500,
+                "max audio bitrate": 160
+            }
         },
         {
             "name": "Switchboard Live (Joicaster)",
@@ -414,84 +455,75 @@
             ]
         },
         {
-            "name": "Vaughn Live / iNSTAGIB.tv",
+            "name": "Vaughn Live / iNSTAGIB",
             "servers": [
                 {
                     "name": "US: Primary",
-                    "url": "rtmp://live.vaughnsoft.net:443/live"
+                    "url": "rtmp://live.vaughnsoft.net/live"
                 },
                 {
-                    "name": "US: San Jose, CA",
-                    "url": "rtmp://live-sjc.vaughnsoft.net:443/live"
+                    "name": "US: Chicago, IL",
+                    "url": "rtmp://live-ord.vaughnsoft.net/live"
                 },
                 {
-                    "name": "US: New York, NY",
-                    "url": "rtmp://live-nyc.vaughnsoft.net:443/live"
+                    "name": "US: Denver, CO",
+                    "url": "rtmp://live-den.vaughnsoft.net/live"
                 },
                 {
-                    "name": "US: New York 2, NY",
-                    "url": "rtmp://live-nyc2.vaughnsoft.net:443/live"
-                }
-            ]
-        },
-        {
-            "name": "Streamup",
-            "servers": [
-                {
-                    "name": "Worldwide",
-                    "url": "rtmp://origin.streamuplive.com/app"
-                }
-            ]
-        },
-        {
-            "name": "connectcast.tv",
-            "servers": [
+                    "name": "US: Los Angeles, CA",
+                    "url": "rtmp://live-lax.vaughnsoft.net/live"
+                },
                 {
-                    "name": "Default",
-                    "url": "rtmp://stream.connectcast.tv/live"
+                    "name": "EU: Amsterdam, NL",
+                    "url": "rtmp://live-ams.vaughnsoft.net/live"
                 }
-            ]
+            ],
+            "recommended": {
+                "keyint": 2,
+                "max video bitrate": 3500,
+                "max audio bitrate": 160
+            }
         },
         {
-            "name": "Kamcord",
+            "name": "Breakers.TV",
             "servers": [
                 {
-                    "name": "US East (N. Virginia)",
-                    "url": "rtmp://us-east-1.stream.kamcord.com/live"
-                },
-                {
-                    "name": "Asia Pacific (Seoul)",
-                    "url": "rtmp://ap-northeast-2.stream.kamcord.com/live"
-                },
-                {
-                    "name": "Asia Pacific (Sydney)",
-                    "url": "rtmp://ap-southeast-2.stream.kamcord.com/live"
+                    "name": "US: Primary",
+                    "url": "rtmp://live.vaughnsoft.net/live"
                 },
                 {
-                    "name": "Asia Pacific (Tokyo)",
-                    "url": "rtmp://ap-northeast-1.stream.kamcord.com/live"
+                    "name": "US: Chicago, IL",
+                    "url": "rtmp://live-ord.vaughnsoft.net/live"
                 },
                 {
-                    "name": "EU (Frankfurt)",
-                    "url": "rtmp://eu-central-1.stream.kamcord.com/live"
+                    "name": "US: Denver, CO",
+                    "url": "rtmp://live-den.vaughnsoft.net/live"
                 },
                 {
-                    "name": "South America (Sao Paulo)",
-                    "url": "rtmp://sa-east-1.stream.kamcord.com/live"
+                    "name": "US: Los Angeles, CA",
+                    "url": "rtmp://live-lax.vaughnsoft.net/live"
                 },
                 {
-                    "name": "US West (N. California)",
-                    "url": "rtmp://us-west-1.stream.kamcord.com/live"
+                    "name": "EU: Amsterdam, NL",
+                    "url": "rtmp://live-ams.vaughnsoft.net/live"
                 }
             ],
             "recommended": {
                 "keyint": 2,
-                "profile": "main",
-                "max video bitrate": 4000,
-                "max audio bitrate": 192
+                "max video bitrate": 3500,
+                "max audio bitrate": 160
             }
         },
         {
+            "name": "connectcast.tv",
+            "servers": [
+                {
+                    "name": "Default",
+                    "url": "rtmp://stream.connectcast.tv/live"
+                }
+            ]
+        },
+        {
             "name": "CyberGame.TV",
             "servers": [
                 {
@@ -553,60 +585,60 @@
             "common": true,
             "servers": [
                 {
-                    "name": "US-West (San Jose, California)",
-                    "url": "rtmp://us-west.restream.io/live"
-                },
-                {
-                    "name": "US-West (Los Angeles, California)",
-                    "url": "rtmp://us-la.restream.io/live"
+                    "name": "EU-West (London, GB)",
+                    "url": "rtmp://eu-london.restream.io/live"
                 },
                 {
-                    "name": "US-West (Seattle, Washington)",
-                    "url": "rtmp://us-seattle.restream.io/live"
+                    "name": "EU-West (Amsterdam, NL)",
+                    "url": "rtmp://eu-ams.restream.io/live"
                 },
                 {
-                    "name": "US-Central (Dallas, Texas)",
-                    "url": "rtmp://us-central.restream.io/live"
+                    "name": "EU-Central (Frankfurt, DE)",
+                    "url": "rtmp://eu-central.restream.io/live"
                 },
                 {
-                    "name": "US-East (Washington, D.C.)",
-                    "url": "rtmp://us-east.restream.io/live"
+                    "name": "EU-East (Falkenstein, DE)",
+                    "url": "rtmp://eu-east.restream.io/live"
                 },
                 {
-                    "name": "NA-East (Toronto, Canada)",
-                    "url": "rtmp://na-toronto.restream.io/live"
+                    "name": "Russia (Moscow)",
+                    "url": "rtmp://ru.restream.io/live"
                 },
                 {
-                    "name": "EU-Central (Frankfurt, Germany)",
-                    "url": "rtmp://eu-central.restream.io/live"
+                    "name": "US-West (Seattle, WA)",
+                    "url": "rtmp://us-seattle.restream.io/live"
                 },
                 {
-                    "name": "EU-Central 2 (Frankfurt, Germany)",
-                    "url": "rtmp://eu.restream.io/live"
+                    "name": "US-West (San Jose, CA)",
+                    "url": "rtmp://us-west.restream.io/live"
                 },
                 {
-                    "name": "EU-West (Amsterdam, Netherlands)",
-                    "url": "rtmp://eu-ams.restream.io/live"
+                    "name": "US-West (Los Angeles, CA)",
+                    "url": "rtmp://us-la.restream.io/live"
                 },
                 {
-                    "name": "EU-West (London, Great Britain)",
-                    "url": "rtmp://eu-london.restream.io/live"
+                    "name": "US-Central (Dallas, TX)",
+                    "url": "rtmp://us-central.restream.io/live"
                 },
                 {
-                    "name": "Australia (Sydney)",
-                    "url": "rtmp://au.restream.io/live"
+                    "name": "US-East (Washington, DC)",
+                    "url": "rtmp://us-east.restream.io/live"
                 },
                 {
-                    "name": "Australia Secondary (Sydney)",
-                    "url": "rtmp://au-secondary.restream.io/live"
+                    "name": "NA-East (Toronto, Canada)",
+                    "url": "rtmp://na-toronto.restream.io/live"
                 },
                 {
-                    "name": "South America (Sao Paulo, Brazil)",
+                    "name": "SA (Saint Paul, Brazil)",
                     "url": "rtmp://sa.restream.io/live"
                 },
                 {
                     "name": "Asia (Singapore)",
                     "url": "rtmp://singapore.restream.io/live"
+                },
+                {
+                    "name": "Australia (Sydney)",
+                    "url": "rtmp://au.restream.io/live"
                 }
             ],
             "recommended": {
@@ -662,15 +694,6 @@
             ]
         },
         {
-            "name": "Interactive LifeStream",
-            "servers": [
-                {
-                    "name": "Default",
-                    "url": "rtmp://lifestreamcdn.com/live/_definst_/doPublish=wls36"
-                }
-            ]
-        },
-        {
             "name": "Stre.am",
             "servers": [
                 {
@@ -803,6 +826,30 @@
                 "max video bitrate": 3000,
                 "max audio bitrate": 128
             }
+        },
+        {
+            "name": "Picarto",
+            "servers": [
+                {
+                    "name": "USA/Canada",
+                    "url": "rtmp://live.us.picarto.tv/golive"
+                }
+            ],
+            "recommended": {
+                "keyint": 2,
+                "profile": "main",
+                "max video bitrate": 2000,
+                "max audio bitrate": 160
+            }
+        },
+        {
+            "name": "Pandora TV Korea",
+            "servers": [
+                {
+                    "name": "Default",
+                    "url": "rtmp://plive.pandora.tv:80/mediaHub"
+                }
+            ]
         }
     ]
 }
diff --git a/plugins/text-freetype2/data/locale/et-EE.ini b/plugins/text-freetype2/data/locale/et-EE.ini
new file mode 100644
index 0000000..79b55fa
--- /dev/null
+++ b/plugins/text-freetype2/data/locale/et-EE.ini
@@ -0,0 +1,14 @@
+TextFreetype2="Tekst (FreeType 2)"
+Font="Font"
+Text="Tekst"
+TextFile="Tekstifail (UTF-8 või UTF-16)"
+TextFileFilter="Tekstifailid (*.txt);;"
+ChatLogMode="Vestlus logi režiim (Viimased 6 rida)"
+Color1="Värv 1"
+Color2="Värv 2"
+Outline="Kontuur"
+DropShadow="Langev vari"
+ReadFromFile="Loe failist"
+CustomWidth="Kohandatud teksti laius"
+WordWrap="Eraldi reale"
+
diff --git a/plugins/text-freetype2/data/locale/ms-MY.ini b/plugins/text-freetype2/data/locale/ms-MY.ini
new file mode 100644
index 0000000..95ab97f
--- /dev/null
+++ b/plugins/text-freetype2/data/locale/ms-MY.ini
@@ -0,0 +1,9 @@
+TextFreetype2="Teks (FreeType 2)"
+Font="Jenis Tulisan"
+Text="Teks"
+TextFile="Fail teks (UTF-8 atau UTF-16)"
+TextFileFilter="Fail teks (*.txt);;"
+ChatLogMode="Mod log chat (6 baris terakhir)"
+Color1="Warna 1"
+Color2="Warna 2"
+
diff --git a/plugins/text-freetype2/text-freetype2.c b/plugins/text-freetype2/text-freetype2.c
index 0257959..849d230 100644
--- a/plugins/text-freetype2/text-freetype2.c
+++ b/plugins/text-freetype2/text-freetype2.c
@@ -50,24 +50,34 @@ static struct obs_source_info freetype2_source_info = {
 	.get_properties = ft2_source_properties,
 };
 
-bool obs_module_load()
+static bool plugin_initialized = false;
+
+static void init_plugin(void)
 {
-	char *config_dir = obs_module_config_path(NULL);
-	if (config_dir) {
-		os_mkdirs(config_dir);
-		bfree(config_dir);
-	}
+	if (plugin_initialized)
+		return;
 
 	FT_Init_FreeType(&ft2_lib);
 
 	if (ft2_lib == NULL) {
 		blog(LOG_WARNING, "FT2-text: Failed to initialize FT2.");
-		return false;
+		return;
 	}
 
 	if (!load_cached_os_font_list())
 		load_os_font_list();
 
+	plugin_initialized = true;
+}
+
+bool obs_module_load()
+{
+	char *config_dir = obs_module_config_path(NULL);
+	if (config_dir) {
+		os_mkdirs(config_dir);
+		bfree(config_dir);
+	}
+
 	obs_register_source(&freetype2_source_info);
 
 	return true;
@@ -75,8 +85,10 @@ bool obs_module_load()
 
 void obs_module_unload(void)
 {
-	free_os_font_list();
-	FT_Done_FreeType(ft2_lib);
+	if (plugin_initialized) {
+		free_os_font_list();
+		FT_Done_FreeType(ft2_lib);
+	}
 }
 
 static const char *ft2_source_get_name(void *unused)
@@ -442,6 +454,8 @@ static void *ft2_source_create(obs_data_t *settings, obs_source_t *source)
 	obs_data_t *font_obj = obs_data_create();
 	srcdata->src = source;
 
+	init_plugin();
+
 	srcdata->font_size = 32;
 
 	obs_data_set_default_string(font_obj, "face", DEFAULT_FACE);
diff --git a/plugins/vlc-video/data/locale/da-DK.ini b/plugins/vlc-video/data/locale/da-DK.ini
new file mode 100644
index 0000000..89ebb8e
--- /dev/null
+++ b/plugins/vlc-video/data/locale/da-DK.ini
@@ -0,0 +1,8 @@
+VLCSource="VLC videokilde"
+Playlist="Afspilningsliste"
+LoopPlaylist="Loop afspilningsliste"
+PlaybackBehavior="Synligheds opførsel"
+PlaybackBehavior.StopRestart="Stop når ikke synlig, genstart når synlig"
+PlaybackBehavior.PauseUnpause="Paus når ikke synlig, genoptag når synlig"
+PlaybackBehavior.AlwaysPlay="Afspil altid også når usynlig"
+
diff --git a/plugins/vlc-video/data/locale/et-EE.ini b/plugins/vlc-video/data/locale/et-EE.ini
new file mode 100644
index 0000000..6b419b8
--- /dev/null
+++ b/plugins/vlc-video/data/locale/et-EE.ini
@@ -0,0 +1,8 @@
+VLCSource="VLC Video allikas"
+Playlist="Esitusloend"
+LoopPlaylist="Korda esitusloendit"
+PlaybackBehavior="Käitumine"
+PlaybackBehavior.StopRestart="Lõpeta kui nähtamatu, alusta uuesti kui nähtav"
+PlaybackBehavior.PauseUnpause="Peata kui nähtamatu, jätka kui nähtav"
+PlaybackBehavior.AlwaysPlay="Mängi alati, isegi siis kui pole nähtav"
+
diff --git a/plugins/vlc-video/data/locale/sk-SK.ini b/plugins/vlc-video/data/locale/sk-SK.ini
new file mode 100644
index 0000000..163e36b
--- /dev/null
+++ b/plugins/vlc-video/data/locale/sk-SK.ini
@@ -0,0 +1,2 @@
+Playlist="Playlist"
+
diff --git a/plugins/vlc-video/data/locale/tr-TR.ini b/plugins/vlc-video/data/locale/tr-TR.ini
new file mode 100644
index 0000000..b4c35b7
--- /dev/null
+++ b/plugins/vlc-video/data/locale/tr-TR.ini
@@ -0,0 +1,8 @@
+VLCSource="VLC Video Kaynağı"
+Playlist="Oynatma Listesi"
+LoopPlaylist="Oynatma Listesini Yinele"
+PlaybackBehavior="Görünürlük davranışı"
+PlaybackBehavior.StopRestart="Görünür değilken durdur, görünür olunca yeniden başlat"
+PlaybackBehavior.PauseUnpause="Görünür değilken duraklat, görünür olunca oynat"
+PlaybackBehavior.AlwaysPlay="Görünür değilken bile oynat"
+

-- 
obs-studio packaging



More information about the pkg-multimedia-commits mailing list