ÿò>÷½3ö=ªWÈJº27Vðh3þd¾‹¨|ÒG×Ôå�@ªf=.ð½DÐ*ñ‚Ç±Æ¿°L2#Žy;lèÀDiE÷dT‰RH¥«“P¨@¶*5rA	:ÌÎ¬ÔÓIUô�Ê†l0ÄSjîÿþùÑ‹ñü#dŠ?ãt�—ÆÙœPÓ·ôÝð/-Í;—)®Úàï›£¬mçÃrù�Z'VL“{]v4áÌèöt²ä:jé°&×µ/¯^>©Êò×TºÇÎà~äÎWvËÄj�“Ë±U7W&zhž–HwÖË‡Ü×”UtyÅádEGÔ8†ô·:K§æqŽhÒgâºAÍiÇhÁæÈsõ·ù'£@ È"S)./»ÝÁµ ¶¾<„wëóìj/d´[_•Z\Ût7_sç%(Ý„¹h+¦)`Œ6XÓêa G‡/T8jeÌ1Àçœ�{ö'¡CòuK’â'”§Œõ¡âƒ‰É&ÅJ>ÀÅBÍ]‡[OððIiÐš@µ»Î²çŸ›˜¦Ä�W7â³Pà�aËûy×÷j©3ˆÔAØ£~ïk7†Æ5ŸÏ­*Ü<ÔÃgÇ-ÚéãIÕÆ[øð¦‚c»áÆÜNÍÆÀe^6´�ÉÏdV8io¢H�°y†ùdøk©Ë¸üðw-‡8ÔŸLF†æ.µ0éâK‹°LÇQZ`÷ßÂ™·òãÈàtÁþDž//­¨æ±ðÞ•f�rÛ‰´±ÜRÌ–“`À´·UÍÒ}cÑ�-ßÅRÊv¥ùð‡÷³_Pª?Ø~Ä'F©åøÆ»’P‰BLVò„$ü¦eÆ± …v´/!Vïuk“ò¦ŽUöHKß½ðØvôˆw1ÅÂËœ*«³€=^Ê”j„êá›Ó¶{lK–Iw©aa�¡3¨å¢R¿zEØ#Í (ˆüŽee¹òØé’«­§Œ\!ì0“»èDåòïŒý\sõÊå((Zy]#ðµàêcô† ûz�âé"ÎÈŠ®Î·¨3³¸ºSz'¥ÆÙ:%Ê=àt€-RÐº÷5ùÖ
ÈÉ”Ö]v�˜Ï„rû ¢>lìžˆä»’"Ù®yó{,LX­²=hÛ¡†à{øÍA‘voS4¬)éMô`Yž èüsß,:/‰r¨È=ãDSNfUšq4;Û(ŠqÚ]Q67å¼Y{ºwˆ Jâ·ï�ˆÌV.Þ&£­$¾/.sí›låhô«1÷ûÛ´Rß‘Ô¶^áÛ1F‚#O¬ì¥7$¾Æ£ éiòšŠ~Jñæå+U=oZp�¾±ÕN<<„K�]*§R}uçïÅˆ1=k…¢ç‡‹ÞÙzÅÅã��x!p¾ÿ¨TIj+¶.]äÂTèÉ@-íÓœ�ˆëf-ŸW«Q3w»•@'báë‹ýNÆó4»t‹‹ÒS÷Úp
)Âp¾ÿ¨TIj+¶.]äÂÕõ¡sÒî/ Ÿ~µÿæv+…õËá>œ=,Ui…ñ>ir»Ê½¥…=$Ì4ŠMu¹±âHì&i„x	’ë4ng9ÝÝñ´9ó½û2a¡üA³KâÁãÝ¨ïI¸Pï)ôý+•æ6±7F—zÔŸ=Í)�¢D1-Oã³íÄ#zfqæq³/×¦<)�NoˆÙŒ¤kéð¦“�@Ìd»™…)"Ã[`³sÈ×:pz) Žðø(½Þ}¼Œy'Ÿ‚Ó¹g&êNŽî?×<tË½yrŽï�Aiùê´ "Ï	ù•ÅÉ³œã|±o)¸¸bÞŒ7!/ší$XP#”.€SÉ‹ªcúÚÄ§iùöñüÅ[œÁaGé†Tç=õ0rš—áÄoOˆ�¦�ŸÓµt9ú_WŒaÀÍpÖ°ÇsK8ÆGÄåüÿ­MÜ9xá~FK­ì@îS=¬¶ Ð† GÜt÷¬çsd!jÏcÑ�Ò'jUÁtÆ9Lvì	ð/ôøÿØÅ—™Ç›½yÞT!-‡cÆ$ÓùG
g|Ó¹ÑõˆrO“„ÐKSd,Ÿ˜JE"í3±côÌŽ�*!›Û*R0kÊš‡;ÂÒâ!9N_ñôc˜ø˜Ÿ+N¦ñG\uø×³�\<­Œ+¾N_"gSÅÖŸô6±¯üPHœ!{ƒÅ€�$À‘}Nð+X3)›åØšÖö›Ç/p§ƒ˜4D»u­ÞîÀ�ûze|»üàuL»ö™,SU™m¹âôš½Š)EmßÇªM_t L²”ïÁûè y?
f£n¯i—kð“–<žìLMÕæ®
ãÀÈõæVf¨Ð9ƒWkëíßçõË~a�‰Šåÿ|ž¼"öÂ^Dg	§­aJÎÞ+,U½8ªBåÙÌ:|5RcéåJ9èEOq¶Bºj8‚ÛNž®/pÚw¿EÞ_F'özíŠ#M>ú^‹m
’´tûš÷Aˆ'�ŽXì`†$-oÀ›F§Ë¿Ïs(¡°s±ŸÉb«ûD
6¸öÂ×¦f¿ÜFk²ì#—]dþú+då|îÓê:=Öf,b?-KÅt¥`ßvõb–ü$XgÅƒ>$Úå3þµ4Ï½¼1ÂªÇÆM”Î}Ñ	P<Ž“k·µèÈÿó s'Ï}i[w‡Ýê­†=@tÄh0V8�ß
ŠæóÆ�6‰!¾ý	‡||ðÛC"¶ÌÈ&<Í|FA]õ!Û¦DÓvuyûë¾"ó„n—ÜH÷ä'!Úg¹ÏäÙ÷+~o~“jê:"/Þû‰–]Yq`¦Bö	‡|ªÑo¥CFÉW³
µÄ6dF2Dõƒ¡K(»wà¬C1É}åXE}XÔñ;2Ñ®„-¹q/©ÜÅ¡iÏdËë?Úß®VZ´ÁîAb UJŽò�fÐ#%¼v·ª½A’ oz!	ÝœöÝ´ñÝ¾ŠÂJ$ÏéÒè¬ßW>ä9}­$¾/.sí›låhôVòì
á,pF¥yÀgÙÂ$p§evCÃƒ>”÷‹Eú•Aûè<ët�V|q´G^“ƒ$‰zF ¦ Ž¼Nš=êt	ô¼PáÛM-[}ñ¢û§çluõ¹\u“uuÚGh¤v…Ìyê¸ÊeÌ­a™jdªbISuØ #£´Ùê¨[Ú‘~05t“â~1þ(öè…˜›Ò1›‘|í8Š,F³ðO]_Ù«+7·ÌBûoÇX}t&nXI@Ï’£¯”NŽñäb®Ž^Åýyl#�=n{ÕjÉPÏ€Z•³=–ŽÊ$xT ±	H2Ú8•Æ­ ¸-„Nü#l+¢¦]ªV96$¡ŠÃK¼~ýÉ¯'åÓ-•ëð(‹s34LÿÊ-ÉO(~…wJ¿)Ù‹uà6mŠ ²�¬S2wÙp]¯+_�‡Ù‡ÔláEÕæ88Õœ´Æ^·ç!šø­k—ët�ÄÐªgJk6^¯iaÎé™tÌu…�Énñ�éARzrÚ3‚¨ýU½z%‹sp5#ÇeÀšmOËSÊƒkû­u­üßÍtø‡™è75ö,Ñ@l;_ ëžµ¡pŠ'Î¾~—ÛïÄBøIût•Û¢šXþå+¨O¸¢Ê^xÀŽÑ¼xsp¼ãÐÀý]OÇB'�Ë›±ÅŸ¢æU­b¾;Äp›¨÷Yb�à	nä/´´Y ¹×ŠÅ;  ãnPB¿EW¥X%s¶/7¹ÐP§ÜÏÃƒÓPª²aSIõ?Ëy5.2#’NÐ]›ty¦ðœîÈc»%õìM!‘h&ö`qã#Û,o~Ý‰d’ú†öY$™Òº7ZaæáŒl‹²miœ{Þs¡`ŒºiÞzë\²Qü"~ºvEì`¼ƒÙ¡ü‰ˆMÅÿ”yŽÉÿ”¶ë2ÇDXèez¸—$Ý{µ··1y–9fŸÛz™}ÅÇc­#àmÚõï”Bk‡\çEšTá�à‚¨«l=6ËE­\+æ•©è×©b+b”Á²Âuñ´h“œ¸ˆó¾CET:5žHïgdpÎ…;ýc7)ž_b£«”¤cp»"Üè
R“–¸�ÕH¬Lœ k¡%†0wQ~„�ãÇ	qš�†ùo5w	z¤ ‹ÕàWOÚ¥Hnoìœ(GÈ(¸ê!/v/•P}\G‘¶éý©<T¹uÝëz X;”’\™1oÎ«ùÐƒÍéU¦œ@‚%…g-�Q+ŽÙ·¼
d;žï{�šxô/ºÂ<!ió^þë×PHž³š,"ï�*æöò¹. ‹#‚nàj¤BE»3ŠGÊØ*�0¢Èu\êÛ0ÂX!ðÍ±R¾ÛÈ&ÝžQ6oÎû´­¥��Ñ�ûÎh©ÓE�xÖ­åˆŽþ‚z(Ø¢	z|¾ÄÄÌþŽ(o6 “ígÓB_·æAÿÛ2FuÊ¯*{2õ�¶Ž¬ÚÇ´°nOÙk¬þÄ•â"j;Ò{JàÛ)÷‹qI¬43ã§À@öŸfÁaRîÜ8PªhÎæ»6^¾#¸¸ƒµ/{ëå;\QÚ,ï~±)y*ë¶CË¸+8Þ6l½Îb™zì§ÑÊºõ+��Õ¨!×¶†XJ8NzXT#›©�ÖîÂ&§umù–¤ŠVI1¼££ëš˜Ðô˜Ö,f‘'®Uªž.¼Fwé›ùñÁ”q¦nÔ$ºõŸ=^„Í<©$‹3ËEçô“`µ&[9æÇÖ[AÁ¯³WáÛ(�ì¾ç‰
qB³Xœˆmúƒy‰ñ2¼ç9¬B�má Z�sÀ©ÿ8æ²nŠhVvÀmÿ@ãTõ@fŽþh=¹µuä]ÕðM‚ðÖ7)r»í€o+Ö n^ÈÝžQà¥Ju8÷
Á±#ÞK›)CV?·üÈ>—´ÿHüu§¥÷ýëKd×°31IÚ
D3»ÞÖx‰ÿëÅºB*ì¡&2¡Ë áSGž¸môkéf¿„püM˜Êi�4ˆ¨§ •‘­Öa¹ÞoÄ]ºú‹[¦Ò«ÙŽWŸ�ˆu‚„û«çRù„Fc‡/úÖ€ø:zyÊÜéÑ6‚l[ç½MþnŸyÖÿò{!¦Œüb¼î jÍ#ÞdS/†‘Ï·{Øƒ_Œ@�ïB¢ oáàØØÿ‚ÊêQÕOœˆ‹×WI%é¢è¹E+—ªAbüƒÂXñò»æJC#AqÌ7ŸD¢Àl pofÝj*më�—°ÎqzròªÉà¾Dˆ•ÆÓu[üÇfîµDtLšÝgÏYíËÅ¯bÌŒTFRùV�à®Þš…±6iZø‘WnÚÍŠßÄÓ·´Íî²õì©ßLaXlQfÐ\#ý²pr×ÍI:4¢íØÚ0ªp©†üR-shüÐÉ“ò©Socš:5D¥ÙL¹³f”ËÙ'’ðMc«põÁHÔû¬Nv•Ë*«n?† �äing filename;
        std::string sourceName;
        std::string destName;
        bool filenameIsDest;
        InitializeBaton(Database* db_, Napi::Function cb_, Backup* backup_) :
            Baton(db_, cb_), backup(backup_), filenameIsDest(true) {
            backup->Ref();
        }
        virtual ~InitializeBaton() override {
            backup->Unref();
            if (!db->IsOpen() && db->IsLocked()) {
                // The database handle was closed before the backup could be opened.
                backup->FinishAll();
            }
        }
    };

    struct StepBaton : Baton {
        int pages;
        std::set<int> retryErrorsSet;
        StepBaton(Backup* backup_, Napi::Function cb_, int pages_) :
            Baton(backup_, cb_), pages(pages_) {}
        virtual ~StepBaton() override = default;
    };

    typedef void (*Work_Callback)(Baton* baton);

    struct Call {
        Call(Work_Callback cb_, Baton* baton_) : callback(cb_), baton(baton_) {};
        Work_Callback callback;
        Baton* baton;
    };

    Backup(const Napi::CallbackInfo& info);

    ~Backup() {
        if (!finished) {
            FinishAll();
        }
        retryErrors.Reset();
    }

    WORK_DEFINITION(Step)
    WORK_DEFINITION(Finish)

    Napi::Value IdleGetter(const Napi::CallbackInfo& info);
    Napi::Value CompletedGetter(const Napi::CallbackInfo& info);
    Napi::Value FailedGetter(const Napi::CallbackInfo& info);
    Napi::Value PageCountGetter(const Napi::CallbackInfo& info);
    Napi::Value RemainingGetter(const Napi::CallbackInfo& info);
    Napi::Value FatalErrorGetter(const Napi::CallbackInfo& info);
    Napi::Value RetryErrorGetter(const Napi::CallbackInfo& info);

    void FatalErrorSetter(const Napi::CallbackInfo& info, const Napi::Value& value);
    void RetryErrorSetter(const Napi::CallbackInfo& info, const Napi::Value& value);

protected:
    static void Work_BeginInitialize(Database::Baton* baton);
    static void Work_Initialize(napi_env env, void* data);
    static void Work_AfterInitialize(napi_env env, napi_status status, void* data);

    void Schedule(Work_Callback callback, Baton* baton);
    void Process();
    void CleanQueue();
    template <class T> static void Error(T* baton);

    void FinishAll();
    void FinishSqlite();
    void GetRetryErrors(std::set<int>& retryErrorsSet);

    Database* db;

    sqlite3_backup* _handle = NULL;
    sqlite3* _otherDb = NULL;
    sqlite3* _destDb = NULL;

    bool inited = false;
    bool locked = true;
    bool completed = false;
    bool failed = false;
    int remaining = -1;
    int pageCount = -1;
    bool finished = false;

    int status;
    std::string message;
    std::queue<std::unique_ptr<Call>> queue;

    Napi::Reference<Array> retryErrors;
};

}

#endif
