/* ------------------------------------------------------------------------- */
/*
 *  smb.js
 *
 *  Copyright (c) 2011, clown.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    - Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    - Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    - No names of its contributors may be used to endorse or promote
 *      products derived from this software without specific prior written
 *      permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/* ------------------------------------------------------------------------- */
var smb = new function() {
    /* --------------------------------------------------------------------- */
    //  variables
    /* --------------------------------------------------------------------- */
    var horizontal  = 7; // ソーシャルボタン間の水平方向のマージン
    var vertical    = 2; // 小さなボタンを上下中央に揃えるためのマージン
    
    /* --------------------------------------------------------------------- */
    //  kinds
    /* --------------------------------------------------------------------- */
    var kinds = {
        twitter    : 0x0001, // http://twitter.com/
        facebook   : 0x0002, // http://www.facebook.com/
        hatena     : 0x0004, // http://b.hatena.ne.jp/
        hatena_old : 0x0008, // http://b.hatena.ne.jp/
        delicious  : 0x0010, // http://www.delicious.com/
        livedoor   : 0x0020, // http://clip.livedoor.com/
        yahoo      : 0x0040, // http://bookmarks.yahoo.co.jp/
        buzzurl    : 0x0080, // http://buzzurl.jp/
        evernote   : 0x0100, // http://www.evernote.com/
        newsing    : 0x0200, // http://newsing.jp/
        gree       : 0x0400, // http://gree.jp/
        nifty      : 0x0800, // http://clip.nifty.com/
        atode      : 0x1000, // http://news.atode.cc/
        google     : 0x2000  // http://www.google.com/bookmarks/
    };
    
    /* --------------------------------------------------------------------- */
    //  options
    /* --------------------------------------------------------------------- */
    var options = {
        detail     : 0x0001, // カウント値も併せて表示
        showentry  : 0x0002  // クリック時に該当サービスのエントリーページを開く
    };
    
    /* --------------------------------------------------------------------- */
    //  escape
    /* --------------------------------------------------------------------- */
    var escape = function(str) {
        return str.replace(/<|>|&|'|"|\s/g, function(s){
            var map = {"<":"&lt;", ">":"&gt;", "&":"&amp;", "'":"&#39;", "\"":"&quot;", " ":"&nbsp;"};
            return map[s];
        });
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  md5
     *
     *  CybozuLabs.MD5 を利用して MD5 ハッシュ値を計算する．
     *  ロードされなかった場合は，空文字列を返す．
     *  http://labs.cybozu.co.jp/blog/mitsunari/2007/07/md5js_1.html
     */
    /* --------------------------------------------------------------------- */
    var md5 = function(str) {
        var defined = (typeof CybozuLabs != "undefined") && (typeof CybozuLabs.MD5 != "undefined") && (typeof CybozuLabs.MD5.calc != "undefined");
        return defined ? CybozuLabs.MD5.calc(str) : "";
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_twitter
     *
     *  Twitter のソーシャルボタンを表示する．
     *  http://twitter.com/goodies/tweetbutton
     */
    /* --------------------------------------------------------------------- */
    var show_twitter = function(option) {
        var count = ((option & options.detail) != 0) ? "horizontal" : "none";
        document.write('<a href="http://twitter.com/share"');
        document.write(' class="twitter-share-button"');
        document.write(' data-count="' + count + '"');
        document.write(' data-lang="ja"');
        document.write('>Tweet</a>');
        document.write('<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>');
        
        if ((option & options.detail) == 0) document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_facebook
     *
     *  Facebook のソーシャルボタン（「いいね！」ボタン）を表示する．
     *  NOTE: Facebook はカウントの非表示が効かない．
     *  http://developers.facebook.com/docs/reference/plugins/like/
     */
    /* --------------------------------------------------------------------- */
    var show_facebook = function(option) {
        document.write('<iframe src="http://www.facebook.com/plugins/like.php?href=' + encodeURIComponent(location.href));
        document.write('&amp;layout=button_count');
        document.write('&amp;show_faces=true');
        document.write('&amp;width=100');
        document.write('&amp;action=like');
        document.write('&amp;colorscheme=light');
        document.write('&amp;height=21"');
        document.write(' scrolling="no" frameborder="0" allowTransparency="true"');
        document.write(' style="border:none; overflow:hidden; width:120px; height:21px; position:relative; top:1px;"');
        document.write('></iframe>');
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_gree
     *
     *  GREE の Social Feedback ボタンを表示する．
     *  NOTE: GREE はカウントの表示機能が存在しない？
     *  http://developer.gree.co.jp/connect/plugins/sf
     */
    /* --------------------------------------------------------------------- */
    var show_gree = function(option) {
        var type   = ((option & options.detail) != 0) ? 0 : 4;
        var width  = ((option & options.detail) != 0) ? 70 : 16;
        var height = ((option & options.detail) != 0) ? 20 : 16;
        var bottom = ((option & options.detail) != 0) ? 0 : 2;
        
        document.write('<iframe src="http://share.gree.jp/share?url=' + encodeURIComponent(location.href));
        document.write('&amp;type=' + type);
        document.write('&amp;height=' + height + '"');
        document.write(' scrolling="no" frameborder="0" marginwidth="0" marginheight="0" allowTransparency="true"');
        document.write(' style="border:none; overflow:hidden; width:' + width + 'px; height:' + height + 'px; margin-bottom:' + bottom + 'px;"');
        document.write('></iframe>');
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_google
     *
     *  Google ブックマークボタンを表示する．
     */
    /* --------------------------------------------------------------------- */
    var show_google = function(option) {
        document.write('<a href="https://www.google.com/bookmarks/mark?op=edit&amp;bkmk=' + encodeURIComponent(location.href));
        document.write('&amp;title=' + encodeURIComponent(document.title) + '"');
        document.write(' target="_blank"');
        document.write('>');
        
        document.write('<img src="http://www.google.com/favicon.ico"');
        document.write(' alt="このエントリーを Google ブックマークに追加"');
        document.write(' width="16" height="16"');
        document.write(' style="border:none; margin-bottom:' + vertical + 'px;"');
        document.write(' />');
        
        document.write('</a>');
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    }
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_hatena
     *
     *  はてなブックマークボタンを表示する．
     *  http://b.hatena.ne.jp/guide/bbutton
     */
    /* --------------------------------------------------------------------- */
    var show_hatena = function(option) {
        var count   = ((option & options.detail) != 0) ? "standard" : "simple";
        var link    = ((option & options.showentry) != 0) ?
                        "http://b.hatena.ne.jp/entry/" :
                        "http://b.hatena.ne.jp/entry/add/";
        var title   = ((option & options.showentry) != 0) ?
                        "このエントリーを含むはてブックマーク" :
                        "このエントリーをはてなブックマークに追加";
        
        document.write('<a href="' + link + escape(location.href) + '"');
        document.write(' class="hatena-bookmark-button"');
        document.write(' data-hatena-bookmark-layout="' + count + '"');
        document.write('>');
        
        document.write('<img src="http://b.st-hatena.com/images/entry-button/button-only.gif"');
        document.write(' alt="' + title + '"');
        document.write(' width="20" height="20"');
        document.write(' style="border:none;"');
        document.write(' />');
        
        document.write('</a>');
        
        document.write('<script type="text/javascript" src="http://b.st-hatena.com/js/bookmark_button.js"');
        document.write(' charset="utf-8" async="async"');
        document.write('></script>');
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_hatena_old
     *
     *  旧タイプのはてなブックマークボタンを表示する．
     */
    /* --------------------------------------------------------------------- */
    var show_hatena_old = function(option) {
        var uri     = escape(location.href);
        var link    = ((option & options.showentry) != 0) ?
                        "http://b.hatena.ne.jp/entry/" + uri:
                        "http://b.hatena.ne.jp/entry/add/" + uri;
        var image   = ((option & options.showentry) != 0) ?
                        "http://b.hatena.ne.jp/images/entry.gif" :
                        "http://b.hatena.ne.jp/images/append.gif";
        var title   = ((option & options.showentry) != 0) ?
                        "このエントリーを含むはてブックマーク" :
                        "このエントリーをはてなブックマークに追加";
        
        document.write('<a href="' + link + '" target="_blank">');
        document.write('<img src="' + image + '" alt="' + title + '"');
        document.write(' width="16" height="12"');
        document.write(' style="border:none; margin-bottom:' + vertical + 'px;"');
        document.write(' />');
        document.write('</a>');
        
        if ((option & options.detail) != 0) {
            document.write('<span style="margin-left:2px;"></span>');
            
            document.write('<a href="http://b.hatena.ne.jp/entry/' + uri + '"');
            document.write(' target="_blank"');
            document.write('>');
            
            document.write('<img src="http://b.hatena.ne.jp/entry/image/' + uri + '"');
            document.write(' alt="このエントリーのはてブックマーク数"');
            document.write(' style="border:none; margin-bottom:' + vertical + 'px"');
            document.write(' />');
            
            document.write('</a>');
        }
        
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_evernote
     *
     *  Evernote のソーシャルボタンを表示する．
     *  NOTE: Evernote はカウントの表示機能が存在しない．
     *  http://www.evernote.com/about/developer/sitememory/
     */
    /* --------------------------------------------------------------------- */
    var show_evernote = function(option) {
        document.write('<script type="text/javascript" src="http://static.evernote.com/noteit.js"></script>');
        document.write('<a href="#" onclick="Evernote.doClip({}); return false;">');
        
        if ((option & options.detail) != 0) document.write('<img src="http://static.evernote.com/article-clipper-jp.png"');
        else document.write('<img src="http://static.evernote.com/site-mem-16.png"');
        document.write(' alt="このエントリーを Evernote に追加"');
        document.write(' style="border:none; margin-bottom:' + vertical + 'px;"');
        document.write(' />');
        
        document.write('</a>');
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_delicious
     *
     *  Delicious のブックマークボタンを表示する．
     *  NOTE: Delicious はカウントの表示機能が存在しない．
     */
    /* --------------------------------------------------------------------- */
    var show_delicious = function(option) {
        if ((option & options.showentry) != 0) {
            document.write('<a href="http://www.delicious.com/url/' + md5(location.href) + '"');
            document.write(' target="_blank"');
            document.write('>');
        }
        else {
            document.write('<a href="http://www.delicious.com/save?v=5');
            document.write('&amp;url=' + encodeURIComponent(location.href));
            document.write('&amp;title=' + encodeURIComponent(document.title) + '"');
            document.write(' target="_blank"');
            document.write('>');
        }
        
        var image   = "http://l.yimg.com/hr/img/delicious16.gif";
        var title   = ((option & options.showentry) != 0) ?
                        "このエントリーを含む delicious ブックマーク" :
                        "このエントリーを delicious に追加";
        
        document.write('<img src="' + image + '" alt="' + title + '"');
        document.write(' width="16" height="16"');
        document.write(' style="border:none; margin-bottom:' + vertical + 'px;"');
        document.write(' />');
        
        document.write('</a>');
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_livedoor
     *
     *  livedoor クリップのクリップボタンを表示する．
     */
    /* --------------------------------------------------------------------- */
    var show_livedoor = function(option) {
        var uri     = escape(location.href);
        var link    = ((option & options.showentry) != 0) ?
                        "http://clip.livedoor.com/page/" + uri :
                        "http://clip.livedoor.com/clip/add?link=" + encodeURIComponent(location.href);
        var image   = "http://parts.blog.livedoor.jp/img/cmn/clip_16_16_w.gif";
        var title   = ((option & options.showentry) != 0) ?
                        "このエントリーを含む livedoor クリップ" :
                        "このエントリーを livedoor クリップに追加";
        
        document.write('<a href="' + link + '" target="_blank">');
        document.write('<img src="' + image + '" alt="' + title + '"');
        document.write(' width="16" height="16"');
        document.write(' style="border:none; margin-bottom:' + vertical + 'px;"');
        document.write(' />');
        document.write('</a>');
        
        if ((option & options.detail) != 0) {
            document.write('<span style="margin-left:2px;"></span>');
            
            document.write('<a href="http://clip.livedoor.com/page/' + uri + '"');
            document.write(' target="_blank"');
            document.write('>');
            
            document.write('<img src="http://image.clip.livedoor.com/counter/medium/' + uri + '"');
            document.write(' alt="このエントリーの livedoor クリップ数"');
            document.write(' style="border:none; margin-bottom:' + vertical + 'px;"');
            document.write(' />');
            
            document.write('</a>');
        }
        
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_buzzurl
     *
     *  Buzzurl のブックマークボタンを表示する．
     */
    /* --------------------------------------------------------------------- */
    var show_buzzurl = function(option) {
        var uri     = escape(location.href);
        var link    = ((option & options.showentry) != 0) ?
                        "http://buzzurl.jp/entry/" + uri :
                        "http://buzzurl.jp/config/add/confirm?url=" + encodeURIComponent(location.href);
        var image   = ((option & options.showentry) != 0) ?
                        "http://buzzurl.jp/favicon.ico" :
                        "http://buzzurl.jp.eimg.jp/static/image/api/icon/add_icon_mini_08.gif";
        var title   = ((option & options.showentry) != 0) ?
                        "このエントリーを含む Buzzurl ブックマーク" :
                        "このエントリーを Buzzurl に追加";
        
        document.write('<a href="' + link + '" target="_blank">');
        document.write('<img src="' + image + '" alt="' + title + '"');
        document.write(' width="16" height="16"');
        document.write(' style="border:none; margin-bottom:' + vertical + 'px;"');
        document.write(' />');
        document.write('</a>');
        
        if ((option & options.detail) != 0) {
            document.write('<span style="margin-left:2px;"></span>');
            
            document.write('<a href="http://buzzurl.jp/entry/' + uri + '"');
            document.write(' target="_blank"');
            document.write('>');
            
            document.write('<img src="http://api.buzzurl.jp/api/counter/' + uri + '"');
            document.write(' alt="このエントリーの Buzzurl 登録数"');
            document.write(' style="border:none; margin-bottom:' + vertical + 'px;"');
            document.write(' />');
            
            document.write('</a>');
        }
        
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_yahoo
     *
     *  Yahoo! ブックマークのブックマークボタンを表示する．
     */
    /* --------------------------------------------------------------------- */
    var show_yahoo = function(option) {
        var uri = escape(location.href);
        
        if ((option & options.showentry) != 0) {
            document.write('<a href="http://bookmarks.yahoo.co.jp/url?url=' + uri);
            document.write('&amp;opener=bm&amp;ei=UTF-8"');
            document.write(' target="_blank"');
            document.write('>');
        }
        else {
            document.write('<a href="http://bookmarks.yahoo.co.jp/action/bookmark?');
            document.write('u=' + encodeURIComponent(location.href));
            document.write('&amp;t=' + encodeURIComponent(document.title));
            document.write('&amp;opener=bm&amp;ei=UTF-8"');
            document.write(' target="_blank"');
            document.write('>');
        }
        
        var image   = "http://i.yimg.jp/images/sicons/ybm16.gif";
        var title   = ((option & options.showentry) != 0) ?
                        "このエントリーを含む Yahoo! ブックマーク" :
                        "このエントリーを Yahoo! ブックマークに追加";
        
        document.write('<img src="' + image + '" alt="' + title + '"');
        document.write(' width="16" height="16"');
        document.write(' style="border:none; margin-bottom:' + vertical + 'px;"');
        document.write(' />');
        
        document.write('</a>');
        
        if ((option & options.detail) != 0) {
            document.write('<span style="margin-left:2px;"></span>');
            
            document.write('<a href="http://bookmarks.yahoo.co.jp/url?url=' + uri);
            document.write('&amp;opener=bm&amp;ei=UTF-8"');
            document.write(' target="_blank"');
            document.write('>');
            
            document.write('<img src="http://num.bookmarks.yahoo.co.jp/image/small/' + uri + '"');
            document.write(' alt="このエントリーの Yahoo! ブックマーク登録数"');
            document.write(' style="border:none; margin-bottom:' + vertical + 'px;"')
            document.write(' />');
            
            document.write('</a>');
        }
        
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_nifty
     *
     *  @nifty クリップのブックマークボタンを表示する．
     *  http://clip.nifty.com/help/cat3/post_8.htm
     */
    /* --------------------------------------------------------------------- */
    var show_nifty = function(option) {
        var uri = escape(location.href);
        
        if ((option & options.showentry) != 0) {
            document.write('<a href="http://clip.nifty.com/entry/?url=' + uri + '"');
            document.write(' target="_blank"');
            document.write('>');
        }
        else {
            document.write('<a href="http://clip.nifty.com/create?url=' + encodeURIComponent(location.href));
            document.write('&amp;title=' + encodeURIComponent(document.title) + '"');
            document.write(' target="_blank"');
            document.write('>');
        }
        
        var image   = ((option & options.showentry) != 0) ?
                        "http://clip.nifty.com/images/ico_clip.gif" :
                        "http://clip.nifty.com/images/addclip_icn.gif";
        var title   = ((option & options.showentry) != 0) ?
                        "このエントリーを含む @nifty クリップ" :
                        "このエントリーを @nifty クリップに追加";
        var width   = ((option & options.showentry) != 0) ? 13 : 16;
        
        document.write('<img src="' + image + '" alt="' + title + '"');
        document.write(' width="' + width + '" height="16"');
        document.write(' style="border:none; margin-bottom:' + vertical + 'px;"');
        document.write(' />');
        
        document.write('</a>');
        
        if ((option & options.detail) != 0) {
            document.write('<span style="margin-left:2px;"></span>');
            
            document.write('<a href="http://clip.nifty.com/entry/?url=' + uri + '"');
            document.write(' target="_blank"');
            document.write('>');
            
            document.write('<img src="http://api.clip.nifty.com/api/v1/image/counter/' + uri + '"');
            document.write(' alt="このエントリーの @nifty クリップ登録数"');
            document.write(' style="border:none; margin-bottom:' + vertical + 'px;"')
            document.write(' />');
            
            document.write('</a>');
        }
        
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_newsing
     *
     *  Delicious のピックアップボタンを表示する．
     *  NOTE: newsing はカウントの表示機能が存在しない？
     */
    /* --------------------------------------------------------------------- */
    var show_newsing = function(option) {
        var uri = encodeURIComponent(location.href);
        
        if ((option & options.showentry) != 0) {
            document.write('<a href="http://newsing.jp/entry?url=' + uri + '"');
            document.write(' target="_blank"');
            document.write('>');
        }
        else {
            document.write('<a href="http://newsing.jp/nbutton?title=' + encodeURIComponent(document.title));
            document.write('&amp;url=' + uri + '"');
            document.write(' target="_blank"');
            document.write('>');
        }
        
        //var image = "http://image.newsing.jp/common/images/newsingit/newsingit_s.gif";
        var image   = "http://image.newsing.jp/common/images/newsingit/newsing_button_16.gif";
        var title   = ((option & options.showentry) != 0) ?
                        "このエントリーを含む newsing" :
                        "このエントリーを newsing でピックアップ";
        
        document.write('<img src="' + image + '" alt="' + title + '"');
        document.write(' width="16" height="16"');
        document.write(' style="border:none; margin-bottom:' + vertical + 'px;"');
        document.write(' />');
        
        document.write('</a>');
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    /*
     *  show_atode
     *
     *  あとで新聞のブックマークボタンを表示する．
     *  NOTE: あとで新聞用のボタン画像を取りあえず favicon.ico から取得
     *  している．正式なボタン画像を探す．
     */
    /* --------------------------------------------------------------------- */
    var show_atode = function(option) {
        if ((option & options.showentry) != 0) {
            document.write('<a href="http://news.atode.cc/bar.php?u=' + encodeURIComponent(location.href) + '"');
            document.write(' target="_blank"');
            document.write('>');
            
            document.write('<img src="http://news.atode.cc/favicon.ico"');
            document.write(' alt="このエントリーを含むあとで新聞" width="16" height="16"');
            document.write(' style="border:none; margin-bottom:' + vertical + 'px"');
            document.write(' />');
            
            document.write('</a>');
        }
        else {
            document.write('<a href="http://atode.cc/"');
            document.write(' onclick=\'javascript:(function(){');
            document.write('var s=document.createElement("scr"+"ipt");');
            document.write('s.charset="UTF-8";');
            document.write('s.language="javascr"+"ipt";');
            document.write('s.type="text/javascr"+"ipt";');
            document.write('var d=new Date;');
            document.write('s.src="http://atode.cc/bjs.php?d="+d.getMilliseconds();');
            document.write('document.body.appendChild(s)');
            document.write('})();');
            document.write('return false;\'');
            document.write('>');
            
            var image   = ((option & options.detail) != 0) ?
                            "http://atode.cc/img/iconnja.gif" :
                            "http://atode.cc/img/iconsja.gif";
            var title   = "このエントリーをあとで読む";
            var width   = ((option & options.detail) != 0) ? 66 : 16;
            var height  = ((option & options.detail) != 0) ? 20 : 16;
            var bottom  = ((option & options.detail) != 0) ? 0 : vertical;
            
            document.write('<img src="' + image + '" alt="' + title + '"');
            document.write(' width="' + width + '" height="' + height + '"');
            document.write(' style="border:none; margin-bottom:' + bottom + 'px"');
            document.write(' />');
            
            document.write('</a>');
        }
        document.write('<span style="margin-left:' + horizontal + 'px;"></span>');
    };
    
    /* --------------------------------------------------------------------- */
    //  public variables/functions
    /* --------------------------------------------------------------------- */
    var public = {
        /* ----------------------------------------------------------------- */
        //  version
        /* ----------------------------------------------------------------- */
        version    : "0.1.0",
        
        /* ----------------------------------------------------------------- */
        //  kinds
        /* ----------------------------------------------------------------- */
        twitter    : kinds.twitter,
        facebook   : kinds.facebook,
        google     : kinds.google,
        hatena     : kinds.hatena,
        hatena_old : kinds.hatena_old,
        delicious  : kinds.delicious,
        livedoor   : kinds.livedoor,
        yahoo      : kinds.yahoo,
        buzzurl    : kinds.buzzurl,
        nifty      : kinds.nifty,
        newsing    : kinds.newsing,
        atode      : kinds.atode,
        evernote   : kinds.evernote,
        gree       : kinds.gree,
        
        /* ----------------------------------------------------------------- */
        //  options
        /* ----------------------------------------------------------------- */
        detail     : options.detail,
        showentry  : options.showentry,
        
        /* ----------------------------------------------------------------- */
        /*
         *  show
         *
         *  メイン関数．
         *
         *  引数 kind には twitter, facebook, hatena, hatena_old,
         *  delicious, livedoor, yahoo, buzzurl, evernote, newsing,
         *  gree のうち，表示したいものを | 演算子で繋げて指定する．
         */
        /* ----------------------------------------------------------------- */
        show : function(kind, option) {
            var tmp = 0;
            if (arguments.length == 2) {
                // version 0.0.* との互換性を保つため．
                if (typeof option == "boolean" && option == true) tmp = options.detail;
                else tmp = option;
            }
            
            if ((kind & kinds.hatena_old) != 0) show_hatena_old(tmp);
            if ((kind & kinds.google) != 0) show_google(tmp);
            if ((kind & kinds.delicious) != 0) show_delicious(tmp);
            if ((kind & kinds.livedoor) != 0) show_livedoor(tmp);
            if ((kind & kinds.yahoo) != 0) show_yahoo(tmp);
            if ((kind & kinds.buzzurl) != 0) show_buzzurl(tmp);
            if ((kind & kinds.nifty) != 0) show_nifty(tmp);
            if ((kind & kinds.newsing) != 0) show_newsing(tmp);
            if ((kind & kinds.atode) != 0 && ((tmp & options.detail) == 0 || (tmp & options.showentry) != 0)) show_atode(tmp);
            if ((kind & kinds.evernote) != 0) show_evernote(tmp);
            if ((kind & kinds.gree) != 0 && (tmp & options.detail) == 0) show_gree(tmp);
            if ((kind & kinds.atode) != 0 && ((tmp & options.detail) != 0 && (tmp & options.showentry) == 0)) show_atode(tmp);
            if ((kind & kinds.hatena) != 0) show_hatena(tmp);
            if ((kind & kinds.twitter) != 0) show_twitter(tmp);
            if ((kind & kinds.gree) != 0 && (tmp & options.detail) != 0) show_gree(tmp);
            if ((kind & kinds.facebook) != 0) show_facebook(tmp);
        }
    };
    
    return public;
}

/*
	MD5
	Copyright (C) 2007 MITSUNARI Shigeo at Cybozu Labs, Inc.
	license:new BSD license
	how to use
	CybozuLabs.MD5.calc(<ascii string>);
	CybozuLabs.MD5.calc(<unicode(UTF16) string>, CybozuLabs.MD5.BY_UTF16);

	ex. CybozuLabs.MD5.calc("abc") == "900150983cd24fb0d6963f7d28e17f72";
*/
var CybozuLabs = {
	MD5 : {
		// for Firefox
		int2hex8_Fx : function(x) {
			return this.int2hex8((x[1] * 65536) + x[0]);
		},

		update_Fx : function(buf, charSize) {
			var aL = this.a_[0];
			var aH = this.a_[1];
			var bL = this.b_[0];
			var bH = this.b_[1];
			var cL = this.c_[0];
			var cH = this.c_[1];
			var dL = this.d_[0];
			var dH = this.d_[1];
			var tmpL0, tmpL1, tmpL2, tmpL3, tmpL4, tmpL5, tmpL6, tmpL7, tmpL8, tmpL9, tmpLa, tmpLb, tmpLc, tmpLd, tmpLe, tmpLf;
			var tmpH0, tmpH1, tmpH2, tmpH3, tmpH4, tmpH5, tmpH6, tmpH7, tmpH8, tmpH9, tmpHa, tmpHb, tmpHc, tmpHd, tmpHe, tmpHf;
			if (charSize == 1) {
				tmpL0 = buf.charCodeAt( 0) | (buf.charCodeAt( 1) << 8); tmpH0 = buf.charCodeAt( 2) | (buf.charCodeAt( 3) << 8);
				tmpL1 = buf.charCodeAt( 4) | (buf.charCodeAt( 5) << 8); tmpH1 = buf.charCodeAt( 6) | (buf.charCodeAt( 7) << 8);
				tmpL2 = buf.charCodeAt( 8) | (buf.charCodeAt( 9) << 8); tmpH2 = buf.charCodeAt(10) | (buf.charCodeAt(11) << 8);
				tmpL3 = buf.charCodeAt(12) | (buf.charCodeAt(13) << 8); tmpH3 = buf.charCodeAt(14) | (buf.charCodeAt(15) << 8);
				tmpL4 = buf.charCodeAt(16) | (buf.charCodeAt(17) << 8); tmpH4 = buf.charCodeAt(18) | (buf.charCodeAt(19) << 8);
				tmpL5 = buf.charCodeAt(20) | (buf.charCodeAt(21) << 8); tmpH5 = buf.charCodeAt(22) | (buf.charCodeAt(23) << 8);
				tmpL6 = buf.charCodeAt(24) | (buf.charCodeAt(25) << 8); tmpH6 = buf.charCodeAt(26) | (buf.charCodeAt(27) << 8);
				tmpL7 = buf.charCodeAt(28) | (buf.charCodeAt(29) << 8); tmpH7 = buf.charCodeAt(30) | (buf.charCodeAt(31) << 8);
				tmpL8 = buf.charCodeAt(32) | (buf.charCodeAt(33) << 8); tmpH8 = buf.charCodeAt(34) | (buf.charCodeAt(35) << 8);
				tmpL9 = buf.charCodeAt(36) | (buf.charCodeAt(37) << 8); tmpH9 = buf.charCodeAt(38) | (buf.charCodeAt(39) << 8);
				tmpLa = buf.charCodeAt(40) | (buf.charCodeAt(41) << 8); tmpHa = buf.charCodeAt(42) | (buf.charCodeAt(43) << 8);
				tmpLb = buf.charCodeAt(44) | (buf.charCodeAt(45) << 8); tmpHb = buf.charCodeAt(46) | (buf.charCodeAt(47) << 8);
				tmpLc = buf.charCodeAt(48) | (buf.charCodeAt(49) << 8); tmpHc = buf.charCodeAt(50) | (buf.charCodeAt(51) << 8);
				tmpLd = buf.charCodeAt(52) | (buf.charCodeAt(53) << 8); tmpHd = buf.charCodeAt(54) | (buf.charCodeAt(55) << 8);
				tmpLe = buf.charCodeAt(56) | (buf.charCodeAt(57) << 8); tmpHe = buf.charCodeAt(58) | (buf.charCodeAt(59) << 8);
				tmpLf = buf.charCodeAt(60) | (buf.charCodeAt(61) << 8); tmpHf = buf.charCodeAt(62) | (buf.charCodeAt(63) << 8);
			} else {
				tmpL0 = buf.charCodeAt( 0); tmpH0 = buf.charCodeAt( 1);
				tmpL1 = buf.charCodeAt( 2); tmpH1 = buf.charCodeAt( 3);
				tmpL2 = buf.charCodeAt( 4); tmpH2 = buf.charCodeAt( 5);
				tmpL3 = buf.charCodeAt( 6); tmpH3 = buf.charCodeAt( 7);
				tmpL4 = buf.charCodeAt( 8); tmpH4 = buf.charCodeAt( 9);
				tmpL5 = buf.charCodeAt(10); tmpH5 = buf.charCodeAt(11);
				tmpL6 = buf.charCodeAt(12); tmpH6 = buf.charCodeAt(13);
				tmpL7 = buf.charCodeAt(14); tmpH7 = buf.charCodeAt(15);
				tmpL8 = buf.charCodeAt(16); tmpH8 = buf.charCodeAt(17);
				tmpL9 = buf.charCodeAt(18); tmpH9 = buf.charCodeAt(19);
				tmpLa = buf.charCodeAt(20); tmpHa = buf.charCodeAt(21);
				tmpLb = buf.charCodeAt(22); tmpHb = buf.charCodeAt(23);
				tmpLc = buf.charCodeAt(24); tmpHc = buf.charCodeAt(25);
				tmpLd = buf.charCodeAt(26); tmpHd = buf.charCodeAt(27);
				tmpLe = buf.charCodeAt(28); tmpHe = buf.charCodeAt(29);
				tmpLf = buf.charCodeAt(30); tmpHf = buf.charCodeAt(31);
			}

			var t;
			aL += ((bL & cL) | (~bL & dL)) + tmpL0 + 0xa478; aH += ((bH & cH) | (~bH & dH)) + tmpH0 + 0xd76a;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >>  9) | ((aL <<  7) & 65535); aH = (aL >>  9) | ((aH <<  7) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL & bL) | (~aL & cL)) + tmpL1 + 0xb756; dH += ((aH & bH) | (~aH & cH)) + tmpH1 + 0xe8c7;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  4) | ((dL << 12) & 65535); dH = (dL >>  4) | ((dH << 12) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL & aL) | (~dL & bL)) + tmpL2 + 0x70db; cH += ((dH & aH) | (~dH & bH)) + tmpH2 + 0x2420;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cL >> 15) | ((cH <<  1) & 65535); cH = (cH >> 15) | ((cL <<  1) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL & dL) | (~cL & aL)) + tmpL3 + 0xceee; bH += ((cH & dH) | (~cH & aH)) + tmpH3 + 0xc1bd;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 10) | ((bH <<  6) & 65535); bH = (bH >> 10) | ((bL <<  6) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += ((bL & cL) | (~bL & dL)) + tmpL4 + 0x0faf; aH += ((bH & cH) | (~bH & dH)) + tmpH4 + 0xf57c;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >>  9) | ((aL <<  7) & 65535); aH = (aL >>  9) | ((aH <<  7) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL & bL) | (~aL & cL)) + tmpL5 + 0xc62a; dH += ((aH & bH) | (~aH & cH)) + tmpH5 + 0x4787;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  4) | ((dL << 12) & 65535); dH = (dL >>  4) | ((dH << 12) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL & aL) | (~dL & bL)) + tmpL6 + 0x4613; cH += ((dH & aH) | (~dH & bH)) + tmpH6 + 0xa830;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cL >> 15) | ((cH <<  1) & 65535); cH = (cH >> 15) | ((cL <<  1) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL & dL) | (~cL & aL)) + tmpL7 + 0x9501; bH += ((cH & dH) | (~cH & aH)) + tmpH7 + 0xfd46;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 10) | ((bH <<  6) & 65535); bH = (bH >> 10) | ((bL <<  6) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += ((bL & cL) | (~bL & dL)) + tmpL8 + 0x98d8; aH += ((bH & cH) | (~bH & dH)) + tmpH8 + 0x6980;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >>  9) | ((aL <<  7) & 65535); aH = (aL >>  9) | ((aH <<  7) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL & bL) | (~aL & cL)) + tmpL9 + 0xf7af; dH += ((aH & bH) | (~aH & cH)) + tmpH9 + 0x8b44;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  4) | ((dL << 12) & 65535); dH = (dL >>  4) | ((dH << 12) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL & aL) | (~dL & bL)) + tmpLa + 0x5bb1; cH += ((dH & aH) | (~dH & bH)) + tmpHa + 0xffff;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cL >> 15) | ((cH <<  1) & 65535); cH = (cH >> 15) | ((cL <<  1) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL & dL) | (~cL & aL)) + tmpLb + 0xd7be; bH += ((cH & dH) | (~cH & aH)) + tmpHb + 0x895c;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 10) | ((bH <<  6) & 65535); bH = (bH >> 10) | ((bL <<  6) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += ((bL & cL) | (~bL & dL)) + tmpLc + 0x1122; aH += ((bH & cH) | (~bH & dH)) + tmpHc + 0x6b90;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >>  9) | ((aL <<  7) & 65535); aH = (aL >>  9) | ((aH <<  7) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL & bL) | (~aL & cL)) + tmpLd + 0x7193; dH += ((aH & bH) | (~aH & cH)) + tmpHd + 0xfd98;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  4) | ((dL << 12) & 65535); dH = (dL >>  4) | ((dH << 12) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL & aL) | (~dL & bL)) + tmpLe + 0x438e; cH += ((dH & aH) | (~dH & bH)) + tmpHe + 0xa679;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cL >> 15) | ((cH <<  1) & 65535); cH = (cH >> 15) | ((cL <<  1) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL & dL) | (~cL & aL)) + tmpLf + 0x0821; bH += ((cH & dH) | (~cH & aH)) + tmpHf + 0x49b4;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 10) | ((bH <<  6) & 65535); bH = (bH >> 10) | ((bL <<  6) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
///
			aL += ((bL & dL) | (cL & ~dL)) + tmpL1 + 0x2562; aH += ((bH & dH) | (cH & ~dH)) + tmpH1 + 0xf61e;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 11) | ((aL <<  5) & 65535); aH = (aL >> 11) | ((aH <<  5) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL & cL) | (bL & ~cL)) + tmpL6 + 0xb340; dH += ((aH & cH) | (bH & ~cH)) + tmpH6 + 0xc040;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  7) | ((dL <<  9) & 65535); dH = (dL >>  7) | ((dH <<  9) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL & bL) | (aL & ~bL)) + tmpLb + 0x5a51; cH += ((dH & bH) | (aH & ~bH)) + tmpHb + 0x265e;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cH >>  2) | ((cL << 14) & 65535); cH = (cL >>  2) | ((cH << 14) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL & aL) | (dL & ~aL)) + tmpL0 + 0xc7aa; bH += ((cH & aH) | (dH & ~aH)) + tmpH0 + 0xe9b6;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 12) | ((bH <<  4) & 65535); bH = (bH >> 12) | ((bL <<  4) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += ((bL & dL) | (cL & ~dL)) + tmpL5 + 0x105d; aH += ((bH & dH) | (cH & ~dH)) + tmpH5 + 0xd62f;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 11) | ((aL <<  5) & 65535); aH = (aL >> 11) | ((aH <<  5) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL & cL) | (bL & ~cL)) + tmpLa + 0x1453; dH += ((aH & cH) | (bH & ~cH)) + tmpHa + 0x0244;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  7) | ((dL <<  9) & 65535); dH = (dL >>  7) | ((dH <<  9) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL & bL) | (aL & ~bL)) + tmpLf + 0xe681; cH += ((dH & bH) | (aH & ~bH)) + tmpHf + 0xd8a1;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cH >>  2) | ((cL << 14) & 65535); cH = (cL >>  2) | ((cH << 14) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL & aL) | (dL & ~aL)) + tmpL4 + 0xfbc8; bH += ((cH & aH) | (dH & ~aH)) + tmpH4 + 0xe7d3;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 12) | ((bH <<  4) & 65535); bH = (bH >> 12) | ((bL <<  4) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += ((bL & dL) | (cL & ~dL)) + tmpL9 + 0xcde6; aH += ((bH & dH) | (cH & ~dH)) + tmpH9 + 0x21e1;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 11) | ((aL <<  5) & 65535); aH = (aL >> 11) | ((aH <<  5) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL & cL) | (bL & ~cL)) + tmpLe + 0x07d6; dH += ((aH & cH) | (bH & ~cH)) + tmpHe + 0xc337;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  7) | ((dL <<  9) & 65535); dH = (dL >>  7) | ((dH <<  9) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL & bL) | (aL & ~bL)) + tmpL3 + 0x0d87; cH += ((dH & bH) | (aH & ~bH)) + tmpH3 + 0xf4d5;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cH >>  2) | ((cL << 14) & 65535); cH = (cL >>  2) | ((cH << 14) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL & aL) | (dL & ~aL)) + tmpL8 + 0x14ed; bH += ((cH & aH) | (dH & ~aH)) + tmpH8 + 0x455a;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 12) | ((bH <<  4) & 65535); bH = (bH >> 12) | ((bL <<  4) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += ((bL & dL) | (cL & ~dL)) + tmpLd + 0xe905; aH += ((bH & dH) | (cH & ~dH)) + tmpHd + 0xa9e3;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 11) | ((aL <<  5) & 65535); aH = (aL >> 11) | ((aH <<  5) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL & cL) | (bL & ~cL)) + tmpL2 + 0xa3f8; dH += ((aH & cH) | (bH & ~cH)) + tmpH2 + 0xfcef;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  7) | ((dL <<  9) & 65535); dH = (dL >>  7) | ((dH <<  9) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL & bL) | (aL & ~bL)) + tmpL7 + 0x02d9; cH += ((dH & bH) | (aH & ~bH)) + tmpH7 + 0x676f;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cH >>  2) | ((cL << 14) & 65535); cH = (cL >>  2) | ((cH << 14) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL & aL) | (dL & ~aL)) + tmpLc + 0x4c8a; bH += ((cH & aH) | (dH & ~aH)) + tmpHc + 0x8d2a;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 12) | ((bH <<  4) & 65535); bH = (bH >> 12) | ((bL <<  4) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
///
			aL += ((bL ^ cL) ^ dL) + tmpL5 + 0x3942; aH += ((bH ^ cH) ^ dH) + tmpH5 + 0xfffa;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 12) | ((aL <<  4) & 65535); aH = (aL >> 12) | ((aH <<  4) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL ^ bL) ^ cL) + tmpL8 + 0xf681; dH += ((aH ^ bH) ^ cH) + tmpH8 + 0x8771;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  5) | ((dL << 11) & 65535); dH = (dL >>  5) | ((dH << 11) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL ^ aL) ^ bL) + tmpLb + 0x6122; cH += ((dH ^ aH) ^ bH) + tmpHb + 0x6d9d;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cL >> 16) | ((cH <<  0) & 65535); cH = (cH >> 16) | ((cL <<  0) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL ^ dL) ^ aL) + tmpLe + 0x380c; bH += ((cH ^ dH) ^ aH) + tmpHe + 0xfde5;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >>  9) | ((bH <<  7) & 65535); bH = (bH >>  9) | ((bL <<  7) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += ((bL ^ cL) ^ dL) + tmpL1 + 0xea44; aH += ((bH ^ cH) ^ dH) + tmpH1 + 0xa4be;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 12) | ((aL <<  4) & 65535); aH = (aL >> 12) | ((aH <<  4) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL ^ bL) ^ cL) + tmpL4 + 0xcfa9; dH += ((aH ^ bH) ^ cH) + tmpH4 + 0x4bde;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  5) | ((dL << 11) & 65535); dH = (dL >>  5) | ((dH << 11) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL ^ aL) ^ bL) + tmpL7 + 0x4b60; cH += ((dH ^ aH) ^ bH) + tmpH7 + 0xf6bb;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cL >> 16) | ((cH <<  0) & 65535); cH = (cH >> 16) | ((cL <<  0) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL ^ dL) ^ aL) + tmpLa + 0xbc70; bH += ((cH ^ dH) ^ aH) + tmpHa + 0xbebf;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >>  9) | ((bH <<  7) & 65535); bH = (bH >>  9) | ((bL <<  7) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += ((bL ^ cL) ^ dL) + tmpLd + 0x7ec6; aH += ((bH ^ cH) ^ dH) + tmpHd + 0x289b;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 12) | ((aL <<  4) & 65535); aH = (aL >> 12) | ((aH <<  4) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL ^ bL) ^ cL) + tmpL0 + 0x27fa; dH += ((aH ^ bH) ^ cH) + tmpH0 + 0xeaa1;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  5) | ((dL << 11) & 65535); dH = (dL >>  5) | ((dH << 11) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL ^ aL) ^ bL) + tmpL3 + 0x3085; cH += ((dH ^ aH) ^ bH) + tmpH3 + 0xd4ef;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cL >> 16) | ((cH <<  0) & 65535); cH = (cH >> 16) | ((cL <<  0) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL ^ dL) ^ aL) + tmpL6 + 0x1d05; bH += ((cH ^ dH) ^ aH) + tmpH6 + 0x0488;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >>  9) | ((bH <<  7) & 65535); bH = (bH >>  9) | ((bL <<  7) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += ((bL ^ cL) ^ dL) + tmpL9 + 0xd039; aH += ((bH ^ cH) ^ dH) + tmpH9 + 0xd9d4;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 12) | ((aL <<  4) & 65535); aH = (aL >> 12) | ((aH <<  4) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += ((aL ^ bL) ^ cL) + tmpLc + 0x99e5; dH += ((aH ^ bH) ^ cH) + tmpHc + 0xe6db;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  5) | ((dL << 11) & 65535); dH = (dL >>  5) | ((dH << 11) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += ((dL ^ aL) ^ bL) + tmpLf + 0x7cf8; cH += ((dH ^ aH) ^ bH) + tmpHf + 0x1fa2;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cL >> 16) | ((cH <<  0) & 65535); cH = (cH >> 16) | ((cL <<  0) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += ((cL ^ dL) ^ aL) + tmpL2 + 0x5665; bH += ((cH ^ dH) ^ aH) + tmpH2 + 0xc4ac;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >>  9) | ((bH <<  7) & 65535); bH = (bH >>  9) | ((bL <<  7) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
///
			aL += (cL ^ ((65535 - dL) | bL)) + tmpL0 + 0x2244; aH += (cH ^ ((65535 - dH) | bH)) + tmpH0 + 0xf429;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 10) | ((aL <<  6) & 65535); aH = (aL >> 10) | ((aH <<  6) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += (bL ^ ((65535 - cL) | aL)) + tmpL7 + 0xff97; dH += (bH ^ ((65535 - cH) | aH)) + tmpH7 + 0x432a;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  6) | ((dL << 10) & 65535); dH = (dL >>  6) | ((dH << 10) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += (aL ^ ((65535 - bL) | dL)) + tmpLe + 0x23a7; cH += (aH ^ ((65535 - bH) | dH)) + tmpHe + 0xab94;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cH >>  1) | ((cL << 15) & 65535); cH = (cL >>  1) | ((cH << 15) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += (dL ^ ((65535 - aL) | cL)) + tmpL5 + 0xa039; bH += (dH ^ ((65535 - aH) | cH)) + tmpH5 + 0xfc93;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 11) | ((bH <<  5) & 65535); bH = (bH >> 11) | ((bL <<  5) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += (cL ^ ((65535 - dL) | bL)) + tmpLc + 0x59c3; aH += (cH ^ ((65535 - dH) | bH)) + tmpHc + 0x655b;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 10) | ((aL <<  6) & 65535); aH = (aL >> 10) | ((aH <<  6) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += (bL ^ ((65535 - cL) | aL)) + tmpL3 + 0xcc92; dH += (bH ^ ((65535 - cH) | aH)) + tmpH3 + 0x8f0c;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  6) | ((dL << 10) & 65535); dH = (dL >>  6) | ((dH << 10) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += (aL ^ ((65535 - bL) | dL)) + tmpLa + 0xf47d; cH += (aH ^ ((65535 - bH) | dH)) + tmpHa + 0xffef;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cH >>  1) | ((cL << 15) & 65535); cH = (cL >>  1) | ((cH << 15) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += (dL ^ ((65535 - aL) | cL)) + tmpL1 + 0x5dd1; bH += (dH ^ ((65535 - aH) | cH)) + tmpH1 + 0x8584;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 11) | ((bH <<  5) & 65535); bH = (bH >> 11) | ((bL <<  5) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += (cL ^ ((65535 - dL) | bL)) + tmpL8 + 0x7e4f; aH += (cH ^ ((65535 - dH) | bH)) + tmpH8 + 0x6fa8;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 10) | ((aL <<  6) & 65535); aH = (aL >> 10) | ((aH <<  6) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += (bL ^ ((65535 - cL) | aL)) + tmpLf + 0xe6e0; dH += (bH ^ ((65535 - cH) | aH)) + tmpHf + 0xfe2c;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  6) | ((dL << 10) & 65535); dH = (dL >>  6) | ((dH << 10) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += (aL ^ ((65535 - bL) | dL)) + tmpL6 + 0x4314; cH += (aH ^ ((65535 - bH) | dH)) + tmpH6 + 0xa301;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cH >>  1) | ((cL << 15) & 65535); cH = (cL >>  1) | ((cH << 15) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += (dL ^ ((65535 - aL) | cL)) + tmpLd + 0x11a1; bH += (dH ^ ((65535 - aH) | cH)) + tmpHd + 0x4e08;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 11) | ((bH <<  5) & 65535); bH = (bH >> 11) | ((bL <<  5) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
			aL += (cL ^ ((65535 - dL) | bL)) + tmpL4 + 0x7e82; aH += (cH ^ ((65535 - dH) | bH)) + tmpH4 + 0xf753;
			aH += aL >> 16;
			aL &= 65535; aH &= 65535;
			t = (aH >> 10) | ((aL <<  6) & 65535); aH = (aL >> 10) | ((aH <<  6) & 65535);
			aL = t + bL; aH += bH; if (aL > 65535) { aL &= 65535; aH++; }
			aH &= 65535;
			dL += (bL ^ ((65535 - cL) | aL)) + tmpLb + 0xf235; dH += (bH ^ ((65535 - cH) | aH)) + tmpHb + 0xbd3a;
			dH += dL >> 16;
			dL &= 65535; dH &= 65535;
			t = (dH >>  6) | ((dL << 10) & 65535); dH = (dL >>  6) | ((dH << 10) & 65535);
			dL = t + aL; dH += aH; if (dL > 65535) { dL &= 65535; dH++; }
			dH &= 65535;
			cL += (aL ^ ((65535 - bL) | dL)) + tmpL2 + 0xd2bb; cH += (aH ^ ((65535 - bH) | dH)) + tmpH2 + 0x2ad7;
			cH += cL >> 16;
			cL &= 65535; cH &= 65535;
			t = (cH >>  1) | ((cL << 15) & 65535); cH = (cL >>  1) | ((cH << 15) & 65535);
			cL = t + dL; cH += dH; if (cL > 65535) { cL &= 65535; cH++; }
			cH &= 65535;
			bL += (dL ^ ((65535 - aL) | cL)) + tmpL9 + 0xd391; bH += (dH ^ ((65535 - aH) | cH)) + tmpH9 + 0xeb86;
			bH += bL >> 16;
			bL &= 65535; bH &= 65535;
			t = (bL >> 11) | ((bH <<  5) & 65535); bH = (bH >> 11) | ((bL <<  5) & 65535);
			bL = t + cL; bH += cH; if (bL > 65535) { bL &= 65535; bH++; }
			bH &= 65535;
///
			t = this.a_[0] += aL; this.a_[1] += aH; if (t > 65535) { this.a_[0] -= 65536; this.a_[1]++; } this.a_[1] &= 65535;
			t = this.b_[0] += bL; this.b_[1] += bH; if (t > 65535) { this.b_[0] -= 65536; this.b_[1]++; } this.b_[1] &= 65535;
			t = this.c_[0] += cL; this.c_[1] += cH; if (t > 65535) { this.c_[0] -= 65536; this.c_[1]++; } this.c_[1] &= 65535;
			t = this.d_[0] += dL; this.d_[1] += dH; if (t > 65535) { this.d_[0] -= 65536; this.d_[1]++; } this.d_[1] &= 65535;
		},

		/* sprintf(buf, "%08x", i32); */
		int2hex8 : function(i32) {
			var i, c, ret = "";
			var hex = "0123456789abcdef";
			for (i = 0; i < 4; i++) {
				c = i32 >>> (i * 8);
				ret += hex.charAt((c >> 4) & 15);
				ret += hex.charAt(c & 15);
			}
			return ret;
		},

		update_std : function(buf, charSize) {
			var a = this.a_, b = this.b_, c = this.c_, d = this.d_;
			var tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmpa, tmpb, tmpc, tmpd, tmpe, tmpf;
			if (charSize == 1) {
				tmp0 = buf.charCodeAt( 0) | (buf.charCodeAt( 1) << 8) | (buf.charCodeAt( 2) << 16) | (buf.charCodeAt( 3) << 24);
				tmp1 = buf.charCodeAt( 4) | (buf.charCodeAt( 5) << 8) | (buf.charCodeAt( 6) << 16) | (buf.charCodeAt( 7) << 24);
				tmp2 = buf.charCodeAt( 8) | (buf.charCodeAt( 9) << 8) | (buf.charCodeAt(10) << 16) | (buf.charCodeAt(11) << 24);
				tmp3 = buf.charCodeAt(12) | (buf.charCodeAt(13) << 8) | (buf.charCodeAt(14) << 16) | (buf.charCodeAt(15) << 24);
				tmp4 = buf.charCodeAt(16) | (buf.charCodeAt(17) << 8) | (buf.charCodeAt(18) << 16) | (buf.charCodeAt(19) << 24);
				tmp5 = buf.charCodeAt(20) | (buf.charCodeAt(21) << 8) | (buf.charCodeAt(22) << 16) | (buf.charCodeAt(23) << 24);
				tmp6 = buf.charCodeAt(24) | (buf.charCodeAt(25) << 8) | (buf.charCodeAt(26) << 16) | (buf.charCodeAt(27) << 24);
				tmp7 = buf.charCodeAt(28) | (buf.charCodeAt(29) << 8) | (buf.charCodeAt(30) << 16) | (buf.charCodeAt(31) << 24);
				tmp8 = buf.charCodeAt(32) | (buf.charCodeAt(33) << 8) | (buf.charCodeAt(34) << 16) | (buf.charCodeAt(35) << 24);
				tmp9 = buf.charCodeAt(36) | (buf.charCodeAt(37) << 8) | (buf.charCodeAt(38) << 16) | (buf.charCodeAt(39) << 24);
				tmpa = buf.charCodeAt(40) | (buf.charCodeAt(41) << 8) | (buf.charCodeAt(42) << 16) | (buf.charCodeAt(43) << 24);
				tmpb = buf.charCodeAt(44) | (buf.charCodeAt(45) << 8) | (buf.charCodeAt(46) << 16) | (buf.charCodeAt(47) << 24);
				tmpc = buf.charCodeAt(48) | (buf.charCodeAt(49) << 8) | (buf.charCodeAt(50) << 16) | (buf.charCodeAt(51) << 24);
				tmpd = buf.charCodeAt(52) | (buf.charCodeAt(53) << 8) | (buf.charCodeAt(54) << 16) | (buf.charCodeAt(55) << 24);
				tmpe = buf.charCodeAt(56) | (buf.charCodeAt(57) << 8) | (buf.charCodeAt(58) << 16) | (buf.charCodeAt(59) << 24);
				tmpf = buf.charCodeAt(60) | (buf.charCodeAt(61) << 8) | (buf.charCodeAt(62) << 16) | (buf.charCodeAt(63) << 24);
			} else {
				tmp0 = buf.charCodeAt( 0) | (buf.charCodeAt( 1) << 16);
				tmp1 = buf.charCodeAt( 2) | (buf.charCodeAt( 3) << 16);
				tmp2 = buf.charCodeAt( 4) | (buf.charCodeAt( 5) << 16);
				tmp3 = buf.charCodeAt( 6) | (buf.charCodeAt( 7) << 16);
				tmp4 = buf.charCodeAt( 8) | (buf.charCodeAt( 9) << 16);
				tmp5 = buf.charCodeAt(10) | (buf.charCodeAt(11) << 16);
				tmp6 = buf.charCodeAt(12) | (buf.charCodeAt(13) << 16);
				tmp7 = buf.charCodeAt(14) | (buf.charCodeAt(15) << 16);
				tmp8 = buf.charCodeAt(16) | (buf.charCodeAt(17) << 16);
				tmp9 = buf.charCodeAt(18) | (buf.charCodeAt(19) << 16);
				tmpa = buf.charCodeAt(20) | (buf.charCodeAt(21) << 16);
				tmpb = buf.charCodeAt(22) | (buf.charCodeAt(23) << 16);
				tmpc = buf.charCodeAt(24) | (buf.charCodeAt(25) << 16);
				tmpd = buf.charCodeAt(26) | (buf.charCodeAt(27) << 16);
				tmpe = buf.charCodeAt(28) | (buf.charCodeAt(29) << 16);
				tmpf = buf.charCodeAt(30) | (buf.charCodeAt(31) << 16);
			}

			a += tmp0 + 0xd76aa478 + ((b & c) | (~b & d)); a = b + ((a <<  7) | (a >>> 25));
			d += tmp1 + 0xe8c7b756 + ((a & b) | (~a & c)); d = a + ((d << 12) | (d >>> 20));
			c += tmp2 + 0x242070db + ((d & a) | (~d & b)); c = d + ((c << 17) | (c >>> 15));
			b += tmp3 + 0xc1bdceee + ((c & d) | (~c & a)); b = c + ((b << 22) | (b >>> 10));
			a += tmp4 + 0xf57c0faf + ((b & c) | (~b & d)); a = b + ((a <<  7) | (a >>> 25));
			d += tmp5 + 0x4787c62a + ((a & b) | (~a & c)); d = a + ((d << 12) | (d >>> 20));
			c += tmp6 + 0xa8304613 + ((d & a) | (~d & b)); c = d + ((c << 17) | (c >>> 15));
			b += tmp7 + 0xfd469501 + ((c & d) | (~c & a)); b = c + ((b << 22) | (b >>> 10));
			a += tmp8 + 0x698098d8 + ((b & c) | (~b & d)); a = b + ((a <<  7) | (a >>> 25));
			d += tmp9 + 0x8b44f7af + ((a & b) | (~a & c)); d = a + ((d << 12) | (d >>> 20));
			c += tmpa + 0xffff5bb1 + ((d & a) | (~d & b)); c = d + ((c << 17) | (c >>> 15));
			b += tmpb + 0x895cd7be + ((c & d) | (~c & a)); b = c + ((b << 22) | (b >>> 10));
			a += tmpc + 0x6b901122 + ((b & c) | (~b & d)); a = b + ((a <<  7) | (a >>> 25));
			d += tmpd + 0xfd987193 + ((a & b) | (~a & c)); d = a + ((d << 12) | (d >>> 20));
			c += tmpe + 0xa679438e + ((d & a) | (~d & b)); c = d + ((c << 17) | (c >>> 15));
			b += tmpf + 0x49b40821 + ((c & d) | (~c & a)); b = c + ((b << 22) | (b >>> 10));
			a += tmp1 + 0xf61e2562 + ((b & d) | (c & ~d)); a = b + ((a <<  5) | (a >>> 27));
			d += tmp6 + 0xc040b340 + ((a & c) | (b & ~c)); d = a + ((d <<  9) | (d >>> 23));
			c += tmpb + 0x265e5a51 + ((d & b) | (a & ~b)); c = d + ((c << 14) | (c >>> 18));
			b += tmp0 + 0xe9b6c7aa + ((c & a) | (d & ~a)); b = c + ((b << 20) | (b >>> 12));
			a += tmp5 + 0xd62f105d + ((b & d) | (c & ~d)); a = b + ((a <<  5) | (a >>> 27));
			d += tmpa + 0x02441453 + ((a & c) | (b & ~c)); d = a + ((d <<  9) | (d >>> 23));
			c += tmpf + 0xd8a1e681 + ((d & b) | (a & ~b)); c = d + ((c << 14) | (c >>> 18));
			b += tmp4 + 0xe7d3fbc8 + ((c & a) | (d & ~a)); b = c + ((b << 20) | (b >>> 12));
			a += tmp9 + 0x21e1cde6 + ((b & d) | (c & ~d)); a = b + ((a <<  5) | (a >>> 27));
			d += tmpe + 0xc33707d6 + ((a & c) | (b & ~c)); d = a + ((d <<  9) | (d >>> 23));
			c += tmp3 + 0xf4d50d87 + ((d & b) | (a & ~b)); c = d + ((c << 14) | (c >>> 18));
			b += tmp8 + 0x455a14ed + ((c & a) | (d & ~a)); b = c + ((b << 20) | (b >>> 12));
			a += tmpd + 0xa9e3e905 + ((b & d) | (c & ~d)); a = b + ((a <<  5) | (a >>> 27));
			d += tmp2 + 0xfcefa3f8 + ((a & c) | (b & ~c)); d = a + ((d <<  9) | (d >>> 23));
			c += tmp7 + 0x676f02d9 + ((d & b) | (a & ~b)); c = d + ((c << 14) | (c >>> 18));
			b += tmpc + 0x8d2a4c8a + ((c & a) | (d & ~a)); b = c + ((b << 20) | (b >>> 12));
			a += tmp5 + 0xfffa3942 + ((b ^ c) ^ d); a = b + ((a <<  4) | (a >>> 28));
			d += tmp8 + 0x8771f681 + ((a ^ b) ^ c); d = a + ((d << 11) | (d >>> 21));
			c += tmpb + 0x6d9d6122 + ((d ^ a) ^ b); c = d + ((c << 16) | (c >>> 16));
			b += tmpe + 0xfde5380c + ((c ^ d) ^ a); b = c + ((b << 23) | (b >>>  9));
			a += tmp1 + 0xa4beea44 + ((b ^ c) ^ d); a = b + ((a <<  4) | (a >>> 28));
			d += tmp4 + 0x4bdecfa9 + ((a ^ b) ^ c); d = a + ((d << 11) | (d >>> 21));
			c += tmp7 + 0xf6bb4b60 + ((d ^ a) ^ b); c = d + ((c << 16) | (c >>> 16));
			b += tmpa + 0xbebfbc70 + ((c ^ d) ^ a); b = c + ((b << 23) | (b >>>  9));
			a += tmpd + 0x289b7ec6 + ((b ^ c) ^ d); a = b + ((a <<  4) | (a >>> 28));
			d += tmp0 + 0xeaa127fa + ((a ^ b) ^ c); d = a + ((d << 11) | (d >>> 21));
			c += tmp3 + 0xd4ef3085 + ((d ^ a) ^ b); c = d + ((c << 16) | (c >>> 16));
			b += tmp6 + 0x04881d05 + ((c ^ d) ^ a); b = c + ((b << 23) | (b >>>  9));
			a += tmp9 + 0xd9d4d039 + ((b ^ c) ^ d); a = b + ((a <<  4) | (a >>> 28));
			d += tmpc + 0xe6db99e5 + ((a ^ b) ^ c); d = a + ((d << 11) | (d >>> 21));
			c += tmpf + 0x1fa27cf8 + ((d ^ a) ^ b); c = d + ((c << 16) | (c >>> 16));
			b += tmp2 + 0xc4ac5665 + ((c ^ d) ^ a); b = c + ((b << 23) | (b >>>  9));
			a += tmp0 + 0xf4292244 + (c ^ (~d | b)); a = b + ((a <<  6) | (a >>> 26));
			d += tmp7 + 0x432aff97 + (b ^ (~c | a)); d = a + ((d << 10) | (d >>> 22));
			c += tmpe + 0xab9423a7 + (a ^ (~b | d)); c = d + ((c << 15) | (c >>> 17));
			b += tmp5 + 0xfc93a039 + (d ^ (~a | c)); b = c + ((b << 21) | (b >>> 11));
			a += tmpc + 0x655b59c3 + (c ^ (~d | b)); a = b + ((a <<  6) | (a >>> 26));
			d += tmp3 + 0x8f0ccc92 + (b ^ (~c | a)); d = a + ((d << 10) | (d >>> 22));
			c += tmpa + 0xffeff47d + (a ^ (~b | d)); c = d + ((c << 15) | (c >>> 17));
			b += tmp1 + 0x85845dd1 + (d ^ (~a | c)); b = c + ((b << 21) | (b >>> 11));
			a += tmp8 + 0x6fa87e4f + (c ^ (~d | b)); a = b + ((a <<  6) | (a >>> 26));
			d += tmpf + 0xfe2ce6e0 + (b ^ (~c | a)); d = a + ((d << 10) | (d >>> 22));
			c += tmp6 + 0xa3014314 + (a ^ (~b | d)); c = d + ((c << 15) | (c >>> 17));
			b += tmpd + 0x4e0811a1 + (d ^ (~a | c)); b = c + ((b << 21) | (b >>> 11));
			a += tmp4 + 0xf7537e82 + (c ^ (~d | b)); a = b + ((a <<  6) | (a >>> 26));
			d += tmpb + 0xbd3af235 + (b ^ (~c | a)); d = a + ((d << 10) | (d >>> 22));
			c += tmp2 + 0x2ad7d2bb + (a ^ (~b | d)); c = d + ((c << 15) | (c >>> 17));
			b += tmp9 + 0xeb86d391 + (d ^ (~a | c)); b = c + ((b << 21) | (b >>> 11));

			this.a_ = (this.a_ + a) & 0xffffffff;
			this.b_ = (this.b_ + b) & 0xffffffff;
			this.c_ = (this.c_ + c) & 0xffffffff;
			this.d_ = (this.d_ + d) & 0xffffffff;
		},

		fillzero : function(size) {
			var buf = "";
			for (var i = 0; i < size; i++) {
				buf += "\x00";
			}
			return buf;
		},

		main : function(buf, bufSize, update, self, charSize) {
			if (charSize == 1) {
				var totalBitSize = bufSize * 8;
				while (bufSize >= 64) {
					self[update](buf, charSize);
					buf = buf.substr(64);
					bufSize -= 64;
				}
				buf +="\x80";
				if (bufSize >= 56) {
					buf += this.fillzero(63 - bufSize);
					self[update](buf, charSize);
					buf = this.fillzero(56);
				} else {
					buf += this.fillzero(55 - bufSize);
				}
				buf += String.fromCharCode(totalBitSize & 0xff, (totalBitSize >>> 8) & 0xff, (totalBitSize >>> 16) & 0xff, totalBitSize >>> 24);
				buf += "\x00\x00\x00\x00"; // in stead of (totalBitSize) >> 32
				self[update](buf, charSize);
			} else {
				/* charSize == 2 */
				var totalBitSize = bufSize * 16;
				while (bufSize >= 32) {
					self[update](buf, charSize);
					buf = buf.substr(32);
					bufSize -= 32;
				}
				buf +="\x80";
				if (bufSize >= 28) {
					buf += this.fillzero(31 - bufSize);
					self[update](buf, charSize);
					buf = this.fillzero(28);
				} else {
					buf += this.fillzero(27 - bufSize);
				}
				buf += String.fromCharCode(totalBitSize & 0xffff, totalBitSize >>> 16);
				buf += "\x00\x00"; // in stead of (totalBitSize) >> 32
				self[update](buf, charSize);
			}
		},

		VERSION : "1.0",
		BY_ASCII : 0,
		BY_UTF16 : 1,

		calc_Fx : function(msg, mode) {
			var charSize = (arguments.length == 2 && mode == this.BY_UTF16) ? 2 : 1;
			this.a_ = [0x2301, 0x6745];
			this.b_ = [0xab89, 0xefcd];
			this.c_ = [0xdcfe, 0x98ba];
			this.d_ = [0x5476, 0x1032];
			this.main(msg, msg.length, "update_Fx", this, charSize);
			return this.int2hex8_Fx(this.a_) + this.int2hex8_Fx(this.b_) + this.int2hex8_Fx(this.c_) + this.int2hex8_Fx(this.d_);
		},

		calc_std : function(msg, mode) {
			var charSize = (arguments.length == 2 && mode == this.BY_UTF16) ? 2 : 1;
			this.a_ = 0x67452301;
			this.b_ = 0xefcdab89;
			this.c_ = 0x98badcfe;
			this.d_ = 0x10325476;
			this.main(msg, msg.length, "update_std", this, charSize);
			return this.int2hex8(this.a_) + this.int2hex8(this.b_) + this.int2hex8(this.c_) + this.int2hex8(this.d_);
		}
	} // end of MD5
}; // end of CybozuLabs

