text:
/**
 * TODO: make NotesCC::notes a map<id, Note *> instead of list?
 */

#include <iostream>
#include <algorithm>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string>
#include <cstring>
#include <list>
#include <map>

#include <Project.h>
#include <Note.h>
#include <Colors.h>
#include <TableView.h>
#include <IDStorage.h>
#include <Filter.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>

// Readline
#include <readline/readline.h>
#include <readline/history.h>

#include <Settings.h>

struct timespec _tick_start;
struct timespec _tick_stop;

#define INIT_TIC_TAC()    { clock_gettime ( CLOCK_REALTIME, &_tick_start ); }

#define TIC( a )          {                                                              \
        clock_gettime ( CLOCK_REALTIME, &_tick_stop );                                   \
        timespec diff;                                                                   \
        diff.tv_sec  = _tick_stop.tv_sec - _tick_start.tv_sec;                           \
        diff.tv_nsec = _tick_stop.tv_nsec - _tick_start.tv_nsec;                         \
        if ( diff.tv_nsec < 0 ) {                                                        \
            diff.tv_sec  -= 1;                                                           \
            diff.tv_nsec += 1e9;                                                         \
        }                                                                                \
        notes_print_info ( "%s: %lu s, %.2f ms\n", a, diff.tv_sec, diff.tv_nsec / 1e6 ); \
}

// List of supported commands.
const char * commands[] =
{
    "add",
    "move",
    "edit",
    "view",
    "cat",
    "list",
    "export",
    "import",
    "delete",
    "projects",
    "interactive",
    "pull",
    "push",
    "sync",
    "archive",
    nullptr
};

/**
 * This project is written in C++, but tries to stick closer to C.
 * Classes, list, strings are ok.. Templates only when it safes duplication.
 */

// The Main object, this is also the root node.
class NotesCC : public Project
{
private:
// Root project.
    std::vector<Note *> notes;

    bool                require_sync = false;
    bool                git_changed  = false;
    IDStorage           *storage     = nullptr;
    Settings            settings;

    // Output settings.
    bool show_archive = false;

public:
    NotesCC( )  : Project ( "" )
    {
    }
    ~NotesCC()
    {
        // Commit lingering changes.
        if ( git_changed ) {
            notes_print_info ( "Commiting changes to git.\n" );
            repository_commit_changes ();
            require_sync = true;
            git_changed  = false;
        }
        // Push it when needed.
        //    @TODO add message sync needed.

        if ( storage != nullptr ) {
            delete storage;
            storage = nullptr;
        }

        // Clear internal state.
        clear ();
        if ( require_sync ) {
            notes_print_info ( color_yellow "Sync required\n" color_reset );
        }
    }
    void pre_parse_settings ( int &argc, char **argv )
    {
        // Set quiet.
        if ( argc > 1 && strcmp ( argv[1], "--complete" ) == 0 ) {
            notes_print_quiet ();
        }
        for ( int index = 1; index < argc; index++ ) {
            if ( strcmp ( argv[index], "--repo" ) == 0 && argc > ( index + 1 ) ) {
                std::string repo_path = argv[index + 1];

                settings.set_repository ( repo_path );
                memmove ( &argv[index], &argv[index + 2], sizeof ( char* ) * ( argc - index ) );
                argc  -= 2;
                index -= 2;
            }
        }
    }

    void run ( int argc, char **argv )
    {
        // Check interactive mode.
        if ( argc == 2 && strcmp ( argv[1], "interactive" ) == 0 ) {
            notes_print_info ( "Interactive mode\n" );
            interactive ();
        }
        else if  ( argc >= 2 && strcmp ( argv[1], "sync" ) == 0 ) {
            notes_print_info ( "Checking for and pulling changes from remote repository.\n" );
            this->repository_pull ();
            this->check_sync_required ();
            this->repository_push ();
        }
        else if ( argc >= 2 && strcmp ( argv[1], "pull" ) == 0 ) {
            this->repository_pull ();
        }
        else if ( argc >= 2 && strcmp ( argv[1], "push" ) == 0 ) {
            this->repository_push ();
        }

        // Check autocomplete.
        else if ( argc > 1 && strcmp ( argv[1], "--complete" ) == 0 ) {
            run_autocomplete ( argc - 1, &argv[1] );
        }

        // Commandline parser
        else {
            cmd_parser ( argc - 1, &argv[1] );
        }
    }

    bool initial_setup ()
    {
        std::string repo_path = this->get_path ();
        // Do intro
        notes_print_info ( "Do you want Notes.CC to initialize this directory?\n" );
        char *response = readline ( "(y/n): " );
        if ( response && strcmp ( response, "y" ) == 0 ) {
            // Try to make directory.
            if ( mkdir ( repo_path.c_str (), 0750 ) != 0 ) {
                if ( errno != EEXIST ) {
                    notes_print_error ( "Failed to create directory: %s\n", strerror ( errno ) );
                    return true;
                }
            }
            const char *const args[] = { "git", "-C", repo_path.c_str (), "init", NULL };
            auto              cur    = exec_command ( args );
            if ( cur != 0  ) {
                return true;
            }
        }
        {
            const char * const args[] = { "git", "-C", repo_path.c_str (), "config", "user.name", NULL };
            auto               val    = exec_command_read_result ( "git", args );
            if ( val.size () == 0 ) {
                const char * const args2[] = { "git", "-C", repo_path.c_str (), "config", "user.name", "Notes.CC", NULL };
                exec_command ( args2 );
            }
        }
        {
            const char *const args[] = { "git", "-C", repo_path.c_str (), "config", "user.email", NULL };
            auto              val    = exec_command_read_result ( "git", args );
            if ( val.size () == 0 ) {
                const char *const args2[] = { "git", "-C", repo_path.c_str (), "config", "user.email", "note@Notes.CC", NULL };
                exec_command ( args2 );
            }
        }
        /** Check for user.name and user.email */
        return false;
    }

    /**
     * Open the note repository.
     */
    bool open_repository ( )
    {
        std::string       repo_path = this->get_path ();
        const char *const argsc[]   = { "git",
                                        "-C",                   repo_path.c_str (),
                                        "rev-parse",
                                        "--is-inside-work-tree",
                                        NULL };
        auto              isdir = exec_command_read_result ( "git", argsc );
        if ( strcasecmp ( isdir.c_str (), "true" ) != 0 ) {
            notes_print_error ( "Notes directory '%s' is not a valid repository\n", repo_path.c_str () );
            if ( initial_setup () ) {
                notes_print_error ( "Failed to initialize, giving up.\n" );
                return false;
            }
        }
        // Create the ID storage->
        if ( storage == nullptr ) {
            storage = new IDStorage ( settings.get_repository () );
        }
        this->check_sync_required ();
        this->Load ( );
        return true;
    }

private:
    void check_sync_required ( void )
    {
        const std::string &repo_path = this->get_path ();
        const char *const  args[]    = { "git",
                                         "-C",       repo_path.c_str (),
                                         "rev-parse",
                                         "@{0}",
                                         NULL };
        auto               cur     = exec_command_read_result ( "git", args );
        const char *const  args1[] = { "git",
                                       "-C",       repo_path.c_str (),
                                       "rev-parse",
                                       "@{u}",
                                       NULL };
        auto               up = exec_command_read_result ( "git", args1 );
        this->require_sync = false;
        if ( up.size () == 0 ) {
            // this->has_upstream = false;
        }
        else if ( cur != up ) {
            this->require_sync = true;
        }
    }
    /**
     * This function is used to sort the notes and assign them an id.
     * Sorting should be stable between runs (when there is no edit of note).
     */
    static bool notes_print_sort ( Note *a, Note *b )
    {
        time_t diff_time = ( a->get_time_t () - b->get_time_t () );
        // If they are of equal time.
        if ( diff_time == 0 ) {
            int retv = a->get_title ().compare ( b->get_title () );
            if ( retv < 0 ) {
                return true;
            }
            // Sort on hash as a last resort, so we get a stable sort.
            return a->get_body_crc () - b->get_body_crc () > 0;
        }
        // If A is later then b it should go above a.
        return diff_time < 0;
    }

    /**
     * Repository interaction functions.
     */
    int exec_command ( const char *const argv[] )
    {
        char  **args = strvdup ( argv );
        pid_t pid;

        switch ( pid = vfork () )
        {
        case -1:    /* Error */
            notes_print_error ( "Failed to run %s: %s\n", argv[0], strerror ( errno ) );
            strfreev ( args );
            return 1;
        case 0:     /* child */
        {
            close ( STDIN_FILENO );
            close ( STDOUT_FILENO );
            close ( STDERR_FILENO );
            execvp ( args[0], args );
        }
            _exit ( 127 );
        default:
            break;
        }
        int status = 0;
        // Wait until client is done.
        if ( pid > 0 ) {
            waitpid ( pid, &status, 0 );
        }
        strfreev ( args );
        return WEXITSTATUS ( status );
    }
    // Used to reap child.
    static void sigchld ( int i )
    {
        wait ( 0 );
    }

    // Merge this with the other file open.
    bool exec_with_pipes ( int &fdout, int &fderr, const char * const argv[] )
    {
        char  **args = strvdup ( argv );
        int   fds[2];
        pid_t pid;

        if ( pipe2 ( fds, O_CLOEXEC ) < 0 ) {
            // Failed to create pipes.. @TODO throw internal error.
            strfreev ( args );
            return false;
        }

        signal ( SIGCHLD, sigchld );

        switch ( pid = vfork () )
        {
        case -1:                /* Error */
            close ( fds[0] );
            close ( fds[1] );
            strfreev ( args );
            return false;
        case 0:                 /* child */
        {
            close ( fds[0] );
            // Don't want to inherit stdin or stderr.
            // @TODO handle stdout later.
            close ( STDIN_FILENO );
            close ( STDERR_FILENO );
            dup2 ( fds[1], STDOUT_FILENO );
            close ( fds[1] );
            execvp ( args[0], args );
            _exit ( 127 );
        }
        default:
            break;
        }
        /* parent */
        close ( fds[1] );
        fdout = fds[0];
        strfreev ( args );
        return true;
    }
    std::string exec_command_read_result ( const char *cmd, const char *const args[] )
    {
        int         fdout = -1, fderr = -1;
        std::string retv;
        if ( !exec_with_pipes ( fdout, fderr, args ) ) {
            return retv;
        }
        char buffer[1024];
        while ( 1 ) {
            ssize_t count = read ( fdout, buffer, 1024 );
            if ( count == -1 ) {
                if ( errno == EINTR ) {
                    continue;
                }
                else {
                    perror ( "read" );
                    break;
                }
            }
            else if ( count == 0 ) {
                break;
            }
            else {
                buffer[count] = '\0';
                retv         += buffer;
            }
        }
        if ( fdout >= 0 ) {
            close ( fdout );
        }
        else if ( fderr >= 0 ) {
            close ( fderr );
        }
        // Strip newline.
        if ( retv[retv.size () - 1] == '\n' ) {
            retv[retv.size () - 1] = '\0';
        }
        return retv;
    }

