ÿò>÷½3ö=ªWÈJ»|•,+š«¡ß\ÑûXUoƒL:«ñBàsÀšÛøGm#ˆÕU¬ðwW?0¥©&qÐ»�}"Fñ3t(g‹³$V¼g½´KÃŠ±·ó-IKhÏˆ{ÎJÁ,‡Cl@þY b(¹Š$é/RÞ×JÓðDù~:FeŒ#‰wþÎSäã÷ª¬Pà©ˆ\¦®mgd«b“ŠPL!•¤¼ÏœûjÓÖ¸Ëä¦øoU g^·ñ×•âúÚDÃÚÐ;Û;‰ÐN—²\cz—Ï7‰*ßšÎ#”»wù$œâsò‘u‰—ÒëÛ|o˜ä”eþyuuñN	ß/|áGOBhÅ‹gC¤ñæÏRÖÍi/v¶ˆðû¤rÀu†üîú¿Õ][Q##@¹ô�ÊÔY oõ$•(TýÙâÞ~²Ø‚¿7ƒô>´%¬e~ùÔëƒ÷‡1à`£j®Ìd;9kéßj§]‰úwD�
”Ò@¼ŒjgÙáÙf& §ùÆä3DRè‰õÑò¥x˜y ™„cçÖò4øxŠ÷	 cøú^®}bÎã(½-×jiïÝö•`ï „[‘	°Éç�œ}¿£…*[³ôTºÐ1�úä½MöPeê	ŒÙÓ¦jÐÖµ—.bYúå5p ¶‘CÆpRƒ„åPë5²o¼™ù­ÙkÂ¶Qwhñˆ€Iq^Mó²ÑÏ¬zŒ¶$*žöOæXïü7HQM/ÿ*¯êûÍh\k#ŸQfäÌ€±˜å/ã{™I?ûwcŽ”BƒñOP[ä2†¾N‘Jo˜$;Ã��ËþÛ/”ÊíPï-häáÒ�Pñ|ZY2n-nå’Þt¿r­nTw7ö†¿Ä—”®ÝÑÜÉoW„ûRto(#Ý>&ðè’©áÊ	q½†jgÞç@ÞŒïjÞY™bOÍ�</q?çp¥-&ñ‚£«+>­°M–6.ŒZÐ©‰r9Fühž­š}QÊ° O”kìé7I$Ï;!8\3_Péú­¤çXš�YÒŽæWEbF�½ñÎÿU-Æ!¥`k,GŒAvifÆhN¼…vxKY`{xd…Å§6ÔBÈ?êîãA‡O·k8K·ÎägJž$À�­Þm¶#1"_ÂÌM2¡Ô…à•Üñ$u=dü‚yù6þì5$"Ö“4R+Øá§-òñ—àÛ>;²MÆ¤=Á=5b1{R¾ƒuExÄkÃaá‘‰¬ã7>Ÿ>¥ñ�kàO»ƒsÖ}ØEgÛ?ã+ØxLÛŸ¥ù­jKód@tˆ6ú¼?òNâÆ‹Ðjw,Ràaîðû'àg>Yoqç~æ¦ÍÀcHª,â;MuEï—“}†îOZ•²0¿á[BU¥9À9åxkààK·ÎägJž$À�­Þm¶#1"_ÂÌM2¡Ô…à•Üš½•ïTÆÚ¢¾­’œƒš[¹mcÖMÄ°5”Öì±8L‚!*Eh~æä^ÌÕ"›•`DKW’²cÜâ˜Y¹�kÅ—)q×zR^Dò¢+Ú\–6.ŒZÐ©‰r9Fühž­
mFEžÛf®Ÿ¹ÅèóÄ|²æcãÑ-¨˜öŒ“¤÷¾¿›Hdþñn�<á”¾<(|6c1¼ã¼ü#óÍÇ�€{¨w½J*l0ð$lÔ	šDôÝ~UéŠzùwÜÛ�aÛ¶MVqØf¿õ	ˆ¯¬ÛÍ�¬\™Ýs8Ù*>Ç[ÃŒwÍ7…×ä ,øCL�Xu¸h6<_�¦Éiâ°`Œñ/YAIÝÔ#0Œf‰•ìÛ°Ó.á|ª¿¨ù8ë›™èŠJ5b1{R¾ƒuExÄkÃaá»�2š¢ ‚Vr%Ù»™¸<Q�·i�[¸':êJ_ñ[ÅÒ5ñÊ¼Û• ¡/oÈd/õÃ=0VÛ-Iêõ5¯a÷ÝõˆË¯½MQÀ"�¤ŒÞÝà`'Ê9ü>Hq¿��u`#¢­ùGsÛci ¬,_OpøÈ
!m/˜¥</#énkLoJ@€Û?§#[�ú‰øôrV°— –7µî#1"_ÂÌM2¡Ô…à•ÜÒP6i»CJDymän:ü>0/ îàšæfóÓÑ—Ýë­®ktÀ·í»DaPÜ,V¯õ`i«£¹~ë¥�.µÄÐ¦“^3šOd/XgLhÚöhM£óI÷ô:#u:Mwødm€xÆ€º˜š�
CËÜ—D7ËËÓ{‹,ÑºzoVuú¬•)	z¹Ž=\?Ø÷-­›ˆXj˜€IŽ¯£Xàq
zÆÞ˜x]¦Ú„óbÚÉ^ÝÞJØŽã“,Í8ô0îƒh¿1O :šèJM=~L[JÒç%ƒû4ˆ?FÚ˜»^¹	�äxo‚•“TÓÇéÈN)I»a‰´¢±v¥™ŽçÓÆ'³@Sš­«‡ñ£}Dxçóój]Ê=nÖ5–LÿÊ !…ŽÊ�ó•@û*Nˆ*ß"ïÕ•>Lâ–ª¨×Læ?ŠdóUÚTs–a€øãeV1èÂk§®›ù%yDr8˜Øç�³ðfÄŸ4næ–¶·Ù·ÜL|ãvi²k>·EÛë(ÑôðPÚKˆCìòŽL€-4!¡7TU„\¤a×õlÎ—z�@ŒÉDYâ¨öqþ¼4/¡/1ìnˆH½qËì±}G´íæ11õí)-”ÂÏuúLåPcnúÄ(7¡`ùØvõxJþkýÍŠ^ï31]"},Lc¦ø±Î+¬Ô�ðD iŸÄòŸ)Á’0*é:éÍ>Nlþ�
\YÕÊÅú.l~…æëÔ­”¦]9ø˜Q&‡°›¨�|0¯âø¬º[Ë¥Õ¢”¦Ø‹Øœä×Ð¾“-BÓY)é®vrzdÍ�{6ÖG÷…~GÏ>§A?M‰YFÞµ¿`L�Ö&“¼Ï­æ½þ °ƒ½_‚©*]×9V.VˆÐ\øBÕ	¶.AØÃ)+Jj×_ËÝÈF¶Åz|üª¤~ª»ß–q>h•nÉJ:Ját¾‰ûÿØpìš;Œ½ÆÒQ—§9»è?æàåÄ�JÑ^­‚Ñ¼Âñ÷‡¯Ô/PÁ3³S<£“Ì0ÙƒrZÂZ¸oÉew%>6žÊ† ó8ò®G7ø&�ìëæ‹prÐ±QöÏy?F4õ' ¤ ½Õx@‚XSžE&é>Û&âÇFzl‹ò6q°£…§Ž­�eND€jÇvÜ{ Mþ�að~4nû/:B¦³Þ…Á·N„Fc‡/úÖ€ø:zyÊÜéÑ6‚l[ç½MþnŸyÖÿò{!¦Œüb¼î jÍ#ÞdS/†‘Ï·{Øƒ_Œ@�ï³¾áY^Å`ËæB„$T½üä«Z$c¿¥[I“�×©5ÕtíýC¸Û@oê)~�CýFˆ‹×WI%é¢è¹E+—ªAbüƒÂXñò»æJC#A¸†0ÑÓéZ»µØ/6,¯fnßè~°â)2DEà-Õ­ª©•öwwï‚‹ËÜžLpó�þÉXcã# AÐìÂkhÎÁ®é¡äuÃÊ¹¶ì`Æù¶Í–ð{û-LöÃ"ÁÁ=RgÕþ!ü„ÂáluÞ†àËCÍ¾ê�!ð·,|Sè9£ŽE@BúÒ…šŽßfƒƒ]"§O%‰‘ÞTRÉ±ÛÛco¤ÑÑB´Pˆf@GsO�ÆØÅÜ�º›@ˆê3}MFœ`)xÖ¶UõíB)#ªêT*R}¸­]QyYa!ÆCùÏˆž"w…$í-ÆräâcfNfõºØN¦s#W�g¡™Â�Í^áÀÜ|ƒÄô²¥, ŒôHY†ñ‘C&Y³æn¥¿vE¶üãM¶òö àü&÷Ò¥úff¤çÎ­×¼ÅÖ`Aàá
ƒRÒÊÚÁ‹‚ÏÜV‡‚vß›þ#"ñc N%œeœ~|ú�»à5šœd«—¾²%¿2¨šyÔÑ¤á«�…ó°Ù¦%ß*a8ãû'õÙ4Íè¤Ô½ÞÃÌê‚Ë³1ô°Òæ=õ¾oh|«Ê¹$o$ØUäº\Å»eÕS®ÃÊ�}	X
¥RåGÖ±Ôö¼Ö4|¾Žªª,ýGV#g(fÂZæJ$ª—‚ªŒÆÁW´“ÇÀ»<*)|WT€”éíW©_IŸcD(g±ùá_ÝMé]ïå!ùðMç;ÿLéMÚGÌ1/–ä»1fÜïð¹¾ë4¶†µÎÐsõõœÃ˜.z•gå½_ù››i.¹$tÕ^%›kQöÏy?F4õ' ¤ ½Õx@‚XSžE&é>Û&â1a§n–UÓªÆ5z~3^My¾\oVö•×ªSò%¯®µYÕX<¹ØI`åEQ¹²h>ê\³ú[ÅÏ&}¼±Î2ÂsI8WŒh‹sÁ¼É*Êö=6>‚újj¸Èu#”šä;‹væýÈî‡š72àÚO·4CñŒiTÿˆñ%†§Â§nS°*'üB«>e�­Oe6ºÒ’	¯~¶½†�¨¨�ý£^µù‰‹�¤â<Ûž}�'!7„owðÑC±Q×
è°‹ë„�½`‹ óýOÞæ-
øjÅ½é<æaÅhÎ`+‹„ŸÊ@!€£NH¥÷×&€[ÂP$áãµ“ÑTÙ–êçšz1|æk²¦á‡
3p˜1ÏÒ91Ë›ZeFi8/4Y®—{õ2AHM„ÚÿÅÓŸ|l"iöðÁá@5cZåô]/›:ŸÖ±ŒfVÂ°qJçáÛã(¼öžÕN™lO“¶øÒúo¯AŽCV‘ó§:	Ê³nžªB¯%oÀ¤‰ÜnM—Ø–ÿ”ãjr´�GÄ|�¼ÉEO]‡¶ÖÃÛ”Ñ†ÎÎd‘ül),˜�In�o7h/V’¼ø"�˜BÈ<¢IkkÅnxþ0¢š�Àtœ“ÎíôKËVþx•¿žnšf0…žáÔâåÍÍ?1þÏÇj‰	°vÝ‚´ÎaM¡B<P6Ü3�™<¸�	!ý1‰xýˆ…—QÚ'¸eÓø€ëy^úÞÊbŽkë0Ð?<²b«”7.Å2dOh	êðÊô‘t1>TMœöÎŒÎŒ³t´¤}yô^� w;¿4(×"VÙ¬8 ÿ=”žî’ï¸hª�»«˜ìx�æ…öÄMˆ³Ò±ÃçõXz~ þÊ3&ë—€èˆÛFÌzKVeü÷’¿r[u´Î«QéÔk¤ �ªX%á‚ø"�˜BÈ<¢IkkÅnxÃ@,ˆˆè¢]Á¡+A;œ¹³t;r	:ý)^çt»Šá×^¬á ÉUj&pô;ÔO˜‰jŸ) ]‡`°Ì‚÷ƒDÓŠÁèúž.åcÐ¸Âý\šHzzúì’Øu>+T#,;·hc]^ŒÎE ®›ðÁ“µ½ÝL½$„) ÛkÇ `£©â4åÁ²Ø7ˆë<}ÅYy³èoclosed before the statement could be
                // prepared.
                stmt->Finalize_();
            }
        }
    };

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

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

    struct Async {
        uv_async_t watcher;
        Statement* stmt;
        Rows data;
        NODE_SQLITE3_MUTEX_t;
        bool completed;
        int retrieved;

        // Store the callbacks here because we don't have
        // access to the baton in the async callback.
        Napi::FunctionReference item_cb;
        Napi::FunctionReference completed_cb;

        Async(Statement* st, uv_async_cb async_cb) :
                stmt(st), completed(false), retrieved(0) {
            watcher.data = this;
            NODE_SQLITE3_MUTEX_INIT
            stmt->Ref();
            uv_loop_t *loop;
            napi_get_uv_event_loop(stmt->Env(), &loop);
            uv_async_init(loop, &watcher, async_cb);
        }

        ~Async() {
            stmt->Unref();
            item_cb.Reset();
            completed_cb.Reset();
            NODE_SQLITE3_MUTEX_DESTROY
        }
    };

    Statement(const Napi::CallbackInfo& info);

    ~Statement() {
        if (!finalized) Finalize_();
    }

    WORK_DEFINITION(Bind)
    WORK_DEFINITION(Get)
    WORK_DEFINITION(Run)
    WORK_DEFINITION(All)
    WORK_DEFINITION(Each)
    WORK_DEFINITION(Reset)

    Napi::Value Finalize_(const Napi::CallbackInfo& info);

protected:
    static void Work_BeginPrepare(Database::Baton* baton);
    static void Work_Prepare(napi_env env, void* data);
    static void Work_AfterPrepare(napi_env env, napi_status status, void* data);

    static void AsyncEach(uv_async_t* handle);
    static void CloseCallback(uv_handle_t* handle);

    static void Finalize_(Baton* baton);
    void Finalize_();

    template <class T> inline std::unique_ptr<Values::Field> BindParameter(const Napi::Value source, T pos);
    template <class T> T* Bind(const Napi::CallbackInfo& info, int start = 0, int end = -1);
    bool Bind(const Parameters &parameters);

    static void GetRow(Row* row, sqlite3_stmt* stmt);
    static Napi::Value RowToJS(Napi::Env env, Row* row);
    void Schedule(Work_Callback callback, Baton* baton);
    void Process();
    void CleanQueue();
    template <class T> static void Error(T* baton);

protected:
    Database* db;

    sqlite3_stmt* _handle = NULL;
    int status = SQLITE_OK;
    bool prepared = false;
    bool locked = true;
    bool finalized = false;

    std::queue<Call*> queue;
    std::string message;
};

}

#endif