new function() {
	CybozuLabs.MD5.calc = navigator.userAgent.match(/Firefox/) ? CybozuLabs.MD5.calc_Fx : CybozuLabs.MD5.calc_std;
};



//** Smooth Navigational Menu- By Dynamic Drive DHTML code library: http://www.dynamicdrive.com
//** Script Download/ instructions page: http://www.dynamicdrive.com/dynamicindex1/ddlevelsmenu/
//** Menu created: Nov 12, 2008

//** Dec 12th, 08" (v1.01): Fixed Shadow issue when multiple LIs within the same UL (level) contain sub menus: http://www.dynamicdrive.com/forums/showthread.php?t=39177&highlight=smooth

//** Feb 11th, 09" (v1.02): The currently active main menu item (LI A) now gets a CSS class of ".selected", including sub menu items.

//** May 1st, 09" (v1.3):
//** 1) Now supports vertical (side bar) menu mode- set "orientation" to 'v'
//** 2) In IE6, shadows are now always disabled

//** July 27th, 09" (v1.31): Fixed bug so shadows can be disabled if desired.
//** Feb 2nd, 10" (v1.4): Adds ability to specify delay before sub menus appear and disappear, respectively. See showhidedelay variable below

//** Dec 17th, 10" (v1.5): Updated menu shadow to use CSS3 box shadows when the browser is FF3.5+, IE9+, Opera9.5+, or Safari3+/Chrome. Only .js file changed.