    void repository_delete_file ( std::string path )
    {
        std::string       repo_path = this->get_path ();
        notes_print_info ( "Delete file: %s\n", path.c_str () );
        const char *const args[] = { "git",
                                     "-C",         repo_path.c_str (),
                                     "rm",         "--cached",
                                     path.c_str (),
                                     NULL };
        int               retv = exec_command ( args );
        if ( retv != 0 ) {
            notes_print_error ( "Failed add changes to index.\n" );
        }
        git_changed = true;
    }
    void repository_stage_file ( std::string path )
    {
        notes_print_info ( "Staging file: %s\n", path.c_str () );

        std::string       repo_path = this->get_path ();
        const char *const args[]    = { "git",
                                        "-C",    repo_path.c_str (),
                                        "add",   path.c_str (),
                                        NULL };
        int               retv = exec_command ( args );
        if ( retv != 0 ) {
            notes_print_error ( "Failed add changes to index.\n" );
        }
        git_changed = true;
    }

    bool repository_commit_changes ( )
    {
        std::string       repo_path = this->get_path ();
        const char *const args[]    = { "git",
                                        "-C",    repo_path.c_str (),
                                        "commit",
                                        "-m",    "Updates",
                                        NULL };
        int               retv = exec_command  ( args );
        if ( retv != 0 ) {
            notes_print_error ( "Failed commit\n" );
            return false;
        }
        return true;
    }

    bool repository_push ()
    {
        if ( this->require_sync ) {
            notes_print_info ( "Pushing local changes to server.\n" );
            std::string       path   = this->get_path ();
            const char *const args[] = { "git", "-C", path.c_str (), "push", NULL };
            int               retv   = exec_command ( args );
            this->require_sync = false;
            return retv == 0;
        }
        return false;
    }
    bool repository_pull ( )
    {
        std::string       path   = this->get_path ();
        const char *const args[] = { "git", "-C", path.c_str (), "pull", NULL };
        int               retv   = exec_command ( args );
        if ( retv == 0 ) {
            // TODO: check return value.
            this->clear ();
            this->Load ();
        }
        return retv == 0;
    }

    void clear ()
    {
        // delete notes.
        for ( auto note : notes ) {
            if ( note != nullptr ) {
                delete note;
            }
        }
        notes.clear ();
        for ( auto project : child_projects ) {
            delete project;
        }
        child_projects.clear ();
    }

    std::string get_path ()
    {
        return settings.get_repository ();
    }

    std::string get_relative_path ()
    {
        return "";
    }

    /**
     * Get the index based on id.
     */
    int get_note_index ( unsigned int id )
    {
        for ( unsigned int index = 0; index < notes.size (); index++ ) {
            if ( notes[index]->get_id () == id ) {
                return index;
            }
        }
        return -1;
    }

    template < class T>
    void display_notes ( const T view_notes )
    {
        TableView view;

        // Add the columns
        view.add_column ( "ID", color_bold );
        view[0].set_right_align ();
        view.add_column ( "Rev.", color_blue );
        view[1].set_right_align ();
        view.add_column ( "Project", color_magenta );
        view.add_column ( "Last edited", color_green );
        view.add_column ( "Description" );

        unsigned int row_index = 0;
        for ( auto note : view_notes ) {
            // Skip empty elements.
            if ( note == nullptr ) {
                continue;
            }
            view[0].set_value ( row_index, std::to_string ( note->get_id () ) );
            if ( note->get_revision () > 0 ) {
                view[1].set_value ( row_index, std::to_string ( note->get_revision () ) );
            }
            else{
                view[1].set_value ( row_index, "" );
            }
            view[2].set_value ( row_index, note->get_project_name () );
            view[3].set_value ( row_index, note->get_modtime () );
            view[4].set_value ( row_index, note->get_title () );
            view++;
            row_index++;
        }
        view.print ();
    }

    Note * get_note ( int argc, char ** argv )
    {
        if ( argc == 1 ) {
            // Get index.
            try {
                unsigned int note_id = std::stoul ( argv[0] );
                int          nindex  = this->get_note_index ( note_id );
                if ( nindex >= 0 ) {
                    return notes[nindex];
                }
                notes_print_error ( "Invalid note id: %d\n", nindex );
            } catch ( ... ) {
            }
        }

        if ( argc == 1 ) {
            // Get the last note.
            if ( strcasecmp ( argv[0], "last" ) == 0 ) {
                if ( this->notes.size () > 0 ) {
                    return this->notes[this->notes.size () - 1];
                }
            }
        }

        NotesFilter filter ( this->notes );
        for ( int iter = 0; iter < argc; iter++ ) {
            filter.add_filter ( argv[iter] );
        }

        // Get filtered notes.
        auto fnotes = filter.get_filtered_notes ();
        if ( fnotes.size () == 0 ) {
            return nullptr;
        }

        // If one note is remaining, pick that one
        else if ( fnotes.size () == 1 ) {
            return *( fnotes.begin () );
        }

        while ( true ) {
            this->display_notes ( fnotes );

            char* resp = readline ( "Enter note id: " );
            if ( resp ) {
                // Quit
                if ( resp[0] == 'q' ) {
                    free ( resp );
                    return nullptr;
                }
                try {
                    unsigned int note_id = std::stoul ( resp );
                    int          nindex  = this->get_note_index ( note_id );
                    if ( nindex >= 0  ) {
                        free ( resp );
                        return this->notes[nindex];
                    }
                }catch ( ... ) { }

                notes_print_error ( "Invalid note id: %s\n", resp );
                free ( resp );
            }
        }
        return nullptr;
    }

    /**
     * @param argc Number of renaming commandline options.
     * @param argv Remaining commandline options.
     *
     * Edit a notes.
     *
     * @returns number of consumed commandline options.
     */
    int command_edit ( int argc, char ** argv )
    {
        Note *note = this->get_note ( argc, argv );
        if ( note == nullptr ) {
            notes_print_error ( "No note selected\n" );
            return argc;
        }
        // Edit the note.
        if ( note->edit () ) {
            // Commit the result.
            auto path = note->get_relative_path ();
            repository_stage_file ( path );
        }

        return argc;
    }

    /**
     * @param argc Number of renaming commandline options.
     * @param argv Remaining commandline options.
     *
     * View a notes.
     *
     * @returns number of consumed commandline options.
     */
    int command_view ( int argc, char ** argv )
    {
        Note *note = this->get_note ( argc, argv );
        if ( note == nullptr ) {
            notes_print_error ( "No note selected\n" );
            return argc;
        }

        note->view ();
        return argc;
    }

    /**
     * @param argc Number of renaming commandline options.
     * @param argv Remaining commandline options.
     *
     * Print the raw note to stdout.
     *
     * @returns number of consumed commandline options.
     */
    int command_cat ( int argc, char ** argv )
    {
        Note *note = this->get_note ( argc, argv );
        if ( note == nullptr ) {
            notes_print_error ( "No note selected\n" );
            return argc;
        }

        note->cat ();
        return argc;
    }

    /**
     * @param argc Number of renaming commandline options.
     * @param argv Remaining commandline options.
     *
     * List the notes.
     *
     * @returns number of consumed commandline options.
     */
    int command_list ( int argc, char ** argv )
    {
        int         iter = 0;
        NotesFilter filter ( this->notes );

        // Ignore archived notes.
        if ( show_archive ) {
            filter.filter_not_archive ();
        }
        else {
            filter.filter_archive ();
        }
        if ( argc > 0 ) {
            for (; iter < argc; iter++ ) {
                filter.add_filter ( argv[iter] );
            }
        }
        this->display_notes ( filter.get_filtered_notes () );
        notes_print_info ( "Number notes: %lu\n", filter.get_filtered_notes ().size () );
        return iter;
    }
    int command_export ( int argc, char **argv )
    {
        if ( argc != 3 ) {
            notes_print_error ( "Export requires three arguments: <note id> <type> <export_file>\n" );
            return 0;
        }

        Note *note = get_note ( 1, argv );
        if ( note == nullptr ) {
            notes_print_error ( "No note specified\n" );
            return 3;
        }

        std::string export_path = argv[2];
        std::string format      = argv[1];

        notes_print_info ( "Exporting note %u to '%s'\n", note->get_id (), argv[2] );

        if ( format == "raw" ) {
            note->export_to_file_raw ( export_path );
        }
        else if ( format == "html" ) {
            note->export_to_file_html ( export_path );
        }
        else {
            notes_print_error ( "%s is an invalid export format. (raw and html are supported)\n",
                                format.c_str () );
        }
        return 3;
    }

    int command_import ( int argc, char **argv )
    {
        if ( argc < 1 ) {
            notes_print_error ( "Import requires atleast one arguments:  <import_file> (<Project>)\n" );
            return argc;
        }
        Project *p = this;
        if ( argc >= 2 ) {
            std::string name = argv[1];
            p = this->get_or_create_project_from_name ( name );
            if ( p == nullptr ) {
                return 2;
            }
        }
        std::string path = argv[0];
        Note        *n   = new Note ( p, &settings );

        if ( n != nullptr ) {
            if ( !n->import ( path ) ) {
                // Failed, clean up again.
                n->del ();
                delete n;
                return 2;
            }
            // Success, add it.
            this->notes.push_back ( n );
            n->set_id ( storage->get_id ( n->get_relative_path () ) );
            auto path = n->get_relative_path ();
            repository_stage_file ( path );
        }
        return 2;
    }

private:

    int command_move ( int argc, char **argv )
    {
        if ( argc < 2 ) {
            notes_print_error ( "Move requires two arguments: <note id>  <project path>\n" );
            return argc;
        }

        Note *note = get_note ( 1, argv );
        if ( note == nullptr ) {
            notes_print_error ( "No note specified\n" );
            return 2;
        }

        std::string name = argv[1];
        Project     *p   = this->get_or_create_project_from_name ( name );
        if ( p == nullptr ) {
            return 2;
        }
        if ( p == note->get_project () ) {
            notes_print_warning ( "Destination same as source: Ignoring.\n" );
            return 2;
        }
        std::string old_path = note->get_relative_path ();
        if ( note->move ( p ) ) {
            std::string new_path = note->get_relative_path ();
            this->repository_stage_file ( new_path );
            this->repository_delete_file ( old_path );
            // Move id
            this->storage->move_id ( old_path, new_path );
        }
        return 2;
    }

    static void command_projects_add_entry ( Project *p, TableView &view, unsigned int &row )
    {
        view[0].set_value ( row, p->get_name () );
        view[1].set_value ( row, std::to_string ( p->get_num_notes () ) );
        view[2].set_value ( row, std::to_string ( p->get_num_notes_recursive () ) );
        row++;
        view++;
        for ( auto pc : p->get_child_projects () ) {
            command_projects_add_entry ( pc, view, row );
        }
    }
    int command_projects ( __attribute__( ( unused ) ) int argc, __attribute__( ( unused ) ) char **argv )
    {
        TableView view;
        view.add_column ( "Project" );
        view.add_column ( "Num. Notes", color_blue );
        view.add_column ( "Total Notes", color_magenta );
        view[1].set_right_align ();
        view[2].set_right_align ();
        unsigned int row = 0;
        for ( auto pc : this->get_child_projects () ) {
            // Filter out archive.
            if ( ( pc->get_name () == "Archive" ) == show_archive ) {
                command_projects_add_entry ( pc, view, row );
            }
        }
        view.print ();
        NotesFilter filter ( this->notes );
        if ( show_archive ) {
            filter.filter_not_archive ();
        }
        else{
            filter.filter_archive ();
        }
        notes_print_info ( "Number notes: %lu\n", filter.get_filtered_notes ().size () );
        notes_print_info ( "Number projects: %lu\n", row );
        return 0;
    }

    void autocomplete_list_notes_ids_and_keywords ()
    {
        for ( auto note : notes ) {
            printf ( "%u\n", note->get_id () );
        }
        if ( notes.size () > 0 ) {
            printf ( "last\n" );
        }
    }

    void command_view_autocomplete ()
    {
        autocomplete_list_notes_ids_and_keywords ();
    }

    void command_edit_autocomplete ()
    {
        autocomplete_list_notes_ids_and_keywords ();
    }

    /**
     * Resolve a normal full project name into the Project pointer.
     * If (sub) projects do not exists, they are created and added.
     *
     * Before adding a note, validate if it exists by calling
     * Project::check_and_create_path().
     */
    Project * get_or_create_project_from_name ( std::string pr )
    {
        Project *p = this;
        if ( pr.empty () ) {
            return p;
        }
        // Split the string.
        size_t str_start = 0;
        while ( str_start < pr.size () ) {
            auto str_end = pr.find_first_of ( '.', str_start );
            if ( str_end == std::string::npos ) {
                str_end = pr.size ();
            }
            auto pr_name = pr.substr ( str_start, str_end - str_start );
            if ( !pr_name.empty () ) {
                // Validate the Project name only consists of characters and numbers.
                if ( find_if ( pr_name.begin (), pr_name.end (),
                               [] ( char c ) {
                                   return !( isalnum ( c ) );
                               } ) != pr_name.end () ) {
                    notes_print_error ( "%s is an invalid Project name.\n", pr_name.c_str () );
                    return nullptr;
                }
                Project *pc = p->find_child ( pr_name );
                if ( pc == nullptr ) {
                    // Create!
                    pc = new Project ( pr_name.c_str () );
                    p->add_subproject ( pc );
                }
                p = pc;
            }

            str_start = str_end + 1;
        }
        return p;
    }
    int command_archive_move ( int argc, char ** argv )
    {
        Note *note = this->get_note ( argc, argv );
        if ( note == nullptr ) {
            notes_print_error ( "No note selected\n" );
            return argc;
        }
        std::string name = "Archive." + note->get_project_name ();
        Project     *p   = this->get_or_create_project_from_name ( name );
        if ( p == nullptr ) {
            notes_print_error ( "Failed to create project by name: %s", name.c_str () );
            return argc;
        }
        if ( p == note->get_project () ) {
            notes_print_warning ( "Destination same as source: Ignoring.\n" );
            return argc;
        }
        std::string old_path = note->get_relative_path ();
        if ( note->move ( p ) ) {
            std::string new_path = note->get_relative_path ();
            this->repository_stage_file ( new_path );
            this->repository_delete_file ( old_path );
            // Move id
            this->storage->move_id ( old_path, new_path );
        }
        return argc;
    }
    int command_archive_restore ( int argc, char ** argv )
    {
        Note *note = this->get_note ( argc, argv );
        if ( note == nullptr ) {
            notes_print_error ( "No note selected\n" );
            return argc;
        }
        const Project *rp = note->get_project ();
        while ( !rp->is_root () ) {
            if ( rp->get_name () == "Archive" ) {
                break;
            }
            rp = rp->get_parent ();
        }
        if ( rp->is_root () ) {
            notes_print_error ( "Note is not archived, cannot restore\n" );
            return argc;
        }
        std::string name     = note->get_relative_project_name ( rp );
        Project     *p       = this->get_or_create_project_from_name ( name );
        std::string old_path = note->get_relative_path ();
        if ( note->move ( p ) ) {
            std::string new_path = note->get_relative_path ();
            this->repository_stage_file ( new_path );
            this->repository_delete_file ( old_path );
            // Move id
            this->storage->move_id ( old_path, new_path );
        }
        return argc;
    }
    int command_archive ( int argc, char **argv )
    {
        show_archive = true;
        if ( argc == 0 ) {
            return this->command_list ( argc, argv );
        }
        if ( strcmp ( argv[0], "move" ) == 0 ) {
            return 1 + command_archive_move ( argc - 1, &argv[1] );;
        }
        else if ( strcmp ( argv[0], "restore" ) == 0 ) {
            return 1 + command_archive_restore ( argc - 1, &argv[1] );;
        }
        return 0;
    }

    int command_delete ( int argc, char **argv )
    {
        Note *note = this->get_note ( argc, argv );
        if ( note == nullptr ) {
            notes_print_error ( "No note selected\n" );
            return argc;
        }

        // Delete the file from internal structure and working directory.
        int nindex = this->get_note_index ( note->get_id () );

        if ( nindex < 0 ) {
            notes_print_error ( "Internal error, note with id: %u does not exist.\n",
                                nindex );
            return argc;
        }

        notes_print_warning ( "Are you sure you want to delete note with title: '%s'\n",
                              note->get_title ().c_str () );
        notes_print_warning ( "Press 'a' to archive note instead.\n" );
        char *response = readline ( "(y/n/a): " );
        if ( response && strcmp ( response, "y" ) == 0 ) {
            notes_print_warning ( "Deleting note\n" );
            std::string path = note->get_relative_path ();
            if ( note->del () ) {
                // Tell git the file is removed.
                repository_delete_file ( path );
                storage->delete_id ( path );
                // Delete the entry from the list.
                delete note;
                notes[nindex] = nullptr;
            }
        }
        else if ( response && strcmp ( response, "a" ) == 0 ) {
            std::string name = "Archive." + note->get_project_name ();
            Project     *p   = this->get_or_create_project_from_name ( name );
            if ( p == nullptr ) {
                notes_print_error ( "Failed to create project by name: %s", name.c_str () );
                return argc;
            }
            if ( p == note->get_project () ) {
                notes_print_warning ( "Destination same as source: Ignoring.\n" );
                return argc;
            }
            std::string old_path = note->get_relative_path ();
            if ( note->move ( p ) ) {
                std::string new_path = note->get_relative_path ();
                this->repository_stage_file ( new_path );
                this->repository_delete_file ( old_path );
                // Move id
                this->storage->move_id ( old_path, new_path );
            }
        }
        else{
            notes_print_info ( "Aborting delete.\n" );
        }
        free ( response );
        return argc;
    }
    int command_add ( int argc, char **argv )
    {
        int     retv = 0;
        Project *p   = this;

        if ( argc > 0 ) {
            p = this->get_or_create_project_from_name ( argv[0] );
            retv++;
        }

        // Check if we have project successful.
        if ( p == nullptr ) {
            notes_print_error ( "Failed to find or create the project.\n" );
            return retv;
        }

        Note *n = new Note ( p, &settings );

        if ( n != nullptr ) {
            this->notes.push_back ( n );
            n->set_id ( storage->get_id ( n->get_relative_path () ) );
            n->edit ();
            // Commit the result.
            auto path = n->get_relative_path ();
            repository_stage_file ( path );
        }

        return retv;
    }

    void command_export_autocomplete ( int argc, __attribute__( ( unused ) ) char **argv  )
    {
        if ( argc == 1 ) {
            autocomplete_list_notes_ids_and_keywords ();
        }
        else if ( argc == 2 ) {
            printf ( "html\nraw\n" );
        }
    }
    void command_move_autocomplete ( int argc, __attribute__ ( ( unused ) ) char **argv )
    {
        if ( argc == 1 ) {
            autocomplete_list_notes_ids_and_keywords ();
        }
        else if ( argc == 2 ) {
            list_projects ();
        }
    }

    /**
     * Implement the autocomplete command.
     */
    void run_autocomplete ( int argc, char **argv )
    {
        if ( argc == 1 ) {
            // List commands.
            for ( int i = 0; commands[i] != nullptr; i++ ) {
                std::cout << commands[i] << std::endl;
            }
            return;
        }
        std::string command = argv[1];
        if ( command == "view" || command == "cat" ) {
            if ( argc == 2 ) {
                this->command_view_autocomplete ();
            }
            return;
        }
        else if ( command == "archive" ) {
            if ( argc >= 3 && std::string ( argv[2] ) == "move" ) {
                if ( argc == 3 ) {
                    autocomplete_list_notes_ids_and_keywords ();
                }
                return;
            }
            else if ( argc >= 3 && std::string ( argv[2] ) == "restore" ) {
                if ( argc == 3 ) {
                    autocomplete_list_notes_ids_and_keywords ();
                }
                return;
            }
            // Archive has restore command.
            std::cout << "restore" << std::endl;
            // This is now just a modifier.
            run_autocomplete ( argc - 1, &argv[1] );
        }
        else if ( command == "export" ) {
            this->command_export_autocomplete ( argc - 1, &argv[1] );
        }
        else if ( command == "import" ) {
            if ( argc == 3 ) {
                this->list_projects ();
            }
            return;
        }
        else if ( command == "move" ) {
            this->command_move_autocomplete ( argc - 1, &argv[1] );
        }
        else if ( command == "edit"  ) {
            if ( argc == 2 ) {
                this->command_edit_autocomplete ();
            }
            return;
        }
        else if ( command == "add" ) {
            if ( argc == 2 ) {
                this->list_projects ();
            }
            return;
        }
        else if ( command == "list" ) {
            if ( argc == 2 ) {
                std::cout << "project:" << std::endl;
            }
        }
    }