var ddsmoothmenu={

//Specify full URL to down and right arrow images (23 is padding-right added to top level LIs with drop downs):
arrowimages: {down:['downarrowclass', 'down.gif', 23], right:['rightarrowclass', 'right.gif']},
transition: {overtime:300, outtime:300}, //duration of slide in/ out animation, in milliseconds
shadow: {enable:true, offsetx:0, offsety:0}, //enable shadow?
showhidedelay: {showdelay: 100, hidedelay: 200}, //set delay in milliseconds before sub menus appear and disappear, respectively

///////Stop configuring beyond here///////////////////////////

detectwebkit: navigator.userAgent.toLowerCase().indexOf("applewebkit")!=-1, //detect WebKit browsers (Safari, Chrome etc)
detectie6: document.all && !window.XMLHttpRequest,
css3support: window.msPerformance || (!document.all && document.querySelector), //detect browsers that support CSS3 box shadows (ie9+ or FF3.5+, Safari3+, Chrome etc)

getajaxmenu:function($, setting){ //function to fetch external page containing the panel DIVs
	var $menucontainer=$('#'+setting.contentsource[0]) //reference empty div on page that will hold menu
	$menucontainer.html("Loading Menu...")
	$.ajax({
		url: setting.contentsource[1], //path to external menu file
		async: true,
		error:function(ajaxrequest){
			$menucontainer.html('Error fetching content. Server Response: '+ajaxrequest.responseText)
		},
		success:function(content){
			$menucontainer.html(content)
			ddsmoothmenu.buildmenu($, setting)
		}
	})
},


buildmenu:function($, setting){
	var smoothmenu=ddsmoothmenu
	var $mainmenu=$("#"+setting.mainmenuid+">ul") //reference main menu UL

	var $headers=$mainmenu.find("ul").parent()
	$headers.hover(
		function(e){
			$(this).children('a:eq(0)').addClass('selected')
		},
		function(e){
			$(this).children('a:eq(0)').removeClass('selected')
		}
	)
	$headers.each(function(i){ //loop through each LI header
		var $curobj=$(this).css({zIndex: 100-i}) //reference current LI header
		var $subul=$(this).find('ul:eq(0)').css({display:'block'})
		$subul.data('timers', {})
		this._dimensions={w:this.offsetWidth, h:this.offsetHeight, subulw:$subul.outerWidth(), subulh:$subul.outerHeight()}
		this.istopheader=$curobj.parents("ul").length==1? true : false //is top level header?
		$subul.css({top:this.istopheader && setting.orientation!='v'? this._dimensions.h+"px" : 0})
		if (smoothmenu.shadow.enable && !smoothmenu.css3support){ //if shadows enabled and browser doesn't support CSS3 box shadows
			this._shadowoffset={x:(this.istopheader?$subul.offset().left+smoothmenu.shadow.offsetx : this._dimensions.w), y:(this.istopheader? $subul.offset().top+smoothmenu.shadow.offsety : $curobj.position().top)} //store this shadow's offsets
			if (this.istopheader)
				$parentshadow=$(document.body)
			else{
				var $parentLi=$curobj.parents("li:eq(0)")
				$parentshadow=$parentLi.get(0).$shadow
			}
			this.$shadow=$('<div class="ddshadow'+(this.istopheader? ' toplevelshadow' : '')+'"></div>').prependTo($parentshadow).css({left:this._shadowoffset.x+'px', top:this._shadowoffset.y+'px'})  //insert shadow DIV and set it to parent node for the next shadow div
		}
		$curobj.hover(
			function(e){
				var $targetul=$subul //reference UL to reveal
				var header=$curobj.get(0) //reference header LI as DOM object
				clearTimeout($targetul.data('timers').hidetimer)
				$targetul.data('timers').showtimer=setTimeout(function(){
					header._offsets={left:$curobj.offset().left, top:$curobj.offset().top}
					var menuleft=header.istopheader && setting.orientation!='v'? 0 : header._dimensions.w
					menuleft=(header._offsets.left+menuleft+header._dimensions.subulw>$(window).width())? (header.istopheader && setting.orientation!='v'? -header._dimensions.subulw+header._dimensions.w : -header._dimensions.w) : menuleft //calculate this sub menu's offsets from its parent
					if ($targetul.queue().length<=1){ //if 1 or less queued animations
						$targetul.css({left:menuleft+"px", width:header._dimensions.subulw+'px'}).animate({height:'show',opacity:'show'}, ddsmoothmenu.transition.overtime)
						if (smoothmenu.shadow.enable && !smoothmenu.css3support){
							var shadowleft=header.istopheader? $targetul.offset().left+ddsmoothmenu.shadow.offsetx : menuleft
							var shadowtop=header.istopheader?$targetul.offset().top+smoothmenu.shadow.offsety : header._shadowoffset.y
							if (!header.istopheader && ddsmoothmenu.detectwebkit){ //in WebKit browsers, restore shadow's opacity to full
								header.$shadow.css({opacity:1})
							}
							header.$shadow.css({overflow:'', width:header._dimensions.subulw+'px', left:shadowleft+'px', top:shadowtop+'px'}).animate({height:header._dimensions.subulh+'px'}, ddsmoothmenu.transition.overtime)
						}
					}
				}, ddsmoothmenu.showhidedelay.showdelay)
			},
			function(e){
				var $targetul=$subul
				var header=$curobj.get(0)
				clearTimeout($targetul.data('timers').showtimer)
				$targetul.data('timers').hidetimer=setTimeout(function(){
					$targetul.animate({height:'hide', opacity:'hide'}, ddsmoothmenu.transition.outtime)
					if (smoothmenu.shadow.enable && !smoothmenu.css3support){
						if (ddsmoothmenu.detectwebkit){ //in WebKit browsers, set first child shadow's opacity to 0, as "overflow:hidden" doesn't work in them
							header.$shadow.children('div:eq(0)').css({opacity:0})
						}
						header.$shadow.css({overflow:'hidden'}).animate({height:0}, ddsmoothmenu.transition.outtime)
					}
				}, ddsmoothmenu.showhidedelay.hidedelay)
			}
		) //end hover
	}) //end $headers.each()
	if (smoothmenu.shadow.enable && smoothmenu.css3support){ //if shadows enabled and browser supports CSS3 shadows
		var $toplevelul=$('#'+setting.mainmenuid+' ul li ul')
		var css3shadow=parseInt(smoothmenu.shadow.offsetx)+"px "+parseInt(smoothmenu.shadow.offsety)+"px 0px #aaa" //construct CSS3 box-shadow value
		var shadowprop=["boxShadow", "MozBoxShadow", "WebkitBoxShadow", "MsBoxShadow"] //possible vendor specific CSS3 shadow properties
		for (var i=0; i<shadowprop.length; i++){
			$toplevelul.css(shadowprop[i], css3shadow)
		}
	}
	$mainmenu.find("ul").css({display:'none', visibility:'visible'})
},

init:function(setting){
	if (typeof setting.customtheme=="object" && setting.customtheme.length==2){ //override default menu colors (default/hover) with custom set?
		var mainmenuid='#'+setting.mainmenuid
		var mainselector=(setting.orientation=="v")? mainmenuid : mainmenuid+', '+mainmenuid
		document.write('<style type="text/css">\n'
			+mainselector+' ul li a {background:'+setting.customtheme[0]+';}\n'
			+mainmenuid+' ul li a:hover {background:'+setting.customtheme[1]+';}\n'
		+'</style>')
	}
	this.shadow.enable=(document.all && !window.XMLHttpRequest)? false : this.shadow.enable //in IE6, always disable shadow
	jQuery(document).ready(function($){ //ajax menu?
		if (typeof setting.contentsource=="object"){ //if external ajax menu
			ddsmoothmenu.getajaxmenu($, setting)
		}
		else{ //else if markup menu
			ddsmoothmenu.buildmenu($, setting)
		}
	})
}

} //end ddsmoothmenu variable