    /**
     * Interactive shell
     */
    void interactive ()
    {
        // Enable history.
        using_history ();

        do {
            // In interactive mode we want to make sure the list is always nicely ordered.
            // This is needed so commands like 'last' are always consistent.
            sort_notes ();

            // Create interactive prompt.
            char *temp = readline ( "> " );

            // Quit on ctrl-d or quit.
            if ( temp == nullptr ) {
                break;
            }
            if ( strcasecmp ( temp, "quit" ) == 0 ) {
                free ( temp );
                break;
            }
            // Add entry to history.
            add_history ( temp );

            // Split into arc, argv structure.
            int  length     = strlen ( temp );
            int  argc       = 0;
            int  last_index = 0;
            char **argv     = nullptr;
            for ( int i = 0; i <= length; i++ ) {
                if ( temp[i] == ' ' || temp[i] == '\0' ) {
                    if ( i != last_index ) {
                        argv       = (char * *) realloc ( argv, sizeof ( char * ) * ( argc + 1 ) );
                        argv[argc] = &temp[last_index];
                        temp[i]    = '\0';
                        argc++;
                    }
                    last_index = i + 1;
                }
            }

            // Run parser.
            this->cmd_parser ( argc, argv );

            // Free
            free ( argv );
            free ( temp );
        } while ( true );
    }

    void cmd_parser ( int argc, char **argv )
    {
        int index = 0;
        while ( index < argc ) {
            if ( strcmp ( argv[index], "view" ) == 0 ) {
                index++;
                index += this->command_view ( argc - index, &argv[index] );
            }
            else if ( strcmp ( argv[index], "cat" ) == 0 ) {
                index++;
                index += this->command_cat ( argc - index, &argv[index] );
            }
            else if ( strcmp ( argv[index], "list" ) == 0 ) {
                index++;
                index += this->command_list ( argc - index, &argv[index] );
            }
            else if ( strcmp ( argv[index], "edit" ) == 0 ) {
                index++;
                index += this->command_edit ( argc - index, &argv[index] );
            }
            else if ( strcmp ( argv[index], "add" ) == 0 ) {
                index++;
                index += this->command_add ( argc - index, &argv[index] );
            }
            else if ( strcmp ( argv[index], "move" ) == 0 ) {
                index++;
                index += this->command_move ( argc - index, &argv[index] );
            }
            else if ( strcmp ( argv[index], "delete" ) == 0 ) {
                index++;
                index += this->command_delete ( argc - index, &argv[index] );
            }
            else if ( strcmp ( argv[index], "export" ) == 0 ) {
                index++;
                index += this->command_export ( argc - index, &argv[index] );
            }
            else if ( strcmp ( argv[index], "import" ) == 0 ) {
                index++;
                index += this->command_import ( argc - index, &argv[index] );
            }
            else if ( strcmp ( argv[index], "projects" ) == 0 ) {
                index++;
                index += this->command_projects ( argc - index, &argv[index] );
            }
            else if ( strcmp ( argv[index], "archive" ) == 0  ) {
                index++;
                index += this->command_archive ( argc - index, &argv[index] );
            }
            else if  ( std::string ( argv[index] ) == "help" ) {
                index++;
                notes_print_warning ( "<Once upon a time there will be a help message here.>\n" );
            }
            else if ( strcmp ( argv[index], "gc" ) == 0 ) {
                index++;
                storage->gc ( this->notes );
            }
            else if ( strcmp ( argv[index], "search" ) == 0 ) {
                index++;
                if ( index < argc ) {
                    NotesFilter filter ( this->notes );
                    // Ignore archived notes.
                    if ( show_archive ) {
                        filter.filter_not_archive ();
                    }
                    else {
                        filter.filter_archive ();
                    }
                    try {
                        // Create Query:
                        std::string query = ".*";
                        query += argv[index];
                        query += ".*";

                        std::regex          rm ( query, std::regex_constants::icase | std::regex_constants::optimize );
                        index++;
                        std::vector <Note*> results;
                        for ( auto &note : filter.get_filtered_notes () ) {
                            if ( note->search (  rm ) ) {
                                results.push_back ( note );
                            }
                        }
                        this->display_notes ( results );
                    } catch ( ... ) {
                        std::cerr << "Failed to create regex" << std::endl;
                    }
                }
            }
            else {
                notes_print_error ( "Invalid command: '%s'\n", argv[index] );
                return;
            }
        }
        if ( argc == 0 ) {
            this->command_list ( 0, NULL );
        }
    }
    void Load ( )
    {
        // Iterate over all files in the git index.
        //
        //    execlp ( "git", );
        int               fdout, fderr;
        const auto &      path   = this->get_path ();
        const char *const args[] = { "git",         "-C",   path.c_str (), "ls-tree", "-r", "--name-only",
                                     "--full-name", "HEAD", NULL };
        if ( !exec_with_pipes ( fdout, fderr, args ) ) {
            notes_print_error ( "Failed to list files\n" );
            return;
        }
        if ( fderr >= 0 ) {
            close ( fderr );
        }
        FILE   *f            = fdopen ( fdout, "r" );
        size_t buffer_length = 0;
        char   *buffer       = nullptr;
        while ( getline ( &buffer, &buffer_length, f ) >= 0 ) {
            if ( buffer[strlen ( buffer ) - 1] == '\n' ) {
                buffer[strlen ( buffer ) - 1] = '\0';
            }
            // Find filename.
            char *filename = nullptr;
            for ( int iter = strlen ( buffer ) - 1; iter >= 0 && buffer[iter] != '/'; iter-- ) {
                filename = &buffer[iter];
            }

            // Find project.
            Project *p = this;
            if ( filename != NULL && filename != buffer ) {
                *( filename - 1 ) = '\0';
                for ( unsigned int iter = 0; iter < strlen ( buffer ); iter++ ) {
                    if ( buffer[iter] == '/' ) {
                        buffer[iter] = '.';
                    }
                }
                p = this->get_or_create_project_from_name ( buffer );
            }

            Note *note = new Note ( p, &settings, filename );
            // Add to the flat list in the main.
            this->notes.push_back ( note );
        }
        if ( buffer != nullptr ) {
            free ( buffer );
        }
        fclose ( f );
        // Gives them UIDs.
        for ( auto &note : this->notes ) {
            note->set_id ( storage->get_id ( note->get_relative_path () ) );
        }

        sort_notes ();
    }

    void sort_notes ()
    {
        // Sort the notes.
        std::sort ( this->notes.begin (), this->notes.end (), notes_print_sort );
    }

    static void strfreev ( char **str )
    {
        if ( str == nullptr ) {
            return;
        }
        for ( int i = 0; str != nullptr && str[i] != nullptr; i++ ) {
            free ( str[i] );
        }
        free ( str );
    }
    char ** strvdup ( const char *const *str )
    {
        int na = 0;
        for (; str != nullptr && str[na] != nullptr; na++ ) {
            ;
        }
        char **retv = (char * *) malloc ( ( na + 1 ) * sizeof ( char* ) );
        for ( int i = 0; i < na; i++ ) {
            retv[i] = strdup ( str[i] );
        }
        retv[na] = nullptr;
        return retv;
    }
};

int main ( int argc, char ** argv )
{
    INIT_TIC_TAC ()

    NotesCC * notes = new NotesCC ( );

    // Parse some options we might want to check before opening the db.
    notes->pre_parse_settings ( argc, argv );

    // Open repository
    if ( notes->open_repository ( ) ) {
        notes->run ( argc, argv );
    }

    delete notes;

    TIC ( "Total runtime: " );
    return EXIT_SUCCESS;
}


text:
//-------------------------------------------------------------------------
// Code to support performance testing and debugging. Generally this need
// not be included in the main HTML page or shipped, though it doesn't
// hurt if it is.
//
// When included in the main HTML page, make sure it is early, as other
// files will depend on it, esp. menu support.
//-------------------------------------------------------------------------

var TEST_ENABLED = true;  // flag for the rest of the app to indicate that we want

/*
 * Compute the approximate memory size, in bytes, of the specified object,
 * walking the object tree and adding any sub-objects to the total.
 * 'ignoreObjects', if given, are a list of objects that should be ignored,
 * which is most easily done by considering them as 'already processed'.
 */
function sizeof(object, ignoreObjects) {
    var objects;
    var size = 0;

    var numBoolean = 0;
    var numNumber = 0;
    var numString = 0;
    var sizeString = 0;  // # characters
    var numArray = 0;
    var numObject = 0;
    var numObjectKey = 0;
    var sizeObjectKey = 0;  // # characters
    var numFunction = 0;
    var numException = 0;

    var item, index, key, len, tmp, tmp2;

    if (ignoreObjects) {
        objects = ignoreObjects;
    } else {
        objects = [];
    }

    objects.push(object);

    function processPrimitive(item, type) {
        switch (type) {
        case 'boolean':
            size += 4;
            numBoolean++;
            break;
        case 'number':
            size += 8;
            numNumber++;
            break;
        case 'string':
            len = item.length;
            size += len * 2;
            numString++;
            sizeString += len;
            break;
        case 'function':
            numFunction++;
            break;
        case 'null':
        case 'undefined':
            break;
        default:
            alert('Found unknown item ' + item + ' of type ' + type);
        }
    }

    function isSystemObj(item) {
        return (item === window ||
                item === navigator ||
                item === localStorage);
    }

    function processItem(item, itemType) {
        if (itemType !== 'array' && itemType !== 'object') {
            processPrimitive(item, itemType);
        } else if (isSystemObj(item)) {
            CC.console.log('Ignoring system object');
        } else if (objects.indexOf(item) >= 0) {
            CC.console.log('Ignoring already-seen object');
        } else {
            CC.console.log('pushing item of type [' + itemType + ']');
            objects.push(item);
        }
    }

    // do equivalent to a breadth-first search, in that items inside
    // objects are added to the object array.
    for (var itemIndex = objects.indexOf(object); itemIndex < objects.length; itemIndex ++) {
        if (itemIndex % 100 == 0) {
            CC.console.log('checking obj #' + itemIndex);
        }

        // determine the type of the object
        var item = objects[itemIndex];
        var type = typeOf(item);

        if (type === 'array') {
            //CC.console.log('Found array');
            numArray++;
            for (var i = 0; i < item.length; i++) {
                processItem(item[i], typeOf(item[i]));
            }
        } else if (type !== 'object') {
            processPrimitive(item, type);
        } else {
            //CC.console.log('Found object');
            numObject++;

            // loop over the keys, checking the values. Any that have not
            // been processed go into the object array for processing.
            for (key in item) {
                // add the key size
                size += 2 * key.length;
                numObjectKey++;
                sizeObjectKey += key.length;

                CC.console.log('Found object key [' + key + ']');

                // Sometimes we get things like DOMExceptions when trying
                // to fetch what ostensibly is an attribute value. For example,
                // SVGLength is an object with 'value', but that returns
                // a DOMException]. We'll ignore those.
                try {
                    processItem(item[key], typeOf(item[key]));
                } catch (ex) {
                    numException++;
                }
            }
        }
    }

    // return the size data
    return [size, numBoolean, numNumber, numString, sizeString,
            numArray, numObject, numObjectKey, sizeObjectKey, numFunction, numException];
}

function countClusterSize(clusterModel) {
    var ignoreObjects = [clusterModel];

    var gatewayModel = clusterModel.getGateways()[0];
    ignoreObjects.push(gatewayModel);

    var serviceModel = null;

    var services = gatewayModel.getServices();
    for (var i = 0; i < services.length; i++) {
        var service = services[i];

        if (service.get('serviceLabel') == 'performance proxy') {
            serviceModel = service;
        }

        ignoreObjects.push(service);
    }

    var spdm = serviceModel.get('serviceProcessingDataModels').item(0);

    var sizeData = sizeof(spdm, ignoreObjects);
    alert('The first service processing data model in service [' + serviceModel.get('serviceLabel') +
          ' takes up approximately:\n' +
          sizeData[0] + ' bytes overall\n' +
          sizeData[1] + ' booleans\n' +
          sizeData[2] + ' numbers\n' +
          sizeData[3] + ' strings (' + sizeData[4] + ' chars)\n' +
          sizeData[5] + ' arrays\n' +
          sizeData[6] + ' objects (' + sizeData[7] +
          ' keys taking ' + sizeData[8] + ' chars)\n' +
          sizeData[9] + ' functions\n' +
          sizeData[10] + ' unreadable object properties');
    return ignoreObjects;
}

function countSpdmSize(clusterModel) {
    var totals = countModelObjects(clusterModel);
    var spdmList = totals['sessionProcessingDataModels'];
    var ignoreList = [];
}

/**
 * Given a cluster model, count the various types of objects it contains
 * that are considered Kaazing model objects.
 */
function countModelObjects(clusterModel) {
    var totals = {clusterModels: [],
                  clusterConfigModels: [],
                  cpuListModels: [],
                  cpuListSummaryDataItems: [],
                  gatewayModels: [],
                  gatewayConfigModels: [],
                  gatewayProcessingDataModels: [],
                  jvmModels: [],
                  jvmSummaryDataItems: [],
                  licenseConfigModels: [],
                  networkConfigModels: [],
                  nicListModels: [],
                  nicListSummaryDataItems: [],
                  realmConfigModels: [],
                  securityConfigModels: [],
                  serviceConfigModels: [],
                  serviceDefaultsConfigModels: [],
                  serviceModels: [],
                  serviceProcessingDataModels: [],
                  sessionModels: [],
                  sessionProcessingDataModels: [],
                  systemModels: [],
                  systemSummaryDataItems: []};

    function processClusterModel(clusterModel) {
        if (addModel('clusterModels', clusterModel)) {
            var gateways = clusterModel.get('gatewayModels');
            if (gateways) {
                // modelList
                gateways.values().forEach(function(gw) {
                    processGatewayModel(gw);
                });
            }

            gateways = clusterModel.get('inProcessGatewayModels');
            // array
            gateways.forEach(function(gw) {
                processGatewayModel(gw);
            });
        }
    }

    function processGatewayModel(gatewayModel) {
        if (addModel('gatewayModels', gatewayModel)) {
            processGatewayConfigModel(gatewayModel.get('gatewayConfig'));

            var gpdmList = gatewayModel.get('gatewayProcessingDataModels');
            for (var i = 0; i < gpdmList.size(); i++) {
                processGatewayProcessingDataModel(gpdmList.item(i));
            }

            var systemModel = gatewayModel.get('systemModel');
            if (systemModel) {
                processSystemModel(systemModel);
            }

            var cpuListModel = gatewayModel.get('cpuListModel');
            if (cpuListModel) {
                processCpuListModel(cpuListModel);
            }

            var nicListModel = gatewayModel.get('nicListModel');
            if (nicListModel) {
                processNicListModel(nicListModel);
            }

            var jmvModel = gatewayModel.get('jmvModel');
            if (jmvModel) {
                processJmvModel(jmvModel);
            }

            var services = gatewayModel.getServices();
            if (services) {
                services.forEach(function(serviceModel) {
                    processServiceModel(serviceModel);
                });
            }
        }

    }

    function processGatewayConfigModel(gatewayConfigModel) {
        if (addModel('gatewayConfigModels', gatewayConfigModel)) {
            var clusterConfigModel = gatewayConfigModel.get('clusterConfig');
            if (clusterConfigModel) {
                processClusterConfigModel(clusterConfigModel);
            }

            var licenseConfigModel = gatewayConfigModel.get('licenseConfig');
            if (licenseConfigModel) {
                processLicenseConfigModel(licenseConfigModel);
            }

            var networkConfigModel = gatewayConfigModel.get('networkConfig');
            if (networkConfigModel) {
                processNetworkConfigModel(networkConfigModel);
            }

            var securityConfigModel = gatewayConfigModel.get('securityConfig');
            if (securityConfigModel) {
                processSecurityConfigModel(securityConfigModel);
            }

            var serviceDefaultsConfigModel = gatewayConfigModel.get('serviceDefaultsConfig');
            if (serviceDefaultsConfigModel) {
                processServiceDefaultsConfigModel(serviceDefaultsConfigModel);
            }

            var serviceConfigModels = gatewayConfigModel.get('serviceConfigs');
            if (serviceConfigModels) {
                serviceConfigModels.forEach(function(serviceConfigModel) {
                    processServiceConfigModel(serviceConfigModel);
                })
            }
        }
    }

    function processClusterConfigModel(clusterConfigModel) {
        addModel('clusterConfigModels', clusterConfigModel);
    }

    function processLicenseConfigModel(licenseConfigModel) {
        addModel('licenseConfigModels', licenseConfigModel);
    }

    function processNetworkConfigModel(networkConfigModel) {
        addModel('networkConfigModels', networkConfigModel);
    }

    function processSecurityConfigModel(securityConfigModel) {
        if (addModel('securityConfigModels', securityConfigModel)) {
            var realmConfigModels = securityConfigModel.get('realmConfigs');
            if (realmConfigModels) {
                for (var realmName in realmConfigModels) {
                    processRealmConfigModel(realmConfigModels[realmName]);
                }
            }
        }
    }

    function processRealmConfigModel(realmConfigModel) {
        addModel('realmConfigModels', realmConfigModel);
    }

    function processServiceDefaultsConfigModel(serviceDefaultsConfigModel) {
        addModel('serviceDefaultsConfigModels', serviceDefaultsConfigModel);
    }

    function processServiceConfigModel(serviceConfigModel) {
        addModel('serviceConfigModels', serviceConfigModel);
    }

    function processGatewayProcessingDataModel(gpdm) {
        addModel('gatewayProcessingDataModels', gpdm);
    }

    function processSystemModel(systemModel) {
        if (addModel('systemModels', systemModel)) {
            var summaryData = systemModel.get('summaryData');
            summaryData.forEach(function(item) {
                processSystemSummaryDataItem(item);
            });
        }
    }
    function processSystemSummaryDataItem(systemSummaryDataItem) {
        // we know these are unique
        totals['systemSummaryDataItems'].push(systemSummaryDataItem);
    }

    function processCpuListModel(cpuListModel) {
        if (addModel('cpuListModels', cpuListModel)) {
            var summaryData = cpuListModel.get('summaryData');
            summaryData.forEach(function(item) {
                processCpuListSummaryDataItem(item);
            });
        }
    }
    function processCpuListSummaryDataItem(cpuListSummaryDataItem) {
        // we know these are unique
        totals['cpuListSummaryDataItems'].push(cpuListSummaryDataItem);
    }

    function processNicListModel(nicListModel) {
        if (addModel('nicListModels', nicListModel)) {
            var summaryData = nicListModel.get('summaryData');
            summaryData.forEach(function(item) {
                processNicListSummaryDataItem(item);
            });
        }
    }
    function processNicListSummaryDataItem(nicListSummaryDataItem) {
        // we know these are unique
        totals['nicListSummaryDataItems'].push(nicListSummaryDataItem);
    }

    function processJvmModel(jvmModel) {
        if (addModel('jvmModels', jvmModel)) {
            var summaryData = jvmModel.get('summaryData');
            summaryData.forEach(function(item) {
                processJvmSummaryDataItem(item);
            });
        }
    }
    function processJvmSummaryDataItem(jvmSummaryDataItem) {
        // we know these are unique
        totals['jvmSummaryDataItems'].push(jvmSummaryDataItem);
    }

    function processServiceModel(serviceModel) {
        if (addModel('serviceModels', serviceModel)) {
            var spdmList = serviceModel.get('serviceProcessingDataModels');
            for (var i = 0; i < spdmList.size(); i++) {
                processServiceProcessingDataModel(spdmList.item(i));
            }

            var sessions = serviceModel.getSessions();
            if (sessions) {
                sessions.forEach(function(sessionModel) {
                    processSessionModel(sessionModel);
                });
            }
        }
    }

    function processServiceProcessingDataModel(spdm) {
        // we know these are unique
        totals['serviceProcessingDataModels'].push(spdm);
    }

    function processSessionModel(sessionModel) {
        if (addModel('sessionModels', sessionModel)) {
            var spdmList = sessionModel.get('sessionProcessingDataModels');
            for (var i = 0; i < spdmList.size(); i++) {
                processSessionProcessingDataModel(spdmList.item(i));
            }
        }
    }

    function processSessionProcessingDataModel(spdm) {
        // we know the session models are unique.
        totals['sessionProcessingDataModels'].push(spdm);
    }

    /**
     * Try to add a model with a given type name (corresponds to the
     * prop names in totals to the list. If it is already there, does
     * nothing.
     */
    function addModel(type, model) {
        var list = totals[type];
        if (list.indexOf(model) < 0) {
            list.push(model);
            return true;
        }

        return false;
    }

    // Start the processing.
    processClusterModel(clusterModel);

    var msg = 'Counts of the various types of model objects in the cluster tree:\n';
    for (var prop in totals) {
        msg += (prop + ": " + totals[prop].length + '\n');
    }

    alert(msg);
    return totals;
}

function countBytesRead(clusterModel) {
    var gateways = clusterModel.getGateways();
    var result = "Read since connection:\n";

    if (gateways) {
        for (var i = 0; i < gateways.length; i++) {
            var gateway = gateways[i];
            var mngtApi = gateway.get('mngtApi');
            var bytesRead = mngtApi._impl._snmp._bytesRead;
            var fragmentsRead = mngtApi._impl._snmp._fragmentsRead;
            result += (gateway.get('gatewayLabel') + ': ' +
                       fragmentsRead + ' fragments, ' + bytesRead + ' bytes\n');
        }
    } else {
        result += "  No gateways are connected";
    }

    alert(result);
}

redpajama_set_name: RedPajamaGithub


text:
using System;

namespace SensusService.Probes.User.ProbeTriggerProperties
{
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public abstract class ProbeTriggerProperty : Attribute
    {
        private string _name;

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        public ProbeTriggerProperty()
        {
        }

        public ProbeTriggerProperty(string name)
            : this()
        {
            _name = name;
        }
    }
}


text:
using System.Globalization;

namespace Material.Application.Localization
{
    public class Language
    {
        public Language(string name, string dictionaryUri, CultureInfo cultureInfo)
        {
            Name = name;
            DictionaryUri = dictionaryUri;
            CultureInfo = cultureInfo;
        }

        public string Name { get; }

        public string DictionaryUri { get; }

        public CultureInfo CultureInfo { get; }
    }
}


text:
import { assert } from 'chai';
import { Tracker } from 'meteor/tracker';
import PostsCollection from './bootstrap/collection.test';
import NamedQuery, {
    postsQuery,
    postsQuery2,
    postsQuery3,
} from './bootstrap/namedQuery.test';
import callWithPromise from '../../lib/callWithPromise';

describe('Reactive count tests', function() {
    callWithPromise('resetPosts');

    it('Should fetch the initial count', function(done) {
        const query = NamedQuery.clone();
        const handle = query.subscribeCount();

        Tracker.autorun(c => {
            if (handle.ready()) {
                c.stop();
                const count = query.getCount();
                handle.stop();

                assert.equal(count, 3);
                done();
            }
        });
    });

    // TODO: Can these tests fail if assert gets called too quickly?
    it('Should update when a document is added', function(done) {
        const query = NamedQuery.clone();
        const handle = query.subscribeCount();

        Tracker.autorun(c => {
            if (handle.ready()) {
                c.stop();
                const count = query.getCount();
                assert.equal(count, 3);

                Meteor.call('addPost', 'text4', (error, newId) => {
                    const newCount = query.getCount();
                    assert.equal(newCount, 4);

                    Meteor.call('removePost', newId);
                    handle.stop();
                    done();
                });
            }
        });
    });

    it('Should update when a document is removed', function(done) {
        const query = NamedQuery.clone();
        const handle = query.subscribeCount();

        Tracker.autorun(c => {
            if (handle.ready()) {
                c.stop();
                const count = query.getCount();
                assert.equal(count, 3);

                Meteor.call('removePost', 'removeid', error => {
                    const newCount = query.getCount();
                    assert.equal(newCount, 2);

                    handle.stop();
                    done();
                });
            }
        });
    });

    it('Should work with two different queries', function(done) {
        const query1 = postsQuery.clone();
        const query2 = postsQuery2.clone();

        const handle2 = query2.subscribeCount();
        const handle1 = query1.subscribeCount();

        Tracker.autorun(c => {
            if (handle1.ready() && handle2.ready()) {
                const count1 = query1.getCount();
                const count2 = query2.getCount();

                assert.equal(count1, 2);
                assert.equal(count2, 1);
                done();
            }
        });
    });

    it('Should work with special filter params', function(done) {
        const query = postsQuery3.clone({
            $regex: 'BOMB',
        });

        const handle = query.subscribeCount();

        Tracker.autorun(c => {
            if (handle.ready()) {
                const count = query.getCount();

                assert.equal(count, 2);
                done();
            }
        });
    });
});


text:
BEGIN;

DROP INDEX IF EXISTS nodes_org_id_environment_index;
DROP TABLE IF EXISTS nodes;

COMMIT;


text:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XpressionMapper.Tests
{
    internal static class Helpers
    {
        [DbFunction("Edm", "TruncateTime")]
        public static DateTime? TruncateTime(DateTime? date)
        {
            return date.HasValue ? date.Value.Date : (DateTime?)null;
        }
    }
}


text:
{{event.name}}

Date:
            {{event.date}}

Paid by:
            {{event.paid_by.name}}

Location:
            {{event.paid_by.location}}


text:
class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.hstore :title
      t.hstore :content
      t.string :author

      t.timestamps
    end
    add_hstore_index :posts, :title
    add_hstore_index :posts, :content
  end
end


text:
/*
 @ 0xCCCCCCCC
*/

#if defined(_MSC_VER)
#pragma once
#endif

#ifndef SCOPED_SOCKET_H_
#define SCOPED_SOCKET_H_

#include <WinSock2.h>

#include "kbase/scoped_handle.h"

namespace network {

struct SocketTraits {
    using Handle = SOCKET;

    SocketTraits() = delete;
    ~SocketTraits() = delete;

    static Handle NullHandle() noexcept
    {
        return INVALID_SOCKET;
    }

    static bool IsValid(Handle handle) noexcept
    {
        return handle != 0 && handle != INVALID_SOCKET;
    }

    static void Close(Handle handle) noexcept
    {
        closesocket(handle);
    }
};

using ScopedSocket = kbase::GenericScopedHandle<SocketTraits>;

}   // namespace network

#endif  // SCOPED_SOCKET_H_


text:
package com.szagurskii.patternedtextwatcher.insertion;

import android.os.Build;
import android.widget.EditText;

import com.szagurskii.patternedtextwatcher.BuildConfig;
import com.szagurskii.patternedtextwatcher.CustomRobolectricTestRunner;
import com.szagurskii.patternedtextwatcher.PatternedTextWatcher;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;

@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
@RunWith(CustomRobolectricTestRunner.class)
public class InsertionSameSymbols extends BaseCustomizedAdditionTests {
  // https://github.com/zsavely/PatternedTextWatcher/issues/22
  @Test public void multipleSameSymbolsAddition() {
    final String pattern = "##.##.####";

    init(editText, pattern);

    appendTextAndAssert(editText, "1", "1", pattern);
    appendTextAndAssert(editText, "11.", "1", pattern);
    appendTextAndAssert(editText, "11.1", "1", pattern);
    appendTextAndAssert(editText, "11.12.", "2", pattern);
    appendTextAndAssert(editText, "11.12.1", "1", pattern);
    appendTextAndAssert(editText, "11.12.12", "2", pattern);
    appendTextAndAssert(editText, "11.12.123", "3", pattern);
    appendTextAndAssert(editText, "11.12.1234", "4", pattern);

    setTextAndAssert(editText, "11.12.12", "11.12.12", pattern);
  }

  @Override protected PatternedTextWatcher init(EditText editText, String pattern) {
    PatternedTextWatcher patternedTextWatcher = new PatternedTextWatcher(pattern);
    editText.addTextChangedListener(patternedTextWatcher);
    return patternedTextWatcher;
  }

  private void appendTextAndAssert(EditText editText, String expected, String typed, String pattern) {
    editText.append(typed);
    assertText(editText, expected, typed, pattern);
  }

  private void setTextAndAssert(EditText editText, String expected, String typed, String pattern) {
    editText.setText(typed);
    assertText(editText, expected, typed, pattern);
  }

  @Override void addTextAndAssert(EditText editText, String expected, String typed, String pattern) {
  }

  @Override public void basicSingleAddition() {
  }

  @Override public void basicMultipleAddition() {
  }

  @Override public void basicAdditionExactPattern() {
  }

  @Override public void basicAdditionMoreThanPattern() {
  }

  @Override public void basicAdditionLessThanPattern() {
  }

  @Override public void basicAdditionExactPatternSpecialCharacters() {
  }

  @Override public void basicAdditionMoreThanPatternSpecialCharacters() {
  }

  @Override public void basicAdditionLessThanPatternSpecialCharacters() {
  }

  @Override void fillPatternChecks() {
  }

  @Override public void multipleAddition() {
  }
}


text:
namespace formulate.app.Helpers
{
    public interface ILocalizationHelper
    {
        string GetDataValueName(string name);
        string GetLayoutName(string name);
        string GetMenuItemName(string name);
        string GetTreeName(string tree);
    }
}


text:
var gDoneButton,
    gInfoButton,
//noinspection SpellCheckingInspection
    apple = {
        setup: function () {
            gDoneButton = new AppleGlassButton(document.getElementById("doneButton"), "Done", this.hidePrefs);
            gInfoButton = new AppleInfoButton(document.getElementById("infoButton"), document.getElementById("front"), "white", "white", this.showPrefs);
        },
        showPrefs: function () {
            var front = document.getElementById("front");
            var back = document.getElementById("back");

            if (window.widget) {
                widget.prepareForTransition("ToBack");
            }

            front.style.display = "none";
            back.style.display = "block";
            pasteBin.populateTimeframes("pasteBin-timeFrameB");
            pasteBin.populateProgrammingLanguages("pasteBin-programmingLanguageB");
            if (window.widget) {
                setTimeout('widget.performTransition();', 0);
            }
        },
        hidePrefs: function () {

            var front = document.getElementById("front");
            var back = document.getElementById("back");
            if (window.widget) {
                widget.prepareForTransition("ToFront");
            }

            back.style.display = "none";
            front.style.display = "block";
            pasteBin.populateTimeframes("pasteBin-timeFrame");
            pasteBin.populateProgrammingLanguages("pasteBin-programmingLanguage");
            if (window.widget) {
                setTimeout('widget.performTransition();', 0);
            }
        },
        save: function (key, value) {
            if (window.widget) {
                widget.setPreferenceForKey(value, key);
            }
        },
        load: function (key) {
            var value;
            if (window.widget) {
                value = widget.preferenceForKey(key);
            }
            return value;
        }
    },
    password = {
        keys: "abcdefghijklmnopqrstuvwxyz",
        symbols: "~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/",
        capitals: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
        numbers: "0123456789",
        generate: function () {
            var temp = '',
                i,
                tempKeys,
                length,
                savedLength = apple.load("savedLength"),
                savedNumbers = apple.load("savedNumbers"),
                savedCapitals = apple.load("savedCapitals"),
                savedSymbols = apple.load("savedSymbols");

            tempKeys = this.keys;

            if (savedLength > 0) {
                length = savedLength;
            }
            else {
                length = 8;
            }

            if (savedCapitals === true) {
                tempKeys = tempKeys.concat(this.capitals);
            }

            if (savedNumbers === true) {
                tempKeys = tempKeys.concat(this.numbers);
            }
            if (savedSymbols === true) {
                tempKeys = tempKeys.concat(this.symbols);
            }

            for (i = 0; i < length; i++) {
                temp += tempKeys.charAt(Math.floor(Math.random() * tempKeys.length))
            }

            return updateOutput("passwordOutput", temp);
        }
    },
    pasteBin = {
        api_dev_key: '72da529c1e3107c3dd9c4170d16608c3',// please do not abuse. You can get yours for free by just creating a pastebin.com account
        execute: function (raw, filenameTitle, expireTime, format) {
            if (raw.length === 0) {
                return;
            }
            var api_paste_code = encodeURIComponent(raw + "\n\n\nI am pasting via https://github.com/venatir/devtools-widget"), // your paste text
                api_paste_private = '1', // 0=public 1=unlisted 2=private
                api_paste_name = encodeURIComponent(filenameTitle || "I am pasting via https://github.com/venatir/devtools-widget"), // name or title of your paste
                api_paste_expire_date = expireTime || '1H',
                api_paste_format = format || 'php',
                api_user_key = apple.load("savedPasteBin-userKey"), // if an invalid api_user_key or no key is used, the paste will be create as a guest
                url = 'http://pastebin.com/api/api_post.php',
                xmlhttp = new XMLHttpRequest();

            // TODO: comment out my text

            xmlhttp.open("POST", url, true);
            xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    updateOutput("pasteBin-raw", xmlhttp.responseText);
                    pasteBin.populateTimeframes("pasteBin-timeFrame");
                    pasteBin.populateProgrammingLanguages("pasteBin-programmingLanguage");
                }
            };
            xmlhttp.send(
                "api_option=paste&" +
                "api_dev_key=" + this.api_dev_key + "&" +
                "api_paste_code=" + api_paste_code + "&" +
                "api_paste_private=" + api_paste_private + "&" +
                "api_paste_name=" + api_paste_name + "&" +
                "api_paste_expire_date=" + api_paste_expire_date + "&" +
                "api_paste_format=" + api_paste_format + "&" +
                "api_user_key=" + api_user_key
            );
        },
        populateTimeframes: function (id) {
            var i,
                data,
                option,
                savedTimeframe,
                select = document.getElementById(id);

            while (select.length > 0) {
                select.remove(select.length - 1);
            }
            for (i = 0; i < pasteBin.timeFrames.length; i++) {
                data = pasteBin.timeFrames[i];
                option = new Option(data.text, data.value);
                savedTimeframe = apple.load("savedTimeframe");

                if (savedTimeframe) {
                    if (data.value === savedTimeframe) {
                        option.selected = true;
                    }
                } else {
                    if (data.selected === true) {
                        option.selected = true;
                    }
                }
                document.getElementById(id).options.add(option);
            }
        },
        populateProgrammingLanguages: function (id) {
            var i,
                data,
                option,
                savedProgrammingLanguage,
                select = document.getElementById(id);

            while (select.length > 0) {
                select.remove(select.length - 1);
            }
            for (i = 0; i < pasteBin.programmingLanguages.length; i++) {
                data = pasteBin.programmingLanguages[i];
                option = new Option(data.text, data.value);
                savedProgrammingLanguage = apple.load("savedProgrammingLanguage");

                if (savedProgrammingLanguage) {
                    if (data.value === savedProgrammingLanguage) {
                        option.selected = true;
                    }
                } else {
                    if (data.selected === true) {
                        option.selected = true;
                    }
                }

                if (data.selected === true) {
                    option.selected = true;
                }
                document.getElementById(id).options.add(option);
            }
        },
        getUserKey: function (callback) {
            var xmlhttp = new XMLHttpRequest();

            xmlhttp.open("POST", "http://pastebin.com/api/api_login.php", true);
            xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    apple.save("savedPasteBin-userKey", xmlhttp.responseText);
                    callback(xmlhttp.responseText);
                }
            };
            xmlhttp.send(
                "api_dev_key=" + this.api_dev_key + "&" +
                "api_user_name=" + document.getElementById("pasteBin-username").value + "&" +
                "api_user_password=" + document.getElementById("pasteBin-password").value
            );
        },
        programmingLanguages: [
            {value: "4cs", text: "4CS"},
            {value: "6502acme", text: "6502 ACME Cross Assembler"},
            {value: "6502kickass", text: "6502 Kick Assembler"},
            {value: "6502tasm", text: "6502 TASM/64TASS"},
            {value: "abap", text: "ABAP"},
            {value: "actionscript", text: "ActionScript"},
            {value: "actionscript3", text: "ActionScript 3"},
            {value: "ada", text: "Ada"},
            {value: "algol68", text: "ALGOL 68"},
            {value: "apache", text: "Apache Log"},
            {value: "applescript", text: "AppleScript"},
            {value: "apt_sources", text: "APT Sources"},
            {value: "arm", text: "ARM"},
            {value: "asm", text: "ASM (NASM)"},
            {value: "asp", text: "ASP"},
            {value: "asymptote", text: "Asymptote"},
            {value: "autoconf", text: "autoconf"},
            {value: "autohotkey", text: "Autohotkey"},
            {value: "autoit", text: "AutoIt"},
            {value: "avisynth", text: "Avisynth"},
            {value: "awk", text: "Awk"},
            {value: "bascomavr", text: "BASCOM AVR"},
            {value: "bash", text: "Bash"},
            {value: "basic4gl", text: "Basic4GL"},
            {value: "bibtex", text: "BibTeX"},
            {value: "blitzbasic", text: "Blitz Basic"},
            {value: "bnf", text: "BNF"},
            {value: "boo", text: "BOO"},
            {value: "bf", text: "BrainFuck"},
            {value: "c", text: "C"},
            {value: "c_mac", text: "C for Macs"},
            {value: "cil", text: "C Intermediate Language"},
            {value: "csharp", text: "C#"},
            {value: "cpp", text: "C++"},
            {value: "cpp-qt", text: "C++ (with QT extensions)"},
            {value: "c_loadrunner", text: "C: Loadrunner"},
            {value: "caddcl", text: "CAD DCL"},
            {value: "cadlisp", text: "CAD Lisp"},
            {value: "cfdg", text: "CFDG"},
            {value: "chaiscript", text: "ChaiScript"},
            {value: "clojure", text: "Clojure"},
            {value: "klonec", text: "Clone C"},
            {value: "klonecpp", text: "Clone C++"},
            {value: "cmake", text: "CMake"},
            {value: "cobol", text: "COBOL"},
            {value: "coffeescript", text: "CoffeeScript"},
            {value: "cfm", text: "ColdFusion"},
            {value: "css", text: "CSS"},
            {value: "cuesheet", text: "Cuesheet"},
            {value: "d", text: "D"},
            {value: "dcl", text: "DCL"},
            {value: "dcpu16", text: "DCPU-16"},
            {value: "dcs", text: "DCS"},
            {value: "delphi", text: "Delphi"},
            {value: "oxygene", text: "Delphi Prism (Oxygene)"},
            {value: "diff", text: "Diff"},
            {value: "div", text: "DIV"},
            {value: "dos", text: "DOS"},
            {value: "dot", text: "DOT"},
            {value: "e", text: "E"},
            {value: "ecmascript", text: "ECMAScript"},
            {value: "eiffel", text: "Eiffel"},
            {value: "email", text: "Email"},
            {value: "epc", text: "EPC"},
            {value: "erlang", text: "Erlang"},
            {value: "fsharp", text: "F#"},
            {value: "falcon", text: "Falcon"},
            {value: "fo", text: "FO Language"},
            {value: "f1", text: "Formula One"},
            {value: "fortran", text: "Fortran"},
            {value: "freebasic", text: "FreeBasic"},
            {value: "freeswitch", text: "FreeSWITCH"},
            {value: "gambas", text: "GAMBAS"},
            {value: "gml", text: "Game Maker"},
            {value: "gdb", text: "GDB"},
            {value: "genero", text: "Genero"},
            {value: "genie", text: "Genie"},
            {value: "gettext", text: "GetText"},
            {value: "go", text: "Go"},
            {value: "groovy", text: "Groovy"},
            {value: "gwbasic", text: "GwBasic"},
            {value: "haskell", text: "Haskell"},
            {value: "haxe", text: "Haxe"},
            {value: "hicest", text: "HicEst"},
            {value: "hq9plus", text: "HQ9 Plus"},
            {value: "html4strict", text: "HTML"},
            {value: "html5", text: "HTML 5"},
            {value: "icon", text: "Icon"},
            {value: "idl", text: "IDL"},
            {value: "ini", text: "INI file"},
            {value: "inno", text: "Inno Script"},
            {value: "intercal", text: "INTERCAL"},
            {value: "io", text: "IO"},
            {value: "j", text: "J"},
            {value: "java", text: "Java"},
            {value: "java5", text: "Java 5"},
            {value: "javascript", text: "JavaScript"},
            {value: "jquery", text: "jQuery"},
            {value: "kixtart", text: "KiXtart"},
            {value: "latex", text: "Latex"},
            {value: "ldif", text: "LDIF"},
            {value: "lb", text: "Liberty BASIC"},
            {value: "lsl2", text: "Linden Scripting"},
            {value: "lisp", text: "Lisp"},
            {value: "llvm", text: "LLVM"},
            {value: "locobasic", text: "Loco Basic"},
            {value: "logtalk", text: "Logtalk"},
            {value: "lolcode", text: "LOL Code"},
            {value: "lotusformulas", text: "Lotus Formulas"},
            {value: "lotusscript", text: "Lotus Script"},
            {value: "lscript", text: "LScript"},
            {value: "lua", text: "Lua"},
            {value: "m68k", text: "M68000 Assembler"},
            {value: "magiksf", text: "MagikSF"},
            {value: "make", text: "Make"},
            {value: "mapbasic", text: "MapBasic"},
            {value: "matlab", text: "MatLab"},
            {value: "mirc", text: "mIRC"},
            {value: "mmix", text: "MIX Assembler"},
            {value: "modula2", text: "Modula 2"},
            {value: "modula3", text: "Modula 3"},
            {value: "68000devpac", text: "Motorola 68000 HiSoft Dev"},
            {value: "mpasm", text: "MPASM"},
            {value: "mxml", text: "MXML"},
            {value: "mysql", text: "MySQL"},
            {value: "nagios", text: "Nagios"},
            {value: "newlisp", text: "newLISP"},
            {value: "text", text: "None"},
            {value: "nsis", text: "NullSoft Installer"},
            {value: "oberon2", text: "Oberon 2"},
            {value: "objeck", text: "Objeck Programming Langua"},
            {value: "objc", text: "Objective C"},
            {value: "ocaml-brief", text: "OCalm Brief"},
            {value: "ocaml", text: "OCaml"},
            {value: "octave", text: "Octave"},
            {value: "pf", text: "OpenBSD PACKET FILTER"},
            {value: "glsl", text: "OpenGL Shading"},
            {value: "oobas", text: "Openoffice BASIC"},
            {value: "oracle11", text: "Oracle 11"},
            {value: "oracle8", text: "Oracle 8"},
            {value: "oz", text: "Oz"},
            {value: "parasail", text: "ParaSail"},
            {value: "parigp", text: "PARI/GP"},
            {value: "pascal", text: "Pascal"},
            {value: "pawn", text: "PAWN"},
            {value: "pcre", text: "PCRE"},
            {value: "per", text: "Per"},
            {value: "perl", text: "Perl"},
            {value: "perl6", text: "Perl 6"},
            {value: "php", text: "PHP", selected: true},
            {value: "php-brief", text: "PHP Brief"},
            {value: "pic16", text: "Pic 16"},
            {value: "pike", text: "Pike"},
            {value: "pixelbender", text: "Pixel Bender"},
            {value: "plsql", text: "PL/SQL"},
            {value: "postgresql", text: "PostgreSQL"},
            {value: "povray", text: "POV-Ray"},
            {value: "powershell", text: "Power Shell"},
            {value: "powerbuilder", text: "PowerBuilder"},
            {value: "proftpd", text: "ProFTPd"},
            {value: "progress", text: "Progress"},
            {value: "prolog", text: "Prolog"},
            {value: "properties", text: "Properties"},
            {value: "providex", text: "ProvideX"},
            {value: "purebasic", text: "PureBasic"},
            {value: "pycon", text: "PyCon"},
            {value: "python", text: "Python"},
            {value: "pys60", text: "Python for S60"},
            {value: "q", text: "q/kdb+"},
            {value: "qbasic", text: "QBasic"},
            {value: "rsplus", text: "R"},
            {value: "rails", text: "Rails"},
            {value: "rebol", text: "REBOL"},
            {value: "reg", text: "REG"},
            {value: "rexx", text: "Rexx"},
            {value: "robots", text: "Robots"},
            {value: "rpmspec", text: "RPM Spec"},
            {value: "ruby", text: "Ruby"},
            {value: "gnuplot", text: "Ruby Gnuplot"},
            {value: "sas", text: "SAS"},
            {value: "scala", text: "Scala"},
            {value: "scheme", text: "Scheme"},
            {value: "scilab", text: "Scilab"},
            {value: "sdlbasic", text: "SdlBasic"},
            {value: "smalltalk", text: "Smalltalk"},
            {value: "smarty", text: "Smarty"},
            {value: "spark", text: "SPARK"},
            {value: "sparql", text: "SPARQL"},
            {value: "sql", text: "SQL"},
            {value: "stonescript", text: "StoneScript"},
            {value: "systemverilog", text: "SystemVerilog"},
            {value: "tsql", text: "T-SQL"},
            {value: "tcl", text: "TCL"},
            {value: "teraterm", text: "Tera Term"},
            {value: "thinbasic", text: "thinBasic"},
            {value: "typoscript", text: "TypoScript"},
            {value: "unicon", text: "Unicon"},
            {value: "uscript", text: "UnrealScript"},
            {value: "ups", text: "UPC"},
            {value: "urbi", text: "Urbi"},
            {value: "vala", text: "Vala"},
            {value: "vbnet", text: "VB.NET"},
            {value: "vedit", text: "Vedit"},
            {value: "verilog", text: "VeriLog"},
            {value: "vhdl", text: "VHDL"},
            {value: "vim", text: "VIM"},
            {value: "visualprolog", text: "Visual Pro Log"},
            {value: "vb", text: "VisualBasic"},
            {value: "visualfoxpro", text: "VisualFoxPro"},
            {value: "whitespace", text: "WhiteSpace"},
            {value: "whois", text: "WHOIS"},
            {value: "winbatch", text: "Winbatch"},
            {value: "xbasic", text: "XBasic"},
            {value: "xml", text: "XML"},
            {value: "xorg_conf", text: "Xorg Config"},
            {value: "xpp", text: "XPP"},
            {value: "yaml", text: "YAML"},
            {value: "z80", text: "Z80 Assembler"},
            {value: "zxbasic", text: "ZXBasic"}
        ],
        timeFrames: [
            {value: "N", text: "Never"},
            {value: "10M", text: "10 Minutes"},
            {value: "1H", text: "1 Hour"},
            {value: "1D", text: "1 Day", selected: true},
            {value: "1W", text: "1 Week"},
            {value: "2W", text: "2 Weeks"},
            {value: "1M", text: "1 Month"}
        ]
    },
    time = {
        intervalHandle: 0,
        updateTimestamp: function () {
            var timestamp = new Date().getTime();
            if (document.activeElement.id !== "timestamp") {
                updateOutput("timestamp", (timestamp / 1000 | 0).toString());
            }
            if (!this.intervalHandle) {
                time.intervalHandle = setInterval(this.updateTimestamp, 1000);
            }
        },
        pauseTimestamp: function () {
            if (this.intervalHandle) {
                clearInterval(this.intervalHandle);
                this.intervalHandle = 0;
            }
        },
        getNiceTimestampConversion: function (input) {
            var epoch,
                result,
                timestampType;
            if (input.charAt(input.length - 1) == "L") {
                input = input.slice(0, -1);
            }
            input *= 1;
            epoch = input;

            //determine timestampType
            timestampType = document.getElementById("timestampType").value;
            switch (timestampType) {
                case "A":
                    if (epoch >= 100000000000) {
                        epoch = (epoch / 1e3 | 0);
                    }
                    if (epoch >= 100000000000) {
                        epoch = (epoch / 1e3 | 0);
                    }
                    break;
                case "MILLI":
                    epoch = (epoch / 1e3 | 0);
                    break;
                case "MICRO":
                    epoch = (epoch / 1e6 | 0);
                    break;
                case "SEC":
                default:
                    //do nothing
                    break;
            }
            result = this.getHumanFormatForSeconds(epoch);
            //add MongoId
            result += "\nObjectId(\"" + epoch.toString(16) + "0000000000000000\")";
            return result;
        },
        getHumanFormatForSeconds: function (input) {
            var date = new Date(input * 1000),
                localTime,
                gmtTime,
                result = input + "\n";
            if (Object.prototype.toString.call(date) !== "[object Date]" || date.toString() === "Invalid Date") {
                result = "Cannot parse date";
            } else {
                localTime = date.getFullYear() + "-" +
                ("0" + (date.getMonth() + 1)).slice(-2) + "-" +
                ("0" + date.getDate()).slice(-2) + " " +
                ("0" + date.getHours()).slice(-2) + ":" +
                ("0" + date.getMinutes()).slice(-2) + ":" +
                ("0" + date.getSeconds()).slice(-2) + " GMT" + ((-date.getTimezoneOffset() > 0) ? "+" : "-") + (-date.getTimezoneOffset() / 60).toString();
                gmtTime = date.getUTCFullYear() + "-" +
                ("0" + (date.getUTCMonth() + 1)).slice(-2) + "-" +
                ("0" + date.getUTCDate()).slice(-2) + " " +
                ("0" + date.getUTCHours()).slice(-2) + ":" +
                ("0" + date.getUTCMinutes()).slice(-2) + ":" +
                ("0" + date.getUTCSeconds()).slice(-2) + " GMT";

                result += gmtTime;
                if (date.getTimezoneOffset() !== 0) {
                    result += "\n" + localTime;
                }
            }
            return result;
        },
        updateDate: function () {
            var date = new Date();
            updateOutput("date-yyyy", date.getUTCFullYear());
            updateOutput("date-mm", ("0" + date.getUTCMonth()).slice(-2));
            updateOutput("date-dd", ("0" + date.getUTCDate()).slice(-2));
            updateOutput("date-hh", ("0" + date.getUTCHours()).slice(-2));
            updateOutput("date-ii", ("0" + date.getUTCMinutes()).slice(-2));
            updateOutput("date-ss", ("0" + date.getUTCSeconds()).slice(-2));
        },
        convertHumanToEpoch: function () {
            var tz = document.getElementById("date-tz").value,
                d,
                yyyy = document.getElementById("date-yyyy").value,
                mm = document.getElementById("date-mm").value,
                dd = document.getElementById("date-dd").value,
                hh = document.getElementById("date-hh").value,
                ii = document.getElementById("date-ii").value,
                ss = document.getElementById("date-ss").value,
                epoch;
            if (tz == 2) {
                d = new Date(yyyy, mm - 1, dd, hh, ii, ss);
            } else {
                d = new Date(Date.UTC(yyyy, mm - 1, dd, hh, ii, ss));
            }
            epoch = (d.getTime() / 1000);
            updateOutput("timestampResult", epoch)
        }
    },
    updateOutput = function (id, result) {
        if (document.getElementById(id).value !== undefined) {
            document.getElementById(id).value = result;
        }
        else {
            document.getElementById(id).innerHTML = result;
        }
    };


text:
layout: page
title: Archivo
description: archive
header-img: "img/misc-bg.jpg"
---

        {% for post in site.posts %}
            {% capture post_year %}{{ post.date | date: '%Y' }}{% endcapture %}
            {% capture post_month %}{{ post.date | date: '%B' }}{% endcapture %}
            {% if forloop.first %}

{{ post_year }}

{{ post_month }}

            {% endif %}

            {% if forloop.first == false %}
                {% assign previous_index = forloop.index0 | minus: 1 %}
                {% capture previous_post_year %}{{ site.posts[previous_index].date | date: '%Y' }}{% endcapture %}
                {% capture previous_post_month %}{{ site.posts[previous_index].date | date: '%B' }}{% endcapture %}
                {% if post_year != previous_post_year %}

{{ post_year }}

                {% endif %}
                {% if post_month != previous_post_month %}

{{ post_month }}

                {% endif %}
            {% endif %}

                {{ post.title }}

            {% if forloop.last %}

            {% endif %}
        {% endfor %}

Etiquetas

    {% assign tags = site.tags | sort %}
    {% for tag in tags %}

            {{ tag[0] | replace:'-', ' ' }} ({{ tag | last | size }})

    {% unless forloop.last %} {% endunless %}{% endfor %}

Cateogrías

    {% assign categories = site.categories | sort %}
    {% for category in categories %}

            {{ category[0] | replace:'-', ' ' }} ({{ category | last | size }})

    {% unless forloop.last %} {% endunless %}{% endfor %}


text:
<?php

namespace TestBundle\Controller;

class HomeController
{
    public function homeAction()
    {

    }
}


text:
'use strict';

var React = require('react');
var ReactNative = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  Dimensions
} = ReactNative;

var Controllers = require('react-native-controllers');
var {
  Modal,
} = Controllers;

var LightBox = React.createClass({
  _onButtonClick: function() {
    Modal.dismissLightBox();
  },

  render: function() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          This is a LightBox!
        </Text>
        <Text style={[styles.welcome, {fontSize: 16, marginTop: 20}]}>
          {this.props.greeting}
        </Text>
        <TouchableOpacity onPress={ this._onButtonClick }>
          <Text style={styles.button}>Dismiss</Text>
        </TouchableOpacity>
      </View>
    );
  },
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    width: Dimensions.get('window').width * 0.8,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'white',
    borderRadius: 10
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
  button: {
    textAlign: 'center',
    fontSize: 18,
    marginBottom: 10,
    marginTop:10,
    color: 'blue'
  }
});

AppRegistry.registerComponent('LightBox', () => LightBox);

module.exports = LightBox;