[
  {
    "path": ".gitattributes",
    "content": "*.gif filter=lfs diff=lfs merge=lfs -text\n*.png filter=lfs diff=lfs merge=lfs -text\n*.jpg filter=lfs diff=lfs merge=lfs -text\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Platform:**\n- Eg Mac ST3 or PC ST4\n\n** Sublime debug console output**\nCtrl-~ and include the output here. This may have an exception we need to deal with.\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".python-version",
    "content": "3.8"
  },
  {
    "path": "Default.sublime-keymap",
    "content": "[\n\n\t{ \"keys\": [\"ctrl+shift+x\"],      \"command\": \"org_capture\"                                                                                                          },\n\t{ \"keys\": [\"ctrl+up\"],           \"command\": \"org_up\" ,                       \"context\": [{ \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" }]},\n\t{ \"keys\": [\"ctrl+down\"],         \"command\": \"org_down\" ,                     \"context\": [{ \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" }]},\n    // TODO: ST4 REQUIRES the use of context vs wrapping.\n    //       Split these appart to make the easier to manage.\n\n    { \"keys\": [\"tab\"],               \"command\": \"org_tab_cycling\",               \"context\": \n        [\n            { \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" },\n            { \"key\": \"org_table\",  \"operator\": \"equal\", \"operand\": true },\n            { \"key\": \"has_next_field\", \"operator\": \"not_equal\", \"operand\": true},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"shift+tab\"], \"command\": \"table_editor_previous_field\", \"context\":\n        [\n            { \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" },\n            { \"key\": \"org_table\",  \"operator\": \"equal\", \"operand\": true },\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n\t{ \"keys\": [\"tab\"],               \"command\": \"org_tab_cycling\",               \"context\": \n        [\n            { \"key\": \"eol_selector\",   \"operator\": \"equal\",     \"operand\": \"text.orgmode\" },\n            { \"key\": \"org_heading\",    \"operator\": \"equal\",     \"operand\": true },\n            { \"key\": \"has_next_field\", \"operator\": \"not_equal\", \"operand\": true}\n        ]\n    },\n    { \"keys\": [\"shift+tab\"],         \"command\": \"org_global_tab_cycling\",               \"context\": \n        [\n            { \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" },\n            { \"key\": \"org_heading\",  \"operator\": \"equal\", \"operand\": true },\n            { \"key\": \"has_next_field\", \"operator\": \"not_equal\", \"operand\": true}\n        ]\n    },\n    { \"keys\": [\"tab\"],               \"command\": \"org_tab_cycling\",               \"context\": \n        [\n            { \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" },\n            { \"key\": \"org_link\",  \"operator\": \"equal\", \"operand\": true },\n            { \"key\": \"auto_complete_visible\", \"operator\": \"equal\", \"operand\": false},\n            { \"key\": \"has_next_field\", \"operator\": \"not_equal\", \"operand\": true}\n        ]\n    },\n    { \"keys\": [\"tab\"],               \"command\": \"org_tab_cycling\",               \"context\": \n        [\n            { \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" },\n            { \"key\": \"org_global\",  \"operator\": \"equal\", \"operand\": true },\n            { \"key\": \"org_table\",  \"operator\": \"equal\", \"operand\": false },\n            { \"key\": \"has_next_field\", \"operator\": \"not_equal\", \"operand\": true}\n        ]\n    },\n    { \"keys\": [\"tab\"],               \"command\": \"org_tab_cycling\",               \"context\": \n        [\n            { \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" },\n            { \"key\": \"org_checkbox\",  \"operator\": \"equal\", \"operand\": true },\n            { \"key\": \"has_next_field\", \"operator\": \"not_equal\", \"operand\": true}\n        ]\n    },\n    { \"keys\": [\"tab\"],               \"command\": \"org_tab_cycling\",               \"context\": \n        [\n            { \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" },\n            { \"key\": \"org_block\",  \"operator\": \"equal\", \"operand\": true },\n            { \"key\": \"has_next_field\", \"operator\": \"not_equal\", \"operand\": true}\n        ]\n    },\n    { \"keys\": [\"tab\"], \"command\": \"expand_snippet\", \"context\":\n        [\n            { \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" },\n            { \"key\": \"has_snippet\" }\n        ]\n    },\n\n\t{ \"keys\": [\"ctrl+alt+x\"],        \"command\": \"org_open_refile\"                                                                                                      },\n\n\n\n    // Core OrgMode Behaviour\n    //{ \"keys\": [\"enter\"],             \"command\": \"orgmode_toggle_checkbox\",         \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.checkbox\" }]},\n    //{ \"keys\": [\"enter\"],             \"command\": \"orgmode_recalc_checkbox_summary\", \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.checkbox.summary\" }]},\n    { \"keys\": [\"enter\"],             \"command\": \"org_open_link\",                   \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.link\" },{ \"key\": \"auto_complete_visible\", \"operator\": \"equal\", \"operand\": false}]},\n    { \"keys\": [\"enter\"],             \"command\": \"orgmode_cycle_internal_link\",     \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.link.internal\" }]},\n    { \"keys\": [\"enter\"],             \"command\": \"org_enter_on_heading\",            \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.headline\" }],  \"args\": { \"Indent\": 1} },\n    { \"keys\": [\"enter\"],             \"command\": \"org_enter_on_heading\",            \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.headline2\" }], \"args\": { \"Indent\": 2} },\n    { \"keys\": [\"enter\"],             \"command\": \"org_enter_on_heading\",            \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.headline3\" }], \"args\": { \"Indent\": 3} },\n    { \"keys\": [\"enter\"],             \"command\": \"org_enter_on_heading\",            \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.headline4\" }], \"args\": { \"Indent\": 4} },\n    { \"keys\": [\"enter\"],             \"command\": \"org_enter_on_heading\",            \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.headline5\" }], \"args\": { \"Indent\": 5} },\n    { \"keys\": [\"enter\"],             \"command\": \"org_enter_on_heading\",            \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.headline6\" }], \"args\": { \"Indent\": 6} },\n    { \"keys\": [\"enter\"],             \"command\": \"org_enter_on_heading\",            \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.headline7\" }], \"args\": { \"Indent\": 7} },\n    { \"keys\": [\"enter\"],             \"command\": \"org_enter_on_heading\",            \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.headline8\" }], \"args\": { \"Indent\": 8} },\n    { \"keys\": [\"enter\"],             \"command\": \"org_enter_on_heading\",            \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"orgmode.headline9\" }], \"args\": { \"Indent\": 9} },\n    { \"keys\": [\"ctrl+enter\"],        \"command\": \"org_generic_insert\",              \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"text.orgmode\" }]},\n    { \"keys\": [\"ctrl+shift+enter\"],  \"command\": \"org_generic_insert_aux\",          \"context\": [{ \"key\": \"selector\", \"operator\": \"equal\", \"operand\":  \"text.orgmode\" }]},\n\n    // Normal non vim style bindings\n    { \"keys\": [\"alt+o\",\"z\"],         \"command\": \"org_capture\"                  },\n    { \"keys\": [\"alt+o\",\"a\", \"d\"],    \"command\": \"org_agenda_day_view\"          },\n\n    { \"keys\": [\"alt+o\", \"t\"],        \"command\": \"org_toggle\",                    \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"R\"],        \"command\": \"org_refile\",                    \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"p\"],            \"command\": \"org_priority_change\",           \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"right\"],        \"command\": \"org_change_indent\",             \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"left\"],         \"command\": \"org_change_de_indent\",          \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"up\"],           \"command\": \"org_move_heading_up\",           \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"down\"],         \"command\": \"org_move_heading_down\",         \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"i\", \"h\"],       \"command\": \"org_insert_heading_sibling\",    \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"i\", \"c\"],       \"command\": \"org_insert_heading_child\",      \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"i\", \"d\", \"i\"],  \"command\": \"org_insert_date_inactive\",      \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"i\", \"d\", \"a\"],  \"command\": \"org_insert_date_active\",        \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"i\", \"t\"],       \"command\": \"org_insert_tag\",                \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"i\", \"i\"],       \"command\": \"org_insert_custom_id\",          \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"i\", \"s\"],       \"command\": \"org_schedule\",                  \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"i\", \"t\"],       \"command\": \"org_active_timestamp\",          \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"i\", \"e\"],       \"command\": \"org_deadline\",                  \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"c\", \"i\"],       \"command\": \"org_clock_in\",                  \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"c\", \"o\"],       \"command\": \"org_clock_out\",                 \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"c\", \"c\"],       \"command\": \"org_recalc\",                    \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"c\", \"s\"],       \"command\": \"org_insert_checkbox_summary\",   \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\"alt+o\", \"y\", \"l\"],       \"command\": \"org_create_link\",               \"context\": []},\n    { \"keys\": [\"alt+o\", \"m\", \"s\"],       \"command\": \"org_select_subtree\",            \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]},\n    { \"keys\": [\"alt+o\", \"m\", \"e\"],       \"command\": \"org_select_entity\",             \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]},\n    { \"keys\": [\"alt+o\", \"y\", \"s\"],       \"command\": \"org_copy_subtree\",              \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]},\n    { \"keys\": [\"alt+o\", \"y\", \"e\"],       \"command\": \"org_copy_entity\",               \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]},\n\n    // DAYPAGE\n    { \"keys\": [\"alt+o\", \"d\", \"n\"],       \"command\": \"org_day_page_next\",             \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]  },\n    { \"keys\": [\"alt+o\", \"d\", \"p\"],       \"command\": \"org_day_page_previous\",         \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]  },\n    { \"keys\": [\"alt+o\", \"d\", \"c\"],       \"command\": \"org_day_page_create\",                                                                             },\n    // TABLES\n    { \"keys\": [\"alt+o\", \"t\", \"a\"],       \"command\": \"table_editor_align\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+o\",\"t\",\"j\"],         \"command\": \"table_editor_join_lines\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+o\",\"t\", \"-\"],        \"command\": \"table_editor_insert_single_hline\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+o\",\"t\", \"=\"],        \"command\": \"table_editor_insert_double_hline\", \"context\":\n        [\n            { \"key\": \"eol_selector\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+o\",\"enter\"],         \"command\": \"table_editor_hline_and_move\", \"context\":\n        [\n            { \"key\": \"eol_selector\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"enter\"], \"command\": \"table_editor_next_row\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"shift+enter\"], \"command\": \"table_editor_split_column_down\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+right\"], \"command\": \"table_editor_move_column_right\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+left\"], \"command\": \"table_editor_move_column_left\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+shift+left\"], \"command\": \"table_editor_delete_column\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+shift+right\"], \"command\": \"table_editor_insert_column\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+shift+up\"], \"command\": \"table_editor_kill_row\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+shift+down\"], \"command\": \"table_editor_insert_row\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+up\"], \"command\": \"table_editor_move_row_up\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\"alt+down\"], \"command\": \"table_editor_move_row_down\", \"context\":\n        [\n            { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n\n    // ORG AGENDA NORMAL KEYBINDING\n    { \"keys\": [\"alt+o\", \"o\", \"a\"],       \"command\": \"org_agenda_custom_view\",        \"context\": []  },\n    { \"keys\": [\"enter\"],             \"command\": \"org_agenda_go_to\",                  \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\" \"],                 \"command\": \"org_agenda_go_to_split\",            \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"g\"],                 \"command\": \"org_agenda_day_view\",               \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\",\"],                 \"command\": \"org_agenda_change_priority\",        \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"s\"],                 \"command\": \"org_agenda_change_todo\",            \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"e\"],                 \"command\": \"org_agenda_insert_effort\",          \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"i\"],                 \"command\": \"org_agenda_id\"           ,          \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"t\"],                 \"command\": \"org_agenda_insert_tag\",             \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"a\"],                 \"command\": \"org_agenda_assign\",                 \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"c\",\"i\"],             \"command\": \"org_agenda_clock_in\",               \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"c\",\"o\"],             \"command\": \"org_agenda_clock_out\",              \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\">\"],                 \"command\": \"org_agenda_goto_next_day\",          \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"<\"],                 \"command\": \"org_agenda_goto_prev_day\",          \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"alt+o\", \"f\", \"f\"],   \"command\": \"org_agenda_re_open_filter_view\",    \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n\n\n\t// NeoVintageous - Command / Normal Mode - Quick commands\n    // GLOBAL BINDINGS\n    { \"keys\": [\"Z\"],                 \"command\": \"org_capture\",                   \"context\": [{\"key\": \"vi_command_mode_aware\"}]                                                      },\n    { \"keys\": [\"shift+space\"],       \"command\": \"org_agenda_day_view\",           \"context\": [{\"key\": \"vi_command_mode_aware\"}]                                                      },\n    { \"keys\": [\" \", \"y\", \"l\"],       \"command\": \"org_create_link\",               \"context\": [{\"key\": \"vi_command_mode_aware\"}]},\n    // Personal Doom/Spacemacs style keybindings. Really should be in their own package.\n    // I will move at some future point.\n    // Spacemacs style group switching. I prefer this, feel free to remove.\n    { \"keys\": [\" \", \"1\"],            \"command\": \"focus_group\",                   \"context\": [{\"key\": \"vi_command_mode_aware\"}], \"args\": { \"group\": 0}  },\n    { \"keys\": [\" \", \"2\"],            \"command\": \"focus_group\",                   \"context\": [{\"key\": \"vi_command_mode_aware\"}], \"args\": { \"group\": 1}  },\n    { \"keys\": [\" \", \"3\"],            \"command\": \"focus_group\",                   \"context\": [{\"key\": \"vi_command_mode_aware\"}], \"args\": { \"group\": 2}  },\n    { \"keys\": [\" \", \"4\"],            \"command\": \"focus_group\",                   \"context\": [{\"key\": \"vi_command_mode_aware\"}], \"args\": { \"group\": 3}  },\n    { \"keys\": [\" \", \"5\"],            \"command\": \"focus_group\",                   \"context\": [{\"key\": \"vi_command_mode_aware\"}], \"args\": { \"group\": 4}  },\n    // Spacemacs style save file\n    { \"keys\": [\" \", \"f\", \"s\"],       \"command\": \"save\",                          \"context\": [{\"key\": \"vi_command_mode_aware\"}]},\n    // ORGMODE BINDINGS\n    { \"keys\": [\" \", \"t\"],            \"command\": \"org_toggle\",                    \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}, { \"key\": \"selector\", \"operator\": \"not_equal\", \"operand\": \"orgmode.table\"} ] },\n    { \"keys\": [\"R\"],                 \"command\": \"org_refile\",                    \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \",\"r\",\"f\"],         \"command\": \"org_refile_to_file\",            \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \",\"r\",\"r\"],         \"command\": \"org_refile_to_file_and_headline\",\"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n\n    { \"keys\": [\" \",\"r\",\"m\"],         \"command\": \"org_remove_tag\",                \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \",\"r\",\"a\",\"m\"],     \"command\": \"org_remove_all_tags\",           \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"p\"],            \"command\": \"org_priority_change\",           \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"right\"],        \"command\": \"org_change_indent\",             \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"left\"],         \"command\": \"org_change_de_indent\",          \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"up\"],           \"command\": \"org_move_heading_up\",           \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"down\"],         \"command\": \"org_move_heading_down\",         \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"i\", \"h\"],       \"command\": \"org_insert_heading_sibling\",    \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"i\", \"c\"],       \"command\": \"org_insert_heading_child\",      \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"i\", \"d\", \"i\"],  \"command\": \"org_insert_date_inactive\",      \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"i\", \"d\", \"a\"],  \"command\": \"org_insert_date_active\",        \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"i\", \"m\"],       \"command\": \"org_insert_tag\",                \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"i\", \"i\"],       \"command\": \"org_insert_custom_id\",          \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"i\", \"s\"],       \"command\": \"org_schedule\",                  \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"i\", \"t\"],       \"command\": \"org_active_timestamp\",          \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"i\", \"e\"],       \"command\": \"org_deadline\",                  \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"c\", \"i\"],       \"command\": \"org_clock_in\",                  \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"c\", \"o\"],       \"command\": \"org_clock_out\",                 \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"c\", \"c\"],       \"command\": \"org_recalc\",                    \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}] },\n    { \"keys\": [\" \", \"c\", \"s\"],       \"command\": \"org_insert_checkbox_summary\",   \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]  },\n    { \"keys\": [\" \", \"m\", \"s\"],       \"command\": \"org_select_subtree\",            \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]  },\n    { \"keys\": [\" \", \"m\", \"e\"],       \"command\": \"org_select_entity\",             \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]  },\n    { \"keys\": [\" \", \"y\", \"s\"],       \"command\": \"org_copy_subtree\",              \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]  },\n    { \"keys\": [\" \", \"y\", \"e\"],       \"command\": \"org_copy_entity\",               \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]  },\n    { \"keys\": [\" \", \"f\", \"o\"],       \"command\": \"org_fold_all_but_me\",           \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]  },\n    { \"keys\": [\" \", \"f\", \"m\"],       \"command\": \"org_fix_tags\",                  \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]  },\n    \n    // DAYPAGE\n    { \"keys\": [\" \", \"d\", \"n\"],       \"command\": \"org_day_page_next\",             \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]  },\n    { \"keys\": [\" \", \"d\", \"p\"],       \"command\": \"org_day_page_previous\",         \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"text.orgmode\"}]  },\n    { \"keys\": [\" \", \"d\", \"c\"],       \"command\": \"org_day_page_create\",           \"context\": [{\"key\": \"vi_command_mode_aware\"}]  },\n\n    // ORG AGENDA\n    { \"keys\": [\" \", \"o\", \"a\"],       \"command\": \"org_agenda_custom_view\",        \"context\": [{\"key\": \"vi_command_mode_aware\"}]  },\n    { \"keys\": [\"enter\"],             \"command\": \"org_agenda_go_to\",              \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\" \"],                 \"command\": \"org_agenda_go_to_split\",        \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"g\"],                 \"command\": \"org_agenda_day_view\",           \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\",\"],                 \"command\": \"org_agenda_change_priority\",    \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"t\"],                 \"command\": \"org_agenda_change_todo\",        \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"c\",\"i\"],             \"command\": \"org_agenda_clock_in\",           \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"c\",\"o\"],             \"command\": \"org_agenda_clock_out\",          \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\">\"],                 \"command\": \"org_agenda_goto_next_day\",      \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"<\"],                 \"command\": \"org_agenda_goto_prev_day\",      \"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"f\", \"f\"],            \"command\": \"org_agenda_re_open_filter_view\",\"context\": [{\"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n\n\n    // TABLES\n    { \"keys\": [\" \", \"t\", \"a\"],       \"command\": \"table_editor_align\", \"context\":\n        [\n            { \"key\": \"vi_command_mode_aware\"}, { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\" \",\"t\",\"j\"],         \"command\": \"table_editor_join_lines\", \"context\":\n        [\n            { \"key\": \"vi_command_mode_aware\"}, { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"\\\\|\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\" \",\"t\", \"-\"],        \"command\": \"table_editor_insert_single_hline\", \"context\":\n        [\n            { \"key\": \"vi_command_mode_aware\"}, { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\" \",\"t\", \"=\"],        \"command\": \"table_editor_insert_double_hline\", \"context\":\n        [\n            { \"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\" \",\"enter\"],         \"command\": \"table_editor_hline_and_move\", \"context\":\n        [\n            { \"key\": \"vi_command_mode_aware\"}, { \"key\": \"eol_selector\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\" \", \"t\", \"e\"],       \"command\": \"org_edit_formula_for_cell\", \"context\":\n        [\n            { \"key\": \"vi_command_mode_aware\"}, { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n    { \"keys\": [\" \", \"t\", \"k\"],       \"command\": \"org_clear_cell\", \"context\":\n        [\n            { \"key\": \"vi_command_mode_aware\"}, { \"key\": \"selector\", \"operator\": \"equal\", \"operand\": \"orgmode.table\"},\n            { \"key\": \"preceding_text\", \"operator\": \"regex_contains\", \"operand\": \"^\\\\s*\\\\|\", \"match_all\": true },\n            { \"key\": \"following_text\", \"operator\": \"regex_contains\", \"operand\": \"$\", \"match_all\": true }\n        ]\n    },\n\n\n    // ORG DATE PICKER\n    { \"keys\": [\">\"],                 \"command\": \"org_date_picker_next_day\",         \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgdateeditor\"}]  },\n    { \"keys\": [\"<\"],                 \"command\": \"org_date_picker_prev_day\",         \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgdateeditor\"}]  },\n    { \"keys\": [\"ctrl+,\"],            \"command\": \"org_date_picker_prev_week\",        \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgdateeditor\"}]  },\n    { \"keys\": [\"ctrl+.\"],            \"command\": \"org_date_picker_next_week\",        \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgdateeditor\"}]  },\n    { \"keys\": [\"alt+,\"],             \"command\": \"org_date_picker_prev_month\",       \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgdateeditor\"}]  },\n    { \"keys\": [\"alt+.\"],             \"command\": \"org_date_picker_next_month\",       \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgdateeditor\"}]  },\n    { \"keys\": [\"ctrl+shift+,\"],      \"command\": \"org_date_picker_prev_hour\",        \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgdateeditor\"}]  },\n    { \"keys\": [\"ctrl+shift+.\"],      \"command\": \"org_date_picker_next_hour\",        \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgdateeditor\"}]  },\n    { \"keys\": [\"alt+shift+,\"],       \"command\": \"org_date_picker_prev_minute\",      \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgdateeditor\"}]  },\n    { \"keys\": [\"alt+shift+.\"],       \"command\": \"org_date_picker_next_minute\",      \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgdateeditor\"}]  },\n    // ORG INPUT SELECTOR\n    { \"keys\": [\"down\"],             \"command\": \"org_input_down\",                \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orginput\"}]  },\n    { \"keys\": [\"up\"],               \"command\": \"org_input_up\",                  \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orginput\"}]  }\n]\n "
  },
  {
    "path": "Indentation Rules.tmPreferences",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n   <key>name</key>\n   <string>orgmode</string>\n   <key>scope</key>\n   <string>text.orgmode</string>\n   <key>settings</key>\n   <dict>\n      <key>increaseIndentPattern</key>\n      <string>(^\\s*[#][+]((BEGIN)|(begin)))|(^\\s*[*]+ )</string>\n      <key>decreaseIndentPattern</key>\n      <string>(^\\s*[#][+]((END)|(end)))</string>\n   </dict>\n   <key>uuid</key>\n   <string>BC062860-3346-4D3B-8421-C3543F83D11F</string>\n</dict>\n</plist>"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Ian Davids\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Main.sublime-menu",
    "content": "[\n    {\n        \"mnemonic\": \"n\", \n        \"caption\": \"Preferences\", \n        \"id\": \"preferences\", \n        \"children\": [\n            {\n                \"mnemonic\": \"P\", \n                \"caption\": \"Package Settings\", \n                \"id\": \"package-settings\", \n                \"children\": [\n                    {\n                        \"caption\": \"Org Extended\", \n                        \"children\": [\n                            {\n                                \"caption\": \"Docs\", \n                                \"args\": {\n                                    \"url\": \"https://github.com/ihdavids/orgextended_docs/blob/master/start.org\"\n                                }, \n                                \"command\": \"open_url\"\n                            }, \n                            {\n                                \"caption\": \"-\"\n                            },\n                            {\n                                \"caption\": \"Setup MouseMap\", \n                                \"command\": \"org_setup_mouse_map\"\n                            }, \n                            {\n                                \"caption\": \"Open MouseMap\", \n                                \"args\": {\n                                    \"file\": \"${packages}/User/Default.sublime-mousemap\"\n                                }, \n                                \"command\": \"open_file\"\n                            }, \n                            {\n                                \"caption\": \"-\"\n                            },\n                            {\n                                \"caption\": \"Settings\",\n                                \"command\": \"edit_settings\", \"args\":\n                                {\n                                    \"base_file\": \"${packages}/OrgExtended/OrgExtended.sublime-settings\",\n                                    \"default\": \"// OrgExtended Settings - User\\n{\\n\\t$0\\n}\\n\"\n                                }\n                            },\n                            {\n                                \"caption\": \"Key Bindings\",\n                                \"command\": \"edit_settings\", \"args\":\n                                {\n                                    \"base_file\": \"${packages}/OrgExtended/Default.sublime-keymap\",\n                                    \"user_file\": \"${packages}/User/Default ($platform).sublime-keymap\"\n                                }\n                            },\n                            {\n                                \"caption\": \"-\"\n                            }\n                        ]\n                    }\n                ]\n            }\n        ]\n    }\n]"
  },
  {
    "path": "OrgBeancount.sublime-settings",
    "content": "{\n\t\"somevalue\": true,\n}\n"
  },
  {
    "path": "OrgBeancount.sublime-syntax",
    "content": "%YAML 1.2\n---\n# See http://www.sublimetext.com/docs/3/syntax.html\nname: OrgBeancount\nfile_extensions:\n  - orgbeancount\nversion: 2\nextends: Packages/OrgExtended/OrgExtended.sublime-syntax\nscope: source.orgbeancount text.orgmode\ncontexts:\n  comment:\n    # Comment\n    - match: ;.*\n      scope: comment.line.beancount\n  comments:\n    - match: (?<=\\s)(;.*)(?=\\n)\n      captures:\n        1: comment.line.beancount\n  illegal:\n    - match: ([^\\s])\n      scope: invalid.illegal.unrecognized.beancount\n  amount:\n    - match: ([\\-|\\+]?)((?:\\d|\\d[\\d,]*\\d)(?:\\.\\d*)?)\\s*([A-Z][A-Z0-9\\'\\.\\_\\-]{0,22}[A-Z0-9])\n      captures:\n        1: keyword.operator.modifier.beancount\n        2: constant.numeric.currency.beancount\n        3: entity.type.commodity.beancount\n      scope: meta.amount.beancount\n  commodity:\n    - match: ([A-Z][A-Z0-9\\'\\.\\_\\-]{0,22}[A-Z0-9])\n      scope: entity.type.commodity.beancount\n  cost:\n    - match: \\{\\{?\n      captures:\n        0: keyword.operator.assignment.beancount\n      push:\n        - meta_scope: meta.cost.beancount\n        - include: amount\n        - include: date\n        - match: \\,\n          scope: punctuation.separator.beancount\n        - include: illegal\n        - match: \\}\\}?\n          captures:\n            0: keyword.operator.assignment.beancount\n          pop: true\n  date:\n    - match: ([0-9]{4})([\\-|/])([0-9]{2})([\\-|/])([0-9]{2})\n      scope: meta.date.beancount\n      captures:\n        1: constant.numeric.date.year.beancount\n        2: punctuation.separator.beancount\n        3: constant.numeric.date.month.beancount\n        4: punctuation.separator.beancount\n        5: constant.numeric.date.day.beancount\n  flag:\n    - match: (?<=\\s)([*!&amp;#?%PSTCURM])\n      scope: keyword.other.beancount\n  link:\n    - match: (?<=\\s)(\\^)([A-Za-z0-9\\-_/.]+)(?=\\s)\n      captures:\n        1: keyword.operator.link.beancount\n        2: markup.underline.link.beancount\n  meta:\n    - match: ^\\s*([a-z][A-Za-z0-9\\-]+)([:])\\s\n      captures:\n        1: keyword.operator.directive.beancount\n        2: punctuation.separator.beancount\n      push:\n        - meta_scope: meta.meta.beancount\n        - include: string\n        - include: comments\n        - include: illegal\n        - match: \\n\n          pop: true\n  posting:\n    - match: ^\\s+(?=([A-Z\\!]))\n      push:\n        - meta_scope: meta.posting.beancount\n        - include: meta\n        - include: comments\n        - include: flag\n        - include: account\n        - include: amount\n        - include: cost\n        - include: date\n        - include: price\n        - include: illegal\n        - match: (?=(^\\s*$|^\\S|^\\s*[A-Z]))\n          pop: true\n  price:\n    - match: \\@\\@?\n      captures:\n        0: keyword.operator.assignment.beancount\n      push:\n        - meta_scope: meta.price.beancount\n        - include: amount\n        - include: illegal\n        - match: (?=(;|\\n))\n          pop: true\n  string:\n    - match: \\\"\n      push:\n        - meta_scope: string.quoted.double.beancount\n        - match: \\\\.\n          scope: constant.character.escape.beancount\n        - match: \\\"\n          pop: true\n  tag:\n    - match: (?<=\\s)(#)([A-Za-z0-9\\-_/.]+)(?=\\s)\n      captures:\n        1: keyword.operator.tag.beancount\n        2: entity.name.tag.beancount\n  account:\n    # Account\n    - match: ([A-Z][A-Za-z0-9\\-]+)(:)\n      captures:\n        1: constant.language.beancount\n        2: punctuation.separator.beancount\n      push:\n        - meta_scope: meta.account.beancount\n        # Sub Accounts\n        - match: ([A-Z][A-Za-z0-9\\-]+)([:]?)\n          captures:\n            1: variable.account.beancount\n            2: punctuation.separator.beancount\n          push:\n            - match: ([:]?)|(\\s)\n              pop: true\n            - include: illegal\n            - include: $self\n        - match: \\s\n          pop: true\n  main:\n    - meta_append: true\n    # Tag directive\n    - match: ^(poptag|pushtag)\\s+(#)([A-Za-z0-9\\-_/.]+) \n      captures:\n        1: support.function.beancount\n        2: keyword.operator.tag.beancount\n        3: entity.name.tag.beancount \n      push:\n        - meta_scope: meta.directive.tag.beancount\n        - include: comment\n        - include: illegal\n        - match: (?=(^\\s*$|^\\S))\n          pop: true \n    # Include\n    - match: ^(include)\\s+(\\\".*\\\")\n      captures:\n        1: support.function.beancount\n        2: string.quoted.double.beancount\n      push:\n        - meta_scope: meta.directive.include.beancount\n        - include: comment\n        - include: illegal\n        - match: (?=(^\\s*$|^\\S))\n          pop: true \n    # Option directive\n    - match: ^(option)\\s+(\\\".*\\\")\\s+(\\\".*\\\")\n      captures:\n        1: support.function.beancount\n        2: support.variable.beancount\n        3: support.quoted.double.beancount\n      push:\n        - meta_scope: meta.directive.option.beancount\n        - include: comment\n        - include: illegal\n        - match: (?=(^\\s*$|^\\S))\n          pop: true\n    # Plugin\n    - match: ^(plugin)\\s+(\\\"(.*)\\\")\\s+(\\\".*\\\")\n      captures:\n        1: support.function.beancount\n        2: support.quoted.double.beancount\n        3: entity.name.function.beancount\n        4: string.quoted.double.beancount\n      push:\n        - meta_scope: keyword.operator.directive.beancount\n        - include: comment\n        - include: illegal\n        - match: (?=(^\\s*$|^\\S))\n          pop: true\n    # Open/Close/Pad directive\n    - match: ([0-9]{4})([\\-|/])([0-9]{2})([\\-|/])([0-9]{2})\\s+(open|close|pad)\n      captures:\n        1: constant.numeric.date.year.beancount\n        2: punctuation.separator.beancount\n        3: constant.numeric.date.month.beancount\n        4: punctuation.separator.beancount\n        5: constant.numeric.date.day.beancount\n        6: support.function.beancount\n      push:\n        - meta_scope: meta.directive.dated.beancount\n        - include: comment\n        - include: illegal\n        - include: account\n        - include: commodity\n        - match: \\,\n          scope: punctuation.separator.beancount\n        - match: (?=(^\\s*$|^\\S))\n          pop: true\n    # Event directive\n    - match: ([0-9]{4})([\\-|/])([0-9]{2})([\\-|/])([0-9]{2})\\s(event)\n      captures:\n        1: constant.numeric.date.year.beancount\n        2: punctuation.separator.beancount\n        3: constant.numeric.date.month.beancount\n        4: punctuation.separator.beancount\n        5: constant.numeric.date.day.beancount\n        6: support.function.directive.beancount\n      push:\n        - meta_scope: meta.directive.dated.beancount\n        - include: comment\n        - include: meta\n        - include: string\n        - include: illegal\n        - match: (?=(^\\s*$|^\\S))\n          pop: true\n    # Commodity directive\n    - match: ([0-9]{4})([\\-|/])([0-9]{2})([\\-|/])([0-9]{2})\\s(commodity)\n      captures:\n        1: constant.numeric.date.year.beancount\n        2: punctuation.separator.beancount\n        3: constant.numeric.date.month.beancount\n        4: punctuation.separator.beancount\n        5: constant.numeric.date.day.beancount\n        6: support.function.directive.beancount\n      push:\n        - meta_scope: meta.directive.dated.beancount\n        - include: comments\n        - include: meta\n        - include: commodity\n        - include: illegal\n        - match: (?=(^\\s*$|^\\S))\n          pop: true\n    # Note/Document directive\n    - match: ([0-9]{4})([\\-|/])([0-9]{2})([\\-|/])([0-9]{2})\\s(note|document)\n      captures:\n        1: constant.numeric.date.year.beancount\n        2: punctuation.separator.beancount\n        3: constant.numeric.date.month.beancount\n        4: punctuation.separator.beancount\n        5: constant.numeric.date.day.beancount\n        6: support.function.directive.beancount\n      push:\n        - meta_scope: meta.directive.dated.beancount\n        - include: comments\n        - include: meta\n        - include: account\n        - include: string\n        - include: illegal\n        - match: (?=(^\\s*$|^\\S))\n          pop: true\n    # Price directives\n    - match: ([0-9]{4})([\\-|/])([0-9]{2})([\\-|/])([0-9]{2})\\s(price)\n      captures:\n        1: constant.numeric.date.year.beancount\n        2: punctuation.separator.beancount\n        3: constant.numeric.date.month.beancount\n        4: punctuation.separator.beancount\n        5: constant.numeric.date.day.beancount\n        6: support.function.directive.beancount\n      push:\n        - meta_scope: meta.directive.dated.beancount\n        - include: comments\n        - include: meta\n        - include: commodity\n        - include: amount\n        - include: illegal\n        - match: (?=(^\\s*$|^\\S))\n          pop: true\n    # Balance directives\n    - match: ([0-9]{4})([\\-|/])([0-9]{2})([\\-|/])([0-9]{2})\\s(balance)\n      captures:\n        1: constant.numeric.date.year.beancount\n        2: punctuation.separator.beancount\n        3: constant.numeric.date.month.beancount\n        4: punctuation.separator.beancount\n        5: constant.numeric.date.day.beancount\n        6: support.function.directive.beancount\n      push:\n        - meta_scope: meta.directive.dated.beancount\n        - include: comments\n        - include: meta\n        - include: account\n        - include: amount\n        - include: illegal\n        - match: (?=(^\\s*$|^\\S))\n          pop: true\n    # Transaction directive\n    - match: ([0-9]{4})([\\-|/])([0-9]{2})([\\-|/])([0-9]{2})\\s+(txn|[*!&amp;#?%PSTCURM])(?:\\s+(\".*\")(?=\\s+\"))?\\s+(\".*?\")(?=((?:\\s+#[a-zA-z\\-]+(?=\\s))*(?:\\s+\\^[a-zA-z\\-\\.]+(?=\\s))*(?:\\s+;\\s*.*)?)\\s)\n      captures:\n        1: constant.numeric.date.year.beancount\n        2: punctuation.separator.beancount\n        3: constant.numeric.date.month.beancount\n        4: punctuation.separator.beancount\n        5: constant.numeric.date.day.beancount\n        6: support.function.directive.beancount\n        7: string.quoted.tiers.beancount\n        8: string.quoted.narration.beancount}       \n      push:\n        - meta_scope: meta.directive.transaction.beancount\n        - include: comments\n        - include: posting\n        - include: meta\n        - include: tag\n        - include: link\n        - include: illegal\n        - match: (?=(^\\s*$|^\\S))\n          pop: true\n"
  },
  {
    "path": "OrgExtended-Light.sublime-color-scheme",
    "content": "{\n\t\"name\": \"Org Extended Light\",\n\t\"globals\": {\n\t\t\"background\": \"#fafafa\",\n\t\t\"foreground\": \"#575f66\",\n\t\t\"invisibles\": \"#575f664d\",\n\t\t\"caret\": \"#ff9940\",\n\t\t\"block_caret\": \"#ff99404d\",\n\t\t\"line_highlight\": \"#8a91991a\",\n\t\t\"accent\": \"#ff9940\",\n\t\t\"popup_css\": \"\\n      html, body {\\n        background-color: #ffffff;\\n        color: #575f66;\\n      }\\n      body {\\n        padding: 1px 3px;\\n      }\\n      a {\\n        color: rgba(85,180,212, .7);\\n      }\\n    \",\n\t\t\"gutter\": \"#fafafa\",\n\t\t\"gutter_foreground\": \"#8a919966\",\n\t\t\"line_diff_width\": \"2\",\n\t\t\"line_diff_added\": \"#99bf4d\",\n\t\t\"line_diff_modified\": \"#709ecc\",\n\t\t\"line_diff_deleted\": \"#f27983\",\n\t\t\"selection\": \"#d1e4f4\",\n\t\t\"selection_border\": \"#e1e1e2\",\n\t\t\"selection_border_width\": \"1\",\n\t\t\"inactive_selection\": \"#e7e8e9\",\n\t\t\"inactive_selection_foreground\": \"#575f664d\",\n\t\t\"selection_corner_style\": \"round\",\n\t\t\"selection_corner_radius\": \"3\",\n\t\t\"highlight\": \"#ff994066\",\n\t\t\"find_highlight\": \"#ff9940\",\n\t\t\"find_highlight_foreground\": \"#fafafa\",\n\t\t\"guide\": \"#8a91992e\",\n\t\t\"active_guide\": \"#8a919959\",\n\t\t\"stack_guide\": \"#8a919966\",\n\t\t\"shadow\": \"#fafafa4d\",\n\t\t\"shadow_width\": \"0\"\n\t},\n\t\"rules\": [\n\t\t{\n\t\t\t\"background\": \"#000000\",\n\t\t\t\"scope\": \"col_gutter\",\n\t\t\t\"foreground\": \"#ffffff\"\n\t\t},\n\t\t{\n\t\t\t\"background\": \"#FFC0CBFF\",\n\t\t\t\"scope\": \"col_FFC0CBFF\",\n\t\t\t\"foreground\": \"#545454FF\"\n\t\t},\n\t\t{\n\t\t\t\"background\": \"#0000FFFF\",\n\t\t\t\"scope\": \"col_0000FFFF\",\n\t\t\t\"foreground\": \"#9D9D9DFF\"\n\t\t},\n\t\t{\n\t\t\t\"background\": \"#FF0000FF\",\n\t\t\t\"scope\": \"col_FF0000FF\",\n\t\t\t\"foreground\": \"#CCCCCCFF\"\n\t\t},\n\t\t{\n\t\t\t\"background\": \"#800080FF\",\n\t\t\t\"scope\": \"col_800080FF\",\n\t\t\t\"foreground\": \"#B4B4B4FF\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Comment\",\n\t\t\t\"scope\": \"comment\",\n\t\t\t\"font_style\": \"italic\",\n\t\t\t\"foreground\": \"#abb0b6\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"String\",\n\t\t\t\"scope\": \"string, constant.other.symbol\",\n\t\t\t\"foreground\": \"#86a300\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Regular Expressions and Escape Characters\",\n\t\t\t\"scope\": \"string.regexp, constant.character, constant.other\",\n\t\t\t\"foreground\": \"#4cbf99\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Number\",\n\t\t\t\"scope\": \"constant.numeric\",\n\t\t\t\"foreground\": \"#ff9940\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Built-in constants\",\n\t\t\t\"scope\": \"constant.language\",\n\t\t\t\"foreground\": \"#ff9940\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Constants\",\n\t\t\t\"scope\": \"meta.constant, entity.name.constant\",\n\t\t\t\"foreground\": \"#a37acc\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Variable\",\n\t\t\t\"scope\": \"variable\",\n\t\t\t\"foreground\": \"#575f66\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Member Variable\",\n\t\t\t\"scope\": \"variable.member\",\n\t\t\t\"foreground\": \"#f07171\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Language variable\",\n\t\t\t\"scope\": \"variable.language\",\n\t\t\t\"font_style\": \"italic\",\n\t\t\t\"foreground\": \"#55b4d4\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Storage\",\n\t\t\t\"scope\": \"storage, storage.type.keyword\",\n\t\t\t\"foreground\": \"#fa8d3e\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Keyword\",\n\t\t\t\"scope\": \"keyword\",\n\t\t\t\"foreground\": \"#fa8d3e\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Java keyword fixes\",\n\t\t\t\"scope\": \"source.java meta.class.java meta.class.identifier.java storage.type.java\",\n\t\t\t\"foreground\": \"#fa8d3e\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Operators\",\n\t\t\t\"scope\": \"keyword.operator\",\n\t\t\t\"foreground\": \"#ed9366\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Separators like ; or ,\",\n\t\t\t\"scope\": \"punctuation.separator, punctuation.terminator\",\n\t\t\t\"foreground\": \"#575f66b3\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Punctuation\",\n\t\t\t\"scope\": \"punctuation.section\",\n\t\t\t\"foreground\": \"#575f66\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Accessor\",\n\t\t\t\"scope\": \"punctuation.accessor\",\n\t\t\t\"foreground\": \"#ed9366\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Types fixes\",\n\t\t\t\"scope\": \"source.java storage.type, source.haskell storage.type, source.c storage.type\",\n\t\t\t\"foreground\": \"#399ee6\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Inherited class type\",\n\t\t\t\"scope\": \"entity.other.inherited-class\",\n\t\t\t\"foreground\": \"#55b4d4\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Lambda arrow\",\n\t\t\t\"scope\": \"storage.type.function\",\n\t\t\t\"foreground\": \"#fa8d3e\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Java primitive variable types\",\n\t\t\t\"scope\": \"source.java storage.type.primitive\",\n\t\t\t\"foreground\": \"#55b4d4\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Function name\",\n\t\t\t\"scope\": \"entity.name.function\",\n\t\t\t\"foreground\": \"#f2ae49\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Function arguments\",\n\t\t\t\"scope\": \"variable.parameter, meta.parameter\",\n\t\t\t\"foreground\": \"#a37acc\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Function call\",\n\t\t\t\"scope\": \"variable.function, variable.annotation, meta.function-call.generic, support.function.go\",\n\t\t\t\"foreground\": \"#f2ae49\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Library function\",\n\t\t\t\"scope\": \"support.function, support.macro\",\n\t\t\t\"foreground\": \"#f07171\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Imports and packages\",\n\t\t\t\"scope\": \"entity.name.import, entity.name.package\",\n\t\t\t\"foreground\": \"#86b300\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Entity name\",\n\t\t\t\"scope\": \"entity.name, source.js meta.function-call.constructor variable.type\",\n\t\t\t\"foreground\": \"#399ee6\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Tag\",\n\t\t\t\"scope\": \"entity.name.tag, meta.tag.sgml\",\n\t\t\t\"foreground\": \"#55b4d4\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Tag start/end\",\n\t\t\t\"scope\": \"punctuation.definition.tag.end, punctuation.definition.tag.begin, punctuation.definition.tag\",\n\t\t\t\"foreground\": \"#55b4d480\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Tag attribute\",\n\t\t\t\"scope\": \"entity.other.attribute-name\",\n\t\t\t\"foreground\": \"#f2ae49\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Library constant\",\n\t\t\t\"scope\": \"support.constant\",\n\t\t\t\"font_style\": \"italic\",\n\t\t\t\"foreground\": \"#ed9366\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Library class/type\",\n\t\t\t\"scope\": \"support.type, support.class, source.go storage.type\",\n\t\t\t\"foreground\": \"#55b4d4\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Decorators/annotation\",\n\t\t\t\"scope\": \"meta.decorator variable.other, meta.decorator punctuation.decorator, storage.type.annotation, variable.annotation, punctuation.definition.annotation\",\n\t\t\t\"foreground\": \"#e6ba7e\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Invalid\",\n\t\t\t\"scope\": \"invalid\",\n\t\t\t\"foreground\": \"#f51818\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"diff.header\",\n\t\t\t\"scope\": \"meta.diff, meta.diff.header\",\n\t\t\t\"foreground\": \"#c594c5\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Ruby class methods\",\n\t\t\t\"scope\": \"source.ruby variable.other.readwrite\",\n\t\t\t\"foreground\": \"#f2ae49\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"CSS tag names\",\n\t\t\t\"scope\": \"source.css entity.name.tag, source.sass entity.name.tag, source.scss entity.name.tag, source.less entity.name.tag, source.stylus entity.name.tag\",\n\t\t\t\"foreground\": \"#399ee6\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"CSS browser prefix\",\n\t\t\t\"scope\": \"source.css support.type, source.sass support.type, source.scss support.type, source.less support.type, source.stylus support.type\",\n\t\t\t\"foreground\": \"#abb0b6\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"CSS Properties\",\n\t\t\t\"scope\": \"support.type.property-name\",\n\t\t\t\"font_style\": \"normal\",\n\t\t\t\"foreground\": \"#55b4d4\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Search Results Nums\",\n\t\t\t\"scope\": \"constant.numeric.line-number.find-in-files - match\",\n\t\t\t\"foreground\": \"#abb0b6\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Search Results Match Nums\",\n\t\t\t\"scope\": \"constant.numeric.line-number.match\",\n\t\t\t\"foreground\": \"#fa8d3e\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Search Results Lines\",\n\t\t\t\"scope\": \"entity.name.filename.find-in-files\",\n\t\t\t\"foreground\": \"#86b300\"\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"message.error\",\n\t\t\t\"foreground\": \"#f51818\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup heading\",\n\t\t\t\"scope\": \"markup.heading, markup.heading entity.name\",\n\t\t\t\"font_style\": \"bold\",\n\t\t\t\"foreground\": \"#86b300\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup links\",\n\t\t\t\"scope\": \"markup.underline.link, string.other.link\",\n\t\t\t\"foreground\": \"#55b4d4\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup Italic\",\n\t\t\t\"scope\": \"markup.italic\",\n\t\t\t\"font_style\": \"italic\",\n\t\t\t\"foreground\": \"#f07171\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup Bold\",\n\t\t\t\"scope\": \"markup.bold\",\n\t\t\t\"font_style\": \"bold\",\n\t\t\t\"foreground\": \"#f07171\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup Bold/italic\",\n\t\t\t\"scope\": \"markup.italic markup.bold, markup.bold markup.italic\",\n\t\t\t\"font_style\": \"bold italic\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup Code\",\n\t\t\t\"scope\": \"markup.raw\",\n\t\t\t\"background\": \"#575f6605\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup Code Inline\",\n\t\t\t\"scope\": \"markup.raw.inline\",\n\t\t\t\"background\": \"#575f660f\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markdown Separator\",\n\t\t\t\"scope\": \"meta.separator\",\n\t\t\t\"font_style\": \"bold\",\n\t\t\t\"background\": \"#575f660f\",\n\t\t\t\"foreground\": \"#abb0b6\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup Blockquote\",\n\t\t\t\"scope\": \"markup.quote\",\n\t\t\t\"foreground\": \"#4cbf99\",\n\t\t\t\"font_style\": \"italic\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup List Bullet\",\n\t\t\t\"scope\": \"markup.list punctuation.definition.list.begin\",\n\t\t\t\"foreground\": \"#f2ae49\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup added\",\n\t\t\t\"scope\": \"markup.inserted\",\n\t\t\t\"foreground\": \"#99bf4d\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup modified\",\n\t\t\t\"scope\": \"markup.changed\",\n\t\t\t\"foreground\": \"#709ecc\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup removed\",\n\t\t\t\"scope\": \"markup.deleted\",\n\t\t\t\"foreground\": \"#f27983\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup Strike\",\n\t\t\t\"scope\": \"markup.strike\",\n\t\t\t\"foreground\": \"#e6ba7e\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup Table\",\n\t\t\t\"scope\": \"markup.table\",\n\t\t\t\"background\": \"#575f660f\",\n\t\t\t\"foreground\": \"#55b4d4\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markup Raw Inline\",\n\t\t\t\"scope\": \"text.html.markdown markup.inline.raw\",\n\t\t\t\"foreground\": \"#ed9366\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markdown - Line Break\",\n\t\t\t\"scope\": \"text.html.markdown meta.dummy.line-break\",\n\t\t\t\"background\": \"#abb0b6\",\n\t\t\t\"foreground\": \"#abb0b6\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Markdown - Raw Block Fenced\",\n\t\t\t\"scope\": \"punctuation.definition.markdown\",\n\t\t\t\"background\": \"#575f66\",\n\t\t\t\"foreground\": \"#abb0b6\"\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.break\",\n\t\t\t\"foreground\": \"#ed188a\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.page\",\n\t\t\t\"foreground\": \"#f5eebf\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline\",\n\t\t\t\"foreground\": \"#14adfa\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline2\",\n\t\t\t\"foreground\": \"#bb86fc\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline3\",\n\t\t\t\"foreground\": \"#03cab5\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline4\",\n\t\t\t\"foreground\": \"#afb681\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline5\",\n\t\t\t\"foreground\": \"#018786\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline6\",\n\t\t\t//\"foreground\": \"#afe3de\",\n\t\t\t\"foreground\": \"#7fa3ae\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t// Stars before the last star in a headline\n\t\t// make these background to hide them.\n\t\t{\n\t\t\t\"scope\": \"orgmode.preamble\",\n\t\t\t\"foreground\": \"var(bgcol)\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t// Maybe I can use regions to collapse these?\n\t\t// Right now they look uber ugly\n\t\t{\n\t\t\t\"scope\": \"orgmode.link\",\n\t\t\t\"foreground\": \"#3cb7da\",\n\t\t\t\"font_style\": \"\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.link.href\",\n\t\t\t\"foreground\": \"#777788\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.link.text\",\n\t\t\t\"foreground\": \"#7aa7ed\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.email\",\n\t\t\t\"foreground\": \"#a188b3\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.deadline\",\n\t\t\t\"foreground\": \"#d1771d\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.scheduled\",\n\t\t\t\"foreground\": \"#d1771d\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t// #+PRIORITIES: A B C\n\t\t{\n\t\t\t\"scope\": \"orgmode.controltag\",\n\t\t\t\"foreground\": \"#aaaaaa\",\n\t\t},\n\t\t// controltag.text also exists\n\t\t{\n\t\t\t\"scope\": \"orgmode.controltag.tag\",\n\t\t\t\"foreground\": \"#aaaaaa\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t// < DATETIME >\n\t\t{\n\t\t\t\"scope\": \"orgmode.datetime\",\n\t\t\t\"foreground\": \"#b0a497\",\n\t\t},\n\t\t// [ DATETIME ]\n\t\t{\n\t\t\t\"scope\": \"orgmode.unscheddatetime\",\n\t\t\t\"foreground\": \"#b0a497\",\n\t\t},\n\t\t// CLOSED: SCHEDULED: DEADLINE:\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.statekeyword\",\n\t\t\t\"foreground\": \"#d1771d\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.checkbox\",\n\t\t\t\"foreground\": \"#a99e5b\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.checkbox.checked\",\n\t\t\t\"foreground\": \"#00cc00\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.checkbox.blocked\",\n\t\t\t\"foreground\": \"#cc0000\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.tags\",\n\t\t\t\"foreground\": \"#3e349b\",\n\t\t\t//\"foreground\": \"#ded49b\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.tags.headline\",\n\t\t\t//\"foreground\": \"#deff9b\",\n\t\t\t\"foreground\": \"#aebf7b\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority\",\n\t\t\t\"foreground\": \"#c27532\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value\",\n\t\t\t\"foreground\": \"#f5a55f\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.a\",\n\t\t\t\"foreground\": \"#e05a7b\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.b\",\n\t\t\t\"foreground\": \"#f59a76\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.c\",\n\t\t\t\"foreground\": \"#fab978\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.d\",\n\t\t\t\"foreground\": \"#f5d976\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.e\",\n\t\t\t\"foreground\": \"#bcbfae\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.general\",\n\t\t\t\"foreground\": \"#b59eb5\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.todo\",\n\t\t\t\"foreground\": \"#e6ab4c\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.blocked\",\n\t\t\t\"foreground\": \"#FF0000\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.done\",\n\t\t\t\"foreground\": \"#47c94f\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.cancelled\",\n\t\t\t\"foreground\": \"#bab9b8\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.meeting\",\n\t\t\t\"foreground\": \"#bea7dc\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.phone\",\n\t\t\t\"foreground\": \"#67cbcd\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.note\",\n\t\t\t\"foreground\": \"#a272a0\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.doing\",\n\t\t\t\"foreground\": \"#9c9c17\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.inprogress\",\n\t\t\t\"foreground\": \"#9c9c17\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.next\",\n\t\t\t\"foreground\": \"#37dae6\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.reassigned\",\n\t\t\t\"foreground\": \"#bab9b8\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.tack\",\n\t\t\t\"foreground\": \"#a963a4\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.numberedlist\",\n\t\t\t\"foreground\": \"#a963a4\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.definition\",\n\t\t\t\"foreground\": \"#42a8c4\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.definition.marker\",\n\t\t\t\"foreground\": \"#E1A2E8\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.follow_up\",\n\t\t\t\"foreground\": \"#FF0000\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.fence\",\n\t\t\t\"background\": \"#f2f0f0\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.fence.language\",\n\t\t\t\"background\": \"#f2f0f0\",\n\t\t\t\"foreground\": \"#f1bff2\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.raw.block\",\n\t\t\t\"background\": \"#e5e5e0\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.table.block\",\n\t\t\t\"background\": \"#e7e8e8\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.bold\",\n\t\t\t\"foreground\": \"#aaffaa\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.italics\",\n\t\t\t\"foreground\": \"#aaffff\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.underline\",\n\t\t\t\"foreground\": \"#aaaaff\",\n\t\t\t\"font_style\": \"underline\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.strikethrough\",\n\t\t\t\"foreground\": \"#aaaaaa\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.code\",\n\t\t\t\"foreground\": \"#ffaaff\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.verbatim\",\n\t\t\t\"foreground\": \"#ffaaaa\",\n\t\t},\n        // MONOKAI EXTENDED COLORING\n\n\t\t// Generic colorization\n\t\t// function call\n\t\t{ \"scope\": \"support.function\",                     \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"keyword\",                              \"foreground\": \"#f92672\", },\n\t\t{ \"scope\": \"comment\",                              \"foreground\": \"#75715e\", },\n\t\t{ \"scope\": \"string\",                               \"foreground\": \"#c6bb54\", },\n\t\t{ \"scope\": \"constant.numeric\",                     \"foreground\": \"#be84ff\", },\n\t\t{ \"scope\": \"constant.language\",                    \"foreground\": \"#be84ff\", },\n\t\t{ \"scope\": \"meta.preprocessor\",                    \"foreground\": \"#be84ff\", },\n\t\t{ \"scope\": \"constant.character\",                   \"foreground\": \"#be84ff\", },\n\t\t{ \"scope\": \"constant.other\",                       \"foreground\": \"#be84ff\", },\n\t\t{ \"scope\": \"variable.language\",                    \"foreground\": \"#000000\", },\n\t\t{ \"scope\": \"variable.other\",                       \"foreground\": \"#000000\", },\n\t\t{ \"scope\": \"storage\",                              \"foreground\": \"#f92672\", },\n\t\t{ \"scope\": \"storage.type\",                         \"foreground\": \"#56c9df\", },\n\t\t{ \"scope\": \"entity.name.class\",                    \"foreground\": \"#66D9EF\", \"font_style\": \"underline\" },\n\t\t{ \"scope\": \"entity.other.inherited-class\",         \"foreground\": \"#a6e22e\", \"font_style\": \"italic underline\" },\n\t\t{ \"scope\": \"variable.parameter\",                   \"foreground\": \"#fd971f\", \"font_style\": \"italic\" },\n\t\t{ \"scope\": \"entity.name.tag\",                      \"foreground\": \"#f92672\", },\n\t\t{ \"scope\": \"entity.other.attribute-name\",          \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"entity.name.function\",                 \"foreground\": \"#86c22e\", },\n\t\t{ \"scope\": \"entity.constant\",                      \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"support.constant\",                     \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"support.type\",                         \"foreground\": \"#A6E22E\", \"font_style\": \"italic\", },\n\t\t{ \"scope\": \"support.other.variable\",                                        },\n\t\t{ \"scope\": \"string.constant\",                      \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"string.regexp\",                        \"foreground\": \"#f6aa11\", },\n\t\t{ \"scope\": \"string.variable\",                      \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.definition.variable\",      \"foreground\": \"#ffffff\", },\n\t\t// Html / Xml\n\t\t{ \"scope\": \"meta.tag.sgml.doctype.xml\",            \"foreground\": \"#c8cecc\", },\n\t\t{ \"scope\": \"declaration.sgml.html declaration.doctype\",         \"foreground\": \"#c8cecc\", },\n\t\t{ \"scope\": \"declaration.sgml.html declaration.doctype entity\",  \"foreground\": \"#c8cecc\", },\n\t\t{ \"scope\": \"declaration.sgml.html declaration.doctype string\",  \"foreground\": \"#c8cecc\", },\n\t\t{ \"scope\": \"content.block.html\",                                \"foreground\": \"#7c7865\", },\n\t\t{ \"scope\": \"entity.name.tag.script.html\",                       \"font_style\": \"italic\",},\n\t\t{ \"scope\": \"text.html.basic meta.tag.other.html\",               \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.any.html\",                 \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.block.any\",                \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.inline.any\",               \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.structure.any.html\",       \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.structure.any.html\",       \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic source.js.embedded.html\",           \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"punctuation.separator.key-value.html\",              \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic entity.other.attribute-name\",       \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.structure.any.html punctuation.definition.string.begin.html\",       \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.definition.string.begin.html\",          \"foreground\": \"#000000\", },\n\t\t{ \"scope\": \"punctuation.definition.string.end.html\",            \"foreground\": \"#000000\", },\n\t\t{ \"scope\": \"punctuation.definition.tag.end\",                    \"foreground\": \"#000000\", },\n\t\t{ \"scope\": \"punctuation.definition.tag.begin\",                  \"foreground\": \"#000000\", },\n\t\t{ \"scope\": \"punctuation.definition.tag\",                        \"foreground\": \"#000000\", },\n\t\t// Handlebars\n\t\t{ \"scope\": \"variable.parameter.handlebars\",                     \"foreground\": \"#f6aa11\", },\n\t\t{ \"scope\": \"support.constant.handlebars\",                       \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"meta.function.block.start.handlebars\",              \"foreground\": \"#66d9ef\", },\n\t\t// CSS\n\t\t{ \"scope\": \"meta.preprocessor.at-rule\",                            \"foreground\": \"#f6aa11\", },\n\t\t{ \"scope\": \"meta.selector.css entity.other.attribute-name.id\",     \"foreground\": \"#f6aa11\", },\n\t\t{ \"scope\": \"meta.selector.css entity.other.attribute-name.class\",  \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"support.type.property-name.css\",                       \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"meta.constructor.argument.css\",                        \"foreground\": \"#f6aa11\", },\n\t\t{ \"scope\": \"punctuation.section.property-list.css\",                \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.definition.tag.css\",                       \"foreground\": \"#f92672\", },\n\t\t{ \"scope\": \"punctuation.separator.key-value.css\",                  \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.terminator.rule.css\",                      \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"entity.other.attribute-name.pseudo-element.css\",       \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"entity.other.attribute-name.pseudo-class.css\",         \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"entity.other.attribute-name.pseudo-selector.css\",      \"foreground\": \"#a6e22e\", },\n\t\t// LESS Variables\n\t\t{ \"scope\": \"variable.other.less\",                                  \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"variable.other.less.mixin\",                            \"foreground\": \"#e0fdce\", \"font_style\": \"italic\"},\n\t\t{ \"scope\": \"entity.other.attribute-name.pseudo-element.less\",      \"foreground\": \"#ff9117\", },\n\t\t// Javascript\n\t\t{ \"scope\": \"meta.instance.constructor meta.function-call.constructor.js\",                          \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"meta.template.expression.js punctuation.definition.template-expression.begin.js\",      \"foreground\": \"#AFF132\", },\n\t\t{ \"scope\": \"meta.template.expression.js punctuation.definition.template-expression.end.js\",        \"foreground\": \"#AFF132\", },\n\t\t{ \"scope\": \"meta.template.expression.js punctuation.accessor\",                                     \"foreground\": \"#AFF132\", },\n\t\t{ \"scope\": \"meta.function.js\",                                                                     \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"entity.name.function.js\",                                                              \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"support.function.dom.js\",                                                              \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"source.js meta.function.js punctuation.separator.parameter.function.js\",               \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"meta.property.object.js\",                                                              \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"keyword.operator.accessor.js\",                                                         \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"source.js meta.group.braces.curly constant.other.object.key.js punctuation.separator.key-value.js\", \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"source.js meta.group.braces.curly constant.other.object.key.js string.unquoted.label.js\", \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"support.type.object.module.js\",                                                        \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"source.js meta.function.declaration.js support.class.js\",                              \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"support.type.object.module.js support.type.object.module.js\",                          \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"storage.type.js\",                                                                      \"foreground\": \"#66d9ef\", \"font_style\": \"italic\",},\n\t\t{ \"scope\": \"text.html.basic source.js.embedded.html\",                                              \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"storage.type.function.js\",                                                             \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"constant.numeric.js\",                                                                  \"foreground\": \"#ae81ff\", },\n\t\t// JS: Literal language variable\t\n\t\t{ \"scope\": \"variable.language.arguments.js, variable.language.super.js, variable.language.this.js, variable.language.self.js, variable.language.proto.js, variable.language.constructor.js, variable.language.prototype.js\",                                                                  \"foreground\": \"#66d9ef\", \"font_style\": \"italic\",},\n        // JS: []\n        { \"scope\": \"meta.brace.square.js\", \"foreground\": \"#ffffff\", },\n        // JS: ()\n        { \"scope\": \"meta.brace.round, punctuation.definition.parameters.begin.js, punctuation.definition.parameters.end.js, punctuation.definition.group\", \"foreground\": \"#ffffff\", },\n        // JS: object literal {}\n        { \"scope\": \"meta.brace.curly.js, meta.object-literal.js\", \"foreground\": \"#ffffff\", },\n        // JSON String\n        { \"scope\": \"meta.structure.dictionary.json string.quoted.double.json\", \"foreground\": \"#cfcfc2\", },\n        // CoffeeScript String Interpolated\n        { \"scope\": \"punctuation.section.embedded.coffee\", \"foreground\": \"#e69f66\", },\n        // PHP: []\n        { \"scope\": \"keyword.operator.index-start.php, keyword.operator.index-end.php\", \"foreground\": \"#ffffff\", },\n        // PHP: Array\n        { \"scope\": \"meta.array.php\", \"foreground\": \"#ffffff\", },\n        // PHP: Array()\n        { \"scope\": \"meta.array.php support.function.construct.php, meta.array.empty.php support.function.construct.php\", \"foreground\": \"#e42e70\", },\n        // PHP: Array Construct\n        { \"scope\": \"support.function.construct.php\", \"foreground\": \"#e42e70\", },\n        // PHP: Storage Type Function\n        { \"scope\": \"storage.type.function.php\", \"foreground\": \"#f92672dd\", },\n        // PHP: Numeric Constant\n        { \"scope\": \"constant.numeric.php\", \"foreground\": \"#be84ff\", },\n        // PHP: New\n        { \"scope\": \"keyword.other.new.php\", \"foreground\": \"#f6aa11\", },\n        // PHP: ::\n        { \"scope\": \"support.class.php\", \"foreground\": \"#ffffff\", },\n        // PHP: Other Property\n        { \"scope\": \"variable.other.property.php\", \"foreground\": \"#f6aa11\", },\n        // PHP: Class\n        { \"scope\": \"storage.modifier.extends.php, storage.type.class.php, keyword.operator.class.php\", \"foreground\": \"#a6e22e\", },\n        // PHP: Inherited Class\n        { \"scope\": \"meta.other.inherited-class.php\", \"foreground\": \"#a6e22e\", },\n        // PHP: Storage Type\n        { \"scope\": \"storage.type.php\", \"foreground\": \"#66d9ef\", },\n        // PHP: Function\n        { \"scope\": \"entity.name.function.php\", \"foreground\": \"#66d9ef\", },\n        // PHP: Function Construct\n        { \"scope\": \"support.function.construct.php\", \"foreground\": \"#a6e22e\", },\n        // PHP: Function Call\n        { \"scope\": \"entity.name.type.class.php, meta.function-call.php, meta.function-call.static.php, meta.function-call.object.php\", \"foreground\": \"#ffffff\", },\n        // PHP: Comment\n        { \"scope\": \"keyword.other.phpdoc\", \"foreground\": \"#7c7865\", },\n        // PHP: Source Emebedded\n        { \"scope\": \"source.php.embedded.block.html\", \"foreground\": \"#ffffff\", },\n        // Invalid\n        { \"scope\": \"invalid\", \"foreground\": \"#f8f8f0\",\"background\": \"#f92672\", },\n        // Invalid deprecated\n        { \"scope\": \"invalid.deprecated\", \"foreground\": \"#f8f8f0\",\"background\": \"#ae81ff\", },\n        // diff.header\n        { \"scope\": \"meta.diff, meta.diff.header\", \"foreground\": \"#75715e\", },\n        // diff.deleted\n        { \"scope\": \"markup.deleted\", \"foreground\": \"#f92672\", },\n        // diff.inserted\n        { \"scope\": \"markup.inserted\", \"foreground\": \"#a6e22e\", },\n        // diff.changed\n        { \"scope\": \"markup.changed\", \"foreground\": \"#e6db74\", },\n        // diff.range\n        { \"scope\": \"meta.diff, meta.diff.range\", \"foreground\": \"#3bc0f0\", },\n        // Python: storage\n        { \"scope\": \"storage.type.class.python, storage.type.function.python, storage.modifier.global.python\", \"foreground\": \"#a6e22e\", },\n        // Python: import\n        { \"scope\": \"keyword.control.import.python, keyword.control.import.from.python\", \"foreground\": \"#f92672dd\", },\n        // Python: Support.exception\n        { \"scope\": \"support.type.exception.python\", \"foreground\": \"#66d9ef\", },\n        // Perl: variables\n        { \"scope\": \"punctuation.definition.variable.perl, variable.other.readwrite.global.perl, variable.other.predefined.perl, keyword.operator.comparison.perl\", \"foreground\": \"#e42e70\", },\n        // Perl: functions\n        { \"scope\": \"support.function.perl\", \"foreground\": \"#66d9ef\", },\n        // Perl: comments\n        { \"scope\": \"comment.line.number-sign.perl\", \"foreground\": \"#75715e\",\"font_style\": \"italic\", },\n        // Perl: quotes\n        { \"scope\": \"punctuation.definition.string.begin.perl, punctuation.definition.string.end.perl\", \"foreground\": \"#ffffff\", },\n        // Perl: char\n        { \"scope\": \"constant.character.escape.perl\", \"foreground\": \"#dc322f\", },\n        // Ruby: Constant\n        { \"scope\": \"constant.language.ruby, constant.numeric.ruby\", \"foreground\": \"#ae81ff\", },\n        // Ruby: Variable definition\n        { \"scope\": \"punctuation.definition.variable.ruby\", \"foreground\": \"#f6aa11\", },\n        // Ruby: Function Name\n        { \"scope\": \"meta.function.method.with-arguments.ruby\", \"foreground\": \"#a6e22e\", },\n        // Ruby: Variable\n        { \"scope\": \"variable.language.ruby\", \"foreground\": \"#ffffff\", },\n        // Ruby: Function\n        { \"scope\": \"entity.name.function.ruby\", \"foreground\": \"#f6aa11\", },\n        // Ruby: Keyword Control\n        { \"scope\": \"keyword.control.ruby, keyword.control.def.ruby\", \"foreground\": \"#a6e22e\",\"font_style\": \"bold\", },\n        // Ruby: Class\n        { \"scope\": \"keyword.control.class.ruby, meta.class.ruby\", \"foreground\": \"#a6e22e\", },\n        // Ruby: Class Name\n        { \"scope\": \"entity.name.type.class.ruby\", \"foreground\": \"#66d9ef\", },\n        // Ruby: Keyword\n        { \"scope\": \"keyword.control.ruby\", \"foreground\": \"#a6e22e\", },\n        // Ruby: Support Class\n        { \"scope\": \"support.class.ruby\", \"foreground\": \"#66d9ef\", },\n        // Ruby: Special Method\n        { \"scope\": \"keyword.other.special-method.ruby\", \"foreground\": \"#a6e22e\", },\n        // Ruby: Constant Other\n        { \"scope\": \"variable.other.constant.ruby\", \"foreground\": \"#66d9ef\", },\n        // Ruby: :symbol\n        { \"scope\": \"constant.other.symbol.ruby\", \"foreground\": \"#f6f080\", },\n        // Ruby: Punctuation Section\n        { \"scope\": \"punctuation.section.embedded.ruby, punctuation.definition.string.begin.ruby, punctuation.definition.string.end.ruby\", \"foreground\": \"#f92672\", },\n        // Ruby: Special Method\n        { \"scope\": \"keyword.other.special-method.ruby\", \"foreground\": \"#e42e70\", },\n        // Markdown: plain\n        { \"scope\": \"text.html.markdown\", \"foreground\": \"#ffffff\", },\n        // Markup: raw inline\n        { \"scope\": \"text.html.markdown markup.raw.inline\", \"foreground\": \"#ec3533\", },\n        // Markdown: linebreak\n        { \"scope\": \"text.html.markdown meta.dummy.line-break\", \"foreground\": \"#e0eddd\", },\n        // Markdown: heading\n        { \"scope\": \"markdown.heading, markup.heading | markup.heading entity.name, markup.heading.markdown punctuation.definition.heading.markdown\", \"foreground\": \"#fd971f\", },\n        // Markup: italic\n        { \"scope\": \"markup.italic\", \"foreground\": \"#e42e70\",\"font_style\": \"italic\", },\n        // Markup: bold\n        { \"scope\": \"markup.bold\", \"foreground\": \"#f92672\",\"font_style\": \"bold\", },\n        // Markup: underline\n        { \"scope\": \"markup.underline\", \"foreground\": \"#a6e22e\",\"font_style\": \"underline\", },\n        // Markup: strike\n        { \"scope\": \"markup.strike\", \"foreground\": \"#cc4273\", },\n        // Markdown: Blockquote\n        { \"scope\": \"markup.quote, punctuation.definition.blockquote.markdown\", \"foreground\": \"#66d9ef\",\"font_style\": \"italic\", },\n        // Markup: Quote\n        { \"scope\": \"markup.quote\", \"foreground\": \"#66d9ef\",\"font_style\": \" italic\", },\n        // Markdown: Link\n        { \"scope\": \"string.other.link.title.markdown\", \"foreground\": \"#66d9ef\",\"font_style\": \"underline\", },\n        // Markup: Raw block\n        { \"scope\": \"markup.raw.block\", \"foreground\": \"#ae81ff\", },\n        // Markdown: List Items Punctuation\n        { \"scope\": \"punctuation.definition.list_item.markdown\", \"foreground\": \"#777777\", },\n        // Markdown: Raw Block fenced\n        { \"scope\": \"markup.raw.block.fenced.markdown\", \"foreground\": \"#ffffff\",\"background\": \"#222\", },\n        // Markdown: Fenced Bode Block\n        { \"scope\": \"punctuation.definition.fenced.markdown, variable.language.fenced.markdown\", \"foreground\": \"#636050\",\"background\": \"#222222\", },\n        // Markdown: Fenced Language\n        { \"scope\": \"variable.language.fenced.markdown\", \"foreground\": \"#7c7865\", },\n        // Markdown: Separator\n        { \"scope\": \"meta.separator\", \"foreground\": \"#ffffff33\",\"background\": \"#ffffff0f\",\"font_style\": \"bold\", },\n        // Markup: table\n        { \"scope\": \"markup.table\", \"foreground\": \"#b42a1d\",\"background\": \"#ff3a281a\", },\n        // LaTeX: Math Variables\n        { \"scope\": \"variable.other.math.tex\", \"foreground\": \"#e6db74\", },\n        // Other: Removal\n        { \"scope\": \"other.package.exclude, other.remove\", \"foreground\": \"#d3201f\", },\n        // Shell: builtin\n        { \"scope\": \"support.function.builtin.shell\", \"foreground\": \"#a6e22e\", },\n        // Shell: variable\n        { \"scope\": \"variable.other.normal.shell\", \"foreground\": \"#66d9ef\", },\n        // Shell: DOTFILES\n        { \"scope\": \"source.shell\", \"foreground\": \"#ffffff\", },\n        // Shell: meta scope in loop\n        { \"scope\": \"meta.scope.for-in-loop.shell, variable.other.loop.shell\", \"foreground\": \"#fd971f\", },\n        // Shell: Function name\n        { \"scope\": \"entity.name.function.shell\", \"foreground\": \"#a6e22e\", },\n        // Shell: Quotation Marks\n        { \"scope\": \"punctuation.definition.string.end.shell, punctuation.definition.string.begin.shell\", \"foreground\": \"#ffffff\", },\n        // Shell: Meta Block\n        { \"scope\": \"meta.scope.case-block.shell, meta.scope.case-body.shell\", \"foreground\": \"#fd971f\", },\n        // Shell: []\n        { \"scope\": \"punctuation.definition.logical-expression.shell\", \"foreground\": \"#ffffff\", },\n        // Shell: Comment\n        { \"scope\": \"comment.line.number-sign.shell\", \"foreground\": \"#7c7865\",\"font_style\": \"italic\", },\n        // Makefile: Comment\n        { \"scope\": \"comment.line.number-sign.makefile\", \"foreground\": \"#7c7865\", },\n        // Makefile: Comment punctuation\n        { \"scope\": \"punctuation.definition.comment.makefile\", \"foreground\": \"#7c7865\", },\n        // Makefile: Variables\n        { \"scope\": \"variable.other.makefile\", \"foreground\": \"#f92672\", },\n        // Makefile: Function name\n        { \"scope\": \"entity.name.function.makefile\", \"foreground\": \"#a6e22e\", },\n        // Makefile: Function\n        { \"scope\": \"meta.function.makefile\", \"foreground\": \"#66d9ef\", },\n        // GitGutter deleted\n        { \"scope\": \"markup.deleted.git_gutter\", \"foreground\": \"#F92672\", },\n        // GitGutter inserted\n        { \"scope\": \"markup.inserted.git_gutter\", \"foreground\": \"#A6E22E\", },\n        // GitGutter changed\n        { \"scope\": \"markup.changed.git_gutter\", \"foreground\": \"#FC951E\", },\n        // GitGutter ignored\n        { \"scope\": \"markup.ignored.git_gutter\", \"foreground\": \"#565656\", },\n        // GitGutter untracked\n        { \"scope\": \"markup.untracked.git_gutter\", \"foreground\": \"#565656\", },\n        // Nginx path\n        { \"scope\": \"string.other.path.nginx\", \"foreground\": \"#fc951e\", },\n\n\t\t\n\t]\n}"
  },
  {
    "path": "OrgExtended.sublime-color-scheme",
    "content": "{\n\t\"name\": \"OrgExtended\",\n\t\"variables\": {\n\t\t\"bgcol\": \"#071812\",\n\t\t// Define variables here\n\t},\n\t\"globals\": {\n\t\t\"foreground\": \"#F8F8F2\",\n\t\t\"background\": \"var(bgcol)\",\n\t\t\"accent\":     \"#ffffff\",\n\t\t\"selection\":  \"#9D550F\",\n\t    \"selectionBackground\": \"#000000\",\n\t    \"selectionForeground\": \"#FF0000\",\n\t    \"caret\":               \"#FF55ff\",\n\t    \"line_highlight\":      \"#373730\"\n\t},\n\t\"rules\": [\n\t\t{\n\t\t\t\"foreground\": \"#191919FF\",\n\t\t\t\"scope\": \"col_999999FF\",\n\t\t\t\"background\": \"#999999FF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#C1C1C1FF\",\n\t\t\t\"scope\": \"col_0645CDFF\",\n\t\t\t\"background\": \"#0645CDFF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#E0E0E0FF\",\n\t\t\t\"scope\": \"col_1E74ACFF\",\n\t\t\t\"background\": \"#1E74ACFF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#7E7E7EFF\",\n\t\t\t\"scope\": \"col_FEFEFEFF\",\n\t\t\t\"background\": \"#FEFEFEFF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#939393FF\",\n\t\t\t\"scope\": \"col_0B0090FF\",\n\t\t\t\"background\": \"#0B0090FF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#4C4C4CFF\",\n\t\t\t\"scope\": \"col_CCCCCCFF\",\n\t\t\t\"background\": \"#CCCCCCFF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#D8D8D8FF\",\n\t\t\t\"scope\": \"col_765037FF\",\n\t\t\t\"background\": \"#765037FF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#C4C4C4FF\",\n\t\t\t\"scope\": \"col_444444FF\",\n\t\t\t\"background\": \"#444444FF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#C9C9C9FF\",\n\t\t\t\"scope\": \"col_66402FFF\",\n\t\t\t\"background\": \"#66402FFF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#D7D7D7FF\",\n\t\t\t\"scope\": \"col_0066EEFF\",\n\t\t\t\"background\": \"#0066EEFF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#2C2C2CFF\",\n\t\t\t\"scope\": \"col_FAA700FF\",\n\t\t\t\"background\": \"#FAA700FF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#616161FF\",\n\t\t\t\"scope\": \"col_FFFF00FF\",\n\t\t\t\"background\": \"#FFFF00FF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#DBDBDBFF\",\n\t\t\t\"scope\": \"col_1E747CFF\",\n\t\t\t\"background\": \"#1E747CFF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#D0D0D0FF\",\n\t\t\t\"scope\": \"col_FFFF004C\",\n\t\t\t\"background\": \"#FFFF004C\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#BEBEBEFF\",\n\t\t\t\"scope\": \"col_0645ADFF\",\n\t\t\t\"background\": \"#0645ADFF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#737373FF\",\n\t\t\t\"scope\": \"col_FFFF99FF\",\n\t\t\t\"background\": \"#FFFF99FF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#2A2A2AFF\",\n\t\t\t\"scope\": \"col_AAAAAAFF\",\n\t\t\t\"background\": \"#AAAAAAFF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#C6C6C6FF\",\n\t\t\t\"scope\": \"col_474356FF\",\n\t\t\t\"background\": \"#474356FF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#5D5D5DFF\",\n\t\t\t\"scope\": \"col_DDDDDDFF\",\n\t\t\t\"background\": \"#DDDDDDFF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#6E6E6EFF\",\n\t\t\t\"scope\": \"col_EEEEEEFF\",\n\t\t\t\"background\": \"#EEEEEEFF\"\n\t\t},\n\t\t{\n\t\t\t\"foreground\": \"#3B3B3BFF\",\n\t\t\t\"scope\": \"col_BBBBBBFF\",\n\t\t\t\"background\": \"#BBBBBBFF\"\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"col_008000FF\",\n\t\t\t\"background\": \"#008000FF\",\n\t\t\t\"foreground\": \"#CBCBCBFF\"\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"col_D2B48CFF\",\n\t\t\t\"background\": \"#D2B48CFF\",\n\t\t\t\"foreground\": \"#383838FF\"\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"col_000000FF\",\n\t\t\t\"background\": \"#000000FF\",\n\t\t\t\"foreground\": \"#808080FF\"\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"col_339966FF\",\n\t\t\t\"background\": \"#339966FF\",\n\t\t\t\"foreground\": \"#F4F4F4FF\"\n\t\t},\n\t\t{\n\t\t\t\"background\": \"#000000\",\n\t\t\t\"scope\": \"col_gutter\",\n\t\t\t\"foreground\": \"#ffffff\"\n\t\t},\n\t\t{\n\t\t\t\"background\": \"#FFC0CBFF\",\n\t\t\t\"scope\": \"col_FFC0CBFF\",\n\t\t\t\"foreground\": \"#545454FF\"\n\t\t},\n\t\t{\n\t\t\t\"background\": \"#800080FF\",\n\t\t\t\"scope\": \"col_800080FF\",\n\t\t\t\"foreground\": \"#B4B4B4FF\"\n\t\t},\n\t\t{\n\t\t\t\"background\": \"#0000FFFF\",\n\t\t\t\"scope\": \"col_0000FFFF\",\n\t\t\t\"foreground\": \"#9D9D9DFF\"\n\t\t},\n\t\t{\n\t\t\t\"background\": \"#FF0000FF\",\n\t\t\t\"scope\": \"col_FF0000FF\",\n\t\t\t\"foreground\": \"#CCCCCCFF\"\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.break\",\n\t\t\t\"foreground\": \"#ed188a\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.page\",\n\t\t\t\"foreground\": \"#f5eebf\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline\",\n\t\t\t\"foreground\": \"#14adfa\",\n\t\t\t\"background\": \"#172822\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline2\",\n\t\t\t\"background\": \"#172822\",\t\t\t\n\t\t\t\"foreground\": \"#bb86fc\",\n\t\t\t\"background\": \"#171812\",\n\t\t\t\"font_style\": \"bold underline\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline3\",\n\t\t\t\"foreground\": \"#03dac5\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline4\",\n\t\t\t\"foreground\": \"#dfe6a1\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline5\",\n\t\t\t\"foreground\": \"#018786\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline6\",\n\t\t\t\"foreground\": \"#afe3de\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline7\",\n\t\t\t\"foreground\": \"#afe3fe\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline8\",\n\t\t\t\"foreground\": \"#ffe3de\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.headline9\",\n\t\t\t\"foreground\": \"#fff3de\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t// Stars before the last star in a headline\n\t\t// make these background to hide them.\n\t\t{\n\t\t\t\"scope\": \"orgmode.preamble\",\n\t\t\t\"foreground\": \"var(bgcol)\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t// Links can target these\n\t\t{\n\t\t\t\"scope\": \"orgmode.target\",\n\t\t\t\"foreground\": \"#7c004a\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t// Links can target these\n\t\t{\n\t\t\t\"scope\": \"orgmode.target.bracket\",\n\t\t\t\"foreground\": \"#7c004a\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t// Maybe I can use regions to collapse these?\n\t\t// Right now they look uber ugly\n\t\t{\n\t\t\t\"scope\": \"orgmode.link\",\n\t\t\t\"foreground\": \"#3cd7fa\",\n\t\t\t\"font_style\": \"\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.link.href\",\n\t\t\t\"foreground\": \"#9999aa\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.link.text\",\n\t\t\t\"foreground\": \"#4ce7fd\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.email\",\n\t\t\t\"foreground\": \"#a188b3\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.deadline\",\n\t\t\t\"foreground\": \"#d1771d\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.scheduled\",\n\t\t\t\"foreground\": \"#d1771d\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t// #+PRIORITIES: A B C\n\t\t{\n\t\t\t\"scope\": \"orgmode.controltag\",\n\t\t\t\"foreground\": \"#aaaaaa\",\n\t\t},\n\t\t// controltag.text also exists\n\t\t{\n\t\t\t\"scope\": \"orgmode.controltag.tag\",\n\t\t\t\"foreground\": \"#aaaaaa\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t// < DATETIME >\n\t\t{\n\t\t\t\"scope\": \"orgmode.datetime\",\n\t\t\t\"foreground\": \"#b0a497\",\n\t\t},\n\t\t// [ DATETIME ]\n\t\t{\n\t\t\t\"scope\": \"orgmode.unscheddatetime\",\n\t\t\t\"foreground\": \"#b0a497\",\n\t\t},\n\t\t// CLOSED: SCHEDULED: DEADLINE:\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.statekeyword\",\n\t\t\t\"foreground\": \"#d1771d\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.checkbox\",\n\t\t\t\"foreground\": \"#c9be7b\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.checkbox.checked\",\n\t\t\t\"foreground\": \"#00FF00\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.checkbox.blocked\",\n\t\t\t\"foreground\": \"#FF0000\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.tags\",\n\t\t\t\"foreground\": \"#ded49b\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.tags.headline\",\n\t\t\t\"foreground\": \"#deff9b\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority\",\n\t\t\t\"foreground\": \"#c27532\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value\",\n\t\t\t\"foreground\": \"#f5a55f\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.a\",\n\t\t\t\"foreground\": \"#e05a7b\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.b\",\n\t\t\t\"foreground\": \"#f59a76\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.c\",\n\t\t\t\"foreground\": \"#fab978\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.d\",\n\t\t\t\"foreground\": \"#f5d976\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.e\",\n\t\t\t\"foreground\": \"#bcbfae\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.priority.value.general\",\n\t\t\t\"foreground\": \"#b59eb5\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.todo\",\n\t\t\t\"foreground\": \"#e6ab4c\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.blocked\",\n\t\t\t\"foreground\": \"#FF0000\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.done\",\n\t\t\t\"foreground\": \"#47c94f\",\n\t\t},\t\t\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.cancelled\",\n\t\t\t\"foreground\": \"#bab9b8\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.meeting\",\n\t\t\t\"foreground\": \"#dec7fc\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.phone\",\n\t\t\t\"foreground\": \"#77ebed\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.note\",\n\t\t\t\"foreground\": \"#d2a2e0\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.doing\",\n\t\t\t\"foreground\": \"#9c9c17\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.inprogress\",\n\t\t\t\"foreground\": \"#9c9c17\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.flag\",\n\t\t\t\"foreground\": \"#9c9c17\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.cleanup\",\n\t\t\t\"foreground\": \"#9c9c17\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.next\",\n\t\t\t\"foreground\": \"#37dae6\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.reassigned\",\n\t\t\t\"foreground\": \"#bab9b8\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.state.fixed\",\n\t\t\t\"foreground\": \"#bab9b8\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.tack\",\n\t\t\t\"foreground\": \"#c993c4\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.numberedlist\",\n\t\t\t\"foreground\": \"#c993c4\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.definition\",\n\t\t\t\"foreground\": \"#A2E8E4\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.definition.marker\",\n\t\t\t\"foreground\": \"#E1A2E8\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.follow_up\",\n\t\t\t\"foreground\": \"#FF0000\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.fence\",\n\t\t\t\"background\": \"#322830\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.fence.language\",\n\t\t\t\"background\": \"#322830\",\n\t\t\t\"foreground\": \"#f1bff2\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.raw.block\",\n\t\t\t\"background\": \"#252520\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.table.block\",\n\t\t\t\"background\": \"#272828\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.bold\",\n\t\t\t\"foreground\": \"#aaffaa\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.italics\",\n\t\t\t\"foreground\": \"#aaffff\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.underline\",\n\t\t\t\"foreground\": \"#aaaaff\",\n\t\t\t\"font_style\": \"underline\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.strikethrough\",\n\t\t\t\"foreground\": \"#aaaaaa\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.code\",\n\t\t\t\"foreground\": \"#ffaaff\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgmode.verbatim\",\n\t\t\t\"foreground\": \"#ffaaaa\",\n\t\t},\n        // MONOKAI EXTENDED COLORING\n\n\t\t// Generic colorization\n\t\t// function call\n\t\t{ \"scope\": \"support.function\",                     \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"keyword\",                              \"foreground\": \"#f92672\", },\n\t\t{ \"scope\": \"comment\",                              \"foreground\": \"#75715e\", },\n\t\t{ \"scope\": \"string\",                               \"foreground\": \"#e6db74\", },\n\t\t{ \"scope\": \"constant.numeric\",                     \"foreground\": \"#be84ff\", },\n\t\t{ \"scope\": \"constant.language\",                    \"foreground\": \"#be84ff\", },\n\t\t{ \"scope\": \"meta.preprocessor\",                    \"foreground\": \"#be84ff\", },\n\t\t{ \"scope\": \"constant.character\",                   \"foreground\": \"#be84ff\", },\n\t\t{ \"scope\": \"constant.other\",                       \"foreground\": \"#be84ff\", },\n\t\t{ \"scope\": \"variable.language\",                    \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"variable.other\",                       \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"storage\",                              \"foreground\": \"#f92672\", },\n\t\t{ \"scope\": \"storage.type\",                         \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"entity.name.class\",                    \"foreground\": \"#66D9EF\", \"font_style\": \"underline\" },\n\t\t{ \"scope\": \"entity.other.inherited-class\",         \"foreground\": \"#a6e22e\", \"font_style\": \"italic underline\" },\n\t\t{ \"scope\": \"variable.parameter\",                   \"foreground\": \"#fd971f\", \"font_style\": \"italic\" },\n\t\t{ \"scope\": \"entity.name.tag\",                      \"foreground\": \"#f92672\", },\n\t\t{ \"scope\": \"entity.other.attribute-name\",          \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"entity.name.function\",                 \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"entity.constant\",                      \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"support.constant\",                     \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"support.type\",                         \"foreground\": \"#A6E22E\", \"font_style\": \"italic\", },\n\t\t{ \"scope\": \"support.other.variable\",                                        },\n\t\t{ \"scope\": \"string.constant\",                      \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"string.regexp\",                        \"foreground\": \"#f6aa11\", },\n\t\t{ \"scope\": \"string.variable\",                      \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.definition.variable\",      \"foreground\": \"#ffffff\", },\n\t\t// Html / Xml\n\t\t{ \"scope\": \"meta.tag.sgml.doctype.xml\",            \"foreground\": \"#c8cecc\", },\n\t\t{ \"scope\": \"declaration.sgml.html declaration.doctype\",         \"foreground\": \"#c8cecc\", },\n\t\t{ \"scope\": \"declaration.sgml.html declaration.doctype entity\",  \"foreground\": \"#c8cecc\", },\n\t\t{ \"scope\": \"declaration.sgml.html declaration.doctype string\",  \"foreground\": \"#c8cecc\", },\n\t\t{ \"scope\": \"content.block.html\",                                \"foreground\": \"#7c7865\", },\n\t\t{ \"scope\": \"entity.name.tag.script.html\",                       \"font_style\": \"italic\",},\n\t\t{ \"scope\": \"text.html.basic meta.tag.other.html\",               \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.any.html\",                 \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.block.any\",                \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.inline.any\",               \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.structure.any.html\",       \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.structure.any.html\",       \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic source.js.embedded.html\",           \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"punctuation.separator.key-value.html\",              \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic entity.other.attribute-name\",       \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"text.html.basic meta.tag.structure.any.html punctuation.definition.string.begin.html\",       \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.definition.string.begin.html\",          \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.definition.string.end.html\",            \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.definition.tag.end\",                    \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.definition.tag.begin\",                  \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.definition.tag\",                        \"foreground\": \"#ffffff\", },\n\t\t// Handlebars\n\t\t{ \"scope\": \"variable.parameter.handlebars\",                     \"foreground\": \"#f6aa11\", },\n\t\t{ \"scope\": \"support.constant.handlebars\",                       \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"meta.function.block.start.handlebars\",              \"foreground\": \"#66d9ef\", },\n\t\t// CSS\n\t\t{ \"scope\": \"meta.preprocessor.at-rule\",                            \"foreground\": \"#f6aa11\", },\n\t\t{ \"scope\": \"meta.selector.css entity.other.attribute-name.id\",     \"foreground\": \"#f6aa11\", },\n\t\t{ \"scope\": \"meta.selector.css entity.other.attribute-name.class\",  \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"support.type.property-name.css\",                       \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"meta.constructor.argument.css\",                        \"foreground\": \"#f6aa11\", },\n\t\t{ \"scope\": \"punctuation.section.property-list.css\",                \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.definition.tag.css\",                       \"foreground\": \"#f92672\", },\n\t\t{ \"scope\": \"punctuation.separator.key-value.css\",                  \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"punctuation.terminator.rule.css\",                      \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"entity.other.attribute-name.pseudo-element.css\",       \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"entity.other.attribute-name.pseudo-class.css\",         \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"entity.other.attribute-name.pseudo-selector.css\",      \"foreground\": \"#a6e22e\", },\n\t\t// LESS Variables\n\t\t{ \"scope\": \"variable.other.less\",                                  \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"variable.other.less.mixin\",                            \"foreground\": \"#e0fdce\", \"font_style\": \"italic\"},\n\t\t{ \"scope\": \"entity.other.attribute-name.pseudo-element.less\",      \"foreground\": \"#ff9117\", },\n\t\t// Javascript\n\t\t{ \"scope\": \"meta.instance.constructor meta.function-call.constructor.js\",                          \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"meta.template.expression.js punctuation.definition.template-expression.begin.js\",      \"foreground\": \"#AFF132\", },\n\t\t{ \"scope\": \"meta.template.expression.js punctuation.definition.template-expression.end.js\",        \"foreground\": \"#AFF132\", },\n\t\t{ \"scope\": \"meta.template.expression.js punctuation.accessor\",                                     \"foreground\": \"#AFF132\", },\n\t\t{ \"scope\": \"meta.function.js\",                                                                     \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"entity.name.function.js\",                                                              \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"support.function.dom.js\",                                                              \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"source.js meta.function.js punctuation.separator.parameter.function.js\",               \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"meta.property.object.js\",                                                              \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"keyword.operator.accessor.js\",                                                         \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"source.js meta.group.braces.curly constant.other.object.key.js punctuation.separator.key-value.js\", \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"source.js meta.group.braces.curly constant.other.object.key.js string.unquoted.label.js\", \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"support.type.object.module.js\",                                                        \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"source.js meta.function.declaration.js support.class.js\",                              \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"support.type.object.module.js support.type.object.module.js\",                          \"foreground\": \"#a6e22e\", },\n\t\t{ \"scope\": \"storage.type.js\",                                                                      \"foreground\": \"#66d9ef\", \"font_style\": \"italic\",},\n\t\t{ \"scope\": \"text.html.basic source.js.embedded.html\",                                              \"foreground\": \"#ffffff\", },\n\t\t{ \"scope\": \"storage.type.function.js\",                                                             \"foreground\": \"#66d9ef\", },\n\t\t{ \"scope\": \"constant.numeric.js\",                                                                  \"foreground\": \"#ae81ff\", },\n\t\t// JS: Literal language variable\t\n\t\t{ \"scope\": \"variable.language.arguments.js, variable.language.super.js, variable.language.this.js, variable.language.self.js, variable.language.proto.js, variable.language.constructor.js, variable.language.prototype.js\",                                                                  \"foreground\": \"#66d9ef\", \"font_style\": \"italic\",},\n        // JS: []\n        { \"scope\": \"meta.brace.square.js\", \"foreground\": \"#ffffff\", },\n        // JS: ()\n        { \"scope\": \"meta.brace.round, punctuation.definition.parameters.begin.js, punctuation.definition.parameters.end.js, punctuation.definition.group\", \"foreground\": \"#ffffff\", },\n        // JS: object literal {}\n        { \"scope\": \"meta.brace.curly.js, meta.object-literal.js\", \"foreground\": \"#ffffff\", },\n        // JSON String\n        { \"scope\": \"meta.structure.dictionary.json string.quoted.double.json\", \"foreground\": \"#cfcfc2\", },\n        // CoffeeScript String Interpolated\n        { \"scope\": \"punctuation.section.embedded.coffee\", \"foreground\": \"#e69f66\", },\n        // PHP: []\n        { \"scope\": \"keyword.operator.index-start.php, keyword.operator.index-end.php\", \"foreground\": \"#ffffff\", },\n        // PHP: Array\n        { \"scope\": \"meta.array.php\", \"foreground\": \"#ffffff\", },\n        // PHP: Array()\n        { \"scope\": \"meta.array.php support.function.construct.php, meta.array.empty.php support.function.construct.php\", \"foreground\": \"#e42e70\", },\n        // PHP: Array Construct\n        { \"scope\": \"support.function.construct.php\", \"foreground\": \"#e42e70\", },\n        // PHP: Storage Type Function\n        { \"scope\": \"storage.type.function.php\", \"foreground\": \"#f92672dd\", },\n        // PHP: Numeric Constant\n        { \"scope\": \"constant.numeric.php\", \"foreground\": \"#be84ff\", },\n        // PHP: New\n        { \"scope\": \"keyword.other.new.php\", \"foreground\": \"#f6aa11\", },\n        // PHP: ::\n        { \"scope\": \"support.class.php\", \"foreground\": \"#ffffff\", },\n        // PHP: Other Property\n        { \"scope\": \"variable.other.property.php\", \"foreground\": \"#f6aa11\", },\n        // PHP: Class\n        { \"scope\": \"storage.modifier.extends.php, storage.type.class.php, keyword.operator.class.php\", \"foreground\": \"#a6e22e\", },\n        // PHP: Inherited Class\n        { \"scope\": \"meta.other.inherited-class.php\", \"foreground\": \"#a6e22e\", },\n        // PHP: Storage Type\n        { \"scope\": \"storage.type.php\", \"foreground\": \"#66d9ef\", },\n        // PHP: Function\n        { \"scope\": \"entity.name.function.php\", \"foreground\": \"#66d9ef\", },\n        // PHP: Function Construct\n        { \"scope\": \"support.function.construct.php\", \"foreground\": \"#a6e22e\", },\n        // PHP: Function Call\n        { \"scope\": \"entity.name.type.class.php, meta.function-call.php, meta.function-call.static.php, meta.function-call.object.php\", \"foreground\": \"#ffffff\", },\n        // PHP: Comment\n        { \"scope\": \"keyword.other.phpdoc\", \"foreground\": \"#7c7865\", },\n        // PHP: Source Emebedded\n        { \"scope\": \"source.php.embedded.block.html\", \"foreground\": \"#ffffff\", },\n        // Invalid\n        { \"scope\": \"invalid\", \"foreground\": \"#f8f8f0\",\"background\": \"#f92672\", },\n        // Invalid deprecated\n        { \"scope\": \"invalid.deprecated\", \"foreground\": \"#f8f8f0\",\"background\": \"#ae81ff\", },\n        // diff.header\n        { \"scope\": \"meta.diff, meta.diff.header\", \"foreground\": \"#75715e\", },\n        // diff.deleted\n        { \"scope\": \"markup.deleted\", \"foreground\": \"#f92672\", },\n        // diff.inserted\n        { \"scope\": \"markup.inserted\", \"foreground\": \"#a6e22e\", },\n        // diff.changed\n        { \"scope\": \"markup.changed\", \"foreground\": \"#e6db74\", },\n        // diff.range\n        { \"scope\": \"meta.diff, meta.diff.range\", \"foreground\": \"#3bc0f0\", },\n        // Python: storage\n        { \"scope\": \"storage.type.class.python, storage.type.function.python, storage.modifier.global.python\", \"foreground\": \"#a6e22e\", },\n        // Python: import\n        { \"scope\": \"keyword.control.import.python, keyword.control.import.from.python\", \"foreground\": \"#f92672dd\", },\n        // Python: Support.exception\n        { \"scope\": \"support.type.exception.python\", \"foreground\": \"#66d9ef\", },\n        // Perl: variables\n        { \"scope\": \"punctuation.definition.variable.perl, variable.other.readwrite.global.perl, variable.other.predefined.perl, keyword.operator.comparison.perl\", \"foreground\": \"#e42e70\", },\n        // Perl: functions\n        { \"scope\": \"support.function.perl\", \"foreground\": \"#66d9ef\", },\n        // Perl: comments\n        { \"scope\": \"comment.line.number-sign.perl\", \"foreground\": \"#75715e\",\"font_style\": \"italic\", },\n        // Perl: quotes\n        { \"scope\": \"punctuation.definition.string.begin.perl, punctuation.definition.string.end.perl\", \"foreground\": \"#ffffff\", },\n        // Perl: char\n        { \"scope\": \"constant.character.escape.perl\", \"foreground\": \"#dc322f\", },\n        // Ruby: Constant\n        { \"scope\": \"constant.language.ruby, constant.numeric.ruby\", \"foreground\": \"#ae81ff\", },\n        // Ruby: Variable definition\n        { \"scope\": \"punctuation.definition.variable.ruby\", \"foreground\": \"#f6aa11\", },\n        // Ruby: Function Name\n        { \"scope\": \"meta.function.method.with-arguments.ruby\", \"foreground\": \"#a6e22e\", },\n        // Ruby: Variable\n        { \"scope\": \"variable.language.ruby\", \"foreground\": \"#ffffff\", },\n        // Ruby: Function\n        { \"scope\": \"entity.name.function.ruby\", \"foreground\": \"#f6aa11\", },\n        // Ruby: Keyword Control\n        { \"scope\": \"keyword.control.ruby, keyword.control.def.ruby\", \"foreground\": \"#a6e22e\",\"font_style\": \"bold\", },\n        // Ruby: Class\n        { \"scope\": \"keyword.control.class.ruby, meta.class.ruby\", \"foreground\": \"#a6e22e\", },\n        // Ruby: Class Name\n        { \"scope\": \"entity.name.type.class.ruby\", \"foreground\": \"#66d9ef\", },\n        // Ruby: Keyword\n        { \"scope\": \"keyword.control.ruby\", \"foreground\": \"#a6e22e\", },\n        // Ruby: Support Class\n        { \"scope\": \"support.class.ruby\", \"foreground\": \"#66d9ef\", },\n        // Ruby: Special Method\n        { \"scope\": \"keyword.other.special-method.ruby\", \"foreground\": \"#a6e22e\", },\n        // Ruby: Constant Other\n        { \"scope\": \"variable.other.constant.ruby\", \"foreground\": \"#66d9ef\", },\n        // Ruby: :symbol\n        { \"scope\": \"constant.other.symbol.ruby\", \"foreground\": \"#f6f080\", },\n        // Ruby: Punctuation Section\n        { \"scope\": \"punctuation.section.embedded.ruby, punctuation.definition.string.begin.ruby, punctuation.definition.string.end.ruby\", \"foreground\": \"#f92672\", },\n        // Ruby: Special Method\n        { \"scope\": \"keyword.other.special-method.ruby\", \"foreground\": \"#e42e70\", },\n        // Markdown: plain\n        { \"scope\": \"text.html.markdown\", \"foreground\": \"#ffffff\", },\n        // Markup: raw inline\n        { \"scope\": \"text.html.markdown markup.raw.inline\", \"foreground\": \"#ec3533\", },\n        // Markdown: linebreak\n        { \"scope\": \"text.html.markdown meta.dummy.line-break\", \"foreground\": \"#e0eddd\", },\n        // Markdown: heading\n        { \"scope\": \"markdown.heading, markup.heading | markup.heading entity.name, markup.heading.markdown punctuation.definition.heading.markdown\", \"foreground\": \"#fd971f\", },\n        // Markup: italic\n        { \"scope\": \"markup.italic\", \"foreground\": \"#e42e70\",\"font_style\": \"italic\", },\n        // Markup: bold\n        { \"scope\": \"markup.bold\", \"foreground\": \"#f92672\",\"font_style\": \"bold\", },\n        // Markup: underline\n        { \"scope\": \"markup.underline\", \"foreground\": \"#a6e22e\",\"font_style\": \"underline\", },\n        // Markup: strike\n        { \"scope\": \"markup.strike\", \"foreground\": \"#cc4273\", },\n        // Markdown: Blockquote\n        { \"scope\": \"markup.quote, punctuation.definition.blockquote.markdown\", \"foreground\": \"#66d9ef\",\"font_style\": \"italic\", },\n        // Markup: Quote\n        { \"scope\": \"markup.quote\", \"foreground\": \"#66d9ef\",\"font_style\": \" italic\", },\n        // Markdown: Link\n        { \"scope\": \"string.other.link.title.markdown\", \"foreground\": \"#66d9ef\",\"font_style\": \"underline\", },\n        // Markup: Raw block\n        { \"scope\": \"markup.raw.block\", \"foreground\": \"#ae81ff\", },\n        // Markdown: List Items Punctuation\n        { \"scope\": \"punctuation.definition.list_item.markdown\", \"foreground\": \"#777777\", },\n        // Markdown: Raw Block fenced\n        { \"scope\": \"markup.raw.block.fenced.markdown\", \"foreground\": \"#ffffff\",\"background\": \"#222\", },\n        // Markdown: Fenced Bode Block\n        { \"scope\": \"punctuation.definition.fenced.markdown, variable.language.fenced.markdown\", \"foreground\": \"#636050\",\"background\": \"#222222\", },\n        // Markdown: Fenced Language\n        { \"scope\": \"variable.language.fenced.markdown\", \"foreground\": \"#7c7865\", },\n        // Markdown: Separator\n        { \"scope\": \"meta.separator\", \"foreground\": \"#ffffff33\",\"background\": \"#ffffff0f\",\"font_style\": \"bold\", },\n        // Markup: table\n        { \"scope\": \"markup.table\", \"foreground\": \"#b42a1d\",\"background\": \"#ff3a281a\", },\n        // LaTeX: Math Variables\n        { \"scope\": \"variable.other.math.tex\", \"foreground\": \"#e6db74\", },\n        // Other: Removal\n        { \"scope\": \"other.package.exclude, other.remove\", \"foreground\": \"#d3201f\", },\n        // Shell: builtin\n        { \"scope\": \"support.function.builtin.shell\", \"foreground\": \"#a6e22e\", },\n        // Shell: variable\n        { \"scope\": \"variable.other.normal.shell\", \"foreground\": \"#66d9ef\", },\n        // Shell: DOTFILES\n        { \"scope\": \"source.shell\", \"foreground\": \"#ffffff\", },\n        // Shell: meta scope in loop\n        { \"scope\": \"meta.scope.for-in-loop.shell, variable.other.loop.shell\", \"foreground\": \"#fd971f\", },\n        // Shell: Function name\n        { \"scope\": \"entity.name.function.shell\", \"foreground\": \"#a6e22e\", },\n        // Shell: Quotation Marks\n        { \"scope\": \"punctuation.definition.string.end.shell, punctuation.definition.string.begin.shell\", \"foreground\": \"#ffffff\", },\n        // Shell: Meta Block\n        { \"scope\": \"meta.scope.case-block.shell, meta.scope.case-body.shell\", \"foreground\": \"#fd971f\", },\n        // Shell: []\n        { \"scope\": \"punctuation.definition.logical-expression.shell\", \"foreground\": \"#ffffff\", },\n        // Shell: Comment\n        { \"scope\": \"comment.line.number-sign.shell\", \"foreground\": \"#7c7865\",\"font_style\": \"italic\", },\n        // Makefile: Comment\n        { \"scope\": \"comment.line.number-sign.makefile\", \"foreground\": \"#7c7865\", },\n        // Makefile: Comment punctuation\n        { \"scope\": \"punctuation.definition.comment.makefile\", \"foreground\": \"#7c7865\", },\n        // Makefile: Variables\n        { \"scope\": \"variable.other.makefile\", \"foreground\": \"#f92672\", },\n        // Makefile: Function name\n        { \"scope\": \"entity.name.function.makefile\", \"foreground\": \"#a6e22e\", },\n        // Makefile: Function\n        { \"scope\": \"meta.function.makefile\", \"foreground\": \"#66d9ef\", },\n        // GitGutter deleted\n        { \"scope\": \"markup.deleted.git_gutter\", \"foreground\": \"#F92672\", },\n        // GitGutter inserted\n        { \"scope\": \"markup.inserted.git_gutter\", \"foreground\": \"#A6E22E\", },\n        // GitGutter changed\n        { \"scope\": \"markup.changed.git_gutter\", \"foreground\": \"#FC951E\", },\n        // GitGutter ignored\n        { \"scope\": \"markup.ignored.git_gutter\", \"foreground\": \"#565656\", },\n        // GitGutter untracked\n        { \"scope\": \"markup.untracked.git_gutter\", \"foreground\": \"#565656\", },\n        // Nginx path\n        { \"scope\": \"string.other.path.nginx\", \"foreground\": \"#fc951e\", },\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.0\",\n\t\t\t\"foreground\": \"#550000\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.1\",\n\t\t\t\"foreground\": \"#007700\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.2\",\n\t\t\t\"foreground\": \"#770077\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.3\",\n\t\t\t\"foreground\": \"#0000ff\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.4\",\n\t\t\t\"foreground\": \"#999900\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.5\",\n\t\t\t\"foreground\": \"#007777\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.6\",\n\t\t\t\"foreground\": \"#aa5522\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.7\",\n\t\t\t\"foreground\": \"#cc99cc\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.8\",\n\t\t\t\"foreground\": \"#225522\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.9\",\n\t\t\t\"foreground\": \"#623456\",\n\t\t},\n\n\t]\n}\n\n"
  },
  {
    "path": "OrgExtended.sublime-commands",
    "content": "[\n\n    // Give the user access to our settings in the preferences menu\n    {\n        \"caption\": \"Preferences: OrgExtended Settings – Default\",\n        \"command\": \"open_file\",\n        \"args\": {\n            \"file\": \"${packages}/OrgExtended/OrgExtended.sublime-settings\"\n        }\n    },\n    {\n        \"caption\": \"Preferences: OrgExtended Settings – User\",\n        \"command\": \"open_file\",\n        \"args\": {\n            \"file\": \"${packages}/User/OrgExtended.sublime-settings\"\n        }\n    },\n    {\"caption\": \"TableNext\", \"command\":\"table_editor_next_field\"},\n\n    {\"caption\": \"Org New File\",                \"command\": \"org_new_file\"                },\n    {\"caption\": \"Org Jump In File\",            \"command\": \"org_jump_in_file\"            },\n    {\"caption\": \"Org Tab Cycling\",             \"command\": \"org_tab_cycling\"             },\n    {\"caption\": \"Org Global Tab Cycling\",      \"command\": \"org_global_tab_cycling\"      },\n    {\"caption\": \"Org Fold All\",                \"command\": \"org_fold_all\"                },\n    {\"caption\": \"Org Unfold All\",              \"command\": \"org_unfold_all\"              },\n    {\"caption\": \"Org Fold Contents\",           \"command\": \"org_fold_contents\"           },\n    {\"caption\": \"Org Copy\",                    \"command\": \"org_copy\"                    },\n    {\"caption\": \"Org Refile\",                  \"command\": \"org_refile\"                  },\n    {\"caption\": \"Org Refile To EOF\",           \"command\": \"org_refile_to_file\"          },\n    {\"caption\": \"Org Refile File and Heading\", \"command\": \"org_refile_to_file_and_headline\"},\n    {\"caption\": \"Org Archive Subtree\",         \"command\": \"org_archive_subtree\"         },\n    {\"caption\": \"Org Archive All Done\",        \"command\": \"org_archive_all_done\"        },\n    {\"caption\": \"Org Open Refile\",             \"command\": \"org_open_refile\"             },\n    {\"caption\": \"Org Capture\",  \t           \"command\": \"org_capture\"                 },\n    {\"caption\": \"Org Rebuild Db\",\t           \"command\": \"org_rebuild_db\"              },\n    {\"caption\": \"Org Up\",    \t               \"command\": \"org_up\"                      },\n    {\"caption\": \"Org Down\",    \t               \"command\": \"org_down\"                    },\n    {\"caption\": \"Org Remove All Folds\",        \"command\": \"org_remove_all_folds\"        },\n    {\"caption\": \"Org Change Todo\",             \"command\": \"org_todo_change\"             },\n    {\"caption\": \"Org Change Priority\",         \"command\": \"org_priority_change\"         },\n    {\"caption\": \"Org Change Indent\",           \"command\": \"org_change_indent\"           },\n    {\"caption\": \"Org Change DeIndent\",         \"command\": \"org_change_de_indent\"        },\n    {\"caption\": \"Org Reload File\",             \"command\": \"org_reload_file\"             },\n    {\"caption\": \"Org Fold Thing\",              \"command\": \"org_fold_thing\"              },\n    {\"caption\": \"Org Fold Others\",             \"command\": \"org_fold_all_but_me\"         },\n    {\"caption\": \"Org Move Heading Up\",         \"command\": \"org_move_heading_up\"         },\n    {\"caption\": \"Org Move Heading Down\",       \"command\": \"org_move_heading_down\"       },\n    {\"caption\": \"Org Open Link\",               \"command\": \"org_open_link\"               },\n    {\"caption\": \"Org Fold All Links\",          \"command\": \"org_fold_all_links\"          },\n    {\"caption\": \"Org Show Images\",             \"command\": \"org_show_images\"             },\n    {\"caption\": \"Org Hide Images\",             \"command\": \"org_hide_images\"             },\n    {\"caption\": \"Org Show Image\",              \"command\": \"org_show_image\"              },\n    {\"caption\": \"Org Hide Image\",              \"command\": \"org_hide_image\"              },\n    {\"caption\": \"Org Link To File\",            \"command\": \"org_link_to_file\"            },\n    {\"caption\": \"Org Jump To Backlink\",        \"command\": \"org_jump_to_backlinks\"       },\n    {\"caption\": \"Org Show Backlinks\",          \"command\": \"org_show_backlinks\"          },\n    {\"caption\": \"Org Search Links\",            \"command\": \"org_search_links\"            },\n    {\"caption\": \"Org Insert Heading Sibling\",  \"command\": \"org_insert_heading_sibling\"  },\n    {\"caption\": \"Org Insert Heading Child\",    \"command\": \"org_insert_heading_child\"    },\n    {\"caption\": \"Org Insert Date Inactive\",    \"command\": \"org_insert_date_inactive\"    },\n    {\"caption\": \"Org Insert Date Active\",      \"command\": \"org_insert_date_active\"      },\n    {\"caption\": \"Org Insert Today Inactive\",   \"command\": \"org_insert_today_inactive\"   },\n    {\"caption\": \"Org Insert Today Active\",     \"command\": \"org_insert_today_active\"     },\n    {\"caption\": \"Org Insert Now Inactive\",     \"command\": \"org_insert_now_inactive\"     },\n    {\"caption\": \"Org Insert Now Active\",       \"command\": \"org_insert_now_active\"       },\n    {\"caption\": \"Org Insert Created Property\", \"command\": \"org_insert_created_property\" },\n    {\"caption\": \"Org Insert Drawer\",           \"command\": \"org_insert_drawer\"           },\n    {\"caption\": \"Org Insert Property Drawer\",  \"command\": \"org_insert_property_drawer\"  },\n    {\"caption\": \"Org Insert Property\",         \"command\": \"org_insert_property\"         },\n    {\"caption\": \"Org Set Today\",               \"command\": \"org_set_today\"               },\n    {\"caption\": \"Org Clock In\",                \"command\": \"org_clock_in\"                },\n    {\"caption\": \"Org Clock Out\",               \"command\": \"org_clock_out\"               },\n    {\"caption\": \"Org Clear Clock\",             \"command\": \"org_clear_clock\"             },\n    {\"caption\": \"Org Recalculate Clock\",       \"command\": \"org_recalculate_clock\"       },\n    {\"caption\": \"Org Jump To Clock\",           \"command\": \"org_jump_to_clock\"           },\n    {\"caption\": \"Org Update Active Clock\",     \"command\": \"org_update_clock\"            },\n    {\"caption\": \"Org Todo View\",               \"command\": \"org_todo_view\"               },\n    {\"caption\": \"Org Filtered Todo View\",      \"command\": \"org_tag_filtered_todo_view\"  },\n    {\"caption\": \"Org Exec Dynamic Block\",      \"command\": \"org_execute_dynamic_block\"   },\n    {\"caption\": \"Org Exec Source Block\",       \"command\": \"org_execute_source_block\"    },\n    {\"caption\": \"Org Exec All Source Blocks\",  \"command\": \"org_execute_all_source_blocks\"},\n    {\"caption\": \"Org Exec Inline Source Block\",\"command\": \"org_execute_inline_source_block\"},\n    {\"caption\": \"Org Tangle File\",             \"command\": \"org_tangle_file\"             },\n    {\"caption\": \"Org Checkbox Toggle\",         \"command\": \"org_toggle_checkbox\"         },\n    {\"caption\": \"Org Recalc Checkbox\",         \"command\": \"org_recalc_checkbox_summary\" },\n    {\"caption\": \"Org Recalc All Checkbox\",     \"command\": \"org_recalc_all_checkbox_summaries\" },\n    {\"caption\": \"Org Add Checkbox Summary\",    \"command\": \"org_insert_checkbox_summary\" },\n    {\"caption\": \"Org Jump To CustomId\",        \"command\": \"org_jump_to_custom_id\"       },\n    {\"caption\": \"Org Jump To Today\",           \"command\": \"org_jump_to_today\"           },\n    {\"caption\": \"Org Insert Tag\",              \"command\": \"org_insert_tag\"              },\n    {\"caption\": \"Org Remove Tag\",              \"command\": \"org_remove_tag\"              },\n    {\"caption\": \"Org Remove All Tags\",         \"command\": \"org_remove_all_tags\"         },\n    {\"caption\": \"Org Fix Tags\",                \"command\": \"org_fix_tags\"                },\n    {\"caption\": \"Org Closed\",                  \"command\": \"org_insert_closed\"           },\n    {\"caption\": \"Org Insert CustomId\",         \"command\": \"org_insert_custom_id\"        },\n    {\"caption\": \"Org Schedule\",                \"command\": \"org_schedule\"                },\n    {\"caption\": \"Org Deadline\",                \"command\": \"org_deadline\"                },\n    {\"caption\": \"Org Timestamp\",               \"command\": \"org_active_timestamp\"        },\n    {\"caption\": \"Org Create Link\",             \"command\": \"org_create_link\"             },\n    {\"caption\": \"Org Link To Today\",           \"command\": \"org_link_to_today\"           },\n    {\"caption\": \"Org Update Numbered List\",    \"command\": \"org_update_numbered_list\"    },\n    {\"caption\": \"Org Append Numbered List\",    \"command\": \"org_append_numbered_list\"    },\n    {\"caption\": \"Org Select Subtree\",          \"command\": \"org_select_subtree\"          },\n    {\"caption\": \"Org Select Entity\",           \"command\": \"org_select_entity\"           },\n    {\"caption\": \"Org Select Href\",             \"command\": \"org_select_link_href\"        },\n    {\"caption\": \"Org Copy Subtree\",            \"command\": \"org_copy_subtree\"            },\n    {\"caption\": \"Org Copy Entity\",             \"command\": \"org_copy_entity\"             },\n    {\"caption\": \"Org Copy Href\",               \"command\": \"org_copy_link_href\"          },\n    {\"caption\": \"Org Sort List\",               \"command\": \"org_sort_list\"               },\n    {\"caption\": \"Org Create Heading Id\",       \"command\": \"org_create_heading_id\"       },\n    {\"caption\": \"Org Insert Effort\",           \"command\": \"org_insert_effort\"           },\n    {\"caption\": \"Org Insert Archive Tag\",      \"command\": \"org_insert_archive_tag\"      },\n    {\"caption\": \"Org Execute Call\",            \"command\": \"org_execute_call_comment\"    },\n\n    // Agenda\n    {\"caption\": \"Org Agenda Goto\",             \"command\": \"org_agenda_go_to\"            },\n    {\"caption\": \"Org Agenda Goto Split\",       \"command\": \"org_agenda_go_to_split\"      },\n    {\"caption\": \"Org Agenda Change Todo\",      \"command\": \"org_agenda_change_todo\"      },\n    {\"caption\": \"Org Agenda Change Priority\",  \"command\": \"org_agenda_change_priority\"  },\n    {\"caption\": \"Org Agenda ClockIn\",          \"command\": \"org_agenda_clock_in\"         },\n    {\"caption\": \"Org Agenda ClockOut\",         \"command\": \"org_agenda_clock_out\"        },\n    {\"caption\": \"Org Agenda Insert Tag\",       \"command\": \"org_agenda_insert_tag\"       },\n    {\"caption\": \"Org Agenda Insert Effort\",    \"command\": \"org_agenda_insert_effort\"    },\n    {\"caption\": \"Org Agenda Insert Assign\",    \"command\": \"org_agenda_assign\"           },\n    {\"caption\": \"Org Agenda Insert Id\",        \"command\": \"org_agenda_id\"               },\n    {\"caption\": \"Org Agenda Day View\",         \"command\": \"org_agenda_day_view\"         },\n    {\"caption\": \"Org Agenda Custom View\",      \"command\": \"org_agenda_custom_view\"      },\n    {\"caption\": \"Org Agenda Rebuild Notices\",  \"command\": \"org_rebuild_notifications\"   },\n    {\"caption\": \"Org Agenda Choose View\",      \"command\": \"org_agenda_choose_custom_view\"},\n    {\"caption\": \"Org Agenda Goto Next Day\",    \"command\": \"org_agenda_goto_next_day\"    },\n    {\"caption\": \"Org Agenda Goto Prev Day\",    \"command\": \"org_agenda_goto_prev_day\"    },\n\n    // Date Picker\n    {\"caption\": \"Org Date Picker\",             \"command\": \"org_date_picker\"             },\n    {\"caption\": \"Org Date Next Day\",           \"command\": \"org_date_picker_next_day\"    },\n    {\"caption\": \"Org Date Prev Day\",           \"command\": \"org_date_picker_prev_day\"    },\n\n    // Export\n    {\"caption\": \"Org Export File As Reveal Js\",\"command\": \"org_export_file_reveal_js\"         },\n    {\"caption\": \"Org Export File As Html\",     \"command\": \"org_export_file_org_html\"          },\n    {\"caption\": \"Org Export Subtree As Html\",  \"command\": \"org_export_subtree_as_org_html\"    },\n    {\"caption\": \"Org Export File As Pdf\",      \"command\": \"org_export_file_as_pdf\"            },\n    {\"caption\": \"Org Export File As Latex\",    \"command\": \"org_export_file_as_latex\"          },\n    {\"caption\": \"Org Export File As Dnd\",      \"command\": \"org_export_file_as_dnd_pdf\"        },\n    {\"caption\": \"Org Pandoc File To Html\",     \"command\": \"org_export_file_as_html\"           },\n    {\"caption\": \"Org Pandoc Subtree To Html\",  \"command\": \"org_export_subtree_as_html\"        },\n\n    // Table Management\n    {\"caption\": \"Org Import Csv\",              \"command\": \"org_import_table_from_csv\"         },\n    {\"caption\": \"Org Convert Region To Table\", \"command\": \"org_convert_selection_to_table\"    },\n    {\"caption\": \"Org Insert Blank Table\",      \"command\": \"org_insert_blank_table\"            },\n    {\"caption\": \"Org Clear Table Highlights\",  \"command\": \"org_clear_table_regions\"           },\n    {\"caption\": \"Org Highlight Formula\",       \"command\": \"org_highlight_formula\"             },\n    {\"caption\": \"Org Eval Cell\",               \"command\": \"org_fill_in_formula_from_cell\"     },\n    {\"caption\": \"Org Show Table Rows\",         \"command\": \"org_show_table_rows\"               },\n    {\"caption\": \"Org Hide Table Rows\",         \"command\": \"org_hide_table_rows\"               },\n    {\"caption\": \"Org Plot Table\",              \"command\": \"org_plot_table\"                    },\n    {\"caption\": \"Org Execute All Tables\",      \"command\": \"org_execute_all_tables\"            },\n    {\"caption\": \"Org Execute Formula\",         \"command\": \"org_execute_formula\"               },\n    {\"caption\": \"Org Edit Table Formula\",      \"command\": \"org_edit_formula_for_cell\"         },\n    {\"caption\": \"Org Clear Table Cell\",        \"command\": \"org_clear_cell\"                    },\n    {\"caption\": \"Org Table Exec Below\",        \"command\": \"org_exec_on_column\"                },\n    {\"caption\": \"Org Insert Rnd Table Row\",    \"command\": \"org_insert_random_row_from_table\"  },\n\n    // Internal Mechanics\n    {\"caption\": \"Org Internal Keymap Gen\",     \"command\": \"org_create_keymap_doc\"             },\n    {\"caption\": \"Org Download Highligh Js\",    \"command\": \"org_download_highligh_js\"          },\n    {\"caption\": \"Org Select Color Scheme\",     \"command\": \"org_select_existing_color_scheme\"  },\n    {\"caption\": \"Org Create Color Scheme From Active\",     \"command\": \"org_create_color_scheme_from_active\"  },\n   \n    // Resources \n    {\"caption\": \"Org Show Worklog\",            \"command\": \"org_build_dev_docs\"                },\n    {\"caption\": \"Org Show TestFile\",           \"command\": \"org_show_testfile\"                 },\n    {\"caption\": \"Org Show Table Tests\",        \"command\": \"org_show_table_tests\"              },\n    {\"caption\": \"Org Show Source Tests\",       \"command\": \"org_show_source_block_tests\"       },\n\n    // Day Page\n    {\"caption\": \"Org Day Page Create\",         \"command\": \"org_day_page_create\"               },\n    {\"caption\": \"Org Day Page Previous\",       \"command\": \"org_day_page_previous\"             },\n    {\"caption\": \"Org Day Page Next\",           \"command\": \"org_day_page_next\"                 },\n    \n    // Internal Maintenance Commands\n    //{\"caption\": \"Org Output Table Docs\",       \"command\": \"org_doc_table\"                     },\n    //{\"caption\": \"Org Internal Syntax Gen\",     \"command\": \"org_regen_syntax_template\"         },\n    //{\"caption\": \"Org Test Thing\",              \"command\": \"org_show_item\"                     },\n    //{\"caption\": \"Org Test Durations\",          \"command\": \"org_test_duration\"                 },\n    //{\"caption\": \"Org Test PLists\",             \"command\": \"org_plist_test\"                    },\n    //{\"caption\": \"Org Test Template\",           \"command\": \"org_test_template\"                 },\n\n    // Beancount\n    {\"caption\": \"Org Beancount Create\",         \"command\": \"beancount_new_file\"                  },\n    {\"caption\": \"Org Beancount Transaction\",    \"command\": \"beancount_new_transaction\"           },\n\n    // Trello:\n    // Trello commands allow you to 2 way sync with a trello board. It does however require\n    // that you have the Trello package installed as I parasitically use that package.\n    {\"caption\": \"Org Trello Sync Board\",        \"command\": \"org_trello_sync_board\"               },\n\n    // Timesheet System\n    {\"caption\": \"Org Timesheet Table\",          \"command\": \"org_insert_timesheet\"                },\n    {\"caption\": \"Org Choose Timesheet Table\",   \"command\": \"org_choose_timesheet\"                },\n    {\"caption\": \"Org Timesheet Mermaid Gantt\",  \"command\": \"org_generate_mermaid_gantt_chart\"    },\n    {\"caption\": \"Org Timesheet Google Gantt\",   \"command\": \"org_generate_google_gantt_chart\"     },\n]\n"
  },
  {
    "path": "OrgExtended.sublime-keymap",
    "content": "[\n\t{ \"keys\": [\"ctrl+alt+x\"],        \"command\": \"org_capture\"                                                                                                    },\n\t{ \"keys\": [\"ctrl+up\"],           \"command\": \"org_up\" ,                 \"context\": [{ \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" }]},\n\t{ \"keys\": [\"ctrl+down\"],         \"command\": \"org_down\" ,               \"context\": [{ \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" }]},\n\t{ \"keys\": [\"tab\"],               \"command\": \"org_tab_cycling\",         \"context\": [{ \"key\": \"eol_selector\", \"operator\": \"equal\", \"operand\": \"text.orgmode\" }]}\n]"
  },
  {
    "path": "OrgExtended.sublime-project",
    "content": "{\n\t\"folders\":\n\t[\n\t\t{\n\t\t\t\"path\": \".\"\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "OrgExtended.sublime-settings",
    "content": "{\n\t// The color scheme to use for the capture buffer\n    // Right now I only have a light and dark scheme. In the future\n    // I hope to allow your color scheme to impact the scheme and to provide\n    // a means of extending your scheme with the org colors\n\t\"color_scheme\": \"Packages/OrgExtended/OrgExtended.sublime-color-scheme\",\n\n    // Turn on TableEditor for orgmode\n    \"enable_table_editor\": true,\n    \"table_editor_syntax\": \"EmacsOrgMode\",\n\n    // We turn on the autocompletions feature\n    // So we can show filenames in links\n    \"auto_complete\": true,\n    \"auto_complete_selector\": \"text.orgmode\",\n    //\"auto_complete_commit_on_tab\": true,\n    \"auto_complete_use_index\": true,\n\n    // Where should tags start in a headline?\n    // Tags will get inserted at this column\n    \"tagColumn\" : 80,\n\n    // Files which should be loaded outside Sublime when a file link is followed\n    \"file_exclude_patterns\": [\n        \"*.pdf\",\n        \"*.doc\",\n        \"*.docx\",\n        \"*.docm\",\n    ],\n\n\n    // ============================================================\n    // ORG DIRS:\n    // Where are your org files?\n    \"orgDirs\": [\n        \"c:\\\\Users\\\\ian\\\\notes\"\n    ],\n\n    // Specific files to add vs whole directories\n    //\"orgFiles\": [\n    //],\n\n    // Directories to exclude from parsing org files\n    //\"orgExcludeDirs\": [],\n\n    // Files to be excluded from org parsing\n    //\"orgExcludeFiles\": [],\n\n    // The Org DB will not load a file without one of these file extensions.\n    // It assumes we are somehow erroneously trying to load something wrong.\n    // If you create your own #+ARCHIVE: entries make sure the extensions are in here.\n    \"validOrgExtensions\": [ \".org\", \".org_archive\"],\n\n    // Startup is equivalent to #+STARTUP: showall in a file\n    // but has an effect on all org files. This controls what mode\n    // the org files show as globally. Valid values are:\n    // - showall - everything but drawers is shown\n    // - showeverything - even drawers are shown.\n    // - contents - like a table of contents, contents of headings is hidden but all headings shown\n    // - overview - only top level headings are shown. \n    // - noinlineimages - do not show images inline\n    // - inlineimages - show inline images in file\n    //    #+STARTUP: inlineimages\n    //    #+STARTUP: noinlineimages\n    \"startup\": [\"showall\", \"noinlineimages\"],\n\n    // override for logdone. Will force CLOSED: entries even if it is not in your startup.\n    //\"logdone\": true,\n\n    // Used in the tag selector for the font to use in the popup\n    //\"input_font_face\": \"Arial\",\n\n    // List of priorities we can insert / change to\n    // NOTE: only the letters (below) can be highlighted at the moment\n    //       I haven't found a good way to modify the grammer dynamically.\n    //\"priorities\": [\"A\",\"B\",\"C\",\"D\",\"E\"]\n    \n    // Globally where should things be archived?\n    // So the following will expand to myfile.org_archive\n    // NOTE: org allows for datetree/ and a few other options\n    //       we probably only support a subset of those\n    //       properly\n    \"archive\": \"%s_archive::* Archive\",\n\n\n    // When looking for images in org files, where might those images be located?\n    // The first path in this list is where generated images will be placed.\n    // If this list is empty a subdir of images under the first entry in orgDirs will be used.\n    \"imageSearchPath\": [],\n\n\n    \"resolver.jira.url\":\"http://sandbox.onjira.com/browse/%s\",\n    \"resolver.jira.pattern\":\"^(jira|j):(?P<issue>.+)$\",\n\n    //email\n    \"resolver.email.url\":\"mailto:%s\",\n    \"resolver.email.pattern\":\"^(?P<type>email|mailto):(?P<email>[^/]+)(/(?P<subject>.+))?$\",\n\n    //prompt\n    \"resolver.prompt.pattern\":\"^(cmd:|prompt:)(?P<path>.+)$\",\n\n    //file: Only these extensions will be opened in sublime when in a link others will be opened externally.\n    \"resolver.local_file.force_into_sublime\":\"'*.txt', '*.org', '*.py', '*.rb', '*.html', '*.css', '*.js', '*.php', '*.c', '*.cpp', '*.h', '*.png', '*.jpg', '*.gif', '*.cs'\",\n    //\"resolver.local_file.pattern\":\"^(file:)?(?P<filepath>.+?)(?::(?P<row>\\\\d+)(?::(?P<col>\\\\d+))?)?$\",\n\n    // ============================================================\n    // CAPTURE\n    // The quick capture buffer gets this name\n    \"captureBufferName\": \"*capture*\",\n\n    // What file format should we write out as. This should be a python encoding value\n    // CAN BE:\n    // - utf-8\n    // - utf-16\n    // - utf-32\n    // SEE: https://docs.python.org/3.3/library/codecs.html#standard-encodings\n    \"captureWriteFormat\": \"utf-8\",\n\n    // Captures go into this file for refiling later.\n    \"refile\": \"D:\\\\Build\\\\notes\\\\refile.org\",\n\n    // Org Capture templates $0 is where the cursor ends up.\n    \"captureTemplates\":\n    [\n        // OLD DO NOTE USE TEMPLATE TYPE\n        //{\n        //  \"name\": \"Todo\",\n        //  \"template\": \n        //      \"* TODO $0\\n  :PROPERTIES:\\n:CREATED: [{datetime}]\\n:END:\\n  \"\n        //},\n        // PREFER THE SNIPPET TYPE\n        {\n            \"name\":    \"Todo\",\n            \"type\":    \"entry\",\n            \"snippet\": \"todo_heading\",\n            \"target\": [\"file\",\"{refile}\"],\n        },\n        {\n            \"name\":    \"Note\",\n            \"type\":    \"entry\",\n            \"snippet\": \"note_heading\",\n            \"target\": [\"file\",\"{refile}\"],\n        },\n        {\n            \"name\":    \"Capture\",\n            \"type\":    \"entry\",\n            \"snippet\": \"capture_heading\",\n            \"target\": [\"file\",\"{refile}\"],\n        },\n        {\n            \"name\": \"Meeting\",\n            // types:\n            // entry      - An Org mode node, with a headline. Will be filed as the child of the target entry or as a top-level entry\n            // item       - A plain list item, placed in the first plain list at the target location\n            // checkitem  - A checkbox item. This only differs from the plain list item by the default template\n            // table-line - A new line in the first table at the target location. Where exactly the line will be inserted depends on the properties :prepend and :table-line-pos (see below)\n            // plain      - Text to be inserted as it is.\n            \"type\": \"entry\",\n            // targets: \n            // -------------\n            // SUPPORTED:\n            // file           - text appened at end of file.\n            // id             - text appened to existing org id in db\n            // file+headline  - unique headline in file [\"file+headline\",\"filename\",\"headline\"]\n            // file+olp       - full path to headline\n            // file+regexp    - heading is a match to the regexp\n            // clock          - insert under current item being clocked.\n            // file+datetree  - NOT YET SUPPORTED This target creates a heading in a date tree for today’s date. If the optional outline path is given, the tree will be built under the node it is pointing to\n            // function <name>- NOT YET SUPPORTED generic function to find location for you\n            // BUILD IN SYMBOLS:\n            // {date}         - current date\n            // {time}         - current time\n            // {file}         - current filename\n            // {daypage}.     - todays daypage (if setup)\n\n            \"target\": [\"file\",\"{refile}\"],\n            // \"target\": [\"file+headline\",\"{daypage}\",\"Headline Text\"],\n            // \"target\": [\"file+olp\"     ,\"{refile}\" ,\"Heading 1\", \"Heading 2\", ...],\n\n            // We have:\n            // - todo_heading     - make a todo heading at target\n            // - note_heading     - make a note heading at target\n            // - meeting_heading  - make a meeting heading at target\n            // - plain_template   - just put cursor at target\n            // You can add your own in the orgsnippets folder in Users.\n            \"snippet\": \"meeting_heading\",\n\n            // This can be panel or direct\n            // Panel will open up a panel that copies its contents to your target when\n            // the panel loses focus. Direct will open up the actual file at your traget\n            // during the capture\n            \"openas\": \"panel\",\n\n            // NONE OF THESE ARE CURRENTLY SUPPORTED\n            // HOPEFULLY IN THE FUTURE WE WILL SUPPORT THEM\n            //\"template\": \"* MEETING $0\\n  :PROPERTIES:\\n:CREATED: [{datetime}]\\n:END:\\n  \"\n            // prepend - Normally new captured information will be appended at the target location (last child, last table line, last list item, …). Setting this property changes that.\n            // immediate-finish - When set, do not offer to edit the information, just file it away immediately. This makes sense if the template only needs information that can be added automatically.\n            // empty-lines - Set this to the number of lines to insert before and after the new item. Default 0, and the only other common value is 1.\n            // clock-in - Start the clock in this item.\n            // clock-keep - Keep the clock running when filing the captured entry.\n            // clock-resume - If starting the capture interrupted a clock, restart that clock when finished with the capture. Note that clock-keep has precedence over clock-resume. When setting both to non-nil, the current clock will run and the previous one will not be resumed.\n            // time-prompt - Prompt for a date/time to be used for date/week trees and when filling the template. Without this property, capture uses the current date and time. Even if this property has not been set, you can force the same behavior by calling org-capture with a C-1 prefix argument.\n            // tree-type - When week, make a week tree instead of the month tree, i.e., place the headings for each day under a heading with the current ISO week.\n            // unnarrowed - Do not narrow the target buffer, simply show the full buffer. Default is to narrow it so that you only see the new material.\n            // table-line-pos - Specification of the location in the table where the new line should be inserted. It should be a string like ‘II-3’ meaning that the new line should become the third line before the second horizontal separator line.\n            // kill-buffer - If the target file was not yet visited when capture was invoked, kill the buffer again after capture is completed.\n            // no-save - Do not save the target file after finishing the capture.\n\n            // THESE ARE IMPLEMENTED:\n\n            // These are python date strings and allow you to control the header\n            // format of your datetree\n            // \"year-format\":  \"%Y\",          - The root of your datetree * 2021\n            // \"month-format\": \"%Y-%m %B\",    - The month section         ** 2021-11 November\n            // \"day-format\",   \"%Y-%m-%d %A\", - The day section           *** 2021-11-27 Saturday\n            \"properties\": [],\n        }       \n    ],\n\n    // ============================================================   \n    // AGENDA\n    // What does the composite agenda view show?\n    // You can add your own views but that is done through code.\n    // Right now I ONLY have this one composite view.\n    \"AgendaCustomViews\": \n    {\n        \"Default\": [\"Calendar\", \"Week\", \"Day\", \"Blocked Projects\", \"Next Tasks\", \"Loose Tasks\"],\n        \"Todos\":   [\"Todos\"],\n        \"Notes\":   [\"Notes\"],\n        \"Flags\":   [\"Todos : tagfilter |TAG1 |OTHERTAGS\", \"Todos : tagfilter OTHERTAGS\"],\n    },\n\n    // By default our first day of the week is Sunday\n    // But some people prefer the first day to be monday\n    // Set first day to Monday\n    \"firstDayOfWeek\": \"Sunday\",\n\n    // Configure the agenda header format\n    //\"agendaHeaderFormat\": \"%A \\t%d %B %Y\",\n\n    // Include files outside of orgDirs in the agenda\n    // (open files etc)\n    \"agendaIncludeFilesOutsideOrgDir\": false,\n\n    // Day view starts at 6am and ends at 7pm\n    \"agendaDayStartTime\": 6,\n    \"agendaDayEndTime\": 19,  \n\n    // What defines a project?\n    // nested_todo TODO with sub TODO's.\n    // tag         Heading with a :PROJECT: tag\n    // property    Heading with a :PROJECT: True property\n    \"agendaProjectIs\": \"nested_todo\",\n\n    // If you would like to only see the work week\n    // set num days to 5 and the firstDayOfWeek above\n    // to Monday\n    \"agendaWeekViewNumDays\": 7,\n\n    // Do you want todo views to pop up the filter box when they pop up or\n    // only after you ask for it. This is an input panel at the bottom of the view\n    // that lets you filter out todos that do not match a regex as you type it.\n    \"agendaTodoFilterByDefault\": false,\n\n    // Do you want the system to delete clocking entries smaller than 1 minute\n    // or keep them?\n    \"clockingSubMinuteClocks\": true,\n    \n    // We follow the same sort of syntax as the normal orgmode for todos.\n    // I don't have smart syntax highlighting on these. The grammar file gives\n    // me some basic highlighting, but only for this set. I am hoping in the future I can figure\n    // out some way to make this extensible.\n    \"todoStates\": [\"TODO\",\"NEXT\", \"BLOCKED\",\"WAITING\",\"FLAG\", \"CLEANUP\", \"IN-PROGRESS\", \"DOING\",\"|\", \"CANCELLED\",\"REASSIGNED\", \"DONE\",\"MEETING\",\"PHONE\",\"NOTE\", \"FIXED\"],\n\n    // ============================================================   \n    // NOTIFICATION THREAD\n    // This is the template used to notify outside of sublime on org notifications \n    //\"ExternalNotificationCommand\": [\"C:\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe\", \"-ExecutionPolicy\", \"Unrestricted\", \".\\\\balloontip.ps1\", \"\\\"{todo}\\\"\" , \"\\\"{time}\\\"\"]\n\n    // When notice thread is polling, how far off does event need to be?\n    \"notifyHoursBefore\": 0,\n    \"notifyMinsBefore\": 15,\n\n    // How often to check if an event is up? (in minutes)\n    \"noticePeriod\": 1,\n\n    // ============================================================   \n    // Pandoc export uses these to determine the style and the location of pandoc executable\n    // \"PandocPath\": \"C:\\Program Files\\Pandoc\\pandoc.exe\",\n    // \"PandocStyle\": \"blocky\",\n\n    // Turning this on allows you to write table functions and symbol\n    // extensions in: Packages/User/orgtable/myfunction.py \n    //\n    // These can be used in the TBLFM expressions on tables.\n    // These are turned OFF by default and can be enabled\n    // by you when you want to add your own extensions.\n    //\"enableTableExtensions\": true,\n\n    // By default extensions are lazy loaded the first time you encounter a table\n    // when writing an extension this can become tedious fast as it means you have to\n    // reload sublime to test your changes. Turn this on and sublime will forcibly reload\n    // extensions every time it goes to execute them.\n    //\"forceLoadExternalExtensions\": true,\n\n    // Turning this on will turn on a lot of additional logging to help diagnose problems\n    // during debugging. Do not enable unless you really want that.\n    // You will need to restart sublime to get this.\n    // \"enableDebugLogging\": true, \n\n    // This will cause org extended to aggressively re-fold a buffer marked as #+STARTUP: content when you refocus the buffer\n    // Some people may find this jarring so it is hidden behind an option for now.\n    //\"onFocusRespectStartupFolds\": true,\n\n    // ============================================================\n    // DAY PAGE\n    // Path where we would like day pages created\n    //\"dayPagePath\": \"PATH\",\n    //\n    // The name of your new day page snippet (without the file extention!)\n    //\"dayPageSnippet\": \"filename\",\n    //\n    // How should we name day pages? NOTE: This format is how we find old day pages\n    // This means if you change this we may not be able to find old content.\n    //\"dayPageNameFormat\": \"%a_%Y_%m_%d\",\n    //\n    // Do you want to use one page per day or one page per week?\n    // This only impacts the creation of a page not existing pages.\n    // set to \"week\" if you would like one page per week.\n    //\"dayPageMode\": \"day\",\n    //\n    // When in week mode what day should be the official day for your\n    // logs?\n    //\"dayPageModeWeekDay\": \"Monday\",\n    //\n    // Close out the previous day with a #+FILETAGS: ARCHIVE tag when\n    // a new day page is created \n    //\"dayPageArchiveOld\": true,\n    //\n    // Copy tasks in a TODO state from the previous day to a new day page.\n    //\"dayPageCopyOpenTasks\": true,\n    // ============================================================\n    // Source Block Handler Paths\n    // We do not automatically locate these at the moment.\n    //\"nodejsPath\": \"C:\\\\Program Files\\\\nodejs\\\\node.exe\",\n    //\"bashPath\":   \"C:\\\\Windows\\\\System32\\\\wsl.exe\",\n    //\"graphviz\":   \"C:\\\\Path\\\\To\\GraphvizExes\",\n    //\"plantuml\":   \"C:\\\\Path\\\\To\\\\Plantuml.jar\",\n    //\"ditaa\":      \"C:\\\\Path\\\\To\\\\Ditaa.jar\",\n    //\"mermaid\":      \"C:\\\\Path\\\\To\\\\mmdc\",\n    //\"gnuplot\":    \"C:\\Program Files\\gnuplot\\bin\\gnuplot.exe\"\n    //\"perlPath\":   \"<pathtoperlexe>\",\n    // For the plantuml source blocks, where is planuml found?\n    \"plantuml\": \"D:\\\\Build\\\\.imacs\\\\plantuml.jar\",\n\n    \"mermaid\":      \"C:/Users/ihdav/node_modules/.bin/mmdc\",\n    // These source block handlers are built in to org mode. If you want to replace them with your own\n    // version:\n    // 1. write a handler in Packages/User/orgsrc folder\n    // 2. remove them from your list in your settings file.\n    \"builtinSourceBlockHandlers\": [\"plantuml\", \"graphviz\", \"ditaa\", \"mermaid\", \"powershell\", \"python\", \"gnuplot\", \"cmd\", \"sh\", \"javascript\", \"perl\", \"csharp\"],\n    // These are source block aliases for languages listed in the builtinSourceBlockHandlers\n    \"builtinSourceBlockAliases\": {\n        \"bash\":  \"sh\",\n        \"bat\":   \"cmd\",\n        \"js\":    \"javascript\"\n    },\n\n    // These are the default state for all source execution. You can change the defaults by changing this plist\n    // Only exports curently supports default = code at the moment. It's a bit of a hack to avoid conflicts\n    // with the htmlDefaultSkipSrc option.\n    \"orgBabelDefaultHeaderArgs\": \":session none :results replace :exports default :cache no :noweb no\",\n\n    // During Html export some language types we skip exporting source by default unless the user\n    // has explicitly overriden the export. This option lets you control which languages we do that for.\n    \"htmlDefaultSkipSrc\": [\"plantuml\",\"graphviz\",\"ditaa\",\"gnuplot\"], \n\n    // Should we execute our source blocks on export?\n    \"htmlExecuteSourceOnExport\": true,\n\n    // Include roam tag in description when inserting file link\n    \"insertRoamTagToFileLink\": true,\n\n    // LaTeX path for Org Export File As Pdf\n    // \"latex2Pdf\": \"C:\\\\texlive\\\\2021\\\\bin\\\\win32\\\\pdflatex.exe\",\n    //\n    // If you need to control the language mapping you can do so here\n    // using this table. A quick example is below where we are mapping to [5.2]Lua\n    // rather than 5.0 Lua which is the default.\n    // \n    // LateX SRC_BLOC - LaTex Listing package language matching\n    // \"latexListingPackageLang\": {\n    //     \"python\":  \"Python\",\n    //     \"lua\":   \"[5.2]Lua\",\n    // },\n\n\n    // ============================================================\n    // BACKLINKS\n    //\n    // Turn this off if you do not want the system to try to auto\n    // update backlinks for you in the backlinks display\n    \"backlinksUpdate\": true,\n}\n"
  },
  {
    "path": "OrgExtended.sublime-syntax",
    "content": "%YAML 1.2\n---\n# See http://www.sublimetext.com/docs/3/syntax.html\nfile_extensions:\n  - org\n  - org_archive\n# Generic parent scope of the file\nscope: text.orgmode\nversion: 2\n\nvariables:\n  datetime: \"<\\\\d{4}-\\\\d{2}-\\\\d{2}(?:\\\\s*\\\\w{3})?\\\\s*(\\\\d{2}\\\\:\\\\d{2}(-\\\\d{2}\\\\:\\\\d{2})?)?\\\\s*([+]*\\\\d[wdmy])?>\"\n  unscheddatetime: \"\\\\[\\\\d{4}-\\\\d{2}-\\\\d{2}(?:\\\\s*\\\\w{3})?\\\\s*(\\\\d{2}\\\\:\\\\d{2})?\\\\s*([+]*\\\\d[wdmy])?\\\\]\"\n  tags: \"(^|):[\\\\w\\\\d:]+:\"\n  priority: '\\s*\\[((\\#A)|(\\#B)|(\\#C)|(\\#D)|(\\#E)|(\\#[a-zA-Z0-9]+))\\]\\s+'\n  state: (TODO)|(BLOCKED)|(WAITING)|(CANCELLED)|(DONE)|(MEETING)|(PHONE)|(NOTE)|(FLAG)|(CLEANUP)|(IN-PROGRESS)|(DOING)|(NEXT)|(REASSIGNED)|(FIXED)\n  beginmrk: BEGIN_SRC|begin_src\n  endmrk:   END_SRC|end_src\n  beginsrc: '(\\s*\\#\\+({{beginmrk}})\\s+)'\n  endsrc: '(\\s*\\#\\+({{endmrk}})\\s*)'\ncontexts:\n  # The prototype context is prepended to all contexts but those setting\n  # meta_include_prototype: false.\n  #prototype:\n  #- include: comments\n  header-matches:\n    - match: $\n      pop: true\n    - match: ({{state}}\\s+)?({{priority}})?[^\\[\\]:\\n]*(\\[\\d*[/%]\\d*\\])?({{tags}})?\n      captures:\n        2: variable.parameter orgmode.state.todo\n        3: variable.parameter orgmode.state.blocked\n        4: variable.parameter orgmode.state.waiting\n        5: variable.parameter orgmode.state.cancelled\n        6: variable.parameter orgmode.state.done\n        7: variable.parameter orgmode.state.meeting\n        8: variable.parameter orgmode.state.phone\n        9: variable.parameter orgmode.state.note\n        10: variable.parameter orgmode.state.flag\n        11: variable.parameter orgmode.state.cleanup\n        12: variable.parameter orgmode.state.inprogress\n        13: variable.parameter orgmode.state.doing\n        14: variable.parameter orgmode.state.next\n        15: variable.parameter orgmode.state.reassigned\n        16: variable.parameter orgmode.state.fixed\n        17: string.quoted orgmode.priority\n        18: string.quoted orgmode.priority.value\n        19: string.quoted orgmode.priority.value.a\n        20: string.quoted orgmode.priority.value.b\n        21: string.quoted orgmode.priority.value.c\n        22: string.quoted orgmode.priority.value.d\n        23: string.quoted orgmode.priority.value.e\n        24: string.quoted orgmode.priority.value.general\n        25: string.quoted orgmode.checkbox.summary\n        26: entity.name.tag.orgmode orgmode.tags.header\n  main:\n    # The main context is the initial starting point of our syntax.\n    # Include other contexts from here (or specify them directly).\n    #- include: keywords\n    #- include: numbers\n    #- include: strings\n      # --- # Todo investigate what this actually is?\n    - match: ^\\s*\\-\\-\\- [^\\n]*\n      scope: comment orgmode.page\n      # ~~~~~ # Todo investigate what this is?\n    - match: ^\\s*[~]+ [^\\n]*\n      scope: comment orgmode.break\n\n\n      # Generic headline, TODO: Make multiple of these so we can color them\n      # and sub captures so we can hide the extraneous stars\n      # embed_scope: entity.name.function.orgmode orgmode.headline\n    - match: ^\\s*[*]\\s+\n      push:\n        - meta_scope: entity.name.class.orgmode orgmode.headline\n        - include: header-matches\n    - match: ^\\s*([*])[*]\\s+\n      captures:\n        1: comment  orgmode.preamble\n      push:\n        - meta_scope: entity.name.function.orgmode orgmode.headline2\n        - include: header-matches\n    - match: ^\\s*([*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      push:\n        - meta_scope: entity.other.attribute-name.orgmode orgmode.headline3\n        - include: header-matches\n    - match: ^\\s*([*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      push:\n        - meta_scope: entity.name.section.orgmode orgmode.headline4\n        - include: header-matches\n    - match: ^\\s*([*][*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      push:\n        - meta_scope: entity.name.type.orgmode orgmode.headline5\n        - include: header-matches\n    - match: ^\\s*([*][*][*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      scope: orgmode.headline6\n      push:\n        - meta_scope: entity.name.filename orgmode.headline6\n        - include: header-matches\n    - match: ^\\s*([*][*][*][*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      scope: orgmode.headline7\n      push:\n        - meta_scope: entity.name.filename orgmode.headline7\n        - include: header-matches\n    - match: ^\\s*([*][*][*][*][*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      scope: orgmode.headline8\n      push:\n        - meta_scope: entity.name.filename orgmode.headline8\n        - include: header-matches\n    - match: ^\\s*([*][*][*][*][*][*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      scope: orgmode.headline9\n      push:\n        - meta_scope: entity.name.filename orgmode.headline9\n        - include: header-matches\n\n    - match: ^\\s*(\\|.+\\|)\n      captures:\n        1: markup.raw.block orgmode.table.block\n      scope: orgmode.table\n      # DEADLINE: <DATETIME>\n    - match: \"(DEADLINE:)\\\\s+({{datetime}})\"\n      captures:\n        1: keyword orgmode.statekeyword\n        2: markup.italic orgmode.datetime\n      scope: orgmode.deadline\n      # SCHEDULED: <DATETIME>\n    - match: \"(SCHEDULED:)\\\\s+({{datetime}})\"\n      captures:\n        1: keyword orgmode.statekeyword\n        2: markup.italic orgmode.datetime\n      scope: orgmode.scheduled\n      # CLOSED: [DATETIME]\n    - match: \"(CLOSED:)\\\\s+({{unscheddatetime}})\"\n      captures:\n        1: keyword orgmode.statekeyword\n        2: markup.italic orgmode.unscheddatetime\n      scope: orgmode.closed\n      # numbered list\n    - match: \"^\\\\s*([0-9]+[.)])\\\\s+(([^:]+\\\\s+)(::))?\"\n      captures:\n        1: constant.numeric\n        3: keyword orgmode.definition\n        4: punctuation orgmode.definition.marker\n      scope: orgmode.numberedlist\n      # bullet list\n    - match: \"^\\\\s*(\\\\-) (([^:]+\\\\s+)(::))?\"\n      captures:\n        1: constant.character\n        3: keyword orgmode.definition\n        4: punctuation orgmode.definition.marker\n      scope: orgmode.tack.minus\n      # bullet list\n    - match: \"^\\\\s*(\\\\+) (([^:]+\\\\s+)(::))?\"\n      captures:\n        1: constant.character\n        3: keyword orgmode.definition\n        4: punctuation orgmode.definition.marker\n      scope: orgmode.tack.plus\n      # To follow up: -> and =>\n    - match: \"^\\\\s*(\\\\-\\\\>|\\\\=\\\\>) \"\n      scope: orgmode.follow_up\n      # [-] Checkbox\n    - match: (\\[[ ]\\])\\s?\n      scope: string orgmode.checkbox\n    - match: (\\[([xX])\\])\\s?\n      scope: orgmode.checkbox.checked\n      captures:\n        1: string\n        2: keyword orgmode.checkbox.checked \n    - match: (\\[([\\-])\\])\\s?\n      scope: orgmode.checkbox.blocked\n      captures:\n        1: string\n        2: constant.other orgmode.checkbox.blocked\n      # [#/#] Checkbox summary\n    - match: (\\[\\d*[/%]\\d*\\])\n      scope: string orgmode.checkbox.summary\n      # [[link]]\n    - match: \\[(\\[([^\\]]+)\\])\\]\n      captures:\n        1: orgmode.link.textblock\n        2: comment orgmode.link.text.href\n      scope: markup.underline.link orgmode.link\n      # [[link][name]]\n    - match: \\[(\\[([^\\]]+)\\])(\\[([^\\]]+)\\])\\]\n      captures:\n        1: orgmode.link.hrefblock\n        2: comment orgmode.link.href\n        3: orgmode.link.textblock\n        4: markup.bold orgmode.link.text\n      scope: markup.underline.link orgmode.link\n    - match: http[s]?://[^ \\t]+\n      scope: orgmode.link.href\n    - match: \\b([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})\\b\n      scope: orgmode.email\n      # {{{results(=hello=)}}}\n    - match: '\\{\\{\\{results\\(([^)]+)\\)\\}\\}\\}'\n      scope: comment orgmode.results.inline\n      captures:\n        1: keyword orgmode.results.value\n      # {numerical_value}\n    - match: \\{(\\d+)\\}\n      scope: orgmode.link.internal.number\n      # {{headline}}\n    - match: \\{\\{(.+?)\\}\\}\n      scope: orgmode.link.internal.headline\n      # :TAG:\n    - match: \"(^|\\\\s):[\\\\w\\\\d:]+:\"\n      scope: entity.name.tag.orgmode orgmode.tags\n      # [code] block, not sure what these are.\n    - match: \\[code\\]\\s*\n      push:  code\n    - match: ^\\s*Traceback \\(most recent call last\\):\\s*$\n      push: pythonstack\n\n    - match: (^|\\s)\\*[^*]+\\*(^|\\s)\n      scope: markup.bold orgmode.bold\n\n    - match: (^|\\s)(/[^/]+/)($|\\s)\n      scope: markup.italic orgmode.italics\n\n    - match: \\b(_[^_]+_)\\b\n      scope: markup.underline orgmode.underline\n\n    - match: (^|\\s)\\+[^\\+]+\\+(^|\\s)\n      scope: markup.underline orgmode.strikethrough\n\n    - match: (^|\\s)~[^~]+~(^|\\s)\n      scope: orgmode.code\n\n    - match: (^|\\s)=[^=]+=(^|\\s)\n      scope: orgmode.verbatim\n\n\n    - match: '(<<)([^>]+)(>>)'\n      captures:\n        1: orgmode.target.bracket\n        2: comment orgmode.link.text.href orgmode.target\n        3: orgmode.target.bracket\n      scope: markup.underline.link\n\n    - match: '(\\s*\\#\\+(BEGIN_CENTER|begin_center)\\s*)'\n      captures:\n        1: orgmode.fence\n      push:\n        - meta_scope: constant.other orgmode.raw.block\n        - meta_content_scope: markup.raw.block orgmode.raw.block\n        - match: '(\\s*\\#\\+(END_CENTER|end_center)\\s*)'\n          captures:\n            1: orgmode.fence\n          pop: true\n    - match: '(\\s*\\#\\+(BEGIN_VERSE|begin_verse)\\s*)'\n      captures:\n        1: orgmode.fence\n      push:\n        - meta_scope: constant.other orgmode.raw.block\n        - meta_content_scope: markup.raw.block orgmode.raw.block\n        - match: '(\\s*\\#\\+(END_VERSE|end_verse)\\s*)'\n          captures:\n            1: orgmode.fence\n          pop: true\n    - match: '(\\s*\\#\\+(BEGIN_QUOTE|begin_quote)\\s*)'\n      captures:\n        1: orgmode.fence\n      push:\n        - meta_scope: constant.other orgmode.raw.block\n        - meta_content_scope: markup.raw.block orgmode.raw.block\n        - match: '(\\s*\\#\\+(END_QUOTE|end_quote)\\s*)'\n          captures:\n            1: orgmode.fence\n          pop: true\n    - match: '(\\s*\\#\\+(BEGIN_NOTES|begin_notes)\\s*)'\n      captures:\n        1: constant.other orgmode.fence\n      embed: scope:text.orgmode\n      escape: '(\\s*\\#\\+(END_NOTES|end_notes)\\s*)'\n      embed_scope: markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence\n\n    - match: '(\\s*\\#\\+(BEGIN_EXAMPLE|begin_example)\\s*)'\n      captures:\n        1: constant.other orgmode.fence\n      embed: scope:text.orgmode\n      escape: '(\\s*\\#\\+(END_EXAMPLE|end_example)\\s*)'\n      embed_scope: markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence\n\n    - match: '{{beginsrc}}((python)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.python\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(python))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.python\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((cpp)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.c++\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(cpp))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.c++\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((C)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.c\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(C))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.c\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((perl)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.perl\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(perl))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.perl\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((ini)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.ini\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(ini))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.ini\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((bash|sh)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.shell.bash\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(bash|sh))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.shell.bash\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((lua)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.lua\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(lua))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.lua\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((javascript|js)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.js\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(javascript|js))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.js\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((json)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.json\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(json))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.json\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((java)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.java\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(java))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.java\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((php)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.php\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(php))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.php\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((xml)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:text.xml\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(xml))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:text.xml\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((csharp|cs)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.cs\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(csharp|cs))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.cs\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((powershell)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.powershell\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(powershell))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.powershell\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((plantuml)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.wsd\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(plantuml))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.wsd\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((ditaa)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.ditaa\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(ditaa))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.ditaa\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((graphviz)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.dot\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(graphviz))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.dot\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((lisp)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.lisp\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(lisp))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.lisp\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((emacs-lisp)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.lisp\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(emacs-lisp))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.lisp\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((yaml)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.yaml\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(yaml))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.yaml\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((rust)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.rust\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(rust))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.rust\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((sql)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.sql\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(sql))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.sql\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((r(\\s|$))\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.r\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(r(\\s|$)))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.r\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((html)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:text.html.basic\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(html))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:text.html.basic\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((go)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.go\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(go))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.go\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((ledger)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.ledger\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(ledger))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.ledger\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((beancount)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.beancount\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(beancount))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.beancount\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((make)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.makefile\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(make))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.makefile\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((makefile)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.makefile\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(makefile))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.makefile\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((typescript|ts)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.ts\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(typescript|ts))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.ts\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((clojure)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.clojure\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(clojure))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.clojure\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((bat|cmd)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.dosbatch\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(bat|cmd))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.dosbatch\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((org)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:text.orgmode\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(org))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:text.orgmode\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((pascal)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.pascal\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(pascal))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.pascal\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((actionscript)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.actionscript.2\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(actionscript))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.actionscript.2\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((applescript)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.applescript\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(applescript))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.applescript\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((dtd)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.xml.dtd\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(dtd))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.xml.dtd\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((haskell)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.haskell\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(haskell))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.haskell\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}(((markdown|md)(\\s|$))\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:text.html.markdown\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_((markdown|md)(\\s|$)))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:text.html.markdown\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((groovy)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.groovy\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(groovy))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.groovy\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((regexp)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.regexp\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(regexp))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.regexp\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((ruby)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.ruby\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(ruby))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.ruby\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((restructuredtext)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:text.restructuredtext\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(restructuredtext))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:text.restructuredtext\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((xsl)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:text.xml.xsl\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(xsl))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:text.xml.xsl\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((scala)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.scala\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(scala))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.scala\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((hex)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.hex\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(hex))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.hex\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((erlang)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.erlang\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(erlang))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.erlang\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((diff)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.diff\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(diff))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.diff\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((d(\\s|$))\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.d(\\s|$)\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(d(\\s|$)))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.d(\\s|$)\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((css)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.css\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(css))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.css\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((cmake)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.cmake\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(cmake))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.cmake\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((asp)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.asp\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(asp))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.asp\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((gnuplot)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.gnuplot\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(gnuplot))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.gnuplot\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((mermaid)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.mermaid\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(mermaid))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.mermaid\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((painless)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.java\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(painless))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.java\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n    - match: '{{beginsrc}}((awk)\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:source.awk\n      escape: '{{endsrc}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_(awk))(\\[[^\\]]+\\])?(\\{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:source.awk\n      scope: orgmode.sourceblock.inline\n      escape: '(\\})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\n      # #+SOMETHING:\n      # But not a dynamic block\n      # Use negative look ahead to avoid matching begin and end dynamic blocks\n    - match: '^\\s*(\\#\\+(?!(TBLFM|tblfm|BEGIN|END|begin|end))([a-zA-Z][a-zA-Z0-9_-]+)(\\s*\\[[a-zA-Z0-9_-]+\\]\\s*)?\\:)\\s*(.*)'\n      scope: orgmode.controltag\n      captures:\n        1: keyword orgmode.controltag.tag\n        5: comment orgmode.controltag.text\n      # #+TBLFM:\n      # But not a dynamic block\n      # Use negative look ahead to avoid matching begin and end dynamic blocks\n    - match: '^\\s*(\\#\\+(TBLFM|tblfm))\\:\\s*(.*)'\n      scope: orgmode.table orgmode.controltag orgmode.tblfm\n      captures:\n        1: keyword orgmode.controltag.tag\n        3: comment orgmode.controltag.text\n\n    # #+BEGIN: NAME dynamic block support\n    - match: '((\\s*\\#\\+BEGIN:|\\#\\+begin:)\\s+([a-zA-Z0-9]+)\\s+(.*)?\\s*)'\n      captures:\n        1: constant.other orgmode.fence.dynamicblock\n        2: orgmode.fence.dynamicblock.begin\n        3: keyword orgmode.fence.dynamicblock.name\n        4: variable.parameter orgmode.fence.dynamicblock.params\n      embed: scope:text.orgmode\n      escape: '(^\\s*\\#\\+END:\\s*|\\#\\+end:\\s*)'\n      embed_scope: markup.raw.block orgmode.raw.block.dynamicblock\n      escape_captures:\n        1: constant.other orgmode.fence.dynamicblock.end\n  code:\n    - meta_scope: text\n    - match: \\s*\\[/code\\]\n      pop: true\n\n  pythonstack:\n    - meta_scope: orgmode.python.traceback\n    - match: \"^\\\\s*\\\\w+: .+$\"\n      pop: true\n\n"
  },
  {
    "path": "OrgExtended.sublime-syntax-template",
    "content": "%YAML 1.2\n---\n# See http://www.sublimetext.com/docs/3/syntax.html\nfile_extensions:\n  - org\n  - org_archive\n# Generic parent scope of the file\nscope: text.orgmode\nversion: 2\n\nvariables:\n  datetime: \"<\\\\d{4}-\\\\d{2}-\\\\d{2}(?:\\\\s*\\\\w{3})?\\\\s*(\\\\d{2}\\\\:\\\\d{2}(-\\\\d{2}\\\\:\\\\d{2})?)?\\\\s*([+]*\\\\d[wdmy])?>\"\n  unscheddatetime: \"\\\\[\\\\d{4}-\\\\d{2}-\\\\d{2}(?:\\\\s*\\\\w{3})?\\\\s*(\\\\d{2}\\\\:\\\\d{2})?\\\\s*([+]*\\\\d[wdmy])?\\\\]\"\n  tags: \"(^|):[\\\\w\\\\d:]+:\"\n  priority: '\\s*\\[((\\#A)|(\\#B)|(\\#C)|(\\#D)|(\\#E)|(\\#[a-zA-Z0-9]+))\\]\\s+'\n  state: (TODO)|(BLOCKED)|(WAITING)|(CANCELLED)|(DONE)|(MEETING)|(PHONE)|(NOTE)|(FLAG)|(CLEANUP)|(IN-PROGRESS)|(DOING)|(NEXT)|(REASSIGNED)|(FIXED)\n  beginmrk: BEGIN_SRC|begin_src\n  endmrk:   END_SRC|end_src\n  beginsrc: '(\\s*\\#\\+({{beginmrk}})\\s+)'\n  endsrc: '(\\s*\\#\\+({{endmrk}})\\s*)'\ncontexts:\n  # The prototype context is prepended to all contexts but those setting\n  # meta_include_prototype: false.\n  #prototype:\n  #- include: comments\n  header-matches:\n    - match: $\n      pop: true\n    - match: ({{state}}\\s+)?({{priority}})?[^\\[\\]:\\n]*(\\[\\d*[/%]\\d*\\])?({{tags}})?\n      captures:\n        2: variable.parameter orgmode.state.todo\n        3: variable.parameter orgmode.state.blocked\n        4: variable.parameter orgmode.state.waiting\n        5: variable.parameter orgmode.state.cancelled\n        6: variable.parameter orgmode.state.done\n        7: variable.parameter orgmode.state.meeting\n        8: variable.parameter orgmode.state.phone\n        9: variable.parameter orgmode.state.note\n        10: variable.parameter orgmode.state.flag\n        11: variable.parameter orgmode.state.cleanup\n        12: variable.parameter orgmode.state.inprogress\n        13: variable.parameter orgmode.state.doing\n        14: variable.parameter orgmode.state.next\n        15: variable.parameter orgmode.state.reassigned\n        16: variable.parameter orgmode.state.fixed\n        17: string.quoted orgmode.priority\n        18: string.quoted orgmode.priority.value\n        19: string.quoted orgmode.priority.value.a\n        20: string.quoted orgmode.priority.value.b\n        21: string.quoted orgmode.priority.value.c\n        22: string.quoted orgmode.priority.value.d\n        23: string.quoted orgmode.priority.value.e\n        24: string.quoted orgmode.priority.value.general\n        25: string.quoted orgmode.checkbox.summary\n        26: entity.name.tag.orgmode orgmode.tags.header\n  main:\n    # The main context is the initial starting point of our syntax.\n    # Include other contexts from here (or specify them directly).\n    #- include: keywords\n    #- include: numbers\n    #- include: strings\n      # --- # Todo investigate what this actually is?\n    - match: ^\\s*\\-\\-\\- [^\\n]*\n      scope: comment orgmode.page\n      # ~~~~~ # Todo investigate what this is?\n    - match: ^\\s*[~]+ [^\\n]*\n      scope: comment orgmode.break\n\n\n      # Generic headline, TODO: Make multiple of these so we can color them\n      # and sub captures so we can hide the extraneous stars\n      # embed_scope: entity.name.function.orgmode orgmode.headline\n    - match: ^\\s*[*]\\s+\n      push:\n        - meta_scope: entity.name.class.orgmode orgmode.headline\n        - include: header-matches\n    - match: ^\\s*([*])[*]\\s+\n      captures:\n        1: comment  orgmode.preamble\n      push:\n        - meta_scope: entity.name.function.orgmode orgmode.headline2\n        - include: header-matches\n    - match: ^\\s*([*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      push:\n        - meta_scope: entity.other.attribute-name.orgmode orgmode.headline3\n        - include: header-matches\n    - match: ^\\s*([*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      push:\n        - meta_scope: entity.name.section.orgmode orgmode.headline4\n        - include: header-matches\n    - match: ^\\s*([*][*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      push:\n        - meta_scope: entity.name.type.orgmode orgmode.headline5\n        - include: header-matches\n    - match: ^\\s*([*][*][*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      scope: orgmode.headline6\n      push:\n        - meta_scope: entity.name.filename orgmode.headline6\n        - include: header-matches\n    - match: ^\\s*([*][*][*][*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      scope: orgmode.headline7\n      push:\n        - meta_scope: entity.name.filename orgmode.headline7\n        - include: header-matches\n    - match: ^\\s*([*][*][*][*][*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      scope: orgmode.headline8\n      push:\n        - meta_scope: entity.name.filename orgmode.headline8\n        - include: header-matches\n    - match: ^\\s*([*][*][*][*][*][*][*][*])[*]\\s+\n      captures:\n        1: comment orgmode.preamble\n      scope: orgmode.headline9\n      push:\n        - meta_scope: entity.name.filename orgmode.headline9\n        - include: header-matches\n\n    - match: ^\\s*(\\|.+\\|)\n      captures:\n        1: markup.raw.block orgmode.table.block\n      scope: orgmode.table\n      # DEADLINE: <DATETIME>\n    - match: \"(DEADLINE:)\\\\s+({{datetime}})\"\n      captures:\n        1: keyword orgmode.statekeyword\n        2: markup.italic orgmode.datetime\n      scope: orgmode.deadline\n      # SCHEDULED: <DATETIME>\n    - match: \"(SCHEDULED:)\\\\s+({{datetime}})\"\n      captures:\n        1: keyword orgmode.statekeyword\n        2: markup.italic orgmode.datetime\n      scope: orgmode.scheduled\n      # CLOSED: [DATETIME]\n    - match: \"(CLOSED:)\\\\s+({{unscheddatetime}})\"\n      captures:\n        1: keyword orgmode.statekeyword\n        2: markup.italic orgmode.unscheddatetime\n      scope: orgmode.closed\n      # numbered list\n    - match: \"^\\\\s*([0-9]+[.)])\\\\s+(([^:]+\\\\s+)(::))?\"\n      captures:\n        1: constant.numeric\n        3: keyword orgmode.definition\n        4: punctuation orgmode.definition.marker\n      scope: orgmode.numberedlist\n      # bullet list\n    - match: \"^\\\\s*(\\\\-) (([^:]+\\\\s+)(::))?\"\n      captures:\n        1: constant.character\n        3: keyword orgmode.definition\n        4: punctuation orgmode.definition.marker\n      scope: orgmode.tack.minus\n      # bullet list\n    - match: \"^\\\\s*(\\\\+) (([^:]+\\\\s+)(::))?\"\n      captures:\n        1: constant.character\n        3: keyword orgmode.definition\n        4: punctuation orgmode.definition.marker\n      scope: orgmode.tack.plus\n      # To follow up: -> and =>\n    - match: \"^\\\\s*(\\\\-\\\\>|\\\\=\\\\>) \"\n      scope: orgmode.follow_up\n      # [-] Checkbox\n    - match: (\\[[ ]\\])\\s?\n      scope: string orgmode.checkbox\n    - match: (\\[([xX])\\])\\s?\n      scope: orgmode.checkbox.checked\n      captures:\n        1: string\n        2: keyword orgmode.checkbox.checked \n    - match: (\\[([\\-])\\])\\s?\n      scope: orgmode.checkbox.blocked\n      captures:\n        1: string\n        2: constant.other orgmode.checkbox.blocked\n      # [#/#] Checkbox summary\n    - match: (\\[\\d*[/%]\\d*\\])\n      scope: string orgmode.checkbox.summary\n      # [[link]]\n    - match: \\[(\\[([^\\]]+)\\])\\]\n      captures:\n        1: orgmode.link.textblock\n        2: comment orgmode.link.text.href\n      scope: markup.underline.link orgmode.link\n      # [[link][name]]\n    - match: \\[(\\[([^\\]]+)\\])(\\[([^\\]]+)\\])\\]\n      captures:\n        1: orgmode.link.hrefblock\n        2: comment orgmode.link.href\n        3: orgmode.link.textblock\n        4: markup.bold orgmode.link.text\n      scope: markup.underline.link orgmode.link\n    - match: http[s]?://[^ \\t]+\n      scope: orgmode.link.href\n    - match: \\b([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})\\b\n      scope: orgmode.email\n      # {{{results(=hello=)}}}\n    - match: '\\{\\{\\{results\\(([^)]+)\\)\\}\\}\\}'\n      scope: comment orgmode.results.inline\n      captures:\n        1: keyword orgmode.results.value\n      # {numerical_value}\n    - match: \\{(\\d+)\\}\n      scope: orgmode.link.internal.number\n      # {{headline}}\n    - match: \\{\\{(.+?)\\}\\}\n      scope: orgmode.link.internal.headline\n      # :TAG:\n    - match: \"(^|\\\\s):[\\\\w\\\\d:]+:\"\n      scope: entity.name.tag.orgmode orgmode.tags\n      # [code] block, not sure what these are.\n    - match: \\[code\\]\\s*\n      push:  code\n    - match: ^\\s*Traceback \\(most recent call last\\):\\s*$\n      push: pythonstack\n\n    - match: (^|\\s)\\*[^*]+\\*(^|\\s)\n      scope: markup.bold orgmode.bold\n\n    - match: (^|\\s)(/[^/]+/)($|\\s)\n      scope: markup.italic orgmode.italics\n\n    - match: \\b(_[^_]+_)\\b\n      scope: markup.underline orgmode.underline\n\n    - match: (^|\\s)\\+[^\\+]+\\+(^|\\s)\n      scope: markup.underline orgmode.strikethrough\n\n    - match: (^|\\s)~[^~]+~(^|\\s)\n      scope: orgmode.code\n\n    - match: (^|\\s)=[^=]+=(^|\\s)\n      scope: orgmode.verbatim\n\n\n    - match: '(<<)([^>]+)(>>)'\n      captures:\n        1: orgmode.target.bracket\n        2: comment orgmode.link.text.href orgmode.target\n        3: orgmode.target.bracket\n      scope: markup.underline.link\n\n    - match: '(\\s*\\#\\+(BEGIN_CENTER|begin_center)\\s*)'\n      captures:\n        1: orgmode.fence\n      push:\n        - meta_scope: constant.other orgmode.raw.block\n        - meta_content_scope: markup.raw.block orgmode.raw.block\n        - match: '(\\s*\\#\\+(END_CENTER|end_center)\\s*)'\n          captures:\n            1: orgmode.fence\n          pop: true\n    - match: '(\\s*\\#\\+(BEGIN_VERSE|begin_verse)\\s*)'\n      captures:\n        1: orgmode.fence\n      push:\n        - meta_scope: constant.other orgmode.raw.block\n        - meta_content_scope: markup.raw.block orgmode.raw.block\n        - match: '(\\s*\\#\\+(END_VERSE|end_verse)\\s*)'\n          captures:\n            1: orgmode.fence\n          pop: true\n    - match: '(\\s*\\#\\+(BEGIN_QUOTE|begin_quote)\\s*)'\n      captures:\n        1: orgmode.fence\n      push:\n        - meta_scope: constant.other orgmode.raw.block\n        - meta_content_scope: markup.raw.block orgmode.raw.block\n        - match: '(\\s*\\#\\+(END_QUOTE|end_quote)\\s*)'\n          captures:\n            1: orgmode.fence\n          pop: true\n    - match: '(\\s*\\#\\+(BEGIN_NOTES|begin_notes)\\s*)'\n      captures:\n        1: constant.other orgmode.fence\n      embed: scope:text.orgmode\n      escape: '(\\s*\\#\\+(END_NOTES|end_notes)\\s*)'\n      embed_scope: markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence\n\n    - match: '(\\s*\\#\\+(BEGIN_EXAMPLE|begin_example)\\s*)'\n      captures:\n        1: constant.other orgmode.fence\n      embed: scope:text.orgmode\n      escape: '(\\s*\\#\\+(END_EXAMPLE|end_example)\\s*)'\n      embed_scope: markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence\n    {{INSERT_LANGUAGES_HERE}}\n      # #+SOMETHING:\n      # But not a dynamic block\n      # Use negative look ahead to avoid matching begin and end dynamic blocks\n    - match: '^\\s*(\\#\\+(?!(TBLFM|tblfm|BEGIN|END|begin|end))([a-zA-Z][a-zA-Z0-9_-]+)(\\s*\\[[a-zA-Z0-9_-]+\\]\\s*)?\\:)\\s*(.*)'\n      scope: orgmode.controltag\n      captures:\n        1: keyword orgmode.controltag.tag\n        5: comment orgmode.controltag.text\n      # #+TBLFM:\n      # But not a dynamic block\n      # Use negative look ahead to avoid matching begin and end dynamic blocks\n    - match: '^\\s*(\\#\\+(TBLFM|tblfm))\\:\\s*(.*)'\n      scope: orgmode.table orgmode.controltag orgmode.tblfm\n      captures:\n        1: keyword orgmode.controltag.tag\n        3: comment orgmode.controltag.text\n\n    # #+BEGIN: NAME dynamic block support\n    - match: '((\\s*\\#\\+BEGIN:|\\#\\+begin:)\\s+([a-zA-Z0-9]+)\\s+(.*)?\\s*)'\n      captures:\n        1: constant.other orgmode.fence.dynamicblock\n        2: orgmode.fence.dynamicblock.begin\n        3: keyword orgmode.fence.dynamicblock.name\n        4: variable.parameter orgmode.fence.dynamicblock.params\n      embed: scope:text.orgmode\n      escape: '(^\\s*\\#\\+END:\\s*|\\#\\+end:\\s*)'\n      embed_scope: markup.raw.block orgmode.raw.block.dynamicblock\n      escape_captures:\n        1: constant.other orgmode.fence.dynamicblock.end\n  code:\n    - meta_scope: text\n    - match: \\s*\\[/code\\]\n      pop: true\n\n  pythonstack:\n    - meta_scope: orgmode.python.traceback\n    - match: \"^\\\\s*\\\\w+: .+$\"\n      pop: true\n\n"
  },
  {
    "path": "README.md",
    "content": "# Org Extended\n\n  ![Org](https://orgmode.org/resources/img/org-mode-unicorn.svg)\n\n  OrgMode is a lifestyle. While I like sublime, living without Org Mode has been something \n  that has driven me back to Emacs over and over again. I finally decided that I might take a stab\n  at building a usable orgmode plugin for sublime.\n\n  ![Start](https://raw.githubusercontent.com/ihdavids/orgextended_docs/master/images/orgstart.gif)\n\n  NOTE: To get setup, please jump down the Setup link below.\n  \n  When people show off org, they often just show off some folding\n  and the ability to tab cycle a headings tree. This often leads people\n  to compare org with Markdown. Org IS a markup and document interchange\n  format like markdown, but it is also much more.\n\n  ![Folding](https://raw.githubusercontent.com/ihdavids/orgextended_docs/master/images/orgstartfolding.gif)\n\n  Fundamentally org mode is *2* very /different/ things and fairly hard to describe:\n\n  1. Org Files - A text based document markup language similar to markdown.\n  2. Org Mode  - A wide variety of tools for operating on and working with collections of these files.\n  3. Org Extensions - I know I said 2 but Org Mode has a wide variety of tools built around the mode and api's extending it in many creative ways. Although not org mode itself most people refer to these tools when they think of org mode.\n\n  Org Mode can and has been used for a large variety of things:\n\n  + A Personal Wiki\n  + Professional Notes\n  + Time Tracking and Billing\n  + Documentation\n  + Research Papers - Dynamic Documents\n  + Literate Programming\n  + Personal Agenda\n  + Project Planning\n  + As a blogging tool\n  + Website content management \n  + A means of planning and managing a budget with ledger mode\n  + As a process and memory aid for IT professionals\n  + As a self documenting configuration file for emacs itself (and other things).\n  + Many many more things\n\n  I use org to manage my agenda:\n\n  ![Agenda](https://raw.githubusercontent.com/ihdavids/orgextended_docs/master/images/agenda_day.gif)\n\n  Or to help me manipulate tables of data:\n\n  ![Tables](https://raw.githubusercontent.com/ihdavids/orgextended_docs/master/images/table_hacking.gif) \n\n  Or build document diagrams:\n\n  ![Diagrams](https://raw.githubusercontent.com/ihdavids/orgextended_docs/master/images/creating_diagrams.gif) \n\n\n  Or build presentations with revealjs, html or pdfs with latex:\n\n  ![Presentations](https://raw.githubusercontent.com/ihdavids/orgextended_docs/master/images/revealjs.gif) \n\n\n  What makes Org Mode so versatile is the deceptive simplicity of the format\n  the flexibility of the simple markup and the depth of the tools and API's provided around that format.\n\n  At times I have wondered why I shouldn't just use markdown? It is a much more widely popular markup system.\n  There is no reason markdown could not be extended to become exactly what Org Mode\n  has become, but markdown is not quite as flexible with its meta data and has not had the same degree of *cult*\n  following so has yet to evolve into something like Org.\n\n  I hope to go beyond simply the file format and bring some of the actual Mode to Sublime.\n  I simply cannot build the entire thing, but I hope we can build something unique and amazing\n  in sublime, in its own right.\n\n# This Plugin\n\n  - [Starter Tutorial](https://github.com/ihdavids/orgextended_docs/blob/master/learning_todos.org) - Learning about todos\n  - [Basic Structure](https://github.com/ihdavids/orgextended_docs/blob/master/orgextended.org) - Basic file structure\n  - [Setup](https://github.com/ihdavids/orgextended_docs/blob/master/setup.org) - Sublime Setup\n  - [Editing](https://github.com/ihdavids/orgextended_docs/blob/master/editing.org) - Editing your org file\n  - [Lists](https://github.com/ihdavids/orgextended_docs/blob/master/lists.org) - Supported lists in an org file\n  - [Folding](https://github.com/ihdavids/orgextended_docs/blob/master/folding.org) - Jumping from the full view to a folded representation.\n  - [Links](https://github.com/ihdavids/orgextended_docs/blob/master/links.org) - Jumping within and without.\n  - [Navigation](https://github.com/ihdavids/orgextended_docs/blob/master/navigation.org) - Powerful ways of navigating your org files.\n  - [Capture, Refile, Archive](https://github.com/ihdavids/orgextended_docs/blob/master/capture.org) - Save ideas fast.\n  - [Exporting](https://github.com/ihdavids/orgextended_docs/blob/master/exporting.org) - Converting from org to other things.\n  - [Properties and Drawers](https://github.com/ihdavids/orgextended_docs/blob/master/properties.org) - Metadata within a heading\n  - [Scheduling](https://github.com/ihdavids/orgextended_docs/blob/master/dates.org) - Dates and times\n  - [Time Tracking](https://github.com/ihdavids/orgextended_docs/blob/master/clocking.org) - Clocking and clock reports\n  - [Dynamic Blocks](https://github.com/ihdavids/orgextended_docs/blob/master/dynamicblocks.org) - Run arbitrary code\n  - [Living Documents](https://github.com/ihdavids/orgextended_docs/blob/master/babel.org) - Babel - Literate Programming, Reproducible Research and Living Documents\n  - [Tables](https://github.com/ihdavids/orgextended_docs/blob/master/tables.org) - Spreadsheets in your documents.\n  - [Diagrams](https://github.com/ihdavids/orgextended_docs/blob/master/diagrams.org) - Adding diagrams to your documents.\n  - [Agenda](https://github.com/ihdavids/orgextended_docs/blob/master/agenda.org) - Keeping track of your day.\n  - [Key Bindings](https://github.com/ihdavids/orgextended_docs/blob/master/keybindings.org) - A quick reference of some of the default keybindings.\n  \n  The full documentation for this plugin can be found at: [Docs](https://github.com/ihdavids/orgextended_docs)\n\n# Thank You\n  I have shamelessly built this plugin on the backs of some excellent plugins and libraries.\n\n  - The original orgmode plugin - This work was exceptional, OrgExtended is a tribute to that work and consumes some of it.\n  - sublime_ZK - The inline image preview is entirely due to the Markdown ZK plugin. \n    [ZK](https://github.com/renerocksai/sublime_zk) Thank you renerocksai for pointing out that phantoms can be used for image preview.\n  - Table Edit - For now this excellent plugin is a dependency and the basis by which we offer Org style table editing.\n  \tIn a future version we may look to consume the package and own table editing to facilitate expressions and some of the more\n  \tadvanced org table tools, but for now, thank you for making this excellent plugin!\n  - pymitter - a great little event library for python.\n  - highlightjs - a wonderful highlighting library for html.\n  - pandoc - a great command line tool for converting formats.\n\n\n# References\n  To help get you started on your Org journey\n  Here are some useful external links:\n\n- [Org Mode Site](https://orgmode.org) - Org\n- [The Org Manual](https://orgmode.org/manual/) - The official source of truth for all things orgmode\n- [Org Mode 4 Beginners](https://orgmode.org/worg/org-tutorials/org4beginners.html) - An introduction\n- [David O'Tools Introduction](https://orgmode.org/worg/org-tutorials/orgtutorial_dto.html) - Yet another intro\n- [The Many Uses of Org Mode](https://thoughtbot.com/blog/the-many-uses-of-org-mode)\n- [More Uses](https://kitchingroup.cheme.cmu.edu/blog/2014/08/08/What-we-are-using-org-mode-for/)\n- [Your Life In Plain Text](http://doc.norang.ca/org-mode.html) - A wonderful reference on one mans journey to use orgmode to improve his life\n"
  },
  {
    "path": "Symbol List.tmPreferences",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>name</key>\n\t<string>Symbol List</string>\n\t<key>scope</key>\n\t<string>text.orgmode orgmode.page, text.orgmode orgmode.break, text.orgmode orgmode.headline, text.orgmode orgmode.headline2, text.orgmode orgmode.headline3, text.orgmode orgmode.headline4, text.orgmode orgmode.headline5, text.orgmode orgmode.headline6</string>\n\t<key>settings</key>\n\t<dict>\n\t\t<key>showInSymbolList</key>\n\t\t<integer>1</integer>\n\t\t<key>symbolTransformation</key>\n\t\t<string>\n\t\t\t s/\\s*\\**\\s*\\z//g;       #Search for *\n\t\t\ts/(?&lt;=\\*)\\*/  /g;     #replace * with two spaces, except first\n\t\t\ts/^\\*( *)\\s+(.*)/$1$2/;  #replace first found with a space\n\t\t</string>\n\t</dict>\n\t<key>uuid</key>\n\t<string>a5b8a9bb-75fa-41bf-a15c-3832eb894331</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "asettings.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport os\nimport logging\nimport shutil\nimport OrgExtended.orgutil.template as temp\n\n\nlog = logging.getLogger(__name__)\n\n\n\ndefaultTodoStates = [\"TODO\", \"NEXT\", \"BLOCKED\",\"WAITING\",\"FLAG\", \"CLEANUP\", \"IN-PROGRESS\", \"DOING\", \"|\", \"REASSIGNED\", \"CANCELLED\", \"DONE\",\"MEETING\",\"PHONE\",\"NOTE\", \"FIXED\"]\nweekdayNames = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"]\n\n\nclass ASettings:\n\tdef __init__(self, settingsName):\n\t\tself.settings = sublime.load_settings(settingsName + '.sublime-settings')\n\n\tdef Get(self, name, defaultVal):\n\t\tval = self.settings.get(name)\n\t\tif(val == None):\n\t\t\tval = defaultVal\n\t\treturn val\n\n\nconfigFilename    = \"OrgExtended\"\n\ndef setup_user_settings():\n\t# This is old and I should remove it!\n\t# We don't need this mechanism anymore!\n\tfilename = configFilename + \".sublime-settings\"\n\tuser_settings_path = os.path.join(\n\t\tsublime.packages_path(),\n\t\t\"User\",\n\t\tfilename)\n\n\tif not os.path.exists(user_settings_path):\n\t\tdefault_settings_path = os.path.join(\n\t\t\tsublime.packages_path(),\n\t\t\t\"OrgExtended\",\n\t\t\tfilename)\n\t\tif os.path.exists(default_settings_path):\n\t\t\tshutil.copyfile(default_settings_path, user_settings_path)\n\ndef setup_mousemap():\n\tfilename = \"Default.sublime-mousemap\"\n\tuser_settings_path = os.path.join(\n\t\tsublime.packages_path(),\n\t\t\"User\",\n\t\tfilename)\n\tmousemap = \"\"\"\n[\n    {\n        \"button\": \"button1\", \n        \"count\": 1, \n        \"modifiers\": [\"alt\"],\n        \"press_command\": \"drag_select\",\n        // In the future we may vector this to a more generic handler\n        \"command\": \"org_mouse_handler\",\n    }\n]\n\t\"\"\"\t\n\tif not os.path.exists(user_settings_path):\n\t\twith open(user_settings_path,\"w\") as o:\n\t\t\to.write(mousemap)\n\t\t\to.write(\"\\n\")\n\nclass OrgSetupMouseMapCommand(sublime_plugin.TextCommand):\n    def run(self, edit, event=None):\n    \tsetup_mousemap()\n\n\n# Singleton access\n_sets = None\n\ndef Load():\n\tglobal configFilename\n\tglobal _sets\n\t_sets          = ASettings(configFilename)\n\n\n\ndef Get(name, defaultValue, formatDictionary = None):\n\tglobal _sets\n\tif(_sets == None):\n\t\tlog.warning(\"SETTINGS IS NULL? IS THIS BEING CALLED BEFORE PLUGIN START?\")\n\t\tLoad()\n\trv = _sets.Get(name, defaultValue)\n\tformatDict = {\n\t\t\"date\":     str(datetime.date.today()),\n\t\t\"time\":     datetime.datetime.now().strftime(\"%H:%M:%S\"),\n\t\t\"datetime\": str(datetime.datetime.now().strftime(\"%Y-%m-%d %a %H:%M\")),\n\t}\n\n\tif(formatDictionary != None):\n\t\tformatDict.update(formatDictionary)\n\n\tif(str == type(rv)):\n\t\tformatter = temp.TemplateFormatter(Get)\n\t\trv  = formatter.format(rv, **formatDict)\n\tif(list == type(rv)):\n\t\tformatter = temp.TemplateFormatter(Get)\n\t\trv = [ (formatter.format(r, **formatDict) if str == type(r) else r) for r in rv ]\n\treturn rv\n\ndef RepresentsInt(s):\n    try: \n        int(s)\n        return True\n    except ValueError:\n        return False\t\n\ndef GetInt(name, defaultValue):\n\tv = Get(name, defaultValue)\n\ttry:\n\t\ti = int(v)\n\t\treturn i\n\texcept:\n\t\treturn defaultValue\n\n\ndef GetWeekdayIndexByName(name):\n    try:\n        weekdayIndex = weekdayNames.index(name)\n    except:\n        weekdayIndex = 6\n    return weekdayIndex\n\n# Will return a date or an index as an integer where 0 means Sunday\n# and so on in the week.\ndef GetDateAsIndex(name, defaultValue):\n\tglobal daysOfWeek\n\tval = Get(name, defaultValue)\n\tif(RepresentsInt(val)):\n\t\treturn int(val) % 7\n\tval = val.lower()\n\tfor i in range(0,len(daysOfWeek)):\n\t\tif daysOfWeek[i] in val:\n\t\t\treturn i\n\treturn 0\n\n# ================================================================================\nclass OrgTestTemplateCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit, onDone=None):\n\t\tv = temp.ExpandTemplate(self.view, \"DATE: {date} TIME: {time} DT: {datetime} FILE: {file.lower:call}\")\n\t\tprint(str(v))\n\t\tformatDict = { \"aaa\":     str(datetime.date.today()),}\n\t\tformatter = temp.TemplateFormatter(Get)\n\t\trv  = formatter.format(\"{aaa} {archive}\", **formatDict)\n\t\tprint(str(rv))\n\n"
  },
  {
    "path": "balloontip.ps1",
    "content": "Add-Type -AssemblyName System.Windows.Forms\n$global:balloon = New-Object System.Windows.Forms.NotifyIcon\n$path = (Get-Process -id $pid).Path\n#$path = \"C:\\Program Files\\Sublime Text 3\\sublime_text.exe\"\n$balloon.Icon            = [System.Drawing.Icon]::ExtractAssociatedIcon($path)\n$balloon.BalloonTipIcon  = [System.Windows.Forms.ToolTipIcon]::Warning\n$balloon.BalloonTipText  = $Args[0]\n$balloon.BalloonTipTitle = \"REMINDER: @ \" + $Args[1]\n$balloon.Visible         = $true\n$balloon.ShowBalloonTip(5000)"
  },
  {
    "path": "beancount.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\n\n\nclass BeancountNewTransactionCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        ai = sublime.active_window().active_view().settings().get('auto_indent')\n        self.view.settings().set('auto_indent',False)\n        snipName = \"Packages/Beancount/snipets/transaction.sublime-snippet\"\n        # OTHER VARIABLES:\n        # TM_FULLNAME - Users full name\n        # TM_FILENAME - File name of the file being edited\n        # TM_CURRENT_WORD - Word under cursor when snippet was triggered\n        # TM_SELECTED_TEXT - Selected text when snippet was triggered\n        # TM_CURRENT_LINE - Line of snippet when snippet was triggered\n        # For NeoVintageous Users FORCE insert mode during snippet insertion for ease of use.\n        self.view.run_command('_enter_insert_mode', {\"count\": 1, \"mode\": \"mode_internal_normal\"})\n        self.view.run_command(\"insert_snippet\", \n            { \"name\" : snipName\n            , \"MONTH\":         datetime.datetime.now().strftime(\"%m\")\n            , \"YEAR\":          datetime.datetime.now().strftime(\"%Y\")\n            , \"DAY\":           datetime.datetime.now().strftime(\"%d\")\n            , \"DATE\":          str(datetime.date.today())\n            , \"TIME\":          datetime.datetime.now().strftime(\"%H:%M:%S\")\n            , \"CLIPBOARD\":     sublime.get_clipboard()\n            , \"SELECTION\":     self.view.substr(self.view.sel()[0])\n            , \"FILENAME\":      self.view.file_name()\n            , \"DEFAULT_CURRENCY\": \"CAD\"\n            })\n        sublime.active_window().active_view().settings().set('auto_indent',ai)\n\n\nclass BeancountNewFileCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        win = sublime.active_window()\n        win.run_command('new_file')\n        panel = win.active_view()\n        panel.set_syntax_file(\"Packages/OrgExtended/OrgBeancount.sublime-syntax\")\n        \n\n"
  },
  {
    "path": "dependencies.json",
    "content": "{\n\t\"*\": {\n\t\t\"*\": [\n\t\t\t\"pathlib\",\n\t\t\t\"pyyaml\",\n\t\t\t\"dateutil\",\n\t\t\t\"requests\",\n\t\t\t\"regex\",\n\t\t\t\"websocket\",\n\t\t\t\"six\"\n\t\t]\n\t}\n}"
  },
  {
    "path": "htmlstyles/blocky.css",
    "content": "/*\n * I add this to html files generated with pandoc.\n */\nhtml {\n  font-size: 100%;\n  overflow-y: scroll;\n  -webkit-text-size-adjust: 100%;\n  -ms-text-size-adjust: 100%;\n}\n\nbody {\n  color: #444;\n  background-color: #ddd;\n  font-size: 12px;\n  line-height: 1.7;\n  padding: 1em;\n  margin: auto;\n  max-width: 42em;\n  /*background: #fefefe;*/\n  font-family: 'Montserrat', sans-serif;\n}\n\na {\n  /*#0645cd;*/\n  color:  #1e74ac;\n  text-decoration: underline;\n  text-decoration-style: dotted;\n  font-weight: bold;\n}\n\na:visited {\n  color: #0b0090;\n}\n\na:hover {\n  color: #06e;\n}\n\na:active {\n  color: #faa700;\n}\n\na:focus {\n  outline: thin dotted;\n}\n\n*::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\n*::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\na::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\na::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\np {\n  margin: 1em 0;\n}\n\nimg {\n  max-width: 100%;\n}\n\nh1, h2, h3, h4, h5, h6 {\n  color: #1e747c;\n  line-height: 125%;\n  margin-top: 2em;\n  font-weight: normal;\n  font-family: 'Bebas Neue', cursive;\n  border-left-color: #1e747c;\n  border-left-style: solid;\n  border-left-width: 4px;\n  padding-left: 12px;\n}\n\nh4, h5, h6 {\n  color:aaa;\n  font-weight: bold;\n}\n\nh1 {\n  font-size: 2.5em;\n}\n\nh2 {\n  font-size: 2em;\n}\n\nh3 {\n  font-size: 1.5em;\n}\n\nh4 {\n  font-size: 1.2em;\n}\n\nh5 {\n  font-size: 1em;\n}\n\nh6 {\n  font-size: 0.9em;\n}\n\nblockquote {\n  color: #765037;\n  margin: 0;\n  padding-left: 2em;\n  border-left: 0.3em #474356 solid;\n}\n\nhr {\n  display: block;\n  height: 2px;\n  border: 0;\n  border-top: 1px solid #aaa;\n  border-bottom: 1px solid #eee;\n  margin: 1em 0;\n  padding: 0;\n}\n\npre, code, kbd, samp {\n  color: #66402f;\n  font-family: monospace, monospace;\n  _font-family: 'courier new', monospace;\n  font-size: 0.98em;\n  background: #ccc;\n}\n\npre {\n  white-space: pre;\n  white-space: pre-wrap;\n  word-wrap: break-word;\n}\n\nb, strong {\n  font-weight: bold;\n}\n\ndfn {\n  font-style: italic;\n}\n\nins {\n  background: #ff9;\n  color: #000;\n  text-decoration: none;\n}\n\nmark {\n  background: #ff0;\n  color: #000;\n  font-style: italic;\n  font-weight: bold;\n}\n\nsub, sup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nul, ol {\n  margin: 1em 0;\n  padding: 0 0 0 2em;\n}\n\nli p:last-child {\n  margin-bottom: 0;\n}\n\nul ul, ol ol {\n  margin: .3em 0;\n}\n\ndl {\n  margin-bottom: 1em;\n}\n\ndt {\n  font-weight: bold;\n  margin-bottom: .8em;\n}\n\ndd {\n  margin: 0 0 .8em 2em;\n}\n\ndd:last-child {\n  margin-bottom: 0;\n}\n\nimg {\n  border: 0;\n  -ms-interpolation-mode: bicubic;\n  /*vertical-align: middle;*/\n}\n\nfigure {\n  display: block;\n  text-align: center;\n  margin: 1em 0;\n}\n\nfigure img {\n  border: none;\n  margin: 0 auto;\n}\n\nfigcaption {\n  font-size: 0.8em;\n  font-style: italic;\n  margin: 0 0 .8em;\n}\n\ntable {\n  margin-bottom: 2em;\n  border-bottom: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n  border-top: 1px solid #ddd;\n  border-spacing: 0;\n  border-collapse: collapse;\n}\n\ntable th {\n  padding: .2em 1em;\n  background-color: #bbb;\n  border-top: 1px solid #ddd;\n  border-left: 1px solid #aaa;\n}\n\ntable td {\n  padding: .2em 1em;\n  border-top: 1px dotted #aaa;\n  border-left: 1px solid #ddd;\n  vertical-align: top;\n}\n\n.author {\n  font-size: 1.2em;\n  text-align: center;\n}\n\n@media only screen and (min-width: 480px) {\n  body {\n    font-size: 14px;\n  }\n}\n@media only screen and (min-width: 768px) {\n  body {\n    font-size: 16px;\n  }\n}\n@media print {\n  * {\n    background: transparent !important;\n    color: black !important;\n    filter: none !important;\n    -ms-filter: none !important;\n  }\n\n  body {\n    font-size: 12pt;\n    max-width: 100%;\n  }\n\n  a, a:visited {\n    text-decoration: underline;\n  }\n\n  hr {\n    height: 1px;\n    border: 0;\n    border-bottom: 1px solid black;\n  }\n\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n\n  .ir a:after, a[href^=\"javascript:\"]:after, a[href^=\"#\"]:after {\n    content: \"\";\n  }\n\n  pre, blockquote {\n    border: 1px solid #999;\n    padding-right: 1em;\n    page-break-inside: avoid;\n  }\n\n  tr, img {\n    page-break-inside: avoid;\n  }\n\n  img {\n    max-width: 100% !important;\n  }\n\n  @page :left {\n    margin: 15mm 20mm 15mm 10mm;\n}\n\n  @page :right {\n    margin: 15mm 10mm 15mm 20mm;\n}\n\n  p, h2, h3 {\n    orphans: 3;\n    widows: 3;\n  }\n\n  h2, h3 {\n    page-break-after: avoid;\n  }\n}"
  },
  {
    "path": "htmlstyles/blocky_heading.html",
    "content": ""
  },
  {
    "path": "htmlstyles/blocky_inheader.html",
    "content": "<link href=\"https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Montserrat&display=swap\" rel=\"stylesheet\">\n<!--font-family: 'Bebas Neue', cursive;-->\n<!--font-family: 'Montserrat', sans-serif;-->"
  },
  {
    "path": "htmlstyles/funky.css",
    "content": "/*\n * I add this to html files generated with pandoc.\n */\nhtml {\n  font-size: 100%;\n  overflow-y: scroll;\n  -webkit-text-size-adjust: 100%;\n  -ms-text-size-adjust: 100%;\n}\n\nbody {\n  color: #000;\n  background-color: #fff;\n  font-size: 12px;\n  line-height: 1.7;\n  padding: 1em;\n  margin: auto;\n  max-width: 42em;\n  /*background: #fefefe;*/\n  font-family: 'Oswald', sans-serif;\n}\n\na {\n  /*#0645cd;*/\n  color:  #1e74ac;\n  text-decoration: underline;\n  text-decoration-style: dotted;\n  font-weight: bold;\n}\n\na:visited {\n  color: #0b0090;\n}\n\na:hover {\n  color: #06e;\n}\n\na:active {\n  color: #faa700;\n}\n\na:focus {\n  outline: thin dotted;\n}\n\n*::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\n*::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\na::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\na::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\np {\n  margin: 1em 0;\n}\n\nimg {\n  max-width: 100%;\n}\n\nh1, h2, h3, h4, h5, h6, h7 {\n  color: #40320d;\n  line-height: 125%;\n  margin-top: 2em;\n  font-weight: normal;\n  font-family: 'Amatic SC', cursive;\n  padding-left: 12px;\n  text-shadow: 2px 2px 5px;\n}\n\nh4, h5, h6 {\n  color:aaa;\n  font-weight: bold;\n}\n\nh1 {\n  font-size: 2.5em;\n}\n\nh2 {\n  font-size: 2em;\n}\n\nh3 {\n  font-size: 1.5em;\n}\n\nh4 {\n  font-size: 1.2em;\n}\n\nh5 {\n  font-size: 1em;\n}\n\nh6 {\n  font-size: 0.9em;\n}\n\nblockquote {\n  color: #765037;\n  margin: 0;\n  padding-left: 2em;\n  border-left: 0.3em #474356 solid;\n}\n\nhr {\n  display: block;\n  height: 2px;\n  border: 0;\n  border-top: 1px solid #aaa;\n  border-bottom: 1px solid #eee;\n  margin: 1em 0;\n  padding: 0;\n}\n\npre, code, kbd, samp {\n  color: #66402f;\n  font-family: monospace, monospace;\n  _font-family: 'courier new', monospace;\n  font-size: 0.98em;\n  background: #ccc;\n  border-radius: 25px; \n  box-shadow: 5px 5px 10px #888888;\n}\n\npre {\n  white-space: pre;\n  white-space: pre-wrap;\n  word-wrap: break-word;\n}\n\nb, strong {\n  font-weight: bold;\n}\n\ndfn {\n  font-style: italic;\n}\n\nins {\n  background: #ff9;\n  color: #000;\n  text-decoration: none;\n}\n\nmark {\n  background: #ff0;\n  color: #000;\n  font-style: italic;\n  font-weight: bold;\n}\n\nsub, sup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nul, ol {\n  margin: 1em 0;\n  padding: 0 0 0 2em;\n}\n\nli p:last-child {\n  margin-bottom: 0;\n}\n\nul ul, ol ol {\n  margin: .3em 0;\n}\n\ndl {\n  margin-bottom: 1em;\n}\n\ndt {\n  font-weight: bold;\n  margin-bottom: .8em;\n}\n\ndd {\n  margin: 0 0 .8em 2em;\n}\n\ndd:last-child {\n  margin-bottom: 0;\n}\n\nimg {\n  border: 0;\n  -ms-interpolation-mode: bicubic;\n  /*vertical-align: middle;*/\n}\n\nfigure {\n  display: block;\n  text-align: center;\n  margin: 1em 0;\n}\n\nfigure img {\n  border: none;\n  margin: 0 auto;\n}\n\nfigcaption {\n  font-size: 0.8em;\n  font-style: italic;\n  margin: 0 0 .8em;\n}\n\ntable {\n  margin-bottom: 2em;\n  border-bottom: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n  border-top: 1px solid #ddd;\n  border-spacing: 0;\n  border-collapse: collapse;\n}\n\ntable th {\n  padding: .2em 1em;\n  background-color: #bbb;\n  border-top: 1px solid #ddd;\n  border-left: 1px solid #aaa;\n}\n\ntable td {\n  padding: .2em 1em;\n  border-top: 1px dotted #aaa;\n  border-left: 1px solid #ddd;\n  vertical-align: top;\n}\n\n.author {\n  font-size: 1.2em;\n  text-align: center;\n}\n\n\n.node-body {\n  padding: 0 18px;\n  max-height: 0;\n  overflow: hidden;\n  transition: max-height 0.2s ease-out;\n }\n  .active, .collapsible:hover {\n  background-color: #fff;\n  }\n  .collapsible:after {\n    font-size: 22px;\n    float: right;\n    margin-right: 20px;\n  }\n  .active:after {\n  font-size: 22px;\n  margin-right: 20px;\n  }\n\n@media only screen and (min-width: 480px) {\n  body {\n    font-size: 14px;\n  }\n}\n@media only screen and (min-width: 768px) {\n  body {\n    font-size: 16px;\n  }\n}\n@media print {\n  * {\n    background: transparent !important;\n    color: black !important;\n    filter: none !important;\n    -ms-filter: none !important;\n  }\n\n  body {\n    font-size: 12pt;\n    max-width: 100%;\n  }\n\n  a, a:visited {\n    text-decoration: underline;\n  }\n\n  hr {\n    height: 1px;\n    border: 0;\n    border-bottom: 1px solid black;\n  }\n\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n\n  .ir a:after, a[href^=\"javascript:\"]:after, a[href^=\"#\"]:after {\n    content: \"\";\n  }\n\n  pre, blockquote {\n    border: 1px solid #999;\n    padding-right: 1em;\n    page-break-inside: avoid;\n  }\n\n  tr, img {\n    page-break-inside: avoid;\n  }\n\n  img {\n    max-width: 100% !important;\n  }\n\n  @page :left {\n    margin: 15mm 20mm 15mm 10mm;\n}\n\n  @page :right {\n    margin: 15mm 10mm 15mm 20mm;\n}\n\n  p, h2, h3 {\n    orphans: 3;\n    widows: 3;\n  }\n\n  h2, h3 {\n    page-break-after: avoid;\n  }\n}\n"
  },
  {
    "path": "htmlstyles/funky_inheader.html",
    "content": "<link href=\"https://fonts.googleapis.com/css2?family=Amatic+SC:wght@700&family=Oswald:wght@200&display=swap\" rel=\"stylesheet\">\n<!--font-family: 'Oswald', sans-serif;-->\n<!--font-family: 'Amatic SC', cursive;-->\n"
  },
  {
    "path": "htmlstyles/plain.css",
    "content": "/*\n * I add this to html files generated with pandoc.\n */\nhtml {\n  font-size: 100%;\n  overflow-y: scroll;\n  -webkit-text-size-adjust: 100%;\n  -ms-text-size-adjust: 100%;\n}\n\nbody {\n  color: #444;\n  background-color: #fff;\n  font-size: 12px;\n  line-height: 1.7;\n  padding: 1em;\n  margin: auto;\n  max-width: 42em;\n  /*background: #fefefe;*/\n  /*font-family: 'Montserrat', sans-serif;*/\n  font-family: 'Open Sans', sans-serif;\n}\n\na {\n  /*#0645cd;*/\n  color:  #1e74ac;\n  text-decoration: underline;\n  text-decoration-style: dotted;\n  font-weight: bold;\n}\n\na:visited {\n  color: #0b0090;\n}\n\na:hover {\n  color: #06e;\n}\n\na:active {\n  color: #faa700;\n}\n\na:focus {\n  outline: thin dotted;\n}\n\n*::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\n*::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\na::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\na::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\np {\n  margin: 1em 0;\n}\n\nimg {\n  max-width: 100%;\n}\n\nh1, h2, h3, h4, h5, h6 {\n  color: #111111;\n  line-height: 125%;\n  margin-top: 2em;\n  font-weight: normal;\n  font-family: 'Open Sans';\n  border-left-color: #fcfcfc;\n  border-left-style: solid;\n  border-left-width: 4px;\n  padding-left: 12px;\n}\n\nh4, h5, h6 {\n  color:222;\n  font-weight: bold;\n}\n\nh1 {\n  font-size: 2.5em;\n}\n\nh2 {\n  font-size: 2em;\n}\n\nh3 {\n  font-size: 1.5em;\n}\n\nh4 {\n  font-size: 1.2em;\n}\n\nh5 {\n  font-size: 1em;\n}\n\nh6 {\n  font-size: 0.9em;\n}\n\nblockquote {\n  color: #765037;\n  margin: 0;\n  padding-left: 2em;\n  border-left: 0.3em #474356 solid;\n}\n\nhr {\n  display: block;\n  height: 2px;\n  border: 0;\n  border-top: 1px solid #aaa;\n  border-bottom: 1px solid #eee;\n  margin: 1em 0;\n  padding: 0;\n}\n\npre, code, kbd, samp {\n  color: #66402f;\n  font-family: monospace, monospace;\n  _font-family: 'courier new', monospace;\n  font-size: 0.98em;\n  background: #ccc;\n}\n\npre {\n  white-space: pre;\n  white-space: pre-wrap;\n  word-wrap: break-word;\n}\n\nb, strong {\n  font-weight: bold;\n}\n\ndfn {\n  font-style: italic;\n}\n\nins {\n  background: #ff9;\n  color: #000;\n  text-decoration: none;\n}\n\nmark {\n  background: #ff0;\n  color: #000;\n  font-style: italic;\n  font-weight: bold;\n}\n\nsub, sup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nul, ol {\n  margin: 1em 0;\n  padding: 0 0 0 2em;\n}\n\nli p:last-child {\n  margin-bottom: 0;\n}\n\nul ul, ol ol {\n  margin: .3em 0;\n}\n\ndl {\n  margin-bottom: 1em;\n}\n\ndt {\n  font-weight: bold;\n  margin-bottom: .8em;\n}\n\ndd {\n  margin: 0 0 .8em 2em;\n}\n\ndd:last-child {\n  margin-bottom: 0;\n}\n\nimg {\n  border: 0;\n  -ms-interpolation-mode: bicubic;\n  /*vertical-align: middle;*/\n}\n\nfigure {\n  display: block;\n  text-align: center;\n  margin: 1em 0;\n}\n\nfigure img {\n  border: none;\n  margin: 0 auto;\n}\n\nfigcaption {\n  font-size: 0.8em;\n  font-style: italic;\n  margin: 0 0 .8em;\n}\n\ntable {\n  margin-bottom: 2em;\n  border-bottom: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n  border-top: 1px solid #ddd;\n  border-spacing: 0;\n  border-collapse: collapse;\n}\n\ntable th {\n  padding: .2em 1em;\n  background-color: #bbb;\n  border-top: 1px solid #ddd;\n  border-left: 1px solid #aaa;\n}\n\ntable td {\n  padding: .2em 1em;\n  border-top: 1px dotted #aaa;\n  border-left: 1px solid #ddd;\n  vertical-align: top;\n}\n\n.active, .collapsible:hover {\n  background-color: #fff;\n}\n\n.author {\n  font-size: 1.2em;\n  text-align: center;\n}\n\n@media only screen and (min-width: 480px) {\n  body {\n    font-size: 14px;\n  }\n}\n@media only screen and (min-width: 768px) {\n  body {\n    font-size: 16px;\n  }\n}\n@media print {\n  * {\n    background: transparent !important;\n    color: black !important;\n    filter: none !important;\n    -ms-filter: none !important;\n  }\n\n  body {\n    font-size: 12pt;\n    max-width: 100%;\n  }\n\n  a, a:visited {\n    text-decoration: underline;\n  }\n\n  hr {\n    height: 1px;\n    border: 0;\n    border-bottom: 1px solid black;\n  }\n\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n\n  .ir a:after, a[href^=\"javascript:\"]:after, a[href^=\"#\"]:after {\n    content: \"\";\n  }\n\n  pre, blockquote {\n    border: 1px solid #999;\n    padding-right: 1em;\n    page-break-inside: avoid;\n  }\n\n  tr, img {\n    page-break-inside: avoid;\n  }\n\n  img {\n    max-width: 100% !important;\n  }\n\n  @page :left {\n    margin: 15mm 20mm 15mm 10mm;\n}\n\n  @page :right {\n    margin: 15mm 10mm 15mm 20mm;\n}\n\n  p, h2, h3 {\n    orphans: 3;\n    widows: 3;\n  }\n\n  h2, h3 {\n    page-break-after: avoid;\n  }\n}"
  },
  {
    "path": "htmlstyles/plain_heading.html",
    "content": ""
  },
  {
    "path": "htmlstyles/plain_inheader.html",
    "content": "<!--<link href=\"https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Montserrat&display=swap\" rel=\"stylesheet\"> -->\n<link href=\"https://fonts.googleapis.com/css2?family=Open+Sans:wght@300&display=swap\" rel=\"stylesheet\">\n<!--font-family: 'Bebas Neue', cursive;-->\n<!--font-family: 'Montserrat', sans-serif;-->"
  },
  {
    "path": "htmlstyles/refined.css",
    "content": "/*\n * I add this to html files generated with pandoc.\n */\nhtml {\n  font-size: 100%;\n  overflow-y: scroll;\n  -webkit-text-size-adjust: 100%;\n  -ms-text-size-adjust: 100%;\n}\n\nbody {\n  color: #fff;\n  background-color: #555;\n  font-size: 12px;\n  line-height: 1.7;\n  padding: 1em;\n  margin: auto;\n  max-width: 42em;\n  /*background: #fefefe;*/\n  font-family: 'Raleway', sans-serif;\n}\n\n.node-body.h2 {\n\tborder-top-style: solid;\n\tborder-top-color: #595959;\n  #background-image: linear-gradient(to top right, #555 , #555, #555, #555, #444);\t\n}\n\na {\n  /*#0645cd;*/\n  color:  #1e74ac;\n  text-decoration: underline;\n  text-decoration-style: dotted;\n  font-weight: bold;\n}\n\na:visited {\n  color: #0b0090;\n}\n\na:hover {\n  color: #06e;\n}\n\na:active {\n  color: #faa700;\n}\n\na:focus {\n  outline: thin dotted;\n}\n\n*::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\n*::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\na::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\na::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\np {\n  margin: 1em 0;\n}\n\nimg {\n  max-width: 100%;\n}\n\nh2 {\n  font-family: 'Julius Sans One', sans-serif;\n  color: #ffffff;\n  line-height: 100%;\n  margin-top: 2em;\n  font-weight: normal;\n  padding-left: 12px;\n}\n\nh3, h4, h5, h6, h7 {\n  color: #c7af2a;\n  /*line-height: 100%;*/\n  margin-top: 2em;\n  font-weight: normal;\n  font-family: 'Open Sans Condensed', sans serif;\n  /*padding-left: 12px;*/\n  /*text-shadow: 2px 2px 5px;*/\n}\n\nh4, h5, h6 {\n  color:aaa;\n  font-weight: bold;\n}\n\nh1 {\n  font-size: 2.5em;\n}\n\nh2 {\n  font-size: 2em;\n}\n\nh3 {\n  font-size: 1.5em;\n}\n\nh4 {\n  font-size: 1.2em;\n}\n\nh5 {\n  font-size: 1em;\n}\n\nh6 {\n  font-size: 0.9em;\n}\n\nblockquote {\n  color: #765037;\n  margin: 0;\n  padding-left: 2em;\n  border-left: 0.3em #474356 solid;\n}\n\nhr {\n  display: block;\n  height: 2px;\n  border: 0;\n  border-top: 1px solid #aaa;\n  border-bottom: 1px solid #eee;\n  margin: 1em 0;\n  padding: 0;\n}\n\npre, code, kbd, samp {\n  color: #66402f;\n  font-family: monospace, monospace;\n  _font-family: 'courier new', monospace;\n  font-size: 0.98em;\n  background: #ccc;\n  border-radius: 25px; \n}\n\n#box-shadow: 5px 5px 10px #888888;\n\npre {\n  white-space: pre;\n  white-space: pre-wrap;\n  word-wrap: break-word;\n}\n\nb, strong {\n  font-weight: bold;\n}\n\ndfn {\n  font-style: italic;\n}\n\nins {\n  background: #ff9;\n  color: #000;\n  text-decoration: none;\n}\n\nmark {\n  background: #ff0;\n  color: #000;\n  font-style: italic;\n  font-weight: bold;\n}\n\nsub, sup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nul, ol {\n  margin: 1em 0;\n  padding: 0 0 0 2em;\n}\n\nli p:last-child {\n  margin-bottom: 0;\n}\n\nul ul, ol ol {\n  margin: .3em 0;\n}\n\ndl {\n  margin-bottom: 1em;\n}\n\ndt {\n  font-weight: bold;\n  margin-bottom: .8em;\n}\n\ndd {\n  margin: 0 0 .8em 2em;\n}\n\ndd:last-child {\n  margin-bottom: 0;\n}\n\nimg {\n  border: 0;\n  -ms-interpolation-mode: bicubic;\n  /*vertical-align: middle;*/\n}\n\nfigure {\n  display: block;\n  text-align: center;\n  margin: 1em 0;\n}\n\nfigure img {\n  border: none;\n  margin: 0 auto;\n}\n\nfigcaption {\n  font-size: 0.8em;\n  font-style: italic;\n  margin: 0 0 .8em;\n}\n\ntable {\n  margin-bottom: 2em;\n  border-bottom: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n  border-top: 1px solid #ddd;\n  border-spacing: 0;\n  border-collapse: collapse;\n}\n\ntable th {\n  padding: .2em 1em;\n  background-color: #bbb;\n  border-top: 1px solid #ddd;\n  border-left: 1px solid #aaa;\n}\n\ntable td {\n  padding: .2em 1em;\n  border-top: 1px dotted #aaa;\n  border-left: 1px solid #ddd;\n  vertical-align: top;\n}\n.table-number {\n  color:#ccc;\n  font-weight: bold;\n}\ncaption.t-above { caption-side: top; }\ncaption.t-bottom { caption-side: bottom; }\n.figure-number {\n  color:aaa;\n  font-weight: bold;\n}\n.figure {\n  font-style: italic;\n}\n\n.author {\n  font-size: 1.2em;\n  text-align: center;\n}\n\n\n.node-body {\n  padding: 0 18px;\n  max-height: 0;\n  margin-left: 0;\n  padding-left: 0;\n  margin-right: 0;\n  padding-right: 0;\n  overflow: hidden;\n  transition: max-height 0.2s ease-out;\n }\n  .active, .collapsible:hover {\n  background-color: #555;\n  }\n  .collapsible:after {\n    font-size: 22px;\n    float: right;\n    margin-right: 20px;\n  }\n  .active:after {\n  font-size: 22px;\n  margin-right: 20px;\n  }\n\n@media only screen and (min-width: 480px) {\n  body {\n    font-size: 14px;\n  }\n}\n@media only screen and (min-width: 768px) {\n  body {\n    font-size: 16px;\n  }\n}\n@media print {\n  * {\n    background: transparent !important;\n    color: black !important;\n    filter: none !important;\n    -ms-filter: none !important;\n  }\n\n  body {\n    font-size: 12pt;\n    max-width: 100%;\n  }\n\n  a, a:visited {\n    text-decoration: underline;\n  }\n\n  hr {\n    height: 1px;\n    border: 0;\n    border-bottom: 1px solid black;\n  }\n\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n\n  .ir a:after, a[href^=\"javascript:\"]:after, a[href^=\"#\"]:after {\n    content: \"\";\n  }\n\n  pre, blockquote {\n    border: 1px solid #999;\n    padding-right: 1em;\n    page-break-inside: avoid;\n  }\n\n  tr, img {\n    page-break-inside: avoid;\n  }\n\n  img {\n    max-width: 100% !important;\n  }\n/*\n  @page :left {\n    margin: 15mm 20mm 15mm 10mm;\n}\n*/\n  @page :right {\n    margin: 15mm 10mm 15mm 20mm;\n}\n\n  p, h2, h3 {\n    orphans: 3;\n    widows: 3;\n  }\n\n  h2, h3 {\n    page-break-after: avoid;\n  }\n}\n"
  },
  {
    "path": "htmlstyles/refined_inheader.html",
    "content": "<link href=\"https://fonts.googleapis.com/css2?family=Julius+Sans+One&family=Raleway&display=swap\" rel=\"stylesheet\">\n<link href=\"https://fonts.googleapis.com/css2?family=Open+Sans+Condensed:ital,wght@1,300&display=swap\" rel=\"stylesheet\">\n<!-- font-family: 'Julius Sans One', sans-serif; -->\n<!--font-family: 'Oswald', sans-serif;-->\n<!--font-family: 'Amatic SC', cursive;-->\n"
  },
  {
    "path": "languagelist.yaml",
    "content": "\n- language: python\n- language: cpp\n  source: c++\n- language: C\n  source: c\n- language: perl \n- language: ini\n- language: bash\n  source: shell.bash\n  match: bash|sh\n- language: lua\n- language: js\n  match: javascript|js\n- language: json\n- language: java\n- language: php\n- language: xml\n  text: xml\n- language: csharp\n  source: cs\n  match: csharp|cs\n- language: powershell\n- language: plantuml\n  source: wsd\n- language: ditaa\n- language: graphviz\n  source: dot\n- language: lisp\n  source: lisp\n- language: emacs-lisp\n  source: lisp\n- language: yaml\n- language: rust\n- language: sql\n- language: r(\\s|$)\n  source: r\n- language: html\n  text: html.basic\n- language: go\n- language: ledger\n- language: beancount\n- language: make\n  source: makefile\n- language: makefile\n  source: makefile\n- language: typescript\n  match: typescript|ts\n  source: ts\n- language: clojure\n- language: bat|cmd\n  source: dosbatch\n- language: org\n  text: orgmode\n- language: pascal\n- language: actionscript\n  source: actionscript.2\n- language: applescript\n- language: dtd\n  source: xml.dtd\n- language: haskell\n- language: (markdown|md)(\\s|$)\n  text: html.markdown\n- language: groovy\n- language: regexp\n  source: regexp\n- language: ruby\n- language: restructuredtext\n  text: restructuredtext\n- language: xsl\n  text: xml.xsl \n- language: scala\n- language: hex\n- language: erlang\n- language: diff\n- language: d(\\s|$)\n- language: css\n- language: cmake\n- language: asp\n- language: gnuplot\n- language: mermaid\n- language: awk\n- language: painless\n  source: java\n\n\n\n\n\n\n"
  },
  {
    "path": "messages/1.0.1.org",
    "content": "* 1.0.1 \n  - Improving link handling for local files.\n  - Fixes some bugs around generating local file links."
  },
  {
    "path": "messages/1.0.10.org",
    "content": "* 1.0.10\n** Snippets\n\t- Added link insertion snippet\n\t  #+BEGIN_QUOTE\n\t    <l\n\t  #+END_QUOTE\n\n\t  Will insert a new quote jumping between the fields and jumping after the link when done\n\t  #+BEGIN_QUOTE\n\t  [[$1][$2]] $0  \n\t  #+END_QUOTE\n\n** Agenda View\n\t- Truncated filename in day view for filenames longer than 12 characters.\n\n** ST4\n\t- Fixed quick panel views to continue to work on ST4 builds. "
  },
  {
    "path": "messages/1.0.2.org",
    "content": "* 1.2.0\n\t- Documentation moved out of the repository to its own repository\n\t  this was done to shrink the size of the package.\n\t- Turned off logger that was accidentally left on.\n\t- Added \"openas\": \"direct\" to capture definitions. This will\n\t  open the capture directly in the file at the target location.\n\t- Added  \"agendaFirstDay\" and \"agendaWeekViewNumDays\" to settings to allow\n\t  users to start the week view from monday rather than sunday and limit the\n\t  week view to just a 5 day view rather than 7 days if desired.\n\t  - Actually agendaFirstDay got renamed to firstDayOfWeek as \n\t    the date picker now respects the firstDayOfWeek as well\n\t    rather than just the agenda\n\t- Cleaned up a bunch of old debugging output.\n\t- Working on named targets for blocks in the parser, this is to facilitate\n\t  eventual chainging of inputs in the bable execution. \n  - Fixed archive notation to work without the colon separator.\n  - added <q and <v quote and verse snippets\n  - Added these release notes\n  - Improved settings to use the new settings ui.\n  - Changed docs link in settings to open the docs repo rather than\n    opening the docs in sublime.\n  - Fixed global tab cycling on first line of file.\n  - agendaFirstDay can now be the english name of a day of the week OR an integer.\n  - Month view in the agenda now respects agendaFirstDay\n  - PRIORITIES comment is now respected in change priority command\n  - STARTUP comment now recurses\n  - WARNING: orgextended.sublime-syntax renamed to OrgExtended. This is so the\n  \ttitle appears as OrgExtended in the syntax list on the bottom right of sublime.\n  \tThis can caust errors when loading sublime with an old settings file.\n  \tPlease carefully rename your settings file and close all org tabs.\n  - Fixed a number of issues when loading as a zipped package. Export should\n    work from a package again. \n  - agendaDayStart and End renamed to agendaDayStartTime and agendaDayEndTime\n  \tfor more clarity"
  },
  {
    "path": "messages/1.0.3.org",
    "content": "* 1.0.3\n\t- HTML Exporter has better support for HTML_ATTR comments.\n\t- Capture now works on ST4 4096+ with the new modifiers\n\t- Direct capture mode has had some fixes that handle spaces on a line and end of file better\t\n\t- WeekView in calendar now respects agendaDayStartTime and agendaDayEndTime\n\t\t- View will be truncated to the hours specified"
  },
  {
    "path": "messages/1.0.4.org",
    "content": "* 1.0.4 HTML Exporter Improvements\n\t- #+CAPTION comments export a custom figure for tables and images.\n\t\t- At the moment captions are always t-above style.\n\t\t- Figures are done with a div and span pair. \n\t\t- Styles include: .figure .figure-number and caption.t-above and caption.table-number\n\t- #+AUTHOR, #+TITLE, #+EMAIL, #+LANGUAGE tags have rudimentary support although very\n\t  rough.\n\t- #+NAME is stripped out of output properly.\n\n"
  },
  {
    "path": "messages/1.0.5.org",
    "content": "* 1.0.5\n** Syntax Highlighting\n\t- Bash blocks uses embed to allow them to escape properly\n\t- Core syntax (not agenda and picker) now support standard syntax markers\n\t  - NOTE: Not all features are supported or colored. Existing OrgExtended\n\t          color schemes are still the preferred means of viewing an org file.\n\t  - Eventual goal is to take an existing active color scheme and provide a tool to\n\t    extend it to support all the org coloring. This is a first step in that direction.\n\t- Created languagelist.yaml to make it easier to add new languages to the syntax."
  },
  {
    "path": "messages/1.0.6.org",
    "content": "* 1.0.6\n** Color Scheme Generator\n\tThis is a bit of an experimental feature to help people\n\tuse org mode with their own color scheme. It is NOT complete\n\tand not where I want it to be yet. This does not yet touch the agenda\n\tor the data picker, but I do eventually intend to work on those as well.\n\n\tI feel like orgmode should respect your chosen color scheme!\n\n\t- Org Create Color Scheme From Active\n\n\tWhen run from a normal NON org mode buffer will sample the currently\n\tactive color scheme, create a new color scheme file in:\n\n\t#+BEGIN_QUOTE\n\t  Packages/User/OrgColorSchems/<originalName>_Org.sublime-color-scheme\n\t#+END_QUOTE\n\n\tIt will then add a couple of key scopes such as:\n\n\t- orgmode.preamble :: which is used to make the leading stars invisible on a subheading\n\t- orgmode.state.*  :: These are used to give the core built in states some color\n\n\tThis also adds a comment block in the color scheme file that tries to help new users understand\n\twhat their options are. Note this is based off your active color scheme.\n\n\tThis will ALSO change the active OrgExtended color scheme to be this new color scheme to let you\n\tsee how it is going to pan out. This may, or may NOT work out well for you!\n\n\tNOTE: This is a preview feature. It is still under active development and will change / improve\n\t      as I mature it. I felt it might be beneficial to some to release it at this point.\n\t      PLEASE only use this feature if you feel confident with your ability to manipulate sublime\n\t      color schemes. I have yet to document the feature or test it on a wide variety of color\n\t      schemes. Ultimately I would like to include the orgagenda and orgdatepicker schemes into\n\t      this one scheme. To do that I need some more creative programmatic means of generating a\n\t      starting color palette from a pre-existing one. That will take a bit.\n\n\t      However, in the interim I am happily using a generated Guna color scheme on my personal machine.\n\n"
  },
  {
    "path": "messages/1.0.7.org",
    "content": "* 1.0.7\n** Color Scheme Generator\n\t- Date picker syntax extended to work with generic color schemes\n\t- Agenda picker syntax extended to work with generic color schemes\n\t- Color scheme generator has time delay to try to avoid popup errors\n\t  when generating and switching color schemes.\n\t- Color scheme generator will generate some of the key agenda colors.\n\t- Color scheme generator will output a comment block for the date picker\n\t  describing additional scopes.\n\t"
  },
  {
    "path": "messages/1.0.8.org",
    "content": "* 1.0.8\n** Folding\n\t- Fixed a bug where buffers that are lacking a filename\n\t  can still be folded.\n** Clocking\n\tnew setting: \n\t\t- clockingSubMinuteClocks: true will now keep clocking entries that are smaller than a minute\n** Movement\n\t- Fixed move heading up / move heading down. This now does the same\n\t  as org-move-subtree-up and org-move-subtree-down.\n\t  - Moves headings within siblings at the same level of the tree."
  },
  {
    "path": "messages/1.0.9.org",
    "content": "* 1.0.9\n** Editing\n\t- Org Select Subtree \n\t  This will select the full subtree of the active heading.\n\t\t- alt+o m s \n\t\t- <space> m s (neovintageous normal mode)\n    - Org Select Entity\n      This will select just the current node\n        - alt+o m e    (mark entity)\n        - <space> m e  (neovintageous normal mode)\n    - Org Copy Subtree\n      This will copy the entire subtree to the clipboard.\n        - alt+o y s    (yank entity)\n        - <space> y s  (neovintageous normal mode)\n    - Org Copy Entity\n      This will copy the current node to the clipboard.\n        - alt+o y e    (yank entity)\n        - <space> y e  (neovintageous normal mode)\n\n** Folding\n  - Fixed link tab cycling.  \n  \n** Color Scheme Generator\n  - The generator is now able to handle simple tmTheme files.\n\n    NOTE: it converts them to sublime-color-scheme files in the output\n          folder.\n\n  - Added Org Select Color Scheme menu item to switch Org between color schemes\n    you have already generated. NOTE: same caveats hold about having org files\n    open when switching. Sublime does not automatically switch existing views.\n\n** NeoVintageous\n\t- For ST4 users - neovintageous has upgraded to python 3.8\n\t  this means that my hacks to push register 0 with the values\n\t  of the system clipboard aren't working until I upgrade OrgExtended.\n\n\t  I will attempt to make that a priority for those that care."
  },
  {
    "path": "messages/1.1.0.org",
    "content": "* 1.1.0\n** Scheduling\n\t- Support active timestamps vs SCHEDULED\n\t  SCHEDULED is when you want to start on a task\n\t  while tasks with a timestamp are scheduled at a point in time.\n\n\t  #+BEGIN_EXAMPLE\n\t    ** TODO Heading\n\t       SCHEDULED: <startdate>  <-- This will appear in the agenda until you close the task\n\t    ** TODO HEADING\n\t       <date>  <-- This will appear in the agenda but only at the date specified\n\t  #+END_EXAMPLE\n\n\t- BREAKING CHANGE\n\t  Before I would only show tasks, these are items with an open TODO state.\n\t  Now, by default anything that has an active timestamp or is scheduled will\n\t  show up in the agenda UNLESS you set that view to :onlytasks as a parameter.\n\t  #+BEGIN_EXAMPLE\n\t    ** HEADING\n\t       <date>  <-- This will now appear in the agenda where before it would not\n\t  #+END_EXAMPLE\n\n\t  #+BEGIN_SRC js\n      \"AgendaCustomViews\": \n      {\n        \"Default\": [\"Calendar\", \"Week\", \"Day : onlytasks\", \"Blocked Projects\", \"Next Tasks\", \"Loose Tasks\"],\n        \"Todos\":   [\"Todos\"],\n      }\n\t  #+END_SRC\n\n\t  Note the onlytasks parameter, that will filter out non tasks from the Day view in my\n\t  default agenda view.\n\n\t- DEADLINE is still not supported but support should be comming in a future release."
  },
  {
    "path": "messages/1.1.1.org",
    "content": "* 1.1.1\n** Scheduling\n\t- DEADLINE works in the agenda. Very minimal visualization at this time.\n\t  Will show Warning, Due and Overdue messages on the right hand side of the day view.\n\t- DEADLINE: <........ -3d> basic warning cookies work \n\t- Fixed a bug with new SCHEDULED: behaviour in week view.\n\t- Removed visualization in the CalendarView for SCHEDULED and DEADLINE while I figure\n\t  out the best way to visualize that, that is not super ugly. \n\n\n** Editing\n\t- New Link Editing Commands\n\t  Org Copy Href will copy the href out of a link onto the clipboard\n\t  currently not bound to a keybinding.\t\n\n\t  Org Select Href will select the href in a link, even\n\t  if it is folded.\n\n\t  currently not bound to a keybinding"
  },
  {
    "path": "messages/1.1.10.org",
    "content": "* 1.1.10\n\tNone of the new commands are bound to a keybinding.\n\n** Blank Table Insert\n\t- \"Org Insert Blank Table\"\n\t- This will insert a blank WxH blank table at point.\n\n** Csv Import\n\t- \"Org Import Csv\"\n\t- Still in its infancy\n    - Added Org Import Cvs command. Will import a csv file into a table.\n\n** Convert Region To Table\n\t- \"Org Convert Region To Table\"\n\t- Only works with commas at the moment.\n\t- Tries to convert a region to a table, will improve with time.\n"
  },
  {
    "path": "messages/1.1.11.org",
    "content": "* 1.1.11\n** Table Editing\n\t- Incorporated Table Edit keybindings allowing for column and row movement, navigation,\n\t  inserting and deleting rows and columns and hline insertion with some key bindings.\n\t- Improved separator auto detection during import and region conversion.\t\n\n\n\t\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "messages/1.1.12.org",
    "content": "* 1.1.12\n\n** Tables\n\n \tREALLY preliminary table formula preview.\n \tIt's buggy!\n\n \tThe example below runs, but not much else will.\n\n \t[[https://orgmode.org/worg/org-tutorials/org-spreadsheet-intro.html][Spreadsheets In Org]]\t\n\n \tI am undecided if I will continue with attempting to use\n \tthe python ast for my expression support or simply \n \troll my own parser as my limited knowledge of the ast module\n \thas me at a loss of how to change the default grammar. \n \t(If anyone has input and knowledge here that would be beneficial)\n\n    | a | b | c | d | e |\n    |---+---+---+---+---|\n    | a | b | 5 | 1 | 2 |\n    | 1 | 1 | 1 | 1 | 1 |\n    #+TBLFM: @3$5=vmean($1..$5)+sin(@3$1)::$4=$3+5\n\n    Things that work:\n    - Evaluation of rows and columns with basic arithmetic\n    - vmean, vmax, vmin and a handful of other functions\n    - the basic range syntax seen above.\n    - respecting the header in column expressions\n\n    Things that do NOT work:\n    - Automatically updating your expressions when you resize the table\n    - Filling in a cell with an expression and having it automatically be moved to tablefmt\n    - Cell highlighting when editing expressions.\n    - calc style output formatting (semi colon)\n    - Negative or other fancier ranges\n    - Named fields\n    - Visualizing columns\n    - Horizontal separators are currently considered in cell indexes (this will be fixed)\n\n    Right now evaluating a table is bound to the execute DWIM binding.\n\n\n\n"
  },
  {
    "path": "messages/1.1.13.org",
    "content": "* 1.1.13\n** Spreadsheets Preview V2\n\n\tWARNING: Super experimental, use at your own risk.\n\n\n \t[[https://orgmode.org/worg/org-tutorials/org-spreadsheet-intro.html][Spreadsheets In Org]]\t\n\n\t- Horizontal rules are now respected in row ids\n\t- Cell highlight can help with understanding formulas\n\t- Fixed a couple of bugs with cell indexing\n\t- Calling execute on a cell with := will introduce a new formula \n\t  into the TBLFM and evaluate the table.\n\t- = Should add a column expression\n\n    | a | b | c | d |  e   |\n    |---+---+---+---+------|\n    | a | b | 5 | 4 | :=$1 |\n    | 1 | 1 | 1 | 1 | 1    |\n    #+TBLFM: @3$5=vmean($1..$4)+sin(@3$1)::$4=$3+5::@2$5=$1\n\n    Still very poorly tested but improving.\n\n    Things that work:\n    - Evaluation of rows and columns with basic arithmetic\n    - vmean, vmax, vmin and a handful of other functions\n    - the basic range syntax seen above.\n    - respecting the header in column expressions\n    - filling in a cell with an expression and having it automatically be moved to tablefmt\n    - cell highlighting when editing expressions.\n    - horizontal separators are now respected as non cells.\n\n    Things that do NOT work:\n    - Automatically updating your expressions when you resize the table\n    - calc style output formatting (semi colon)\n    - Negative or other fancier ranges\n    - Named fields\n    - Visualizing columns\n\n    Right now evaluating a table is bound to the execute DWIM binding.\n\n\n    NOTE: This feature will never be completely compatible with ORG. Org supports the ability to execute\n          arbitrary lisp expressions on table cells. We aren't going that far. That said, I really appreciate\n          the basics of the spreadsheet feature in org and we should be able to support most of the basics with our own flair.\n"
  },
  {
    "path": "messages/1.1.14.org",
    "content": "* 1.1.14\n** Spreadsheet Preview V3\n\t- Column cell formula insertion was broken, this is now fixed.\n\t- TBLFM expressions on their own lines would cause exceptions\n\t- Added non standard row insertion using >= syntax.\n\t  While testing this found a bug in row expressions\n\n    | a | b | c | d  |         e          |\n    |---+---+---+----+--------------------|\n    | a | b | 5 | 10 | >=@3               |\n    | 1 | 1 | 1 |  6 | 3.0914709848078967 |\n    #+TBLFM: @3$5=vmean($1..$4)+sin(@3$1)::$4=$3+5::@2=@3\n\n    - Still using a hacked up version of simple_eval and python ast\n      for the expression parser. Decided using functions rather than names\n      for the expression differences made sense. Even though this is a bit of\n      a misuse of the parser I think I will stick with this approach, it's simple\n      it's functional and will allow me to support the other variable modifiers in the end.\n    - Right now the parser is pretty locked down.\n    - I will probably never support arbitrary lisp like spreadsheets like emacs can.\n      (As much as it would be fun to build a lisp parser here, it's kind of missing the rest of emacs and the massive function library)\n    - Cleaned up some asserts that happened when editing a table. The highligher didn't like targets changing on the fly.\n    - That said, I may support more and more of the calc library and even allow some user made extensions eventually.\n    - My eventual goal is to flesh out my babel hack to a more full featured version with all the power that comes along with that. \n      Without TRAMP, remote sessions etc. some of the\n      power of bable is muted a little bit. (But who knows, maybe TRAMP is possible in sublime...) That said, we need powerfull spreadsheet\n      support as an input source before really going to town on bable is possible. \n\n*** New Cell Identifiers\n\n\tWith the refactor on how I am handling cells I can now support the > and relative cell identifiers\n\t-1 is one to the left or one up from the current target being calculated. It is a relative identifier.\n\t> means last column while >> means last but one.\n\n    | a | b | c | d  |         e          |\n    |---+---+---+----+--------------------|\n    | a | b | 5 | 10 | >=@3               |\n    | 1 | 1 | 1 |  6 | 3.0914709848078967 |\n    #+TBLFM: @>$5=vmean($1..$4)+sin(@-1$-1)::$4=$#+5::@2=@3\n\n\n    - In addition we have index symbols $# is the current column and @# is the current row\n\n    | idx |   Index Gen   |\n    |-----+---------------|\n    |   1 | Testing Index |\n    |   2 | Generation    |\n    #+TBLFM: $1=@#-1\n\n    - Constants defined in your file can also be used in expressions\n\n    #+CONSTANTS: hello=world a=b\n    | x     | y |\n    | world | b |\n    #+TBLFM:@2$2=$a::@2$1=$hello\n\n\n    Things that work:\n    - Evaluation of rows and columns with basic arithmetic\n    - vmean, vmax, vmin and a handful of other functions\n    - the basic range syntax seen above.\n    - respecting the header in column expressions\n    - filling in a cell with an expression and having it automatically be moved to tablefmt\n    - cell highlighting when editing expressions.\n    - horizontal separators are now respected as non cells.\n    - Negative (relative) or arrow cell indexes\n    - Index symbol $# and @#\n\n    Things that do NOT work:\n    - Automatically updating your expressions when you resize the table\n    - calc style output formatting (semi colon)\n    - Advanced tabled features / Named fields\n    - box range targets\n    - Visualizing columns\n    - gnu plot support\n    - hline symbols\n    - more functions\n    - remote() references to other named tables.\n"
  },
  {
    "path": "messages/1.1.15.org",
    "content": "* 1.1.15\n** Spreadsheets Preview V4\n\t- Fixed a bug with row ranges not expanding properly\n\t- Fixed an issue with tables at the last row of the file.\n\t- Added random(a,b) - integer random range\n\t- Added randomf() - 0.0..1.0 random range\n\t- Range targets are now supported:\n\n\t|    a     |    b     |    c     |    d     |\n\t|----------+----------+----------+----------|\n\t| 0.506666 | 0.995246 |   0.5519 | 0.061723 |\n\t| 0.065874 | 0.993011 | 0.241133 | 0.410426 |\n \t#+TBLFM:@2$1..@3$4=randomf()\n\n\n \t- Removed some extraneous trace information.\n\n \t| a | b | c | d | e  |\n \t|---+---+---+---+----|\n \t| 3 | 4 | 5 | 6 |  7 |\n \t| 2 | 4 | 6 | 8 | 10 |\n  \t#+TBLFM:@2=$#+2::@3=$#*2"
  },
  {
    "path": "messages/1.1.16.org",
    "content": "* 1.1.16\n** Spreadsheet Preview V5\n\t- Moving cells around, adding and deleting cells\n\t  is now starting to try to keep formulas intact now!\n\t- Deleting the target or source of a cell will result in the\n\t  formula having and $INVALID or @INVALID tag which is not currently\n\t  handled properly. This will be improved going forward!\n\n"
  },
  {
    "path": "messages/1.1.17.org",
    "content": "* 1.1.17\n*** Spreadsheets Preview V6\n    :PROPERTIES:\n      :testval: 5\n    :END:\n \t- Invalid cell references now are not assserting in the obvious cases.\n \t- Invalid cell references now generate a status message during the highligh\n \t  phase to let you know you have invalid cell references:\n \t- Fixed a bug with column lookup where it would return curcol sometimes rather than fixed reference.\n \n \t| a | b | c | d | e |\n \t| 1 | 1 | 1 | 1 | 1 |\n \t| 2 | 2 | 2 | 2 | 2 |\n  \t#+TBLFM:@INVALID=@2+1\n \n  \t- Removed a bunch of silly debugging prints that were left around from 1.1.16 release!\n  \t- SOME support for formatting suffix in formulas:\n  \t\t- N    - Will treat empty cells as 0\n  \t\t- %.#f - Will output # decimal places like a printf\n\n \t| a     | b     | c   | d     | e     |\n \t| 1     | 1     |     | 1     | 1     |\n \t| 0.476 | 0.476 | 0.0 | 0.476 | 0.476 |\n  \t#+TBLFM:@3=@2/2.1;N%.3f\n   \n  \t- Additional functions:\n  \t\t- floor\n  \t\t- ceil\n  \t\t- round\n  \t\t- trunc\n\n  \t- Properties can be referenced in an equation:\n  \t\t$PROP_<name>\n\n  \t(See property in node above)\n\n  \t#+NAME: TestName\n \t| a | b  | c  | d  | e  |\n \t| 5 | 10 | 15 | 20 | 25 |\n  \t#+TBLFM:@2=$PROP_testval*$#\n\n  \t#+CONSTANTS: pi=3.1415926\n \t| a   | b   | c   | d    | e    |\n \t| 3.1 | 6.3 | 9.4 | 12.6 | 15.7 |\n  \t#+TBLFM:@2=$pi*$#;%.1f\n\n  \t- Remote table references\n  \t  here we are grabbing a value from the tabled named TestName\n  \t  above:\n \t| a  | b  | c  | d  | e  |\n \t| 10 | 10 | 10 | 10 | 10 |\n  \t#+TBLFM:@2=remote('TestName',@2$2)\n\n\n  \tCURRENT FUNCTIONS:\n        - vmean\n        - vmedian\n        - vmax\n        - vmin\n        - vsum\n        - tan\n        - cos\n        - sin\n        - exp\n        - floor\n        - ceil\n        - round\n        - trunc\n        - randomf\n        - random\n\n    Things that work:\n    - Evaluation of rows and columns with basic arithmetic\n    - vmean, vmax, vmin and a handful of other functions\n    - the basic range syntax seen above.\n    - respecting the header in column expressions\n    - filling in a cell with an expression and having it automatically be moved to tablefmt\n    - cell highlighting when editing expressions.\n    - horizontal separators are now respected as non cells.\n    - Negative (relative) or arrow cell indexes\n    - Index symbol $# and @#\n    - Automatically updating your expressions when you resize the table\n    - box range targets\n    - basic printf style formatting after semi colon for floating point types: $2=$1/2.0;%.1f\n    - Properties and constants (defined in a CONSTANTS comment) can be used in formulas\n    - remote() references to other named tables.\n\n    Things that do NOT work:\n    - Extended calc style output formatting (semi colon)\n    - Advanced tabled features / Named fields\n    - Visualizing columns\n    - gnu plot support\n    - hline symbols\n    - more functions\n"
  },
  {
    "path": "messages/1.1.18.org",
    "content": "* 1.1.18\n** Spreadsheets\n\t- A crude stab at a table visualization\n\t- \"Org Show Table Rows\" - will show a set of phantoms that ID the rows and columns to help when authoring formulas\n\t- \"Org Hide Table Rows\" - will hide the phantoms.\n    - Fixed positive relative offsets, they were not working:\n\n    | a | b | c | d | e | f |\n    | 4 | 5 | 6 | 7 | 8 | 9 |\n    | 1 | 2 | 3 | 4 | 5 | 6 |\n    #+TBLFM:@2= @+1+3\n    \n    Things that work:\n    - Evaluation of rows and columns with basic arithmetic\n    - vmean, vmax, vmin and a handful of other functions\n    - the basic range syntax seen above.\n    - respecting the header in column expressions\n    - filling in a cell with an expression and having it automatically be moved to tablefmt\n    - cell highlighting when editing expressions.\n    - horizontal separators are now respected as non cells.\n    - Negative (relative) or arrow cell indexes\n    - Index symbol $# and @#\n    - Automatically updating your expressions when you resize the table\n    - box range targets\n    - basic printf style formatting after semi colon for floating point types: $2=$1/2.0;%.1f\n    - Properties and constants (defined in a CONSTANTS comment) can be used in formulas\n    - remote() references to other named tables.\n    - Visualizing columns and rows\n\n    Things that do NOT work:\n    - Extended calc style output formatting (semi colon)\n    - Advanced tabled features / Named fields\n    - gnu plot support\n    - more functions\n\n"
  },
  {
    "path": "messages/1.1.19.org",
    "content": "* 1.1.19\n** Spreadsheets Preview V7\n\t- Added the ability to add your own functions\n\n\tCreate a file with the name of your function in:\n\n\t#+BEGIN_EXAMPLE\n\tPackages/User/orgtable/<yourfunction>.py\n\t#+END_EXAMPLE\n\n\tHere I have created a file called nowstr.py:\n\n\t#+BEGIN_SRC python\n    def Execute():\n\t    import sublime\n\t    import datetime\n\t    return str(datetime.datetime.now())\n\t#+END_SRC\t\n\n\tThe module will be run dynamically so your imports are best to put in the function as seen above.\n\tIf your function takes cells they should be parameters to Execute.\n\n\tIn my example I am returning the current datetime as a string:\n\n\t| 2021-03-03 12:42:03.720657 | b | c | d | e |\n\t| 2021-03-03 12:42:03.738691 |   |   |   |   |\n    #+TBLFM:$1=nowstr()\n\n    I will have further examples in the documentation going forward.\n\n    - Fixed a couple of asserts found when navigating tables.\n\n   \tThis feature is considered an advanced feature and is disabled by default in your settings file.\n\n   \t#+BEGIN_EXAMPLE\n    \"enableTableExtensions\": true,\n   \t#+END_EXAMPLE\t\n\n*** Data Time methods\n\n\tAdded a bunch of the datetime methods\n\n   |             A              |\n   |----------------------------|\n   | 2021-03-03 19:56:44.294403 |\n   | 2021                       |\n   | 3                          |\n   | 3                          |\n   | 2021-03-03                 |\n   | 19:56:44.375228            |\n   | 19                         |\n   | 56                         |\n   | 44                         |\n   | 2                          |\n   | 62                         |\n   #+TBLFM:@2$1=now()::@3$1=year(now())::@4$1=month(now())::@5$1=day(now())::@6$1=date(now())::@7$1=time(now())::@10$1=second(now())::@9$1=minute(now())::@8$1=hour(now())::@11$1=weekday(now())::@12$1=yearday(now())\n\n\n** Checkboxes\n  :PROPERTIES:\n    :COOKIE_DATA: recursive\n  :END:\n\n  Recursive todo summary data. NOTE: this counts ALL checkboxes as if they are part of the parent checkbox not just leaves.\n  This can be set using the COOKIE_DATA property above or using the global setting:\n\n  #+BEGIN_EXAMPLE\n      \"checkboxSummaryRecursive\": true,\n  #+END_EXAMPLE\n\n - [-] Testing parent\t[3/6]\n   - [x] A\n   - [-] B\n   \t- [ ] C \n   \t- [x] D\n   \t- [x] E\n   - [ ] F\n\n   Supporting this was a request from:\n   [[https://github.com/ihdavids/orgextended/issues/13][Checkbox summaries]] \n\n\n"
  },
  {
    "path": "messages/1.1.2.org",
    "content": "* 1.1.2\n\t- Added OrgDeadlineCommand OrgScheduleCommand OrgActiveTimestampCommand\n\t  to add SCHEDULE, DEADLINE and active timestamps using the quick picker."
  },
  {
    "path": "messages/1.1.20.org",
    "content": "* 1.1.20\n** Editing\n\t- Heading and Child heading insertion now ignores whitespace at the end of a node\n** Extensions\n\t- Improved extension reloading on modification. Before it would force reload to often\n\t  now we track and reload only when we have to. This should improve table performance\n\t  a little. This is in prep for the advanced table features including automatic\n\t  cell calculations on # fields.\n\t- Extension folders renamed for consistency:\n\t\t- src folder renamed to orgsrc\n\t\t- resolver folder renamed to orgresolver\n\t\t- dynamic folder renamed to orgdynamic\n\t\t- table extensions were already in orgtable\n** Spreadsheets Preview V7\n\t- Fixed small issue with syntax coloring\n\n** Syntax\n\t- Added lisp coloring for source blocks marked with lisp or emacs-lisp as the language.\n\tAlso added the following language identifiers to src blocks:\n\t- yaml\n\t- rust\n\t- sql\n\t- r\n\t- html\n\t- go\n\t- ledger\n\t- make|makefile\n  \t- typescript|ts\n\n"
  },
  {
    "path": "messages/1.1.21.org",
    "content": "* 1.1.21\n** Db\n\t- orgFiles was not working, this has been fixed.\n\t  [[https://github.com/ihdavids/orgextended/issues/16][orgFiles does not work]] \n\t- Files with a BOM. I can't easily handle BOMs\n\t  but I now do try to detect it and swap encodings if\n\t  I fail to load the file as utf-8.\n\t- Notifications fix. The notification system was asserting on SCHEDULED: <DATE>\n\t  where date did not have a time.\n** Spreadsheets Preview V8\n\t\n\t- Fix for floating point values.\n\t- VERY early support for gnuplot\n\n\tTo use: \n\t- install gnuplot\n\t- Set your gnuplot path:\n\t\t#+BEGIN_EXAMPLE\n\t\t  \"gnuplot\": \"<fullpathtognuplot.exe>\",\n\t\t#+END_EXAMPLE\n\n\t- Run \"Org Plot Table\" with cursor on the table\n\t- Right now I am just dumping an image and using the inline image show option\n\t  in the future I may change that.\n\n    #+PLOT: title:\"Citas\" ind:1 deps:(3 4) with:lines set:grid\n    |    Sede   |  Max   | H-index |  top  |\n    |-----------+--------+---------+-------|\n    | Sao Paolo |  71.00 |   11.50 |  13.5 |\n    | Stockholm | 134.19 |   14.33 | 16.33 |\n    | Leeds     | 165.77 |   19.68 | 21.68 |\n    | Morelia   | 257.56 |   17.67 | 19.67 |\n    | Chile     | 257.72 |   21.39 | 23.39 |\n    #+TBLFM:$4=$3+2.0\n"
  },
  {
    "path": "messages/1.1.22.org",
    "content": "* 1.1.22\n** Configuration\n    - Added directory globbing support to orgDirs\n    #+BEGIN_EXAMPLE\n       \"c:\\\\Users\\\\ihdav\\\\notes\\\\**\\\\test\\\\\"\n    #+END_EXAMPLE\n\n    This will find valid org extensions in all test sub folders of the path.\n    CAUTION: This will slow down sublime start times with overly large search space!\n\n** Spreadsheet Preview V9\n\n\t- GPU Plot support extended: file option now allows for several output formats:\n\t\t- file.txt  - dumb option in gnu plot.\n\t\t- file.html - canvas option in gnu plot.\n\t\t- file.jpg  - jpeg option in gnu plot.\n\t\t- file.png  - png option in gnu plot.\n\t\t- file.svg  - svg option in gnu plot.\n\t\t- file.ps   - postscript option in gnu plot.\n\t\t- file.gif  - gif option in gnu plot. \n\n\t- GPU Plot\n\t\t- Added include:header to include header row in data (you have to account for it in your plot)\n\t\t- Added using statement to allow you to write your own full using statement rather than just the style: \n\t\t- Improved quoting, spaces in fields are accounted for and quoted.\n\t\t- Improved indent of RESULTS block.\n\n    #+PLOT: title:\"Citas\" include:header ind:1 deps:(2 3 4) set:\"key autotitle columnheader\" unset:xtics set:\"auto x\" set:\"boxwidth 0.25\" using:\"using 2:xtic(1), for [i=3:4] '' using i\" set:\"style data histogram\" set:\"xtics nomirror rotate by -45 scale 0\" set:\"style histogram rowstacked\" set:\"style fill solid border -1\" file:plot.png\n\n    |    Sede   |  Max   | H-index |  top  |\n    |-----------+--------+---------+-------|\n    | Sao Paolo |  71.00 |   11.50 |  13.5 |\n    | Stockholm | 134.19 |   14.33 | 16.33 |\n    | Leeds     | 165.77 |   19.68 | 21.68 |\n    | Morelia   | 257.56 |   17.67 | 19.67 |\n    | Chile     | 257.72 |   21.39 | 23.39 |\n    #+TBLFM:$4=$3+2.0\n\n   #+RESULTS:\n   [[file:C:/Users/ihdav/AppData/Roaming/Sublime Text/Packages/OrgExtended/messages/plot.png]]\n\n\n** Source Blocks\n    - PlantUml info in docs.\n    - Added auto image preview mode when creating images using diagram methods.\n\n*** New Source Block type\n    - GraphViz support.\n    - Only dot engine is currently supported.\n    - To use add graphviz path to settings file:\n\n    #+BEGIN_EXAMPLE\n      \"graphviz\": \"C:\\fullpath\\dot.exe\"\n    #+END_EXAMPLE\n\n    Create a source block like so and execute it\n    #+BEGIN_SRC graphviz :file graphviz.png\n     digraph G {\n       a -> b;\n       a -> c;\n       c -> d\n     } \n    #+END_SRC\n\n  \n  \n  \n"
  },
  {
    "path": "messages/1.1.23.org",
    "content": "* 1.1.23\n** Configuration\n  - orgDirs - in 1.1.22 we added support for directory globbing. We have added a little more error handling in 1.1.23 to\n    detect single stars rather than double stars and to not throw in those cases.\n\n    #+BEGIN_EXAMPLE\n      D:\\mypath\\**\\   - This is supported\n\n      D:\\mypath\\*\\   - This is NOT supported\n    #+END_EXAMPLE\n\n** Source Blocks\n    - Improved handling of unsaved files when executing source blocks.\n      NOTE: Sublime WILL save the file for you if it has already been saved, or\n            error out.\n            [[https://github.com/ihdavids/orgextended_docs/issues/5][PlantUml Example Request]] \n             \n*** GraphViz Blocks\n\n    - added engine (neato, dot, etc)\n    - added fmt (jpg, ps, png)\t\n\n    #+BEGIN_SRC graphviz :fmt jpg :engine neato :file graphviz.jpg\n     digraph G {\n       a -> b;\n       a -> c;\n       c -> d\n     } \n    #+END_SRC\n\n*** Ditaa Src Blocks\n    To use:\n    Add the path to ditaa.jar from sourceforge in your settings file:\n\n    #+BEGIN_EXAMPLE\n      \"ditaa\": \"<pathto>/ditaa.jar\",   \n    #+END_EXAMPLE\n\n    Create a source block with your diagram.\n    (Nope, we don't have an artist mode for sublime yet)\n\n    #+BEGIN_SRC ditaa :file ditaa.png\n    +--------+       +----------+\n    | Hello  | ----> | Hello2   |\n    +--------+       +----------+\n    #+END_SRC \n\n    Execute the block and you should now have a diagram!\n\n \n \n  \n  \n"
  },
  {
    "path": "messages/1.1.24.org",
    "content": "* 1.1.24\n** PlantUml\n\t- Fixed bug with working directory that was causing problems when executing as a package."
  },
  {
    "path": "messages/1.1.25.org",
    "content": "* 1.1.25\n** Source Block Diagrams\n  - Non existent subdirs are auto-created\n  - Execute block works on any line inside the source block as well as on the fence.\n  - Evaluating a block on the last line of the file was not inserting the RESULTS tag.\n  - Repeated re-evaluation kept adding newlines at the end.\n  - When evaluating source with a diagram the cursor could move, this is now fixes.\n\n    #+BEGIN_SRC graphviz :file thisdirdoesnotexist/graphviz.png\n     digraph G {\n       a -> b;\n       a -> c;\n       c -> d;\n     } \n    #+END_SRC\n\n   #+RESULTS:\n   [[file:thisdirdoesnotexist\\graphviz.png]]\n\n** Customization\n  - Support single directory wildcards:\n\n  #+BEGIN_EXAMPLE\n    \"orgDirs\": \"C:\\Mypath\\*\\SubFolder\"\n  #+END_EXAMPLE\n\n  Will match a single folder wildcard like so:\n\n  - C:\\Mypath\\foo\\SubFolder\\x.org\n  - C:\\Mypath\\bar\\SubFolder\\y.org\n  - C:\\Mypath\\baz\\SubFolder\\z.org\n\n  Again, this can increase your startup time dramatically. Please use with caution!\n\n** Spreadsheet Preview V10\n  - boxes mode seems to work.\n\n    #+PLOT: title:\"Box\" ind:2 deps:(3 4)  with:boxes file:plot.png\n    |    Sede   |  Max   | H-index |  top  |\n    |-----------+--------+---------+-------|\n    | Sao Paolo |  71.00 |   11.50 |  13.5 |\n    | Stockholm | 134.19 |   14.33 | 16.33 |\n    | Leeds     | 165.77 |   19.68 | 21.68 |\n    | Morelia   | 257.56 |   17.67 | 19.67 |\n    | Chile     | 257.72 |   21.39 | 23.39 |\n    #+TBLFM:$4=$3+2.0\n\n*** Start of Advanced Table Features\n    - Auto computed cells now mostly work.\n      Careful with these in big tables.\n      They only auto compute when you use tab or shift tab\n      to move between cells, arrow keys do not recompute\n    - Row names seem to work work.\n    - Above and Below names seem to work\n    - Symbol rows seem to work\n\n    |   |   a   |   b   |    c     |\n    |---+-------+-------+----------|\n    | # | 0.38  | 0.1   | 0.46     |\n    | # | 0.38  | 0.1   | 0.86     |\n    | # | 0.03  | 0.6   | 0.01     |\n    | * | 0.02  | 0.0   | 0.06     |\n    | ^ | hello | world | namedRow |\n    | * |       | 0.3   |          |\n    |   |       |       |          |\n    | _ | below |       |          |\n    | # | 3.5   | 0.7   |          |\n    | # | 4.5   | 0.9   |          |\n    | # | 4.0   | 0.8   |          |\n    | # | 2.0   | 0.4   |          |\n    | $ | max=5 |       |          |\n    #+TBLFM:$hello=rand()*$world;%.2f::$namedRow=rand();%.2f::$3=rand();%.1f::$below=$3*$max\n\n** HTML Export\n  Fixed issue with 0 blank lines at the top of the file.\n  The comment gathering code was not being initialized properly.\n"
  },
  {
    "path": "messages/1.1.26.org",
    "content": "#+COLUMNS: %ITEM(Task) %Effort(Effort) %TODO(Todo) %DEADLINE(Deadline) %ALLTAGS(Tags) %TIMESTAMP(Time) %TIMESTAMP_IA(Inactive) %PRIORITY(Priority)\n\n* 1.1.26                                                                  :a:\n** Configuration\n\t- improvements to orgdir globbing / error handling / parsing thanks to Anti-Distinctlyminty \n** DONE Source Blocks\n   :PROPERTIES:\n     :EFFORT: 2d\n   :END:\n\tNew languages colored in source blocks:\n\t\t- clojure\n\t\t- bat|cmd\n\t\t- org\n\t\t- pascal\n\t\t- actionscript\n\t\t- applescript\n\t\t- dtd\n\t\t- haskell\n\t\t- markdown|md\n\t\t- groovy\n\t\t- regexp\n\t\t- ruby\n\t\t- restructuredtext\n\t\t- xsl\n\t\t- scala\n\t\t- hex\n\t\t- erlang\n\t\t- diff\n\t\t- d\n\t\t- css\n\t\t- cmake\n\t\t- asp\n\t\t- json\n\t\t- r \n\n** Folding\n\t- Block folding inside a block was driving me nuts\n\t  I have changed it so you can only fold a dynamic block or a source block from its header\n\t  If this bothers you, we can make this configurable, just let me know.\n\n** Properties\n   DEADLINE: <2021-03-09 Tue 20:55> \n   :PROPERTIES:\n     :EFFORT: 2d\n   :END:\n\n\t- New Command: \"Org Create Heading Id\"\n\t  This will add a UUID ID to the current heading.\n\t- Db handling of ids reworked a little to support jumping to an ID or a CUSTOM_ID\n\t- New Command: \"Org Insert Effort\"\n\t  Must be org duration format. Will insert an effort property\n\t  defaultEffortEstimateUnit - setting (defaults to d) can be used to set the default effort unit \n\n** Spreadsheets Preview V11                                               :tag:\n   :PROPERTIES:\n     :EFFORT: 4h\n   :END:\n    <2021-03-09 Tue 14:53> \n\n\t- remote function can now take a custom id or id as per:\n\t  [[https://lists.gnu.org/archive/html/emacs-orgmode/2010-01/msg00420.html][Remote Table References]] \n\t- Nodes now have a table property that lists the position of the first table in the node.\n    - It doesn't really work well because the existing table system requires a view, which means that we have to load the file\n      which cannot easily be done during the execution of a formula. This means you can get odd tab swaps if you have a remote reference\n      and the file is not opened. I will have to think about another way of handling this in the future.\n\n** [#B] ColumnView Dynamic Block\n   :PROPERTIES:\n     :EFFORT: 1d\n   :END:\n   [2021-03-09 Tue 11:00]\n\n   Part of the reason for the tags, priorities and effort markers in these release notes is to show the new column view\n   dynamic block. It is still in its infancy. It has none of the summary functionality of the real\n   column view. It also only has a limited set of handlers. It can access properties and has the following\n   built in handlers:\n\n\n   - ALLTAGS\t  All tags, including inherited ones.\n   - CLOSED\t    When was this entry closed?\n   - DEADLINE  \tThe deadline timestamp.\n   - FILE      \tThe filename the entry is located in.\n   - ITEM      \tThe headline of the entry.\n   - PRIORITY \tThe priority of the entry, a string with a single letter.\n   - SCHEDULED \tThe scheduling timestamp.\n   - TAGS     \tThe tags defined directly in the headline.\n   - TIMESTAMP \tThe first keyword-less timestamp in the entry.\n   - TIMESTAMP_IA \tThe first inactive timestamp in the entry.\n   - TODO         \tThe TODO keyword of the entry.\n\n   Parameters that work:\n\n   - hlines\n   - maxdepth\n   - id (local, global, ID value, file:)\n   - indent\n   - skip-empty-rows\n   - exclude-tags\n\n   Parameters that do not yet work:\n\n   - match\n\n\t#+BEGIN: columnview  :hlines nil :id global :indent t :maxdepth 2 :skip-empty-rows t :exclude-tags (ExcludeMe)\n   | Task                       | Effort | Todo | Deadline             | Tags  | Time                 | Inactive             | Priority |\n   | 1.1.26                     |        |      |                      | a     |                      |                      |          |\n   | ..Source Blocks            | 2d     | DONE |                      | a     |                      |                      |          |\n   | ..Folding                  |        |      |                      | a     |                      |                      |          |\n   | ..Properties               | 2d     |      | 2021-03-09 Tue 20:55 | a     |                      |                      |          |\n   | ..Spreadsheets Preview V11 | 4h     |      |                      | a tag | 2021-03-09 Tue 14:53 |                      |          |\n   | ..ColumnView Dynamic Block | 1d     |      |                      | a     |                      | 2021-03-09 Tue 11:00 | B        |\n\t#+END:\n\n\tI am slowly driving towards being able to do this:\n\t[[https://www.youtube.com/watch?v=5ViUBaarsbw][Gantt Charts in Org Mode]] \n\n\tI don't have column mode yet, but we will get something like it eventually.\t\n\n*** ColumnView Beyond Max Depth\n** Excluded Because Of Tag                                                :ExcludeMe:\n* Empty"
  },
  {
    "path": "messages/1.1.27.org",
    "content": "\n\n* 1.1.27\n** Archiving\n\t- Fixed a bug where ARCHIVE_TIME was missing a colon at the front when inserted.\n\t- Switched archiving to save as utf-8 by default to avoid some of the unicode problems I have been running into.\n\n** Editing\n\t- Org Insert Now Active     - Inserts right now as an active datetime \n\t- Org Insert Now Inactive   - Inserts right now as an inactive datetime\n\t- Org Insert Date Active    - Pops up the date picker to insert an active datetime\n\t- Org Insert Date Inactive  - Pops up the date picker to insert an inactive datetime\n\n\t- Dynamic Block Snippet:\n\t#+BEGIN_EXAMPLE\n\t  <b\n\t#+END_EXAMPLE\n\n\t- Example blocks are now orgmode syntax inside the block.\n\n** Spreadsheet Preview V11\n\n\t- date() function improved to auto convert strings and cells to OrgDate objects.\n\t- duration() added to handle columnview duration syntax. This is compatible with adding to dates.\n\t- if statements work although they do not follow the calc style, here we are diverging a little at the moment\n\t  due to the fact that our backend is really python ast. \"If\" is a keyword, I can't easily use it like a function without playing\n\t  some games I am not sure I am ready to do.\n\t- percentages can be treated like numbers much like they can in orgmode\n\n\t|           a            |           b            | c  |           d            | e  | f  |  g  |  h   |\n\t|------------------------+------------------------+----+------------------------+----+----+-----+------|\n\t| <2021-03-10 Wed 22:25> | <2021-03-09 Tue 22:25> | 5d | <2021-03-15 Mon 22:25> | 5d | 50 | 20% | 10.0 |\n    #+TBLFM:@2$2=date($-1)-1::@2$4=date(@2$1)+duration($-1)::@2$5=$3 if True else 5::@2$9=$-2*$-1\n\n** Columnview\n\t- Empty properties still make a row in the column view (allowing you to setup additional rows for calculations)\n\t- Table format blocks can live after the end marker on a dynamic block. This is not org standard but it lets us\n\t  build formulas for generated tables which can be really handy on clock tables and columnviews (building timesheets and project plans)\n\t- Org syntax is turned on inside a dynamic block now allowing tables to be highlighted inside the block.\n\n    #+COLUMNS: %ITEM(Task) %Effort(Effort) %TESTING(Testing)\n\t#+BEGIN: columnview\n   | Task                    | Effort | Testing |\n   | 1.1.27                  |        |         |\n   | Archiving               |        |         |\n   | Editing                 |        |         |\n   | Spreadsheet Preview V11 |        |         |\n   | Columnview              |        |         |\n\t#+END:\t\n   #+TBLFM:@2$9=5\n\t"
  },
  {
    "path": "messages/1.1.28.org",
    "content": "* 1.1.28\n** Dynamicblocks\n\t- Params structure is now a PList class and has:\n\t\t- Get(name,default) :: Returns the parameter as a string value\n\t\t- GetInt(name,default) :: Returns the parameter as an int value\n\t\t- GetFloat(name,default) :: Returns the parameter as a float value\n\t\t- GetList(name,default) :: Returns the parameter as a list of strings\n\t\t- GetIntList(name,default) :: Returns the parameter as a list of ints\n\n\t\tPlists now support double quotes \"\" and () brackets delimiting parameter values.\n\n** Image Links\n\t- Fixed an assert that could happen when backing image was removed.\n\t- Sublime will now show the non image icon as expected.\n\n\t- ORG_ATTR comments on image links with plists specifying image dimensions\n\t  are now respected in inline sublime visualization of an image.\t\n\n\t#+BEGIN_EXAMPLE\n    #+ORG_ATTR: :width 700\n\t#+END_EXAMPLE\n\n** Spreadsheets Preview V12\n\tMostly quality of life improvements in this release.\n\t\n\t- Table cache works across files properly now.\n\t- Turned off highlight updates during formula execution\n\t  it was costing us during the update needlessly.\n\t- Improved function table, symbol table and constants table construction.\n\t  They are now lazy loaded and reused as much as possible for all tables\n\t  reducing the costs associated with highlighting cells and navigation.\n\t- In the interest of supporting only pay for what you use.\n\t  Dynamic table extensions (user added functions) are reloaded ONCE when\n\t  the tables are first constructed, if you are developing a function for\n\t  table handling you can now turn on:\n\t  #+BEGIN_EXAMPLE\n\t    \"forceLoadExternalExtensions\": True\n\t  #+END_EXAMPLE \n\n\t  In your settings to dynamically reload your extension all the time.\n\t  This reduces the cost of building the function table.\n\n\t- Added abs function\n\n\t  |  a   | d |    |\n\t  |------+---+----|\n\t  | 0.50 | 2 | 51 |\n\t  | 0.46 | 3 | 56 |\n\t  | 0.19 | 4 |  2 |\n\t  | 0.02 | 5 |  3 |\n\t  | 0.49 | 6 |  4 |\n\t  | 0.64 | 7 |  5 |\n    #+TBLFM:$1=rand();%.2f::$2=abs(-@#)::$3=remote(\"my-table-test\",$2)\n\n    - Improved remote() function, it no longer requires you to open a view / tab although\n      the file has to have been parsed so should be in your orgDirs / orgFile list.\n    - Added the ability to add dynamic symbols as well as functions.\n\n      To use add a python file in your User folder like so:\n      #+BEGIN_EXAMPLE\n    \t.../Packages/User/orgtable/mysymbols.py\n      #+END_EXAMPLE\n\n      And add the symbols you would like exposed for use in your tables.\n      #+BEGIN_SRC python\n        def AddSymbols(symbolTable):\n        \tsymbolTable['pi'] = 3.14159268\n        \tsymbolTable['c']  = 299792458\n      #+END_SRC\n\n** Source Blocks\n\t- gnuplot language added to syntax, to use install the GNU Plot package.\n\n** Folding\n\t- \"Org Fold Others\" - New command that folds all other headings but the immediate part of the tree you are on."
  },
  {
    "path": "messages/1.1.29.org",
    "content": "* 1.1.29\n   Core Idea: Add GNU Plot Script Blocks\n\n   - [x] Add a syntax for gnu plot script blocks if one does not already exist\n   - [x] Add a src handler to execute these script blocks.\n** Spreadsheets Preview V13\n\n    - Fixed a bug with TBLFM appearing after a END marker on dynamic blocks\n    - Fixed a bug with if statements and equals signs in TBLFM blocks\n    - Fixed a bug with tables where it would look up the properties on the root node of the file.\n      this would cause an assert.\n\n** GNU Plot Script Block\n\n   We now have a GNU Plot script block and source handler.\n   We have a very limited set of source hanlders.\n\n   Here is some gnu plot code that draws a sine wave if executed and\n   gnuplot can be found in your settings file. The requirements are the\n   same as those for table plotting.\n   #+BEGIN_SRC gnuplot :file gantt-table.png\n    # We don't need a key (or legend) for this simple graph.\n    set key off\n \n    # Set the title for the graph.\n    set title \"Sine against Phase\"\n  \n    # We want the graph to cover a full sine wave.\n    set xrange [0:6.28]\n  \n    # Set the label for the X axis.\n    set xlabel \"Phase (radians)\"\n  \n    # Draw a horizontal centreline.\n    set xzeroaxis\n  \n    # Pure sine wave amplitude ranges from +1 to -1.\n    set yrange [-1:1]\n  \n    # No tick-marks are needed for the Y-axis .\n    unset ytics\n  \n    # Plot the curve.\n    plot sin(x) \n   #+END_SRC\n\n  #+RESULTS:\n  [[file:gantt-table.png]]\n\n  - Params for src blocks have been converted to use the new PList system added in 1.1.28\n  - Source Blocks now have a PreProcessSourceFile() method that allows for injection of file and other paramters into the source block.\n\n  - GNU Plot is the first module to start implementing the data source mechanism:\n    The following example generates a graphed line line by feeding the data in my-table into gnu plot using babel like\n    mechanics. NOTE: Babel is in its infancy in our system. We have source handlers for python, powershell, gnuplot, ditaa, plantuml, graphviz and that is it.\n    ONLY GNU Plot can read from tables at this time. This will change.\n\n  #+NAME: my-table\n  | 1 | 2 |\n  | 2 | 3 |\n  | 3 | 4 |\n\n   #+BEGIN_SRC gnuplot :var DATA=my-table :file my-table.png\n    plot \"$DATA\" using 1:2 with lines title \"hello\"\n   #+END_SRC\n\n  #+RESULTS:\n  [[file:my-table.png]] \n\n\n** Powershell Block Execute Bug\n\t- this was using the OrgExtended package dir as it's cwd\n\t  which was causing problems when running as a package. FIXED.\n\n"
  },
  {
    "path": "messages/1.1.3.org",
    "content": "* 1.1.3\n\t- Fixing regression in 1.1.2\n\t  New shared keybinding command was being instantiated improperly"
  },
  {
    "path": "messages/1.1.30.org",
    "content": "* 1.1.30\n\tCore Idea: Testing pass on tables to ensure what is there is relatively usable.\n\n** Spreadsheet Preview V14\n\t- added:\n\t\t- bool(cell)\n\t\t- int(cell)\n\t\t- float(cell) \n\t\tto convert string cells to boolean, ints and floats explicitly if desired\n\n\t- added highlight(cell,color,text) which highlights a cell a specific color for you\n\t- added passed(test) that will highlight a target cell\n\t  green or red and write PASSED or FAILED into the cell. We are using this for unit testing at the moment.\n\n\t- added unit tests org file for tables.\n\t- Execute table now restores the cursor after the evaluation of the table improving usability.\n\t- Fixed assert when cursor was on a formula during table formula execution due to call \n\t  to table_editor_align requiring the cursor be in the table\n\t- Fixed a bug with <= not evaluating properly next to a cell name ($1<=$2 would fail)\n\t- Added Org Execute All Tables - scans the whole file for tables and executes all of them.\n\t- Improved all date functions handling of datestrings\n\t- Fixed double digit row index parsing, @10$2 was failing to parse properly sometimes.\n\t- Fixed a bug with vmedian where it would sometimes not compute the median!\n\n\t- More docs including a little view of the new highlight in action in a unit test capture: (at the bottom of the tables doc)\n\t[[https://github.com/ihdavids/orgextended_docs/blob/master/tables.org][Tables]]\t\n\n\t- New documentation on adding the emacs constants.el to your table experience in docs\n\t[[https://github.com/ihdavids/orgextended_docs/blob/master/mathconstants.org][Math Constants]] \n\n** GNU Plot\n\t- Calling \"Org Plot Table\" on the #+PLOT: header rather than the table would cause problems."
  },
  {
    "path": "messages/1.1.4.org",
    "content": "* 1.1.4\n** Editing\n\t- Changed default keybinding. Capture is now Alt+o z to mirror neovintageous mode with Z\n\t\t(it also did not work before due to other Alt+o c ... commands)\n** Stability\n\t- Removed legacy automatic copy of settings files to User folder now that we are using\n\t  the new dual pane settings mechanic. This was causing an assert on startup for \n\t  users on ST3.\n\t- Active timestamps with ranges were not showing up in the agenda properly.\n\t  This was due to how the timestamps were querried. Should now be fixed.\n\t- Closed Scheduled timestamps would show up in the week view even after the scheduled date.\n\t  this was a byproduct of the new scheduled behaviour and has been fixed. When closed\n\t  the items will show up ONLY for the date they were scheduled. (They do not reflect)\n\t  the date at which they were closed. In the future I hope to make that happen. NOTE:\n\t  they do not show up in the day view at the moment. I will work to improve that in a future\n\t  release.\n\t- Toggling a task to done with a recurring timestamp will set the LAST_REPEAT and LOGBOOK\n\t  entries properly now and will update the base timestamp."
  },
  {
    "path": "messages/1.1.5.org",
    "content": "* 1.1.5\n** Stability and Performance\n\t- Fixed some issues in the agenda with old SCHEDULED: values\n\t\tWe would search forward in time forever trying to find\n\t\ta match in the agenda. This could make org files with REALLY old\n\t\tSCHEDULED tasks that were not closed take a long time to render in the agenda.\n\n\t\tI have now capped it. 4 Months is the default:\n\t\tThis goes for deadlines, active timestamps and scheduled values.\n\n\t\tIn addition I have enabled some caching for following repeat rules\n\t\twhich should improve overall performance here.\n\n\t\t#+BEGIN_EXAMPLE\n\t\tagendaMaxScheduledIterations: 120\n\t\t#+END_EXAMPLE\n\n\t- Working to improve handling of dates without times in the agenda.\n\t  This could cause some assertions in some of the new scheduled and deadline handling systems\n\t  I believe I have all the asserts now but I am working on ensuring intuitive behaviour.\n\n    - Fixed display of plain (no time) DEADLINES, they now show the due date properly\n    - Fixed closing of plain (no time) DEADLINES, they would assert before when trying to update the time.\n\t\n\n"
  },
  {
    "path": "messages/1.1.6.org",
    "content": "* 1.1.6\n\t- Added keybindings utility function to help author docs.\n\t- Bug found with active timestamps not recurring properly datetime conversion was not working properly\n"
  },
  {
    "path": "messages/1.1.7.org",
    "content": "* 1.1.7\n** Editing\n\t- Request: [[https://github.com/ihdavids/orgextended/issues/13][Checkboxes in Headings]]\n\n\t- Checkbox summaries at the END of a heading but before tags are now supported and will be updated when\n\t  a checkbox is toggled:\n\n*** TODO [#A] Heading with summary [33%]   :TAG:\n\t- [ ] A\n\t- [ ] B\n\t- [x] C\n\t    - [x] D\n\n** Agenda\n    - Request: [[https://github.com/ihdavids/orgextended/issues/10][Agenda Items Not Showing]]\n\t- Org Agenda will reload all open buffers to pick up agenda items in unsaved buffers"
  },
  {
    "path": "messages/1.1.8.org",
    "content": "* 1.1.8\n** Editing\n\t- DWIM editing of numbered lists has improved slightly\n\t  Fixed some bugs with lists at the end of a buffer\n\t  or with a blank line above the list.\n    - DWIM editing of standard unordered lists (not checkbox)\n      is now supported properly.\n    - Indent and DeIndent somewhat work on lists (tabs vs spaces are\n      still a little problematic) "
  },
  {
    "path": "messages/1.1.9.org",
    "content": "* 1.1.9\n** Editing\n*** Improved DWIM Additions to Numbered lists   \n    A numbered list preceded by a normal list was confusing\n    DWIM extension. The system was putting the new entry\n    above the unordered list.\n\n    #+BEGIN_EXAMPLE\n    - This would disrupt DWIM editing of the list below\n    - DWIM was finding this list and thinking it was part\n    - of the numbered list.\n    1. I am extending this list\n    2. This is the list I am extending\n    #+END_EXAMPLE   \n\n    The same thing could happen for example blocks or src blocks.\n        \n*** Improved Alternate Additions to Lists\n    - Ctrl+Shift+Enter is an extended insert\n      For numbered lists it will extend the list vs insert where you are.\n    - This should now work for all the list types.\n\n*** Org Sort List\n    - Works when cursor is on list types.\n    - Will sort the list aphabetically\n\n** Agenda\n    - Loose Tasks View was sometimes not detecting top level loose tasks\n\n"
  },
  {
    "path": "messages/1.2.0.org",
    "content": "* 1.2.0\n\tCore Idea: I am considering the spreadsheet feature out of preview now.\n               most of the core org features with spreadsheets are now supported.\n               While there are a ton of functions yet to support to have calc equivalence\n               I believe what we have is a pretty good line in the sand to say we have something\n               some usable.\n\n** Spreadsheets Beta\n  More core functions\n\n  - tanh\n  - cosh\n  - sinh\n  - atanh\n  - acosh\n  - asinh\n  - atan\n  - acos\n  - asin\n  - degrees\n  - radians\n  - sqrt\n  - pow\n  - log\n  - log10\n  - log2\n\n  Added unit tests for these functions.\n\n** Editing\n  - New Command: \"Org Insert Archive Tag\" will add the :ARCHIVE: Tag to a node. Not currently bound to a key.\n  - ARCHIVE tag gets filtered out by default in agenda. This means archived TODO's do not accidentally show up if you have a FILETAG on your archive file.\n  - Fixed a bug with moving headings up and down when the heading is at the end of the file.\n \n** Tags\n  - FILETAGS comment is now respected properly as an inheritied tag on a heading. \n\n** Notifications\n  - Notifications system now respects the ARCHIVE tag.\n"
  },
  {
    "path": "messages/1.2.1.org",
    "content": "* 1.2.1\n\n\tJust like 1.2.0 was focused on supporting tables 1.3.0 has a focus on better\n\tbabel support.\n\n\tCore Idea for 1.2.1: Input - More language handlers supporting table and list data sources.\n\n\tThis is a fairly simple first step into the world of babel. The GNU Plot handler\n\tpaved the way for this we are just adding the same support to the other handlers.\n\n\tRight now we only really have python and powershell handlers anyways.\n\tAs this matures we will document how to add your own language handlers as well\n\tas extend the list of supported languages.\n\n\tThere is still more to do with input. This gets us 30% of the way to handling input sources.\n\tWe still have to improve our plist handle spaces a little better and then handle the various\n\tways that variables can be set for handlers vs the local mechanism. We also need to handle\n\tsource blocks being the source of data for other source blocks. We are going to hold off on that\n\tuntil we have a slightly better handle on the various execution types for source blocks.\n\n** PlantUML\n\t- Thanks to Antidistinctlyminty for improving file handling in the plantuml source block handler.\n\t  The module not respects the :file tag properly. This was actually fixed in the 1.2.0 release but\n\t  went unmentioned.\n\n** Lists\n\t- fixed a bug with unordered list sorting including source blocks.\t\n\n** Source Block Output Formatting\n\t- In preparation for working on output formatting in a future release (for babel)\n\t  we have tweaked the output formatting to respect indents a little better when executing source blocks.\n\n** Python\t\n\tPython now supports tables as data sources. True babel execution\n\twould auto format the output or provide controls over how we handle the output\n\tbut... these are our first steps here.\n\t\n\t#+NAME: p-data\n\t| a | b | c | d | e |\n\t|---+---+---+---+---|\n\t| 1 | 2 | 3 | 4 | 5 |\n\t| 6 | 7 | 8 | 9 | 0 |\n\n\t#+BEGIN_SRC python :var DATA=p-data\n\t  print(str(DATA))\n\t#+END_SRC\n\n    #+RESULTS:\n    [['a', 'b', 'c', 'd', 'e'], [1, 2, 3, 4, 5], [6, 7, 8, 9, 0]]\n\n\n    Basic variables are also somewhat operational.\n\n\t#+BEGIN_SRC python :var DATA=5\n\t  print(str(DATA))\n\t#+END_SRC\n\n   #+RESULTS:\n   5\n   \n \n** Powershell\n    #+BEGIN_SRC powershell :var DATA=p-data\n      $DATA | % {\"$_\"} \n    #+END_SRC\n\n    #+RESULTS:\n   a b c d e\n   1 2 3 4 5\n   6 7 8 9 0\n\n** List Data Sources Within a File.\n\tSource blocks are also getting list as as data sources:\n\tNotice that the indented item is excluded this is normal org behaviour with lists.\n\n  #+NAME: l-data\n  - b\n  - a\n  \t- a\n  - c\n\n  #+BEGIN_SRC python :var DATA=l-data\n    print(str(DATA))\n  #+END_SRC\n\n   #+RESULTS:\n   ['b', 'a', 'c']\n    \n   #+BEGIN_SRC powershell :var DATA=l-data\n      ,$DATA \n   #+END_SRC\n\n   #+RESULTS:\n   b\n   a\n   c\n\n** Numbered List Data Sources Within a File.\n\tNumbered lists are also now potential data sources:\n\n\t#+NAME: n-data\n\t1. b\n\t2. a \n\t3. c\n\t  4. 4 \n  \n  #+BEGIN_SRC python :var DATA=n-data\n    print(str(DATA))\n  #+END_SRC\n\n   #+RESULTS:\n   ['b', 'a', 'c']\n    \n   #+BEGIN_SRC powershell :var DATA=n-data\n     ,$DATA\n   #+END_SRC\n\n   #+RESULTS:\n   b\n   a\n   c\n"
  },
  {
    "path": "messages/1.2.10.org",
    "content": "* 1.2.10\n  Dateutil seems to have vanished on package control. This was causing some people to have problems installing.\n  I have been forced (for now) to embed dateutil into orgextended so we can continue chugging along.\n\n  My hope is that in doing this it will fix the ST3 issues we have been seeing."
  },
  {
    "path": "messages/1.2.11.org",
    "content": "* 1.2.11\n  - Trying to get dateutil to operate well as a package inside OrgExtended. Had some problems with six.py's location.\n  - I believe this will fix it."
  },
  {
    "path": "messages/1.2.12.org",
    "content": "* 1.2.12\n  - Thankfully the problem with dateutil has been discovered by wbond.\n    we should now be able to install again once dateutil clears.\n    I have removed the dependency on an internal dateutil."
  },
  {
    "path": "messages/1.2.13.org",
    "content": "* 1.2.13\n  - Fixed a fairly major regression with capture templates.\n\n  1. Capture snippets now live in Packages\\User\\orgsnippets folder (for consistency with other extension types)\n  2. A bug was fixed which would fail to find a snippet in some cases.\n  "
  },
  {
    "path": "messages/1.2.14.org",
    "content": "* 1.2.14\n\n** Color Scheme Generator\n  - FIXED: Improved color scheme generator. It did not handle comments so Solarized Dark as throwing.\n    [[https://github.com/ihdavids/orgextended/issues/29][Issue]] \n\n** Max Header Depth In Syntax Coloring\n  - This has been extended to 10 as per request from antidistinctiminty (Was 7 previously)\n\n  \n"
  },
  {
    "path": "messages/1.2.15.org",
    "content": "* 1.2.15\n  :PROPERTIES:\n    :header-args: :noweb-ref includeme \n  :END:\n\n\n  1.2.15 introduces the start of noweb like macro support to our babel offering.\n\n  The contents of source blocks can be dynamically included \n  from remote blocks. (Much like a macro the code is pasted into the block)\n\n  References can be done by parameters or by name.\n  The noweb-ref parameter allows you to define the target of a reference much like a name would.\n\n  Since the source of a noweb reference can be named in a parameter this means that property parameters \n  can apply to a set of source blocks that each has a part of the full snippet.\n  In this case snippets will be pasted in the order they appear in your file.\n\n\n  #+BEGIN_SRC python \n      print(\"Hello World\")\n  #+END_SRC\n  \n  #+BEGIN_SRC python\n      print(\"And again!\")\n  #+END_SRC\n  \n  #+BEGIN_SRC python\n      print(\"Even More!\")\n  #+END_SRC\n\n  #+BEGIN_SRC python :noweb yes\n      <<includeme>>\n      <<by-name>>\n      <<by-results(x=5)>>\n  #+END_SRC\n  #+RESULTS:\n  : Hello World\n  : And again!\n  : Even More!\n  : By-Name\n  : By-Results: 5\n\n* By-Name Source Block\n\n  In the example above we are referencing the blocks by a name in the parameter field.\n  Here we are referencing the source block by the name of the block.\n\n\n    #+NAME: by-name\n    #+BEGIN_SRC python\n      print(\"By-Name\")\n    #+END_SRC\n\n\n    If you use () in your reference you are requesting the results of the block be pasted rather than the block itself.\n    This can be useful but can easily get complicated if abused. So use with restraint.\n     \n\n    #+NAME: by-results\n    #+BEGIN_SRC python :var x=5 :results raw\n      print(\"print('By-Results: \" + str(x) + \"')\")\n    #+END_SRC\n"
  },
  {
    "path": "messages/1.2.16.org",
    "content": "* 1.2.16\n** Source Blocks\n\t- Improved noweb error reporting and handling\n\t- Added \"builtinSourceBlockHandlers\" setting allowing users \n\t  to override one of the built in source handlers with their own.\n\n** Cmd Source Block Support\n\n\tBatch files do not support arrays so we play some games.\n\tVAR_width and VAR_height are defined to help with iteration and\n\tarray like variables are defined a value at a time VARNAME[r#,c#]\n\n\t#+NAME: table-source\n\t| a | b | c | d | e |\n\t| 1 | 2 | 3 | 4 | 6 |\n\n\t#+BEGIN_SRC cmd :var x=5 :var DATA=table-source\n        setLocal enableDelayedExpansion\t\n\t\techo Hello World %x%\n\t\tFOR /L %%r IN (1,1,%DATA_height%) DO (\n\t\t    FOR /L %%c IN (1,1,%DATA_width%) DO (\n\t\t\techo|set /p dummy=!DATA[%%r,%%c]!\n\t\t)\n\t\techo .\n\t\t)\n\t#+END_SRC\n\n   #+RESULTS:\n   : Hello World 5\n   : 'a''b''c''d''e'.\n   : 12346.\n\n*** Cmd Return Values\n\n\tValue execution is kind of funny. Batch files can reach out and touch a parent parameter var.\n\tThe return value is the first. Set it like so:\n\n\t#+BEGIN_SRC cmd :results value\n\t  echo \"hi\"\n\t  set \"%~1=5\"\n\t#+END_SRC\n\t\n    #+RESULTS:\n    : 5\n"
  },
  {
    "path": "messages/1.2.17.org",
    "content": "* 1.2.17\n\n  More source block handlers!\n\n** Alias Support in Source Blocks\n    bat = cmd\n    js  = javascript\n\n** SH source blocks kind on windows with WSL (assuming you have WSL setup)\n\n\tThis is not yet tested on any other platform!\n\n\t#+NAME: in-table\n\t| a | b | c | d | e |\n\t| 1 | 2 | 3 | 4 | 5 |\n\n  #+BEGIN_SRC bash :var DATA=in-table\n   echo \"$DATA\" \n  #+END_SRC\n  #+RESULTS:\n   : a  b   c   d   e\n   : 1  2   3   4   5\n\n\n  Not yet sure if value types work like this in emacs.\n  I may need to adjust this.\n\n  #+BEGIN_SRC sh :results value\n  return 5\n  #+END_SRC\n  #+RESULTS:\n  : 5\n\n** Javascript source blocks require node.js\n    Set nodejsPath in your settings file.\n\n    #+BEGIN_SRC javascript :var x=5\n        console.log('Hello world ' + x);\n    #+END_SRC\n\n   #+RESULTS:\n   : Hello world 5\n\n\n   #+BEGIN_SRC js :var DATA=in-table :results table\n     console.log(DATA);\n   #+END_SRC\n   #+RESULTS:\n   | a | b | c | d | e |\n   | 1 | 2 | 3 | 4 | 5 |\n"
  },
  {
    "path": "messages/1.2.18.org",
    "content": "* 1.2.18\n** Syntax Highlighting\n\n  Beancount is now supported for syntax highlighting in source blocks\n\n** Html Exporter\n\t- Fixed issue with exporting unordered lists.\n\t- Org Export Subtree as Html now handles HTML_STYLE properly\n\t- Org Export Subtree as Html will export <filename>_subtree.html rather than as a temp file.\n\t- \"htmlExportPartialCheckboxChecked\": False - Will export partial checkboxes as unchecked vs checked."
  },
  {
    "path": "messages/1.2.19.org",
    "content": "* 1.2.19\n** Html Exporter\n\t- Exporter now exports as utf-8 to avoid problems with unicode characters.\n\t- Fixed a type in the postamble handling\n\t- The exporter can handle \"* NOTE :\" malformed headings and not crash.\n\t- The collapse system had problems computing the correct max-height on \n\t  startup and nodes would not fold properly.\n\t- Added plain style to htmlstyles"
  },
  {
    "path": "messages/1.2.2.org",
    "content": "* 1.2.2 - Improving Babel Input\n** Worklog\n    - \"Org Show Worklog\" will generate our worklog to a new buffer\n\n** Babel PList Params\n    Quotes work for variables in plists\n    \n    #+BEGIN_SRC python :var x=\"hello world\"\n    print(x)      \n    #+END_SRC\n\n   #+RESULTS:\n   hello world\n  \n** Property Parameters\n    All of the following are now possible sources of variables\n    In a parameter block, including the local fence variable\n\n    This required fixing the properties parser to understand multiple semi colons\n    in a variable list.\n\n  :PROPERTIES:\n  :header-args:           :var g=global\n  :header-args:python:    :var x=5\n  :var: v=10\n  :END: \n\n  #+PROPERTY: header-args: :var y=11\n  #+PROPERTY: header-args:python: :var z=12\n  \n  #+BEGIN_SRC python :var p=42\n    print(v)   \n    print(x)   \n    print(y)   \n    print(z)\n    print(p)\n    print(g)\n  #+END_SRC \n\n   #+RESULTS:\n   10\n   5\n   11\n   12\n   42\n   global\n   \n** Output As Table\n    I have started working on output handling. Right now things are pretty manual. \n\n    Things that work:\n\n    :results table - This will try to format your output as a table\n    :results verbatim - This will output things in verbatim format\n    :file - The presence of a file parameter will cause the system to output a link to the file.\n            This does not work for script output yet only for ditaa, plantuml and graphviz modules that naturally want to output to a file.\n\n    Things that do not work:\n    :file - for script blocks, that is comming\n    :results - auto detection of tables\n    :results - value\n    a bunch of other stuff...\n\n    #+NAME: in-table\n    | a | b | c | d | e |\n    | 1 | 2 | 3 | 4 | 5 |\n    | 6 | 7 | 8 | 9 | 0 |\n   \n   #+BEGIN_SRC powershell :var DATA=in-table\n     $DATA | %{\"$_\"}\n   #+END_SRC\n\n   #+RESULTS:\n   | a | b | c | d | e |\n   | 1 | 2 | 3 | 4 | 5 |\n   | 6 | 7 | 8 | 9 | 0 |\n\n   #+BEGIN_SRC python :var DATA=in-table :results table\n     print(str(DATA))\n   #+END_SRC\n\n   #+RESULTS:\n   | a | b | c | d | e |\n   | 1 | 2 | 3 | 4 | 5 |\n   | 6 | 7 | 8 | 9 | 0 |\n\n\n   #+BEGIN_SRC python :results verbatim\n     print(\"Hello World This Is Tablular?\")\n   #+END_SRC\n\n   #+RESULTS:\n   : Hello World This Is Tablular?\n\n\n   #+BEGIN_SRC plantuml :file out.png\n     a -> b\n     b -> c\n   #+END_SRC\n\n   #+RESULTS:\n   [[file:out.png]]\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "messages/1.2.20.org",
    "content": "* 1.2.20\n** Html Exporter\n\tContinuing the Babel adventure we add support for :exports [code,results,both,none]\n\n\tNOTE: this means that the default parameters for babel header args are now more important\n\t      Before we would default to exporting both code and results, now, due to the defaults set in our settings\n\t      we only export code. This is in complaince with org mode defaults. If you would like to change that\n\t      add the key to your settings file and set the defaults as you need:\n\n\t#+BEGIN_SRC python :exports both\n\t print(\"hi\") \n\t#+END_SRC\n\n   #+RESULTS:\n   : hi\n\n\n\t#+BEGIN_EXAMPLE\n      \"orgBabelDefaultHeaderArgs\": \":session none :results replace :exports code :cache no :noweb no\",\n\t#+END_EXAMPLE\n\n*** Skip Source \n\n\tSome source formats it is handy to always skip the source and only include results.\n\tWe have added a list of formats where this overrides the defaults (listed above) for convenience:\n\n\t#+BEGIN_EXAMPLE\n    \"htmlDefaultSkipSrc\": [\"plantuml\",\"graphviz\",\"ditaa\",\"gnuplot\"], \n\t#+END_EXAMPLE\n\n\tRemove this list if you would like to always have explicit control with the exports keyword.\n\n*** Source Block Execution on Export\n\n\tThis is now turned on by default. If you would like to disable it:\n\n\t#+BEGIN_EXAMPLE\n      \"htmlExecuteSourceOnExport\": false,\n\t#+END_EXAMPLE"
  },
  {
    "path": "messages/1.2.21.org",
    "content": "* 1.2.21\n** Html Exporter\n\t- Exporting source blocks that do not have handlers was generating an error.\n\n** Early Preview of Latex Exporter\n\t- An early perview of a new latex exporter.\n\t- Many of the basic org data types work already.\n\t- Thanks to FleurDePassion for his time in helping work on this.\n\n** Links To Files in OrgDirs\n\n\tNew command: quick panel based insertion of links to files\n\n\t#+BEGIN_EXAMPLE\n\t\"Org Link To File\" \n\t#+END_EXAMPLE\n\n\tThis was requested by: [[https://github.com/ihdavids/orgextended/issues/30][Autocompletion of Links]] \n\n\tIn addition to the quick insert autocompletion during link insertion also tries to help with mapping to local files if possible. You can turn off autocomplete\n\tin the settings file if you are finding it annoying.\n\n** Home Directory orgDirs\n\tThanks to waynezhang for implementing this.\n\tWe now support ~ in orgDirs in your settings file.\n\t  \n"
  },
  {
    "path": "messages/1.2.22.org",
    "content": "* 1.2.22\n** Table Bug\n\tFixing a remote indexing bug.\n\tIf the local table does not have enough columns to match your remote index\n\tthe remote target would get capped to the local width:\n\n\tNote the a in the second table, it should have been a b, this is because we are\n\ttrying to access column 2 remotely but our local table only has 1 column.\n\n\tThe temporary fix was to add another column.\n\n    #+NAME: hiya\n    | a | b | c |\n    | 1 | 2 |   |\n\n    | a |\n    #+TBLFM:@1$1=remote('hiya',@1$2)\n\n    After the fix this now reads b\n\n** Link Insertion\n\t- Thanks to waynezhang link insertion using \"Link To File\" or the autocomplete\n\t  method now inserts relative paths relative to the current file.\n\t- The title of the link reflects the #+TITLE: field in the file is present.\n\t- \"linkFindUseRoamTags\": False will turn off visualization of ROAM_TAGS in quick panel\n\t  if desired. (NOTE they do not appear in the search unless you have them in the file)\n\n** Capture\n\t- Somehow the snippets folder was not renamed orgsnippets when I normalized\n\t  my extension folder names. This means that while my local snippets were working\n\t  none of the default ones that come with the package were working.\n\t  Hopefully this has been fixed.\n\n** Day Page\n\t- I am moving the day page feature forward a little bit.\n\t- Do not forget to set the \"dayPagePath\" setting if using this feature\n\t- \"Org Day Page Create\" is really going to be more of a\n\t  goto today. It will create the day page or open it.\n\t- Create also now uses a snippet that is keyed off of:\n\t  This should be the filename of a snippet file that lives in your\n\t  orgsnippets folder. (without the .sublime-snippet extension)\n\n \t  #+BEGIN_EXAMPLE\n \t    \"dayPageSnippet\": \"dayPageSnippet\",\n \t  #+END_EXAMPLE \n\n \t  This snippet will get expanded into the file on creation as a means\n \t  of authoring a new day. Symbols exist to help in your snippet authoring \n \t  the list of symbols is similar to the capture templates.\n\n \t  Two new symbols exist for use in your snippet:\n \t  ORG_FILENAME is the filename without the org extension and\n \t  ORG_AUTHOR is your username.\n\n    - Day Page Filenames are now configurable\n      They use the python strftime syntax for defining the filename:\n\n      Note changing this with pre-existing content will likely have consequences\n      when searching old files.\n\n    \t#+BEGIN_EXAMPLE\n    \t  \"dayPageNameFormat\": \"%a_%Y_%m_%d\",\n    \t#+END_EXAMPLE\n\n    - New Commands:\n    \tLets you cycle through your day pages in sequence.\n\n    \t#+BEGIN_EXAMPLE\n    \t  Org Day Page Next\n    \t  Org Day Page Previous\n    \t#+END_EXAMPLE\n\n** Latex Exporter\n\t- NAME now exports a label like it should\n\t- LATEX_HEADER tag should now add to the latex preamble\n\t- LATEX_CLASS_OPTIONS now adds an option next to the documentclass\n\t- surrounding an expression with dollar signs will export properly in latex\n\t- Slightly improved spacing in latex documents\n\t- Fixed a bug with the segment parser and secments right at the start of a line\n\t- Better stripping of html attributes\n\t- Added first try at SetupFile tag."
  },
  {
    "path": "messages/1.2.23.org",
    "content": "* 1.2.23\n** Day Page\n\t- Bugfix - Create was subject to \n\t  a timing problem that would stop it from expanding the snippet.\n\t  This has been fixed.\n\n** Latex Preview\n\t- We continue to move the latex exporter forward with\n\t  some basic image support\n\t- Results have the results header stripped properly now\n\t  A first stab at :exports keyword\n\t  (not really well tested yet)\n\t- More keywords that should be removed are stripped out. "
  },
  {
    "path": "messages/1.2.24.org",
    "content": "* 1.2.24\n** Day Page\n\t- Fixed small exception with create\n\t- Fixed inserting templates when moving back and forth to current\n\t  day page a disturbing leftover from a previous debugging session.\n** Latex\n\t- Improved output parsing in list contents  \n\t- Images have some ATTRS_LATEX support\n\t- table of contenst is included\n\t"
  },
  {
    "path": "messages/1.2.25.org",
    "content": "* 1.2.25\n** Latex Preview\n\t- more #+OPTIONS: controls\n\t  date:nil toc:nil toc:2 author:nil title:nil\n\t- Table export supports some ATTR_LATEX options:\n\t  :environment bmatrix :mode math \n** Hide Images\n\t- This was removing indent for some reason\n\t  which was disconcerting.\n"
  },
  {
    "path": "messages/1.2.26.org",
    "content": "* 1.2.26\n** Bugfix: Do What I Mean Insert\n\tCtrl + Enter is a DWIM insert\n\tSadly I broke it when I renamed the orgsnippets folder\n\n\t"
  },
  {
    "path": "messages/1.2.27.org",
    "content": "* 1.2.27\n** LaTeX Exporter\n\t- LATEX: and @@ @@ support in the latex exporter.\n\t- Something went wrong with 1.2.26, People are downloading 1.1.13 instead... I don't know why. Pushing another version in the hopes this fixes it."
  },
  {
    "path": "messages/1.2.28.org",
    "content": "* 1.2.28\n** Backlinks Experimentation\n\tOrg Roam is a very powerful package. I am nowhere near supporting the power pretty views and flexibility of that package.\n\tThat said, I am experimenting with the backlinks feature. This release has an experimental version of the org-roam backlinks\n\tview. These are links that are referencing your current document in your orgDirs not links that this document references. \n\n\n\t- Org Jump To Backlinks - is a new quick menu command that shows the links referencing your current file and lets you jump to them.\n\t- Org Show Backlinks - is a new command that pops up a panel with the backlinks to the file you are currently looking at.\n\n\tThis is an experimental feature. It automatically tries to keep the backlinks display visible but this is somewhat challenging with the existing\n\tsublime API. You can turn this off if it is causing you problems:\n\n\tTurn off the attempts to update the backlinks display using the following option in your settings file:\n\t#+BEGIN_EXAMPLE\n\t \"backlinksUpdate\": false, \n\t#+END_EXAMPLE\n\n** Mermaid Source Blocks\n\n\t- Syntax is supported if you install the mermaid package\n\t- Can be executed to generate diagrams if setup.\n\n\tSetting it up is a bit of a pain:\n\n\t1. npm install @mermaid-js/mermaid-cli\n\t2. NOTE it gets installed into a node_modules folder. This is REQUIRED!\n\t3. Set the mermaid variable in your settings to point to mmdc in the node_modules\\.bin\\mmdc path\n\t4. Ensure node is in your path \n\n\tThen execute this block:\n\n\t#+BEGIN_SRC mermaid :file ganttdemo.png\ngantt\n    title A Gantt Diagram\n    dateFormat  YYYY-MM-DD\n    section Section\n    A task           :a1, 2014-01-01, 30d\n    Another task     :after a1  , 20d\n    section Another\n    Task in sec      :2014-01-12  , 12d\n    another task      : 24d\n\t \n\t#+END_SRC\n\n   #+RESULTS:\n   [[file:ganttdemo.png]]\n"
  },
  {
    "path": "messages/1.2.29.org",
    "content": "* 1.2.29\n** Links\n\t- New command \"Org Search Links\" searches links across all org files.\n\n** Backlinks\n\t- Fixed a bug where folds in the backlinks buffer would get confused.\n\n** Awk\n\t- Syntax highlighting for awk source blocks:\n\n\t#+BEGIN_SRC awk\n\t  BEGIN {OFS=\"|\"}; { sum+= $2}; END { print \"Sum\", sum} \n\t#+END_SRC\n\n\t"
  },
  {
    "path": "messages/1.2.3.org",
    "content": "* 1.2.3\n\tCore Idea - Better output support and results controls\n\n** Column View\n  - Fixed a small regression introduced in plists in some of the earlier babel work.\n    This was impacting columnview\n\n** Test File\n  To help new users we now have an:\n\n  \"Org Show Testfile\" command that will quickly create a testfile for a user to play with.\n** Babel Preview Output Handlers\n  List Handler\n\n   #+BEGIN_SRC python :results list\n     print(str([1,2,3,4,5]))\n   #+END_SRC\n\n   #+RESULTS:\n   - 1\n   - 2\n   - 3\n   - 4\n   - 5\n\n   File Handler With a List\n   \n   #+BEGIN_SRC python :results list :file out.py\n     print(str([1,2,3,4,5]))\n   #+END_SRC\n\n   #+RESULTS:\n   [[file:out.py]] \n\n\n** Babel Preview Output Formatting\n  These wrap the output in a formatting block of some sort.\n\n*** Drawer Formatter\n   will wrap output in a drawer\n\n   #+BEGIN_SRC python :results drawer verbatim:var x=5\n     print(\"Hello World\")\n     print(x)\n   #+END_SRC\n\n   #+RESULTS:\n    :results:\n    Hello World\n    5\n    :end:\n\n*** Code Formatter\n    will generate a code block with the output:\n\n   #+BEGIN_SRC python :results code\n     print(str([1,2,3,4,5]))\n   #+END_SRC\n\n   #+RESULTS:\n    #+begin_src python\n    [1, 2, 3, 4, 5]\n    #+end_src\n\n*** Org Mode Formatter\n    will generate a code block specific to org\n\n   #+BEGIN_SRC python :results org\n     print(\"#+COMMENT: org data here\")\n   #+END_SRC\n\n   #+RESULTS:\n    #+begin_src org\n    #+COMMENT: org data here\n    #+end_src\n\n*** Append Prepend Silent Replace\n\n   #+BEGIN_SRC python :results org append\n     print(\"#+COMMENT: org data here\")\n   #+END_SRC\n\n   #+RESULTS:\n    #+begin_src org\n    #+COMMENT: org data here\n    #+end_src\n    #+begin_src org\n    #+COMMENT: org data here\n    #+end_src\n    #+begin_src org\n    #+COMMENT: org data here\n    #+end_src\n   \n\n   #+BEGIN_SRC python :results org prepend\n     print(\"#+COMMENT: org data here\")\n   #+END_SRC\n\n   #+RESULTS:\n    #+begin_src org\n    #+COMMENT: org data here\n    #+end_src\n    #+begin_src org\n    #+COMMENT: org data here\n    #+end_src\n    #+begin_src org\n    #+COMMENT: org data here\n    #+end_src\n   \n   #+BEGIN_SRC python :results org silent\n     print(\"#+COMMENT: org data here\")\n   #+END_SRC\n\n    #+RESULTS:\n"
  },
  {
    "path": "messages/1.2.30.org",
    "content": "* 1.2.30\n** Auto Indentation\n   - Not yet perfect but some simple auto indentation rules\n   - begin blocks are automatically indended.\n   - Headings get indentation inserted when you hit enter off them\n\n** BEGIN_NOTES\n   - notes block added to syntax highlighter\n   - <n snippet added as well.\n\n** New Agenda Filter Keyword\n\n   statefilter is a new filter that can help tweak a todo view to only a subset of \n   open states.\n\n   #+BEGIN_EXAMPLE\n     Loose Tasks: statefilter +TODO +NEXT : tagfilter MyTag\n   #+END_EXAMPLE\n\n** Known Issues\n   - Since the default reveal.js exporter uses a CDN the presenter\n     notes are not being shown because the notes.html file is not hosted\n     anymore. I will work to fix this in the future.\n\n     (As well as upgrade to the latest reveal.js distribution)"
  },
  {
    "path": "messages/1.2.31.org",
    "content": "* 1.2.31\n** Insert Heading\n\tSlight improvement to DWIM behaviour\n\tFile with no headings will behave a little better on insertion.\n** RevealJs Exporter\n   \t- Converted RevealJs exporter to use version 4.1.0 \n   \t- Converted RevealJs exporter to use new export framework written for the latex exporter\n   \t- New global option for CDN:\n\n   \t  #+BEGIN_EXAMPLE\n   \t    \"RevealLocation\": \"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/\",\n   \t  #+END_EXAMPLE\n\n   \t- Switched CDNs from cdnjs to jsdelivr to get presenters notes working again.\n\n** Show Inline Images\n   \t- Improvement when unadorned http links are next to images Show Images would not work\n   \t  Thanks to waynezhang for this bugfix.\n\n** Indentation Rules Improvement\n    - Fixing small bug with indent rules regexs."
  },
  {
    "path": "messages/1.2.32.org",
    "content": "* 1.2.32\n** Insert Sibling Heading\n   - If the next line has spaces the inserted heading could have spaces which is not a good idea.\n     This is now stripped properly.\n\n** Agenda\n   - Done - a new view that lists done tasks\n    WATCH OUT this can be massive! Use this with other filters.\n   - durationfilter added -2w filters items 2 weeks ago from right now. \n     a negative duration value will filter against CLOSED values while a positive will filter\n     against SCHEDULED and DEADLINE values.\n   - datefilter allows you to filter by absolute date range >=20210501 <=20210531\n   - hasclose and other attributes were not handled properly as filter keywords, this has been fixed.\n\n** Reveal Exporter\n   - Tables are now actually supported\n\n** Exporting\n   - Tables had a bug if tabs were present in front of the table.\n\n** Editing\n   - New override setting: logDone - forces CLOSED entries to be inserted even if logdone\n     is not in your #+STARTUP: tags or global \"startup\": \"...\" settings.\n   #+BEGIN_EXAMPLE\n     \"logDone\": true,\n   #+END_EXAMPLE\n\n** Tables\n   Found a bug with complete relative syntax.\n   They were always evaluating to 1,1 in the table.\n\n   This has been fixed.\n\n   #+BEGIN_EXAMPLE\n     @-1$+1 \n   #+END_EXAMPLE\n\n   Known issue:\n   ------------\n   Complex expansions are not working:\n\n   @int($-1)$1\n   This would look up the row from the neighboring cell\n\n   There is a workaround for now till I can improve the parser\n\n   getcell(int($-1), 1, 1, 0)\n            |        |  |  not relative\n            |        |  column 1\n            |        relative offset\n            grab value 1 cell to the left, ensure it is an int\n\n*** New Table Commands\n   \n    The following will pull the active formula for the current cell into the current cell.\n    Facilitating editing.\n\n    #+BEGIN_EXAMPLE\n      Org Edit Table Formula\n    #+END_EXAMPLE\n\n    The following will clear the current cell\n\n    #+BEGIN_EXAMPLE\n      Org Clear Table Cell\n    #+END_EXAMPLE\n\n    The following will run a temporary formula on the cells on and below the cursor\n    which can be handy when fixing up a table.\n\n    #+BEGIN_EXAMPLE\n      Org Table Exec Below\n    #+END_EXAMPLE\n\n*** Babel Preview\n    - Improved results block discovery previously results might confuse a source block\n      as being part of the results.\n\n"
  },
  {
    "path": "messages/1.2.33.org",
    "content": "* 1.2.33\n** Editing\n   - Tag insertion could not insert tags on headings with colons\n     this has now been fixed.\n     [[https://github.com/ihdavids/orgextended/issues/38][Issue]] \n\n*** Indenting\n    An attempt to improve heading indentation with exiting content. We will see how this\n    new attempt plays out.\n\n** Syntax Highlighting\n   - Internal syntaxes are now hidden.\n   - Syntaxes are now marked as version 2 which may improve perf.\n\n** Org Beancount Experiment\n   This is a bit of a departure from org's primary purpose.\n   I however use beancount and beancount is designed to work\n   inside other markup languages like markdown and... orgmode!\n\n   Due to how packages and syntaxes work I have not found a good\n   way to create an amalgamated syntax without doing inside the\n   orgmode package. So... here we are. By default we highlight\n   .orgbeancount files.\n\n   This also adds a snippet for inserting a transaction with\n   some additional metadata. My hope is to eventually facilitate\n   babel and beancount. \n\n** Clocking\n   - I was logging clock entries into the PROPERTIES drawer.\n     this is a bit non standard.\n   - this is now configurable and by default we are now\n     logging into a LOGBOOK drawer which is more orgmode standard.\n\n     Use the following to preserve the old behaviour:\n     #+BEGIN_EXAMPLE\n        \"clockInPropertyBlock\": true,\n     #+END_EXAMPLE \n   "
  },
  {
    "path": "messages/1.2.34.org",
    "content": "* 1.2.34\n** Active Table Cell Highlight\n   Show cursor for current cell.\n\n   Use the following option to turn this off if\n   it is causing you problems.\n\n   #+BEGIN_EXAMPLE\n     \"tableShowCursor\": false,\n   #+END_EXAMPLE\n\n** Babel Preview\n   - Perl is now supported. Like the other languages you have to\n   \t tell the language handler where your perl interpreter can be found\n   \t with:\n\n   \t #+BEGIN_QUOTE\n   \t   \"perlPath\": \"<path to perl interpreter\",\n   \t #+END_QUOTE\n\n  \t#+NAME: input-table\n  \t| a | b | c |\n  \t| 1 | 2 | 3 |\n  \n  \t#+BEGIN_SRC perl :var DATA=input-table :results table\n    \tforeach(my $m = 0; $m <= $#DATA; $m++)\n    \t{   \n      \t\tfor(my $n = 0; $n <= $#{$DATA[$m]} ; $n++)\n      \t\t{  \n        \t\tprint \"$DATA[$m][$n] \";  \n      \t\t}  \n      \t\tprint \"\\n\";  \n    \t} \n  \t#+END_SRC\n  \t#+RESULTS:\n  \t| a | b | c |\n  \t| 1 | 2 | 3 |\n\n  \tI am certainly not a perl master, if someone wants to tweak my perl\n  \tintegration please be my guest.\n\n  \t#+BEGIN_SRC perl :results value\n    \treturn \"Hello world\"\n  \t#+END_SRC\n  \t#+RESULTS:\n  \t: Hello world\n\n*** R\n   The R language in source blocks was not marked up properly.\n\n** Agenda\n   Files outside of orgDir were being included in the agenda.\n   A request was made to fix this. The old behaviour can be toggled\n   using the following:\n\n   #+BEGIN_SRC js\n        \"agendaIncludeFilesOutsideOrgDir\": true     \n   #+END_SRC\n\n** Sinamore Slow Checkbox Improvement [0/5]\n   - Improvement to checkbox performance in files with lots of checkboxes and summaries.\n\n"
  },
  {
    "path": "messages/1.2.35.org",
    "content": "* 1.2.35\n** Bold Italic etc only on word boundaries\n   - Emacs org mode only supports formatting on propper word boundaries:\n\n      _THIS_SHOULD_NOT_BE_HIGHLIGHTED_\n      _THISSHOULDBE_\n\n      /This/Is/Not/Italics/\n      /This is italics/\n\n      I have adjusted the grammar to avoid formatting improperly.\n\n** Experimental Trello Export\n   Org is an interchange format and can be used like markdown to export to other formats. It is also a great way to store notes and other todos.\n   that said, sometimes you have to work in other systems, like trello, but still want Org goodness. This is an experimental export feature from\n   Trello to a local org file. This is not only a handy backup but I am hoping I might evolve this into a 2 way sync.\n   This builds on and requires the existing Trello package, you will need it to be able to use the new Trello sync features herein.\n\n   - Ability to author an org file from a trello board. This requires that you have installed the Trello package and set it up.\n     Running \"Org Trello Sync Board\" Will let you select a board and generate an org file from it.\n   - The command will not be present if you have not setup the Trello package.\n   - Eventually I would like this to be a 2 way sync but that is going to take a bit more work. \n\n** Day Page Extension\n   - The day page system got a bit of a facelift.\n   - dayPageMode: \"week\" Will now flip the system to have one page per week rather than a page per day. NOTE: The page will always be the monday of\n     every week.\n   - dayPageCopyOpenTasks:true will now copy any unfinished todo's from the previous page to today when you create a new day page.\n   - dayPageArchiveOld:true will add an archive tag to the previous day when you start a new day page. \n   "
  },
  {
    "path": "messages/1.2.36.org",
    "content": "* 1.2.36\n** Slightly Improved DatePicker\n\t- Working to improve the datepicker a bit, there is sooo much functionality that org offers here\n\t  and I only support a tiny fraction of the abilities.\n\t- Added clock to demonstrate current time to the datepicker.\n\t- Added Ctrl+Shift+. and Ctrl+Shift+, to change the active hour\n\t- Added Alt+Shift+. and Alt+Shift+, to change the active minute\n\t- Clock disappears if we failed to parse a time out of your date string.\n\t- I have added REALLY basic duration capabilities to the date picker.\n\n\t\t#+BEGIN_SRC org\n\t\t\t1d    -- Will select a date tomorrow at the current time.\n\t\t\t3h    -- Will select a time 3h from now. \t  \n\t\t\t4     -- Will select the next day 4 of the month in the future.\n\t\t\tFri   -- Jump to the next friday from curren day\n\t\t\tsept 12 -- Jump to sept 12\n\t\t#+END_SRC\t\n\n\tThis is still nowhere NEAR: https://orgmode.org/manual/The-date_002ftime-prompt.html\n\tBut I am slowly working in that direction. Hopefully one day we will have a date picker that\n\tthat is as powerful and flexible as the full orgmode version.\t\n"
  },
  {
    "path": "messages/1.2.37.org",
    "content": "* 1.2.37\n  - Fixed a bug with agenda having extra spaces after calendar view.\n** dayPage - Capture symbols\n    - added {daypage} symbol as a capture target symbol\n    #+BEGIN_SRC js\n        \"target\": [\"file\",\"{daypage}\"],\n    #+END_SRC\n\n    - you can now also set a symbol in your sublime settings file and use it as a target expansion:\n    #+BEGIN_SRC js\n        \"mysym\": \"to use over and over\"\n        ...\n        \"target\": [\"file\",\"{mysym}\"],\n    #+END_SRC\n\n** Capture\n   Added file+headline to capture templates.\n   #+BEGIN_SRC js\n   \"target\": [\"file+headline\",\"{myfile}\",\"MyHeadline\"]\n   #+END_SRC"
  },
  {
    "path": "messages/1.2.38.org",
    "content": "* 1.2.38\n** Day Page\n   - Bugfix, regression: snippets were not running when creating a new daypage.\n** Capture\n   - Fixed symbol expansion of filenames\n   - Indent fix when inserting at the end of the buffer\n   - file+headline improved insertion"
  },
  {
    "path": "messages/1.2.39.org",
    "content": "* 1.2.39\n** Improving Org Capture\n   - file+regexp now works for inserting entry's\n   \t no item or anything else, just entry's but it works.\n   \t This searches an org file line by line for the first match.\n   \t [\"file+regexp\",\"filename\",\"REGEX\"]\n\n   - file+olp - full path in a file. When there are multiple paths\n     this is the safest.\n     [\"file+olp\",\"filename\",\"Heading level 1\",\"Heading level 2\" ...]"
  },
  {
    "path": "messages/1.2.4.org",
    "content": "* 1.2.4\n\n\tCore Idea: Value vs Output execution\n\n** Links Improvements\n   By default most file links will be loaded within sublime.\n   If there is a file type you want launched outside of sublime use:\n\n   #+BEGIN_EXAMPLE\n     \"file_exclude_patterns\": [\"*.pdf\"],\n   #+END_EXAMPLE\n\n** Column View\n  - Fixed a problem where the columnview dynamic block was grabbing its column definitions\n    from the current node. This would cause column view to use the default definition.\n\n\t #+COLUMNS: %TODO(To do) %ITEM(Task) %TAGS(Tags) %Effort(effort)\n   #+BEGIN: columnview :id global :indent t\n   | TODO | Task          | Tags | effort |\n   |      | 1.2.4         |      |        |\n   | DONE | ..Column View |      |        |\n   #+END:\n\n** Value Type Execution\n\n  Acts like a function, the return statement of the code is returned.\n\n  #+BEGIN_SRC python :results value\n      print(\"Hello world\")\n      print(\"Hello world2\")\n      if 5 < 10:\n        print(\"hi\")\n      return 11\n  #+END_SRC\n   #+RESULTS:\n   : 11\n    \n   #+BEGIN_SRC powershell :results value\n     Write-Host \"Hello World\"\n     return 10\n   #+END_SRC\n   #+RESULTS:\n   : 10\n\n** Chainging Execution\n\n  A src block should be able to reference another src block as an input.\n  This is a REALLY early version of this. Only tables work at the moment.\n\n  There are a couple of challenges here:\n\n  - Things move as other items execute, I haven't fully solved that yet.\n  - Right now I ALWAYS execute the target source block, I need to improve that going forward.\n  - Errors in the chain are not handled very well yet.\n\n  #+NAME: tbl-source\n  | a | b | c | d | e |\n  | 1 | 2 | 3 | 4 | 5 |\n\n  This source block uses the output from the table above\n\n  #+NAME: python-src\n  #+BEGIN_SRC python :results table :var DATA=tbl-source\n   print(DATA)\n  #+END_SRC\n\n  #+RESULTS:\n   | a | b | c | d | e |\n   | 1 | 2 | 3 | 4 | 5 |\n\n\n   This source block uses the output from python-src as an input\n\n   #+BEGIN_SRC python :results table :var DATA=python-src\n    print(DATA) \n   #+END_SRC\n\n   #+RESULTS:\n   | a | b | c | d | e |\n   | 1 | 2 | 3 | 4 | 5 |\n\n\n\n\n\n\n\n"
  },
  {
    "path": "messages/1.2.40.org",
    "content": "* 1.2.40\n** Refile Improvements\n\t2 new commands for refiling:\n\n\t- org_refile_to_file command vs heading, quick refile at end of file.\n\t- org_refile_to_file_and_headline - 2 step prompt file + headline\n\n\tRight now, for vimmers bound to:\n\t- <space> r f for refile to file.\n\t- <space> r r for refile to file and headline\n\n** Capture\n\t- Added new capture type: 'plain'\n\t  we now support 'entry' and 'plain' Eventually I will add all the capture types\n\t  but we are a bit off from that.\n\t- Added new capture type: 'item'\n\t  This will add at the end of the first list found in the node\n\t- Added new capture item: 'checkitem'\n\t  This will add at the end of the first checklist found in the node\n\t- Added really early attempt at 'table-line'. Not sure if this is sufficient\n\tAll of the types above only work with the snippet type\n\n\t- Added first stab at 'file+olp+datetree' I only have the full day mode not month or week yet.\n\t  The olp part will take a heading and will add something like:\n\t  under that heading\n\n\t  * 2021\n\t  ** 2021-11 November\n\t  *** 2021-11-27 Saturday\n\t      <your snippet here>\n\n\t  The target should look something like:\n      ['file+olp+datetree',\"{myfile}\",\"Heading a\",\"Heading b\",\"Heading c\"]\n\n      We have 3 non standard properties implemented for datetree:\n\n      #+BEGIN_QUOTE\n        These are python date strings and allow you to control the header\n        format of your datetree\n          \"year-format\":  \"%Y\",          - The root of your datetree * 2021\n          \"month-format\": \"%Y-%m %B\",    - The month section         ** 2021-11 November\n          \"day-format\":   \"%Y-%m-%d %A\", - The day section           *** 2021-11-27 Saturday\n      #+END_QUOTE"
  },
  {
    "path": "messages/1.2.41.org",
    "content": "* 1.2.41\n\tThank you for the contribution Sinamore:\n\n\t- Some small agenda fixes from Sinamore for the agena\n\t  when day of week starts on Monday it was showing the wrong week.\n\t- Datepicker had problems with date wrap around.\n\t- A bug in mouse hovering with hasattr\n"
  },
  {
    "path": "messages/1.2.42.org",
    "content": "* 1.2.42\n** Template formatter\n\t- Small enhancement to template formatting in settings file for capture templates.\n\t- Stolen from superformatter a very simple python template expansion tool.\n\t- {variable.<function>:call} will call a function on the variable contents (such as upper())\n\t- {variable:repeat:string to repeat for {{item}} } assuming variable is a list will output the string expanded per item in the list\n\t- {variable:if:string to output} Will output string to output if variable evaluates to true otherwise \"\"\n** DatePicker\n\t- Fixed moving outside of the 3 month range. Highlighting today would fail and date would fail to update properly.\n\n** DayPage\n   New option: \"dayPageCopyTasksForToday\": True\n   This will copy all todos that would target today to the current daypage. This is experimental and will likely change in the future.\n   Iterating with olBC to get this feature to his liking.\n   The option can scan files in memory but not in your org dir if you turn on: \"dayPageIncludeFilesOutsideOrgDir\": true\n\n   \n"
  },
  {
    "path": "messages/1.2.43.org",
    "content": "* 1.2.43\n** Agenda Flexible Project Definition\n   New options for defining what a project is.\n\n   #+BEGIN_SRC js\n    // nested_todo TODO with sub TODO's.\n    // tag         Heading with a :PROJECT: tag\n    // property    Heading with a :PROJECT: True property\n    \"agendaProjectIs\": \"nested_todo\",\n   #+END_SRC \n\n   nested_todo is a todo under a todo:\n\n   * TODO My Project\n   ** TODO Task\n\n   tag defines a project as a heading with a project tag:\n\n   * My Project                      :PROJECT:\n   ** TODO Task\n\n   property defines a project as a heading with a PROJECT property:\n\n   * My Project\n   :PROPERTIES:\n     :PROJECT:\n   :END:\n   ** TODO Task\n\n** Agenda Projects\n\t2 new agenda views:\n\t- Not Blocked Projects - Shows projects that are not in the blocked state (have a NEXT task)\n\t- Projects             - Shows all projects\n\n"
  },
  {
    "path": "messages/1.2.44.org",
    "content": "* 1.2.44\n** FIXED Capture Supports Unicode\n\t- [[https://github.com/ihdavids/orgextended/issues/57][Fix for Capture fails silently with unicode error]] \n\n\tCaptures that contained unicode characters would fail. This was\n\tdue to the fact that the capture mechanism was not saving files with the default text encoding.\n\n\tThere is a new option that allows you to control the format of the destination capture file:\n\t#+BEGIN_SRC js\n    // What file format should we write out as. This should be a python encoding value\n    // CAN BE:\n    // - utf-8\n    // - utf-16\n    // - utf-32\n    // SEE: https://docs.python.org/3.3/library/codecs.html#standard-encodings\n    \"captureWriteFormat\": \"utf-8\",\n\t#+END_SRC\n\n\tThe default is now utf-8\n\n** FIXED Autocalculated Rows Fix\n\t- [[https://github.com/ihdavids/orgextended/issues/59][in tables, auto calculating rows sometimes break a column formula]]\n\n\tThanks to JosefTaylor reporting that autocalculating tables sometimes get confused with table formulas.\n\tSome improvements have been made to fix this going forward.\n\n\tThe problem was that as you edit the column you can cross over into the next cell's space while editing. \n\tThis was confusing the automatic targetting for the formula since the destination cell\n\twas computed before the table was reformatted. I have added a table align before recomputing the cell.\n\tIt's a little slower when tabbing around but should result in correct behaviour.\n   \n   |   | am | I  |   what  |   |\n   |---+----+----+---------+---|\n   | # |  2 | 20 |  62.832 |   |\n   | # |  3 | 13 |  40.841 |   |\n   | # |  5 | 41 | 128.805 |   |\n   #+TBLFM::$4=$3*pi;N%.3f\n\n** FEATURE Rounding Out Tag Support\n   Added new option to control the tag column when inserting tags:\n\n   #+BEGIN_SRC js\n    // Where should tags start in a headline?\n    // Tags will get inserted at this column\n    \"tagColumn\" : 80,\n   #+END_SRC\n\n   3 new commands (sadly t is used for timestamp so I am using m for mark...)\n   - Org Remove Tag      ::   (NeoVintageous: <space> r m)     Prompt to remove a tag\n   - Org Remove All Tags ::   (NeoVintageous: <space> r a m)   Removes all tags from current headline\n   - Org Fix Tags        ::   (NeoVintageous: <space> f m)     Will re-indent all tags in the file to the tag column specified\n\n\n\n"
  },
  {
    "path": "messages/1.2.45.org",
    "content": "* 1.2.45\n** FIXED Internal Target Highlighting\n   - [[https://github.com/ihdavids/orgextended/issues/62][Internal Target Problem]]\n\n   Thanks to flintforge for reporting that adding an unterminated << to a line would cause the rest of the document to become\n   an internal link in the org syntax setup as it is. This is now fixed:\n\n   << Internal Link >>  - This should be a valid link\n   << This is not a valid link\n\n\n   | This | Table | Should | Be | Okay |\n   |------+-------+--------+----+------|\n   |    1 |     2 |      3 |  4 |    5 | \n"
  },
  {
    "path": "messages/1.2.46.org",
    "content": "* 1.2.46\n** FIXED Duplicate filenames appearing in refile listing\n   When refiling to EOF sometimes the list would have duplicate files.\n   This should now be fixed.\n"
  },
  {
    "path": "messages/1.2.47.org",
    "content": "* 1.2.47\n** FIXED Sometimes tasks were misidentified as being a task.\n   - Tasks are defined as being a todo that has a parent and that parent is a project identifier.\n   - NOTE: When I eventually support using the orgs server as an alternative to the orgdb the query language will\n           be cleaner. Right now I am not a fan of how I chose to build these querries.\n           \n** New default state keywords added\n\tNew open states:\n    - FLAG - Personal state meaning this is waiting on processing. \n    - CLEANUP - Personal state meaning this todo is in the cleanup phase and needs further cleanup effort.\n\n    New closed states:\n    - FIXED - same as DONE\n** FIXED Agenda color scheme was not highlighting filenames with underscores"
  },
  {
    "path": "messages/1.2.48.org",
    "content": "* 1.2.48\n** Properties\n   :PROPERTIES:\n     :Created: [2022-07-20 Wed 08:49]\n   :END:\n\n\t- I found myself adding a Created property to a lot of new notes.\n\t  (I like timestamps on when a note has been created)\n\t  So I have added a new command Org Insert Created Property that will\n\t  auto insert a :Created: [TIMESTAMP] to a heading, saves me a few keystrokes.\n\t  (See above for the format)\n\n\n** FIXED FILETAGS\n   Filestags with colons around them were not having the colon stripped.\n   This was a bug introduced a while back and I did not notice.\n   This is no longer the case:\n\n   #+BEGIN_SRC org\n      #+FILETAGS: :A:B:C:\n   #+END_SRC \n\n   Will now correctly tag all nodes with A B and C tags\n\n** FIXED Checkbox summaries\n   Summaries that were followed by a list of checkboxes in a second heading could miscalculate the summary\n   including checkboxes from the next heading\n\n   #+BEGIN_SRC org\n\n   * A [1/2]       <-- This would be miscalculated as [1/3] vs [1/2]\n     - [ ] B\n     - [x] C\n   ** D \n     - [ ] E\n\n   While still facilitating nested summaries:\n\n   * Heading [3/5]\n   - [x] A\n   - [x] B\n   - [ ] C\n   - [-] D [1/3]\n      - [ ] X\n      - [x] Y\n      - [ ] Z\n   - [x] E\n\n   #+END_SRC\n   \n** FIXED Clocking in and out was crashing\n   Clocking in and out on a node was throwing exceptions due to the property\n   drawer API attempting to operate on a root node missing some API. This should now be fixed.\n\n** New Command Org Jump To Clock\n   This will jump to an active clock if one is running. Currently not bound to anything.\n\n** New Todo filters\n*** clockedtoday\n   clockedtoday tests if the todo has a clock value and if either start or end spans today\n   If you are using the clocking feature this makes it easier to get a quick list of things you have worked on today.\n  \n   #+BEGIN_SRC js\n     \"Todays Work\":   [\"Todos : clockedtoday\"],\n   #+END_SRC \n\n*** clockfilter\n   clockfilter is like durationfilter in that it takes a duration specifier\n\n   #+BEGIN_SRC js\n     \"This Weeks Work\":   [\"Todos : clockfilter +7d\"],\n   #+END_SRC\n\n*** showduration\n   This will show the amount of time in hours and minutes that you spent on a todo, in the todo view\n\n   #+BEGIN_SRC js\n     \"This Weeks Work\":   [\"Todos : clockfilter +7d : showduration\"],\n   #+END_SRC\n\n*** hide filters\n   3 Additional formatting options for task list views:\n\n   - hidefilename\n   - hideheading\n   - hidestatus\n\n   #+BEGIN_SRC js\n     \"This Weeks Work\":   [\"Todos : clockfilter +7d : showduration : hidefilename\"],\n   #+END_SRC\n\n   These will hide the filename, todo heading and todo status fields as desired in the listing.\n\n*** showtotalduration\n   This option will turn on a summary of the total duration at the end of task listing of tasks that were clocked.\n\n   #+BEGIN_SRC js\n     \"This Weeks Work\":   [\"Todos : clockfilter +7d : showduration : showtotalduration\"],\n   #+END_SRC\n\n*** byproject\n   This task pane option will group tasks by project adding a == [Project Name] == header to each project for clarity\n\n   #+BEGIN_SRC js\n     \"This Weeks Work\":   [\"Todos : clockfilter +7d : showduration : showtotalduration : byproject\"],\n   #+END_SRC\n\n** New Agenda Views\n   Clocked view shows anything with a clock value including non todos\n\n   For example this is different than the above as the above will show anything in an open state\n   since it uses the Todo view while the following will actually show all work done on any node.\n   Obviously this comes with a slight performance cost as it has to scan non todo nodes, but it makes\n   the clocking feature more useful.\n\n   #+BEGIN_SRC js\n     \"This Weeks Work\":   [\"Clocked : clockfilter +7d : showduration\"],\n   #+END_SRC\n\n** Tweak to Composite Todo List Titles\n   If the composite list only contains a single view, the name of the view is assigned the name of the composite view + [view name]\n   This allows a custom view with \"This Weeks Work\" as the name to appear as:\n\n   #+BEGIN_EXAMPLE\n     This Weeks Work [Clocked]\n   #+END_EXAMPLE\n\n   Increasing clarity as to the type of list you are viewing\n"
  },
  {
    "path": "messages/1.2.49.org",
    "content": "* 1.2.49\n\n** FIXED Clocking out\n\t- When clocking in to a different file while a previous clock was running the clock value was getting written\n\t  to the wrong file due to using the wrong view!\n\t- We now open the other file, add the clock out value, save it and switch back to the correct buffer\n** REMINDER org_agenda_custom_view\n   Recently I was asked about todo views. I thought I would take a moment and\n   highlight what is already there. \n\n\tThe org_agenda_choose_custom_view command can be handy\n\tfor scanning through your todo lists, but if you are like me,\n\tit can get in the way.\n\n\tYou can bind your own keybindings and select a particular view quickly like so:\n\tHere I am using a neovintageous style keybinding to pop up my \"This Weeks Work\" list\n\twhen I press <space> o l w in normal mode. (Think VIM) You can do much the same for whatever your\n\tpreferences might be.\n\n\n\t#+BEGIN_SRC js\n    { \"keys\": [\" \",\"o\", \"l\", \"w\"]\n    , \"command\": \"org_agenda_custom_view\"\n    , \"args\": {\"toShow\": \"This Weeks Work\"}\n    , \"context\": [{\"key\": \"vi_command_mode_aware\"}]  \n    },\n\t#+END_SRC\n\n\tThis view is created using the view syntax like so:\n\n\t#+BEGIN_SRC js\n    \"AgendaCustomViews\": \n    {\n    \t# My agenda is comprised of several standard views\n        \"Default\":           [\"Calendar\", \"Week\", \"Day\", \"Blocked Projects\", \"Loose Tasks\"],\n        # Show any todos tagged as being active\n        \"Active\":            [\"Todos : tagfilter +Active\"],\n        # Show my todos tagged as being part of my backlog.\n        \"Backlog\":           [\"Todos : tagfilter +Backlog\"],\n        # Show anything, not just todos that have been clocked within the last 7 days. Also show their duration\n        # and group them in projects if they are associated with a project.\n        \"This Weeks Work\":   [\"Clocked : clockfilter +7d : showduration : showtotalduration : byproject\"],\n    },\n\t#+END_SRC\n\n\t\n** Agenda Task Lists\n\t- Todo lists now have a dynamic filter option. This option will provide an input box that allows you to dynamically filter the text in the todo list.\n\t- The keybinding is REALLY rough right now. \n\t\t- In neovintageous mode \"f\",\"f\" will bring back up the input box allowing for more filtering goodness.\n\t\t- In normal mode alt+o f f will bring back up the input box allowing for more filtering goodness.\n\t- Escape will clear the filter\n\t- Enter will make the filter permanent allowing you to scroll through todos again.\n\n\tYou can force this input panel to have focus and be visible when the todo list pops up with the following option:\n\n\tIf sublime will ever support more rich panels I would love to add dynamic filtering by tag, priority and other things in there.\n\tFor now I will have to add then piecemeal.\n\n\t#+BEGIN_SRC js\n    \"agendaTodoFilterByDefault\": true,\n\t#+END_SRC\n\n*** New todo view columns\n\tNot sure I like this yet, still somewhat experimental.\n\n    - showdate - will show most relevant date information (active, scheduled, dealine, closed timestamp)\n    - showtime - will show the time info from the most relevant date information\n\n    #+BEGIN_SRC js\n        \"This Weeks Work\":   [\"Clocked : clockfilter +7d : showduration : showtotalduration : byproject : showdate : showtime\"],\n    #+END_SRC\n\n*** Better todo sorting\n\tSomewhat experimental at the moment...\n\n    - Now sorts by date by default, will be looking to make this configurable going forward as well.\n    - Sort order can be flipped globally if preferred using:\n\n    #+BEGIN_SRC js\n      \"agendaTodoSortAscending\": false,\n    #+END_SRC\n\n    Or locally in a list using:\n\n    - sortascend\n    - sortdescend"
  },
  {
    "path": "messages/1.2.5.org",
    "content": "* 1.2.5\n\tCore Idea: Better Chaining Support\n\n** Agenda - WeekView\n  - Bugfix: The weekview could show things last month but in the current week erroneously.\n\n\n** PlantUML\n  - Fixed a regression in the parameter handling for plantuml.\n\n  #+BEGIN_SRC plantuml :file out.png\n    a -> b\n    b -> c\n  #+END_SRC\n\n   #+RESULTS:\n   [[file:out.png]]\n\n** Handling Drawers in Chained Sources\n\n  #+NAME: tbl-source\n  | a | b | c | d | e |\n  | 1 | 2 | 3 | 4 | 5 |\n\n  This source block uses the output from the table above\n\n  #+NAME: python-src\n  #+BEGIN_SRC python :results drawer table :var DATA=tbl-source\n   print(DATA)\n  #+END_SRC\n\n  #+RESULTS:\n   :results:\n   | a | b | c | d | e |\n   | 1 | 2 | 3 | 4 | 5 |\n   :end:\n\n   This source block uses the output from python-src as an input\n\n   #+BEGIN_SRC python :results table :var DATA=python-src\n    print(DATA) \n   #+END_SRC\n\n   #+RESULTS:\n   | a | b | c | d | e |\n   | 1 | 2 | 3 | 4 | 5 |\n\n** Handling Lists in Chained Sources\n\n\tHere we have a list that acts as a source for some python that acts as a source for more python.\n\n\t#+NAME: lst-source\n\t1. a\n\t2. b\n\t3. c\n\n\t#+NAME: python-lstsrc\n\t#+BEGIN_SRC python :results drawer list :var DATA=lst-source\n\t  print(DATA)\n\t#+END_SRC\n\n   #+RESULTS:\n   :results:\n   - a\n   - b\n   - c\n   :end:\n\n   #+BEGIN_SRC python :results list :var DATA=python-lstsrc\n    print(DATA) \n   #+END_SRC\n\n   #+RESULTS:\n   - a\n   - b\n   - c\n\n** Numeric and Text Values\n\n\tHere the powershell scripts results are piped into the python script.\n\n   #+NAME: ps-src\n   #+BEGIN_SRC powershell :results value\n\treturn 5     \n   #+END_SRC\n   #+RESULTS:\n   : 5\n\n   #+BEGIN_SRC python :results drawer :var DATA=ps-src\n     print(DATA)\n   #+END_SRC\n\n   #+RESULTS:\n   :results:\n   5\n   :end:\n\n** Silent Exec \n\n   #+NAME: ps-src2\n   #+BEGIN_SRC powershell :results output list silent :var DATA=lst-source\n\t  $DATA\n   #+END_SRC\n\n\n   #+BEGIN_SRC python :results drawer list :var DATA=ps-src2\n     print(DATA)\n   #+END_SRC\n\n   #+RESULTS:\n   :results:\n   - a\n   - b\n   - c\n   :end:\n\n\n  #+NAME: python-src2\n  #+BEGIN_SRC python :results table silent :var DATA=tbl-source\n   print(DATA)\n  #+END_SRC\n\n\n   #+BEGIN_SRC python :results table :var DATA=python-src2\n    print(DATA) \n   #+END_SRC\n\n   #+RESULTS:\n   | a | b | c | d | e |\n   | 1 | 2 | 3 | 4 | 5 |\n   \n** Call\n  Begining support for the babel call syntax.\n  Here we define a function that can be called elsewhere in the document\n  with different parameters.\n\n \n   #+NAME: varfunction\n   #+BEGIN_SRC python :var DATA=6\n     print(DATA)\n   #+END_SRC \n\n   #+RESULTS:\n   : 6\n\n   #+call: varfunction(DATA=7)\n\n   #+RESULTS:\n   : 7\n\n\n** First Draft Source Block Execute in Tables\n\n  This is a slight breakaway from orgmode as we do not support lisp and in orgmode this would be done with (org-sbe 'name' (key x) (key y))\n  This is not a syntax I can easily support properly without implementing a full lisp parser inside sublime and... I don't like that idea.\n  So, I am using the more python friendly function call as seen below. Note this is running the varfunction above, taking the results and placing\n  them in the table below in cell 2,1.\n\n  | a     | b |\n  | 12345 | 6 |\n  #+TBLFM:@2$1=sbe('varfunction',DATA=12345)::@2$2=sbe('varfunction')\n   \n\n\n"
  },
  {
    "path": "messages/1.2.50.org",
    "content": "* 1.2.50\n** Agenda\n*** FIXED Task Lists\n\t- Some print cleanup from the sublime output window.\n\n*** FIXED Agenda View\n\t- Searchable task lists broke the agenda render. Very frustrating.\n\n*** New showeffort todo agenda option \n    \n    #+BEGIN_SRC js\n        \"Active\":   [\"Todos: tagfilter +Active :showeffort\"],\n    #+END_SRC \n\n    This will add the :EFFORT: property if present on a todo to the todo list view in a column\n\n*** New showid todo agenda option\n\n\tWill show the ID or CUSTOM_ID property of a task in the todo list\n    #+BEGIN_SRC js\n        \"Active\":   [\"Todos: tagfilter +Active :showid\"],\n    #+END_SRC \n\n*** New showafter todo agenda option\n\n\tWill show the AFTER property of a task in the todo list\n    #+BEGIN_SRC js\n        \"Active\":   [\"Todos: tagfilter +Active :showafter\"],\n    #+END_SRC \n\n*** New showassigned todo agenda option\n\n\tWill show the ASSIGNED property of a task in the todo list\n    #+BEGIN_SRC js\n        \"Active\":   [\"Todos: tagfilter +Active :showassigned\"],\n    #+END_SRC \n*** Change in TODO Tables\n\t- As I have added more columns it becomes more confusing deciphering what you are looking at. I have added headings to the table.\n\t- I may simply convert this to an org table, we will see.\n\n** Todo Views\n\t- Org Agenda * commands now work on todo views as well as the agenda\n\t- This allows for changing priority et al directly form todo lists.\n\t- 3 new commands for todo view editing:\n\t\t- Add tag from view\n\t\t- Add property EFFORT\n\t\t- Add property ASSIGNED\n \n\t\tThese get us closer to a pseudo column view mode using a todo table.\n\n** Tables\n   - Fixed some tabbing problems (mostly highlight related in some generated tables)\n   - Problem was both a potential exception AND a table living at global scope\n     the keybinding was going to the global scope tab binding rather than the\n     table keybinding which was causing improper behaviour.\n\n*** Random Insertion From Remote Table\n\tSometimes I would like to make a random selection from a remote table. There is a new command to insert at point a random selection from a remote table (by ID)\n\tNOTE the properties block with ID this lets you reference this table and make a random selection from the table.\n\n    \n    #+BEGIN_SRC org\n     * Common Items\n       :PROPERTIES:\n        :ID: common-items\n       :END:\n\n\t|            Item Name             |      Type     | Attuned | Source |                                    Link                                   |\n\t|----------------------------------+---------------+---------+--------+---------------------------------------------------------------------------|\n\t| Armblade                         | Weapon        | Attuned | E:RLW  | http://dnd5e.wikidot.com//wondrous-items:armblade                         |\n\t| Armor of Gleaming                | Armor         | -       | XGE    | http://dnd5e.wikidot.com//wondrous-items:armor-of-gleaming                |\n\t| Bead of Nourishment              | Wondrous Item | -       | XGE    | http://dnd5e.wikidot.com//wondrous-items:bead-of-nourishment              |\n\t| Bead of Refreshment              | Wondrous Item | -       | XGE    | http://dnd5e.wikidot.com//wondrous-items:bead-of-refreshment              |\n\t| Boots of False Tracks            | Wondrous Item | -       | XGE    | http://dnd5e.wikidot.com//wondrous-items:boots-of-false-tracks            |\n\t| Bottle of Boundless Coffee       | Wondrous Item | -       | SCC    | http://dnd5e.wikidot.com//wondrous-items:bottle-of-boundless-coffee       |\n\t| Breathing Bubble                 | Wondrous Item | -       | EGW    | http://dnd5e.wikidot.com//wondrous-items:breathing-bubble                 |\n      \n    #+END_SRC\n\n\n** Timechart Initial Experiment\n    - New VERY experimental feature. Much like an agenda we have the timechart. This is a table that can be inserted anywhere from todo's.\n      Much like a clocktable dynamic block / report. \n      However this maps effort vs spent, who has been assigned to a task (if desired) and done tasks, more than your standard clock report.\n    - My thought is to make it possible to dump out one of these and eventually automatically output as several gantt chart options as well.\n    - First version is outputting to mermaid. It is not fully ready for consumption but can be experimented with for those that are adventurous.\n\n"
  },
  {
    "path": "messages/1.2.51.org",
    "content": "* 1.2.51\n** FIXED Date only labels were confounding some TODO reports causing an assert.\n   - This would manifest as a blank todo list when the todo had a date but no time, this has been fixed\n\n\n** Timesheet / Timechart\n   Still an experimental feature\n\n   - Org Choose Timesheet command acts like Agenda Choose View and uses the same list.\n   - Mermaid and an Html visualiztion experiment.\n\n** Clocking\n   New command Org Update Active Clock Command\n   - updates the start time in the clock info file.\n\n** Todo view rebinds:\n\tThese allow editing of task state in a todo view which is handy for planning purposes\n\n    { \"keys\": [\"t\"],                 \"command\": \"org_agenda_change_todo\",            \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"s\"],                 \"command\": \"org_agenda_change_todo\",            \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"e\"],                 \"command\": \"org_agenda_insert_effort\",          \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"i\"],                 \"command\": \"org_agenda_id\"           ,          \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"t\"],                 \"command\": \"org_agenda_insert_tag\",             \"context\": [{ \"key\": \"eol_selector\", \"operand\": \"source.orgagenda\"}]  },\n    { \"keys\": [\"a\"],                 \"command\": \"org_agenda_assign\",          \n\n\n*** New Agenda Todo List Type\n    Has Status - Lists all todos regardless of status or presence in a project. Useful if you want to filter you tasks by tag or property instead\n\n*** Todo table adjustable column width\n    the column statements now take format specifiers: >12.12 (right justify 12 characters min x 12 characters max) \n\n    #+BEGIN_SRC js\n        \"Recent\":   [\"Done : -5d : hasclose : showdate >12.12 : showtime : sortdescend : showid : showeffort : showafter : showassigned\"],\n      \n    #+END_SRC\n\n** Tables\n\n*** FIXED Executing all tables clears all highlights\n    - Still need better highlight management but this improves things slightly when recomputing all tables\n\n*** FIXED Table Cache\n    - At times the table cache was getting out of sync due to invalid dirty buffer checks. This could cause the highlighting of cells in a page with\n      multiple tables to go wonky. I believe I have fixed this now but this is a complex issue to fully track down.\n\n*** New Sum Functions\n    - vsumifeq(a,b,range) - will sum all cells in range where a == b \n    - vsumifgt(a,b,range) - will sum all cells in range where a > b\n    - vsumiflt(a,b,range) - will sum all cells in range where a < b\n    - vsumifgteq(a,b,range) - will sum all cells in range where a >= b\n    - vsumiflteq(a,b,range) - will sum all cells in range where a <= b\n\n    In the blow example I am computing the damage tally for John by adding up all damage values during combat where john has been hit\n      #+BEGIN_SRC org\n      ** Combat\n        #+NAME: Combat-Action\n        | Player | Damage |     |\n        |--------+--------+-----|\n        | John   | 15     |     |\n        |--------+--------+-----|\n        | I Hit  | Who    | For |\n        |--------+--------+-----|\n        | Sam    | John   | 10  |\n        | John   | Sam    | 1   |\n        | Sam    | John   | 5   |\n        #+TBLFM: @2$2=vsumifeq($2,'John',@4$3..@>$3) \n      #+END_SRC\n\n*** Color Shortcut functions\n   - red(cell):\n   - green(cell):\n   - yellow(cell):\n   - blue(cell):\n   - cyan(cell):\n   - purple(cell):\n   - orange(cell):\n   - pink(cell):\n\n   This would highlight a cell red if a players current hp is less than 10% and green otherwise:\n\n   #+BEGIN_SRC org\n   #+NAME: Player-Stats\n   | Player | Start Health | Temp Hits | AC | Damage | Cur Hp | Initiative |\n   |--------+--------------+-----------+----+--------+--------+------------|\n   |        |           13 |         0 |    |      1 |     12 |            |\n   #+TBLFM:$6=($2+$3)-$5::%6=highlight($6,\"red\",$6) if((($6)/$2)*100.0)<=10.0 else highlight($6,\"green\",$6)\n   #+END_SRC\n\n   But it can now be rewritten as:\n\n   #+BEGIN_SRC org\n   #+NAME: Player-Stats\n   | Player | Start Health | Temp Hits | AC | Damage | Cur Hp | Initiative |\n   |--------+--------------+-----------+----+--------+--------+------------|\n   |        |           13 |         0 |    |      1 |     12 |            |\n   #+TBLFM:$6=($2+$3)-$5::%6=red($6) if((($6)/$2)*100.0)<=10.0 else green($6)\n   #+END_SRC\n\n\n*** Gradient Shortcut\n    \n    Better yet, avoid all the if else and use the new gradient method:\n\n    - gradient(cell, progress_out_of_100, *colors) - Will choose a color sequentially out of the colors list based on the progress value:\n\n    In the following example the Bridand would have a red Cur Hp and the Rabid Wolf will have a green Cur Hp value when the table is evaluated\n\n    #+BEGIN_SRC org\n     ** Monsters\n        #+NAME: Monster-Stats\n        |    Name    | Start Health | Damage | Cur Hp | AC | Initiative |\n        |------------+--------------+--------+--------+----+------------|\n        | Brigand    |           10 |      9 |      1 |  4 |            |\n        | Rabid Wolf |           10 |      2 |      8 |  2 |            |\n        #+TBLFM:$4=$2-$3::$4=gradient($4,($4/$2)*100.0, \"red\",\"orange\",\"yellow\",\"cyan\",\"green\")\n    #+END_SRC"
  },
  {
    "path": "messages/1.2.52.org",
    "content": "* 1.2.52\n** FIXED Html Exporter\n   - The html exporter was crashing downloading HighlightJs with some odd SSL certificate errors.\n   - The exporter may still have a few problems as it was converted recently.\n     Please report any problems you may experience.  \n\n   [[https://github.com/ihdavids/orgextended/issues/69][Github Issue]] \n   Thanks berteh for finding this one.\n\n\n"
  },
  {
    "path": "messages/1.2.53.org",
    "content": "* 1.2.53\n** FIXED Mermaid JS source blocks\n\n  The mermaid source block handler was using an old default command line for mermaid.\n  You should now specify mmdc.ps1 on windows:\n\n  #+BEGIN_SRC js\n    \"mermaid\": \"C:\\Users\\ihdav\\node_modules\\.bin\\mmdc.ps1\", \n  #+END_SRC\n\n  On windows this will allow the following to run properly\n  \n  #+BEGIN_SRC mermaid :file mermaidout.png\n  flowchart TD\n    Start --> Stop\t\n  #+END_SRC\n\n** FIXED Org Capture\n   - If the user had a list as their dayPagePath variable org capture would crash.\n     Improved symbol expansion reliability a little bit.\n   - File creation in directory that does not exists was not working. This should now be fixed\n\n** FIXED Reveal JS Exporter\n   Reveal js had moved on since the last time I used the exporter. Derusting is required to get it\n   functional again.\n\n   - [x] Reveal js exporter was missing Escape method of embedded source blocks\n\n   Please note when using reveal exporter that if slides have to much content they will become jumbled.\n   The layout is somewhat simplistic\n"
  },
  {
    "path": "messages/1.2.54.org",
    "content": "* 1.2.54\n** 3.8 Upgrade\n   Package upgraded to the 3.8 runtime.\n   TextTable plugin is still running on 3.3 but orgextended itself\n   is now running on 3.8 for greater performance and cleanliness.\n\n   NOTE: YOU WILL NEED TO RESTART SUBLIME TEXT SEVERAL TIMES TO ALLOW \n         DEPENDENCIES TO INSTALL AND UPGRADE.\n\n   I have run into some problems where the dateutil.rrule package will not update from the 3.3 version\n   to the 3.8 version.\n   \n   The only solution I have found is to reinstall sublime and then reinstall OrgExtended.\n   This forces the upgrade and allows things to work again.\n\n** Agenda haschildtask filter \n   Thanks to tim3z for his contribution to the agenda:\n\n   - I sometimes need to filter for tasks with/without child tasks\n\n   This adds the following keywords for child tasks\n\n   #+BEGIN_QUOTE\n     haschildtasks\n     nochildtasks\n   #+END_QUOTE\n   \n** Extended default binary formats for links\n   Thanks to dyaso for extending the default binary formats list\n   to include pdfs and word documents.\n\n   #+BEGIN_EXAMPLE\n     \"file_exclude_patterns\": [\n        \"*.pdf\",\n        \"*.doc\",\n        \"*.docx\",\n        \"*.docm\",\n    ],\n   #+END_EXAMPLE\n\n** FIX Agenda Day View Rendering Bug  \n\tFix for: [[https://github.com/ihdavids/orgextended/issues/85][Agenda does not work in ST4]]\t\n\n\tIn recent builds of sublime text 4 The composite Agenda class was only able to render the first view\n\twhen the tab is first opened. I am not sure why. I added a recursive command that draws on a second pass\n\tto work around the issue. This is not ideal but it at least gets things rendering again.\n\n** FIX Todo View Not Rendering in ST4\n   Fix for: [[https://github.com/ihdavids/orgextended/issues/80][Org Todo View command shows an empty file, despite TODOs existing in tracked files]] \n   This seems to have been the same issue as the Day View Rendering bug.\n   When the tab pops up the first write attempt to the buffer seems to not be accepted until control \n   has been returned to ST. I have made the command recursive to fix the issue.\n\n   - The same problem also existed with Org Agenda Custom View which is consumed by Org Choose Custom View\n\n   Overall these are all the same issue and something that has developed in modern versions of Sublime Text. I am not sure \n   what has caused this but I suspect some of the read only features I am using are perhaps asynchronous events in some fashion and\n   I may be racing with some internal message pump I do not fully understand vs my plugin thread.\n\n** FIX Agenda Week View Lineup With Week\n   Some previous changes to the week view had it a week off from the current day.\n   This has been fixed\n\n** FIX Color Scheme Genereator\n   Fix for: [[https://github.com/ihdavids/orgextended/issues/83][Generated color schemas (partially) use camelCase instead of snake_case]]\n\n   If you follow the [[https://github.com/ihdavids/orgextended_docs/blob/master/setup.org#color-scheme-generator][Color Scheme Generator]] instructions the generator seems to sometimes generate a:\n   lineHighlight global vs line_highlight. This is an odd quirk that seems to manifest itself when parsing some\n   existing color schemes. That camelCase version comes FROM the parsed version of the color scheme and I am not sure why.\n   We now account for this and export a line_highlight variant that matches the lineHighlight version in the globals.\n\n** FIX Agenda View Overlap Sorting\n   Fix for: [[https://github.com/ihdavids/orgextended/issues/86][Overlapping events can appear out of order in the Agenda timeline]] \n\n   Thanks to r4dian for reporting. \n\n   This particular issue only seemed to happen if you moved to a previous day in the agenda. The time list was not being sorted properly\n   resulting in times appearing out of order during the day.\n   \n** List Sort Docs\n   There was confusion over the simplistic Org Sort List command.\n   I added some quick docs to help demonstrate how that command works. It currently does not work on headings. \n   Contributions welcome. \n\n   [[https://github.com/ihdavids/orgextended_docs/blob/master/lists.org#sorting-lists][Org Sort List]] \n\n** List Cookie Issues\n   [[https://github.com/ihdavids/orgextended/issues/84][Cookies are wrongly calculated in lists with checkboxes]]\n\n\n   List cookies:\n   #+BEGIN_EXAMPLE\n      - List [1/2]     \n         - [x] A\n         - [ ] B\n      - List2\n         - [ ] This should NOT be included in list 1\n   #+END_EXAMPLE\n\n   had a problem when list types alternated from unordered lists to checked lists.\n   This is not perfect but has been improved and should now no longer be combined.\n"
  },
  {
    "path": "messages/1.2.55.org",
    "content": "* 1.2.55\n  1.2.54 was a maintenance release with the goal of sorting some of the more \n  painful reported issues people were struggling with.\n\n  This release is about trying to clear the Issue list of any requested features.\n  This is all in preparation for my next big personal feature push.\n\n  I have been sort of forced to work in VSCode for the last few years and as such I have\n  built a similar plugin to this one for VSCode (although I have not officially released it)\n\n  That plugin took a slightly different route. As I was faced with the daunting task of \n  duplicating what I had done here, I realized I had been foolish. LSP is a model I should have\n  taken a page from, right from the get go. \n\n  So While there are a ton of highlighting, editing \n  and general movement commands built into the VSCode plugin the database and many of\n  the auto formatting, refiling, capturing etc is done in a sort of org mode server over a rest\n  api. It has always bugged me that this plugin is limited by the editor integration and\n  while this brings org outside of emacs, its still locked into yet another editor.\n\n  My plan is to migrate to some of the ideas I had with the VSCode version wrapping the existing\n  DB in an abstraction so it can consume and work with the orgs server.\n  I hope to offer a choice, either use the built in python DB\n  in this plugin, OR choose to run the orgs server (it's written in Go) externally and get\n  a web portal into your org files and command line capture and other CLI goodness as well\n  as the editor integration. This will be a 2.0 offering of this plugin.\n\n  orgs has other really great features. It has a JIRA integration that allows the creation of JIRA\n  tickets from org files and syncing JIRA to an org file. It has a nice auto git sync option\n  and some new exporters like a latex exporter that supports the DnD2Latex project, impressjs \n  AND reveal exporter and an extensible, universal todo query language instead of the hacky thing\n  I built into the Agenda system in this plugin.\n\n  My end game here is that I would like to provide an LSP like setup for org-mode that \n  can be used from any editor, but takes org outside of my editor in a variety of ways.\n  This will have the benefit that:\n\n  - Org is in your editor and can be ported to others without re-inventing the wheel.\n  - Using Orgs allows for an HTML portal rendering your org files directly to your browser or phone\n    helping with the challenge of using org on mobile.\n  - Support the org-protocol capture mechanism\n  - Access, refile, tag and search your orgs from your command line.\n  - Supports integration into other tools like JIRA, Trello, Confluence, Todoist, Ad nauseum.\n  - Supports a framework for exporting from org to other formats and importing from other formats to org.\n  - Provides really powerful and comprehensive search tools for your data.\n  - Is extensible enough I can integrate with beancount or other great text based finance tools with literate programming style\n    reports, combined with the exporters offering all the invoicing, and other integrations I really appreciate.\n  - Takes the dynamic burden of execution and refiling et al off the editor itself and pushes it squarely on a capable backend.\n    In the past, chasing after updates in how the editor handles reloading of files has been a serious issue.\n  - Is flexible enough, but also lightweight enough that you can use it in a ton of different creative ways.\n\n  Anyways, BEFORE I get to working on the orgs integration, I really wanted to spend some time to cleanup anything that \n  has been frustrating those people that have been on this journey with me and have been trying to use this thing.\n  I sincerely hope you get value out of it.\n\n** OrgCapture New File added TAGS instead of FILETAGS\n   - OrgCapture when it creates a new file was adding TAGS: refile vs FILETAGS: :refile:\n\n** Org Archive All Done Command\n\tStuk asked for a command to archive all todos with a DONE status.\n\tThis first version of the command is simplistic and hardcoded to DONE status but it will\t\n\titerate through a buffer and archive all the DONE TODOS.\n\n    [[https://github.com/ihdavids/orgextended/issues/72][Archive all DONE tasks]]\n"
  },
  {
    "path": "messages/1.2.56.org",
    "content": "* 1.2.56\n** htmlDefaultSkipSrc Not Respected\n\tBugFix htmlDefaultSkipSrc was not being respected\n\twhen exporting to html. Thanks to bradleysmith who found that ditaa source\n\tblocks were exporting both the image and the source to\n\thtml files even when ditaa was listed as a source skip block\n\n\tThe plist system by its nature overrides this list if explicitly stated. \n\tInternally we did not have a way of determining if a user had explicitly \n\tset an exports mode or if we were operating in the default\n\tstate. The system now has a default setting allowing this to work again.\n\n\t[[https://github.com/ihdavids/orgextended/issues/90][htmlDefaultSkipSrc ignores ditaa]]"
  },
  {
    "path": "messages/1.2.6.org",
    "content": "* 1.2.6\n  Core Idea: Inline Babel Blocks\n             #+header: comments\n\n  With this release we are focusing on some fringe pieces\n  of the core babel feature set that we need to be complete.\n\n  Inline babel blocks allow you to call a babel function within\n  some other text providing even more dynamic living breathing documents.\n\n  Header blocks extend the core babel features providing more real estate to add\n  parameters to a source block.\n\n** Links\n\t- Bugfix thanks to Anti-Distinctlyminty - on windows uses os.startfile() to launch a file link\n\t  providing better support for out of sublime file links. Also some improved error notation\n\t  in the contols when a link cannot resolve.\n** Agenda Hover\n\t- Sometimes this would assert when the agenda was not active.\n\n** Settings orgDirs\n\t- If someone sets their orgDirs to a string vs a list we would treat each character as an orgDir\n\t\twhich was just plain wrong. I have augmented the db to detect that and just \"do the right thing\"\n\n** Input\n\t- Additional guards against asserts in popups for the input box:\n\t  [[https://github.com/ihdavids/orgextended/issues/28][Errors in Sublime Console]]\n\n\t  Thanks to OlegBc for finding this one.\n\n** Inline Blocks\n\n\tBasic inline source block syntax highlighting now works. \n\tOrg has a somewhat odd inline syntax:\n\n\tsrc_python[:var x=5]{print(\"hello\" + str(x))} {{{results(=hello5=)}}}       \n\n\tSimple execution seems to be working:\n\n\tsrc_powershell{Write-Host \"Hello World\"} {{{results(=Hello World=)}}} \n\n** PList Enhancements\n\t- Plists now have propper exclusion properties so :results output value will only have the last value\n\t\tsince the options are considered mutually exclusive.\n\t- The unit tests have been enhanced to cover exclusivity.\n\t- Source blocks now have a global setting allowing you to control their default behaviour globally.\n\t  this is inline with what you can do in emacs with: org-babel-default-header-args\n\n\t\n\t\t#+BEGIN_EXAMPLE\n\t\t\t\t\"orgBabelDefaultHeaderArgs\": \":var x=5\"\n\t\t#+END_EXAMPLE\t\n\n** HEADER comments\n\n\tAdded support for the more generic HEADER comment blocks as seen below.\n\n\t#+HEADER: :var y=10\n\t#+BEGIN_SRC python :var x=5\n\t  print(str(y) + \" x \" + str(x))\n\t#+END_SRC\n\n   #+RESULTS:\n   : 10 x 5\n\n** Buffer Swap Respects Startup Comment\n\n\tI find that as I move around the buffer I tend to unfold a lot of \"things\"\n\tWhen I have a buffer set to \"content\" mode I like it to clean up the open folds when it can.\n\t\n\tThis new setting will allow sublime to aggressively cleanup the folds to just your active subtree\n\tof the file if you turn this on.\n\n\tWhat I really want is org-narrow-to-subtree which is the ability to restrict a view to a narrowing of the buffer\n\tbut in the absence of that capability this helps keep me focused on the\n\tthings that matter in my file.\n\n\t- This is controlled by a setting:\n\n\t#+BEGIN_EXAMPLE\n\t  \"onFocusRespectStartupFolds\": true,\n\t#+END_EXAMPLE\n\n\n"
  },
  {
    "path": "messages/1.2.7.org",
    "content": "* 1.2.7\n\tCore Idea: Quality of Life\n\n\tThis release is about stability, testing and validating the core babel feature set before I move on to noweb and tangle.\n\n** Babel Unit Tests\n\t- Having most of the core babel features in place we have started to work towards\n\t  validating the core babel feature set and putting a rough stamp of non preview on\n\t  the babel feature set.\n\n\t- Added \"Org Show Table Tests\" and \"Org Show Source Block Tests\" which will create a file with the unit tests\n\t  for these features as a means of documentation and exploration for new users.\n\n  - FIXED: Issues with multiple :var statements on the fence line of a babel block.\n  - FIXED: Exception with initial inserts with drawer formatter. \n\n** SBE\n\n\t- FIXED: The Source Block Execute method had a bug that was preventing propper execution due to some\n\t  of the features introduced in 1.2.6\n\t- FIXED: cell being passed to an sbe function would sometimes not evaluate properly.\n\n** Table Execution\n\t- New command: \"Org Execute Formula\" This will only execute the formula targetting the current cell vs the entire table.\n\t  This can help when building a table.\n\n** Table Highlights\n\t- Some expressions using SBE can get fairly expensive to compute. When highlighting cells the system executes\n\t  formulas in the background to determine which cells the formula touches. To avoid paying that cost when moving\n\t  around you can turn this off for a node in the heirarchy as follows:\n\n\t  #+BEGIN_EXAMPLE\n      :PROPERTIES:\n        :NoTableHighlight: True\n      :END:\n\t  #+END_EXAMPLE\n\n\t  I had to do this for the unit tests since our unit tests were generating diagrams as a result of the sbe calls\n\t  Although an unrealistic real world case, this was slowing down the highlight to be somewhat unusable so merited\n\t  the feature.\n\n** Day Page\n\t- olegBc asked for a day page system. The project still has a little definition before we know where we need to take it.\n\t  That said, I added a text command to create a day page as a first little step in that direction.\n"
  },
  {
    "path": "messages/1.2.8.org",
    "content": "* 1.2.8\n\t- 1.2.7 was missing a source file. This fixes that."
  },
  {
    "path": "messages/1.2.9.org",
    "content": "* 1.2.9\n\n** Babel Cache\n   Caching will try to avoid executing a block if the source and or parameters have not changed.\n   Caching uses a Sha1 hash of the source and parameter mix to determine if it should re-run the\n   block.\n\n   This mode is dangerous if the operation has any side effects.\n\n   It does  however skip execution when the operation is already present.\n   It will keep a hash of the source and params and will only execute\n   if the source does not change.\n\n\t#+BEGIN_SRC python :cache yes :var x=5 :tangle yes\n\t  print(\"Hello world\") \n\t#+END_SRC\n\n\tThis feature is not yet well tested with source block chaining.\n\n   #+RESULTS[5ce4498b4cf15deb48101207ad5673485754fd11]:\n   : Hello world\n\n** Never Eval\n\tA security feature of org is that you can specify that a block should never execute.\n\tThis is now mostly working.\n\n\t#+BEGIN_SRC python :eval never\n\t\tprint(\"hi\")\t  \n\t#+END_SRC\n\n** Query Eval\n\n\tQuery evaluation is mostly working now although the title of the query prompt is not great.\n\n\t#+BEGIN_SRC python :eval query :tangle yes\n\t  print(\"Hello World\")\n\t#+END_SRC\n\n   #+RESULTS:\n   : Hello World\n\n** Tangle\n   This release marks the begining of tangle work. Marking a source block as tangleable\n   allows someone to export just the source code to a \"detangled\" file containing the source code and data\n   from the page without the rest of the document. \n   The resulting file will have the name of the the org file with the appropriate file extension\n   for the source code.\n\n   We get a new command with this release:\n\n   - Org Tangle File\n\n   #+BEGIN_SRC powershell :var y=5 :tangle yes\n   \tWrite-Host(\"Hello World\")\n   #+END_SRC"
  },
  {
    "path": "messages/gantt-demo.org",
    "content": "\n#+PROPERTY: header-args:R  :session *R*\n#+PROPERTY: header-args    :results silent\n#+COLUMNS: %ITEM(Task) %Effort(Effort) %START(Start) %END(End) %RESPONSIBLE(Responsible) %SPENT(Spent) %PROGRESS(Progress) %PROJECTED(Projected) %OVERUNDER(Over_Under)\n\n* Task 1\n   :PROPERTIES:\n     :Effort: 1d\n   :END:\n* Task 2\n   :PROPERTIES:\n     :Effort: 3d\n   :END:\n* Task 3\n   :PROPERTIES:\n     :Effort: 4d\n   :END:\n* Gantt Demo                                                              :Skip:\n    \n  \n  #+NAME: gantt-table\n  #+BEGIN: columnview :exclude-tags (Skip)\n  |  Task  | Effort |      Start       |       End        | Responsible | Spent | Progress | Projected | Over_Under |\n  |--------+--------+------------------+------------------+-------------+-------+----------+-----------+------------|\n  | Task 1 | 1d     | <2021-03-13 Sat> | <2021-03-14 Sun> | Ian         |     1 | 40%      |      2.50 | 1d 12h     |\n  | Task 2 | 3d     | <2021-03-15 Mon> | <2021-03-18 Thu> | Joe         |     2 | 10%      |     20.00 | 17d        |\n  | Task 3 | 4d     | <2021-03-18 Thu> | <2021-03-22 Mon> | Sam         |     1 | 50%      |      2.00 | 2d         |\n  | Task 4 | 7d     | <2021-03-18 Thu> | <2021-03-25 Thu> | Sam         |     1 | 50%      |      2.00 | 5d         |\n  | Task 5 | 1d     | <2021-03-18 Thu> | <2021-03-19 Fri> | Sam         |     1 | 50%      |      2.00 | 1d         |\n  | Task 6 | 2d     | <2021-03-18 Thu> | <2021-03-20 Sat> | Sam         |     1 | 35%      |      2.86 | 20h 38mins |\n  #+END:\n  #+TBLFM:$4=date($-1)+duration($-2) if \"$-1\"!=\"\" else \"\"::$8=$-2/$-1 if $-1 > 0 else \"\";%.2f::$9=duration($2) - $-1 if $-1>0 else \"\"\n\n\n   #+BEGIN_SRC gnuplot :var DATA=gantt-table :file gantt-table.png\n    OneMonth = strptime(\"%m\",\"2\")\n    timeformat = \"%Y-%m-%d\"\n    T(N) = timecolumn(N,timeformat)\n\n    set xdata time\n    set format x \"%b\\n'%y\"\n    set xtics OneMonth nomirror\n    set xtics scale 2, 0.5\n    set mxtics 4\n\n    skiptorow=3\n    set yrange [(skiptorow-2):] reverse\n    set ytics nomirror\n\n    unset key\n    set title \"{/=15 GANTT Chart Example}\"\n    set grid x y\n    set border 3\n    set style arrow 1 nohead filled size screen 0.02, 15 fixed lt 3 lw 8\n\n    plot \"$DATA\" using (T(3)) : ($0) : (T(4)-T(3)) : (0.0) : yticlabel(1) with vector as 1 \n   #+END_SRC\n\n  #+RESULTS:\n  [[file:gantt-table.png]]\n"
  },
  {
    "path": "messages/install.org",
    "content": "* Initial release of Org Extended\n\n  AFTER YOU INSTALL FOR THE FIRST TIME: LET IT RUN FOR ABOUT 60 SECONDS AND RESTART SUBLIME.\n  WE INSTALL SOME DEPENDENCIES AND ARE NOT VERY GOOD ABOUT LETTING YOU KNOW THAT YOU\n  NEED TO RESTART SUBLIME!\n\n  Setup instructions can be found here:\n  https://github.com/ihdavids/orgextended_docs/blob/master/start.org\n\n  Org Mode in Emacs is an extensive lifestyle plugin.\n  This plugin couldn't hope to duplicate the full expanse of\n  Emacs org mode. That said, this plugin attempts to provide\n  some of the amazing functionality found in Emacs org mode\n  right here in sublime text!\n\n  Org Mode IS: https://orgmode.org \n\n  - A document interchange format\n  - A personal wiki\n  - A task and project management toolset\n  - An agenda\n  - A means of building living documents known as literate programming\n  - The backend for blogs, webpages, and an outliner for authors.\n  - A tool for authoring presentations.\n  - A time tracking tool\n  - A spreadsheet and data management tool\n  - And much much more. \n\n  This plugin is written selfishly as a means of helping\n  me stay organized. It comes with no warranty whatsoever.\n  It is my hope that you still find it useful."
  },
  {
    "path": "messages.json",
    "content": "{\n\t\"install\": \"messages/install.org\",\n\t\"1.0.0\": \"messages/install.org\",\n\t\"1.0.1\": \"messages/1.0.1.org\",\n\t\"1.0.2\": \"messages/1.0.2.org\",\n\t\"1.0.3\": \"messages/1.0.3.org\",\n\t\"1.0.4\": \"messages/1.0.4.org\",\n\t\"1.0.5\": \"messages/1.0.5.org\",\n\t\"1.0.6\": \"messages/1.0.6.org\",\n\t\"1.0.7\": \"messages/1.0.7.org\",\n\t\"1.0.8\": \"messages/1.0.8.org\",\n\t\"1.0.9\": \"messages/1.0.9.org\",\n\t\"1.0.10\": \"messages/1.0.10.org\",\n\t\"1.1.0\": \"messages/1.1.0.org\",\n\t\"1.1.1\": \"messages/1.1.1.org\",\n\t\"1.1.2\": \"messages/1.1.2.org\",\n\t\"1.1.3\": \"messages/1.1.3.org\",\n\t\"1.1.4\": \"messages/1.1.4.org\",\n\t\"1.1.5\": \"messages/1.1.5.org\",\n\t\"1.1.6\": \"messages/1.1.6.org\",\n\t\"1.1.7\": \"messages/1.1.7.org\",\n\t\"1.1.8\": \"messages/1.1.8.org\",\n\t\"1.1.9\": \"messages/1.1.9.org\",\n\t\"1.1.10\": \"messages/1.1.10.org\",\n\t\"1.1.11\": \"messages/1.1.11.org\",\n\t\"1.1.12\": \"messages/1.1.12.org\",\n\t\"1.1.13\": \"messages/1.1.13.org\",\n\t\"1.1.14\": \"messages/1.1.14.org\",\n\t\"1.1.15\": \"messages/1.1.15.org\",\n\t\"1.1.16\": \"messages/1.1.16.org\",\n\t\"1.1.17\": \"messages/1.1.17.org\",\n\t\"1.1.18\": \"messages/1.1.18.org\",\n\t\"1.1.19\": \"messages/1.1.19.org\",\n\t\"1.1.20\": \"messages/1.1.20.org\",\n\t\"1.1.21\": \"messages/1.1.21.org\",\n\t\"1.1.22\": \"messages/1.1.22.org\",\n\t\"1.1.23\": \"messages/1.1.23.org\",\n\t\"1.1.24\": \"messages/1.1.24.org\",\n\t\"1.1.25\": \"messages/1.1.25.org\",\n\t\"1.1.26\": \"messages/1.1.26.org\",\n\t\"1.1.27\": \"messages/1.1.27.org\",\n\t\"1.1.28\": \"messages/1.1.28.org\",\n\t\"1.1.29\": \"messages/1.1.29.org\",\n\t\"1.1.30\": \"messages/1.1.30.org\",\n\t\"1.2.0\": \"messages/1.2.0.org\",\n\t\"1.2.1\": \"messages/1.2.1.org\",\n\t\"1.2.2\": \"messages/1.2.2.org\",\n\t\"1.2.3\": \"messages/1.2.3.org\",\n\t\"1.2.4\": \"messages/1.2.4.org\",\n\t\"1.2.5\": \"messages/1.2.5.org\",\n\t\"1.2.6\": \"messages/1.2.6.org\",\n\t\"1.2.7\": \"messages/1.2.7.org\",\n\t\"1.2.8\": \"messages/1.2.8.org\",\n\t\"1.2.9\": \"messages/1.2.9.org\",\n\t\"1.2.10\": \"messages/1.2.10.org\",\n\t\"1.2.11\": \"messages/1.2.11.org\",\n\t\"1.2.12\": \"messages/1.2.12.org\",\n\t\"1.2.13\": \"messages/1.2.13.org\",\n\t\"1.2.14\": \"messages/1.2.14.org\",\n\t\"1.2.15\": \"messages/1.2.15.org\",\n\t\"1.2.16\": \"messages/1.2.16.org\",\n\t\"1.2.17\": \"messages/1.2.17.org\",\n\t\"1.2.18\": \"messages/1.2.18.org\",\n\t\"1.2.19\": \"messages/1.2.19.org\",\n\t\"1.2.20\": \"messages/1.2.20.org\",\n\t\"1.2.21\": \"messages/1.2.21.org\",\n\t\"1.2.22\": \"messages/1.2.22.org\",\n\t\"1.2.23\": \"messages/1.2.23.org\",\n\t\"1.2.24\": \"messages/1.2.24.org\",\n\t\"1.2.25\": \"messages/1.2.25.org\",\n\t\"1.2.26\": \"messages/1.2.26.org\",\n\t\"1.2.27\": \"messages/1.2.27.org\",\n\t\"1.2.28\": \"messages/1.2.28.org\",\n\t\"1.2.29\": \"messages/1.2.29.org\",\n\t\"1.2.30\": \"messages/1.2.30.org\",\n\t\"1.2.31\": \"messages/1.2.31.org\",\n\t\"1.2.32\": \"messages/1.2.32.org\",\n\t\"1.2.33\": \"messages/1.2.33.org\",\n\t\"1.2.34\": \"messages/1.2.34.org\",\n\t\"1.2.35\": \"messages/1.2.35.org\",\n\t\"1.2.36\": \"messages/1.2.36.org\",\n\t\"1.2.37\": \"messages/1.2.37.org\",\n\t\"1.2.38\": \"messages/1.2.38.org\",\n\t\"1.2.39\": \"messages/1.2.39.org\",\n\t\"1.2.40\": \"messages/1.2.40.org\",\n\t\"1.2.41\": \"messages/1.2.41.org\",\n\t\"1.2.42\": \"messages/1.2.42.org\",\n\t\"1.2.43\": \"messages/1.2.43.org\",\n\t\"1.2.44\": \"messages/1.2.44.org\",\n\t\"1.2.45\": \"messages/1.2.45.org\",\n\t\"1.2.46\": \"messages/1.2.46.org\",\n\t\"1.2.47\": \"messages/1.2.47.org\",\n\t\"1.2.48\": \"messages/1.2.48.org\",\n\t\"1.2.49\": \"messages/1.2.49.org\",\n\t\"1.2.50\": \"messages/1.2.50.org\",\n\t\"1.2.51\": \"messages/1.2.51.org\",\n\t\"1.2.52\": \"messages/1.2.52.org\",\n\t\"1.2.53\": \"messages/1.2.53.org\",\n\t\"1.2.54\": \"messages/1.2.54.org\",\n\t\"1.2.55\": \"messages/1.2.55.org\",\n\t\"1.2.56\": \"messages/1.2.56.org\"\n}"
  },
  {
    "path": "orgagenda.py",
    "content": "import re\nimport os\nimport time\nimport sublime, sublime_plugin\nimport datetime\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nimport OrgExtended.orgparse.date as orgdate\nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport OrgExtended.orgduration as dur\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.orgdatepicker as dpick\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orginsertselected as insSel\nimport calendar\n\nimport dateutil.rrule as dr\nimport dateutil.parser as dp\nimport dateutil.relativedelta as drel\n\nlog = logging.getLogger(__name__)\nAGENDA_VIEW = \"Org Mode Agenda\"\nTODO_VIEW   = \"Org Todos\"\n\nViewMappings = {}\n\n\ndef ReloadAllUnsavedBuffers():\n    sheets = sublime.active_window().sheets()\n    for sheet in sheets:\n        view = sheet.view()\n        if(view and util.isPotentialOrgFileOrBuffer(view)):\n            db.Get().FindInfo(view)\n\ndef IsRawDate(ts):\n    return isinstance(ts,datetime.date) or isinstance(ts,datetime.datetime)\n\ndef EnsureDateTime(ts):\n    if(ts and not isinstance(ts,datetime.datetime)):\n        return datetime.datetime.combine(ts, datetime.datetime.min.time())\n    return ts\n\ndef EnsureDate(ts):\n    if(isinstance(ts,datetime.datetime)):\n        return ts.date()\n    return ts\n\ndef FindMappedView(view):\n    if(view.name() in ViewMappings):\n        return ViewMappings[view.name()]\n    log.debug(\"Could not find view named: \" + view.name())\n    return None\n\ndef move_file_other_group(myview, view):\n    window = sublime.active_window()\n    if (window.num_groups() < 2):\n        #self.window.run_command('clone_file')\n        window.set_layout({\n            \"cols\": [0.0, 0.5, 1.0],\n            \"rows\": [0.0, 1.0],\n            \"cells\": [[0, 0, 1, 1], [1, 0, 2, 1]]\n            })\n        mygroup    = 0\n        othergroup = 1\n    else:\n        window.focus_view(view)\n        mygroup    = 1\n        othergroup = 0\n        if (window.get_view_index(myview)[0] == 0):\n            othergroup = 1\n            mygroup    = 0\n    window.focus_view(view)\n    window.run_command('move_to_group', {'group': othergroup})\n    window.run_command('focus_group', {'group': mygroup})\n    window.focus_view(myview)\n        #view0 = self.window.active_view_in_group(0)\n        #view1 = self.window.active_view_in_group(1)\n\n        # Same file open in each of the two windows, cull to 1 if possible\n        #if (view0.file_name() == view1.file_name()):\n        #    self.window.focus_view(view1)\n\n#class CloneFileToNewViewCommand(sublime_plugin.WindowCommand):\n#    def run(self):\n\ndef get_view_for_silent_edit_file(file):\n    # First check all sheets for this file.\n    window = sublime.active_window()\n    view = window.find_open_file(file.filename)\n    if(view):\n        return view\n    # Okay the file is not opened, we have to open it\n    # but we don't want it having focus\n    # So keep the old view so we can refocus just to\n    # be sure.\n    currentView = window.active_view()\n    view = window.open_file(file.filename, sublime.ENCODED_POSITION)\n    window.focus_view(currentView)\n    return view\n\ndef CreateUniqueViewNamed(name, mapped=None):\n    # Close the view if it exists\n    win = sublime.active_window()\n    for view in win.views():\n        if view.name() == name:\n            win.focus_view(view)\n            win.run_command('close')\n    win.run_command('new_file')\n    view = win.active_view()\n    view.set_name(name)\n    # TODO: Change this.\n    view.set_syntax_file(\"Packages/OrgExtended/orgagenda.sublime-syntax\")\n    ViewMappings[view.name()] = mapped\n    return view\n\n\ndef IsPhone(n):\n    return n and n.todo and \"PHONE\" in n.todo\n\ndef IsMeeting(n):\n    return n and n.todo and \"MEETING\" in n.todo\n\ndef IsNote(n):\n    return n and n.todo and \"NOTE\" in n.todo\n\ndef IsTodo(n):\n    return n.todo and n.todo in n.env.todo_keys\n\ndef IsDone(n):\n    return n.todo and n.todo in n.env.done_keys\n\ndef IsArchived(n):\n    return \"ARCHIVE\" in n.tags\n\ndef HasChildTasks(n):\n    for c in n.children:\n        if(IsTodo(c)):\n            return True\n    return False\n\n# Task that belongs to a project. This means we have to have a parent and that parent has to be\n# identified as a project.\ndef IsProjectTask(n):\n    if(not n or n.is_root()):\n        return False\n    return (IsTodo(n) and n.parent and not n.parent.is_root() and IsProject(n.parent))\n\ndef IsBlockedProject(n):\n    if(IsProject(n) and n.num_children > 0):\n        isBlocked = True\n        for c in n.children:\n            if(c.todo and c.todo == 'NEXT'):\n                isBlocked = False\n        return isBlocked\n    else:\n        return False\n\ndef IsProjectTodoWithTodos(n):\n    if(IsTodo(n) and n.num_children > 0):\n        for c in n.children:\n            if(IsTodo(c)):\n                return True\n    return False\n\ndef IsProjectTaskWithProjectTag(n):\n    if(n):\n        tags = n.shallow_tags\n        if(\"PROJECT\" in tags or \"Project\" in tags or \"project\" in tags):\n            #print(\"PROJ: \" + n.heading)\n            return True\n    return False\n\ndef IsProjectTaskWithProjectProperty(n):\n    if(n and (n.get_property(\"PROJECT\") or n.get_property(\"Project\") or n.get_property(\"project\"))):\n        return True\n    return False\n\ndef IsProject(n):\n    projType = sets.Get(\"agendaProjectIs\", \"nested_todo\").lower()\n    if(projType == \"nested_todo\"):\n        return IsProjectTodoWithTodos(n)\n    if(projType == \"tag\"):\n        return IsProjectTaskWithProjectTag(n)\n    if(projType == \"property\"):\n        return IsProjectTaskWithProjectProperty(n)\n    return IsProjectTodoWithTodos(n)\n\ndef IsTodaysDate(check, today):\n    if(not type(check) == datetime.date):\n        check = check.date()\n    if(not type(today) == datetime.date):\n        today = today.date()\n    return today == check\n\ndef IsInMonthCheck(t, now):\n    if(IsRawDate(t)):\n        dateT = t\n    else:\n        dateT = datetime.date(t.start.year, t.start.month, t.start.day)\n\n    if (dateT.year == now.year):\n        if (dateT.month >= (now.month-1) and dateT.month <= (now.month+1)):\n            return True\n        else:\n            return False\n    if (dateT.year == now.year + 1) and (dateT.month == 0 and now.month == 11):\n        return True\n    if (dateT.year == now.year - 1) and (dateT.month == 11 and now.month == 0):\n        return True\n    return False\n\ndef IsInMonth(n, now):\n    if(not n):\n        return (None,None)\n    if(n):\n        timestamps = n.get_timestamps(active=True,point=True,range=True)\n        for t in timestamps:\n            if(t.repeating):\n                next = t.next_repeat_from(now)\n                if(IsInMonthCheck(next, now)):\n                    if(IsRawDate(t)):\n                        return (now,True)\n                    else:\n                        return (now, True)\n            else:\n                if(IsInMonthCheck(t, now)):\n                    return (t,False)\n        if(n.scheduled):\n            if(IsInMonthCheck(n.scheduled, now)):\n                return (n.scheduled.start,n.scheduled.repeating)\n    return (None,None)\n\ndef IsToday(n, today):\n    # 4 months of per day scheduling is the maximum \n    # we are willing to loop to avoid crazy slow loops.\n    kMaxLoops = sets.GetInt(\"agendaMaxScheduledIterations\", 120)\n    timestamps = n.get_timestamps(active=True,point=True,range=True)\n    for t in timestamps:\n        if(t.repeating):\n            if(IsTodaysDate(t.start, today)):\n                return t\n            next = EnsureDateTime(t.start)\n            loopcount = 0\n            while(next <= EnsureDateTime(today) and loopcount <= kMaxLoops):\n                if IsTodaysDate(next, today):\n                    return next\n                next = t.next_repeat_from(next)\n                loopcount += 1\n        else:\n            if(t.has_overlap(today)):\n                return t\n    if(n.scheduled):\n        if(n.scheduled.repeating):\n            next = n.scheduled.start\n            loopcount = 0\n            while(EnsureDateTime(next) <= EnsureDateTime(today) and loopcount <= kMaxLoops):\n                if IsTodaysDate(next, today):\n                    return next\n                next = n.scheduled.next_repeat_from(EnsureDateTime(next))\n                loopcount += 1\n        else:\n            return n.scheduled.after(today)\n    if(n.deadline):\n        start = EnsureDateTime(n.deadline.deadline_start)\n        if start <= today:\n            return n.deadline\n        if(n.deadline.repeating):\n            next = n.deadline.start\n            loopcount = 0\n            while(EnsureDateTime(next) <= EnsureDateTime(today) and loopcount <= kMaxLoops):\n                if IsTodaysDate(next, today):\n                    return next\n                next = n.deadline.next_repeat_from(EnsureDateTime(next))\n                loopcount += 1\n    return None\n\ndef IsAllDay(n,today):\n    if(not n):\n        return None\n    timestamps = n.get_timestamps(active=True,point=True,range=True)\n    for t in timestamps:\n        if(t.repeating):\n            dt = t.next_repeat_from(today)\n            if(dt.hour == 0 and dt.minute == 0 and dt.second == 0 and dt.microsecond == 0):\n                return dt\n        else:\n            if(t.has_end() or t.has_time()):\n                continue\n            return t\n    if(n.scheduled):\n        if(n.scheduled.repeating):\n            dt = n.scheduled.next_repeat_from(today)\n            if(dt.hour == 0 and dt.minute == 0 and dt.second == 0 and dt.microsecond == 0):\n                return n.scheduled\n        else:\n            if(not n.scheduled.has_end() and not n.scheduled.has_time()):\n                return n.scheduled\n    if(n.deadline):\n        dt = n.deadline.deadline_start\n        if(isinstance(dt,datetime.date)):\n            return True\n        if(dt.hour == 0 and dt.minute == 0 and dt.second == 0 and dt.microsecond == 0):\n            return today\n    return None\n\ndef HasTimestamp(n):\n    if(not n):\n        return False\n    timestamps = n.get_timestamps(active=True,point=True,range=True)\n    return n.scheduled or (timestamps and len(timestamps) > 0) or n.deadline\n\ndef IsInHourBracket(s, e, hour):\n    if(not e):\n        # TODO Make this configurable\n        e = s + datetime.timedelta(minutes=30)\n    # Either this task is a ranged task OR it is a single point task\n    # Ranged tasks have to fit within the hour, point tasks have to \n    if( Overlaps(s.hour*60 + s.minute, e.hour*60 + e.minute, hour*60, hour*60 + 59)):\n        return True\n\n\ndef IsInHour(n, hour, today):\n    if(not n):\n        return None\n    timestamps = n.get_timestamps(active=True, point=True,range=True)\n    if(timestamps):\n        for t in timestamps:\n            if(t.has_time()):\n                if(t.repeating):\n                    next = t.next_repeat_from(today)\n                    if(next.hour == hour):\n                        return next\n                else:\n                    s = t.start\n                    e = t.end\n                    if(IsInHourBracket(s,e,hour)):\n                        return t\n    if(n.scheduled and n.scheduled.has_time()):\n        if(n.scheduled.repeating):\n            next = n.scheduled.next_repeat_from(today)\n            if next.hour == hour:\n                return next\n            else:\n                return None\n        s = EnsureDateTime(n.scheduled.start)\n        e = EnsureDateTime(n.scheduled.end)\n        if(IsInHourBracket(s,e,hour)):\n            return n.scheduled\n    if(n.deadline):\n        s = EnsureDateTime(n.deadline.start)\n        e = EnsureDateTime(n.deadline.end)\n        if(IsInHourBracket(s,e,hour)):\n            return n.deadline\n    return None\n\n\ndef Overlaps(s,e,rs,re):\n    # s | e |\n    # +---+\n    if(s <= rs and e >= rs and e <= re):\n        return True\n    # | s | e\n    #   +---+\n    if(s >= rs and s < re and e >= re):\n        return True\n    # | s  e |\n    #   +-+\n    if(s >= rs and e <= re):\n        return True\n    # s |    | e\n    # +-------+\n    if(s <= rs and e >= re):\n        return True\n    return False\n\ndef IsInHourAndMinuteBracket(s,e,hour,mstart,mend):\n    if(not e):\n        # TODO Make this configurable\n        e = s + datetime.timedelta(minutes=30)\n\n    # Either this task is a ranged task OR it is a single point task\n    # Ranged tasks have to fit within the hour, point tasks have to \n    if( Overlaps(s.hour*60 + s.minute, e.hour*60 + e.minute, hour*60 + mstart, hour*60 + mend)):\n        return True\n    return False\n\ndef IsInHourAndMinute(n, hour, mstart, mend, today):\n    if(not n):\n        return None\n    timestamps = n.get_timestamps(active=True, point=True,range=True)\n    if(timestamps):\n        for t in timestamps:\n            if(t.has_time()):\n                if(t.repeating):\n                    next = t.next_repeat_from(today)\n                    if(next.hour == hour):\n                        return next\n                else:\n                    s = t.start\n                    e = t.end\n                    if(IsInHourAndMinuteBracket(s,e,hour,mstart,mend)):\n                        return t\n\n    if(n.scheduled and n.scheduled.has_time()):\n        if(n.scheduled.repeating):\n            next = n.scheduled.next_repeat_from(today)\n            if(next.hour == hour):\n                return next\n        s = n.scheduled.start\n        e = n.scheduled.end\n        if(IsInHourAndMinuteBracket(s,e,hour,mstart,mend)):\n            return n.scheduled\n\n    if(n.deadline):\n        s = EnsureDateTime(n.deadline.start)\n        e = EnsureDateTime(n.deadline.end)\n        if(IsInHourAndMinuteBracket(s,e,hour,mstart,mend)):\n            return n.deadline\n    return None\n\n\ndef distanceFromStart(e, hour, minSlot):\n    ts = e['ts']\n    if(IsRawDate(ts)):\n        rv = 5*(hour - ts.hour) + (minSlot - int(ts.minute/12))\n    else:\n        rv = 5*(hour - ts.start.hour) + (minSlot - int(ts.start.minute/12))\n    return rv\n\n# ================================================================================\n# IDEA Make a base class that has all the functionality needed to\n#      render an agenda view. Then create an agenda folder with\n#      all my views, like dynamic blocks.\n#\n#      The goal being to allow people to extend and create custom\n#      agenda views from their user folder, without having to\n#      write all the \"stuff\"\n#\n#      Also create a BUNCH of filters that filter by tag, properties\n#      and other things so there are example versions of each.\n#\n# statefilter\n# tagfilter\n# priorityfilter\nclass AgendaBaseView:\n    def __init__(self, name, setup=True, **kwargs):\n        self.name = name\n        self.SetTagFilter(kwargs)\n        self.SetPriorityFilter(kwargs)\n        self.SetStateFilter(kwargs)\n        self.SetDurationFilter(kwargs)\n        self.SetClockedDurationFilter(kwargs)\n        self.SetDateFilter(kwargs)\n        self.hasclock = \"hasclock\" in kwargs\n        self.clockedtoday = \"clockedtoday\" in kwargs\n        self.clockfilter = \"clockfilter\" in kwargs\n        self.hasclose = \"hasclose\" in kwargs\n        self.hasdeadline = \"hasdeadline\" in kwargs\n        self.hasschedule = \"hasschedule\" in kwargs\n        self.noclock = \"noclock\" in kwargs\n        self.noclose = \"noclose\" in kwargs\n        self.nodeadline = \"nodeadline\" in kwargs\n        self.noschedule = \"noschedule\" in kwargs\n        self.onlyTasks  = \"onlytasks\" in kwargs\n        self.haschildtasks = \"haschildtasks\" in kwargs\n        self.nochildtasks = \"nochildtasks\" in kwargs\n\n        if(setup):\n            self.SetupView()\n        else:\n            self.BasicSetup()\n\n    # Default view does not have a filter view\n    # Only todo view\n    def OpenFilterView(self):\n        pass\n\n    def BasicSetup(self):\n        self.UpdateNow()\n        self.entries = []\n\n    def SetDurationFilter(self,kwargs):\n        self._beforeDuration     = []\n        self._afterDuration      = []\n        if(\"durationfilter\" in kwargs):\n            self._durationFilter = kwargs[\"durationfilter\"]\n        else:\n            self._durationFilter = None\n            return\n        tags = self._durationFilter.split(' ')\n        for tag in tags:\n            tag = tag.strip()\n            if not tag or len(tag) <= 0:\n                continue\n            m = RE_IN_OUT_TAG.search(tag)\n            if(m):\n                inout = m.group('inout')\n                tagdata = m.group('tag')\n                if(not inout or inout == '+'):\n                    self._beforeDuration.append(dur.OrgDuration.Parse(tagdata.strip()))\n                else:\n                    self._afterDuration.append(dur.OrgDuration.Parse(tagdata.strip()))\n    \n    def SetClockedDurationFilter(self,kwargs):\n        self._beforeClockedDuration     = []\n        self._afterClockedDuration      = []\n        if(\"clockfilter\" in kwargs):\n            self._clockedDurationFilter = kwargs[\"clockfilter\"]\n        else:\n            self._clockedDurationFilter = None\n            return\n        tags = self._clockedDurationFilter.split(' ')\n        for tag in tags:\n            tag = tag.strip()\n            if not tag or len(tag) <= 0:\n                continue\n            m = RE_IN_OUT_TAG.search(tag)\n            if(m):\n                inout = m.group('inout')\n                tagdata = m.group('tag')\n                if(not inout or inout == '+'):\n                    self._beforeClockedDuration.append(dur.OrgDuration.Parse(tagdata.strip()))\n                else:\n                    self._afterClockedDuration.append(dur.OrgDuration.Parse(tagdata.strip()))\n\n    def SetStateFilter(self,kwargs):\n        if(\"statefilter\" in kwargs):\n            self._stateFilter = kwargs[\"statefilter\"]\n        else:\n            self._stateFilter = None\n            return\n        self._inStateTags     = []\n        self._oneofStateTags  = []\n        self._outStateTags    = []\n        tags = self._stateFilter.split(' ')\n        for tag in tags:\n            tag = tag.strip()\n            if not tag or len(tag) <= 0:\n                continue\n            m = RE_IN_OUT_TAG.search(tag)\n            if(m):\n                inout = m.group('inout')\n                tagdata = m.group('tag')\n                if(not inout or inout == '+'):\n                    self._inStateTags.append(tagdata.strip())\n                elif(inout == '|'):\n                    self._oneofStateTags.append(tagdata.strip())\n                else:\n                    self._outStateTags.append(tagdata.strip())\n\n    def SetPriorityFilter(self,kwargs):\n        if(\"priorityfilter\" in kwargs):\n            self._priorityFilter = kwargs[\"priorityfilter\"]\n        else:\n            self._priorityFilter = None\n            return\n        self._inPriorityTags     = []\n        self._oneofPriorityTags  = []\n        self._outPriorityTagsags    = []\n        tags = self._priorityFilter.split(' ')\n        for tag in tags:\n            tag = tag.strip()\n            if not tag or len(tag) <= 0:\n                continue\n            m = RE_IN_OUT_TAG.search(tag)\n            if(m):\n                inout = m.group('inout')\n                tagdata = m.group('tag')\n                if(not inout or inout == '+'):\n                    self._inPriorityTags.append(tagdata.strip())\n                elif(inout == '|'):\n                    self._oneofPriorityTags.append(tagdata.strip())\n                else:\n                    self._outPriorityTags.append(tagdata.strip())\n\n    def SetTagFilter(self,kwargs):\n        if(\"tagfilter\" in kwargs):\n            self._tagfilter = kwargs[\"tagfilter\"]\n        else:\n            self._tagfilter = None\n            return\n        self._intags     = []\n        self._oneoftags  = []\n        self._outtags    = []\n        tags = self._tagfilter.split(' ')\n        for tag in tags:\n            tag = tag.strip()\n            if not tag or len(tag) <= 0:\n                continue\n            m = RE_IN_OUT_TAG.search(tag)\n            if(m):\n                inout = m.group('inout')\n                tagdata = m.group('tag')\n                if(not inout or inout == '+'):\n                    self._intags.append(tagdata.strip())\n                elif(inout == '|'):\n                    self._oneoftags.append(tagdata.strip())\n                else:\n                    self._outtags.append(tagdata.strip())\n\n    def SetDateFilter(self, kwargs):\n        self._startDoneDateComparator = None\n        self._endDoneDateComparator = None\n\n        if \"datefilter\" not in kwargs:\n            return\n\n        DATE_PATTERN = \"([><=]+)(\\d+)\"\n        datefilter = kwargs[\"datefilter\"].split(\" \")\n        for cond in datefilter:\n            match = re.search(DATE_PATTERN, cond)\n            if match is None:\n                continue\n            operator = match.group(1)\n            date_str = match.group(2)\n\n            try:\n                date = dp.parse(date_str)\n            except:\n                log.error(\"Failed to parse datefilter\")\n                continue\n\n            if operator == \">\":\n                self._startDoneDateComparator = lambda d, date=date: d is not None and date < d\n            if operator == \">=\":\n                self._startDoneDateComparator = lambda d, date=date: d is not None and date <= d\n            if operator == \"<\":\n                self._endDoneDateComparator = lambda d, date=date: d is not None and d < date\n            if operator == \"<=\":\n                date = date + datetime.timedelta(days=1)\n                self._endDoneDateComparator = lambda d, date=date: d is not None and d < date\n\n    def MatchHas(self, node):\n        if(self.hasclock and not node.clock):\n            return False\n        if(self.hasdeadline and not node.deadline):\n            return False\n        if(self.hasclose and not node.closed):\n            return False\n        if(self.hasschedule and not node.scheduled):\n            return False\n        if(self.haschildtasks and not HasChildTasks(node)):\n            return False\n        if(self.noclock and node.clock):\n            return False\n        if(self.nodeadline and node.deadline):\n            return False\n        if(self.noclose and node.closed):\n            return False\n        if(self.noschedule and node.scheduled):\n            return False\n        if(self.nochildtasks and HasChildTasks(node)):\n            return False\n        return True\n\n    def MatchTags(self, node):\n        if(not self._tagfilter):\n            return True\n        if(self._intags and len(self._intags) > 0 and not all(elem in node.tags  for elem in self._intags)):\n            return False\n        if(self._outtags and any(elem in node.tags for elem in self._outtags)):\n            return False\n        if(self._oneoftags and len(self._oneoftags) > 0 and not any(elem in node.tags for elem in self._oneoftags)):\n            return False\n        return True\n\n    def MatchPriorities(self, node):\n        if(not self._priorityFilter):\n            return True\n        if(self._inPriorityTags and len(self._inPriorityTags) > 0 and not all(elem in node.priority  for elem in self._inPriorityTags)):\n            return False\n        if(self._outPriorityTags and any(elem in node.priority for elem in self._outPriorityTags)):\n            return False\n        if(self._oneofPriorityTags and len(self._oneofPriorityTags) > 0 and not any(elem in node.priority for elem in self._oneofPriorityTags)):\n            return False\n        return True\n    \n    def MatchState(self, node):\n        t = node.todo\n        if(not node.todo):\n            t = \"\"\n        if(not self._stateFilter):\n            return True\n        if(self._inStateTags and len(self._inStateTags) > 0 and not all(re.search(elem,t) for elem in self._inStateTags)):\n            return False\n        if(self._outStateTags and any(re.search(elem,t) for elem in self._outStateTags)):\n            return False\n        if(self._oneofStateTags and len(self._oneofStateTags) > 0 and not any(re.search(elem,t) for elem in self._oneofStateTags)):\n            return False\n        return True\n\n    def MatchDuration(self, node):\n        t = node.closed\n        if(t and self._afterDuration and any(not t.after_duration(elem) for elem in self._afterDuration)):\n            return False\n        if self._beforeDuration:\n            s = node.scheduled\n            d = node.deadline\n            ts = node.get_timestamps()\n            if(s and any(s and s.before_duration(elem) for elem in self._beforeDuration)):\n                return True\n            if(d and any(d and d.before_duration(elem) for elem in self._beforeDuration)):\n                return True\n            if(ts and len(ts) > 0 and any(ts[0] and ts[0].before_duration(elem) for elem in self._beforeDuration)):\n                return True\n            return False\n        return True\n\n    def MatchDate(self, node):\n        start = node.closed.start\n        end = node.closed.end if node.closed.end is not None else start\n        if self._startDoneDateComparator is not None \\\n                and not self._startDoneDateComparator(start):\n            return False\n        if self._endDoneDateComparator is not None \\\n                and not self._endDoneDateComparator(end):\n            return False\n        return True\n\n    def MatchClock(self, node):\n        if self.clockedtoday:\n            if not node.clock:\n                return False\n            now = datetime.datetime.now()\n            for c in node.clock:\n                if c.start.date() == now.date():\n                    return True\n                if c.end.date() == now.date():\n                    return True\n            return False\n        if self.clockfilter:\n            if not node.clock:\n                return False\n            for t in node.clock:\n                if t:\n                    if(self._afterClockedDuration and any(not t.after_duration(elem) for elem in self._afterClockedDuration)):\n                        return False\n                    if(self._beforeClockedDuration and any(not t.before_duration(elem) for elem in self._beforeClockedDuration)):\n                        return False\n        return True\n\n\n    def SetupView(self):\n        self.view = CreateUniqueViewNamed(self.name, self)\n        self.view.set_read_only(True)\n        self.view.set_scratch(True)\n        self.view.set_name(self.name)\n        self.BasicSetup()\n        self.FilterEntries()\n        # Keep ourselves attached to this agenda\n        # This doesn't work BOO\n        self.view.agenda = self\n\n    def DoRenderView(self,edit, clear = False):\n        self.StartEditing()\n        self.RenderView(edit, clear)\n        self.DoneEditing()\n\n    def OpenFilterView(self):\n        first = True\n        for v in self.agendaViews:\n            v.view = self.view\n            v.OpenFilterView()\n\n\n    def InsertAgendaHeading(self, edit):\n        if(hasattr(self,'_tagfilter') and self._tagfilter):\n            self.view.insert(edit, self.view.size(), self.name + \"\\t\\t TAGS( \" + self._tagfilter + \" )\\n\")\n        else:\n            self.view.insert(edit, self.view.size(), self.name + \"\\n\")\n\n    def UpdateNow(self, now=None):\n        if(now == None):\n            self.now = datetime.datetime.now()\n        else:\n            self.now = now\n            self.entries = []\n            self.FilterEntries()\n\n    # You have to bookend your editing session with these\n    def StartEditing(self):\n        self.view.set_read_only(False)\n\n    def DoneEditing(self):\n        self.view.set_read_only(True)\n\n    def RestoreCursor(self, pos):\n        # Restore the cursor\n        self.view.sel().clear()\n        self.view.sel().add(pos)\n\n    def AddEntry(self, node, file):\n        self.entries.append({\"node\": node, \"file\": file})\n\n\n    def ClearEntriesAt(self):\n        for e in self.entries:\n            if 'at' in e:\n                del e['at']\n\n    def MarkEntryAt(self, entry, ts= None):\n        if(not 'at' in entry):\n            entry['at'] = []\n        entry['at'].append(self.view.rowcol(self.view.size())[0])\n        entry['ts'] = ts\n    \n    def MarkEntryAtRegion(self, entry, reg, ts=None):\n        if(not 'at' in entry):\n            entry['at'] = []\n        entry['at'].append(reg)\n        entry['ts'] = ts\n\n    def At(self, row, col):\n        for e in self.entries:\n            if 'at' in e:\n                for  ea in e['at']:\n                    if(type(ea) == int):\n                        if(ea == row):\n                            return (e['node'], e['file'])\n                    elif(type(ea) == sublime.Region):\n                        if(ea.contains(self.view.text_point(row,col))):\n                            return (e['node'], e['file'])\n        return (None, None)\n\n    def Clear(self, edit):\n        self.StartEditing()\n        self.view.erase(edit, sublime.Region(0,self.view.size()))\n        self.DoneEditing()\n\n    # ----------------------------------------------\n    # These are user extended views!\n    def RenderView(self, edit, clear=False):\n        pass\n\n    def FilterEntries(self):\n        allowOutsideOrgDir = sets.Get(\"agendaIncludeFilesOutsideOrgDir\", False)\n        for file in db.Get().Files: \n            # Skip over files not in orgDir\n            if(not file.isOrgDir and not allowOutsideOrgDir):\n                continue\n            #if(not \"habits\" in file.filename):\n            #    continue\n            #print(\"AGENDA: \" + file.filename + \" \" + file.key)\n            for n in file.org[1:]:\n                if(self.MatchHas(n)\n                   and self.MatchPriorities(n)\n                   and self.MatchTags(n)\n                   and self.MatchState(n)\n                   and self.MatchDuration(n)\n                   and self.MatchDate(n)\n                   and self.MatchClock(n)\n                   and self.FilterEntry(n, file)):\n                    self.AddEntry(n, file)\n\n    def FilterEntry(self, node, file):\n        pass\n\ndef IsBeforeNow(ts, now):\n    if(isinstance(ts,orgdate.OrgDate)):\n        return ts and (not ts.has_time() or ts.start.time() < now.time())\n    elif(ts and isinstance(ts,datetime.datetime)):\n        return ts.time() < now.time()\n    else:\n        return False\n\ndef IsAfterNow(ts, now):\n    if(isinstance(ts,orgdate.OrgDate)):\n        return ts and ts.has_time() and ts.start.time() >= now.time()\n    elif(ts and isinstance(ts,datetime.datetime)):\n        return ts.time() >= now.time()\n    else:\n        return False\n\n# ============================================================ \nclass CalendarView(AgendaBaseView):\n    def __init__(self, name, setup=True,**kwargs):\n        super(CalendarView, self).__init__(name, setup, **kwargs)\n        firstDayIndex = sets.GetWeekdayIndexByName(sets.Get(\"firstDayOfWeek\",\"Sunday\"))\n        self.dv = dpick.DateView(\"orgagenda.now\",firstDayIndex = firstDayIndex)\n\n    def UpdateNow(self, now=None):\n        if(now == None):\n            self.now = datetime.datetime.now()\n        else:\n            self.now = now\n            self.dv.MoveCDateToDate(self.now)\n\n    def AddRepeating(self, date):\n        self.dv.AddToDayHighlights(date, \"repeat\", \"orgagenda.blocked\")\n\n    def AddTodo(self, date):\n        if(isinstance(date,orgdate.OrgDate)):\n            date = date.start\n        self.dv.AddToDayHighlights(date, \"todo\", \"orgagenda.todo\", sublime.DRAW_NO_FILL)\n    #def AddToDayHighlights(self, date, key, hightlight, drawtype = sublime.DRAW_NO_OUTLINE):\n    def RenderView(self, edit, clear=False):\n        self.InsertAgendaHeading(edit)\n        self.dv.SetView(self.view)\n        self.dv.Render(self.now)\n        toHighlight = []\n        for entry in self.entries:\n            n = entry['node']\n            ts, repeating = IsInMonth(n, self.now)\n            if(ts):\n                self.AddTodo(ts)\n            if(ts and repeating):\n                self.AddRepeating(ts)\n\n    def FilterEntry(self, n, filename):\n        return (not self.onlyTasks or (IsTodo(n) and not IsDone(n) and not IsArchived(n))) and not IsProject(n) and HasTimestamp(n)\n\ndef bystartdate(a, b):\n    if a.scheduled.start > b.scheduled.start:\n        return 1\n    if a.scheduled.start < b.scheduled.start:\n        return -1\n    return 0\n\ndef bystartdatekey(a):\n    return a.scheduled.start\n\ndef bystartnodedatekey(a):\n    n = a['node']\n    dt = a['ts']\n    #dt = n.scheduled.start\n    if(isinstance(dt,orgdate.OrgDate)):\n        dt=dt.start\n    elif(isinstance(dt, datetime.date)):\n        return datetime.datetime.combine(dt.today(), datetime.datetime.min.time()).timestamp()\n    return dt.timestamp()\n\ndef getdatefromnode(n):\n    dt = datetime.datetime.min\n    timestamps = n.get_timestamps(active=True,point=True,range=True)\n    if timestamps and len(timestamps) > 0:\n        dt = timestamps[0]\n    if n.deadline:\n        dt = n.deadline.start\n    if n.scheduled:\n        dt = n.scheduled.start\n    if n.closed:\n        dt = n.closed\n    if(isinstance(dt,orgdate.OrgDate)):\n        dt=dt.start\n    #if(isinstance(dt, datetime.datetime)):\n    #    return datetime.datetime.combine(dt.date(), datetime.datetime.min.time())\n    if(isinstance(dt, datetime.date)):\n        return datetime.datetime.combine(dt, datetime.datetime.min.time())\n    return dt\n\ndef getdate(a):\n    n = a['node']\n    return getdatefromnode(n)\n\ndef getsortkey(a):\n    n = a['node']\n    dt = getdatefromnode(n)\n    result = 0\n    if dt:\n        result = (dt - datetime.datetime(1970, 1, 1)).total_seconds()\n    result = int(result)\n    result = float(result)\n    result *= 1000\n    # Include priority after datetime information\n    if n and n.priority and n.priority != \"\":\n        result += (ord(n.priority[0]) - ord('A'))*100\n    else:\n        result += 0\n    # Ensure todos end up before done before archived\n    if IsTodo(n):\n        result += 1\n    if IsDone(n):\n        result += 2\n    if IsArchived(n):\n        result += 3\n    return result\n\n\n# ============================================================ \nclass WeekView(AgendaBaseView):\n    def __init__(self, name, setup=True,**kwargs):\n        super(WeekView, self).__init__(name, setup, **kwargs)\n\n\n    def HighlightTime(self, date):\n        reg = self.DateToRegion(date)\n        style = self.dayhighlight\n        if(style == None):\n            style = \"orgdatepicker.monthheader\"\n        self.output.add_regions(\"curweek\",[reg],style,\"\",sublime.DRAW_NO_OUTLINE)   \n\n    def InsertTimeHeading(self, edit, hour):\n        self.startOffset = 9\n        self.cellSize    = 5\n        pt = self.view.size()\n        row, c = self.view.rowcol(pt)\n        dayStart = sets.Get(\"agendaDayStartTime\",6)\n        dayEnd   = sets.Get(\"agendaDayEndTime\",19)\n        if(dayEnd > 23):\n            dayEnd = 23\n        if(dayStart < 0):\n            dayStart = 0\n        if(dayStart > dayEnd):\n            dayStart = 0\n            dayEnd   = 23\n        header = \"     \"\n        for i in range(dayStart, dayEnd+1):\n            if(i == 10):\n                header += \" \"\n            header += \"   {:2d}\".format(i)\n        header +=\"  \\n\"\n        #header = \"         0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16   17   18   19   20   21   22   23  \\n\"\n        self.view.insert(edit, self.view.size(), header)\n        dayStart = sets.Get(\"agendaDayStartTime\",6)\n        col = self.startOffset + (hour-dayStart)*self.cellSize\n        s = self.view.text_point(row,col)\n        e = self.view.text_point(row,col+2)\n        reg = sublime.Region(s, e)\n        style = \"orgagenda.now\"\n        self.view.add_regions(\"curw\",[reg],style,\"\",sublime.DRAW_NO_OUTLINE)   \n\n    def InsertDay(self, name, date, edit):\n        pt = self.view.size()\n        row, c = self.view.rowcol(pt)\n        if(date.day == datetime.datetime.now().day):\n            if(date.day == self.now.day):\n                self.view.insert(edit, self.view.size(),\"@\" + name + \" \" + \"{0:2}\".format(date.day) + \"W[\")\n            else:\n                self.view.insert(edit, self.view.size(),\"#\" + name + \" \" + \"{0:2}\".format(date.day) + \"W[\")\n        elif(date.day == self.now.day):\n            self.view.insert(edit, self.view.size(),\"&\" + name + \" \" + \"{0:2}\".format(date.day) + \"W[\")\n        else:\n            self.view.insert(edit, self.view.size(),\" \" + name + \" \" + \"{0:2}\".format(date.day) + \"W[\")\n\n        daydata = []\n        for entry in self.entries:\n            n = entry['node']\n            timestamps = n.get_timestamps(active=True,point=True,range=True)\n            shouldContinue = False\n            for t in timestamps:\n                if(t.start.day == date.day and t.start.month == date.month and t.start.year == date.year):\n                    daydata.append(entry)\n                    entry['ts'] = t\n                    shouldContinue = True\n                    break\n            if(shouldContinue):\n                continue\n            if(n.scheduled and (EnsureDate(n.scheduled.start) < EnsureDate(date) and not IsDone(n) and not IsArchived(n) or EnsureDate(n.scheduled.start) == EnsureDate(date))):\n                daydata.append(entry)\n                entry['ts'] = n.scheduled\n                continue\n            if(n.deadline and (EnsureDate(n.deadline.deadline_start) < EnsureDate(date) and not IsDone(n) and not IsArchived(n) or EnsureDate(n.deadline.deadline_start) == EnsureDate(date))):\n                daydata.append(entry)\n                entry['ts'] = n.deadline\n                continue\n        daydata.sort(key=bystartnodedatekey)\n\n        lastMatchStart = 0\n        lastMatch      = None\n        lastMatchEntry = None\n        matchCount     = 0\n        doneMatchCount = 0\n        dayStart = sets.Get(\"agendaDayStartTime\",6)\n        dayEnd   = sets.Get(\"agendaDayEndTime\",19)\n        if(dayEnd > 23):\n            dayEnd = 23\n        if(dayStart < 0):\n            dayStart = 0\n        if(dayStart > dayEnd):\n            dayStart = 0\n            dayEnd   = 23\n        for hour in range(dayStart,dayEnd+1):\n            for minSlot in range(0,self.cellSize):\n                match = None\n                matche = None\n                for entry in daydata:\n                    n = entry['node']\n                    ts = IsInHourAndMinute(n, hour, minSlot*12, (minSlot+1)*12,date)\n                    entry['ts'] = ts\n                    if(ts):\n                        match = n\n                        matche = entry\n                if(lastMatch != match and lastMatch != None):\n                    s = self.view.text_point(row,lastMatchStart)\n                    e = self.view.text_point(row,self.startOffset + (hour-dayStart)*self.cellSize + minSlot)\n                    reg = sublime.Region(s, e)\n                    if(IsDone(lastMatch) or IsArchived(lastMatch)):\n                        style = \"orgagenda.week.done.\" + str(doneMatchCount)\n                        doneMatchCount = (doneMatchCount + 1) % 2\n                        self.MarkEntryAtRegion(lastMatchEntry,reg)\n                        self.view.add_regions(\"week_done_\" + str(date.day) + \"_\" + str(hour) + \"_\" + str(minSlot),[reg],style,\"\", sublime.DRAW_SQUIGGLY_UNDERLINE)   \n                    else:\n                        style = \"orgagenda.week.\" + str(matchCount)\n                        matchCount = (matchCount + 1) % 10\n                        self.MarkEntryAtRegion(lastMatchEntry,reg)\n                        self.view.add_regions(\"week_\" + str(date.day) + \"_\" + str(hour) + \"_\" + str(minSlot),[reg],style,\"\",sublime.DRAW_NO_FILL)   \n                if(match != None):\n                    if(lastMatch != match):\n                        lastMatch      = match\n                        lastMatchEntry = matche\n                        lastMatchStart = self.startOffset + (hour-dayStart)*self.cellSize + minSlot\n                    d = distanceFromStart(matche, hour, minSlot)\n                    # If the time slot is larger than the name we space pad it\n                    c = \" \"\n                    if(d < len(match.heading) and d >= 0):\n                        c = match.heading[d:d+1]\n                    self.view.insert(edit, self.view.size(), c)\n                else:\n                    if(lastMatch != match):\n                        lastMatch      = match\n                        lastMatchStart = self.startOffset + (hour-dayStart)*self.cellSize + minSlot\n                        lastMatchEntry = matche\n                    if(minSlot < 4):\n                        self.view.insert(edit, self.view.size(), \".\")\n                    else:\n                        self.view.insert(edit, self.view.size(), \"_\")\n        self.view.insert(edit, self.view.size(),\"]\\n\")\n\n    def RenderView(self, edit, clear=False):\n        self.InsertAgendaHeading(edit)\n        self.InsertTimeHeading(edit,self.now.hour)\n        #print(str(self.now))\n        wday   = self.now.weekday()\n        firstDayIndex = sets.GetWeekdayIndexByName(sets.Get(\"firstDayOfWeek\", \"Sunday\"))\n        wstart = self.now + datetime.timedelta(days=-((wday+1)%7)-((firstDayIndex+1)%7))\n        dayNames  = sets.Get(\"weekViewDayNames\",[\"Mon\", \"Tue\", \"Wed\", \"Thr\", \"Fri\", \"Sat\", \"Sun\"])\n        numDays   = sets.Get(\"agendaWeekViewNumDays\",7)\n        for i in range(0,numDays):\n            index = (firstDayIndex + i) % len(dayNames)\n            self.InsertDay(dayNames[index], wstart + datetime.timedelta(days=i), edit)\n\n    def FilterEntry(self, n, filename):\n        rc = (not self.onlyTasks or (IsTodo(node) or IsDone(n))) and not IsProject(n) and HasTimestamp(n)\n        return rc\n\n\n# ============================================================ \nclass AgendaView(AgendaBaseView):\n    def __init__(self, name, setup=True, **kwargs):\n        super(AgendaView, self).__init__(name, setup, **kwargs)\n        self.blocks = [None,None,None,None,None,None,None]\n        self.sym     = (\"$\",\"@\",\"!\",\"#\",\"%\",\"^\",\"&\")\n        self.symUsed = [-1,-1,-1,-1,-1,-1,-1]\n\n    def RenderDateHeading(self, edit, now):\n        headerFormat = sets.Get(\"agendaHeaderFormat\",\"%A \\t%d %B %Y\")\n        self.view.insert(edit, self.view.size(), now.strftime(headerFormat) + \"\\n\\n\")\n\n    def BuildHabitDisplay(self, n):\n        if(n.scheduled and n.get_property(\"STYLE\",None)):\n            #OrgDateRepeatedTask\n            repeats = n.repeated_tasks\n            habitbar = \"[_____________________]\"\n            hb = list(habitbar) \n            # not schedule but done\n            # not schedule not done\n            # scheduled but not done\n            # scheduled but last day\n            # late\n            # done\n            if(repeats):\n                start = self.now-drel.relativedelta(days=20)\n                cur = self.now-drel.relativedelta(days=21)\n                while(cur < self.now):\n                   cur = n.scheduled.next_repeat_from(cur)\n                   if(cur < self.now):\n                        diff = (self.now - cur).days\n                        diff = 21 - diff\n                        hb[diff] = '.'\n                for i in range(0,21):\n                    cur = start + drel.relativedelta(days=i)\n                    for r in repeats:\n                        if r.has_overlap(cur):\n                            hb[i+1] = '*'\n                pass\n            return \"H\" + ''.join(hb)\n        return \"\"\n\n    def GetUnusedSymbol(self, blk):\n        start = 0\n        for i in range(0,len(self.symUsed)):\n            if(self.symUsed[i] >= 0):\n                start = i\n                break\n        for i in range(start,len(self.symUsed)):\n            if(self.symUsed[i] < 0):\n                self.symUsed[i] = blk\n                return i\n        return -1\n\n    def ReleaseSymbol(self, blk):\n        for i in range(0,len(self.symUsed)):\n            if(self.symUsed[i] == blk):\n                self.symUsed[i] = -1\n                break\n\n    def FindSymbol(self, blk):\n        for i in range(0,len(self.symUsed)):\n            if(self.symUsed[i] == blk):\n                return i\n        return 0\n\n\n    def ClearAgendaBlocks(self,h):\n        for i in range(0, len(self.blocks)):\n            n = self.blocks[i]\n            if(not IsInHour(n, h,self.now)):\n                self.ReleaseSymbol(i)\n                self.blocks[i] = None\n\n    def UpdateWithThisBlock(self, n, h):\n        idx = -1\n        for i in range(0, len(self.blocks)):\n            if(idx == -1 and self.blocks[i] == None):\n                idx = i\n            if(self.blocks[i] == n):\n                idx = -1\n                return i\n        if(idx != -1):\n            self.blocks[idx] = n\n            return idx\n        return 0\n\n    def GetAgendaBlocks(self,n,h):\n        out = \"\"\n        if(n != None):\n            symIdx = self.GetUnusedSymbol(0)\n            self.ClearAgendaBlocks(h)\n            myIdx = self.UpdateWithThisBlock(n, h)\n            self.symUsed[symIdx] = myIdx\n        else:\n            self.ClearAgendaBlocks(h)\n        spaceSym = \".\"\n        for i in range(0, len(self.blocks)):\n            if(self.blocks[i]):\n                spaceSym = \" \"\n        if(spaceSym == \".\"):\n            out = \"..\"\n        for i in range(0, len(self.blocks)):\n            if(not self.blocks[i]):\n                out = out + spaceSym\n            else:\n                symIdx = self.FindSymbol(i)\n                out = out + self.sym[symIdx]\n        return out\n\n    def RenderAgendaEntry(self,edit,filename,n,h,ts):\n        view = self.view\n        if(IsRawDate(ts)):\n            view.insert(edit, view.size(), \"{0:12} {1:02d}:{2:02d}B[{7}] {3} {4:45} {5}{6}\\n\".format(filename if (len(filename) <= 12) else filename[:11] + \":\" , h, ts.minute, n.todo if n.todo else \"\", n.heading, self.BuildDeadlineDisplay(n), self.BuildHabitDisplay(n), self.GetAgendaBlocks(n,h)))\n        else:\n            view.insert(edit, view.size(), \"{0:12} {1:02d}:{2:02d}B[{7}] {3} {4:45} {5}{6}\\n\".format(filename if (len(filename) <= 12) else filename[:11] + \":\" , h, ts.start.minute, n.todo if n.todo else \"\", n.heading, self.BuildDeadlineDisplay(n), self.BuildHabitDisplay(n), self.GetAgendaBlocks(n,h)))\n\n    def BuildDeadlineDisplay(self, node):\n        if(node.deadline):\n            if(EnsureDateTime(node.deadline.deadline_start) <= self.now):\n                if(EnsureDateTime(node.deadline.start).date() < self.now.date()):\n                    return \"D: Overdue\"\n                elif(EnsureDateTime(node.deadline.start).date() == self.now.date()):\n                    return \"D: Due Today\"\n                else:\n                    return \"D:@\" + str(EnsureDateTime(node.deadline.start).date())\n        else:\n            return \"\"\n\n\n    def RenderView(self, edit, clear=False):\n        self.InsertAgendaHeading(edit)\n        self.RenderDateHeading(edit, self.now)\n        view     = self.view\n        dayStart = sets.Get(\"agendaDayStartTime\",6)\n        dayEnd   = sets.Get(\"agendaDayEndTime\",19)  \n        allDat = []\n        before = True\n        for h in range(dayStart, dayEnd):\n            didNotInsert = True\n            if(self.now.hour == h):\n                foundItems = []\n                for entry in self.entries:\n                    n = entry['node']\n                    #filename = entry['file'].AgendaFilenameTag()\n                    ts = IsInHour(n, h, self.now)\n                    if(IsBeforeNow(ts, self.now) and ts):\n                        entry['ts'] = ts\n                        if(not 'found' in entry):\n                            foundItems.append(entry)\n                            entry['found'] = 'b'\n                if(len(foundItems) > 0):\n                    foundItems.sort(key=bystartnodedatekey)\n                    for it in foundItems:\n                        n = it['node']\n                        ts = it['ts']\n                        if(ts == None):\n                            ts = n.scheduled\n                        filename = it['file'].AgendaFilenameTag()\n                        self.MarkEntryAt(it,ts)\n                        self.RenderAgendaEntry(edit,filename,n,h,ts)\n                        didNotInsert = False\n                view.insert(edit, view.size(), \"{0:12} {1:02d}:{2:02d} - - - - - - - - - - - - - - - - - - - - - \\n\".format(\"now =>\", self.now.hour, self.now.minute) )\n                foundItems = []\n                for entry in self.entries:\n                    n = entry['node']\n                    #filename = entry['file'].AgendaFilenameTag()\n                    ts = IsInHour(n, h, self.now)\n                    if(IsAfterNow(ts, self.now) and ts):\n                        entry['ts'] = ts\n                        if(not 'found' in entry or entry['found'] == 'b'):\n                            foundItems.append(entry)\n                            entry['found'] = 'a'\n                if(len(foundItems) > 0):\n                    foundItems.sort(key=bystartnodedatekey)\n                    for it in foundItems:\n                        n = it['node']\n                        ts = it['ts']\n                        if(ts == None):\n                            ts = n.scheduled\n                        filename = it['file'].AgendaFilenameTag()\n                        self.MarkEntryAt(it,ts)\n                        self.RenderAgendaEntry(edit,filename,n,h,ts)\n                        didNotInsert = False\n                before = False\n            else:\n                # Filter timestamps so we can sort by timestamp\n                foundItems = []\n                for entry in self.entries:\n                    n = entry['node']\n                    ts = IsInHour(n,h,self.now)\n                    if(ts and (not 'found' in entry or (not before and entry['found'] == 'b'))):\n                        entry['ts'] = ts\n                        foundItems.append(entry)\n                foundItems.sort(key=bystartnodedatekey)\n                for entry in foundItems:\n                    n = entry['node']\n                    filename = entry['file'].AgendaFilenameTag()\n                    ts = entry['ts']\n                    if(before):\n                        entry['found'] = 'b'\n                    else:\n                        entry['found'] = 'a'\n                    self.MarkEntryAt(entry, ts)\n                    self.RenderAgendaEntry(edit,filename,n,h,ts)\n                    didNotInsert = False\n            if(didNotInsert):\n                empty = \" \" * 12\n                blocks = self.GetAgendaBlocks(None,h)\n                sep = \"\"\n                esep = \" \"\n                if(not '.' in blocks):\n                    sep = \"B[\"\n                    esep = \"]\"\n                view.insert(edit, view.size(), \"{0:12} {1:02d}:00{3}{2}{4}---------------------\\n\".format(empty, h, blocks, sep, esep))\n        view.insert(edit,view.size(),\"\\n\")\n        for entry in self.entries:\n            n = entry['node']\n            filename = entry['file'].AgendaFilenameTag()\n            ts = IsAllDay(n,self.now)\n            if(ts):\n                self.MarkEntryAt(entry,ts)\n                view.insert(edit, view.size(), \"{0:12} {1} {2:69} {3} {4}\\n\".format(filename, n.todo if n.todo else \"\", n.heading, self.BuildDeadlineDisplay(n), self.BuildHabitDisplay(n)))\n\n    def FilterEntry(self, node, file):\n        rc = (not self.onlyTasks or IsTodo(node)) and not IsDone(node) and not IsArchived(node) and IsToday(node, self.now)\n        return rc\n\nRE_IN_OUT_TAG = re.compile('(?P<inout>[|+-])?(?P<tag>[^ ]+)')\n# ================================================================================\nclass TodoView(AgendaBaseView):\n\n    def GetParam(self, name, defaultVal, kwargs):\n        v       = kwargs[name] if name in kwargs else None\n        if isinstance(v,bool):\n            v = \">10.10\"\n        return v\n    def __init__(self, name, setup=True, **kwargs):\n        super(TodoView, self).__init__(name, setup, **kwargs)\n        self.showduration = self.GetParam(\"showduration\",\"7.7\",kwargs)\n        self.showfilename = \"15.15\" if \"hidefilename\" not in kwargs else None\n        self.showheading  = \"hideheading\" not in kwargs\n        self.showstatus   = \"11.11\" if \"hidestatus\" not in kwargs else None\n        self.showdate     = self.GetParam(\"showdate\",\"15.15\",kwargs)\n        self.showtime     = self.GetParam(\"showtime\",\"6.6\",kwargs)\n        self.showeffort   = self.GetParam(\"showeffort\",\">6.6\",kwargs)\n        self.showafter    = self.GetParam(\"showafter\",\">12.12\",kwargs)\n        self.showassigned = self.GetParam(\"showassigned\",\">12.12\", kwargs)\n        self.showid       = self.GetParam(\"showid\",\">10.10\", kwargs)\n        self.showtotalduration = \"showtotalduration\" in kwargs\n        self.byproject    = \"byproject\" in kwargs\n        self.input        = None\n        self.search_filter = None\n        self.havesortorder = \"sortascend\" in kwargs or \"sortdescend\" in kwargs\n        self.sortorder = False\n        if self.havesortorder:\n            self.sortorder = False if \"sortascend\" in kwargs else self.sortorder\n            self.sortorder = True  if \"sortdescend\" in kwargs else self.sortorder\n\n    def GetFormatHeaders(self, n, filename):\n        data = {}\n        data2 = {}\n        if self.showfilename:\n            data['filename'] = \"File\"\n            data2['filename'] = \"---------------\"\n        if self.showstatus:\n            data['status']   = \"Status\"\n            data2['status']   = \"-----------\"\n        if self.showduration:\n            data['duration'] = \"Duration\"\n            data2['duration']= \"--------\"\n        if self.showheading:\n            data['heading'] =  \"Heading\"\n            data2['heading'] = \"--------------------\"\n        if self.showdate:\n            data['date'] = \"Date\"\n            data2['date']= \"---------------\"\n        if self.showtime:\n            data['time'] = \"Time\"\n            data2['time'] = \"------\"\n        if self.showeffort:\n            data['effort'] = \"Effort\"\n            data2['effort'] = \"------\"\n        if self.showafter:\n            data['after'] = \"After\"\n            data2['after'] = \"------------\"\n        if self.showid:\n            data['id'] = \"ID\"\n            data2['id'] = \"-----------------\"\n        if self.showassigned:\n            data['assigned'] = \"Who\"\n            data2['assigned'] = \"------------\"\n        return (data, data2)\n\n\n\n\n    def GetFormatData(self, n, filename):\n        data = {}\n        if self.showfilename:\n            data['filename'] = filename\n        if self.showstatus:\n            todo = \"\"\n            if n:\n                todo = n.todo\n                if todo == None:\n                    todo = \"\"\n            data['status'] = todo\n        if self.showduration:\n            duration = \"\"\n            dur = datetime.timedelta(days=0)\n            if n:\n                for c in n.clock:\n                    dur += c.duration\n                self.totalduration += dur\n                duration = orgdate.OrgDate.format_duration(dur)\n            data['duration'] = duration\n        if self.showheading:\n            heading = \"\"\n            if n:\n                heading = n.heading\n            data['heading'] = heading\n        if self.showdate:\n            date = \"\"\n            if n:\n                dt = getdatefromnode(n)\n                if dt != datetime.datetime.min and dt.date() != datetime.date.min:\n                    date = dt.strftime(\"%Y-%m-%d %a\")  \n            data['date'] = date\n        if self.showtime:\n            time = \"\"\n            if n:\n                dt = getdatefromnode(n)\n                if dt != datetime.datetime.min and dt.time() != datetime.time.min:\n                    time = dt.time().strftime(\"%H:%M\")  \n            data['time'] = time\n        if self.showeffort:\n            effort = \"\"\n            if n:\n                effort = n.get_property(\"EFFORT\",\"\")\n            data['effort'] = effort\n        if self.showafter:\n            after = \"\"\n            if n:\n                after = n.get_property(\"AFTER\",\"\")\n            data['after'] = after\n        if self.showid:\n            idd = \"\"\n            if n:\n                idd = n.get_property(\"ID\",\"\")\n                if not idd or idd == \"\":\n                    idd = n.get_property(\"CUSTOM_ID\",\"\")\n            data['id'] = idd\n        if self.showassigned:\n            ass = \"\"\n            if n:\n                ass = n.get_property(\"ASSIGNED\",\"\")\n            data['assigned'] = ass\n        return data\n\n\n    def GetF(self,p,name):\n        if p:\n            return \"{\" + name + \":\" + p + \"} \"\n        return \"\"\n    def GetFormatString(self):\n        formatstr = \"\"\n        formatstr += self.GetF(self.showfilename,\"filename\")\n        formatstr += self.GetF(self.showstatus,\"status\")\n        formatstr += self.GetF(self.showduration,\"duration\")\n        formatstr += self.GetF(self.showdate,\"date\")\n        formatstr += self.GetF(self.showtime,\"time\")\n        formatstr += self.GetF(self.showeffort,\"effort\")\n        formatstr += self.GetF(self.showafter,\"after\")\n        formatstr += self.GetF(self.showid,\"id\")\n        formatstr += self.GetF(self.showassigned,\"assigned\")\n        if self.showheading:\n            formatstr += \"{heading}\"\n        formatstr += \"\\n\"\n        return formatstr\n\n    def OnFilter(self, text):\n        #print(\"FILTER: \" + str(text))\n        self.input.onRecalc = evt.Make(self.OnFilter)\n        if text == None:\n            self.search_filter = None\n        else:\n            self.search_filter = re.compile(text + \".*\")\n        self.view.run_command(\"org_agenda_re_render_view\")\n\n    def OpenFilterView(self):\n        if self.input != None:\n            self.input.onRecalc = evt.Make(self.OnFilter)\n            self.input.run(\"Filter:\",None,evt.Make(self.OnFilter))\n\n    def getSortOrdering(self):\n        order = not sets.Get(\"agendaTodoSortAscending\",True)\n        if self.havesortorder:\n            order = self.sortorder\n        return order\n\n    def RenderView(self, edit, clear = False):\n        self.ClearEntriesAt()\n        if clear:\n            self.view.erase(edit, sublime.Region(0, self.view.size()))\n        self.InsertAgendaHeading(edit)\n        formatstr = self.GetFormatString()\n        data,under      = self.GetFormatHeaders(None,\"\")\n        self.view.insert(edit, self.view.size(), formatstr.format(**data))\n        self.view.insert(edit, self.view.size(), formatstr.format(**under))\n        self.totalduration = datetime.timedelta(days=0)\n        if self.byproject:\n            projects   = {}\n            loosetasks = []\n            for entry in self.entries:\n                n        = entry['node']\n                if n == None:\n                    continue\n                if self.search_filter and not n.is_root() and not self.search_filter.match(n.heading):\n                    continue\n                if n.is_root() or n.parent == None or n.parent.is_root() or not IsProject(n.parent):\n                    loosetasks.append(entry)\n                else:\n                    pname = n.parent.heading\n                    if pname not in projects:\n                        projects[pname] = []\n                    projects[pname].append(entry)\n            for pname,vals in projects.items():\n                vals.sort(key=getsortkey,reverse=self.getSortOrdering())\n                projects[pname] = vals\n\n            for pname,vals in projects.items():\n                self.view.insert(edit, self.view.size(), \"\\n== [{0}] ==\\n\".format(pname))\n                for entry in vals:\n                    n        = entry['node']\n                    filename = entry['file'].AgendaFilenameTag()\n                    self.MarkEntryAt(entry)\n                    self.RenderEntry(n, filename, edit)\n            if len(loosetasks) > 0:\n                self.view.insert(edit, self.view.size(), \"\\n== [] ==\\n\")\n                for entry in loosetasks:\n                    n        = entry['node']\n                    filename = entry['file'].AgendaFilenameTag()\n                    self.MarkEntryAt(entry)\n                    self.RenderEntry(n, filename, edit)\n        else:\n            self.entries.sort(key=getsortkey,reverse=self.getSortOrdering())\n            for entry in self.entries:\n                n        = entry['node']\n                if self.search_filter and not n.is_root() and not self.search_filter.match(n.heading):\n                    continue\n                filename = entry['file'].AgendaFilenameTag()\n                self.MarkEntryAt(entry)\n                self.RenderEntry(n, filename, edit)\n        if self.showtotalduration:\n            formatstr = self.GetFormatString()\n            data      = self.GetFormatData(None,\"\")\n            data['duration'] = orgdate.OrgDate.format_duration(self.totalduration)\n            data['filename'] = \"TOTAL: \"\n            self.view.insert(edit, self.view.size(), \"----------------------------------------------------------------------------\\n\")\n            self.view.insert(edit, self.view.size(), formatstr.format(**data))\n        if(self.input == None):\n            self.input = insSel.OrgInput()\n            shouldFilter = sets.Get(\"agendaTodoFilterByDefault\", False)\n            if shouldFilter:\n                self.OpenFilterView()\n\n    def RenderEntry(self, n, filename, edit):\n        formatstr = self.GetFormatString()\n        data      = self.GetFormatData(n, filename)\n        self.view.insert(edit, self.view.size(), formatstr.format(**data))\n\n    def FilterEntry(self, n, filename):\n        return IsTodo(n) and not IsProject(n) and not IsArchived(n)\n\n# ================================================================================\nclass ProjectsView(TodoView):\n    def __init__(self, name, setup=True, **kwargs):\n        super(ProjectsView, self).__init__(name, setup, **kwargs)\n\n    def FilterEntry(self, n, filename):\n        return IsProject(n) and not IsArchived(n)\n\n# ================================================================================\nclass NotBlockedProjectsView(TodoView):\n    def __init__(self, name, setup=True, **kwargs):\n        super(ProjectsView, self).__init__(name, setup, **kwargs)\n\n    def FilterEntry(self, n, filename):\n        return IsProject(n) and not IsBlockedProject(n) and not IsArchived(n)\n\n# ================================================================================\nclass BlockedProjectsView(TodoView):\n    def __init__(self, name, setup=True, **kwargs):\n        super(BlockedProjectsView, self).__init__(name, setup, **kwargs)\n\n    def FilterEntry(self, n, filename):\n        return IsBlockedProject(n) and not IsArchived(n)\n\n# ================================================================================\nclass LooseTasksView(TodoView):\n    def __init__(self, name, setup=True, **kwargs):\n        super(LooseTasksView, self).__init__(name, setup, **kwargs)\n\n    def FilterEntry(self, n, filename):\n        rc = IsTodo(n) and not IsProject(n) and not IsProjectTask(n) and not IsArchived(n)\n        return rc\n\n\n# ================================================================================\nclass DoneTasksView(TodoView):\n    def __init__(self, name, setup=True, **kwargs):\n        super(DoneTasksView, self).__init__(name, setup, **kwargs)\n\n    def FilterEntry(self, n, filename):\n        rc = IsDone(n) and not IsArchived(n)\n        return rc\n\n# ================================================================================\nclass ClockedView(TodoView):\n    def __init__(self, name, setup=True, **kwargs):\n        super(ClockedView, self).__init__(name, setup, **kwargs)\n\n    def FilterEntry(self, n, filename):\n        return n and n.clock\n\n# ================================================================================\nclass HasStatusView(TodoView):\n    def __init__(self, name, setup=True, **kwargs):\n        super(HasStatusView, self).__init__(name, setup, **kwargs)\n\n    def FilterEntry(self, n, filename):\n        return n and (IsDone(n) or IsTodo(n))\n\n# ================================================================================\nclass NextTasksProjectsView(TodoView):\n    def __init__(self, name, setup=True, **kwargs):\n        super(NextTasksProjectsView, self).__init__(name, setup, **kwargs)\n\n    # TODO Print project and then the next task\n    def RenderView(self, edit, clear=False):\n        self.InsertAgendaHeading(edit)\n        newEntries = []\n        for entry in self.entries:\n            n        = entry['node']\n            filename = entry['file'].AgendaFilenameTag()\n            self.MarkEntryAt(entry)\n            self.view.insert(edit, self.view.size(), \"{0:15} {1:12} {2}\\n\".format(filename,\"-------\", n.heading))\n            #self.RenderEntry(n, filename, edit)\n            for c in n.children:\n                if(c.todo and c.todo == \"NEXT\"):\n                    nentry = {'node': c, 'file': entry['file']}\n                    newEntries.append(nentry)\n                    self.MarkEntryAt(nentry)\n                    self.view.insert(edit, self.view.size(), \"{0:15} {1:12} {2}\\n\".format(\" \", c.todo, c.heading))\n                    #self.RenderEntry(c, filename, edit)\n        for e in newEntries:\n            self.entries.append(e)\n                    \n    def FilterEntry(self, n, filename):\n        return IsProject(n) and not IsBlockedProject(n) and not IsArchived(n)\n\n\n# ================================================================================\nclass NoteView(TodoView):\n    def __init__(self, name, setup=True,**kwargs):\n        super(NoteView, self).__init__(name, setup, **kwargs)\n\n    def FilterEntry(self, n, filename):\n        return IsNote(n) and not IsProject(n) and not IsProjectTask(n) and not IsArchived(n)\n\n# ================================================================================\nclass PhoneView(TodoView):\n    def __init__(self, name, setup=True,**kwargs):\n        super(PhoneView, self).__init__(name, setup, **kwargs)\n\n    def FilterEntry(self, n, filename):\n        return IsPhone(n) and not IsProject(n) and not IsProjectTask(n) and self.MatchTags(n) and not IsArchived(n)\n\n# ================================================================================\nclass MeetingView(TodoView):\n    def __init__(self, name, setup=True,**kwargs):\n        super(MeetingView, self).__init__(name, setup, **kwargs)\n\n    def FilterEntry(self, n, filename):\n        return IsMeeting(n) and not IsProject(n) and not IsProjectTask(n) and self.MatchTags(n) and not IsArchived(n)\n\n# ================================================================================\nclass CompositeViewListener(sublime_plugin.ViewEventListener):\n\n    @classmethod\n    def is_applicable(cls, settings):\n        # 4095 seems to crash when querying settings\n        if(int(sublime.version()) != 4095):\n            try:\n                return \"orgagenda\" in settings.get(\"color_scheme\",\"not here\")\n            except:\n                return False\n        return False\n\n    def __init__(self, view):\n        super(CompositeViewListener, self).__init__(view)\n        self.agenda = FindMappedView(self.view)\n        self.phantoms = []\n\n    def clear_phantoms(self):\n        for f in self.phantoms:\n            self.view.erase_phantoms(f)\n        self.phantoms = []\n\n    def on_hover_done(self):\n        self.clear_phantoms()\n    \n    def on_hover(self, point, hover_zone):\n        if(not hasattr(self,'agenda') or self.agenda == None):\n            return\n        if(hover_zone == sublime.HOVER_TEXT):\n            row,col = self.view.rowcol(point)\n            n, f = self.agenda.At(row, col)\n            if(n and f):\n                self.clear_phantoms()\n                line = self.view.line(point)\n                reg = sublime.Region(point, line.end())\n                body = \"\"\"\n                <body id=\"agenda-week-popup\">\n                <style>\n                    div.block {{\n                        display: block;\n                        background-color: #333333;\n                        border-style: solid;\n                        border: 1px;\n                        border-color: #666666;\n                    }}\n                    div.heading {{\n                        color: #880077;\n                        padding: 5px;\n                        font-size: 20px;\n                        font-weight: bold;\n                        }}\n                    div.file {{\n                        color: grey;\n                        padding-left: 5px;\n                        font-size: 15px;\n                        }}\n                </style>\n                <div class=\"block\"/>\n                <div class=\"heading\">{0}</div>\n                <div class=\"file\">{1}</div>\n                </div>\n                </body>\n                \"\"\".format(n.heading,f.filename)\n\n                self.view.add_phantom(n.heading, reg, body, sublime.LAYOUT_INLINE)\n                #sublime.Phantom(sublime.Region(point, point), \"<html><body>\" + n.heading + \"</body></html>\",sublime.LAYOUT_INLINE, None) \n                self.phantoms.append(n.heading)\n                print(n.heading)\n                sublime.set_timeout(self.on_hover_done, 1000*2) \n\n# ================================================================================\n# ORG has this custom composite view feature.\n# I want that. Make a view up of a couple of views.\nclass CompositeView(AgendaBaseView):\n    def __init__(self, name, views):\n        self.agendaViews = views\n        super(CompositeView, self).__init__(name)\n        self.SetupView()\n\n    def RenderView(self, edit, clear=False):\n        first = True\n        for v in self.agendaViews:\n            if not first:\n                self.view.insert(edit, self.view.size(), (\"=\" * 75) + \"\\n\")\n            first = False\n            v.view = self.view\n            v.RenderView(edit, clear)\n        # These get updated when rendered\n        self.entries = []\n        for v in self.agendaViews:\n            self.entries += v.entries\n\n    def UpdateNow(self, now=None):\n        if(now == None):\n            self.now = datetime.datetime.now()\n        else:\n            self.now = now\n        for v in self.agendaViews:\n            v.UpdateNow(now)\n\n    def FilterEntries(self):\n        self.entries = []\n        for v in self.agendaViews:\n            v.entries = []\n            v.FilterEntries()\n            self.entries += v.entries\n\n    def At(self, row, col):\n        for av in self.agendaViews:\n            n, f  = av.At(row,col)\n            if(n and f):\n                return (n,f)\n        return (None, None)\n\n# ================================================================================\nclass OrgTodoViewCommand(sublime_plugin.TextCommand):\n    # This recursive crap seems to be an ST4 issue that\n    # I don't fully understand yet. But am working around.\n    def onDone(self, edit, todo):\n        todo.DoRenderView(edit)\n        if self.pos is not None:\n            todo.RestoreCursor(self.pos)\n\n    def run(self, edit, draw=False, pos=None):\n        if(draw and self.view.name() == TODO_VIEW):\n            todo = FindMappedView(self.view)\n            self.pos = pos\n            self.onDone(edit, todo)\n        else:\n            if self.view.name() == TODO_VIEW:\n                pos = self.view.sel()[0].begin()\n            todo = TodoView(TODO_VIEW)\n            todo.view.run_command(\"org_todo_view\", {\"draw\": True, \"pos\":pos})\n\n# ================================================================================\n# Right now this is a composite view... Need to allow the user to define\n# Their own versions of this.\nclass OrgAgendaDayViewCommand(sublime_plugin.TextCommand):\n    def onDone(self, edit, agenda):\n        agenda.DoRenderView(edit)\n        if(self.pos is not None):\n            agenda.RestoreCursor(self.pos)\n        log.info(\"Day view refreshed\")\n\n    def run(self, edit, draw=False, pos=None):\n        VIEW_NAME=\"Agenda\"\n        if draw:\n            # This is a hack: A bug in sublime 4 seems to not alow multiple inserts\n            # on the edit object when the buffer is created. For now just work around\n            # I HATE this but it at least stops this from being just plain broken\n            self.pos = pos\n            agenda = FindMappedView(self.view)\n            self.onDone(edit, agenda)\n            return\n        else:\n            if(self.view.name() == VIEW_NAME):\n                pos = self.view.sel()[0].begin()\n            # Save and restore the cursor\n            views = [CalendarView(\"Calendar\",False), WeekView(\"Week\", False), AgendaView(\"Agenda\", False), BlockedProjectsView(\"Blocked Projects\",False), NextTasksProjectsView(\"Next\",False), LooseTasksView(\"Loose Tasks\",False)]\n            #views = [AgendaView(\"Agenda\", False), TodoView(\"Global Todo List\", False)]\n            agenda = CompositeView(VIEW_NAME, views)\n            agenda.view.run_command(\"org_agenda_day_view\", {\"draw\": True, \"pos\":pos})\n\n# ================================================================================\n# Goto the file in the current window (ENTER)\nclass OrgAgendaGoToCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        agenda = FindMappedView(self.view)\n        if(agenda):\n            row, col    = self.view.curRowCol()\n            n, f = agenda.At(row, col)\n            if(f):\n                if(n):\n                    path = \"{0}:{1}\".format(f.filename,n.start_row + 1)\n                    self.view.window().open_file(path, sublime.ENCODED_POSITION)\n            else:\n                log.warning(\"COULD NOT LOCATE AGENDA ROW\")\n\n# ================================================================================\nclass RunEditingCommandOnNode:\n    def __init__(self, view, command, params={}):\n        self.view = view\n        self.command = command\n        self.params = params\n\n    def onAfterSaved(self):\n        pass # Not needed anymore\n\n    def onSaved(self):\n        whenDoneEvt = util.RandomString()\n        evt.Get().once(whenDoneEvt, self.onAfterSaved)\n        if self.viewName == \"Agenda\":\n            self.view.run_command(\"org_agenda_day_view\")\n        else:\n            self.view.run_command(\"org_agenda_custom_view\", { \"toShow\": self.viewName, \"onDone\": whenDoneEvt })\n\n    def onEdited(self):\n        # NOTE the save here doesn't seem to be working\n        # Not sure why. BUT...\n        view = self.savedView\n        view.run_command(\"save\")\n        sublime.set_timeout_async(lambda: self.onSaved(), 100)\n\n    def onLoaded(self):\n        view = self.savedView\n        self.n.move_cursor_to(view)\n        eventName = util.RandomString()\n        evt.Get().once(eventName, self.onEdited)\n        log.debug(\"Trying to run: \" + self.command)\n        params = {\"onDone\": eventName }\n        for k,v in self.params.items():\n            params[k] = v\n        view.run_command(self.command, params)\n\n    def Run(self):\n        agenda = FindMappedView(self.view)\n        if(agenda):\n            self.viewName = agenda.name\n            row, col  = self.view.curRowCol()\n            self.row = row\n            n, f = agenda.At(row,col)\n            if(f):\n                if(n):\n                    self.n         = n\n                    self.f         = f\n                    self.savedView = get_view_for_silent_edit_file(f)\n                    # Give time for the document to be opened.\n                    sublime.set_timeout_async(lambda: self.onLoaded(), 200)\n            else:\n                log.warning(\"COULD NOT LOCATE AGENDA ROW\")\n\n# ================================================================================\nclass CalendarViewRegistry:\n    def __init__(self):\n        self.KnownViews = {}\n        self.AddView(\"Calendar\", CalendarView)\n        self.AddView(\"Day\", AgendaView)\n        self.AddView(\"Blocked Projects\", BlockedProjectsView)\n        self.AddView(\"Next Tasks\", NextTasksProjectsView)\n        self.AddView(\"Loose Tasks\", LooseTasksView)\n        self.AddView(\"Has Status\", HasStatusView)\n        self.AddView(\"Todos\", TodoView)\n        self.AddView(\"Notes\", NoteView)\n        self.AddView(\"Meetings\", MeetingView)\n        self.AddView(\"Phone\", PhoneView)\n        self.AddView(\"Week\", WeekView)\n        self.AddView(\"Done\", DoneTasksView)\n        self.AddView(\"Clocked\", ClockedView)\n        self.AddView(\"Projects\", ProjectsView)\n        self.AddView(\"Not Blocked Projects\", NotBlockedProjectsView)\n\n    def AddView(self,name,cls):\n        self.KnownViews[name] = cls\n\n    # ViewName: <NAME> <ARGS> : <NAME> <ARGS>\n    def ParseArgs(self, n ):\n        tokens = n.split(':')\n        name = tokens[0].strip()\n        args = {}\n        i = 1\n        while(i < len(tokens)):\n            p = tokens[i].strip()\n            if(len(p) > 0):\n                idx = p.find(' ')\n                if(idx > 0):\n                    pname = p[:idx].strip()\n                    pval = p[idx:].strip()\n                    args[pname] = pval\n                    #print(pname + \" -> \" + pval)\n                else:\n                    args[p] = True\n            i += 1\n        return (name, args)\n\n    def CreateCompositeView(self,views,name=\"Agenda\"):\n        vlist = []\n        for v in views:\n            n, args = self.ParseArgs(v)\n            vv = None\n            if(args == None):\n                vv = self.KnownViews[n](n, False)\n            else:\n                vv = self.KnownViews[n](n, False, **args)\n            if(vv):\n                vlist.append(vv)\n        if len(vlist) == 1:\n            vlist[0].name = name + \" [\" + vlist[0].name + \"]\"\n        cview = CompositeView(name, vlist)\n        cview.view.set_name(name)\n        ViewMappings[cview.view.name()] = cview\n        return cview\n\nviewRegistry = CalendarViewRegistry()\n\n\n# ================================================================================\nclass OrgAgendaCustomViewCommand(sublime_plugin.TextCommand):\n    def onDone(self, edit, agenda, onDone, pos):\n        agenda.DoRenderView(edit)\n        if pos:\n            agenda.RestoreCursor(pos)\n        log.info(\"Custom view refreshed\")\n        evt.EmitIf(onDone)\n\n    def run(self, edit, toShow=\"Default\", onDone=None, draw=False, pos=None):\n        if draw:\n            agenda = FindMappedView(self.view)\n            self.onDone(edit, agenda, onDone, pos)\n            return\n        #if(self.view.name() == \"Agenda\"):\n        pos = self.view.sel()[0].begin()\n        ReloadAllUnsavedBuffers()\n        views = sets.Get(\"AgendaCustomViews\",{ \"Default\": [\"Calendar\", \"Week\", \"Day\", \"Blocked Projects\", \"Next Tasks\", \"Loose Tasks\"]})\n        views = views[toShow]\n        nameOfShow = toShow\n        if(toShow == \"Default\"):\n            nameOfShow = \"Agenda\"\n\n        agenda = viewRegistry.CreateCompositeView(views, nameOfShow)\n        agenda.view.run_command(\"org_agenda_custom_view\", {\"draw\": True, \"onDone\": onDone, \"toShow\": toShow, \"pos\": pos})\n\n        #agenda = CompositeView(\"Agenda\", views)\n        #agenda = AgendaView(AGENDA_VIEW)\n\n\n# ================================================================================\n# TODO: This is a work in progress that only lists them right now.\n#       The goal is add parameters for filtered todos and support\n#       multiple calendar views in the end. I should probably\n#       rename the command above so we know it is intended to directly\n#       select a view rather than use a quick panel.\n#       I would like to add:\n#       1. Vertical Week View (Org Style)\n#       2. Horizontal Week View (Calendar Style)\n#       3. Month View (Vim Style)\n#       4. Month View Quick Highlight (My Style)\n#       5. Various Filtered Todo lists.\n#       6. Try an HTML version of a todo?\nclass OrgAgendaChooseCustomViewCommand(sublime_plugin.TextCommand):\n    def on_done_st4(self,index,modifers):\n        self.on_done(index)\n    def on_done(self, index):\n        if(index < 0):\n            return\n        key = self.keys[index]\n        self.view.run_command(\"org_agenda_custom_view\", { \"toShow\": key })\n        evt.EmitIf(self.onDone)\n\n    def run(self, edit, onDone=None):\n        self.onDone = onDone\n        self.views = sets.Get(\"AgendaCustomViews\",{ \"Default\": [\"Calendar\", \"Day\", \"Blocked Projects\", \"Next Tasks\", \"Loose Tasks\"]})\n        self.keys = list(self.views.keys())\n        if(int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(self.keys, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(self.keys, self.on_done_st4, -1, -1)\n\n# ================================================================================\n# When the view filter changes we re-render the todo view.\nclass OrgAgendaReRenderViewCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        v = FindMappedView(self.view)\n        if v != None:\n            v.DoRenderView(edit, True)\n\n# ================================================================================\nclass OrgAgendaReOpenFilterViewCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        v = FindMappedView(self.view)\n        if v != None:\n            v.OpenFilterView()\n\n# ================================================================================\n# Change the TODO status of the node.\nclass OrgAgendaChangeTodoCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        self.ed = RunEditingCommandOnNode(self.view, \"org_todo_change\")\n        self.ed.Run()\n\n\n# ================================================================================\nclass OrgAgendaChangePriorityCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        self.ed = RunEditingCommandOnNode(self.view, \"org_priority_change\")\n        self.ed.Run()\n\n# ================================================================================\nclass OrgAgendaClockInCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        self.ed = RunEditingCommandOnNode(self.view,\"org_clock_in\")\n        self.ed.Run()\n\n# ================================================================================\nclass OrgAgendaClockOutCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        self.ed = RunEditingCommandOnNode(self.view,\"org_clock_out\")\n        self.ed.Run()\n\n# ================================================================================\nclass OrgAgendaInsertTagCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        self.ed = RunEditingCommandOnNode(self.view,\"org_insert_tag\")\n        self.ed.Run()\n\n# ================================================================================\nclass OrgAgendaInsertEffortCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        self.ed = RunEditingCommandOnNode(self.view,\"org_insert_property\", {\"name\": \"EFFORT\"})\n        self.ed.Run()\n\n# ================================================================================\nclass OrgAgendaAssignCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        self.ed = RunEditingCommandOnNode(self.view,\"org_insert_property\", {\"name\": \"ASSIGNED\"})\n        self.ed.Run()\n\n# ================================================================================\nclass OrgAgendaIdCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        self.ed = RunEditingCommandOnNode(self.view,\"org_insert_property\", {\"name\": \"ID\"})\n        self.ed.Run()\n\n# ================================================================================\n# Goto the file but in a split (SPACE)\nclass OrgAgendaGoToSplitCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        agenda = FindMappedView(self.view)\n        if(agenda):\n            row, col    = self.view.curRowCol()\n            n, f = agenda.At(row,col)\n            if(f):\n                if(n):\n                    path = \"{0}:{1}\".format(f.filename,n.start_row + 1)\n                    newView = self.view.window().open_file(path, sublime.ENCODED_POSITION)\n                    move_file_other_group(self.view, newView)\n                    #sublime.set_timeout_async(lambda: move_file_other_group(self.view, newView), 100)\n            else:\n                log.warning(\"COULD NOT LOCATE AGENDA ROW\")\n\n# ================================================================================\nclass OrgTagFilteredTodoViewInternalCommand(sublime_plugin.TextCommand):\n    def run(self,edit,tags):\n        # TODO: add filtering to this and name it nicely\n        ReloadAllUnsavedBuffers()\n        todo = TodoView(TODO_VIEW + \" Filtered By: \" + tags,tagfilter=tags)\n        todo.DoRenderView(edit)\n\n# ================================================================================\nclass OrgTagFilteredTodoViewCommand(sublime_plugin.TextCommand):\n    def run(self,edit):\n        self.view.window().show_input_panel(\n                    \"Tags:\",\n                    \"\",\n                    self.showTodos, None, None)\n\n    def showTodos(self, tags):\n        if(not tags):\n            return\n        self.view.run_command('org_tag_filtered_todo_view_internal', {\"tags\": tags})\n\n# ================================================================================\nclass OrgAgendaGotoNextDayCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        agenda = FindMappedView(self.view)\n        now = agenda.now\n        now = now + datetime.timedelta(days=1)\n        agenda.UpdateNow(now)\n        agenda.Clear(edit)\n        agenda.DoRenderView(edit)\n\n# ================================================================================\nclass OrgAgendaGotoPrevDayCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        agenda = FindMappedView(self.view)\n        now = agenda.now\n        now = now + datetime.timedelta(days=-1)\n        agenda.UpdateNow(now)\n        agenda.Clear(edit)\n        agenda.DoRenderView(edit)\n"
  },
  {
    "path": "orgagenda.sublime-color-scheme",
    "content": "{\n\t\"name\": \"orgagenda\",\n\t\"variables\": {\n\t\t\"bgcol\": \"#272822\",\n\t\t// Define variables here\n\t},\n\t\"globals\": {\n\t\t\"foreground\": \"#F8F8F2\",\n\t\t\"background\": \"var(bgcol)\",\n\t\t\"accent\":     \"#ffffff\",\n\t\t\"selection\":  \"#9D550F\",\n\t    \"selectionBackground\": \"#000000\",\n\t    \"selectionForeground\": \"#FF0000\",\n\t    \"caret\":               \"#FF55ff\",\n\t    \"line_highlight\":      \"#373730\"\n\t},\n\t\"rules\": \n\t[\n\t\t{\n\t\t\t\"scope\": \"orgagenda.header\",\n\t\t\t\"foreground\": \"#5b96f5\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.dateheader\",\n\t\t\t\"foreground\": \"#5b96f5\",\n\t\t\t\"font_style\": \"bold italic underline\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.weekendheader\",\n\t\t\t\"foreground\": \"#ab96f5\",\n\t\t\t\"font_style\": \"bold italic underline\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.timeseparator\",\n\t\t\t\"foreground\": \"#7c7c7d\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.now\",\n\t\t\t\"foreground\": \"#a88cd4\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.filename\",\n\t\t\t\"foreground\": \"#76b3ae\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.todo\",\n\t\t\t\"foreground\": \"#a63229\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.doing\",\n\t\t\t\"foreground\": \"#d2a2e0\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.blocked\",\n\t\t\t\"foreground\": \"#FF0000\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.waiting\",\n\t\t\t\"foreground\": \"#ffff00\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.cancelled\",\n\t\t\t\"foreground\": \"#bab9b8\",\n\t\t\t\"font_style\": \"italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.inprogress\",\n\t\t\t\"foreground\": \"#d2a2e0\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.cleanup\",\n\t\t\t\"foreground\": \"#d2a2e0\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.fixed\",\n\t\t\t\"foreground\": \"#d2a2e0\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.flag\",\n\t\t\t\"foreground\": \"#f2a2e0\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.next\",\n\t\t\t\"foreground\": \"#3fd9d7\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{   // Hide the habit markup in the buffer\n\t\t\t\"scope\": \"orgagenda.habit\",\n\t\t\t\"foreground\": \"var(bgcol)\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.habit.didit\",\n\t\t\t\"foreground\": \"#ffffff\",\n\t\t\t\"background\": \"#007700\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.habit.scheduled\",\n\t\t\t\"foreground\": \"#333300\",\n\t\t\t\"background\": \"#550000\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.habit.nothing\",\n\t\t\t\"foreground\": \"#000066\",\n\t\t\t\"background\": \"#000066\",\n\t\t},\n\t\t{   // Hide the week markup in the buffer\n\t\t\t\"scope\": \"orgagenda.week\",\n\t\t\t\"foreground\": \"var(bgcol)\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.something\",\n\t\t\t\"foreground\": \"#ffffff\",\n\t\t\t\"background\": \"#007700\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.today\",\n\t\t\t\"foreground\": \"#f89cf4\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.active\",\n\t\t\t\"foreground\": \"#f8fc00\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.activetoday\",\n\t\t\t\"foreground\": \"#f89cf4\",\n\t\t\t\"background\": \"#485c00\",\n\t\t\t\"font_style\": \"bold\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.empty\",\n\t\t\t\"foreground\": \"#333300\",\n\t\t\t\"background\": \"#333333\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.nothing\",\n\t\t\t\"foreground\": \"var(bgcol)\",\n\t\t\t\"background\": \"var(bgcol)\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.projecttitle\",\n\t\t\t\"foreground\": \"#a87932\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.blockseparator\",\n\t\t\t\"foreground\": \"#4a4a37\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.monthheader\",\n\t\t\t\"foreground\": \"#a87932\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\n\t\t// Week View Cycling Item Colors\n\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.done.0\",\n\t\t\t\"foreground\": \"#4f4f4f\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.done.1\",\n\t\t\t\"foreground\": \"#666666\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.0\",\n\t\t\t\"foreground\": \"#550000\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.1\",\n\t\t\t\"foreground\": \"#007700\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.2\",\n\t\t\t\"foreground\": \"#770077\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.3\",\n\t\t\t\"foreground\": \"#0000ff\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.4\",\n\t\t\t\"foreground\": \"#999900\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.5\",\n\t\t\t\"foreground\": \"#007777\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.6\",\n\t\t\t\"foreground\": \"#aa5522\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.7\",\n\t\t\t\"foreground\": \"#cc99cc\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.8\",\n\t\t\t\"foreground\": \"#225522\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.9\",\n\t\t\t\"foreground\": \"#623456\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgagenda.week.normal\",\n\t\t\t\"foreground\": \"#ffffff\",\n\t\t},\n\n\t\t{   // Hide the block markup in the buffer\n\t\t\t\"scope\": \"orgagenda.block.1\",\n\t\t\t\"background\": \"#623456\",\n\t\t\t\"foreground\": \"#623456\",\n\t\t},\n\t\t{   // Hide the block markup in the buffer\n\t\t\t\"scope\": \"orgagenda.block.2\",\n\t\t\t\"background\": \"#007777\",\n\t\t\t\"foreground\": \"#007777\",\n\t\t},\n\t\t{   // Hide the block markup in the buffer\n\t\t\t\"scope\": \"orgagenda.block.3\",\n\t\t\t\"background\": \"#999900\",\n\t\t\t\"foreground\": \"#999900\",\n\t\t},\n\t\t{   // Hide the block markup in the buffer\n\t\t\t\"scope\": \"orgagenda.block.4\",\n\t\t\t\"background\": \"#007700\",\n\t\t\t\"foreground\": \"#007700\",\n\t\t},\n\t\t{   // Hide the block markup in the buffer\n\t\t\t\"scope\": \"orgagenda.block.5\",\n\t\t\t\"background\": \"#aa5522\",\n\t\t\t\"foreground\": \"#aa5522\",\n\t\t},\n\t\t{   // Hide the block markup in the buffer\n\t\t\t\"scope\": \"orgagenda.block.6\",\n\t\t\t\"background\": \"#f89cf4\",\n\t\t\t\"foreground\": \"#f89cf4\",\n\t\t},\n\t\t{   // Hide the block markup in the buffer\n\t\t\t\"scope\": \"orgagenda.block.7\",\n\t\t\t\"background\": \"#0000ee\",\n\t\t\t\"foreground\": \"#0000ee\",\n\t\t},\n\n\t]\n}\n\n"
  },
  {
    "path": "orgagenda.sublime-settings",
    "content": "{\n\t// The color scheme to use for the agenda buffer\n\t\"color_scheme\": \"Packages/OrgExtended/orgagenda.sublime-color-scheme\",\n}"
  },
  {
    "path": "orgagenda.sublime-syntax",
    "content": "%YAML 1.2\n---\n# See http://www.sublimetext.com/docs/3/syntax.html\nname: orgagenda\nfile_extensions:\n  - orgagenda\nscope: source.orgagenda\nversion: 2\nhidden: true\ncontexts:\n  main:\n    # filename and line location\n    - match: '(^[a-zA-Z0-9_]+:)'\n      scope: string.quoted orgagenda.filename\n\n    - match: '[0-9]+:[0-9]+(\\.)+ (\\-)+'\n      scope: comment orgagenda.timeseparator\n\n\n    - match: '(D:@)\\d+-\\d+-\\d+'\n      scope: region.yellowish orgmode.deadline.warning\n      captures:\n        1: comment orgmode.preamble\n    \n    - match: '(D: )Overdue'\n      scope: region.redish orgmode.deadline.overdue\n      captures:\n        1: comment orgmode.preamble\n    \n    - match: '(D: )Due Today'\n      scope: region.greenish orgmode.deadline.due\n      captures:\n        1: comment orgmode.preamble\n\n    - match: 'H\\['\n      push:\n        - meta_scope: orgmode.preamble orgagenda.habit\n        - match: '[*]'\n          scope: orgagenda.habit.didit\n        - match: '[.]'\n          scope: orgagenda.habit.scheduled\n        - match: '[_]'\n          scope: orgagenda.habit.nothing\n        - match: '\\]'\n          pop: true\n    # Today in week view\n    - match: '^(#)([A-Za-z]+ *[0-9]+)'\n      scope: orgagenda.week.today\n      captures:\n        1: orgmode.preamble orgagenda.week.nothing\n        2: keyword orgagenda.week.today\n\n    # Active day in week view\n    - match: '^(&)([A-Za-z]+ *[0-9]+)'\n      scope: orgagenda.week.active\n      captures:\n        1: orgmode.preamble orgagenda.week.nothing\n        2: string.quoted orgagenda.week.active\n\n    # Both day in week view\n    - match: '^(@)([A-Za-z]+ *[0-9]+)'\n      scope: orgagenda.week.activetoday\n      captures:\n        1: orgmode.preamble orgagenda.week.nothing\n        2: constant.numeric orgagenda.week.activetoday\n\n    - match: 'W\\['\n      push:\n        - meta_scope: orgmode.preamble orgagenda.week\n        - match: '[a-zA-Z0-9 ]'\n          scope: variable.parameter orgagenda.week.normal\n        - match: '[.]'\n          scope: orgagenda.week.empty\n        - match: '[_]'\n          scope: orgmode.preamble orgagenda.week.nothing\n        - match: '\\]'\n          pop: true\n\n    - match: '((Su)|(Mo)|(Tu)|(We)|(Th)|(Fr)|(Sa)) '\n      scope: orgagenda.header\n      captures:\n        2: constant.numeric orgagenda.weekendheader \n        3: keyword orgagenda.dateheader \n        4: keyword orgagenda.dateheader \n        5: keyword orgagenda.dateheader \n        6: keyword orgagenda.dateheader \n        7: keyword orgagenda.dateheader \n        8: constant.numeric orgagenda.weekendheader \n\n    - match: '^[a-zA-Z][^=>:]+$'\n      scope: keyword orgagenda.header\n\n    # Datetime\n    - match: '(\\d{4,4}-\\d{2,2}-\\d{2,2} \\d{2,2}:\\d{2,2}:\\d{2,2})'\n      scope: markup.italic orgagenda.datetime\n\n    - match: '^\\s*now =>.*'\n      scope: variable.parameter orgagenda.now\n\n    - match: '(DONE)'\n      scope: orgmode.state.done orgagenda.done\n\n    - match: '(TODO)'\n      scope: orgmode.state.todo orgagenda.todo\n\n    - match: '(DOING)'\n      scope: orgmode.state.doing orgagenda.doing\n\n    - match: '(BLOCKED)'\n      scope: orgmode.state.blocked orgagenda.blocked\n\n    - match: '(WAITING)'\n      scope: orgmode.state.waiting orgagenda.waiting\n\n    - match: '(CANCELLED)'\n      scope: orgmode.state.cancelled orgagenda.cancelled\n\n    - match: '(IN-PROGRESS)'\n      scope: orgmode.state.inprogress orgagenda.inprogress\n\n    - match: '(CLEANUP)'\n      scope: orgmode.state.cleanup orgagenda.cleanup\n\n    - match: '(FIXED)'\n      scope: orgmode.state.fixed orgagenda.fixed\n\n    - match: '(FLAG)'\n      scope: orgmode.state.flag orgagenda.flag\n\n    - match: '(NEXT)'\n      scope: orgmode.state.next orgagenda.next\n\n    - match: '\\s+-------\\s+.*'\n      scope: comment orgagenda.projecttitle\n\n    - match: '^=====+'\n      scope: comment orgagenda.blockseparator\n\n    - match: '(January|February|March|April|May|June|July|August|September|October|November|December)\\s*([0-9]+)'\n      scope: constant.numeric orgagenda.monthheader\n    \n    - match: 'B\\['\n      scope: orgmode.preamble orgagenda.week.nothing\n      push:\n        - meta_scope: orgagenda.block\n        - match: '[\\$]'\n          scope: keyword orgagenda.block.1\n        - match: '[\\@]'\n          scope: constant.numeric orgagenda.block.2\n        - match: '[!]'\n          scope: string orgagenda.block.3\n        - match: '[#]'\n          scope: variable.parameter orgagenda.block.4\n        - match: '[%]'\n          scope: entity.name.class orgagenda.block.5\n        - match: '[\\^]'\n          scope: entity.name.function orgagenda.block.6\n        - match: '[&]'\n          scope: source orgagenda.block.7\n        - match: '\\]'\n          scope: orgmode.preamble orgagenda.week.nothing\n          pop: true\n\n    - match: '^== \\[.*\\] ==$'\n      scope: keyword orgagenda.header orgagenda.projecttitle\n"
  },
  {
    "path": "orgbuiltinresources.py",
    "content": "import json\nimport sublime\nimport sublime_plugin\n\n\ndef sortMessages(x):\n    r = x\n    xs = x.split('.')\n    if(len(xs) <= 1):\n        return 0\n    m = 1\n    c = 0\n    for i in range(len(xs)-1,-1,-1):\n        x = xs[i]\n        c = c+(int(x)*m)\n        m *= 100\n    return c\n\n# ===================================================================================\nclass OrgBuildDevDocsCommand(sublime_plugin.TextCommand):\n    \"\"\"Show the current worklog to the user\"\"\"\n    def run(self, edit):\n        view = sublime.active_window().new_file()\n        view.set_syntax_file(\"Packages/OrgExtended/OrgExtended.sublime-syntax\")\n        messData = sublime.load_resource(\"Packages/OrgExtended/messages.json\")\n        msgs = json.loads(messData)\n        ks = msgs.keys()\n        ks = list(ks)\n        ks = sorted(ks, key=sortMessages, reverse=True)\n        for n in ks:\n            name = n + \".org\"\n            pdata = None\n            try:\n                pdata = sublime.load_resource(\"Packages/OrgExtended/messages/\" + name)\n            except:\n                pass\n            if(not pdata):\n                continue\n            pdata = pdata.replace(\"\\r\",\"\")\n            view.insert(edit,view.size(),\"\\n\" + pdata + \"\\n\")\n        pass\n\n# ===================================================================================\nclass OrgShowTestfileCommand(sublime_plugin.TextCommand):\n    \"\"\"Show an org testfile to help users get started\"\"\"\n    def run(self, edit):\n        view = sublime.active_window().new_file()\n        view.set_syntax_file(\"Packages/OrgExtended/OrgExtended.sublime-syntax\")\n        data = sublime.load_resource(\"Packages/OrgExtended/tests/testfile.org\")\n        data = data.replace(\"\\r\",\"\")\n        view.insert(edit,view.size(),\"\\n\" + data + \"\\n\")\n        view.run_command(\"save\")\n\n# ===================================================================================\nclass OrgShowTableTestsCommand(sublime_plugin.TextCommand):\n    \"\"\"Show the org extended table unit tests to help users get started\"\"\"\n    def run(self, edit):\n        view = sublime.active_window().new_file()\n        view.set_syntax_file(\"Packages/OrgExtended/OrgExtended.sublime-syntax\")\n        data = sublime.load_resource(\"Packages/OrgExtended/tests/tableunittests.org\")\n        data = data.replace(\"\\r\",\"\")\n        view.insert(edit,view.size(),\"\\n\" + data + \"\\n\")\n        view.run_command(\"save\")\n\n# ===================================================================================\nclass OrgShowSourceBlockTestsCommand(sublime_plugin.TextCommand):\n    \"\"\"Show the org extended babel unit tests to help users get started\"\"\"\n    def run(self, edit):\n        view = sublime.active_window().new_file()\n        view.set_syntax_file(\"Packages/OrgExtended/OrgExtended.sublime-syntax\")\n        data = sublime.load_resource(\"Packages/OrgExtended/tests/sourceunittests.org\")\n        data = data.replace(\"\\r\",\"\")\n        view.insert(edit,view.size(),\"\\n\" + data + \"\\n\")\n        view.run_command(\"save\")\n"
  },
  {
    "path": "orgcapture.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nimport os\nimport OrgExtended.orgparse.loader as loader\nimport OrgExtended.orgparse.node as node\nimport OrgExtended.orgutil.template as templateEngine\nimport OrgExtended.orgparse.date as orgdate\nimport OrgExtended.orgextension as ext\nimport OrgExtended.orgclocking as clk\nimport logging\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgproperties as props\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orgdaypage as daypage\n\nlog = logging.getLogger(__name__)\ncaptureBufferName = \"*capture*\"\nlastHeader        = None\n\n\ndef GetViewById(id):\n    win = sublime.active_window()\n    for v in win.views():\n        if (v.id() == id):\n            return v\n    return None\n\n\ndef GetDict():\n    tempDict = {\n        'refile': sets.Get('refile', ''),\n        'daypage': daypage.dayPageGetName(daypage.dayPageGetToday()),\n    }\n    return tempDict\n\n\ndef GetCaptureFile(view, template, target):\n    # temp = templateEngine.TemplateFormatter(sets.Get)\n    filename = templateEngine.ExpandTemplate(view, target[1], GetDict(), sets.Get)[0]\n    return filename\n\n\ndef GetCaptureFileAndParam(view, template, target):\n    # temp = templateEngine.TemplateFormatter(sets.Get)\n    tempDict = GetDict()\n    filename = templateEngine.ExpandTemplate(view, target[1], tempDict, sets.Get)[0]\n    headline = None\n    if (len(target) > 2):\n        headline = templateEngine.ExpandTemplate(view, target[2], tempDict, sets.Get)[0]\n    return (filename, headline)\n\n\ndef FindNodeByPath(n, target, idx):\n    if (idx >= len(target)):\n        return n\n    for c in n.children:\n        if (c.heading == target[idx]):\n            return FindNodeByPath(c, target, idx + 1)\n    return None\n\n\ndef GetCapturePath(view, template):\n    target    = ['file', '{refile}']\n    if 'target' in template:\n        target    = template['target']\n    filename = None\n    file = None\n    at = None\n    toinsert = \"\"\n    if ('file' in target[0]):\n        filename = GetCaptureFile(view, template, target)\n    if ('file+headline' in target[0]):\n        filename, headline = GetCaptureFileAndParam(view, template, target)\n        file = db.Get().LoadNew(filename)\n        if (file and headline):\n            at = file.FindOrCreateNode(headline)\n            if (at):\n                at = at.local_end_row\n    elif ('file+regexp' in target[0]):\n        filename, reg = GetCaptureFileAndParam(view, template, target)\n        file = db.Get().LoadNew(filename)\n        if (file and reg):\n            r = re.compile(reg)\n            row = 0\n            for n in file.org:\n                for line in n._lines:\n                    m = r.search(line)\n                    if (m):\n                        at = row\n                        break\n                    row += 1\n    elif ('file+olp+datetree' in target[0]):\n        filename, reg = GetCaptureFileAndParam(view, template, target)\n        file = db.Get().FindInfo(filename)\n        n = FindNodeByPath(file.org, target, 2)\n        if (not n):\n            n = file.org\n        # Now we assume this is a date tree. Default is per day.\n        t = datetime.datetime.now()\n        yearformat  = t.strftime(GetProp(template, \"year-format\",  \"%Y\"))\n        monthformat = t.strftime(GetProp(template, \"month-format\", \"%Y-%m %B\"))\n        dayformat   = t.strftime(GetProp(template, \"day-format\",   \"%Y-%m-%d %A\"))\n        nyear  = None\n        nmonth = None\n        nday   = None\n        prefix   = \"\"\n        if (n.level > 0):\n            prefix = \"*\" * n.level\n        for c in n.children:\n            if (c.heading == yearformat):\n                nyear = c\n                break\n        if (nyear is None):\n            toinsert += \"{prefix}* {yearformat}\\n\".format(prefix=prefix, yearformat=yearformat)\n        else:\n            n = nyear\n            for c in nyear.children:\n                if (c.heading == monthformat):\n                    nmonth = c\n                    break\n        if (nmonth is None):\n            toinsert += \"{prefix}** {monthformat}\\n\".format(prefix=prefix, monthformat=monthformat)\n        else:\n            n = nmonth\n            for c in nmonth.children:\n                if (c.heading == dayformat):\n                    nday = c\n                    break\n        if (nday is None):\n            toinsert += \"{prefix}*** {dayformat}\\n\".format(prefix=prefix, dayformat=dayformat)\n        else:\n            n = nday\n        if (n and toinsert == \"\"):\n            at = n.local_end_row\n        else:\n            at = n.end_row\n    elif ('file+olp' in target[0]):\n        filename, reg = GetCaptureFileAndParam(view, template, target)\n        file = db.Get().LoadNew(filename)\n        n = FindNodeByPath(file.org, target, 2)\n        if (n):\n            at = n.local_end_row\n\n    elif ('id' == target[0]):\n        file, at = db.Get().FindByCustomId(target[1])\n        if (file is None):\n            log.error(\"Could not find id: \" + target[1])\n            return\n        filename = file.filename\n    elif ('clock' == target[0]):\n        if (not clk.ClockManager.ClockRunning()):\n            log.debug(\"ERROR: clock is not running!\")\n            raise \"ERROR: clock is not running\"\n        filename = clk.ClockManager.GetActiveClockFile()\n        at       = clk.ClockManager.GetActiveClockAt()\n    # Try to create my capture file if I can\n    try:\n        # Ensure the directory exists first\n        dirName = os.path.dirname(os.path.abspath(filename))\n        if (not os.path.exists(dirName)):\n            os.makedirs(dirName, exist_ok=True)\n        if (not os.path.isfile(str(filename))):\n            with open(filename, \"w\", encoding=sets. Get(\"captureWriteFormat\", \"utf-8\")) as fp:\n                fp.write(\"#+FILETAGS: :refile:\\n\")\n    except Exception as e:\n        log.error(\"@@@@@@@@@@@@\\nFailed to create capture file: \" + str(filename) + \"\\n\" + str(e))\n    # Now make sure that file is loaded in the DB\n    # it might not be in my org path\n    if (file is None):\n        file = db.Get().LoadNew(filename)\n    else:\n        file = db.Get().FindInfo(filename)\n    if (not at and file):\n        at = file.org.start_row\n    return (target, filename, file, at, toinsert)\n\n\n# This is a bit hokey. We track the last header so\n# if you change the header we can still find it\n# in your target file. Every time you swap your\n# mouse away from the capture window we auto save\n# the capture to your target location.\n# TODO: Add more target locations than your refile file.\ndef onDeactivated(view):\n    global captureBufferName\n    global lastHeader\n    if (view.name() == captureBufferName):\n        tempIndex = view.settings().get('cap_index')\n        templates = sets.Get(\"captureTemplates\", [])\n        template  = templates[tempIndex]\n        # outpath, outfile = GetCaptureOutput()\n        # print('template index was: ' + str(tempIndex))\n        target, capturePath, captureFile, at, toinsert = GetCapturePath(GetViewById(view.settings().get('cap_view')), template)\n        # refilePath = sets.Get(\"refile\",\"UNKNOWN\")\n        # refile = load(refilePath)\n        captureFileRoot = None\n        if (captureFile is not None):\n            captureFileRoot = captureFile.org\n\n        bufferContentsToInsert = view.substr(sublime.Region(0, view.size()))\n        if not bufferContentsToInsert.endswith('\\n'):\n            bufferContentsToInsert += \"\\n\"\n        didInsert = False\n        # Get a capture node\n        captureNode = loader.loads(bufferContentsToInsert)\n        # if we moused out of the window we might be replacing\n        # ourselves again.\n        if (lastHeader is None):\n            lastHeader = str(captureNode[1].heading)\n        # We may haved moved around in the capture file\n        # so find the old heading.\n        for heading in captureFileRoot:\n            if (type(heading) is node.OrgRootNode):\n                continue\n            if str(heading.heading) == lastHeader:\n                # log.debug(\"REPLACING: \" + str(heading.heading))\n                heading.replace_node(captureNode[1])\n                didInsert = True\n                continue\n        if (not didInsert):\n            insertAt = captureFileRoot\n            inserted = captureNode[1]\n            if (at is not None and at > 0):\n                # This does not work? its a node not a file\n                insertAt = captureFile.At(at)\n            insertAt.insert_child(inserted)\n        f = open(capturePath, \"w+\", encoding=sets.Get(\"captureWriteFormat\", \"utf-8\"))\n        # reauthor the ENTIRE file.\n        # This can get expensive!\n        for item in captureFileRoot:\n            f.write(str(item))\n        f.close()\n        lastHeader = str(captureNode[1].heading)\n        log.debug(\"***************>>>>> [\" + view.name() + \"] is no more\")\n\n\n# Respond to panel events. If the panel is hidden we stop\n# tracking the last header.\ndef onPostWindowCommand(window, cmd, args):\n    if cmd == \"hide_panel\":\n        global lastHeader\n        # This stops the capture refiling\n        # From finding an entry across capture\n        # window openings\n        lastHeader = None\n\n\nclass OrgCopyCommand(sublime_plugin.TextCommand):\n    def on_done_st4(self, index, modifers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        file, fileIndex = db.Get().FindFileInfoByAllHeadingsIndex(index)\n        node = db.Get().AtInView(self.view)\n        if (fileIndex is not None):\n            # print(str(file.key))\n            file.org[fileIndex].insert_child(node)\n            file.Save()\n        else:\n            log.error(\"Failed to copy, fileindex not found\")\n\n    def run(self, edit):\n        self.headings = db.Get().AllHeadingsWContext(self.view)\n        if (int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(self.headings, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(self.headings, self.on_done_st4, -1, -1)\n\n\nclass OrgOpenRefileCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        refile = sets.Get(\"refile\", None)\n        log.debug(\"REFILE: \", refile)\n        if (refile):\n            self.view.window().open_file(refile)\n        else:\n            log.error(\"Could not find refile file, have you set it in your config?\")\n\n\n# Archiving will push the current item to an archive file (with some tags etc)\nclass OrgArchiveSubtreeCommand(sublime_plugin.TextCommand):\n\n    def close_tempView(self):\n        self.tempView.run_command(\"close\")\n\n    def finish_archive_on_loaded(self):\n        while (self.tempView. is_loading()):\n            sublime.set_timeout_async(lambda: self.finish_archive_on_loaded(), 100)\n        node = self.file.At(self.result.start_row)\n        # :ARCHIVE_TIME: 2017-11-30 Thu 18:15\n        # :ARCHIVE_FILE: ~/notes/inxile/worklog.org\n        # :ARCHIVE_OLPATH: Daily\n        # :ARCHIVE_CATEGORY: InXile\n        # :ARCHIVE_ITAGS: InXile\n        props.UpdateProperty(self.tempView, node, \"ARCHIVE_TIME\", datetime.datetime.now().strftime(\"%Y-%m-%d %a %H:%M\"))\n        props.UpdateProperty(self.tempView, node, \"ARCHIVE_FILE\", self.view.file_name())\n        self.tempView.run_command(\"save\")\n        sublime.set_timeout_async(lambda: self.close_tempView(), 1000)\n        # Now remove the old node\n        self.sourceNode.remove_node()\n        fromFile = db.Get().FindInfo(self.view)\n        fromFile.Save()\n        fromFile.Reload()\n\n    def run(self, edit, onDone=None):\n        globalArchive = sets.Get(\"archive\", \"%s_archive::\")\n        node          = db.Get().AtInView(self.view)\n        archive       = node.archive(globalArchive)\n        if (archive is None or archive.strip() == \"\"):\n            node = db.Get().AtInView(self.view)\n            node.add_tag(\"ARCHIVE\")\n            file = db.Get().FindInfo(self.view)\n            file.Save()\n            print(str(node))\n            return\n        # Set the root to empty if not provided\n        if ('::' not in archive):\n            archive = archive + \"::\"\n        (fileTemplate, headingTarget) = archive.split('::')\n        if ('%' in fileTemplate):\n            filename      = fileTemplate % (self.view.file_name())\n        else:\n            filename = fileTemplate\n        log.debug(\"ARCHIVE FILE:    \" + filename)\n        log.debug(\"ARCHIVE HEADING: \" + headingTarget)\n\n        # Ensure the file actually exists.\n        if (not os.path.dirname(filename).strip() == ''):\n            os.makedirs(os.path.dirname(filename), exist_ok=True)\n        # Okay the file is probably a local path\n        # Get the full path from our file.\n        else:\n            localDirname = os.path.dirname(self.view.file_name())\n            if ('/' not in filename and '\\\\' not in filename):\n                filename = os.path.join(localDirname, filename)\n        with open(filename, \"a\", encoding=sets.Get(\"captureWriteFormat\", \"utf-8\")) as f:\n            f.write(\"\")\n            log.debug(\"  Archive file created...\")\n        # Okay now open the file.\n        file       = db.Get().FindInfo(filename)\n        sourceNode = db.Get().AtInView(self.view)\n        if (sourceNode is not None):\n            log.debug(\"Find or create: \" + headingTarget)\n            targetNode = file.FindOrCreateNode(headingTarget)\n            if (targetNode is None):\n                targetNode = file.Root()\n                self.result = targetNode.insert_child(sourceNode)\n                self.result.update_property(\"ARCHIVE_TIME\", datetime.datetime.now().strftime(\"%Y-%m-%d %a %H:%M\"))\n                self.result.update_property(\"ARCHIVE_FILE\", self.view.file_name())\n                for n in file.org[1:]:\n                    print(n.full_heading)\n            else:\n                log.debug(\"Inserting heading at: \" + targetNode.heading)\n                log.debug(\"Inserting: \" + sourceNode.heading)\n                self.result = targetNode.insert_child(sourceNode)\n\n                self.result.update_property(\"ARCHIVE_TIME\", datetime.datetime.now().strftime(\"%Y-%m-%d %a %H:%M\"))\n                self.result.update_property(\"ARCHIVE_FILE\", self.view.file_name())\n                for n in file.org[1:]:\n                    print(n.full_heading)\n            log.debug(\"Saving the source file\")\n            file.Save()\n            file.Reload()\n\n            sourceNode.remove_node()\n            fromFile = db.Get().FindInfo(self.view)\n            fromFile.Save()\n            fromFile.Reload()\n            # self.tempView = self.view.window().open_file(file.filename, sublime.ENCODED_POSITION)\n            # self.file = file\n            # self.sourceNode = sourceNode\n            # sublime.set_timeout_async(lambda: self.finish_archive_on_loaded(), 1000)\n        else:\n            log.error(\"Failed to archive subtree! Could not find source Node\")\n        evt.EmitIf(onDone)\n\nclass OrgArchiveAllDoneCommand(sublime_plugin.TextCommand):\n    def onDone(self):\n        self.view.run_command(\"org_archive_all_done\")\n\n    def run(self, edit):\n        file = db.Get().Find(self.view)\n        if len(file) > 1:\n            for n in file[1:]:\n                if n.todo == \"DONE\":\n                    self.view.sel().clear()\n                    sp  = self.view.text_point(n.start_row,0)\n                    self.view.sel().add(sp)\n                    self.view.run_command(\"org_archive_subtree\", {\"onDone\": evt.Make(self.onDone)})\n                    return\n\ndef RefileCurNode(view, file, nodeIndex):\n    (curRow, curCol) = view.curRowCol()\n    node = db.Get().At(view, curRow)\n\n    if (node is None):\n        log.error(\"COULD NOT REFILE: Node at line \" + str(curRow) + \" not found\")\n        return\n    if (nodeIndex is None):\n        log.error(\"Could not refile node index is out of bounds\")\n        return\n    log.debug(\"Inserting child into: \" + str(nodeIndex) + \" vs \" + str(len(file.org)) + \" in file: \" + file.filename)\n\n    fromFile = db.Get().FindInfo(view)\n    file.org[nodeIndex].insert_child(node)\n    node.remove_node()\n    # Have to save down here in case\n    # file and fromFile are the same!\n    file.Save()\n    file.Reload()\n    fromFile.Save()\n    fromFile.Reload()\n\n\n# This refile gives you a list of all headings to make it quicker to jump to\n# \"That heading\" This one is bound to R for really quick refiling.\nclass OrgRefileCommand(sublime_plugin.TextCommand):\n    def on_done_st4(self, index, modifiers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        if (index < 0):\n            return\n        file, fileIndex = db.Get().FindFileInfoByAllHeadingsIndex(index)\n        RefileCurNode(self.view, file, fileIndex)\n\n    def run(self, edit):\n        self.headings = db.Get().AllHeadingsWContext(self.view)\n        if (int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(self.headings, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(self.headings, self.on_done_st4, -1, -1)\n\n\n# This refile, files to the end of the file.\nclass OrgRefileToFileCommand(sublime_plugin.TextCommand):\n    def on_done_st4(self, index, modifiers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        if (index < 0):\n            return\n        file = db.Get().FindFileByIndex(index)\n        fileIndex = 0\n        RefileCurNode(self.view, file, fileIndex)\n\n    def run(self, edit):\n        self.headings = db.Get().AllFiles(self.view)\n        if (int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(self.headings, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(self.headings, self.on_done_st4, -1, -1)\n\n\n# This refile version takes a filename prompt first\n# then it shows the headings in the file.\nclass OrgRefileToFileAndHeadlineCommand(sublime_plugin.TextCommand):\n    def on_done_st4(self, index, modifiers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        if (index < 0):\n            return\n        self.file = db.Get().FindFileByIndex(index)\n        self.headings = db.Get().AllHeadingsForFile(self.file)\n        if (int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(self.headings, self.on_done_v2, -1, -1)\n        else:\n            self.view.window().show_quick_panel(self.headings, self.on_done_st4_v2, -1, -1)\n\n    def on_done_st4_v2(self, index, modifiers):\n        self.on_done_v2(index)\n\n    def on_done_v2(self, index):\n        if (index < 0):\n            return\n        RefileCurNode(self.view, self.file, index + 1)\n        pass\n\n    def run(self, edit):\n        headings = db.Get().AllFiles(self.view)\n        if (int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(headings, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(headings, self.on_done_st4, -1, -1)\n\n\nclass OrgCaptureBaseCommand(sublime_plugin.TextCommand):\n    def on_done(self, index):\n        pass\n\n    def on_done_base_st3(self, index):\n        if (index < 0):\n            return\n        self.templates         = sets.Get(\"captureTemplates\", [])\n        self.on_done(index)\n\n    def on_done_base_st4(self, index, modifiers):\n        self.on_done_base_st3(index)\n\n    def run(self, edit):\n        templates = sets.Get(\"captureTemplates\", [])\n        temps = []\n        for temp in templates:\n            log.debug(\"TEMPLATE: \", temp)\n            temps.append(temp['name'])\n        if (int(sublime.version()) >= 4096):\n            self.view.window().show_quick_panel(temps, self.on_done_base_st4, -1, -1)\n        else:\n            self.view.window().show_quick_panel(temps, self.on_done_base_st3, -1, -1)\n\n\ndef IsType(val, template):\n    return 'type' in template and template['type'].strip() == val\n\n\ndef GetProp(template, name, defaultVal=None):\n    if ('properties' in template):\n        props = template['properties']\n        if (isinstance(props, dict)):\n            if (name in props):\n                return props[name]\n    return defaultVal\n\n\n# Capture some text into our refile org file\nclass OrgCaptureCommand(OrgCaptureBaseCommand):\n    def insert_template(self, template, panel):\n        # template          = templates[index]['template']\n        startPos = -1\n        template, startPos = templateEngine.ExpandTemplate(self.view, template)\n\n        panel.run_command(\"insert\", {\"characters\": template})\n        if (startPos >= 0):\n            startPos = sublime.Region(startPos)\n        else:\n            startPos = panel.sel()[0]\n        return startPos\n\n    def cleanup_capture_panel(self):\n        global captureBufferName\n        if (not self.openas):\n            self.panel.set_syntax_file('Packages/OrgExtended/OrgExtended.sublime-syntax')\n            self.panel.set_name(captureBufferName)\n\n    # In OpenAs mode we insert some pre-heading stars\n    # Before inserting the snippet. This SHOULD get our\n    # heading where it needs to be?\n    def on_added_stars(self):\n        self.pt = self.panel.text_point(self.insertRow, 0)\n        linev = self.panel.line(self.pt)\n        linetxt = self.panel.substr(linev)\n        self.panel.sel().clear()\n        self.panel.sel().add(linev.begin() + len(linetxt.rstrip()))\n        self.insert_snippet(self.index)\n\n    def find_end_of_thing(self, panel, insertAt, itemre):\n        self.insertRow = insertAt.local_end_row\n        self.pt = panel.text_point(insertAt.local_end_row, 0)\n        # item_line_regex   = re.compile(r'^(\\s*)([-+])\\s*[^\\[]')\n        have = False\n        itemtype = '-'\n        preprefix = \" \" * (insertAt.level + 1)\n        for row in range(insertAt.start_row, insertAt.local_end_row + 1):\n            pt = panel.text_point(row, 0)\n            line  = panel.substr(panel.line(pt))\n            m = itemre.search(line)\n            if (m):\n                preprefix = m.group(1)\n                itemtype = m.group(2)\n                have = True\n            elif (have):\n                self.insertRow = row\n                self.pt = pt\n                break\n        return (preprefix, itemtype)\n\n    def on_panel_ready(self, index, openas, panel, cnt=0):\n        self.panel = panel\n        global captureBufferName\n        captureBufferName = sets.Get(\"captureBufferName\", captureBufferName)\n        window = self.view.window()\n        template = self.templates[index]\n        target, capturePath, captureFile, at, toinsert = GetCapturePath(self.view, template)\n        if (panel.is_loading()):\n            sublime.set_timeout_async(lambda: self.on_panel_ready(index, openas, panel), 100)\n            return\n\n        if (toinsert != \"\" and cnt == 0):\n            pt = panel.text_point(at, 0)\n            linev = panel.line(pt)\n            linetxt = panel.substr(linev)\n            if ((linetxt and not linetxt.strip() == \"\") or at == 0 or panel.lastRow() == at):\n                toinsert = \"\\n\" + toinsert\n                pt = linev.end()\n            else:\n                pt = linev.begin()\n            panel.Insert(pt, toinsert, evt.Make(lambda: self.on_panel_ready(index, openas, panel, cnt + 1)))\n            return\n\n        startPos = -1\n        # Try to store the capture index\n        panel.settings().set('cap_index', index)\n        panel.settings().set('cap_view', self.view.id())\n        self.openas = openas\n        if ((IsType('item', template) or IsType('checkitem', template) or IsType('plain', template) or IsType('table-line', template)) and 'snippet' not in template):\n            template['snippet'] = 'plain_template'\n            if ('template' in template):\n                del template['template']\n\n        if ('template' in template):\n            startPos = self.insert_template(template['template'], panel)\n            window.run_command('show_panel', args={'panel': 'output.orgcapture'})\n            panel.sel().clear()\n            panel.sel().add(startPos)\n            window.focus_view(panel)\n            self.cleanup_capture_panel()\n        elif ('snippet' in template):\n            self.level = 0\n            self.pt = None\n            prefix = \"\"\n            preprefix = \"\"\n            itemtype = '-'\n            if (self.openas):\n                insertAt = captureFile.At(at)\n                if (IsType('plain', template)):\n                    self.pt = panel.text_point(insertAt.local_end_row, 0)\n                    self.insertRow = insertAt.local_end_row\n                elif (IsType('checkitem', template)):\n                    preprefix, itemtype = self.find_end_of_thing(panel, insertAt, re.compile(r'^(\\s*)([-+])\\s*(\\[[xX\\- ]\\])\\s+'))\n                elif (IsType('item', template)):\n                    preprefix, itemtype = self.find_end_of_thing(panel, insertAt, re.compile(r'^(\\s*)([-+])\\s*[^\\[]'))\n                elif (IsType('table-line', template)):\n                    preprefix, itemtype = self.find_end_of_thing(panel, insertAt, re.compile(r'^(\\s*)([|])'))\n                else:\n                    self.pt = panel.text_point(insertAt.end_row, 0)\n                    self.insertRow = insertAt.end_row\n                linev = panel.line(self.pt)\n                linetxt = panel.substr(linev)\n                if ((linetxt and not linetxt.strip() == \"\") or at == 0 or (insertAt and panel.lastRow() == insertAt.end_row)):\n                    prefix = \"\\n\"\n                    self.pt = linev.end()\n                    self.insertRow += 1\n                else:\n                    self.pt = linev.begin()\n                panel.sel().clear()\n                panel.sel().add(self.pt)\n                self.level = insertAt.level\n            else:\n                window.run_command('show_panel', args={'panel': 'output.orgcapture'})\n            if (self.openas and self.level > 0):\n                self.index = index\n                self.panel = panel\n                if (IsType('plain', template)):\n                    self.panel.Insert(self.pt, prefix + (\" \" * (self.level + 1)), evt.Make(self.on_added_stars))\n                elif (IsType('item', template)):\n                    self.panel.Insert(self.pt, prefix + preprefix + itemtype + \" \", evt.Make(self.on_added_stars))\n                elif (IsType('checkitem', template)):\n                    self.panel.Insert(self.pt, prefix + preprefix + itemtype + \" [ ] \", evt.Make(self.on_added_stars))\n                elif (IsType('table-line', template)):\n                    self.panel.Insert(self.pt, prefix + preprefix + itemtype, evt.Make(self.on_added_stars))\n                else:\n                    self.panel.Insert(self.pt, prefix + (\"*\" * self.level), evt.Make(self.on_added_stars))\n            else:\n                if (IsType('plain', template)):\n                    self.panel.Insert(self.pt, prefix, evt.Make(self.on_added_stars))\n                elif (prefix != \"\"):\n                    self.index = index\n                    self.panel = panel\n                    self.panel.Insert(self.pt, prefix, evt.Make(self.on_added_stars))\n                else:\n                    self.insert_snippet(index)\n\n    def insert_snippet(self, index):\n        window = self.view.window()\n        template = self.templates[index]\n        ai = sublime.active_window().active_view().settings().get('auto_indent')\n        self.panel.settings().set('auto_indent', False)\n        snippet = template['snippet']\n        snipName = ext.find_extension_file('orgsnippets', snippet, '.sublime-snippet')\n        window.focus_view(self.panel)\n        # panel.meta_info(\"shellVariables\", 0)[0]['TM_EMAIL'] = \"Trying to set email value\"\n        self.panel.run_command('_enter_insert_mode', {\"count\": 1, \"mode\": \"mode_internal_normal\"})\n        now = datetime.datetime.now()\n        inow = orgdate.OrgDate.format_date(now, False)\n        anow = orgdate.OrgDate.format_date(now, True)\n        # \"Packages/OrgExtended/orgsnippets/\"+snippet+\".sublime-snippet\"\n        # OTHER VARIABLES:\n        # TM_FULLNAME - Users full name\n        # TM_FILENAME - File name of the file being edited\n        # TM_CURRENT_WORD - Word under cursor when snippet was triggered\n        # TM_SELECTED_TEXT - Selected text when snippet was triggered\n        # TM_CURRENT_LINE - Line of snippet when snippet was triggered\n        self.panel.run_command(\"insert_snippet\", {\n            \"name\": snipName,\n            \"ORG_INACTIVE_DATE\": inow,\n            \"ORG_ACTIVE_DATE\":   anow,\n            \"ORG_DATE\":          str(datetime.date.today()),\n            \"ORG_TIME\":          datetime.datetime.now().strftime(\"%H:%M:%S\"),\n            \"ORG_CLIPBOARD\":     sublime.get_clipboard(),\n            \"ORG_SELECTION\":     self.view.substr(self.view.sel()[0]),\n            \"ORG_LINENUM\":       str(self.view.curRow()),\n            \"ORG_FILENAME\":      self.view.file_name()\n        })\n        sublime.active_window().active_view().settings().set('auto_indent', ai)\n        self.cleanup_capture_panel()\n\n    def on_done_st4(self, index, modifiers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        if (index < 0):\n            return\n        global captureBufferName\n        captureBufferName = sets.Get(\"captureBufferName\", captureBufferName)\n        window = self.view.window()\n        template = self.templates[index]\n        target, capturePath, captureFile, at, toinsert = GetCapturePath(self.view, template)\n        openas = False\n        if ('openas' in template and 'direct' == template['openas']):\n            panel = window.open_file(capturePath)\n            openas = True\n        else:\n            panel = window.create_output_panel(\"orgcapture\")\n        self.on_panel_ready(index, openas, panel)\n"
  },
  {
    "path": "orgcheckbox.py",
    "content": "import sublime\nimport sublime_plugin\nimport re\nimport logging\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\n\n\nlog = logging.getLogger(__name__)\n\n# Stolen from the original orgmode\n\n\nclass CheckState:\n    Unchecked, Checked, Indeterminate, Error = range(1, 5)\n\n\nindent_regex     = re.compile(r'^(\\s*).*$')\nsummary_regex    = re.compile(r'(\\[\\d*[/%]\\d*\\])')\ncheckbox_regex   = re.compile(r'(\\[[xX\\- ]\\])')\ncheckbox_line_regex   = re.compile(r'\\s*[-+]?\\s*(\\[[xX\\- ]\\])\\s+')\nunordered_line_regex   = re.compile(r'\\s*[-+]\\s+')\n\n\n# Extract the indent of this checkbox.\n# RETURNS: a string with the indent of this line.\ndef get_indent(view, content):\n    if isinstance(content, sublime.Region):\n        content = view.substr(content)\n    match = indent_regex.match(content)\n    if (match):\n        return match.group(1)\n    else:\n        log.debug(\"Could not match indent: \" + content)\n        return \"\"\n\n\nRE_HEADING = re.compile('^[*]+ ')\n\ndef check_type(line):\n    if checkbox_regex.search(line):\n        return \"C\"\n    if unordered_line_regex.search(line):\n        return \"L\"\n    ls = line.strip()\n    if len(ls) > 0 and ls[0] == \"*\":\n        return \"H\"\n\n# Try to find the parent of a region (by indent)\ndef find_parent(view, region):\n    row, col = view.rowcol(region.begin())\n    content  = view.substr(view.line(region))\n    indent   = len(get_indent(view, content))\n    row     -= 1\n    found    = False\n    # Look upward\n    while row >= 0:\n        point = view.text_point(row, 0)\n        content = view.substr(view.line(point))\n        if len(content.strip()):\n            if (RE_HEADING.search(content)):\n                break\n            cur_indent = len(get_indent(view, content))\n            if cur_indent < indent:\n                found = True\n                break\n        row -= 1\n    if found:\n        # return the parent we found.\n        return view.line(view.text_point(row,0))\n\n\ndef find_heading(view, region):\n    row, col = view.rowcol(region.begin())\n    row -= 1\n    found = False\n    while row >= 0:\n        point = view.text_point(row, 0)\n        content = view.substr(view.line(point))\n        if len(content.strip()):\n            if RE_HEADING.search(content) and get_summary(view, view.line(point)):\n                found = True\n                break\n        row -= 1\n    if found:\n        # return the heading we found.\n        return view.line(view.text_point(row, 0))\n\n\ndef find_children(view, region, cre = checkbox_regex, includeSiblings=False, recursiveChildFind=False):\n    row, col = view.rowcol(region.begin())\n    line = view.line(region)\n    content = view.substr(line)\n    # print content\n    indent = get_indent(view, content)\n    if(not indent):\n        log.debug(\"Unable to locate indent for line: \" + str(row))\n    indent = len(indent)\n    # print repr(indent)\n    row += 1\n    child_indent = None\n    children = []\n    last_row, _ = view.rowcol(view.size())\n    check = None\n    while row <= last_row:\n        point = view.text_point(row, 0)\n        line = view.line(point)\n        content = view.substr(line)\n        summary = get_summary(view, line)\n        lc = content.lstrip()\n        if lc.startswith(\"*\") or lc.startswith('#'):\n             break\n        if cre.search(content):\n            if check is None:\n                check = check_type(content)\n            cur_indent = len(get_indent(view, content))\n            # check for end of descendants\n            if includeSiblings and cur_indent < indent:\n                break\n            elif not includeSiblings and cur_indent <= indent:\n                break\n            # only immediate children (and siblings)\n            if(not recursiveChildFind):\n                if child_indent is None:\n                    child_indent = cur_indent\n                if cur_indent == child_indent:\n                    children.append(line)\n                if(includeSiblings and cur_indent < child_indent):\n                    children.append(line)\n            else:\n                children.append(line)\n        else:\n            if check is not None:\n                lineType = check_type(content)\n                if check != \"H\" and lineType != check:\n                    break\n        row += 1\n    return children\n\ndef find_siblings(view, child, parent):\n    row, col      = view.rowcol(parent.begin())\n    parent_indent = get_indent(view, parent)\n    child_indent  = get_indent(view, child)\n    siblings = []\n    row += 1\n    last_row, _ = view.rowcol(view.size())\n    while row <= last_row:  # Don't go past end of document.\n        line = view.text_point(row, 0)\n        line = view.line(line)\n        content = view.substr(line)\n        # print content\n        if len(content.strip()):\n            cur_indent = get_indent(view, content)\n            if len(cur_indent) <= len(parent_indent):\n                break  # Indent same as parent found!\n            if len(cur_indent) == len(child_indent):\n                siblings.append((line, content))\n        row += 1\n    return siblings\n\ndef get_summary(view, line):\n    row, _ = view.rowcol(line.begin())\n    content = view.substr(line)\n    match = summary_regex.search(content)\n    if not match:\n        return None\n    col_start, col_stop = match.span()\n    return sublime.Region(\n        view.text_point(row, col_start),\n        view.text_point(row, col_stop),\n    )\n\ndef get_checkbox(view, line):\n    row, _ = view.rowcol(line.begin())\n    content = view.substr(line)\n    # print content\n    match = checkbox_regex.search(content)\n    if not match:\n        return None\n    # checkbox = match.group(1)\n    # print repr(checkbox)\n    # print dir(match), match.start(), match.span()\n    col_start, col_stop = match.span()\n    return sublime.Region(\n        view.text_point(row, col_start),\n        view.text_point(row, col_stop),\n    )\n\ndef get_check_state(view, line):\n    if '[-]' in view.substr(line):\n        return CheckState.Indeterminate\n    if '[ ]' in view.substr(line):\n        return CheckState.Unchecked \n    if '[X]' in view.substr(line) or '[x]' in view.substr(line):\n        return CheckState.Checked\n    return CheckState.Error\n\ndef get_check_char(view, check_state):\n    if check_state == CheckState.Unchecked:\n        return ' '\n    elif check_state == CheckState.Checked:\n        return 'x'\n    elif check_state == CheckState.Indeterminate:\n        return '-'\n    else:\n        return 'E'\n\ndef recalc_summary(view, region):\n    recursive = sets.Get(\"checkboxSummaryRecursive\",False)\n    at = db.Get().AtInView(view)\n    if(at):\n        props = at.properties\n        if(props and 'COOKIE_DATA' in props):\n            cook = props['COOKIE_DATA']\n            if(cook and 'notrecursive' in cook):\n                recursive = False\n            elif(cook and 'recursive' in cook):\n                recursive = True\n    children = None\n    children = find_children(view, region, checkbox_regex, False, recursive)\n    if not len(children) > 0:\n        return (0, 0)\n    num_children = len(children)\n    checked_children = len(\n        [child for child in children if (get_check_state(view,child) == CheckState.Checked)])\n    # print ('checked_children: ' + str(checked_children) + ', num_children: ' + str(num_children))\n    return (num_children, checked_children)\n\ndef update_line(view, edit, region, parent_update=True, children_update=False):\n    #print ('update_line', self.view.rowcol(region.begin())[0]+1)\n    (num_children, checked_children) = recalc_summary(view, region)\n    # No children we don't have to update anything else.\n    if num_children <= 0:\n        return False\n    # update region checkbox\n    if checked_children == num_children:\n        newstate = CheckState.Checked\n    else:\n        if checked_children != 0:\n            newstate = CheckState.Indeterminate\n        else:\n            newstate = CheckState.Unchecked\n    toggle_checkbox(view, edit, region, newstate)\n    # update region summary\n    update_summary(view, edit, region, checked_children, num_children)\n    if children_update:\n        children = find_children(view, region)\n        for child in children:\n            line = view.line(child)\n            summary = get_summary(view, view.line(child))\n            if summary:\n                return update_line(view, edit, line, parent_update=False, children_update=True)\n    if parent_update:\n        parent = find_parent(view, region)\n        if parent:\n            update_line(view, edit, parent)\n        else:\n            # ok, no parent, but may be there is heading with summary?\n            heading = find_heading(view, region)\n            if heading and get_summary(view, heading):\n                update_line(view, edit, heading, parent_update=False)\n    return True\n\ndef update_summary(view, edit, region, checked_children, num_children):\n    # print('update_summary', self.view.rowcol(region.begin())[0]+1)\n    summary = get_summary(view, region)\n    if not summary:\n        return False\n    # print('checked_children: ' + str(checked_children) + ', num_children: ' + str(num_children))\n    line = view.substr(summary)\n    if(\"%\" in line):\n        view.replace(edit, summary, '[{0}%]'.format(int(checked_children/num_children*100)))\n    else:\n        view.replace(edit, summary, '[%d/%d]' % (checked_children, num_children))\n\ndef toggle_checkbox(view, edit, region, checked=None, recurse_up=False, recurse_down=False):\n    # print 'toggle_checkbox', self.view.rowcol(region.begin())[0]+1\n    checkbox = get_checkbox(view, region)\n    if not checkbox:\n        return False\n    if checked is None:\n        check_state = get_check_state(view, region)\n        if (check_state == CheckState.Unchecked) | (check_state == CheckState.Indeterminate):\n            check_state = CheckState.Checked\n        elif (check_state == CheckState.Checked):\n            check_state = CheckState.Unchecked\n    else:\n        check_state = checked\n    view.replace(edit, checkbox, '[%s]' % ( get_check_char(view, check_state)))\n    if recurse_down:\n        # all children should follow\n        children = find_children(view, region)\n        for child in children:\n            toggle_checkbox(view, edit, child, check_state, recurse_down=True)\n            if (get_summary(view, child)):\n                update_line(view, edit, child, parent_update=False)\n\n    if get_summary(view, region):\n        (num_children, checked_children) = recalc_summary(view, region)\n        update_summary(view, edit, region, checked_children, num_children)\n\n    if recurse_up:\n        # update parent\n        parent = find_parent(view, region)\n        if parent:\n            update_line(view, edit, parent)\n        else:\n            # ok, no parent, but may be there is heading with summary?\n            heading = find_heading(view, region)\n            if heading and get_summary(view, heading):\n                update_line(view, edit, heading, parent_update=False)\n\ndef is_checkbox(view, sel):\n    names = view.scope_name(sel.end())\n    return 'orgmode.checkbox' in names or 'orgmode.checkbox.checked' in names or 'orgmode.checkbox.blocked' in names\n\ndef is_checkbox_line(view,sel=None):\n    point = None\n    if(sel == None):\n        row = view.curRow()\n        point = view.text_point(row, 0)\n    else:\n        point = sel.end()\n    line = view.line(point)\n    content = view.substr(line)\n    return checkbox_line_regex.search(content)\n\ndef find_all_summaries(view):\n    return view.find_by_selector(\"orgmode.checkbox.summary\")\n\ndef recalculate_checkbox_summary(view, sel, edit):\n    line    = view.line(sel.begin())\n    update_line(view, edit, line)\n\ndef recalculate_all_checkbox_summaries(view, edit):\n    sums = find_all_summaries(view)\n    for sel in sums:\n        recalculate_checkbox_summary(view, sel, edit)\n\ncline_info_regex = re.compile(r'^(\\s*)([-+0-9](\\.)?)?.*$')\nclass OrgInsertCheckboxCommand(sublime_plugin.TextCommand):\n    def run(self, edit,insertHere=True):\n        row = self.view.curRow()\n        line = self.view.getLine(row)\n        match = cline_info_regex.match(line)\n        indent = match.group(1)\n        start  = match.group(2)\n        if(start):\n            indent = indent + start + \" [ ] \"\n        reg = self.view.curLine()\n        list_regex   = re.compile(r'\\s*(([-+]\\s\\[)|[^#*|+-])')\n        children = find_children(self.view, reg, list_regex, not insertHere)\n        if(children and len(children) > 0):\n            reg = children[len(children) - 1]\n            row,_ =self.view.rowcol(reg.begin())\n        self.view.insert(edit,reg.end(),\"\\n\" + indent)\n        # Move to end of line\n        row = row + 1\n        pt = self.view.text_point(row,0)\n        ln = self.view.line(pt)\n        self.view.sel().clear()\n        self.view.sel().add(ln.end())\n\n\nuline_info_regex = re.compile(r'^(\\s*)([-+]) .*$')\ndef isUnorderedList(line):\n    return uline_info_regex.match(line)\n\n\nRE_THING = re.compile(r'^\\s*[+-](\\s\\[[ xX-]\\])?\\s(?P<data>.*)$')\nRE_NOTHEADERS = re.compile(r'^\\s*[\\#|0-9]')\n\n\ndef getListAtPointForSorting(view):\n    parent = view.findParentByIndent(view.curLine(),RE_NOTHEADERS, RE_THING)\n    if(None != parent):\n        prow, _ = view.rowcol(parent.begin())\n        list_regex   = re.compile(r'\\s*(([-+]\\s\\[)|[^#*|+-])')\n        children = find_children(view, parent, list_regex, True)\n        sortby = view.getLine(prow)\n        m = RE_THING.search(sortby)\n        if(m):\n            sortby = m.group('data')\n        things = [[[prow,0],sortby]]\n        for c in children:\n            srow, _ = view.rowcol(c.begin())\n            if(len(things) > 0):\n                things[len(things)-1][0][1] = srow \n            sortby = view.getLine(srow)\n            m = RE_THING.search(sortby)\n            if(m):\n                sortby = m.group('data')\n            things.append([[srow,0],sortby])\n        if(len(things) > 0):\n            srow, _ = view.rowcol(children[len(children)-1].end())\n            things[len(things)-1][0][1] = srow+1\n        return things\n    return None\n \ndef getListAtPoint(view,pt=None):\n    if(pt):\n        line = view.line(pt)\n    else:\n        line = view.curLine()\n    parent = view.findParentByIndent(line,RE_NOTHEADERS, RE_THING)\n    if(None != parent):\n        prow, _ = view.rowcol(parent.begin())\n        list_regex   = re.compile(r'\\s*(([-+]\\s\\[)|[^#*|+-])')\n        children = find_children(view, parent, list_regex, True)\n        sortby = view.getLine(prow)\n        m = RE_THING.search(sortby)\n        if(m):\n            sortby = m.group('data')\n        things = []\n        lastAppend = False\n        for c in children:\n            srow, _ = view.rowcol(c.begin())\n            if(lastAppend and len(things) > 0):\n                things[len(things)-1][0][1] = srow \n            lastAppend = False\n            sortby = view.getLine(srow)\n            m = RE_THING.search(sortby)\n            if(m):\n                sortby = m.group('data')\n                things.append([[srow,0],sortby])\n                lastAppend = True\n        if(len(things) > 0):\n            srow, _ = view.rowcol(children[len(children)-1].end())\n            things[len(things)-1][0][1] = srow+1\n        return things\n    return None\n\nclass OrgInsertUnorderedListCommand(sublime_plugin.TextCommand):\n    def run(self, edit,insertHere=True):\n        row = self.view.curRow()\n        line = self.view.getLine(row)\n        match = uline_info_regex.match(line)\n        indent = match.group(1)\n        start  = match.group(2)\n        if(start):\n            indent = indent + start + \" \"\n        reg = self.view.curLine()\n        list_regex   = re.compile(r'\\s*([-+]|[^#*|])')\n        children = find_children(self.view, reg, list_regex, not insertHere)\n        if(children and len(children) > 0):\n            reg = children[len(children) - 1]\n            row,_ =self.view.rowcol(reg.begin())\n        self.view.insert(edit,reg.end(),\"\\n\" + indent)\n        # Move to end of line\n        row = row + 1\n        pt = self.view.text_point(row,0)\n        ln = self.view.line(pt)\n        self.view.sel().clear()\n        self.view.sel().add(ln.end())\n\ncbsline_info_regex = re.compile(r'^(\\s*)(.*)\\[\\s*[0-9]*/[0-9]\\s*\\]\\s*$')\nclass OrgInsertCheckboxSummaryCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        row = self.view.curRow()\n        line = self.view.getLine(row)\n        match = cbsline_info_regex.match(line)\n        if(not match):\n            reg = self.view.curLine()\n            self.view.insert(edit,reg.end(),\" [/] \")\n            recalculate_all_checkbox_summaries(self.view, edit)\n\nclass OrgToggleCheckboxCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        view = self.view\n        for sel in view.sel():\n            if(not is_checkbox_line(view, sel)):\n                continue\n            line     = view.line(sel.end())\n            toggle_checkbox(view, edit, line, recurse_up=True, recurse_down=True)\n\n\nclass OrgRecalcCheckboxSummaryCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        view = self.view\n        backup = []\n        for sel in view.sel():\n            if 'orgmode.checkbox.summary' not in view.scope_name(sel.end()):\n                continue\n            backup.append(sel)\n            #summary = view.extract_scope(sel.end())\n            line = view.line(sel.end())\n            update_line(view, edit, line)\n        view.sel().clear()\n        for region in backup:\n            view.sel().add(region)\n\n\nclass OrgRecalcAllCheckboxSummariesCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        recalculate_all_checkbox_summaries(self.view, edit)\n"
  },
  {
    "path": "orgclocking.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport os\n# from OrgExtended.orgparse.sublimenode import *\nimport logging\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgproperties as props\nfrom OrgExtended.orgparse.node import *\nimport copy\nimport yaml\nimport OrgExtended.pymitter as evt\n\nlog = logging.getLogger(__name__)\n\n\nclass ClockManager:\n    Clock = None\n\n    @staticmethod\n    def ClockInRecord(file, onode, dt):\n        # parentHeading = \"\"\n        # if (onode.parent and type(onode.parent) != node.OrgRootNode):\n        #     parentHeading = onode.parent.heading\n        ClockManager.Clock = {\n            'file': file.filename,\n            'start': dt,\n            'heading': onode.get_locator()\n        }\n        ClockManager.SaveClock()\n\n    @staticmethod\n    def ClockRunning():\n        return ClockManager.Clock is not None\n\n    @staticmethod\n    def FormatClock(now):\n        return now.strftime(\"[%Y-%m-%d %a %H:%M]\")\n\n    @staticmethod\n    def FormatDuration(d):\n        hours = d.seconds / 3600\n        minutes = (d.seconds / 60) % 60\n        return \"{0:02d}:{1:02d}\".format(int(hours), int(minutes))\n\n    @staticmethod\n    def ClockPath():\n        return os.path.join(sublime.packages_path(), \"User\", \"OrgExtended_Clocks.yaml\")\n\n    @staticmethod\n    def SaveClock():\n        f = open(ClockManager.ClockPath(), \"w\")\n        yaml.dump(ClockManager.Clock, f)\n        f.close()\n\n    @staticmethod\n    def LoadClock():\n        cpath = ClockManager.ClockPath()\n        if (os.path.isfile(cpath)):\n            stream = open(cpath, 'r')\n            res = yaml.load(stream, Loader=yaml.SafeLoader)\n            if res is not None and isinstance(res, dict):\n                ClockManager.Clock = res\n            else:\n                ClockManager.Clock = None\n            stream.close()\n\n    @staticmethod\n    def ClockIn(view):\n        if (ClockManager.ClockRunning()):\n            view.set_status(\"Clock\", \"CLOCK\")\n            ClockManager.ClockOut(view)\n        # Handle clock already running\n        node = db.Get().AtInView(view)\n        if (node):\n            file = db.Get().FindInfo(view)\n            if (file):\n                dt = datetime.datetime.now()\n                ClockManager.ClockInRecord(file, node, dt)\n                if (sets.Get(\"clockInPropertyBlock\", False)):\n                    props.AddProperty(view, node, \"CLOCK\", ClockManager.FormatClock(dt) + \"--\")\n                else:\n                    props.AddLogbook(view, node, \"CLOCK:\", ClockManager.FormatClock(dt) + \"--\")\n\n    @staticmethod\n    def UpdateClockStart(view):\n        if (not ClockManager.ClockRunning()):\n            log.error(\"Clock not running, nothing to update\")\n            return\n        # Eventually we want to navigate to this node\n        # rather than doing this.\n        if ClockManager.Clock is not None:\n            node = db.Get().FindNode(ClockManager.Clock[\"file\"], ClockManager.Clock[\"heading\"])\n            newStart = None\n            if (node):\n                tview = view.window().open_file(ClockManager.Clock[\"file\"], sublime.ENCODED_POSITION)\n                if (sets.Get(\"clockInPropertyBlock\", False)):\n                    val = props.GetProperty(tview, node, \"CLOCK\")\n                else:\n                    val = props.GetLogbook(tview, node, r\"CLOCK:\")\n                if val:\n                    clock = OrgDateClock.from_str(val)\n                    if clock:\n                        newStart = clock.start\n            if newStart:\n                file = db.Get().FindInfo(ClockManager.Clock[\"file\"])\n                ClockManager.ClockInRecord(file, node, newStart)\n\n    @staticmethod\n    def ClockOut(view):\n        if (not ClockManager.ClockRunning()):\n            return\n        # Eventually we want to navigate to this node\n        # rather than doing this.\n        if ClockManager.Clock is not None:\n            node = db.Get().FindNode(ClockManager.Clock[\"file\"], ClockManager.Clock[\"heading\"])\n            if (node):\n                end = datetime.datetime.now()\n                start = ClockManager.Clock[\"start\"]\n                duration = end - start\n                # Should we keep clocking entries less than a minute?\n                shouldKeep = sets.Get(\"clockingSubMinuteClocks\", True)\n                tview = view.window().open_file(ClockManager.Clock[\"file\"], sublime.ENCODED_POSITION)\n                if (not shouldKeep and duration.seconds < 60):\n                    if (sets.Get(\"clockInPropertyBlock\", False)):\n                        props.RemoveProperty(tview, node, \"CLOCK\")\n                    else:\n                        props.RemoveLogbook(tview, node, r\"CLOCK:\")\n                else:\n                    if (sets.Get(\"clockInPropertyBlock\", False)):\n                        props.UpdateProperty(tview, node, \"CLOCK\", ClockManager.FormatClock(start) + \"--\" + ClockManager.FormatClock(end) + \" => \" + ClockManager.FormatDuration(duration))\n                    else:\n                        props.UpdateLogbook(tview, node, \"CLOCK:\", ClockManager.FormatClock(start) + \"--\" + ClockManager.FormatClock(end) + \" => \" + ClockManager.FormatDuration(duration))\n                view.window().focus_view(view)\n                tview.run_command(\"save\")\n                ClockManager.ClearClock()\n                view.run_command(\"save\")\n        else:\n            log.error(\"Failed to clock out, couldn't find node\")\n\n    @staticmethod\n    def ClearClock():\n        ClockManager.Clock = None\n        cpath = ClockManager.ClockPath()\n        if (os.path.isfile(cpath)):\n            os.remove(cpath)\n\n    @staticmethod\n    def GetActiveClockFile():\n        if (not ClockManager.ClockRunning()):\n            return None\n        return ClockManager.Clock[\"file\"] if ClockManager.Clock is not None else None\n\n    @staticmethod\n    def GetActiveClockAt():\n        if (not ClockManager.ClockRunning()):\n            return None\n        if ClockManager.Clock is not None:\n            node = db.Get().FindNode(ClockManager.Clock[\"file\"], ClockManager.Clock[\"heading\"])\n            if (node):\n                return node.start_row\n\n\n# Load the clock cache.\ndef Load():\n    ClockManager.LoadClock()\n\n# Clock in a task\n\n\nclass OrgClockInCommand(sublime_plugin.TextCommand):\n    def run(self, edit, onDone=None):\n        ClockManager.LoadClock()\n        ClockManager.ClockIn(self.view)\n        evt.EmitIf(onDone)\n\n# Clock out a task\n\n\nclass OrgClockOutCommand(sublime_plugin.TextCommand):\n    def run(self, edit, onDone=None):\n        ClockManager.LoadClock()\n        ClockManager.ClockOut(self.view)\n        evt.EmitIf(onDone)\n\n# Jump to an active clock\n\n\nclass OrgJumpToClockCommand(sublime_plugin.TextCommand):\n    def run(self, edit, onDone=None):\n        ClockManager.LoadClock()\n        at = ClockManager.GetActiveClockAt()\n        filename = ClockManager.GetActiveClockFile()\n        if at and filename:\n            path = \"{0}:{1}\".format(filename, at + 1)\n            self.view.window().open_file(path, sublime.ENCODED_POSITION)\n        else:\n            print(\"No active clock\")\n        evt.EmitIf(onDone)\n\n# Clear the currently running clock (if there is one)\n\n\nclass OrgClearClockCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        ClockManager.ClearClock()\n\n# Update the currently running command based on an open clock manual update\n\n\nclass OrgUpdateClockCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        ClockManager.UpdateClockStart(self.view)\n\n# Recalculate all the clock values in a node (Crtl-c Ctrl-c on a clock entry)\n\n\nclass OrgRecalculateClockCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        node = db.Get().AtInView(self.view)\n        clockList = copy.copy(node.clock)\n        log.debug(str(clockList))\n        log.debug(str(len(clockList)))\n        if (sets.Get(\"clockInPropertyBlock\", False)):\n            props.RemoveAllInstances(self.view, node, \"CLOCK\")\n        else:\n            props.RemoveAllLogbookInstances(self.view, node, r\"^\\s*CLOCK:\")\n        log.debug(str(clockList))\n        log.debug(str(len(clockList)))\n        for clock in clockList:\n            # File is reloaded have to regrab node\n            node = db.Get().At(self.view, node.start_row)\n            if (sets.Get(\"clockInPropertyBlock\", False)):\n                props.AddProperty(self.view, node, \"CLOCK\", clock.format_clock_str())\n            else:\n                props.AddLogbook(self.view, node, \"CLOCK:\", clock.format_clock_str())\n"
  },
  {
    "path": "orgdateeditor.sublime-settings",
    "content": "{\n\t// The color scheme to use for the datepicker buffer\n\t\"color_scheme\": \"Packages/OrgExtended/orgdatepicker.sublime-color-scheme\",\n\t//\"font_face\": \"Courier New\",\n\t//\"font_size\": 15\n}\n"
  },
  {
    "path": "orgdateeditor.sublime-syntax",
    "content": "%YAML1.2\n---\n# See http://www.sublimetext.com/docs/3/syntax.html\nname: orgdateeditor\nfile_extensions:\n  - orgdateeditor\nscope: source.orgdateeditor\nversion: 2\nhidden: true\ncontexts:\n  main:\n    # filename and line location\n    - match: '(Mon|Tue|Wed|Thu|Fri)'\n      scope: orgdatepicker.weekdayheader\n\n    - match: '(Sat|Sun)'\n      scope: orgdatepicker.weekendheader\n\n    - match: '(January|February|March|April|May|June|July|August|September|October|November|December)\\s*([0-9]+)'\n      scope: orgdatepicker.monthheader\n\n    - match: '[0-9][0-9]:[0-9][0-9]'\n      scope: orgdatepicker.time\n"
  },
  {
    "path": "orgdatepicker.py",
    "content": "import calendar\nimport sublime\nimport sublime_plugin\nimport datetime\nfrom OrgExtended.orgparse.date import *\nimport OrgExtended.pymitter as evt\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgutil.asciiclock as aclock\nimport OrgExtended.orgduration as orgduration\n\ntodayHighlight=\"orgagenda.block.1\"\n\ndef CreateUniqueViewNamed(name, mapped=None):\n\t# Close the view if it exists\n\twin = sublime.active_window()\n\tfor view in win.views():\n\t\tif view.name() == name:\n\t\t\twin.focus_view(view)\n\t\t\twin.run_command('close')\n\twin.run_command('new_file')\n\tview = win.active_view()\n\tview.set_name(name)\n\t# TODO: Change this.\n\tview.set_syntax_file(\"Packages/OrgExtended/orgdatepicker.sublime-syntax\")\n\t#ViewMappings[view.name()] = mapped\n\treturn view\n\nclass DateView:\n\tdef __init__(self, dayhighlight=None,firstDayIndex=0, timeView=False):\n\t\tself.months = []\n\t\tself.columnsPerMonth = 30                     # 7 * 3 = 21 + 9\n\t\tself.columnsInDay    = 2  \n\t\tself.columnsPerDay   = self.columnsInDay + 1  # 2 digits plus a space\n\t\tself.midmonth        = datetime.datetime.now().month \n\t\tself.monthdata       = None\n\t\tself.headingLines    = 2\n\t\tself.output          = None\n\t\tself.cdate           = OrgDateFreeFloating(datetime.datetime.now())\n\t\tself.startrow        = 0\n\t\tself.endrow          = 7\n\t\tself.dayhighlight    = dayhighlight\n\t\tself.firstdayindex   = firstDayIndex\n\t\tself.timeView        = timeView\n\n\n\n\tdef SetView(self, view):\n\t\tself.output = view\n\n\n\tdef SetStartRow(self, row):\n\t\tself.startrow = row\n\n\n\tdef DateToRegion(self, date):\n\t\t# Convert \n\t\tmonthIndex = (date.month - (self.midmonth) + 1) % 12\n\t\tif(monthIndex < 0 or monthIndex >= len(self.monthdata)):\n\t\t\treturn\n\t\tmonthData = self.monthdata[monthIndex]\n\t\tweekIndex = 0\n\t\tdayIndex  = 0\n\t\tfor weekId in range(0,len(monthData)):\n\t\t\tweekData = monthData[weekId]\n\t\t\tfor dayId in range(0,len(weekData)):\n\t\t\t\tday = weekData[dayId]\n\t\t\t\tif(day == date.day):\n\t\t\t\t\tweekIndex = weekId\n\t\t\t\t\tdayIndex  = dayId\n\t\t# 2 row heading?\n\t\t# We should have an offset? Probably\n\t\trow = self.headingLines + weekIndex\n\t\tcol = monthIndex * self.columnsPerMonth + dayIndex*self.columnsPerDay\n\t\t#print(\"ROW: \" + str(row) + \" COL: \" + str(col))\n\t\ts = self.output.text_point(row,col)\n\t\te = self.output.text_point(row,col+2)\n\t\treturn sublime.Region(s, e)\n\n\tdef HighlightDay(self, date):\n\t\treg = self.DateToRegion(date)\n\t\tstyle = self.dayhighlight\n\t\tif(style == None):\n\t\t\tstyle = \"orgdatepicker.monthheader\"\n\t\tself.output.add_regions(\"cur\",[reg],style,\"\",sublime.DRAW_NO_OUTLINE)\t\n\n\tdef AddToDayHighlights(self, date, key, highlight, drawtype = sublime.DRAW_NO_OUTLINE):\n\t\treg = self.DateToRegion(date)\n\t\tif(not reg):\n\t\t\t#print(\"NO REGION FOR DATE: \" + str(date))\n\t\t\treturn\n\t\tregs = self.output.get_regions(key)\n\t\tif not regs:\n\t\t\tregs = []\n\t\tregs.append(reg)\n\t\tself.output.add_regions(key,regs,highlight,\"\",drawtype)\t\n\n\tdef ClearDayHighlights(self,key):\n\t\tself.output.erase_regions(key)\n\n\tdef MapRowColToDate(self,row,col):\n\t\tweekid   = int(row - self.headingLines)\n\t\tmonthid  = int(col / self.columnsPerMonth)\n\t\tdayid    = int((col % self.columnsPerMonth) / self.columnsPerDay)\n\t\tday      = self.monthdata[monthid][weekid][dayid]\n\t\tmonth    = monthid + self.midmonth - 1\n\t\tyear     = self.cdate.start.year\n\t\ttime     = self.cdate.start.time()\n\t\tduration = None\n\t\tif(time):\n\t\t\tresult = datetime.datetime(year, month, day, time.hour, time.minute, time.second, time.microsecond)\n\t\telse:\n\t\t\tresult = datetime.datetime(year, month, day)\n\t\treturn result\n\n\tdef MoveCDateToDate(self, now):\n\t\tself.cdate           = OrgDateFreeFloating(now)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToNextDay(self):\n\t\tself.cdate.add_days(1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToPrevDay(self):\n\t\tself.cdate.add_days(-1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToNextWeek(self):\n\t\tself.cdate.add_days(7)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToPrevWeek(self):\n\t\tself.cdate.add_days(-7)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToNextMonth(self):\n\t\tself.cdate.add_months(1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToPrevMonth(self):\n\t\tself.cdate.add_months(-1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToNextHour(self):\n\t\tself.cdate.add_hours(1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToPrevHour(self):\n\t\tself.cdate.add_hours(-1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\t\n\tdef MoveCDateToNextMinute(self):\n\t\tself.cdate.add_minutes(1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToPrevMinute(self):\n\t\tself.cdate.add_minutes(-1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef ReShow(self):\n\t\tif(self.cdate == None):\n\t\t\treturn\n\t\tnow = self.cdate.start\n\t\tif(now == None):\n\t\t\treturn\n\t\tmid = (now.month - self.midmonth + 1)\n\t\tif(mid < 0 or mid > 2 or self.timeView):\n\t\t\tself.Render(now)\n\t\t\tself.ResetRenderState()\n\t\t\tself.ClearDayHighlights(\"today\")\n\t\t\tself.AddToDayHighlights(datetime.datetime.now(), \"today\",todayHighlight, sublime.DRAW_NO_FILL)\n\n\t@staticmethod\n\tdef NextMonth(now):\n\t\tmonth = now.month + 1\n\t\tyear  = now.year\n\t\tif(month > 12):\n\t\t\tyear += 1\n\t\t\tmonth = 1\n\t\treturn (month, year)\n\n\t@staticmethod\n\tdef PrevMonth(now):\n\t\tmonth = now.month - 1\n\t\tyear  = now.year\n\t\tif(month <= 0):\n\t\t\tyear -= 1\n\t\t\tmonth = 12\n\t\treturn (month, year)\n\n\tdef Render(self,now):\n\t\tdays = [calendar.MONDAY, calendar.TUESDAY, calendar.WEDNESDAY, calendar.THURSDAY, calendar.FRIDAY, calendar.SATURDAY, calendar.SUNDAY]\n\t\tfirstDay = days[self.firstdayindex]\n\t\tc = calendar.TextCalendar(firstDay)\n\t\tstr = c.formatmonth(now.year, now.month)\n\t\tcalendar.setfirstweekday(firstDay)\n\t\tself.midmonth  = now.month\n\t\tpmonth, pyear = DateView.PrevMonth(now)\n\t\tnmonth, nyear = DateView.NextMonth(now)\n\t\tself.monthdata = [ calendar.monthcalendar(pyear, pmonth),\n\t\t\t\t\t\t   calendar.monthcalendar(now.year, now.month),\n\t\t\t\t\t\t   calendar.monthcalendar(nyear, nmonth)]\n\t\t#print(str)\n\t\tm2 = str.split('\\n')\n\t\tmonth, year = DateView.NextMonth(now)\n\t\tstr = c.formatmonth(year, month)\n\t\t#print(str)\n\t\tm3 = str.split('\\n')\n\t\tmonth, year = DateView.PrevMonth(now)\n\t\tstr = c.formatmonth(year, month)\n\t\t#print(str)\n\t\tm1 = str.split('\\n')\n\n\t\tself.output.set_read_only(False)\n\t\tself.output.sel().clear()\n\t\tpt = self.output.text_point(self.startrow,0)\n\t\tself.output.sel().add(pt)\n\t\tl = max(len(m1),len(m2),len(m3))\n\t\tself.endrow = self.startrow + l\n\t\trow = self.startrow\n\t\tclock = None\n\t\tendrange = l\n\t\tif(self.timeView):\n\t\t\tclock = aclock.draw_clock(now,30,26)\n\t\t\tendrange = 25\n\t\tfor i in range(0,endrange):\n\t\t\tline = \"{0:90}\".format(\" \")\n\t\t\tpt = self.output.text_point(row,0)\n\t\t\trow += 1\n\t\t\tif(i < l):\n\t\t\t\tml1 = m1[i] if i < len(m1) else \"\"\n\t\t\t\tml2 = m2[i] if i < len(m2) else \"\"\n\t\t\t\tml3 = m3[i] if i < len(m3) else \"\"\n\t\t\t\tline = \"{0:30}{1:30}{2:30}\".format(ml1,ml2,ml3)\n\t\t\tif(clock and self.timeView):\n\t\t\t\tline += clock.get_row(i+2)\t\n\t\t\tlreg = self.output.line(pt)\n\t\t\tlreg = sublime.Region(lreg.begin(), lreg.end() + 1)\n\t\t\tself.output.ReplaceRegion(lreg, line + \"\\n\")\n\t\t\t#print(line)\n\n\n\t\tself.HighlightDay(now)\n\n\tdef ResetRenderState(self):\n\t\tself.output.set_read_only(True)\n\t\tself.output.set_scratch(True)\n\t\tif not self.output.name():\n\t\t\tself.output.set_name(\"DatePicker\")\n\n\nclass DatePicker:\n\tdef __init__(self,firstDayIndex=0):\n\t\tself.dateView = DateView(None, firstDayIndex, True)\n\t\tself.months = []\n\n\tdef on_done(self, text):\n\t\tself.dateView.output.close()\n\t\tif(self.onDone):\n\t\t\tevt.Get().emit(self.onDone, self.dateView.cdate)\n\n\tdef on_canceled(self):\n\t\tself.dateView.output.close()\n\t\tif(self.onDone):\n\t\t\tevt.Get().emit(self.onDone, None)\n\n\tdef on_changed(self, text):\n\t\t#print(\"CHANGED: \" + text)\n\t\tduration = orgduration.OrgDuration.Parse(text,True)\n\t\tif(not duration):\n\t\t\tduration = orgduration.OrgDuration.ParseWeekDayOffset(text)\n\t\tif(not duration):\n\t\t\tduration = orgduration.OrgDuration.ParseMonthOffset(text)\n\t\t# We allow duration syntax 3h\n\t\tif(text == \".\" or text == \"+0\"):\n\t\t\tnow = datetime.datetime.now()\n\t\t\tself.dateView.cdate = OrgDateFreeFloating(now)\n\t\telif(text.isnumeric()):\n\t\t\t# We assume this is a day of the month (this month or next)\n\t\t\tnow = datetime.datetime.now()\n\t\t\tcday = int(text)\n\t\t\tif(cday > now.day):\n\t\t\t\tnow = now.replace(day=cday)\n\t\t\telse:\n\t\t\t\tnow = now.replace(month=now.month+1,day=cday)\n\t\t\tself.dateView.cdate = OrgDateFreeFloating(now)\n\t\telif(duration):\n\t\t\tnow = OrgDateFreeFloating(datetime.datetime.now())\n\t\t\tself.dateView.cdate = now + duration\n\t\telse:\n\t\t\tself.dateView.cdate = OrgDateFreeFloating.from_str(text)\n\t\tself.dateView.ReShow()\n\t\tif(self.dateView.cdate):\n\t\t\tself.dateView.HighlightDay(self.dateView.cdate.start)\n\n\tdef MapRowColToNewDate(self,row,col):\n\t\ttime     = self.dateView.cdate.start.time()\n\t\tduration = None\n\t\tif(self.dateView.cdate.has_end()):\n\t\t\tduration = self.dateView.cdate.end - self.dateView.cdate.start\n\t\tself.dateView.cdate._start = self.dateView.MapRowColToDate(row,col)\n\t\tif(duration):\n\t\t\tself.dateView.cdate._end = self.dateView.cdate.start + duration\n\t\tself.inputpane.ReplaceRegion(self.inputpane.line(self.inputpane.text_point(0,0)), OrgDate.format_datetime(self.dateView.cdate.start))\n\t\tself.dateView.HighlightDay(self.dateView.cdate.start)\n\n\tdef RefreshInputPanelFromDateView(self):\n\t\tself.inputpane.ReplaceRegion(self.inputpane.line(self.inputpane.text_point(0,0)), OrgDate.format_datetime(self.dateView.cdate.start))\n\n\tdef MoveNextDay(self):\n\t\tself.dateView.MoveCDateToNextDay()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MovePrevDay(self):\n\t\tself.dateView.MoveCDateToPrevDay()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MoveNextWeek(self):\n\t\tself.dateView.MoveCDateToNextWeek()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MovePrevWeek(self):\n\t\tself.dateView.MoveCDateToPrevWeek()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MoveNextMonth(self):\n\t\tself.dateView.MoveCDateToNextMonth()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MovePrevMonth(self):\n\t\tself.dateView.MoveCDateToPrevMonth()\n\t\tself.RefreshInputPanelFromDateView()\n\t\n\tdef MoveNextHour(self):\n\t\tself.dateView.MoveCDateToNextHour()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MovePrevHour(self):\n\t\tself.dateView.MoveCDateToPrevHour()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MoveNextMinute(self):\n\t\tself.dateView.MoveCDateToNextMinute()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MovePrevMinute(self):\n\t\tself.dateView.MoveCDateToPrevMinute()\n\t\tself.RefreshInputPanelFromDateView()\n\n\n\tdef Show(self,now, onDone):\n\t\tself.onDone\t= onDone\n\t\twindow      = sublime.active_window()\n\t\tself.output = CreateUniqueViewNamed(\"DatePicker\")\n\t\tself.dateView.SetView(self.output)\n\t\tself.dateView.Render(now)\n\t\tself.dateView.ResetRenderState()\n\t\tcurstr = OrgDate.format_datetime(now)\n\t\tself.cdate = OrgDateFreeFloating.from_str(curstr)\n\t\tself.inputpane = window.show_input_panel(\n\t\t\t\t\t\"Date:\",\n\t\t\t\t\tcurstr,\n\t\t\t\t\tself.on_done,\n\t\t\t\t\tself.on_changed,\n\t\t\t\t\tself.on_canceled)\n\t\tpt = self.inputpane.text_point(0,0)\n\t\tself.inputpane.set_syntax_file(\"Packages/OrgExtended/orgdateeditor.sublime-syntax\")\n\n# =============================================================\ndatePicker = None\n\ndef is_pt_date_view(view, pt):\n    return 'source.orgdatepicker' in view.scope_name(pt)\n\ndef onMouse(pt, view, edit):\n    if(not is_pt_date_view(view, pt)):\n    \treturn\n    row, col = view.rowcol(pt)\n    if(datePicker):\n    \tdatePicker.MapRowColToNewDate(row,col)\n    # TODO Convert point back to a date and push that into\n    #      the input box.\n\ndef SetupMouse():\n\tevt.Get().on(\"orgmouse\",onMouse)\n\n\nclass OrgDatePickerCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker = DatePicker()\n\t\tdatePicker.Show(datetime.datetime.now(),None)\n\nclass OrgDatePickerNextDayCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MoveNextDay()\n\nclass OrgDatePickerPrevDayCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MovePrevDay()\n\nclass OrgDatePickerPrevWeekCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MovePrevWeek()\n\nclass OrgDatePickerNextWeekCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MoveNextWeek()\n\nclass OrgDatePickerPrevMonthCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MovePrevMonth()\n\nclass OrgDatePickerNextMonthCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MoveNextMonth()\n\nclass OrgDatePickerNextHourCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MoveNextHour()\n\nclass OrgDatePickerPrevHourCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MovePrevHour()\n\nclass OrgDatePickerNextMinuteCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MoveNextMinute()\n\nclass OrgDatePickerPrevMinuteCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MovePrevMinute()\n\ndef Pick(onDone):\n\tglobal datePicker\n\tfirstDayIndex = sets.GetWeekdayIndexByName(sets.Get(\"firstDayOfWeek\",\"Sunday\"))\n\tdatePicker = DatePicker(firstDayIndex)\n\tdatePicker.Show(datetime.datetime.now(), onDone)"
  },
  {
    "path": "orgdatepicker.sublime-color-scheme",
    "content": "{\n\t\"name\": \"orgdatepicker\",\n\t\"variables\": {\n\t\t\"bgcol\": \"#272822\",\n\t\t// Define variables here\n\t},\n\t\"globals\": {\n\t\t\"foreground\": \"#F8F8F2\",\n\t\t\"background\": \"var(bgcol)\",\n\t\t\"accent\":     \"#ffffff\",\n\t\t\"selection\":  \"#9D550F\",\n\t    \"selectionBackground\": \"#000000\",\n\t    \"selectionForeground\": \"#FF0000\",\n\t    \"caret\":               \"#FF55ff\",\n\t    \"line_highlight\":      \"#373730\"\n\t},\n\t\"rules\": \n\t[\n\t\t{\n\t\t\t\"scope\": \"orgdatepicker.weekendheader\",\n\t\t\t\"foreground\": \"#5b96f5\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgdatepicker.weekdayheader\",\n\t\t\t\"foreground\": \"#0762a3\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgdatepicker.monthheader\",\n\t\t\t\"foreground\": \"#7e4794\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n\t\t{\n\t\t\t\"scope\": \"orgdatepicker.time\",\n\t\t\t\"foreground\": \"#aaaaaa\",\n\t\t\t\"font_style\": \"bold italic\",\n\t\t},\n    ]\n}\n"
  },
  {
    "path": "orgdatepicker.sublime-settings",
    "content": "{\n\t// The color scheme to use for the datepicker buffer\n\t\"color_scheme\": \"Packages/OrgExtended/orgdatepicker.sublime-color-scheme\",\n\t//\"font_face\": \"Courier New\",\n\t//\"font_size\": 15\n}"
  },
  {
    "path": "orgdatepicker.sublime-syntax",
    "content": "%YAML1.2\n---\n# See http://www.sublimetext.com/docs/3/syntax.html\nname: orgdatepicker\nfile_extensions:\n  - orgdatepicker\nscope: source.orgdatepicker\nversion: 2\nhidden: true\ncontexts:\n  main:\n    # filename and line location\n    - match: '(Mo|Tu|We|Th|Fr)'\n      scope: keyword orgdatepicker.weekdayheader\n\n    - match: '(Sa|Su)'\n      scope: constant.numeric orgdatepicker.weekendheader\n\n    - match: '(January|February|March|April|May|June|July|August|September|October|November|December)\\s*([0-9]+)'\n      scope: string.quoted orgdatepicker.monthheader\n\n    - match: '\\.|`'\n      scope: comment orgdatepicker.timetick\n\n    - match: 'O'\n      scope: orgagenda.block.1 orgdatepicker.hourhand\n    - match: 'o'\n      scope: orgagenda.block.2 orgdatepicker.minutehand\n"
  },
  {
    "path": "orgdaypage.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nimport os\nimport logging\nimport getpass\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orgextension as ext\nimport OrgExtended.orgparse.date as orgdate\nimport OrgExtended.orgdb as db\n\nlog = logging.getLogger(__name__)\n\n# I think I will model this feature after org-roam dailies.\n# olBc has not really gotten back to me on the subject and I think\n# dailies makes a lot of sense.\n\ndef dayPageGetToday():\n    dt     = datetime.datetime.now()\n    change = [\"monday\",\"tuesday\",\"wednesday\",\"thursday\",\"friday\",\"saturday\",\"sunday\"]\n    if(sets.Get(\"dayPageMode\",\"day\") == \"week\"):\n        firstDay = sets.Get(\"dayPageModeWeekDay\",\"Monday\").lower()\n        startAt = [idx for idx, element in enumerate(change) if element.startswith(firstDay)]\n        if(len(startAt) > 0):\n            startAt = startAt[0]\n        else:\n            startAt = 0\n        offset = (dt.weekday() - startAt)\n        if(offset != 0):\n            dt = dt - datetime.timedelta(days=offset)\n    return dt\n\ndef dayPageGetPath():\n    dpPath = sets.Get(\"dayPagePath\",None)\n    if(dpPath == None):\n        return None\n    try:\n        if isinstance(dpPath, list):\n            sublime.status_message(\"Day Page error. dayPagePath setting should be a string not a list! ABORT!\")\n            log.error(\" Cannot create day page without propper dayPathPath in configuration. Expected string, found list\")\n            return None\n        if isinstance(dpPath, str) and not dpPath.strip() == \"\":\n            os.makedirs(dpPath, exist_ok=True)\n    except Exception as e:\n        sublime.status_message(\"Day Page error. dayPagePath setting is not valid could not create daypage! ABORT!\")\n        log.error(\"Cannot create day page without propper dayPathPath in configuration: \\n\" + str(e))\n        return None\n    return dpPath\n\ndef dayPageGetDateString(dt):\n    formatStr = sets.Get(\"dayPageNameFormat\",\"%a_%Y_%m_%d\")\n    return dt.strftime(formatStr)\n\ndef dayPageFilenameToDateTime(view):\n    filename = view.file_name()\n    if(not filename):\n        return None\n    formatStr = sets.Get(\"dayPageNameFormat\",\"%a_%Y_%m_%d\")\n    filename = os.path.splitext(os.path.basename(filename))[0]\n    return datetime.datetime.strptime(filename,formatStr)\n\ndef dayPageGetName(dt):\n    path = dayPageGetPath()\n    if path == None:\n        return \"DAY_PAGE_NOT_SET.org\"\n    else:\n        return os.path.join(dayPageGetPath(),dayPageGetDateString(dt) + \".org\")\n\n\ndef OnLoaded(view,dt):\n    view.sel().clear()    \n    view.sel().add(0)\n    snippet  = sets.Get(\"dayPageSnippet\",\"dayPageSnippet\")\n    snipName = ext.find_extension_file('orgsnippets',snippet,'.sublime-snippet')\n    if(snipName == None):\n        log.error(\" Could not locate snippet file: \" + str(snippet) + \".sublime-snippet using default\")\n        snipName = ext.find_extension_file('orgsnippets','dayPageSnippet.sublime-snippet')\n    # NeoVintageous users probably prefern not to have to hit insert when editing things.\n    view.run_command('_enter_insert_mode', {\"count\": 1, \"mode\": \"mode_internal_normal\"})\n    now  = dt\n    inow = orgdate.OrgDate.format_date(now, False)\n    anow = orgdate.OrgDate.format_date(now, True)\n    ai = view.settings().get('auto_indent')\n    view.settings().set('auto_indent',False)\n    # \"Packages/OrgExtended/orgsnippets/\"+snippet+\".sublime-snippet\"\n    # OTHER VARIABLES:\n    # TM_FULLNAME - Users full name\n    # TM_FILENAME - File name of the file being edited\n    # TM_CURRENT_WORD - Word under cursor when snippet was triggered\n    # TM_SELECTED_TEXT - Selected text when snippet was triggered\n    # TM_CURRENT_LINE - Line of snippet when snippet was triggered\n    #insert_snippet {\"name\": \"Packages/OrgExtended/orgsnippets/page.sublime-snippet\"}\n    view.run_command(\"insert_snippet\",\n        { \"name\" : snipName\n        , \"ORG_INACTIVE_DATE\": inow\n        , \"ORG_ACTIVE_DATE\":   anow\n        , \"ORG_DATE\":          str(dt.date().today())\n        , \"ORG_TIME\":          dt.strftime(\"%H:%M:%S\")\n        , \"ORG_CLIPBOARD\":     sublime.get_clipboard()\n        , \"ORG_SELECTION\":     view.substr(view.sel()[0])\n        , \"ORG_LINENUM\":       str(view.curRow())\n        , \"ORG_FILENAME\":      dayPageGetDateString(dt)\n        , \"ORG_AUTHOR\":        getpass.getuser()\n        })\n    view.settings().set('auto_indent',ai)\n\ndef LoadedCheck(view,dt):\n    if(view.is_loading()):\n        sublime.set_timeout(lambda: LoadedCheck(view,dt),1)\n    else:\n        OnLoaded(view,dt)\n\ndef LoadedCheck2(view,dt, onDone):\n    if(view.is_loading()):\n        sublime.set_timeout(lambda: LoadedCheck2(view,dt,onDone),1)\n    else:\n        onDone(view,dt)\n\ndef dayPageInsertSnippet(view,dt):\n    window   = view.window()\n    window.focus_view(view)\n    LoadedCheck(view,dt)\n\ndef dayPageFindOldPage(dt):\n    maxScan     = 90\n    for i in range(maxScan):\n        dt = dt - datetime.timedelta(days=1)\n        fn = dayPageGetName(dt)\n        if(os.path.exists(fn)):\n            return fn\n    return None\n\ndef dayPageArchiveOld(dt):\n    fn = dayPageFindOldPage(dt)\n    if(fn == None):\n        return\n    f = db.Get().FindFileByFilename(os.path.basename(fn))\n    if(f == None):\n        return\n    if(f.org[0].set_comment(\"FILETAGS\",\"ARCHIVE\")):\n        f.Save()\n\ndef IsTodo(n):\n    return n.todo and n.todo in n.env.todo_keys\n\ndef IsDone(n):\n    return n.todo and n.todo in n.env.done_keys\n\ndef IsArchived(n):\n    return \"ARCHIVE\" in n.tags\n\ndef EnsureDate(ts):\n    if(isinstance(ts,datetime.datetime)):\n        return ts.date()\n    return ts\n\ndef dayPageCopyOpenTasks(tview, dt):\n    fn = dayPageFindOldPage(dt)\n    if(fn == None):\n        dayPageInsertSnippet(tview,dt)\n        return\n    f = db.Get().FindFileByFilename(os.path.basename(fn))\n    if(f == None):\n        dayPageInsertSnippet(tview,dt)\n        return\n    out = \"\"\n    for h in f.org[0].children:\n        if IsTodo(h):\n            for line in h._lines:\n                out += line + \"\\n\"\n    if(out != \"\"):\n        LoadedCheck2(tview, dt, lambda a,b: tview.run_command(\"org_internal_insert\", {\"location\": 0, \"text\": out, \"onDone\": evt.Make(lambda : dayPageInsertSnippet(tview, dt))}))\n    else:\n        dayPageInsertSnippet(tview,dt)\n    pass\n\ndef dayPageCopyOpenPhase(tview,dt):\n    if(sets.Get(\"dayPageCopyOpenTasks\", True)):\n        dayPageCopyOpenTasks(tview, dt)\n    else:\n        dayPageInsertSnippet(tview,dt)\n\ndef dayPageCopyTodayTasks(path, tview, dt):\n    allowOutsideOrgDir = sets.Get(\"dayPageIncludeFilesOutsideOrgDir\", False)\n    out = \"\"\n    for file in db.Get().Files:\n        # Quick out if ARCHIVE is marked on the file\n        globalTags = file.org.list_comment(\"FILETAGS\",[])\n        if(\"ARCHIVE\" in globalTags):\n            continue\n        # Skip over files not in orgDir\n        if(not file.isOrgDir and not allowOutsideOrgDir):\n            continue\n        # Skip over ourselves.\n        if(path.lower() == file.GetFilename().lower()):\n            continue\n        skipTill = 0\n        for i in range(1,len(file.org)):\n            if(i < skipTill):\n                continue\n            n = file.org[i]\n            if(IsTodo(n)):\n                ok = False\n                timestamps = n.get_timestamps(active=True,point=True,range=True)\n                for t in timestamps:\n                    if(t.start.day == dt.day and t.start.month == dt.month and t.start.year == dt.year):\n                        ok = True\n                        break\n                if(n.scheduled and (EnsureDate(n.scheduled.start) < EnsureDate(dt) and not IsDone(n) and not IsArchived(n) or EnsureDate(n.scheduled.start) == EnsureDate(dt))):\n                        ok = True\n                if(n.deadline and (EnsureDate(n.deadline.deadline_start) < EnsureDate(dt) and not IsDone(n) and not IsArchived(n) or EnsureDate(n.deadline.deadline_start) == EnsureDate(dt))):\n                        ok = True\n                if(ok):\n                    for line in n._lines:\n                        out += line + \"\\n\"\n                    skipTill = n.find_last_child_index() + 1\n    if(out != \"\"):\n        LoadedCheck2(tview, dt, lambda a,b: tview.run_command(\"org_internal_insert\", {\"location\": 0, \"text\": out, \"onDone\": evt.Make(lambda : dayPageCopyOpenPhase(tview, dt))}))\n    else:\n        dayPageCopyOpenPhase(tview,dt)\n\ndef dayPageCreateOrOpen(dt):\n    dpPath      = dayPageGetName(dt)\n    dateString  = dayPageGetDateString(dt)\n    didCreate   = False\n    if(not os.path.exists(dpPath)):\n        with open(dpPath,\"w\") as f:\n            f.write(\"\")\n            didCreate = True\n    tview = sublime.active_window().open_file(dpPath, sublime.ENCODED_POSITION)\n    if(didCreate):\n        if(sets.Get(\"dayPageArchiveOld\", True)):\n            dayPageArchiveOld(dt)\n        if(sets.Get(\"dayPageCopyTasksForToday\", True)):\n            dayPageCopyTodayTasks(dpPath, tview, dt)\n        else:\n            dayPageCopyOpenPhase(tview,dt)\n\nclass OrgDayPagePreviousCommand(sublime_plugin.TextCommand):\n    def OnDone(self):\n        evt.EmitIf(self.onDone)\n\n    def run(self, edit, onDone=None):\n        self.edit   = edit\n        self.onDone = onDone\n        self.dt     = datetime.datetime.now()\n        dt          = dayPageFilenameToDateTime(self.view)\n        maxScan     = 90\n        for i in range(maxScan):\n            dt = dt - datetime.timedelta(days=1)\n            if(sets.Get(\"dayPageCreateOldPages\",False)):\n                dayPageCreateOrOpen(dt)\n                break\n            else:\n                fn = dayPageGetName(dt)\n                if(os.path.exists(fn)):\n                    tview = sublime.active_window().open_file(fn, sublime.ENCODED_POSITION)\n                    sublime.active_window().focus_view(tview)\n                    break\n                else:\n                    #log.warning(\"Day page does not exist: \" + fn)\n                    pass\n\nclass OrgDayPageNextCommand(sublime_plugin.TextCommand):\n    def OnDone(self):\n        evt.EmitIf(self.onDone)\n\n    def run(self, edit, onDone=None):\n        self.edit   = edit\n        self.onDone = onDone\n        self.now    = datetime.datetime.now()\n        dt          = dayPageFilenameToDateTime(self.view)\n        maxScan     = 90\n        for i in range(maxScan):\n            dt = dt + datetime.timedelta(days=1)\n            if(dt.date() < self.now.date()):\n                fn = dayPageGetName(dt)\n                if(os.path.exists(fn)):\n                    tview = sublime.active_window().open_file(fn, sublime.ENCODED_POSITION)\n                    sublime.active_window().focus_view(tview)\n                    break\n                else:\n                    #log.warning(\"Day page does not exist: \" + fn)\n                    pass\n            elif(dt.date() == self.now.date()):\n                dayPageCreateOrOpen(dt)\n                break\n            else:\n                fn = dayPageGetName(dt)\n                log.error(\" Create day page in the future? \" + fn)\n                break\n\n\n\nclass OrgDayPageCreateCommand(sublime_plugin.TextCommand):\n    def OnDone(self):\n        evt.EmitIf(self.onDone)\n\n    def run(self, edit, onDone=None):\n        self.edit   = edit\n        self.onDone = onDone\n        self.dt = dayPageGetToday()\n        dayPageCreateOrOpen(self.dt)\n        self.OnDone()\n\n"
  },
  {
    "path": "orgdb.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport OrgExtended.orgparse.loader as loader\nimport OrgExtended.orgparse.node as node\nimport OrgExtended.orgutil.util as util\nimport logging\nimport traceback\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\n\nlog = logging.getLogger(__name__)\nheadingRe = re.compile(\"^([*]+) (.+)\")\n\n\nclass FileInfo:\n    def __init__(self, file, parsed, orgPaths):\n        self.isOrgDir = False\n        self.org      = parsed\n        self.filename = file\n        self.key      = file.lower() if file else None\n        self.change_count = 0\n        self.org.setFile(self)\n        displayFn = self.key\n        oldLen = len(displayFn) if displayFn else 0\n        if (not displayFn):\n            self.displayFn = \"<BUFFER>\"\n            return\n        for prefix in orgPaths:\n            displayFn = displayFn.replace(prefix, \"\")\n            displayFn = displayFn.replace(prefix.lower(), \"\")\n        self.isOrgDir = displayFn != self.key\n        # Max Slashes!\n        # No prefixes. We should count the slashes and truncate\n        # if there are to many.\n        maxSlash = 3\n        if (oldLen == len(displayFn)):\n            scount = displayFn.count('/')\n            if (scount > maxSlash):\n                llist = displayFn.split('/')\n                displayFn = '/'.join(llist[-maxSlash:])\n            scount = displayFn.count('\\\\')\n            if (scount > maxSlash):\n                llist = displayFn.split('\\\\')\n                displayFn = '\\\\'.join(llist[-maxSlash:])\n\n        if (len(displayFn) > 1 and (displayFn[0] == '\\\\' or displayFn[0] == '/')):\n            displayFn = displayFn[1:]\n        self.displayName = displayFn\n\n    def GetFilename(self):\n        return self.filename\n\n    def RebuildBacklinks(self):\n        links = self.org.env.links\n        for link in links:\n            if (link.IsFile()):\n                f = link.link\n                if (not os.path.isabs(f)):\n                    f = os.path.normpath(os.path.join(os.path.dirname(self.filename), f))\n                Get().AddBacklink(f, link, self)\n\n    def Root(self):\n        return self.org[0]\n\n    def RootInView(self, view, db):\n        self.ReloadIfChanged(view, db)\n        return self.Root()\n\n    def LoadS(self, view):\n        bufferContents = view.substr(sublime.Region(0, view.size()))\n        self.org = loader.loads(bufferContents, view.file_name() if view.file_name() else \"<string>\")\n        self.org.setFile(self)\n        # Keep track of last change count.\n        self.change_count = view.change_count()\n        self.RebuildBacklinks()\n\n    def Reload(self):\n        self.org = loader.load(self.filename)\n        self.org.setFile(self)\n        self.RebuildBacklinks()\n\n    def ResetChangeCount(self):\n        self.change_count = 0\n\n    def HeadingCount(self):\n        return len(self.org) - 1\n\n    def Save(self):\n        f = open(self.filename, \"w+\", encoding=\"utf-8\")\n        for item in self.org:\n            f.write(str(item))\n        f.close()\n\n    def ReloadIfChanged(self, view, db):\n        if (self.HasChanged(view)):\n            self.LoadS(view)\n            db.RebuildAllIdsForFile(self)\n\n    def HasChanged(self, view):\n        return self.change_count < view.change_count()\n\n    def At(self, row):\n        return self.org.at(row)\n\n    def AtPt(self, view, pt, db):\n        self.ReloadIfChanged(view, db)\n        row, col = view.rowcol(pt)\n        return self.org.at(row)\n\n    def AtRegion(self, view, reg):\n        row, col = view.rowcol(reg.begin())\n        return self.org.at(row)\n\n    def AtInView(self, view, db):\n        self.ReloadIfChanged(view, db)\n        (row, col) = view.curRowCol()\n        return self.org.at(row)\n\n    def AgendaFilenameTag(self):\n        return os.path.splitext(os.path.basename(self.filename))[0] + \":\"\n\n    def FindOrCreateNode(self, heading):\n        for n in self.org[1:]:\n            if (heading == n.full_heading):\n                return n\n\n        for n in self.org[1:]:\n            if (heading == n.heading):\n                return n\n\n        # Okay got here and didn't find the node, have to make it.\n        m = headingRe.search(heading)\n        if (m is None):\n            log.error(\"FindorCreateNode: failed to parse heading: \" + heading)\n            return None\n        levelGroup = m.group(1)\n        level = len(levelGroup)\n        cur         = self.org[0]\n        parentLevel = level - 1\n        while (cur.level < parentLevel):\n            if (cur.num_children == 0):\n                tree = loader.loads(\"* \" + str(datetime.datetime()))\n                cur.insert_child(tree[1])\n            cur = cur.get_last_child()\n        if (heading is None or heading.isspace() or heading.strip() == \"\"):\n            return cur\n        else:\n            tree = loader.loads(heading)\n            cur.insert_child(tree[1])\n            cur = cur.get_last_child()\n        return cur\n\n\nclass OrgFileId:\n    def __init__(self, file, id, index):\n        self.file  = file\n        self.id    = id\n        self.index = index\n\n\nclass OrgDb:\n    def __init__(self):\n        self.files    = {}\n        self.Files    = []\n        self.orgPaths = None\n        self.customids    = []\n        self.customidmaps = {}\n        self.ids          = []\n        self.idmaps       = {}\n        self.tags = set()\n        self.backlinks = {}\n\n    def GetBacklinks(self, view):\n        fn = view.file_name()\n        if (fn in self.backlinks):\n            return self.backlinks[fn]\n        return None\n\n    def AddBacklink(self, f, link, fi):\n        link.fromFile   = fi\n        link.targetName = f\n        if (f not in self.backlinks):\n            self.backlinks[f] = []\n        for i in range(len(self.backlinks[f])):\n            ff = self.backlinks[f][i]\n            if (link.row == ff.row):\n                self.backlinks[f][i] = link\n                return\n        self.backlinks[f].append(link)\n\n    def OnTags(self, tags):\n        for i in tags:\n            self.tags.add(i)\n\n    def RebuildCustomIdsForFile(self, file):\n        for id in file.org.env.customids:\n            if (id not in self.customidmaps):\n                index = len(self.customids)\n                fid = OrgFileId(file, id, index)\n                self.customids.append(fid)\n                self.customidmaps[id] = fid\n\n    def RebuildIdsForFile(self, file):\n        for id in file.org.env.ids:\n            if (id not in self.idmaps):\n                index = len(self.ids)\n                fid = OrgFileId(file, id, index)\n                self.ids.append(fid)\n                self.idmaps[id] = fid\n\n    def RebuildAllIdsForFile(self, file):\n        self.RebuildIdsForFile(file)\n        self.RebuildCustomIdsForFile(file)\n\n    def RebuildIds(self):\n        self.ids          = []\n        self.idmaps       = {}\n        self.customids    = []\n        self.customidmaps = {}\n        for file in self.Files:\n            self.RebuildAllIdsForFile(file)\n\n    def LoadNew(self, fileOrView):\n        if (fileOrView is None):\n            return None\n        if (not hasattr(self, 'orgPaths') or self.orgPaths is None):\n            self.orgPaths = self.__GetPaths(\"orgDirs\")\n        filename = self.FilenameFromFileOrView(fileOrView)\n        if (util.isPotentialOrgFile(filename)):\n            file = FileInfo(filename, loader.load(filename), self.orgPaths)\n            self.AddFileInfo(file)\n            return file\n        elif (util.isView(fileOrView) and util.isOrgSyntax(fileOrView)):\n            bufferContents = fileOrView.substr(sublime.Region(0, fileOrView.size()))\n            file = FileInfo(filename if filename else util.getKey(fileOrView), loader.loads(bufferContents), self.orgPaths)\n            self.AddFileInfo(file)\n            return file\n        else:\n            log.debug(\"File is not an org file, not loading into the database: \" + str(filename))\n            return None\n\n    def Remove(self, fileOrView):\n        if (type(fileOrView) is sublime.View):\n            filename = fileOrView.file_name().lower()\n        else:\n            filename = fileOrView.lower()\n        for i in range(len(self.Files) - 1, -1, -1):\n            if (self.Files[i].key == filename):\n                del self.Files[i]\n\n        if (filename in self.files):\n            del self.files[filename]\n        # self.files.pop(filename,None)\n\n    def Reload(self, fileOrView):\n        self.orgPaths = self.__GetPaths(\"orgDirs\")\n        fi = self.FindInfo(fileOrView)\n        if (fi is not None):\n            fi.Reload()\n            self.RebuildIds()\n            fi.RebuildBacklinks()\n            return fi\n        else:\n            rv = self.LoadNew(fileOrView)\n            self.RebuildIds()\n            return rv\n\n    def GetIndentForRegion(self, view, region):\n        node = self.AtRegion(view, region)\n        return node.level + 1\n\n    def FilenameFromFileOrView(self, fileOrView):\n        filename = None\n        if (type(fileOrView) is sublime.View):\n            filename = fileOrView.file_name()\n        else:\n            filename = fileOrView\n        return filename\n\n    def AddFileInfo(self, fi):\n        if (self.files is None):\n            self.files = {}\n        self.files[fi.key] = fi\n        if (self.Files is None):\n            self.Files = []\n        unique = True\n        for i, f in enumerate(self.Files):\n            if f.filename == fi.filename:\n                unique = False\n                self.Files[i] = fi\n                break\n        if unique:\n            self.Files.append(fi)\n        self.SortFiles()\n        fi.RebuildBacklinks()\n\n    def SortFiles(self):\n        self.Files.sort(key=lambda x: x.key)\n\n    @staticmethod\n    def IsExcluded(filename, excludedPaths, excludedFiles):\n        if (excludedPaths):\n            excludedPaths = [x.lower().replace('\\\\', '/') for x in excludedPaths]\n            mypath = os.path.dirname(filename).lower().replace('\\\\', '/')\n            for item in excludedPaths:\n                if mypath.startswith(item):\n                    return True\n        if (excludedFiles):\n            excludedFiles = [x.lower().replace('\\\\', '/') for x in excludedFiles]\n            myfile = os.path.basename(filename).lower().replace('\\\\', '/')\n            for item in excludedFiles:\n                if (item == myfile):\n                    return True\n        return False\n\n    def RebuildDb(self):\n        if (evt.Get().listeners('tagsfound')):\n            evt.Get().clear_listeners('tagsfound')\n        evt.Get().on(\"tagsfound\", self.OnTags)\n        self.Files = []\n        self.files = {}\n        self.orgPaths = self.__GetPaths(\"orgDirs\")\n        self.orgFiles = self.__GetPaths(\"orgFiles\")\n        self.orgExcludePaths = self.__GetPaths(\"orgExcludeDirs\")\n        self.orgExcludeFiles = self.__GetPaths(\"orgExcludeFiles\")\n        if (self.orgPaths):\n            # Just in case the user gave us a string instead of a list.\n            if (isinstance(self.orgPaths, str)):\n                self.orgPaths = [self.orgPaths]\n            for orgPath in self.orgPaths:\n                orgPath = orgPath.replace('\\\\', '/')\n                globSuffix = sets.Get(\"validOrgExtensions\", [\".org\"])\n                for suffix in globSuffix:\n                    if ('archive' in suffix):\n                        continue\n                    suffix = \"*\" + suffix\n                    dirGlobPos = orgPath.find(\"*\")\n                    if (dirGlobPos > 0):\n                        suffix  = os.path.join(orgPath[dirGlobPos:], suffix)\n                        orgPath = orgPath[0:dirGlobPos]\n                    if (\"*\" in orgPath):\n                        log.error(\" orgDirs only supports double star style directory wildcards! Anything else is not supported: \" + str(orgPath))\n                        if (sublime.active_window().active_view()):\n                            sublime.active_window().active_view().set_status(\"Error: \", \"orgDirs only supports double star style directory wildcards! Anything else is not supported: \" + str(orgPath))\n                        log.error(\" skipping orgDirs value: \" + str(orgPath))\n                        continue\n                    try:\n                        if not Path(orgPath).exists():\n                            log.warning('orgDir path {} does not exist!'.format(orgPath))\n                            continue\n                    except Exception as e:\n                        log.warning('could not add org path: {} - does not seem to exist {}'.format(orgPath, str(e)))\n                        continue\n                    try:\n                        for path in Path(orgPath).glob(suffix):\n                            if OrgDb.IsExcluded(str(path), self.orgExcludePaths, self.orgExcludeFiles):\n                                continue\n                            try:\n                                filename = str(path)\n                                log.debug(\"PARSING: \" + filename)\n                                file = FileInfo(filename, loader.load(filename), self.orgPaths)\n                                file.isOrgDir = True\n                                self.AddFileInfo(file)\n                            except Exception:\n                                log.warning(\"FAILED PARSING: %s\\n  %s\", str(path), traceback.format_exc())\n                    except Exception:\n                        log.warning(\"ERROR globbing {}\\n{}\".format(orgPath, traceback.format_exc()))\n        if (self.orgFiles):\n            # Just in case the user gave us a string instead of a list.\n            if (isinstance(self.orgFiles, str)):\n                self.orgFiles = [self.orgFiles]\n            for orgFile in self.orgFiles:\n                path = orgFile.replace('\\\\', '/')\n                if OrgDb.IsExcluded(str(path), self.orgExcludePaths, self.orgExcludeFiles):\n                    continue\n                try:\n                    filename = str(path)\n                    file = FileInfo(filename, loader.load(filename), self.orgPaths)\n                    file.isOrgDir = True\n                    self.AddFileInfo(file)\n                except Exception:\n                    log.warning(\"FAILED PARSING: %s\\n  %s\", str(path), traceback.format_exc())\n        self.SortFiles()\n        self.RebuildIds()\n\n    def FindInfo(self, fileOrView):\n        try:\n            if (not fileOrView):\n                return None\n            key = util.getKey(fileOrView).lower()\n            if (key and key in self.files):\n                f = self.files[key]\n            else:\n                f = self.LoadNew(fileOrView)\n            if (f and util.isView(fileOrView)):\n                f.ReloadIfChanged(fileOrView, self)\n            return f\n        except Exception:\n            try:\n                f = self.LoadNew(fileOrView)\n                if (type(fileOrView) is sublime.View):\n                    f.ReloadIfChanged(fileOrView, self)\n                return f\n            except Exception:\n                log.warning(\"FAILED PARSING: \\n  %s\", traceback.format_exc())\n                return None\n\n    def Find(self, fileOrView):\n        n = self.FindInfo(fileOrView)\n        if (n is not None):\n            return n.org\n        return None\n\n    def At(self, fileOrView, line):\n        x = self.Find(fileOrView)\n        if (x is not None):\n            return x.at(line)\n        return None\n\n    def AtInView(self, view):\n        (row, col) = view.curRowCol()\n        return self.At(view, row)\n\n    def AtPt(self, view, pt):\n        file = self.FindInfo(view)\n        return file.AtPt(view, pt, self)\n\n    def RootInView(self, view):\n        file = self.FindInfo(view)\n        if file:\n            return file.RootInView(view, self)\n        return None\n\n    def AtRegion(self, view, reg):\n        file = self.FindInfo(view)\n        return file.AtRegion(view, reg)\n\n    def NodeAtIndex(self, fileOrView, index):\n        return self.Find(fileOrView).node_at(index + 1)\n\n    def Headings(self, view):\n        f = self.Find(view)\n        headings = []\n        if (f is not None):\n            for n in f[1:]:\n                headings.append((\". \" * (n.level)) + n.heading)\n        return headings\n\n    # This is paired with FindFileInfo\n    def AllHeadings(self, view):\n        headings = []\n        for o in self.Files:\n            displayFn = o.displayName\n            f = o.org\n            for n in f[1:]:\n                formattedHeading = \"{0:35}::{1}{2}\".format(displayFn, (\". \" * (n.level)), n.heading)\n                headings.append(formattedHeading)\n        return headings\n\n    # This is paired with FindFileInfo\n    def AllHeadingsWContext(self, view):\n        headings = []\n        count = 0\n        for o in self.Files:\n            displayFn = o.displayName\n            f = o.org\n            for n in f[1:]:\n                parents = \"\"\n                t = n\n                while (type(t.parent) != node.OrgRootNode and t.parent is not None):\n                    t = t.parent\n                    parents = t.heading + \":\" + parents\n                formattedHeading = [\"{0}{1}\".format(parents, n.heading), displayFn]\n                headings.append(formattedHeading)\n                count += 1\n        return headings\n\n    def AllHeadingsForFile(self, file):\n        headings = []\n        count = 0\n        f = file.org\n        for n in f[1:]:\n            parents = \"\"\n            t = n\n            while (type(t.parent) != node.OrgRootNode and t.parent is not None):\n                t = t.parent\n                parents = t.heading + \":\" + parents\n            formattedHeading = \"{0}{1}\".format(parents, n.heading)\n            headings.append(formattedHeading)\n            count += 1\n        return headings\n\n    # This is paired with FindFileInfo\n    def AllFiles(self, view):\n        files = []\n        for o in self.Files:\n            displayFn = o.displayName\n            files.append(displayFn)\n        return files\n\n    def FindFileByIndex(self, index):\n        return self.Files[index]\n\n    # This is a pair with AllHeadings, it can go from an index in that BACK to the\n    # fileinfo\n    def FindFileInfoByAllHeadingsIndex(self, index):\n        curVal = 0\n        for o in self.Files:\n            if (index >= curVal and index < (curVal + o.HeadingCount())):\n                return (o, (index - curVal) + 1)  # remember to account for header\n            curVal += o.HeadingCount()\n        return None\n\n    # Try to find a node by filename and locator\n    def FindNode(self, filename, locator):\n        file = self.FindInfo(filename)\n        if (not file):\n            return None\n\n        # Basic locator search through the headings\n        headings = locator.split(\":\")\n        cur = file.org[0]\n        for index in range(len(headings)):\n            heading = headings[index]\n            for n in cur.children:\n                if (n.heading == heading):\n                    cur = n\n                    break\n            # Did not find this level of heading darn\n            if (not cur or cur.is_root() or cur.heading != heading):\n                break\n        heading = headings[len(headings)-1]\n        if (not cur or cur.is_root() or cur.heading == heading):\n            return cur\n\n        if (len(headings) > 1):\n            parent = headings[-1]\n        bestMatch = None\n\n        # fuzzy search, heading must match (hopefully)\n        for n in file.org[1:]:\n            if (n.heading == heading):\n                bestMatch = n\n                if (n.parent and n.parent.heading == parent):\n                    return n\n        return bestMatch\n\n    def JumpToCustomId(self, id):\n        path = None\n        file, at = self.FindByCustomId(id)\n        if (file is not None):\n            path = \"{0}:{1}\".format(file.filename, at + 1)\n        if (path):\n            sublime.active_window().open_file(path, sublime.ENCODED_POSITION)\n            return True\n        else:\n            log.info(\"Could not locate Custom ID failed to jump there\")\n            return False\n\n    def JumpToId(self, id):\n        path = None\n        file, at = self.FindById(id)\n        if (file is not None):\n            path = \"{0}:{1}\".format(file.filename, at + 1)\n        if (path):\n            sublime.active_window().open_file(path, sublime.ENCODED_POSITION)\n            return True\n        else:\n            log.info(\"Could not locate ID failed to jump there\")\n            return False\n\n    def JumpToAnyId(self, id):\n        if (not self.JumpToId(id)):\n            return self.JumpToCustomId(id)\n        return True\n\n    def FindByAnyId(self, id):\n        v = self.FindById(id)\n        if (not v or v[0] is None):\n            return self.FindByCustomId(id)\n        return v\n\n    def FindNodeByAnyId(self, id):\n        v = self.FindByAnyId(id)\n        if (v and v[0]):\n            return v[0].At(v[1])\n        return None\n\n    def FindFileByFilename(self, filename):\n        for f in self.Files:\n            if (filename in f.filename):\n                return f\n        return None\n\n    def FindByCustomId(self, id):\n        if (id in self.customidmaps):\n            fid = self.customidmaps[id]\n            file = fid.file\n            at = file.org.env.customids[id][1]\n            return (file, at)\n        return (None, None)\n\n    def FindById(self, id):\n        if (id in self.idmaps):\n            fid = self.idmaps[id]\n            file = fid.file\n            at = file.org.env.ids[id][1]\n            return (file, at)\n        return (None, None)\n\n    def GetIds(self):\n        return self.idmaps.keys()\n\n    def __GetPaths(self, name):\n        paths = sets.Get(name, None)\n        if (str == type(paths)):\n            return os.path.expanduser(paths)\n        if (list == type(paths)):\n            return list(map(os.path.expanduser, paths))\n        return None\n\n\n# EXPORTED ORGDB\norgDb = OrgDb()\n\n\ndef Get():\n    global orgDb\n    return orgDb\n\n\n# rebuild our org database from our org directory\nclass OrgRebuildDbCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        Get().RebuildDb()\n\n\n# Just reload the current file.\nclass OrgReloadFileCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        file = Get().FindInfo(self.view)\n        if (file):\n            file.LoadS(self.view)\n            orgDb.RebuildIds()\n        else:\n            log.debug(\"FAILED TO FIND FILE INFO?\")\n\n\nclass OrgJumpToCustomIdCommand(sublime_plugin.TextCommand):\n    def on_done_st4(self, index, modifers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        if (index < 0 or index >= len(orgDb.customids)):\n            return\n        fid  = orgDb.customids[index]\n        file = fid.file\n        id   = fid.id\n        at   = file.org.env.customids[id][1]\n        path = \"{0}:{1}\".format(file.filename, at + 1)\n        self.view.window().open_file(path, sublime.ENCODED_POSITION)\n\n    def run(self, edit):\n        if (int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(orgDb.customids, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(orgDb.customids, self.on_done_st4, -1, -1)\n\n\nclass OrgJumpToIdCommand(sublime_plugin.TextCommand):\n    def on_done_st4(self, index, modifers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        if (index < 0 or index >= len(orgDb.ids)):\n            return\n        fid = orgDb.ids[index]\n        file = fid.file\n        id   = fid.id\n        at   = file.org.env.ids[id][1]\n        path = \"{0}:{1}\".format(file.filename, at + 1)\n        self.view.window().open_file(path, sublime.ENCODED_POSITION)\n\n    def run(self, edit):\n        if (int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(orgDb.ids, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(orgDb.ids, self.on_done_st4, -1, -1)\n\n\nclass OrgJumpToTodayCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        file, at = Get().FindByCustomId(\"TODAY\")\n        path = \"{0}:{1}\".format(file.filename, at + 1)\n        self.view.window().open_file(path, sublime.ENCODED_POSITION)\n"
  },
  {
    "path": "orgduration.py",
    "content": "from ctypes import ArgumentError\nimport datetime\nimport re\nimport math\nimport sublime_plugin\n\n# This library provides tools to manipulate durations.  A duration\n# can have multiple formats:\n#\n#   - 3:12\n#   - 1:23:45\n#   - 1y 3d 3h 4min\n#   - 1d3h5min\n#   - 3d 13:35\n#   - 2.35h\n#\n# More accurately, it consists of numbers and units, as defined in\n# variable `org-duration-units', possibly separated with white\n# spaces, and an optional \"H:MM\" or \"H:MM:SS\" part, which always\n# comes last.  White spaces are tolerated between the number and its\n# relative unit.  Variable `org-duration-format' controls durations\n# default representation.\n#\n# The library provides functions allowing to convert a duration to,\n# and from, a number of minutes: `org-duration-to-minutes' and\n# `org-duration-from-minutes'.  It also provides two lesser tools:\n# `org-duration-p', and `org-duration-h:mm-only-p'.\n#\n# Users can set the number of minutes per unit, or define new units,\n# in `org-duration-units'.  The library also supports canonical\n# duration, i.e., a duration that doesn't depend on user's settings,\n# through optional arguments.\n\nRE_DURATION_PARSER = re.compile(r'\\s*((?P<years>[0-9.]+)y)?\\s*((?P<days>[0-9.]+)d)?\\s*((?P<hours>[0-9.]+)h)?\\s*((?P<mins>[0-9.]+)min)?\\s*((?P<thours>[0-9]+)[:](?P<tmins>[0-9]+)([:](?P<tsecs>[0-9]+))?)?')\n\n\nclass OrgDuration:\n    def __init__(self, minutes):\n        self.mins = minutes\n\n    def __str__(self):\n        r = \"\"\n        y = int(self.mins / 525600.0)\n        if (y > 0):\n            r += str(y) + \"y \"\n        days = math.fmod(self.mins, 525600.0)\n        d = int(days / 1440.0)\n        if (d > 0):\n            r += str(d) + \"d \"\n        hours = math.fmod(days, 1440.0)\n        h = int(hours / 60.0)\n        if (h > 0):\n            r += str(h) + \"h \"\n        mins = int(math.fmod(hours, 60))\n        if (mins > 0):\n            r += str(mins) + \"mins\"\n        return r.strip()\n\n    def days(self):\n        return self.mins / 1440.0\n\n    def months(self):\n        return self.mins / 43800.0\n\n    def weeks(self):\n        return self.mins / 10080.0\n\n    def hours(self):\n        return self.mins / 60.0\n\n    def minutes(self):\n        return self.mins\n\n    def seconds(self):\n        return self.mins * 60.0\n\n    def doubled(self):\n        return OrgDuration(self.mins * 2.0)\n\n    def __sub__(self, o):\n        if (isinstance(o, int)):\n            d = OrgDuration.ParseInt(o)\n            mins = self.mins - d.mins\n            d.mins = abs(mins)\n            return d\n        if (isinstance(o, float)):\n            d = OrgDuration.ParseFloat(o)\n            mins = self.mins - d.mins\n            d.mins = abs(mins)\n            return d\n        if (isinstance(o, OrgDuration)):\n            d = OrgDuration.ParseInt(1)\n            d.mins = abs(self.mins - o.mins)\n            return d\n        return self\n\n    def __add__(self, o):\n        if (isinstance(o, int)):\n            d = OrgDuration.ParseInt(o)\n            mins = self.mins + d.mins\n            d.mins = mins\n            return d\n        if (isinstance(o, float)):\n            d = OrgDuration.ParseFloat(o)\n            mins = self.mins + d.mins\n            d.mins = mins\n            return d\n        if (isinstance(o, OrgDuration)):\n            d = OrgDuration.ParseInt(1)\n            d.mins = self.mins + o.mins\n            return d\n        return self\n\n    def __div__(self, other):\n        if (isinstance(other, int) or isinstance(other, float)):\n            return OrgDuration(self.mins / other)\n        return OrgDuration(self.mins)\n\n    def __mul__(self, other):\n        if isinstance(other, int) or isinstance(other, float):\n            return OrgDuration(self.mins * other)\n        return OrgDuration(self.mins)\n\n    def __rmul__(self, other):\n        return self.__mul__(other)\n\n    def __radd__(self, other):\n        return self.__add__(other)\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n    def __gt__(self, other):\n        if isinstance(other, int) or isinstance(other, float):\n            return self.mins > other\n        if isinstance(other, str):\n            v = OrgDuration.Parse(other)\n            if v is not None:\n                return self.mins > v.mins\n            else:\n                raise ArgumentError(other + \" is not a valid duration\")\n        if isinstance(other, OrgDuration):\n            return self.mins > other.mins\n        return False\n\n    def __ge__(self, other):\n        if isinstance(other, int) or isinstance(other, float):\n            return self.mins >= other\n        if isinstance(other, str):\n            v = OrgDuration.Parse(other)\n            if v is not None:\n                return self.mins >= v.mins\n            else:\n                raise ArgumentError(other + \" is not a valid duration\")\n        if isinstance(other, OrgDuration):\n            return self.mins >= other.mins\n        return False\n\n    def __lt__(self, other):\n        if isinstance(other, int) or isinstance(other, float):\n            return self.mins < other\n        if isinstance(other, str):\n            v = OrgDuration.Parse(other)\n            if v is not None:\n                return self.mins < v.mins\n            else:\n                raise ArgumentError(other + \" is not a valid duration\")\n        if isinstance(other, OrgDuration):\n            return self.mins < other.mins\n        return False\n\n    def __le__(self, other):\n        if isinstance(other, int) or isinstance(other, float):\n            return self.mins <= other\n        if isinstance(other, str):\n            v = OrgDuration.Parse(other)\n            if v is not None:\n                return self.mins <= v.mins\n            else:\n                raise ArgumentError(other + \" is not a valid duration\")\n        if isinstance(other, OrgDuration):\n            return self.mins <= other.mins\n        return False\n\n    def timedelta(self):\n        y     = int(self.mins / 525600.0)\n        days  = math.fmod(self.mins, 525600.0)\n        d     = int(days / 1440.0)\n        hours = math.fmod(days, 1440.0)\n        h     = int(hours / 60.0)\n        mins  = int(math.fmod(hours, 60))\n        td = datetime.timedelta(days=d + (y * 365), hours=h, minutes=mins)\n        return td\n\n    @staticmethod\n    def FromTimedelta(td: datetime.timedelta):\n        return OrgDuration(td.days * 1440 + (td.seconds / 60.0))\n\n    @staticmethod\n    def Parse(txt: str, need: bool = False):\n        m = RE_DURATION_PARSER.search(txt)\n        if (m):\n            mtot = 0.0\n            got = False\n            y = m.group('years')\n            if (y):\n                mtot += float(y) * 525600.0\n                got = True\n            d = m.group('days')\n            if (d):\n                mtot += float(d) * 1440\n                got = True\n            h = m.group('hours')\n            if (h):\n                mtot += float(h) * 60\n                got = True\n            mins = m.group('mins')\n            if (mins):\n                mtot += float(mins)\n                got = True\n            h = m.group('thours')\n            if (h):\n                mtot += float(h) * 60\n                got = True\n            mins = m.group('tmins')\n            if (mins):\n                mtot += float(mins)\n                got = True\n            secs = m.group('tsecs')\n            if (secs):\n                mtot += float(secs) * 0.01666667\n                got = True\n            if (got or not need):\n                return OrgDuration(mtot)\n        return None\n\n    @staticmethod\n    def ParseWeekDayOffset(txt: str):\n        if (len(txt) < 3):\n            return None\n        change = [\"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\", \"sunday\"]\n        nextDay = txt.lower()\n        nextOf = [idx for idx, element in enumerate(change) if element.startswith(nextDay)]\n        if (len(nextOf) > 0):\n            nextOf = nextOf[0]\n        else:\n            return None\n        wd = datetime.datetime.now().weekday()\n        if (wd >= nextOf):\n            offset = 7 - wd + nextOf\n        else:\n            offset = nextOf - wd\n        mtot = 0.0\n        if (offset != 0):\n            mtot += float(offset) * 1440\n            return OrgDuration(mtot)\n        return None\n\n    @staticmethod\n    def ParseMonthOffset(txt: str):\n        if (len(txt) < 3):\n            return None\n        change = [\"january\", \"febuary\", \"march\", \"april\", \"may\", \"june\", \"july\", \"august\", \"september\", \"october\", \"november\", \"december\"]\n        tokens = txt.split(' ')\n        monthOffset = 0\n        dayOffset   = 0\n\n        day   = datetime.datetime.now().day\n        for token in tokens:\n            tk = token.lower()\n            monthCheck = [idx for idx, element in enumerate(change) if element.startswith(tk)]\n            if (len(monthCheck) > 0):\n                monthOffset = (monthCheck[0] + 1)\n            if tk.isnumeric():\n                dayOffset = int(tk)\n        if (monthOffset == 0 and dayOffset == 0):\n            return None\n        if (dayOffset == 0):\n            dayOffset = day\n        dt = datetime.datetime.now().replace(month=monthOffset, day=dayOffset)\n        offset = dt - datetime.datetime.now()\n        mtot = 0.0\n        if ((offset.total_seconds() / 60.0) != 0):\n            mtot += offset.total_seconds() / 60.0\n            return OrgDuration(mtot)\n        return None\n\n    @staticmethod\n    def ParseInt(d: int):\n        # Let the user determine default meaning d is the default\n        mtot = float(d) * 1440\n        return OrgDuration(mtot)\n\n    @staticmethod\n    def ParseFloat(d: float):\n        # Let the user determine default meaning d is the default\n        mtot = float(d) * 1440\n        return OrgDuration(mtot)\n\n\n# ================================================================================\nclass OrgTestDurationCommand(sublime_plugin.TextCommand):\n    def run(self, edit, onDone=None):\n        d = OrgDuration.Parse(\"2y3d5h6min\")\n        print(str(d))\n        d = OrgDuration.Parse(\"1y\")\n        print(str(d))\n        d = OrgDuration.Parse(\"2d\")\n        print(str(d))\n        d = OrgDuration.Parse(\"3h\")\n        print(str(d))\n        d = OrgDuration.Parse(\"4min\")\n        print(str(d))\n        d = OrgDuration.Parse(\"1d 3:44\")\n        print(str(d))\n        d = OrgDuration.Parse(\"1d 4:55:55\")\n        print(str(d))\n"
  },
  {
    "path": "orgdwim.py",
    "content": "import sublime\nimport sublime_plugin\nimport os\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcheckbox as checkbox\nimport OrgExtended.orgnumberedlist as numberedlist\nimport OrgExtended.orgdynamicblock as dynamic\nimport OrgExtended.orgsourceblock as src\nimport OrgExtended.orgediting as editing\nimport OrgExtended.orgtableformula as tbl \n\nlog = logging.getLogger(__name__)\n\n\n# ====================================================================\n# Another Do What I Mean style command.\n# Contextually looks at where you are and \"does the right thing.\"\n# All about inserting things state.\nclass OrgGenericInsertCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        line = self.view.curLine()\n        cb = checkbox.get_checkbox(self.view, line)\n        if(cb):\n            self.view.run_command('org_insert_checkbox')\n            return\n        if(checkbox.isUnorderedList(self.view.substr(line))):\n            self.view.run_command('org_insert_unordered_list')\n            return\n        if(numberedlist.isNumberedLine(self.view)):\n            numberedlist.AppendLine(self.view, edit)\n            return\n        n = db.Get().AtInView(self.view)\n        if(not n.is_root()):\n            self.view.run_command('org_insert_heading_sibling')\n\n# ====================================================================\nclass OrgGenericInsertAuxCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        line = self.view.curLine()\n        cb = checkbox.get_checkbox(self.view, line)\n        if(cb):\n            self.view.run_command('org_insert_checkbox',{'insertHere': False})\n            return\n        if(checkbox.isUnorderedList(self.view.substr(line))):\n            self.view.run_command('org_insert_unordered_list',{'insertHere': False})\n            return\n        if(numberedlist.isNumberedLine(self.view)):\n            numberedlist.AppendLine(self.view, edit, insertHere=False)\n            return\n        n = db.Get().AtInView(self.view)\n        if(not n.is_root()):\n            self.view.run_command('org_insert_heading_child')\n\n# ====================================================================\n# Another Do What I Mean style command.\n# Contextually looks at where you are and \"does the right thing.\"\n# Recalculates checkboxes, recalculates blocks etc.\nclass OrgRecalcCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        if(dynamic.IsDynamicBlock(self.view)):\n            self.view.run_command('org_execute_dynamic_block')\n            return\n        if(src.IsInlineSourceBlock(self.view)):\n            self.view.run_command('org_execute_inline_source_block')\n            return\n        if(src.IsSourceBlock(self.view)):\n            self.view.run_command('org_execute_source_block')\n            return\n        if(src.IsCallCommentBlock(self.view)):\n            self.view.run_command('org_execute_call_comment')\n            return\n        if(tbl.isTable(self.view)):\n            self.view.run_command('org_execute_table')\n            return\n        checkbox.recalculate_all_checkbox_summaries(self.view, edit)\n        numberedlist.UpdateLine(self.view, edit)\n\n# ====================================================================\n# Another Do What I Mean style command.\n# Contextually looks at where you are and \"does the right thing.\"\n# All about toggling things state.\nclass OrgToggleCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        line = self.view.curLine()\n        cb = checkbox.is_checkbox_line(self.view)\n        #cb = checkbox.get_checkbox(self.view, line)\n        if(cb):\n            self.view.run_command('org_toggle_checkbox')\n            return\n        else:\n            self.view.run_command('org_todo_change')\n\n\n# ====================================================================\nclass OrgChangeIndentCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        line = self.view.curLine()\n        cb = checkbox.get_checkbox(self.view, line)\n        if(cb):\n            editing.indent_list(self.view,self.view.curRow(), edit)\n            return\n        if(checkbox.isUnorderedList(self.view.substr(line))):\n            editing.indent_list(self.view,self.view.curRow(), edit)\n            return\n        if(numberedlist.isNumberedLine(self.view)):\n            editing.indent_list(self.view,self.view.curRow(), edit)\n            return\n        n = db.Get().AtInView(self.view)\n        if(n and type(n) != node.OrgRootNode):\n            editing.indent_node(self.view, n, edit)\n            file = db.Get().FindInfo(self.view)\n            file.LoadS(self.view)\n\n# ====================================================================\n# This does not handle indention of sub trees! Need to fix that!\nclass OrgChangeDeIndentCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        line = self.view.curLine()\n        cb = checkbox.get_checkbox(self.view, line)\n        if(cb):\n            editing.deindent_list(self.view,self.view.curRow(), edit)\n            return\n        if(checkbox.isUnorderedList(self.view.substr(line))):\n            editing.deindent_list(self.view,self.view.curRow(), edit)\n            return\n        if(numberedlist.isNumberedLine(self.view)):\n            editing.deindent_list(self.view,self.view.curRow(), edit)\n            return\n        n = db.Get().AtInView(self.view)\n        if(n and type(n) != node.OrgRootNode):\n            editing.deindent_node(self.view, n, edit)\n            file = db.Get().FindInfo(self.view)\n            file.LoadS(self.view)\n"
  },
  {
    "path": "orgdynamic/clocktable.py",
    "content": "import sublime\nimport OrgExtended.orgdb as db\nimport OrgExtended.orgparse.date as d\n\n# This is a placeholder clocktable dynamic block\ndef setup_heading(output,level):\n\ttitle = \"|Heading|Time|\" + ('|' * (level-1))\n\toutput.append(title)\n\toutput.append(\"|-\")\n\ndef handle_heading(skip, node, clevel, level):\n\t#print(\"H: \" + node.heading)\n\tskipstr = \"\"\n\tif(skip > 0):\n\t\tskipstr = (\"|\" * skip)\n\tclevelskip = \"\"\n\tif(clevel > 0):\n\t\tclevelskip = \"|\" * clevel\n\tdifflevel = level - clevel - 1\n\tdifflevelskip = \"\"\n\tif(difflevel > 0):\n\t\tdifflevelskip = \"|\" * difflevel\n\thindent = \"\"\n\tif(clevel > 0):\n\t\thindent = r'\\_'\n\tif(clevel > 1):\n\t\thindent = hindent + ('__' * (clevel - 1))\n\tif(hindent != \"\"):\n\t\thindent = hindent + \" \"\n\treturn \"{0}|{1}|{2}{3}{4}|\".format(skipstr,hindent + node.heading,clevelskip,d.OrgDate.format_duration(node.duration()),difflevelskip)\n\ndef handle_subheading(output, skip, view, node, params, clevel, level):\n\toutput.append(handle_heading(skip, node, clevel, level))\n\tfor c in node.children:\n\t\thandle_subheading(output, skip, view, c, params, clevel+1, level)\n\n\ndef handle_subtree(view, params, level):\n\tnode = db.Get().AtInView(view)\t\n\toutput = []\n\tsetup_heading(output, level)\n\toutput.append(handle_heading(0, node, 0, level))\n\tfor c in node.children:\n\t\thandle_subheading(output, 0, view, c, params, 1, level)\n\treturn output\n\ndef get_level(params):\n\tlevel = params.GetInt('maxlevel',2)\n\tif(level < 2):\n\t\tlevel = 2\n\treturn level\n\ndef Execute(view, params):\n\tlevel = get_level(params)\n\tif(params.Get('scope','subtree') == 'subtree'):\n\t\treturn handle_subtree(view, params, level)\n\telse:\n\t\tprint(params['scope'] + \" is not implemented\")\n\n\tfile = db.Get().FindInfo(view)\n\tif(file):\n\t\tr = file.org\n\t\tfor n in r.children:\n\t\t\tn.duration()\t\n\toutput = []\n\toutput.append(\"|Heading|Time|\")\n\toutput.append(\"|-\")\n\toutput.append(\"|A|B|\")\n\treturn output\n\ndef PostExecute(view, params, region):\n\trow,col = view.rowcol(view.sel()[0].begin())\n\tview.sel().clear()\n\tview.sel().add(view.text_point(row+1,col))\n\tview.run_command(\"table_editor_next_field\")"
  },
  {
    "path": "orgdynamic/columnview.py",
    "content": "import os\nimport re\n\nimport OrgExtended.orgdb as db\n\n\ndef GetLevel(params):\n\tlevel = params.GetInt('maxlevel',2)\n\tif(level < 2):\n\t\tlevel = 2\n\treturn level\n\ndef HandleItem(params,n,defs,output,depth,maxdepth):\n\tif(maxdepth > 0 and depth > maxdepth):\n\t\treturn\n\tout = []\n\temptyCount = 0\n\tfor d in defs:\n\t\tv = str(d.GetCellValue(n,params)).strip()\n\t\temptyCount += 1 if v == \"\" else 0\n\t\tout.append(v)\n\tok = True\n\texclude = params.GetList('exclude-tags',[])\n\tfor e in exclude:\n\t\tif(e in n.tags):\n\t\t\tok = False\n\t\t\tbreak\n\tif(params.Get('skip-empty-rows','nil') != 'nil'):\n\t\tok = ok and emptyCount < (len(defs)-1)\n\tif(ok):\n\t\tv = params.Get('hlines','nil')\n\t\tif(v == 't'):\n\t\t\toutput.append([\"-\"])\n\t\telif(v != 'nil' and v != \"\"):\n\t\t\tv = int(v)\n\t\t\tif(depth <= v):\n\t\t\t\toutput.append([\"-\"])\n\t\toutput.append(out)\n\tfor c in n.children:\n\t\tHandleItem(params,c,defs,output,depth+1,maxdepth)\n\ndef HandleHeadings(defs,output):\n\tout = \"|\"\n\tfor d in defs:\n\t\tout += d.Heading() + \"|\"\n\toutput.append(out)\n\nclass ColumnHandler:\n\tdef Setup(self,width,propName,heading,summary):\n\t\tself.width = width\n\t\tself.name = propName\n\t\tif(heading):\n\t\t\tself.heading = heading\n\t\telse:\n\t\t\tself.heading = propName\n\t\tself.summary = summary\n\n\tdef Heading(self):\n\t\treturn self.heading\n\nclass ItemHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\tindent = \"\"\n\t\tif(params.Get('indent','') == 't'):\n\t\t\tindent = '..' * (n.level-1)\n\t\treturn indent + n.heading\n\nclass DeadlineHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\treturn n.deadline.format_datetime_str() if n.deadline else \"\"\n\nclass ClosedHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\treturn n.closed.format_datetime_str() if n.closed else \"\"\n\nclass ScheduledHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\treturn n.scheduled.format_datetime_str() if n.scheduled else \"\"\n\nclass TimestampHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\tts = n.get_timestamps(active=True, inactive=False, range=True, point=True)\n\t\tif(ts and len(ts) >= 1):\n\t\t\treturn ts[0].format_datetime_str()\n\t\treturn \"\"\n\nclass IATimestampHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\tts = n.get_timestamps(active=False, inactive=True, range=True, point=True)\n\t\tif(ts and len(ts) >= 1):\n\t\t\treturn ts[0].format_datetime_str()\n\t\treturn \"\"\n\nclass PriorityHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\treturn n.priority if n.priority else \"\"\n\nclass TodoHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\treturn n.todo if n.todo else \"\"\n\nclass AllTagsHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\treturn ' '.join(n.tags) if n.tags else \"\"\n\nclass TagsHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\treturn ' '.join(n.shallow_tags) if n.shallow_tags else \"\"\n\nclass FilenameHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\treturn os.path.basename(n.env.filename)\n\nclass PropertyHandler(ColumnHandler):\n\tdef GetCellValue(self,n,params):\n\t\tv = n.get_property(self.name,None)\n\t\tif(not v):\n\t\t\tv = n.get_property(self.name.upper(),None)\n\t\t\tif(not v):\n\t\t\t\tv = n.get_property(self.name.lower(),\"\")\n\t\treturn v\n\nspecial_registry = {\n    #‘ITEM’\tThe headline of the entry.\n\t\"ITEM\":      ItemHandler,\n    #‘PRIORITY’\tThe priority of the entry, a string with a single letter.\n\t\"PRIORITY\":  PriorityHandler,\n    #‘CLOSED’\tWhen was this entry closed?\n\t\"CLOSED\":    ClosedHandler,\n    #‘SCHEDULED’\tThe scheduling timestamp.\n\t\"SCHEDULED\": ScheduledHandler,\n    #‘TODO’\tThe TODO keyword of the entry.\n\t\"TODO\":      TodoHandler,\n     #‘DEADLINE’\tThe deadline timestamp.\n\t\"DEADLINE\":  DeadlineHandler,\n     #‘ALLTAGS’\tAll tags, including inherited ones.\n\t\"ALLTAGS\":   AllTagsHandler,\n     #‘FILE’\tThe filename the entry is located in.\n\t\"FILE\":      FilenameHandler,\n     #‘TAGS’\tThe tags defined directly in the headline.\n\t\"TAGS\":      TagsHandler,\n\t #‘TIMESTAMP’\tThe first keyword-less timestamp in the entry.\n\t\"TIMESTAMP\":    TimestampHandler,\n     #‘TIMESTAMP_IA’\tThe first inactive timestamp in the entry.\n\t\"TIMESTAMP_IA\": IATimestampHandler,\n}\n\n#‘BLOCKED’\tt if task is currently blocked by children or siblings.\n#‘CATEGORY’\tThe category of an entry.\n#‘CLOCKSUM’\tThe sum of CLOCK intervals in the subtree. org-clock-sum\n#           must be run first to compute the values in the current buffer.\n#‘CLOCKSUM_T’\tThe sum of CLOCK intervals in the subtree for today.\n#               org-clock-sum-today must be run first to compute the\n#               values in the current buffer.\n\n#%[WIDTH]PROPERTY[(TITLE)][{SUMMARY-TYPE}]\nRE_PARSER = re.compile(r\"[%](?P<width>[0-9]+)?(?P<prop>[a-zA-Z][a-zA-Z0-9_-]+)([(](?P<heading>([a-zA-Z0-9 +-]|\\s)+)[)])?(?P<summary>[^ ())]+)?\")\ndef GetColumnDefinitions(f,node):\n\tcolumns = node.list_comment(\"COLUMNS\",[r\"%70ITEM(Task)\",r\"%17Effort(Effort)\"])\n\th = []\n\tfor item in columns:\n\t\tm = RE_PARSER.search(item)\n\t\tif(m):\n\t\t\twidth = m.group('width')\n\t\t\tif(width and width != \"\"):\n\t\t\t\twidth = int(width)\n\t\t\telse:\n\t\t\t\twidth = 0\n\t\t\tprop  = m.group('prop')\n\t\t\theading = m.group('heading')\n\t\t\tsummary = m.group('summary')\n\t\t\tif(prop in special_registry):\n\t\t\t\tcfactory = special_registry[prop]\n\t\t\telse:\n\t\t\t\tcfactory = PropertyHandler\n\t\t\tv = cfactory()\n\t\t\tv.Setup(width,prop,heading,summary)\n\t\t\th.append(v)\n\treturn h\n\ndef Execute(view, params):\n\t# This is the most crucial parameter it defines how\n\t# we will process nodes.\n\tid = params.Get('id',\"global\")\n\t# How far down the tree do we allow?\n\tmaxdepth = params.GetInt('maxdepth',0)\n\t# We accumulate output in here line by line for insertion\n\t# into the main buffer.\n\toutput = []\n\t# By default we operate in the current file off the current view\n\t# Look it up in the DB. This will also reload it if it is dirty.\n\tfile = db.Get().FindInfo(view)\n\tif(file):\n\t\tnode = db.Get().AtInView(view)\n\t\tdefs = GetColumnDefinitions(file,node)\n\t\tr = file.org\n\t\t# Local we search up till we find the node parent that is not the root\n\t\tif(id == 'local'):\n\t\t\tif(node):\n\t\t\t\twhile(node and node.parent and node.parent.parent):\n\t\t\t\t\tnode = node.parent\n\t\t\t\tr = node\n\t\t# Operate on all children of the root (default)\n\t\telif(id == 'global'):\n\t\t\tpass\n\t\t# Operate on the root of another file in the db\n\t\telif('file:' in id):\n\t\t\tfiles = id.split(':')\n\t\t\tfile = db.Get().FindFileByFilename(files[1].strip())\n\t\t\tr = file.org\n\t\t# Operate on a node marked with an ID or CUSTOM_ID\n\t\t# ONLY if found in the DB.\n\t\telse:\n\t\t\tr = db.Get().FindNodeByAnyId(id)\n\n\t\t# Output the headings of our table based on the fields and handlers\n\t\t# we found in our COLUMNS definition.\n\t\tHandleHeadings(defs,output)\n\t\t# If we had a root, run over it and process it's children\n\t\t# building up our output array.\n\t\toutarrays = []\n\t\tif(r):\n\t\t\tfor n in r.children:\n\t\t\t\tHandleItem(params,n,defs,outarrays,1,maxdepth)\n\t# Did we get some output? return it\n\tif(len(outarrays) > 0):\n\t\tfor o in outarrays:\n\t\t\tout = \"|\" + '|'.join(o) + \"|\"\n\t\t\toutput.append(out)\n\t\treturn output\n\t# Nope add a generic error so we know we failed getting output at all...\n\toutput.append(\"|NO COLUMNVIEW DATA|\")\n\treturn output\n\ndef PostExecute(view, params, region):\n\t# We wrote our data to the buffer, get the TableEditor to\n\t# align our data for us.\n\trow,col = view.rowcol(view.sel()[0].begin())\n\tview.sel().clear()\n\tview.sel().add(view.text_point(row+1,col))\n\tview.run_command(\"table_editor_next_field\")\n"
  },
  {
    "path": "orgdynamic/insertdatetime.py",
    "content": "import sublime\nimport datetime\n\ndef Execute(view, params):\n\treturn [str(datetime.datetime.now())]"
  },
  {
    "path": "orgdynamicblock.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcapture as capture\nimport OrgExtended.orglinks as links\nimport OrgExtended.orgclocking as clocking\nimport OrgExtended.orgextension as ext\nimport OrgExtended.pymitter as evt\nfrom   OrgExtended.orgplist import *\nimport importlib\n\nlog = logging.getLogger(__name__)\n\n\nRE_END = re.compile(r\"^\\s*\\#\\+(END|end)[:]\")\nRE_DYN_BLOCK = re.compile(r\"^\\s*\\#\\+(BEGIN|begin)[:]\\s+(?P<name>[^: ]+)\\s*\")\nRE_FN_MATCH = re.compile(r\"\\s+[:]([a-zA-Z][a-zA-Z0-9-_]+)\\s+(([^ ()]+)|([(][^)]+[)]))\")\n\n\ndef IsDynamicBlock(view):\n\tline = view.getLine(view.curRow())\n\treturn RE_DYN_BLOCK.search(line) or RE_END.search(line)\n\nclass OrgExecuteDynamicBlockCommand(sublime_plugin.TextCommand):\n\tdef on_replaced(self):\n\t\tif(hasattr(self.curmod,\"PostExecute\")):\n\t\t\tself.curmod.PostExecute(self.view, self.params, self.region)\n\n\tdef run(self, edit):\n\t\tview = self.view\n\t\tat = view.sel()[0]\n\t\tif(view.match_selector(at.begin(),'orgmode.fence.dynamicblock')):\n\t\t\t# Okay we have a dynamic block, now we need to know where it ends.\n\t\t\tstart = at.begin()\n\t\t\tend   = None\n\t\t\terow = view.endRow()\n\t\t\trow  = view.curRow()\n\t\t\tfor rw in range(row,erow+1):\n\t\t\t\tline = view.substr(view.line(view.text_point(rw,0)))\n\t\t\t\tif(RE_END.search(line)):\n\t\t\t\t\tend = rw\n\t\t\t\t\tbreak\n\t\t\tif(not end):\n\t\t\t\tlog.debug(\"Could not locate #+END: tag\")\n\t\t\t\treturn\n\t\t\t# Okay now we have a start and end to build a region out of.\n\t\t\t# time to run a command and try to get the output.\n\t\t\tdynamic = ext.find_extension_modules('orgdynamic', [\"insertdatetime\", \"clocktable\", \"columnview\"])\n\t\t\tline = view.substr(view.line(start))\n\t\t\tm = RE_DYN_BLOCK.search(line)\n\t\t\tif(not m):\n\t\t\t\tlog.error(\"FAILED TO PARSE DYNAMIC BLOCK: \" + line)\n\t\t\t\treturn\n\t\t\tfnname = m.group('name')\n\t\t\t#log.debug(\"DYN NAME: \" + fnname)\n\t\t\tparams = PList.createPList(line[len(m.group(0)):])\n\t\t\t# Now find me that function!\n\t\t\tif(fnname not in dynamic):\n\t\t\t\tlog.error(\"Function not found in dynamic folder! Cannot execute!\")\n\t\t\t\treturn\n\t\t\t# Run the \"writer\"\n\t\t\tif(hasattr(dynamic[fnname],\"Execute\")):\n\t\t\t\tself.curmod = dynamic[fnname]\n\t\t\t\tself.params = params\n\t\t\t\toutputs = self.curmod.Execute(view, params)\n\t\t\t\t#log.debug(\"OUTPUT: \" + str(outputs))\n\n\t\t\t# Okay now time to replace the contents of the block\n\t\t\ts = view.text_point(row+1,0)\n\t\t\te = view.text_point(end,0)\n\t\t\tself.region = sublime.Region(s,e)\n\t\t\t# Reformat adding indents to each line!\n\t\t\t# No bad formatting allowed!\n\t\t\tn = db.Get().AtInView(view)\n\t\t\tlevel = n.level\n\t\t\tindent = \"\\n\"+ (\" \" * level) + \" \"\n\t\t\t#outputs = output.split('\\n')\n\t\t\toutput = indent.join(outputs)\n\t\t\tprint(output)\n\t\t\tself.view.run_command(\"org_internal_replace\", {\"start\": s, \"end\": e, \"text\": (\" \" * level + \" \") + output+\"\\n\",\"onDone\": evt.Make(self.on_replaced)})\n\t\telse:\n\t\t\tlog.error(\"NOT in A DynamicBlock, nothing to run\")\n"
  },
  {
    "path": "orgediting.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.loader as loader\nimport OrgExtended.orgparse.node as node\nimport OrgExtended.orgparse.date as orgdate\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orgproperties as props\nimport OrgExtended.orgdatepicker as datep\nimport OrgExtended.orginsertselected as insSel\nimport OrgExtended.orglinks as orglink\nimport OrgExtended.orgneovi as nvi\nimport OrgExtended.orgagenda as oa\nimport OrgExtended.orgcheckbox as checkbox\nimport OrgExtended.orgnumberedlist as numberedlist\n\nlog = logging.getLogger(__name__)\n\n# MOVING TO ANY DONE STATE:\n# Support these:\n#+STARTUP: lognotedone   Prompt and stored below the item with a Closing Note heading.\n#+STARTUP: logdone       CLOSED: [TIMESTAMP] in LOGBOOK\n# As well as configuration options\n#\n# PER TRANSITON MOVEMENT:\n# @ - note\n# ! - timestamp\n# / - when leaving the state if next state doesn't log\n#\n# Then they go futher with: :LOGGING: WAIT(@) logrepeat properties\n#\n# - 1) We need the transitions recorded in the node (in the todos list)\n# - 2) We need a method to insert CLOSED: and or prompt and note\n# - 3) We need to track the state transitions themselves (from / to)\n#\n# - 4) Habits break all this with LAST_REPEAT and To From transition text.\n# \n\n\nRE_CLOSED = re.compile(r\"^\\s*CLOSED:\\s*\\[.*\\]\")\ndef LocateClosed(view,node):\n    for row in range(node.start_row, node.local_end_row + 1):\n        pt = view.text_point(row,0)\n        line = view.line(pt)\n        lstr = view.substr(line)\n        m = RE_CLOSED.search(lstr)\n        if(m):\n            return line\n    return None\n\ndef InsertClosed(view, node, onDone=None):\n    stamp = OrgDate.format_clock(datetime.datetime.now(),active=False)\n    closedPt = LocateClosed(view,node)\n    if(closedPt):\n        text = node.indent() + \"CLOSED: \" + stamp\n        view.ReplaceRegion(closedPt, text, onDone)\n    else:\n        row = node.start_row+1\n        pt = view.text_point(row,0)\n        newline = \"\\n\" if view.isBeyondLastRow(row) else \"\"\n        text = newline + node.indent() + \"CLOSED: \" + stamp + \"\\n\"\n        view.Insert(pt, text, onDone)\n        #props.UpdateLogbook(view,node, \"CLOSED:\", stamp)\n\ndef RemoveClosed(view, node, onDone=None):\n    closedPt = LocateClosed(view, node)\n    if(closedPt):\n        view.ReplaceRegion(closedPt.IncEnd(),\"\",onDone)\n        #view.run_command(\"org_internal_replace\", {\"start\": closedPt.begin(), \"end\": closedPt.end() + 1, \"text\": \"\", \"onDone\": onDone})\n    else:\n        evt.EmitIf(onDone)\n\ndef IsDoneState(node, toState):\n    return toState in node.env.done_keys\n\ndef ShouldRecur(node, fromState, toState):\n    if(IsDoneState(node, toState)):\n        if(node.scheduled and node.scheduled.repeating):\n            return node.scheduled\n        if(node.deadline and node.deadline.repeating):\n            return node.deadline\n        timestamps = node.get_timestamps(active=True,point=True,range=True)\n        for t in timestamps:\n            if(t and t.repeating):\n                return t\n    return None\n\ndef ShouldClose(node, fromState, toState):\n    if(ShouldRecur(node,fromState,toState)):\n        return False\n    # NOTE: We need to get the todo transitions\n    #       into this as well!\n    toState = toState.strip()\n    startup = node.root.startup()\n    logDone = sets.Get(\"logDone\",None)\n    if(IsDoneState(node, toState) and (Startup.logdone in startup or logDone)):\n        return True\n\ndef InsertRecurrence(view, node, fromState, toState, onDone=None):\n    #   - State \"DONE\"       from \"TODO\"       [2009-09-29 Tue]\"\n    stamp = OrgDate.format_clock(datetime.datetime.now(),active=False)\n    def OnLogAdded():\n        props.UpdateProperty(view, node, \"LAST_REPEAT\", stamp, onDone)\n    props.AddLogbook(view,node, \"- State {0:12} from {1:12} \".format('\"' + toState + '\"', '\"' + fromState + '\"'), stamp, evt.Make(OnLogAdded))\n\ndef InsertNote(view, node, text, fromState, toState, onDone=None):\n    stamp = OrgDate.format_clock(datetime.datetime.now(),active=False)\n    props.AddLogbook(view,node, \"Note (to:{0},at:{1}): \".format(toState,stamp), text, onDone)\n\ndef ShouldNote(node, fromState, toState):\n    if(ShouldRecur(node,fromState,toState)):\n        return False\n    # NOTE: We need to get the todo transitions\n    #       into this as well!\n    toState = toState.strip()\n    startup = node.root.startup()\n    if(IsDoneState(node,toState) and Startup.lognotedone in startup):\n        return True\n\n\n\nRE_T = re.compile(r'\\s(?P<time><\\s*\\d+-\\d+-\\d+\\s+[^>]+>)(\\s+|$)')\n# Use a menu to change the todo state of an item\nclass OrgTodoChangeCommand(sublime_plugin.TextCommand):\n    def on_totally_done(self):\n        evt.EmitIf(self.onDone)\n\n    # recurrence needs to update the base timestamp!\n    # This needs to respect the .+ ++ and + markers\n    def on_update_timestamps_if_needed(self, row=0):\n        # We have to reload our node as we updated things.\n        self.node = db.Get().At(self.view, self.node.start_row)\n        if(row > (self.node.local_end_row+1)):\n            self.on_totally_done()\n        for i in range(self.node.start_row+row, self.node.local_end_row+1):\n            pt = self.view.text_point(i, 0)\n            line = self.view.line(pt)\n            txt = self.view.substr(line)\n            m = RE_T.search(txt)\n            now = datetime.datetime.now()\n            if(m):\n                tsl = OrgDate.list_from_str(m.group('time'))\n                if(tsl):\n                    t = tsl[0]\n                    if(t.repeating):\n                        next  = t.start\n                        next2 = t.end\n                        if(t.repeatpre == \"+\"):\n                            next = t.next_repeat_from(oa.EnsureDateTime(next))\n                        elif(t.repeatpre == \"++\"):\n                            while(next < now):\n                                next = t.next_repeat_from(oa.EnsureDateTime(next))\n                        elif(t.repeatpre == \".+\"):\n                            next = t.next_repeat_from(now)\n                        s = m.start(1)\n                        e = m.end(1)\n                        rpt = t.repeatpre + str(t.repeatnum) + t.repeatdwmy\n                        wrn = \"\"\n                        if(t.warning):\n                            wrn = \" \" + t.warnpre + str(t.warnnum) + t.warndwmy\n                        if(t.has_end()):\n                            if(t.has_time()):\n                                nout = txt[:s] + next.strftime(\"<%Y-%m-%d %a %H:%M-\") + t.end.strftime(\"%H:%M \")+ rpt + wrn + \">\"  + txt[e:]\n                            else:\n                                # This really shouldn't happen.\n                                nout = txt[:s] + next.strftime(\"<%Y-%m-%d %a \")+ rpt + wrn + \">\" + txt[e:]\n                        else:\n                            if(t.has_time()):\n                                nout = txt[:s] + next.strftime(\"<%Y-%m-%d %a %H:%M \") + rpt + wrn + \">\" +txt[e:]\n                            else:\n                                nout = txt[:s] + next.strftime(\"<%Y-%m-%d %a \")+ rpt + wrn + \">\" + txt[e:]\n                        self.view.run_command(\"org_internal_replace\", {\"start\": line.begin(), \"end\": line.end(), \"text\": nout, \"onDone\": evt.Make(lambda:self.on_update_timestamps_if_needed(i+1)) })\n                        return\n        self.on_totally_done()\n\n    def do_recurrence_if_needed(self):\n        self.rec = ShouldRecur(self.node,self.fromState,self.newState)\n        if(self.rec):\n            InsertRecurrence(self.view, self.node, self.fromState, self.newState, evt.Make(self.on_update_timestamps_if_needed))\n        else:\n            self.on_totally_done()\n\n    def do_close_if_needed(self):\n        if(ShouldClose(self.node,self.fromState,self.newState)):\n            InsertClosed(self.view, self.node, evt.Make(self.do_recurrence_if_needed))\n        else:\n            RemoveClosed(self.view, self.node, evt.Make(self.do_recurrence_if_needed))\n\n    def on_insert_note(self, text):\n        InsertNote(self.view, self.node, text, self.fromState, self.newState, evt.Make(self.do_close_if_needed))\n\n    def do_note_if_needed(self):\n        if(ShouldNote(self.node,self.fromState, self.newState)):\n            self.view.window().show_input_panel(\"(\"+self.fromState + \">>\" + self.newState + \") Note:\",\"\", self.on_insert_note, None, None)\n        else:\n            self.do_close_if_needed()\n\n    def on_done_st4(self,index,modifers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        if(index < 0):\n            return\n        newState = self.todoStates[index]\n        if(newState == \"none\"):\n            newState = \"\"\n        # if we don't have a TODO state then we have to handle that as well.\n        m = self.todoRe.search(self.bufferContents)\n        fromState = None\n        if(m == None):\n            self.todoRe = re.compile(r\"^([*]+ (\\[\\#[a-zA-Z0-9]+\\]\\s+)?)( )*\")\n        else:\n            fromState = m.group(3)\n        if(newState != \"\"):\n            newState += \" \"\n        self.bufferContents = self.todoRe.sub(r\"\\g<1>\" + newState, self.bufferContents)\n        # We have to do the editing in sequence because the reloads can get mixed up otherwise\n        if(fromState):\n            self.fromState = fromState.strip()\n        else:\n            self.fromState = \"\"\n        self.newState  = newState.strip()\n        # Recurring events do not hit the done state when you toggle them\n        # They bounce back to TODO they just get a new note in them\n        if(ShouldRecur(self.node, self.fromState,self.newState)):\n            self.do_note_if_needed()\n        else:\n            self.view.ReplaceRegion(self.row,self.bufferContents, evt.Make(self.do_note_if_needed))\n\n    def run(self, edit, onDone=None):\n        self.onDone = onDone\n        self.node = db.Get().AtInView(self.view)\n        #self.todoStates = sets.Get(\"todoStates\", sets.defaultTodoStates)\n        todos = self.node.env.all_todo_keys\n        if(len(todos) > 0):\n            self.todoStates = todos\n            self.todoStates += [\"none\"]\n        else:\n            for i in range(0, len(self.todoStates)):\n                if(self.todoStates[i] == \"|\"):\n                    self.todoStates[i] = \"none\" \n        # ACTION vs DONE states\n        # TODO\" \"FEEDBACK\" \"VERIFY\" \"|\" \"DONE\" \"DELEGATED\n        row = self.node.start_row\n        self.todoRe = r\"^([*]+ (\\[\\#[a-zA-Z0-9]+\\]\\s+)?)(\"\n        haveFirst = False\n        for state in self.todoStates:\n            if state != \"|\":\n                if(haveFirst):\n                    self.todoRe += \"|\"\n                self.todoRe += state\n                haveFirst = True\n        self.todoRe += r\")( )*\"\n        self.todoRe = re.compile(self.todoRe)\n        sp  = self.view.text_point(row,0)\n        self.row = self.view.line(sp)\n        self.bufferContents = self.view.substr(self.row)\n        if(int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(self.todoStates, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(self.todoStates, self.on_done_st4, -1, -1)\n\n# Use a menu to change the priority of an item\nclass OrgPriorityChangeCommand(sublime_plugin.TextCommand):\n    def on_done_st4(self,index,modifers):\n        self.on_done(index)\n    def on_done(self, index):\n        if(index < 0):\n            return\n        newState = self.priorities[index]\n        if(newState == \"none\"):\n            newState = \"\"\n        # if we don't have a TODO state then we have to handle that as well.\n        m = self.Re.search(self.bufferContents)\n        if(m == None):\n            todos = self.node.env.all_todo_keys\n            todos = '|'.join(todos)\n            self.Re = re.compile(r\"^([*]+\\s+(\" + todos + r\")?\\s*)( )*\")\n        if(newState != \"\"):\n            newState = \"[#\" + newState + \"] \" \n        self.bufferContents = self.Re.sub(r\"\\g<1>\" + newState, self.bufferContents)\n        self.view.ReplaceRegion(self.row, self.bufferContents, self.onDone)\n        #self.view.run_command(\"org_internal_replace\", {\"start\": self.row.begin(), \"end\": self.row.end(), \"text\": self.bufferContents, \"onDone\": self.onDone})\n        #self.view.replace(self.edit, self.row, self.bufferContents)\n\n    def run(self, edit, onDone = None):\n        self.onDone = onDone\n        self.node = db.Get().AtInView(self.view)\n        self.priorities = self.node.priorities()\n        self.priorities = copy.copy(self.priorities)\n        self.priorities.append(\"none\")\n        row = self.node.start_row\n        self.Re = r\"^([*]+ [^\\[\\]]*\\s*)(\\[\\#[a-zA-Z0-9]+\\]\\s+)\"\n        self.Re = re.compile(self.Re)\n        sp  = self.view.text_point(row,0)\n        self.row = self.view.line(sp)\n        self.bufferContents = self.view.substr(self.row)\n        if(int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(self.priorities, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(self.priorities, self.on_done_st4, -1, -1)\n\ndef indent_node(view, node, edit):\n    # Indent the node itself\n    sp  = view.text_point(node.start_row,0)\n    view.insert(edit,sp,\"*\")\n    # Indent MY content\n    for i in range(node.start_row+1,node.local_end_row+1):\n        sp  = view.text_point(i,0)\n        view.insert(edit,sp,\" \")\n    # Find my children and indent them.\n    for n in node.children:\n        indent_node(view, n, edit)\n\ndef indent_list(view, row, edit):\n    # Indent the node itself\n    sp  = view.text_point(row,0)\n    view.insert(edit,sp,\"  \")\n\n    line = view.lineAt(row)\n    children,crow = numberedlist.findChildrenByIndent(view, line)\n    for r in range(row+1,crow):\n        sp  = view.text_point(r,0)\n        view.insert(edit,sp,\"  \")\n\ndef deindent_list(view, row, edit):\n    # Get my position and ensure this node CAN de-indent\n    sp  = view.text_point(row,0)\n    ep  = view.text_point(row,1)\n    np  = view.text_point(row,2)\n    bufferContents = view.substr(sublime.Region(sp,np))\n    bufferContentsS = view.substr(sublime.Region(sp,ep))\n    wasTab = bufferContentsS == \"\\t\"\n    if(bufferContents == \"  \" or wasTab):\n        if(wasTab):\n            view.erase(edit,sublime.Region(sp,ep))\n        else:\n            view.erase(edit,sublime.Region(sp,np))\n        line = view.lineAt(row)\n        children,crow = numberedlist.findChildrenByIndent(view, line)\n        for r in range(row+1,crow):\n            sp  = view.text_point(r,0)\n            ep  = view.text_point(r,1)\n            np  = view.text_point(r,2)\n            bufferContents = view.substr(sublime.Region(sp,np))\n            bufferContentsS = view.substr(sublime.Region(sp,ep))\n            wasTab = bufferContentsS == \"\\t\"\n            if(bufferContents == \"  \" or wasTab):\n                if(wasTab):\n                    view.erase(edit,sublime.Region(sp,ep))\n                else:\n                    view.erase(edit,sublime.Region(sp,np))\n\ndef deindent_node(view, node, edit):\n    # Get my position and ensure this node CAN de-indent\n    sp  = view.text_point(node.start_row,0)\n    ep  = view.text_point(node.start_row,1)\n    np  = view.text_point(node.start_row,2)\n    bufferContents = view.substr(sublime.Region(ep,np))\n    if(bufferContents == \"*\"):\n        view.erase(edit,sublime.Region(sp,ep))\n        # Now erase a space at the front of my contents.\n        for i in range(node.start_row+1,node.local_end_row+1):\n            sp  = view.text_point(i,0)\n            ep  = view.text_point(i,1)\n            bufferContents = view.substr(sublime.Region(sp,ep))\n            if(bufferContents == \" \" or bufferContents == \"\\t\"):\n                view.erase(edit,sublime.Region(sp,ep))\n        for n in node.children:\n            deindent_node(view, n, edit)\n    else:\n        log.debug(\"Did not get star, not deindenting it \" + str(len(bufferContents)) + \" \" + bufferContents)\n\n# Thing is a region, and first line of the thing tuple\n# things is a list of thing\ndef sort_things_alphabetically(things,reverse=False):\n    things.sort(key=lambda thing: thing[1],reverse=reverse)\n\n\nclass OrgSortListCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        # Get a list of things\n        things = None\n        wasNumbered = False\n        if(numberedlist.isNumberedLine(self.view)):\n            wasNumbered = True\n            things = numberedlist.getListAtPointForSorting(self.view)\n        elif(checkbox.isUnorderedList(self.view.getLine(self.view.curRow()))):\n            things = checkbox.getListAtPointForSorting(self.view)\n        if(not things):\n            log.error(\" Could not sort at point\")\n            return\n        # Build macro region\n        start = things[0][0][0]\n        end   = things[len(things)-1][0][1]\n        sp  = self.view.text_point(start,0)\n        ep  = self.view.text_point(end,0)\n        ep  = self.view.line(ep).end()\n        reg = sublime.Region(sp,ep)\n\n        # Sort the things\n        sort_things_alphabetically(things)\n\n        # Copy from macro region to sorted version\n        buffer = \"\"\n        for thing in things:\n            bs = self.view.text_point(thing[0][0],0)\n            be = self.view.text_point(thing[0][1]-1,0)\n            be = self.view.line(be).end()\n            breg = sublime.Region(bs,be)\n            ss = self.view.substr(breg).rstrip() + \"\\n\"\n            buffer += ss\n        # Replace the macro region with new str\n        self.view.replace(edit, reg, buffer)\n        if(wasNumbered):\n            self.view.run_command('org_update_numbered_list')\n        pass\n\n\n\nclass OrgSelectSubtreeCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        curNode = db.Get().AtInView(self.view)\n        if(curNode and type(curNode) != node.OrgRootNode and curNode._index > 1):\n            sp    = self.view.text_point(curNode.start_row, 0)\n            ep    = self.view.text_point(curNode.end_row, 0)\n            r     = self.view.line(ep)\n            reg   = sublime.Region(sp, r.end()+1)\n            self.view.sel().clear()\n            self.view.sel().add(reg)\n\nclass OrgCopySubtreeCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        curNode = db.Get().AtInView(self.view)\n        if(curNode and type(curNode) != node.OrgRootNode and curNode._index > 1):\n            sp    = self.view.text_point(curNode.start_row, 0)\n            ep    = self.view.text_point(curNode.end_row, 0)\n            r     = self.view.line(ep)\n            reg   = sublime.Region(sp, r.end()+1)\n            nodetext = self.view.substr(reg)\n            sublime.set_clipboard(nodetext)\n            nvi.TestAndSetClip(self.view, nodetext)\n\nclass OrgSelectEntityCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        curNode = db.Get().AtInView(self.view)\n        if(curNode and type(curNode) != node.OrgRootNode and curNode._index > 1):\n            sp    = self.view.text_point(curNode.start_row, 0)\n            ep    = self.view.text_point(curNode.local_end_row, 0)\n            r     = self.view.line(ep)\n            reg   = sublime.Region(sp, r.end()+1)\n            self.view.sel().clear()\n            self.view.sel().add(reg)\n\nclass OrgCopyEntityCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        curNode = db.Get().AtInView(self.view)\n        if(curNode and type(curNode) != node.OrgRootNode and curNode._index > 1):\n            sp    = self.view.text_point(curNode.start_row, 0)\n            ep    = self.view.text_point(curNode.local_end_row, 0)\n            r     = self.view.line(ep)\n            reg   = sublime.Region(sp, r.end()+1)\n            nodetext = self.view.substr(reg)\n            sublime.set_clipboard(nodetext)\n            nvi.TestAndSetClip(self.view, nodetext)\n\nclass OrgCopyLinkHrefCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        if(self.view.match_selector(self.view.sel()[0].begin(), \"orgmode.link\")):\n            pt = self.view.sel()[0].end()\n            links = self.view.find_by_selector(\"orgmode.link\")\n            hrefs = self.view.find_by_selector(\"orgmode.link.href\")\n            reg = None\n            for link in links:\n                line = self.view.line(link.begin())\n                if(line.contains(pt)):\n                    for href in hrefs:\n                        if(line.contains(href.begin())):\n                            reg = href\n                            break\n                    break\n            if(reg):\n                nodetext = self.view.substr(reg)\n                sublime.set_clipboard(nodetext)\n                nvi.TestAndSetClip(self.view, nodetext)\n\nclass OrgSelectLinkHrefCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        if(self.view.match_selector(self.view.sel()[0].begin(), \"orgmode.link\")):\n            pt = self.view.sel()[0].end()\n            links = self.view.find_by_selector(\"orgmode.link\")\n            hrefs = self.view.find_by_selector(\"orgmode.link.href\")\n            reg = None\n            for link in links:\n                line = self.view.line(link.begin())\n                if(line.contains(pt)):\n                    for href in hrefs:\n                        if(line.contains(href.begin())):\n                            reg = href\n                            break\n                    break\n            if(reg):\n                self.view.sel().clear()\n                self.view.sel().add(reg)\n\nclass OrgMoveHeadingUpCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        curNode = db.Get().AtInView(self.view)\n        if(curNode and type(curNode) != node.OrgRootNode and curNode._index > 1):\n            targetNode = curNode.get_sibling_up()\n            if(targetNode):\n                index = targetNode._index - 1\n                r,c   = self.view.curRowCol()\n                sp    = self.view.text_point(curNode.start_row, 0)\n                ep    = self.view.text_point(curNode.end_row, 0)\n                r     = self.view.line(ep)\n                reg   = sublime.Region(sp, r.end()+1)\n\n                nodetext = self.view.substr(reg)\n                sp    = self.view.text_point(targetNode.start_row, 0)\n                treg   = sublime.Region(sp, sp)\n\n                self.view.erase(edit,reg)\n                self.view.insert(edit,sp,nodetext)\n                self.view.sel().clear()\n                np = self.view.text_point(targetNode.start_row, c)\n                self.view.sel().add(np)\n\nclass OrgMoveHeadingDownCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        curNode = db.Get().AtInView(self.view)\n        if(curNode and type(curNode) != node.OrgRootNode and curNode._index < (len(curNode.env._nodes) - 1)):\n            targetNode = curNode.get_sibling_down()\n            if(targetNode):\n                temp = curNode\n                curNode = targetNode\n                targetNode = temp\n                index = targetNode._index - 1\n                sp    = self.view.text_point(curNode.start_row, 0)\n                ep    = self.view.text_point(curNode.end_row, 0)\n                r     = self.view.line(ep)\n                reg   = sublime.Region(sp, r.end()+1)\n\n                nodetext = self.view.substr(reg)\n                sp    = self.view.text_point(targetNode.start_row, 0)\n                treg   = sublime.Region(sp, sp)\n                endline = self.view.line(self.view.size())\n\n                if(curNode.is_last_node() and curNode.end_row >= self.view.endRow()):\n                    line = self.view.substr(self.view.line(self.view.text_point(self.view.endRow(),0)))\n                    isEmpty = line.strip() == \"\"\n                    if(not isEmpty):\n                        nodetext = nodetext + \"\\n\"\n                self.view.erase(edit,reg)\n                self.view.insert(edit,sp,nodetext)\n\nclass OrgInsertHeadingSiblingCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        curNode = db.Get().AtInView(self.view)\n        needsNewline = False\n        if(not curNode):\n            level = 1\n            here = sublime.Region(self.view.size(),self.view.size())\n            reg  = here\n            text = self.view.substr(self.view.line(reg))\n            if(text.strip() != \"\"):\n                needsNewline = True\n        else:\n            level = curNode.level\n            reg = curNode.region(self.view,True)  # trim ending whitespace\n            if(level == 0):\n                level = 1\n                here = sublime.Region(self.view.size(),self.view.size())\n                text = self.view.substr(self.view.line(reg))\n                if(text.strip() != \"\"):\n                    needsNewline = True\n            else:\n                here = sublime.Region(reg.end(),reg.end())\n                text = self.view.substr(self.view.line(here))\n                if(text.strip() != \"\"):\n                    needsNewline = True\n        self.view.sel().clear()\n        self.view.sel().add(reg.end())\n        self.view.show(here)\n        if(needsNewline):\n            self.view.insert(edit,self.view.sel()[0].begin(),'\\n')\n        ai = sublime.active_window().active_view().settings().get('auto_indent')\n        self.view.settings().set('auto_indent',False)\n        self.view.run_command(\"insert_snippet\", {\"name\" : \"Packages/OrgExtended/orgsnippets/heading\"+str(level)+\".sublime-snippet\"})\n        sublime.active_window().active_view().settings().set('auto_indent',ai)\n        \nclass OrgInsertHeadingChildCommand(sublime_plugin.TextCommand):\n    def run(self, edit, onDone=None):\n        curNode = db.Get().AtInView(self.view)\n        needsNewline = False\n        if(not curNode):\n            file = db.Get().FindInfo(self.view)\n            if(len(file.org) > 0):\n                curNode = file.org[len(file.org) - 1]\n        if(not curNode):\n            level = 1\n            l = self.view.line(self.view.size())\n            reg = sublime.Region(l.begin(),l.begin())\n            reg  = here\n        else:\n            level = curNode.level\n            reg = curNode.region(self.view, True)\n            if(level == 0):\n                level = 1\n                here = sublime.Region(view.size(),view.size())\n            else:\n                here = sublime.Region(reg.end(),reg.end())\n                text = self.view.substr(self.view.line(here))\n                if(text.strip() != \"\"):\n                    needsNewline = True\n        if(not needsNewline):\n            ll = self.view.line(reg.end())\n            text = self.view.substr(ll)\n            if(text.strip() == \"\" and len(text) > 0):\n                # This is an empty line! Have to work at the front of this line!\n                # Or we will insert to an odd location!\n                reg = sublime.Region(ll.begin(), ll.begin())\n        self.view.sel().clear()\n        self.view.sel().add(reg.end())\n        self.view.show(here)\n        if(needsNewline):\n            self.view.insert(edit,self.view.sel()[0].begin(),'\\n')\n        ai = sublime.active_window().active_view().settings().get('auto_indent')\n        self.view.settings().set('auto_indent',False)\n        self.view.run_command(\"insert_snippet\", {\"name\" : \"Packages/OrgExtended/orgsnippets/heading\"+str((level+1))+\".sublime-snippet\"})\n        sublime.active_window().active_view().settings().set('auto_indent',ai)\n        evt.EmitIf(onDone)\n\n# This will insert whatever text you provide as a child heading of the current node\nclass OrgInsertTextAsChildHeadingCommand(sublime_plugin.TextCommand):\n    def run(self, edit, heading=None, onDone=None):\n        curNode = db.Get().AtInView(self.view)\n        if(not curNode):\n            file = db.Get().FindInfo(self.view)\n            if(len(file.org) > 0):\n                curNode = file.org[len(file.org) - 1]\n        if(not curNode):\n            level = 1\n            l = self.view.line(self.view.size())\n            reg = sublime.Region(l.begin(),l.begin())\n            reg  = here\n        else:\n            level = curNode.level\n            reg = curNode.region(self.view)\n            if(level == 0):\n                level = 1\n                here = sublime.Region(view.size(),view.size())\n            else:\n                here = sublime.Region(reg.end(),reg.end())\n        self.view.sel().clear()\n        self.view.sel().add(reg.end()+1)\n        #self.view.show(here)\n        self.view.insert(edit,self.view.sel()[0].begin(),'\\n' + ('*'*(level+1)) + ' ' + heading)\n        evt.EmitIf(onDone)\n        \nclass OrgInsertTodayInactiveCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        now = datetime.datetime.now()\n        toInsert = orgdate.OrgDate.format_date(now, False)\n        self.view.insert(edit,self.view.sel()[0].begin(), toInsert)\n\nclass OrgInsertNowInactiveCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        now = datetime.datetime.now()\n        toInsert = orgdate.OrgDate.format_clock(now, False)\n        self.view.insert(edit,self.view.sel()[0].begin(), toInsert)\n\nclass OrgInsertTodayActiveCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        now = datetime.datetime.now()\n        toInsert = orgdate.OrgDate.format_date(now, True)\n        self.view.insert(edit,self.view.sel()[0].begin(), toInsert)\n\nclass OrgInsertNowActiveCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        now = datetime.datetime.now()\n        toInsert = orgdate.OrgDate.format_clock(now, True)\n        self.view.insert(edit,self.view.sel()[0].begin(), toInsert)\n\nclass OrgInsertDateInactiveCommand(sublime_plugin.TextCommand):\n    def insert(self, date):\n        if(date):\n            self.view.Insert(self.view.sel()[0].begin(), OrgDate.format_clock(date.start, active=False))\n\n    def run(self, edit):\n        datep.Pick(evt.Make(self.insert))\n\n\nclass OrgInsertDateActiveCommand(sublime_plugin.TextCommand):\n    def insert(self, date):\n        if(date):\n            self.view.Insert(self.view.sel()[0].begin(), OrgDate.format_clock(date.start, active=True))\n\n    def run(self, edit):\n        datep.Pick(evt.Make(self.insert))\n\n\nclass OrgBaseTimestampCommand(sublime_plugin.TextCommand):\n    def __init__(self,unknown=None, prefix=None):\n        super(OrgBaseTimestampCommand, self).__init__(unknown)\n        self.prefix = prefix\n\n    def insert(self, date):\n        if(date):\n            self.view.Insert(self.view.sel()[0].begin(), OrgDate.format_clock(date.start, active=True))\n        else:\n            self.view.Erase(self.reg)\n        self.view.sel().clear()\n        self.view.sel().add(self.oldsel)\n\n    def run(self, edit, dateval=None):\n        if(type(dateval) == str):\n            dateval = orgdate.OrgDateFreeFloating.from_str(dateval)\n        # TODO: Find scheduled and replace it as well.\n        node = db.Get().AtInView(self.view)\n        if(node and not node.is_root()):\n            self.oldsel = self.view.sel()[0]\n            pt = self.view.text_point(node.start_row,0)\n            l = self.view.line(pt)\n            # Last row handling If we are the last row we can't jump over the newline\n            # we have to add one.\n            nl = \"\"\n            addnl = 1\n            if(self.view.isBeyondLastRow(node.start_row+1)):\n                nl = \"\\n\"\n                addnl = 0\n            insertpt = l.end() + addnl\n            endpt = insertpt + len(nl) + len(node.indent()) + len(self.prefix)\n            self.reg = sublime.Region(insertpt, endpt)\n            self.view.insert(edit, insertpt, nl + node.indent() + self.prefix)\n            pt = self.view.text_point(node.start_row+1,0)\n            l = self.view.line(pt)\n            self.view.sel().clear()\n            self.view.sel().add(l.end())\n            if(dateval == None):\n                datep.Pick(evt.Make(self.insert))\n            else:\n                self.insert(dateval)\n\nclass OrgScheduleCommand(OrgBaseTimestampCommand):\n    def __init__(self,unknown=None):\n        super(OrgScheduleCommand, self).__init__(unknown,\"SCHEDULED:  \\n\")\n\nclass OrgDeadlineCommand(OrgBaseTimestampCommand):\n    def __init__(self,unknown=None):\n        super(OrgDeadlineCommand, self).__init__(unknown,\"DEADLINE:  \\n\")\n\nclass OrgActiveTimestampCommand(OrgBaseTimestampCommand):\n    def __init__(self,unknown=None):\n        super(OrgActiveTimestampCommand, self).__init__(unknown,\"  \\n\")\n\nclass OrgInsertClosedCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        node = db.Get().AtInView(self.view)\n        if(not node.is_root()):\n            self.oldsel = self.view.sel()[0]\n            pt = self.view.text_point(node.start_row,0)\n            l = self.view.line(pt)\n            # Last row handling If we are the last row we can't jump over the newline\n            # we have to add one.\n            nl = \"\"\n            addnl = 1\n            if(self.view.isBeyondLastRow(node.start_row+1)):\n                nl = \"\\n\"\n                addnl = 0\n            now = datetime.datetime.now()\n            toInsert = orgdate.OrgDate.format_clock(now, False)\n            self.view.insert(edit, l.end() + addnl, nl + node.indent() + \"CLOSED: \"+toInsert+\"\\n\")\n\ndef getTagColumn():\n    tagColumn = sets.Get(\"tagColumn\",70)\n    if not isinstance(tagColumn,int):\n        tagColumn = 70\n    elif tagColumn < 30:\n        tagColumn = 30\n    elif tagColumn > 150:\n        tagColumn = 150\n    return tagColumn\n\n# ================================================================================\nRE_TAGS = re.compile(r'^(?P<heading>[*]+((?![ \\t][:]).)+\\s*)(\\s+(?P<tags>[:]([^: ]+[:])+))?$')\nclass OrgInsertTagCommand(sublime_plugin.TextCommand):\n    def OnDone(self, text):\n        if(not text):\n            return\n        node = db.Get().AtInView(self.view)\n        if(node):\n            if not text in node.tags:\n                (region, line) = self.view.getLineAndRegion(node.start_row)\n                m = RE_TAGS.search(line)\n                if(m and m.group('tags') != None):\n                    tags = m.group('tags').strip() + text + \":\"\n                else:\n                    tags = \":\" + text + \":\" \n                tagColumn = getTagColumn()\n                print(\"{0:\"+str(tagColumn)+\"s}{1}\")\n                toline = (\"{0:\"+str(tagColumn)+\"s}{1}\").format(m.group('heading').strip(), tags)\n                self.view.ReplaceRegion(region,toline,self.onDone)\n            else:\n                log.debug(\"Tag already part of node\")\n                evt.EmitIf(self.onDone)\n\n    def run(self, edit, text=None, onDone=None):\n        self.onDone = onDone\n        self.text = text.strip() if text != None else text\n        if(self.text != None and self.text != \"\"):\n            self.OnDone(self.text)\n        else:\n            self.input = insSel.OrgInput()\n            self.input.run(\"Tag:\",db.Get().tags,evt.Make(self.OnDone))\n\n# ================================================================================\nclass OrgRemoveTagCommand(sublime_plugin.TextCommand):\n    def OnDone(self, text):\n        if(not text):\n            return\n        node = db.Get().AtInView(self.view)\n        if(node):\n            if text in node.tags:\n                (region, line) = self.view.getLineAndRegion(node.start_row)\n                m = RE_TAGS.search(line)\n                if(m and m.group('tags') != None):\n                    txt = m.group('tags')\n                    tgs = txt.split(':')\n                    tags = []\n                    for tag in tgs:\n                        tag = tag.strip()\n                        if tag != None and tag != \"\" and tag.lower() != text.lower():\n                            tags.append(tag)\n                    tagColumn = getTagColumn()\n                    if len(tags) > 0:\n                        tags = (\":\" + \":\".join(tags) + \":\").strip()\n                        toline = (\"{0:\"+str(tagColumn)+\"s}{1}\").format(m.group('heading').strip(), tags)\n                        self.view.ReplaceRegion(region,toline,self.onDone)\n                    else:\n                        toline = (\"{0:\"+str(tagColumn)+\"s}{1}\").format(m.group('heading').strip(), \"\")\n                        self.view.ReplaceRegion(region,toline,self.onDone)\n            else:\n                log.debug(\"Tag not part of node\")\n                evt.EmitIf(self.onDone)\n\n    def run(self, edit, text=None, onDone=None):\n        self.onDone = onDone\n        self.text = text.strip() if text != None else text\n        if(self.text != None and self.text != \"\"):\n            self.OnDone(self.text)\n        else:\n            self.ipt = insSel.OrgInput()\n            self.ipt.run(\"Tag:\",db.Get().tags,evt.Make(self.OnDone))\n\n# ================================================================================\nclass OrgRemoveAllTagsCommand(sublime_plugin.TextCommand):\n    def run(self, edit, text=None, onDone=None):\n        self.onDone = onDone\n        node = db.Get().AtInView(self.view)\n        if(node):\n            if len(node.tags) > 0:\n                (region, line) = self.view.getLineAndRegion(node.start_row)\n                m = RE_TAGS.search(line)\n                toline = (\"{0}\").format(m.group('heading'))\n                self.view.ReplaceRegion(region,toline,self.onDone)\n            else:\n                log.debug(\"Tags not part of node\")\n                evt.EmitIf(self.onDone)\n\n# ================================================================================\nclass OrgFixTagsCommand(sublime_plugin.TextCommand):\n    def run(self, edit, text=None, onDone=None):\n        self.onDone = onDone\n\n        file = db.Get().Find(self.view)\n        if file:\n            tagColumn = getTagColumn()\n            for node in file:\n                if(node):\n                    if len(node.tags) > 0:\n                        (region, line) = self.view.getLineAndRegion(node.start_row)\n                        m = RE_TAGS.search(line)\n                        if(m and m.group('tags') != None):\n                            txt = m.group('tags').strip()\n                            toline = (\"{0:\"+str(tagColumn)+\"s}{1}\").format(m.group('heading').strip(), txt)\n                            self.view.ReplaceRegion(region,toline,self.onDone)\n\n# ================================================================================\nclass OrgInsertArchiveTagCommand(sublime_plugin.TextCommand):\n    def OnDone(self):\n        evt.EmitIf(self.onDone)\n    def run(self, edit, onDone=None):\n        self.onDone = onDone\n        self.view.run_command(\"org_insert_tag\",{\"onDone\": evt.Make(self.OnDone), \"text\": \"ARCHIVE\"})\n\n# ================================================================================\nclass OrgInsertCustomIdCommand(sublime_plugin.TextCommand):\n    def on_done(self, text):\n        if(text):\n            # No spaces allowed in a custom id\n            text = text.replace(\" \",\"-\")\n            node = db.Get().AtInView(self.view)\n            if(node and not node.is_root()):\n               props.UpdateProperty(self.view,node,\"CUSTOM_ID\",text,self.onDone)\n\n    def run(self, edit, onDone=None):\n        self.onDone = onDone\n        self.input = insSel.OrgInput()\n        #print(str(db.Get().customids))\n        self.input.run(\"Custom Id:\",db.Get().customids, evt.Make(self.on_done))\n\n# ================================================================================\nclass OrgSetTodayCommand(sublime_plugin.TextCommand):\n    def run(self, edit, onDone=None):\n        self.onDone = onDone\n        idValue = \"TODAY\"\n        node = db.Get().AtInView(self.view)\n        if(not node or node.is_root()):\n            log.debug(\"Cannot update root node or non existent node as today\")\n            return\n        file, at = db.Get().FindByCustomId(idValue)\n        if(file != None and at != None):\n            node = file.At(at)\n            if(node):\n                props.RemoveProperty(self.view, node, \"CUSTOM_ID\")\n        node = db.Get().AtInView(self.view)\n        if(node and not node.is_root()):\n            props.UpdateProperty(self.view,node,\"CUSTOM_ID\",idValue,self.onDone)\n\n\ndef get_view_for_silent_edit_file(file):\n    # First check all sheets for this file.\n    window = sublime.active_window()\n    view = window.find_open_file(file.filename)\n    if(view):\n        return view\n    # Okay the file is not opened, we have to open it\n    # but we don't want it having focus\n    # So keep the old view so we can refocus just to\n    # be sure.\n    currentView = window.active_view()\n    view = window.open_file(file.filename, sublime.ENCODED_POSITION)\n    window.focus_view(currentView)\n    return view\n\n# ================================================================================\nclass RunEditingCommandOnToday:\n    def __init__(self, view, command, cmds = {}):\n        self.view    = view\n        self.command = command\n        self.cmds    = cmds\n\n    def onSaved(self):\n        db.Get().Reload(self.savedView)\n        evt.EmitIf(self.onDone)\n\n    def onEdited(self):\n        # NOTE the save here doesn't seem to be working\n        # Not sure why. BUT...\n        view = self.savedView\n        view.run_command(\"save\")\n        sublime.set_timeout_async(lambda: self.onSaved(), 100)\n\n    def onLoaded(self):\n        view = self.savedView\n        self.n.move_cursor_to(view)\n        eventName = util.RandomString()\n        evt.Get().once(eventName, self.onEdited)\n        log.debug(\"Trying to run: \" + self.command)\n        cmds = self.cmds\n        cmds[\"onDone\"] = eventName\n        view.run_command(self.command, cmds)\n\n    def Run(self,onDone = None):\n        self.onDone = onDone\n        idValue = \"TODAY\"\n        file, at = db.Get().FindByCustomId(idValue)\n        if(file != None and at != None):\n            node = file.At(at)\n            if(node):\n                self.n         = node\n                self.f         = file\n                self.savedView = get_view_for_silent_edit_file(file)\n                # Give time for the document to be opened.\n                sublime.set_timeout_async(lambda: self.onLoaded(), 200)\n                return\n            else:\n                log.warning(\"COULD NOT LOCATE TODAY\")\n        else:\n            log.warning(\"Could not locate today\")\n\n# Append text to a node\nclass OrgAppendTextCommand(sublime_plugin.TextCommand):\n    def run(self, edit, text=\"\", onDone=None):\n        curNode = db.Get().AtInView(self.view)\n        if(not curNode):\n            file = db.Get().FindInfo(self.view)\n            if(len(file.org) > 0):\n                curNode = file.org[len(file.org) - 1]\n        if(not curNode):\n            level = 1\n            l = self.view.line(self.view.size())\n            reg = sublime.Region(l.start(),l.start())\n            reg  = here\n        else:\n            level = curNode.level\n            reg = curNode.region(self.view)\n            if(level == 0):\n                level = 1\n                here = sublime.Region(view.size(),view.size())\n            else:\n                here = sublime.Region(reg.end(),reg.end())\n        self.view.sel().clear()\n        self.view.sel().add(reg.end() + 1)\n        #self.view.show(here)\n        self.view.insert(edit,self.view.sel()[0].begin(),'\\n' + (' '*(level*2)) + text)\n        evt.EmitIf(onDone)\n\nclass OrgLinkToTodayCommand(sublime_plugin.TextCommand):\n    def OnDone(self):\n        evt.EmitIf(self.onDone)\n\n    def InsertLink(self):\n        self.ed = RunEditingCommandOnToday(self.view, \"org_append_text\", {'text': self.link})\n        self.ed.Run(evt.Make(self.OnDone))\n\n    def run(self, edit, onDone=None):\n        self.onDone = onDone\n        # Schedule this item so it is in the agenda\n        self.view.run_command(\"org_schedule\", {\"dateval\": str(datetime.datetime.now())})\n        # Create a link to the current location so we can insert it in our today item\n        self.link = orglink.CreateLink(self.view)\n        curNode = db.Get().AtInView(self.view)\n        # Should we add a heading to this?\n        if(curNode and not curNode.is_root()):\n            self.ed = RunEditingCommandOnToday(self.view, \"org_insert_text_as_child_heading\", {'heading': curNode.heading})\n            self.ed.Run(evt.Make(self.InsertLink))\n        else:\n            self.InsertLink()\n\n\nclass OrgEnterOnHeadingCommand(sublime_plugin.TextCommand):\n    def run(self, edit, Indent=1):\n        indent = (\" \" * Indent) + \" \"\n        self.view.run_command(\"org_internal_insert\", {\"location\": self.view.sel()[0].begin(), \"text\": \"\\n\" + indent})\n"
  },
  {
    "path": "orgexporter.py",
    "content": "import sublime\nimport sublime_plugin\nimport re\nimport regex\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.asettings as sets\nimport OrgExtended.orgdb as db\nimport OrgExtended.orgparse.date as date\n\nlog = logging.getLogger(__name__)\n\nRE_TITLE = regex.compile(r\"^\\s*[#][+](TITLE|title)[:]\\s*(?P<data>.*)\")\nRE_AUTHOR = regex.compile(r\"^\\s*[#][+](AUTHOR|author)[:]\\s*(?P<data>.*)\")\nRE_NAME = regex.compile(r\"^\\s*[#][+](NAME|name)[:]\\s*(?P<data>.*)\")\nRE_DATE = regex.compile(r\"^\\s*[#][+](DATE|date)[:]\\s*(?P<data>.*)\")\nRE_EMAIL = regex.compile(r\"^\\s*[#][+](EMAIL|email)[:]\\s*(?P<data>.*)\")\nRE_LANGUAGE = regex.compile(r\"^\\s*[#][+](LANGUAGE|language)[:]\\s*(?P<data>.*)\")\n\n\n\ndef ExportFilename(view,extension,suffix=\"\"):\n    fn = view.file_name()\n    fn,ext = os.path.splitext(fn)\n    return fn + suffix + extension\n\ndef GetGlobalOption(file, name, settingsName, defaultValue):\n    value = sets.Get(settingsName, defaultValue)\n    value = ' '.join(file.org[0].get_comment(name, [str(value)]))\n    return value\n\n\nclass OrgExporter:\n\n    def __init__(self,filename,file,**kwargs):\n        self.file = file\n        self.fs   = open(filename,\"w\",encoding=\"utf-8\")\n        self.outputFilename = filename\n        self.InitExportComments()\n        self.PreScan()\n\n    def InitExportComments(self):\n        self.title    = None\n        self.author   = None\n        self.language = None\n        self.email    = None\n        self.date     = None\n        self.name     = None\n\n    def GetOption(self,name,settingsName,defaultValue):\n        return GetGlobalOption(self.file, name, settingsName, defaultValue)\n\n    def PreScanExportCommentsGather(self, l):\n        m = RE_TITLE.match(l)\n        if(m):\n            self.title = m.captures('data')[0]\n            return True\n        m = RE_AUTHOR.match(l)\n        if(m):\n            self.author = m.captures('data')[0]\n            return True\n        m = RE_LANGUAGE.match(l)\n        if(m):\n            self.language = m.captures('data')[0]\n            return True\n        m = RE_EMAIL.match(l)\n        if(m):\n            self.email = m.captures('data')[0]\n            return True\n        m = RE_DATE.match(l)\n        if(m):\n            self.date = m.captures('data')[0]\n            return True\n        m = RE_NAME.match(l)\n        if(m):\n            self.name = m.captures('data')[0]\n            return True\n\n    # Called at the start of export to scan the file for game changing properties\n    def PreScan(self):\n        for l in self.file.org._lines:\n            self.PreScanExportCommentsGather(l)\n            self.PreScanCustom(l)\n        self.PostPreScanCustom()\n    \n    # This is called when the document is being destroyed\n    def Close(self):\n        self.FinishDocCustom()\n        self.fs.close()\n\n    # Override this to add to the pre-scan phase\n    def PreScanCustom(self,l):\n        pass\n\n    # Called after the pre scan is complete\n    def PostPreScanCustom(self):\n        pass\n\n    # Override this to close off the document for exporting\n    def FinishDocCustom(self):\n        pass\n\n\n    # Document header metadata should go in here\n    def AddExportMetaCustom(self):\n        pass\n\n    # Setup to start the export of a node\n    def StartNode(self, n):\n        pass \n\n    # Export the heading of this node\n    def NodeHeading(self,n):\n        pass\n\n    # We are about to start exporting the nodes body\n    def StartNodeBody(self,n):\n        pass\n\n    # Actually buid the node body in the document\n    def NodeBody(self,n):\n        pass\n\n    # We are done exporting the nodes body so finish it off\n    def EndNodeBody(self,n):\n        pass\n\n    # We are now done the node itself so finish that off\n    def EndNode(self,n):\n        pass\n\n    # def about to start exporting nodes\n    def StartNodes(self):\n        pass\n\n    # done exporting nodes\n    def EndNodes(self):\n        pass\n\n    def StartDocument(self, file):\n        pass\n\n    def EndDocument(self):\n        pass\n\n    def InsertScripts(self,file):\n        pass\n\n    def StartHead(self):\n        pass\n\n    def EndHead(self):\n        pass\n\n    def StartBody(self):\n        pass\n\n    def EndBody(self):\n        pass\n\n\nclass OrgExportHelper:\n\n    def __init__(self,view,index):\n        self.view = view\n        self.file = db.Get().FindInfo(self.view)\n        self.index = index\n\n\n    # Extend this for this format\n    def CustomBuildHead(self):\n        pass\n\n    def BuildHead(self):\n        self.CustomBuildHead()\n        self.doc.AddExportMetaCustom()\n\n    def BuildNode(self, n):\n        self.doc.StartNode(n)\n        self.doc.NodeHeading(n)\n        self.doc.StartNodeBody(n)\n        self.doc.NodeBody(n)\n        for c in n.children:\n            self.BuildNode(c)\n        self.doc.EndNodeBody(n)\n        self.doc.EndNode(n)\n\n    def BuildNodes(self):\n        if(self.index == None):\n            nodes = self.file.org\n            for n in nodes.children:\n                self.BuildNode(n)\n        else:\n            n = self.file.org.env._nodes[self.index]\n            self.BuildNode(n)\n\n    def BuildDocument(self):\n        self.doc.StartNodes()\n        self.BuildNodes()\n        self.doc.EndNodes()\n\n    def BuildBody(self):\n        self.doc.StartDocument(self.file)\n        self.BuildDocument()\n        self.doc.EndDocument()\n        self.doc.InsertScripts(self.file)\n\n    def Run(self,outputFilename,doc):\n        try:\n            self.doc = doc\n            self.doc.StartHead()\n            self.BuildHead()\n            self.doc.EndHead()\n\n            self.doc.StartBody()\n            self.BuildBody()\n            self.doc.EndBody()\n        finally:    \n            if(None != self.doc):\n                self.doc.Close()\n            log.log(51,\"EXPORT COMPLETE: \" + str(outputFilename))\n            self.view.set_status(\"ORG_EXPORT\",\"EXPORT COMPLETE: \" + str(outputFilename))\n            sublime.set_timeout(self.ClearStatus, 1000*10)\n\n    def ClearStatus(self):\n        self.view.set_status(\"ORG_EXPORT\",\"\")\n\n\n\nclass BlockState:\n    def __init__(self,startre,endre,doc,exportEndLine=False):\n        self.startre      = startre\n        self.endre        = endre\n        self.e            = doc\n        self.exportEndLine = exportEndLine\n    def Handle(self, lines, orgnode):\n        amIn = False\n        for line in lines:\n            if(amIn):\n                m = self.endre.search(line)\n                if(m):\n                    amIn = False\n                    self.e.SetAmInBlock(False)\n                    self.HandleExiting(m,line,orgnode)\n                    if(self.exportEndLine):\n                        yield line\n                    continue\n                else:\n                    self.HandleIn(line,orgnode)\n                    continue\n            else:\n                if(not self.e.AmInBlock()):\n                    m = self.startre.search(line)\n                    if(m):\n                        amIn = True\n                        self.e.SetAmInBlock(True)\n                        self.HandleEntering(m,line,orgnode)\n                        continue\n                yield line\n        if(amIn):\n            amIn = False\n            self.e.SetAmInBlock(False)\n            self.HandleExiting(None,None,orgnode)\n    def HandleIn(self, line, orgnode):\n        pass\n    def HandleExiting(self, m, line, orgnode):\n        pass\n    def HandleEntering(self, m, line, orgnode):\n        pass \n\nclass ListBlockState:\n    def __init__(self,listre,doc):\n        self.listre      = listre\n        self.e           = doc\n    def Handle(self, lines, orgnode):\n        inList    = 0\n        curIndent = 0\n        for l in lines:\n            m = self.listre.search(l)\n            if(m):\n                thisIndent = len(m.group('indent'))\n                if(not inList):\n                    if(not self.e.AmInBlock()):\n                        curIndent = thisIndent\n                        self.HandleEntering(m,l,orgnode)\n                        inList += 1\n                    else:\n                        yield l\n                        continue\n                elif(thisIndent > curIndent):\n                    curIndent = thisIndent\n                    self.HandleEntering(m,l,orgnode)\n                    inList += 1\n                elif(thisIndent < curIndent and inList > 1):\n                    inList -= 1\n                    self.HandleExiting(m,l,orgnode)\n                startItem = len(self.e.doc)\n                self.StartHandleItem(m,l,orgnode)\n                yield m.group('data')\n                self.EndHandleItem(m,l,orgnode)\n                self.e.doc[startItem] = \"\".join(self.e.doc[startItem:])\n                del self.e.doc[-2:]\n                continue\n            elif(inList):\n                while(inList > 0):\n                    inList -= 1\n                    self.HandleExiting(m,l,orgnode)\n                yield l\n            else:\n                yield l\n        while(inList > 0):\n            inList -= 1\n            self.HandleExiting(m,l,orgnode)\n    def StartHandleItem(self, m, line, orgnode):\n        self.e.doc.append(\"\")\n    def EndHandleItem(self,m,line,orgnode):\n        self.e.doc.append(\"\")\n    def HandleExiting(self, m, line, orgnode):\n        pass\n    def HandleEntering(self, m, line, orgnode):\n        pass \n\nclass AttributeParser:\n    def __init__(self,name,sre,doc):\n        self.sre      = sre\n        self.name     = name\n        self.e        = doc\n    def Handle(self, lines, orgnode):\n        for line in lines:\n            m = self.sre.search(line)\n            if(m):\n                self.HandleData(m,line,orgnode)\n                continue\n            yield line\n    def HandleData(self, m, line, orgnode):\n        self.e.AddAttrib(self.name,m.group('data'))\n\nclass StripParser:\n    def __init__(self,sre,doc):\n        self.sre      = sre\n        self.e        = doc\n    def Handle(self, lines, orgnode):\n        for line in lines:\n            m = self.sre.search(line)\n            if(m):\n                continue\n            yield line\n\n# This parser expects the item to live and consume the entire line\n# Match will replace the entire line\nclass LineParser:\n    def __init__(self,sre,doc):\n        self.sre      = sre\n        self.e        = doc\n    def Handle(self, lines, orgnode):\n        for line in lines:\n            m = self.sre.search(line)\n            if(m):\n                self.HandleLine(m,line,orgnode)\n                continue\n            yield line\n    def HandleLine(self,m,l,orgnode):\n        pass\n\n# This parser expects the item to live and consume the entire line\n# Match will replace the entire line\nclass NotInBlockLineParser:\n    def __init__(self,sre,doc):\n        self.sre      = sre\n        self.e        = doc\n    def Handle(self, lines, orgnode):\n        for line in lines:\n            if(not self.e.AmInBlock()):\n                m = self.sre.search(line)\n                if(m):\n                    self.HandleLine(m,line,orgnode)\n                    continue\n            yield line\n    def HandleLine(self,m,l,orgnode):\n        pass\n\n# This parser expects a match to be \"within\" a line.\n# This is complicated because we may still have to foward off\n# the other portions of the line \nclass SubLineParser:\n    def __init__(self,sre,doc):\n        self.sre      = sre\n        self.e        = doc\n    def Handle(self, lines, orgnode):\n        for line in lines:\n            start = 0\n            llen = len(self.e.doc)\n            for m in self.sre.finditer(line):\n                s,e = m.span()\n                if(s >= start):\n                    segment = line[start:s]\n                    if(segment.strip() == \"\"):\n                        self.e.doc.append(segment)\n                    else:\n                        yield segment\n                    start = e\n                self.HandleSegment(m,line,orgnode)\n            if(start != 0 and len(line) > start):\n                segment = line[start:]\n                if(segment.strip() == \"\"):\n                    self.e.doc.append(segment)\n                else:\n                    yield segment\n            elif(start == 0):\n                yield line\n            # We generated more than one line here! need to collapse\n            nlen = len(self.e.doc) - llen\n            if(nlen > 1):\n                ls = \"\".join(self.e.doc[llen:])\n                del self.e.doc[-nlen:]\n                self.e.doc.append(ls)\n    def HandleSegment(self,m,l,orgnode):\n        pass\n\nRE_STARTSRC = re.compile(r\"^\\s*#\\+(BEGIN_SRC|begin_src)\\s+(?P<lang>[a-zA-Z0-9]+)\")\nRE_ENDSRC = re.compile(r\"^\\s*#\\+(END_SRC|end_src)\")\n\nclass SourceBlockState(BlockState):\n    def __init__(self,doc):\n        super(SourceBlockState,self).__init__(RE_STARTSRC, RE_ENDSRC,doc)\n\nRE_STARTDYN = re.compile(r\"^\\s*#\\+(BEGIN[:]|begin[:])\\s+(?P<lang>[a-zA-Z0-9]+)\")\nRE_ENDDYN = re.compile(r\"^\\s*#\\+(end[:]|END[:])\")\n\nclass DynamicBlockState(BlockState):\n    def __init__(self,doc):\n        super(DynamicBlockState,self).__init__(RE_STARTDYN, RE_ENDDYN,doc)\n\nRE_STARTEXPORT = re.compile(r\"^\\s*#\\+(BEGIN_EXPORT|begin_export)\\s+(?P<lang>[a-zA-Z0-9]+)\")\nRE_ENDEXPORT = re.compile(r\"^\\s*#\\+(END_EXPORT|end_export)\")\n\nclass ExportBlockState(BlockState):\n    def __init__(self,doc):\n        super(ExportBlockState,self).__init__(RE_STARTEXPORT, RE_ENDEXPORT,doc)\n\nRE_STARTQUOTE = re.compile(r\"^\\s*#\\+(BEGIN_QUOTE|begin_quote)\")\nRE_ENDQUOTE = re.compile(r\"^\\s*#\\+(END_QUOTE|end_quote)\")\n\nclass QuoteBlockState(BlockState):\n    def __init__(self,doc):\n        super(QuoteBlockState,self).__init__(RE_STARTQUOTE, RE_ENDQUOTE,doc)\n\nRE_STARTEXAMPLE = re.compile(r\"^\\s*#\\+(BEGIN_EXAMPLE|begin_example)\")\nRE_ENDEXAMPLE = re.compile(r\"^\\s*#\\+(END_EXAMPLE|end_example)\")\n\nclass ExampleBlockState(BlockState):\n    def __init__(self,doc):\n        super(ExampleBlockState,self).__init__(RE_STARTEXAMPLE, RE_ENDEXAMPLE,doc)\n\nRE_STARTNOTE = re.compile(r\"^\\s*#\\+(BEGIN_NOTES|begin_notes)\")\nRE_ENDNOTE = re.compile(r\"^\\s*#\\+(END_NOTES|end_notes)\")\nclass NotesBlockState(BlockState):\n    def __init__(self,doc):\n        super(NotesBlockState,self).__init__(RE_STARTNOTE, RE_ENDNOTE,doc)\n\nRE_STARTGENERIC = re.compile(r\"#\\+(BEGIN_|begin_)(?P<data>[a-zA-Z0-9-]+)(\\s|$)\")\nRE_ENDGENERIC   = re.compile(r\"#\\+(END_|end_)([a-zA-Z0-9-]+)(\\s|$)\")\n\nclass GenericBlockState(BlockState):\n    def __init__(self,doc):\n        super(GenericBlockState,self).__init__(RE_STARTGENERIC, RE_ENDGENERIC,doc)\n\nRE_TABLE_ROW = re.compile(r\"^\\s*[|]\")\nRE_NOT_TABLE_ROW = re.compile(r\"^\\s*[^| \\t]\")\nclass TableBlockState(BlockState):\n    def __init__(self,doc):\n        super(TableBlockState,self).__init__(RE_TABLE_ROW, RE_NOT_TABLE_ROW,doc,True)\n\nRE_DRAWER_LINE = re.compile(r\"^\\s*[:].+[:]\\s*$\")\nRE_END_DRAWER_LINE = re.compile(r\"^\\s*[:](END|end)[:]\\s*$\")\nclass DrawerBlockState(BlockState):\n    def __init__(self,doc):\n        super(DrawerBlockState,self).__init__(RE_DRAWER_LINE, RE_END_DRAWER_LINE,doc)\n\nRE_CAPTION = regex.compile(r\"^\\s*[#][+]CAPTION[:]\\s*(?P<data>.*)\")\nclass CaptionAttributeParser(AttributeParser):\n    def __init__(self,doc):\n        super(CaptionAttributeParser,self).__init__('caption',RE_CAPTION,doc)\n\nRE_TBLFM = regex.compile(r\"^\\s*[#][+]TBLFM[:].*\")\nclass TblFmStripper(StripParser):\n    def __init__(self,doc):\n        super(TblFmStripper,self).__init__(RE_TBLFM,doc)\n\nRE_ATTR_HTML = re.compile(r\"^\\s*[#][+](ATTR_HTML|attr_html)[:].*\")\nclass AttrHtmlStripper(StripParser):\n    def __init__(self,doc):\n        super(AttrHtmlStripper,self).__init__(RE_ATTR_HTML,doc)\n\nRE_ATTR_ORG = re.compile(r\"^\\s*[#][+](ATTR_ORG|attr_org)[:].*\")\nclass AttrOrgStripper(StripParser):\n    def __init__(self,doc):\n        super(AttrOrgStripper,self).__init__(RE_ATTR_ORG,doc)\n\nRE_KEYWORDSTRIP = re.compile(r\"^\\s*[#][+](COLUMNS|columns|PRIORITIES|priorities|PLOT|plot|TODO|todo|TAGS|tags|PROPERTY|property)[:].*\")\nclass KeywordStripper(StripParser):\n    def __init__(self,doc):\n        super(KeywordStripper,self).__init__(RE_KEYWORDSTRIP,doc)\n\nRE_SCHEDULING_LINE = re.compile(r\"^\\s*(SCHEDULED|CLOSED|DEADLINE|CLOCK)[:].*\")\nclass SchedulingStripper(StripParser):\n    def __init__(self,doc):\n        super(SchedulingStripper,self).__init__(RE_SCHEDULING_LINE,doc)\n\nRE_UL   = re.compile(r\"^(?P<indent>\\s*)(?P<listprefix>-|[+])\\s+((?P<definition>[a-zA-Z0-9_-]+?)\\s*[:][:]\\s*)?(?P<data>.+)\")\nclass UnorderedListBlockState(ListBlockState):\n    def __init__(self,doc):\n        super(UnorderedListBlockState,self).__init__(RE_UL,doc)\n\nRE_CL   = re.compile(r\"^(?P<indent>\\s*)(?P<listprefix>(-|[+])\\s+\\[(?P<state>[ xX-])\\])\\s+((?P<definition>[a-zA-Z0-9_-]+?)\\s*[:][:]\\s*)?(?P<data>.+)\")\nclass CheckboxListBlockState(ListBlockState):\n    def __init__(self,doc):\n        super(CheckboxListBlockState,self).__init__(RE_CL,doc)\n\nRE_OL   = re.compile(r\"^(?P<indent>\\s*)(?P<listprefix>[0-9]+[).])\\s+((?P<definition>[a-zA-Z0-9_-]+?)\\s*[:][:]\\s*)?(?P<data>.+)\")\nclass OrderedListBlockState(ListBlockState):\n    def __init__(self,doc):\n        super(OrderedListBlockState,self).__init__(RE_OL,doc)\n\n\nRE_BOLD = re.compile(r\"\\*(?P<data>.+?)\\*\")\nRE_ITALICS = re.compile(r\"/(?P<data>.+?)/\")\nRE_UNDERLINE = re.compile(r\"[_](?P<data>.+?)[_]\")\nRE_STRIKETHROUGH = re.compile(r\"\\+(?P<data>.+?)\\+\")\nRE_CODE = re.compile(r\"~(?P<data>.+?)~\")\nRE_VERBATIM = re.compile(r\"=(?P<data>.+?)=\")\n\nclass BoldParser(SubLineParser):\n    def __init__(self,doc):\n        super(BoldParser,self).__init__(RE_BOLD,doc)\n\nclass ItalicsParser(SubLineParser):\n    def __init__(self,doc):\n        super(ItalicsParser,self).__init__(RE_ITALICS,doc)\n\nclass UnderlineParser(SubLineParser):\n    def __init__(self,doc):\n        super(UnderlineParser,self).__init__(RE_UNDERLINE,doc)\n\nclass StrikethroughParser(SubLineParser):\n    def __init__(self,doc):\n        super(StrikethroughParser,self).__init__(RE_STRIKETHROUGH,doc)\n\nclass CodeParser(SubLineParser):\n    def __init__(self,doc):\n        super(CodeParser,self).__init__(RE_CODE,doc)\n\nclass VerbatimParser(SubLineParser):\n    def __init__(self,doc):\n        super(VerbatimParser,self).__init__(RE_VERBATIM,doc)\n\nRE_LINK = re.compile(r\"\\[\\[(?P<link>[^\\]]+)\\](\\[(?P<desc>[^\\]]+)\\])?\\]\")\nclass LinkParser(SubLineParser):\n    def __init__(self,doc):\n        super(LinkParser,self).__init__(RE_LINK,doc)\n\nRE_HR = re.compile(r\"^((\\s*-----+\\s*)|(\\s*---\\s+[a-zA-Z0-9 ]+\\s+---\\s*))$\")\nclass HrParser(LineParser):\n    def __init__(self,doc):\n        super(HrParser,self).__init__(RE_HR,doc)\n\nRE_TARGET = regex.compile(r\"<<(?P<data>.+?)>>\")\nclass TargetParser(SubLineParser):\n    def __init__(self,doc):\n        super(TargetParser,self).__init__(RE_TARGET,doc)\n\nRE_MATH = regex.compile(r\"\\$(?P<data>.+?)\\$\")\nclass MathParser(SubLineParser):\n    def __init__(self,doc):\n        super(MathParser,self).__init__(RE_MATH,doc)\n\nRE_INLMATH = regex.compile(r\"\\\\\\((?P<data>.+?)\\\\\\)\")\nclass InlineMathParser(SubLineParser):\n    def __init__(self,doc):\n        super(InlineMathParser,self).__init__(RE_INLMATH,doc)\n\nRE_EQMATH = regex.compile(r\"\\\\\\[(?P<data>.+?)\\\\\\]\")\nclass EqMathParser(SubLineParser):\n    def __init__(self,doc):\n        super(EqMathParser,self).__init__(RE_EQMATH,doc)\n\nRE_EMPTY = re.compile(r\"^\\s*$\")\nclass EmptyParser(NotInBlockLineParser):\n    def __init__(self,doc):\n        super(EmptyParser,self).__init__(RE_EMPTY,doc)\n\nclass ActiveDateParser(LineParser):\n    def __init__(self,doc):\n        super(ActiveDateParser,self).__init__(date.gene_timestamp_regex('active'),doc)\n\nclass InactiveDateParser(LineParser):\n    def __init__(self,doc):\n        super(InactiveDateParser,self).__init__(date.gene_timestamp_regex('inactive'),doc)\n\nclass NameParser(LineParser):\n    def __init__(self,doc):\n        super(NameParser,self).__init__(RE_NAME,doc)\n\nRE_LATEX_HEADER = regex.compile(r\"^\\s*[#][+](LATEX_HEADER|latex_header)[:]\\s*(?P<data>.*)\")\nclass LatexHeaderParser(LineParser):\n    def __init__(self,doc):\n        super(LatexHeaderParser,self).__init__(RE_LATEX_HEADER,doc)\n\nRE_LATEX_CLASS_OPTIONS = regex.compile(r\"^\\s*[#][+](LATEX_CLASS_OPTIONS|latex_class_options)[:]\\s*(?P<data>.*)\")\nclass LatexClassOptionsParser(LineParser):\n    def __init__(self,doc):\n        super(LatexClassOptionsParser,self).__init__(RE_LATEX_CLASS_OPTIONS,doc)\n\nRE_SETUPFILE = regex.compile(r\"^\\s*[#][+](SETUPFILE|setupfile)[:]\\s*(?P<data>.*)\")\nclass SetupFileParser(LineParser):\n    def __init__(self,doc):\n        super(SetupFileParser,self).__init__(RE_SETUPFILE,doc)\n    def Handle(self, lines, orgnode):\n        for line in lines:\n            m = self.sre.search(line)\n            if(m):\n                filename = m.group('data').strip()\n                try:\n                    with open(filename,\"r\") as f:\n                        for setupline in f:\n                            yield setupline\n                except:\n                    log.warning(\"Setup file not found: \" + str(filename))\n                continue\n            yield line\n\nRE_RESULTS = regex.compile(r\"^\\s*[#][+](RESULTS|results)[:]\\s*(?P<data>.*)\")\nclass ResultsParser(LineParser):\n    def __init__(self,doc):\n        super(ResultsParser,self).__init__(RE_RESULTS,doc)\n    def Handle(self, lines, orgnode):\n        skip = False\n        for line in lines:\n            if(skip):\n                if(line.strip() == \"\"):\n                    skip = False\n                elif(RE_ENDSRC.search(line) or RE_END_DRAWER_LINE.search(line)):\n                    skip = False\n                    continue\n            m = self.sre.search(line)\n            if(m):\n                if(hasattr(self.e.doc,'sparams')):\n                    exp = self.e.doc.sparams.Get(\"exports\",\"\")\n                    if(exp == 'code' or exp == 'non'):\n                        skip = True \n                        continue\n                else:\n                    continue\n            yield line\n"
  },
  {
    "path": "orgextended.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcapture as capture\nimport OrgExtended.orglinks as links\nimport OrgExtended.orgclocking as clocking\nimport OrgExtended.orgnotifications as notice\nimport OrgExtended.orgdatepicker as datepicker\nimport OrgExtended.pymitter as evt\nimport OrgExtended.packagecon as pkgcon\n\nlog = None\n\ndef InstallIfNeeded(pkg, name):\n    log.debug(\"Checking for \" + name)\n    if(not pkgcon.IsInstalled(pkg)):\n        log.debug(\"Installing \" + name)\n        pkgcon.Install(pkg)\n\n# Lets get our windows in sync now that we are loaded.\ndef sync_up_on_loaded():\n    window = sublime.active_window()\n    window.run_command(\"org_on_load_sync_up\", {})\n    notice.Setup()\n    datepicker.SetupMouse()\n    # Install required packages to operate org extended\n    InstallIfNeeded(pkgcon.TABLE_PACKAGE, \"Table Editor\")\n    InstallIfNeeded(pkgcon.PS_PACKAGE, \"Powershell\")\n\n# This is where we can start to load our DB!\ndef plugin_loaded():\n    evt.Get().off(\"tagsfound\",db.Get().OnTags)\n    sets.setup_user_settings()\n    # Load our settings file.\n    # We probably need a command to reload it\n    # When it is modified, and probably to reload\n    # the DB automatically when your orgs change.\n    sets.Load()\n    clocking.Load()\n\n    # To enable debug logging, set the env var to a non-blank value.\n    # This is the same pattern that neovintageous uses and I think\n    # it is a reasonably decent mechanism\n    _DEBUG = bool(os.getenv('SUBLIME_ORGEXTENDED_DEBUG'))\n    _DEBUG = _DEBUG or sets.Get(\"enableDebugLogging\",False)\n    #_DEBUG = True\n    if _DEBUG:\n        logger = logging.getLogger('OrgExtended')\n        logger.propagate = 0\n        if not logger.hasHandlers():\n            logger.setLevel(logging.DEBUG)\n            stream_handler = logging.StreamHandler()\n            stream_handler.setFormatter(logging.Formatter(\n                'Org: %(levelname)-7s [%(filename)15s:%(lineno)4d] %(message)s'\n            ))\n            logger.addHandler(stream_handler)\n            logger.debug('debug logger initialized')\n    global log\n    log = logging.getLogger(__name__)\n    db.Get().RebuildDb()\n    #window = sublime.active_window()\n    #if window is None:\n    sublime.set_timeout_async(lambda: sync_up_on_loaded(), 1000)\n    log.debug(\"DONE INITIALIZING ORG CAPTURE\")\n\n# This is called when our plugin unloads!\ndef plugin_unloaded():\n    links.onShutdown()\n    if(notice):\n        notice.Get().stop()\n\ndef onLoad(view):\n    if(view and view.file_name() and util.isPotentialOrgFile(view.file_name())):\n        folding.onLoad(view)\n        links.onLoad(view)\n\nRE_TABLE_MATCH = re.compile(r\"^\\s*\\|\")\n# Core events to dispatch to each of our subsystems.\n# This simple direct call is sufficient for our needs\nclass OrgCore(sublime_plugin.EventListener):\n\n    def on_load(self, view):\n        # If this is an org file we need to let the\n        # folding system and others get a crack at this\n        # file. OnLoad will potentially pre-fold the file\n        # or show images in the file.\n        onLoad(view)\n\n    def on_post_window_command(self, window, cmd, args):\n        #print(\"****** CMD: \" + cmd)\n        capture.onPostWindowCommand(window,cmd,args)\n\n    def on_post_save(self, view):\n        if(util.isPotentialOrgFile(view.file_name())):\n            db.Get().Reload(view)\n\n    def on_deactivated(self, view):\n        capture.onDeactivated(view)\n\n    def on_activated(self, view):\n        if(util.isPotentialOrgFile(view.file_name())):\n            folding.onActivated(view)\n\n    def ShouldLocalFold(self, view):\n        file = db.Get().FindInfo(view.file_name())\n        if(file != None and file.HasChanged(view)):\n            file.LoadS(view)\n        return folding.ShouldFoldLocalCycle(view)\n\n    def ShouldGlobalFold(self, view):\n        file = db.Get().FindInfo(view.file_name())\n        return (not self.ShouldLocalFold(view)) and (file != None and type(file.AtInView(view,db.Get())) is node.OrgRootNode)\n\n    def ShouldFoldLinks(self, view):\n        return (not self.ShouldGlobalFold(view)) and folding.am_in_link(view)\n\n    def ShouldTableTab(self,view):\n        cur = view.sel()[0]\n        l = view.line(cur.begin())\n        line = view.substr(l)\n        return RE_TABLE_MATCH.search(line)\n    \n    def ShouldFoldBlock(self,view):\n        cur = view.sel()[0]\n        names = view.scope_name(cur.begin())\n        return 'fence.dynamicblock' in names\n\n    def IsOrgSyntax(self,view):\n        cur = view.sel()[0]\n        names = view.scope_name(cur.begin())\n        return 'text.orgmode' in names\n\n    def ShouldFoldCheckbox(self, view):\n        return (not self.ShouldGlobalFold(view)) and folding.ShouldFoldCheckbox(view)\n\n    def on_query_context(self, view, key, operator, operand, match_all):\n        # A key wants to be inserted, what context are we in for that?\n        rc = False\n        if(operator == sublime.OP_EQUAL and (util.isPotentialOrgFile(view.file_name()) or self.IsOrgSyntax(view))):\n            if(key == 'org_heading'):\n                 rc = operand == self.ShouldLocalFold(view)\n            elif(key == 'org_global'):\n                rc = operand == self.ShouldGlobalFold(view)\n            elif(key == 'org_link'):\n                rc = operand == self.ShouldFoldLinks(view)\n            elif(key == 'org_table'):\n                rc = operand == self.ShouldTableTab(view)\n            elif(key == 'org_block'):\n                rc = operand == self.ShouldFoldBlock(view)\n            elif(key == 'org_checkbox'):\n                rc = operand == self.ShouldFoldCheckbox(view)\n        return rc\n\n\n# Create a new file.\nclass OrgNewFileCommand(sublime_plugin.WindowCommand):\n    def run(self):\n        view = self.window.new_file()\n        view.set_syntax_file('Packages/OrgExtended/OrgExtended.sublime-syntax')\n\n# Iterate over all open \"tabs\" and sync them up so they are folded the way they are supposed to be.\nclass OrgOnLoadSyncUpCommand(sublime_plugin.WindowCommand):\n    def run(self):\n        sheets = self.window.sheets()\n        for sheet in sheets:\n            view = sheet.view()\n            if(view):\n                # Todo detect buffer type as well in the future?\n                # for now we can only do files on disk\n                if(view.file_name()):\n                    log.debug(\"OnLoad: \" + view.file_name())\n                else:\n                    log.debug(\"Loading Unamed Buffer: \" + str(view.id()))\n                onLoad(view)\n            \n"
  },
  {
    "path": "orgextension.py",
    "content": "# LOADING Extension modules.\n# Dynamic Blocks, Links and the Agenda plan to use this mechanism.\n# My extensions can live in subfolder and are loaded dynamically\n# YOUR Extensions can live in User and be loaded dynamically.\n\n\nimport sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport logging\nimport sys\nimport OrgExtended.asettings as sets\nimport importlib\n\nlog = logging.getLogger(__name__)\n\nlastModCache = {}\n\ndef load_module(basemodule, folder, filename,force = False):\n\tif sys.version_info[0] < 3:\n\t\tmodule_path = folder + '.' + filename.split('.')[0]\n\t\tname = filename.split('.')[0]\n\t\tmodule = __import__(module_path, globals(), locals(), name)\n\t\tmodule = reload(module)\n\telse:\n\t\tmodule_path = basemodule + '.'+ folder +'.' + filename.split('.')[0]\n\t\t#for m in sys.modules:\n\t\t#\tif(module_path in m):\n\t\t#\t\tprint(\"KEY: \" + str(m))\n\t\tif force and module_path in sys.modules:\n\t\t\tdel sys.modules[module_path]\n\t\tmodule = importlib.import_module(module_path)\n\treturn module\n\ndef GetUserFolder():\n\tbase = sublime.packages_path()\n\t#base = os.path.dirname(os.path.abspath(__file__))\n\treturn os.path.join(base,'User')\n\n\ndef find_extension_modules(folder, builtins):\n\timportlib.invalidate_caches()\n\t#base = os.path.dirname(os.path.abspath(__file__))\n\tbase = sublime.packages_path()\n\tpath = base + '/' + folder\n\tmoduleTable = {}\n\t# Built in extensions\n\t#for root, dirnames, filenames in os.walk(path):\n\t#\tfor filename in fnmatch.filter(filenames, '*.py'):\n\t#\t\tif '__init__' in filename or 'abstract' in filename:\n\t#\t\t\tcontinue\n\tfor filename in builtins:\n\t\tfilename = filename + \".py\"\n\t\tforce = sets.Get(\"forceLoadInternalExtensions\",False)\n\t\tmodule = load_module(\"OrgExtended\", folder, filename, force)\n\t\tmoduleTable[filename.split('.')[0]] = module\n\t# User generated extensions\n\tpath = os.path.join(base,'User',folder)\n\tfor root, dirnames, filenames in os.walk(path):\n\t\tfor filename in fnmatch.filter(filenames, '*.py'):\n\t\t\tif '__init__' in filename or 'abstract' in filename:\n\t\t\t\tcontinue\n\t\t\t# Only reload if the file is newer.\n\t\t\t# NOTE: Due to how import works, it will not\n\t\t\t#       reload the file until sublime reloads\n\t\t\t#       so we have to track that ourselves\n\t\t\t#       in the loadModCache.\n\t\t\tfullfilename = os.path.join(path,filename)\n\t\t\tlastMod = os.path.getmtime(fullfilename)\n\t\t\tforce = fullfilename not in lastModCache or lastMod > lastModCache[fullfilename] or sets.Get(\"forceLoadExternalExtensions\",False)\n\t\t\tlastModCache[fullfilename] = lastMod\n\t\t\tmodule = load_module(\"User\", folder, filename, force)\n\t\t\tmoduleTable[filename.split('.')[0]] = module\n\treturn moduleTable\n\n\ndef find_extension_file(folder,name,extension='.py'):\n\t# User generated extensions\n\tpath = os.path.join(GetUserFolder(),folder)\n\tfname = name + extension\n\tfor root, dirnames, filenames in os.walk(path):\n\t\tfor filename in fnmatch.filter(filenames, fname):\n\t\t\treturn \"Packages/User/\" + folder + \"/\" + filename\n\t# Built in extensions\n\tinternalName = \"Packages/OrgExtended/\"+folder+\"/\" +fname\n\ttry:\n\t\tif(sublime.load_resource(internalName)):\n\t\t\treturn internalName\n\texcept:\n\t\tpass\n\treturn None\n"
  },
  {
    "path": "orgfolding.py",
    "content": "import OrgExtended.orgdb as db\nimport sublime\nimport sublime_plugin\nimport logging\nimport OrgExtended.orgparse.node as node\nfrom OrgExtended.orgparse.sublimenode import * \nfrom OrgExtended.orgparse.startup import *\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcheckbox as checkbox\n\nlog = logging.getLogger(__name__)\n\n# Link management in the org file.\ndef am_in_link(view):\n    return view.match_selector(view.sel()[0].begin(), \"orgmode.link\")\n\n\ndef find_all_links(view):\n    links = view.find_by_selector(\"orgmode.link.hrefblock\")\n    return links\n\ndef toggle_link(view):\n    pt = view.sel()[0].end()\n    links = view.find_by_selector(\"orgmode.link\")\n    hrefs = view.find_by_selector(\"orgmode.link.hrefblock\")\n    reg = None\n    for link in links:\n        line = view.line(link.begin())\n        if(line.contains(pt)):\n            for href in hrefs:\n                if(line.contains(href.begin())):\n                    reg = href\n                    break\n            break\n    if(reg):\n        if(view.isRegionFolded(reg)):\n            view.unfold(reg)\n        else:\n            view.fold(reg)\n\ndef fold_all_links(view):\n    links = find_all_links(view)\n    view.fold(links)\n\nclass OrgFoldAllLinksCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        fold_all_links(self.view)\n\ndef fold_content(view):\n    file = db.Get().FindInfo(view)\n    if(file):\n        for it in file.org[1:]:\n            it.fold_content(view)\n    else:\n        log.warning(\"Could not locate file in DB for folding\")\n\ndef fold_all_but_my_tree(view):\n    node = db.Get().AtInView(view)\n    if(node):\n        node.unfold(view)\n        while(node and node.parent):\n            for c in node.parent.children:\n                if(c != node):\n                    c.fold(view)\n            node = node.parent\n\ndef fold_all(view):\n    file = db.Get().FindInfo(view)\n    if(file):\n        for it in file.org[1:]:\n            it.fold(view)\n    else:\n        log.warning(\"Could not locate file in DB for folding\")\n\ndef unfold_all(view):\n    file = db.Get().FindInfo(view)\n    if(file):\n        for it in file.org[1:]:\n            it.unfold(view)\n    else:\n        log.warning(\"Could not locate file in DB for folding\")\n\n# hail mary, if things go wrong, remove all the folds in the buffer\ndef remove_all_folds(view):\n\treg = sublime.Region(0,view.size())\n\tview.unfold(reg)\n\ndef fold_showall(view):\n    remove_all_folds(view)\n    file = db.Get().FindInfo(view)\n    for n in file.org[1:]:\n        n.fold_drawers(view)\n    fold_all_links(view)\n\n# When we load a file, it could have\n# been modified out of scope and this CAN\n# cause us grief since our custom folds are\n# persisted and those can be a problem.\ndef onLoad(view):\n    remove_all_folds(view)\n    # Now lets respect the fold state if we have any.\n    file = db.Get().FindInfo(view)\n    if(file):\n        r = file.org[0]\n        globalStartup = sets.Get(\"startup\",[\"showall\"])\n        startup = r.startup(globalStartup)\n        if(Startup.overview in startup or Startup.fold in startup):\n            fold_all(view)\n        elif(Startup.content in startup):\n            fold_content(view)\n            #if(Startup.showall in startup or Startup.nofold in startup):\n        else:\n            fold_showall(view)\n        fold_all_links(view)\n        # showeverything is implicit\n\ndef onActivated(view):\n    shouldHandleActivationFolding = sets.Get(\"onFocusRespectStartupFolds\",None)\n    if(shouldHandleActivationFolding):\n        # Now lets respect the fold state if we have any.\n        file = db.Get().FindInfo(view)\n        if(file):\n            r = file.org[0]\n            globalStartup = sets.Get(\"startup\",[\"showall\"])\n            startup = r.startup(globalStartup)\n            if(Startup.overview in startup or Startup.fold in startup):\n                fold_all_but_my_tree(view)\n            elif(Startup.content in startup):\n                fold_all_but_my_tree(view)\n        fold_all_links(view)\n\nclass OrgFoldAllButMeCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        fold_all_but_my_tree(self.view)\n\nclass OrgFoldAllCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        fold_all(self.view)\n\nclass OrgUnfoldAllCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        unfold_all(self.view)\n\nclass OrgRemoveAllFoldsCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tremove_all_folds(self.view)\n\nclass OrgFoldContentsCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        remove_all_folds(self.view)\n        fold_content(view)\n\nclass OrgFoldThingCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        self.view.fold(self.view.sel()[0])\n\n# ,-> OVERVIEW -> CONTENTS -> SHOW ALL --.\n# '--------------------------------------'\ndef fold_global_cycle(view):\n    file = db.Get().FindInfo(view)\n    # A quick scan of the file to see if we are in\n    # overview: everything is folded to the highest level.\n    # contents: all headings but no content. (like a TOC)\n    # showall:  no property drawers.\n    if(file):\n        allheadersfolded = True\n        allchildrenhidden = True\n        allchildrenvisible = True\n        allchildrencontentvisible = True\n        for n in file.org[0].children:\n            for c in n.children:\n                if(c.is_heading_visible(view)):\n                    allchildrenhiden = False\n                else:\n                    # log.debug(\"Child Not Visible: \" + str(c.heading))\n                    allchildrenvisible = False\n                if(c.is_content_folded(view)):\n                    #log.debug(\"Child Content Not Visible: \" + str(c.heading))\n                    allchildrencontentvisible = False\n            if(n.has_substance() and not n.is_folded(view)):\n                allheadersfolded = False\n\n        if(allheadersfolded):\n            #log.debug(\"To: CONTENTS\")\n            remove_all_folds(view)\n            fold_content(view)\n            return True\n        else:\n            # contents -> showall\n            if(allchildrenvisible and not allchildrencontentvisible):\n                #log.debug(\"To: SHOWALL\")\n                fold_showall(view)\n                return True\n            else:\n                #log.debug(\"CV: \" + str(allchildrenvisible) + \" ACCV: \" + str(allchildrencontentvisible))\n                #log.debug(\"To: FOLDALL\")\n                remove_all_folds(view)\n                fold_all(view)\n                return True\n    return False\n\n\ndef ShouldFoldLocalCycle(view):\n    fnode = db.Get().AtInView(view)\n    if(fnode):\n        row, col = view.curRowCol()\n        if(fnode.start_row == row):\n            return True\n        else:\n            # This could be a property drawer. We want to fold that if so.\n            if(not type(fnode) is node.OrgRootNode and fnode.is_foldable_drawertype(view, row)):\n                return True\n            else:\n                return False\n            pass\n    return False\n\n# ,-> FOLDED -> CHILDREN -> SUBTREE --.\n# '-----------------------------------'\ndef fold_local_cycle(view):\n    fnode = db.Get().AtInView(view)\n    if(fnode and not fnode.is_root()):\n        row, col = view.curRowCol()\n        if(fnode.start_row == row):\n            if(fnode.is_folded(view)):\n                fnode.unfold(view)\n                if(fnode.num_children > 0):\n                    for n in fnode.children:\n                        n.fold(view)\n            else:\n                if(fnode.num_children > 0 and fnode.children[0].is_folded(view)):\n                    for n in fnode.children:\n                        n.unfold(view)\n                else:\n                    fnode.fold(view)\n            fold_all_links(view)\n            return True\n        else:\n            # This could be a property drawer. We want to fold that if so.\n            if(not type(fnode) is node.OrgRootNode and fnode.is_foldable_item(view, row)):\n                if(fnode.is_item_folded(view, row)):\n                    fnode.unfold_item(view, row)\n                    fold_all_links(view)\n                    return True\n                else:\n                    fnode.fold_item(view, row)\n                    fold_all_links(view)\n                    return True\n            #linePos = view.text_point(row,0)\n            #reg     = view.line(linePos)\n            #bufferContents = view.substr(reg)\n            #if(\":PROPERTIES:\" in bufferContents or \":END:\" in bufferContents):\n            #    if(node.is_properties_folded(view)):\n            #        node.unfold_properties(view)\n            #    else:\n            #        node.fold_properties(view)\n            #    return True\n            else:\n                return False\n    return False\n\ndef ShouldFoldCheckbox(view):\n    line = view.curLine()\n    cb = checkbox.get_checkbox(view, line)\n    if(cb != None):\n        childs = checkbox.find_children(view, line)\n        rv = childs != None and len(childs) > 0\n        return rv\n    return False\n\ndef FoldCheckbox(view):\n    line = view.curLine()\n    cb = checkbox.get_checkbox(view, line)\n    if(cb != None):\n        if(view.isRegionFolded(cb)):\n            view.unfold(cb)\n            return\n        childs = checkbox.find_children(view, line)\n        if(childs != None and len(childs) > 0):\n            reg = sublime.Region(line.end(), childs[len(childs) - 1].end())\n            if(view.isRegionFolded(reg)):\n                view.unfold(reg)\n            else:\n                view.fold(reg)\n\n"
  },
  {
    "path": "orghtml.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nimport regex\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcapture as capture\nimport OrgExtended.orgproperties as props\nimport OrgExtended.orgutil.temp as tf\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orgnotifications as notice\nimport OrgExtended.orgextension as ext\nimport OrgExtended.orgsourceblock as src\nimport OrgExtended.orgexporter as exp\nimport OrgExtended.orghtmlexporter as hexp\nimport yaml\nimport sys\nimport subprocess\nimport html\n\nlog = logging.getLogger(__name__)\n\n\n\n# Global properties I AT LEAST want to support.\n# Both as a property on the document and in our settings.\n#+OPTIONS: num:nil toc:nil\n#+REVEAL_TRANS: None/Fade/Slide/Convex/Concave/Zoom\n#+REVEAL_THEME: Black/White/League/Sky/Beige/Simple/Serif/Blood/Night/Moon/Solarized\n#+Title: Title of Your Talk\n#+Author: Your Name\n#+Email: Your Email Address or Twitter Handle\n\ndef GetCollapsibleCodeOld():\n  return \"\"\"\nvar coll = document.getElementsByClassName(\"collapsible\");\nvar i;\n\nfor (i = 0; i < coll.length; i++) {\n  coll[i].addEventListener(\"click\", function() {\n    this.classList.toggle(\"active\");\n    var content = this.nextElementSibling;\n    if (content.style.display === \"block\") {\n      content.style.display = \"none\";\n    } else {\n      content.style.display = \"block\";\n    }\n  });\n}\n\"\"\"\n\n\ndef GetCollapsibleCode():\n  return \"\"\"\nvar coll = document.getElementsByClassName(\"collapsible\");\nvar i;\nvar accume = 0;\nfor (i = 0; i < coll.length; i++) {\n  coll[i].addEventListener(\"click\", function() {\n    this.classList.toggle(\"active\");\n    var content = this.nextElementSibling;\n    if (content.style.maxHeight) {\n      content.style.maxHeight = null;\n    } else {\n      content.style.maxHeight = content.scrollHeight + \"px\";\n    }\n    accume += content.scrollHeight + 5;\n    while(content.parentNode && (content.parentNode.nodeName == 'DIV' || content.parentNode.nodeName == 'SECTION')) {\n      if(content.parentNode.nodeName == 'DIV') {\n        //alert(content.parentNode.nodeName);\n        content.parentNode.style.maxHeight = (accume + content.parentNode.scrollHeight) + \"px\";\n        accume += content.parentNode.scrollHeight;\n      }\n      content = content.parentNode;\n    }\n  });\n  coll[i].click();\n}\n\"\"\"\n\ndef GetCollapsibleCss():\n  return \"\"\"\n  .node-body {\n  padding: 0 18px;\n  max-height: 0;\n  overflow: hidden;\n  transition: max-height 0.2s ease-out;\n  }\n  .active, .collapsible:hover {\n  background-color: #ccc;\n  }\n  .collapsible:after {\n    content: '\\\\002b';\n    font-size: 22px;\n    float: right;\n    margin-right: 20px;\n  }\n  .active:after {\n  content: '\\\\2212';\n  font-size: 22px;\n  margin-right: 20px;\n  }\n\"\"\"\n\n\nRE_CAPTION = regex.compile(r\"^\\s*[#][+]CAPTION[:]\\s*(?P<caption>.*)\")\nRE_ATTR = regex.compile(r\"^\\s*[#][+]ATTR_HTML[:](?P<params>\\s+[:](?P<name>[a-zA-Z0-9._-]+)\\s+(?P<value>([^:]|((?<! )[:]))+))+$\")\nRE_ATTR_ORG = regex.compile(r\"^\\s*[#][+]ATTR_ORG[:] \")\nRE_SCHEDULING_LINE = re.compile(r\"^\\s*(SCHEDULED|CLOSED|DEADLINE|CLOCK)[:].*\")\nRE_DRAWER_LINE = re.compile(r\"^\\s*[:].+[:]\\s*$\")\nRE_END_DRAWER_LINE = re.compile(r\"^\\s*[:](END|end)[:]\\s*$\")\nRE_LINK = re.compile(r\"\\[\\[(?P<link>[^\\]]+)\\](\\[(?P<desc>[^\\]]+)\\])?\\]\")\nRE_UL   = re.compile(r\"^(?P<indent>\\s*)(-|[+])\\s+(?P<data>.+)\")\nRE_STARTQUOTE = re.compile(r\"#\\+(BEGIN_QUOTE|BEGIN_EXAMPLE|BEGIN_VERSE|BEGIN_CENTER|begin_quote|begin_example|begin_verse|begin_center)\")\nRE_ENDQUOTE = re.compile(r\"#\\+(END_QUOTE|END_EXAMPLE|END_VERSE|END_CENTER|end_quote|end_example|end_verse|end_center)\")\nRE_STARTNOTE = re.compile(r\"#\\+(BEGIN_NOTES|begin_notes)\")\nRE_ENDNOTE = re.compile(r\"#\\+(END_NOTES|end_notes)\")\nRE_FN_MATCH = re.compile(r\"\\s*[:]([a-zA-Z0-9-_]+)\\s+([^: ]+)?\\s*\")\nRE_STARTSRC = re.compile(r\"^\\s*#\\+(BEGIN_SRC|begin_src|BEGIN:|begin:)\\s+(?P<lang>[a-zA-Z0-9]+)\")\nRE_ENDSRC = re.compile(r\"^\\s*#\\+(END_SRC|end_src|end:|END:)\")\nRE_RESULTS = re.compile(r\"^\\s*#\\+RESULTS.*\")\nRE_TABLE_ROW = re.compile(r\"^\\s*[|]\")\nRE_TABLE_SEPARATOR = re.compile(r\"^\\s*[|][-]\")\nRE_CHECKBOX         = re.compile(r\"^\\[ \\] \")\nRE_CHECKED_CHECKBOX = re.compile(r\"^\\[[xX]\\] \")\nRE_PARTIAL_CHECKBOX = re.compile(r\"^\\[[-]\\] \")\nRE_EMPTY_LINE = re.compile(r\"^\\s*$\")\n\n\n# <!-- multiple_stores height=\"50%\" width=\"50%\" --> \nRE_COMMENT_TAG = re.compile(r\"^\\s*[<][!][-][-]\\s+(?P<name>[a-zA-Z0-9_-]+)\\s+(?P<props>.*)\\s+[-][-][>]\")\n\n\ndef mapLanguage(lang):\n  if(lang == 'html'):\n    return 'language-html'\n  elif(lang == 'python'):\n    return 'language-python'\n  else:\n    return lang\n\ndef haveLang(lang):\n  return True\n\ndef GetStyleRelatedData(style, extension):\n  inHeader = os.path.join(sublime.packages_path(),\"User\", \"htmlstyles\", style + extension)\n  if(os.path.isfile(inHeader)):\n    with open(inHeader) as f:\n      contents = f.read()\n      return contents\n  resourceName = \"Packages/OrgExtended/htmlstyles/\" + style + extension\n  try:\n    contents = sublime.load_resource(resourceName)\n    return contents\n  except:\n    pass\n  #inHeader = os.path.join(sublime.packages_path(),\"OrgExtended\", \"htmlstyles\", style + extension)\n  #if(os.path.isfile(inHeader)):\n  # with open(inHeader) as f:\n  #   contents = f.read()\n  #   return contents\n  return \"\"\n\n\ndef GetStyleRelatedPropertyData(file, key, setting):\n  val = exp.GetGlobalOption(file, key, setting, \"\")\n  if(\"<\" in val or \"{\" in val):\n    return val\n  elif(os.path.isfile(val)):\n    with open(val) as f:\n      contents = f.read()\n      return contents\n  else:\n    return val\n\n\ndef GetHighlightJsCss(style):\n  import OrgExtended.orgutil.webpull as wp\n  wp.download_highlightjs()\n  data = os.path.join(sublime.packages_path(),\"User\", \"highlightjs\", \"styles\", style + \".css\")\n  if(os.path.isfile(data)):\n    with open(data) as f:\n      contents = f.read()\n      return contents\n\n\ndef GetHighlightJs():\n  import OrgExtended.orgutil.webpull as wp\n  wp.download_highlightjs()\n  data = os.path.join(sublime.packages_path(),\"User\", \"highlightjs\", \"highlight.pack.js\")\n  if(os.path.isfile(data)):\n    with open(data) as f:\n      contents = f.read()\n      return contents\n\n\ndef GetHeaderData(style, file):\n  d1 = GetStyleRelatedData(style,\"_inheader.html\")\n  d2 = GetStyleRelatedPropertyData(file, \"HtmlInHeader\", \"HTML_INHEADER\")\n  return d1 + d2\n\ndef GetHeadingData(style, file):\n  d1 = GetStyleRelatedData(style,\"_heading.html\")\n  d2 = GetStyleRelatedPropertyData(file, \"HtmlHeading\", \"HTML_HEADING\")\n  return d1 + d2\n\ndef GetFootingData(style, file):\n  d1 = GetStyleRelatedData(style,\"_footing.html\")\n  d2 = GetStyleRelatedPropertyData(file, \"HtmlFooting\", \"HTML_FOOTING\")\n  return d1 + d2\n\ndef GetStyleData(style, file):\n  d1 = GetStyleRelatedData(style,\".css\")\n  d2 = GetStyleRelatedPropertyData(file, \"HtmlCss\", \"HTML_CSS\")\n  return d1 + d2\n\nclass HtmlHrParser(exp.HrParser):\n    def __init__(self,doc):\n        super(HtmlHrParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(r\"<hr/>\")\n\nclass HtmlNameParser(exp.NameParser):\n    def __init__(self,doc):\n        super(HtmlNameParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(\"<a name=\\\"{data}\\\"/>\".format(data=m.group('data')))\n\n\nRE_ATTR_HTML = regex.compile(r\"^\\s*[#][+]ATTR_HTML[:]\\s*(?P<data>.*)\")\nclass HtmlAttributeParser(exp.AttributeParser):\n    def __init__(self,doc):\n        super(HtmlAttributeParser,self).__init__('attr_html',RE_ATTR_HTML,doc)\n\nclass HtmlDoc(exp.OrgExporter):\n  def __init__(self, filename, file,**kwargs):\n    super(HtmlDoc, self).__init__(filename, file, **kwargs)\n    self.pre      = []\n    self.doc      = []\n    self.attribs  = {}\n    self.amInBlock = False\n    self.pre.append(\"<!DOCTYPE html>\\n\")\n    self.pre.append(\"<!-- exported by orgextended html exporter -->\\n\")\n    if(self.language):\n      self.pre.append(\"<html xmlns=\\\"http://www.w3.org/1999/xhtml\\\" lang=\\\"{language}\\\" xml:lang=\\\"{language}\\\">\".format(language=self.language))\n    else: \n      self.pre.append(\"<html lang=\\\"en\\\" class>\\n\")\n    self.commentName = None\n    self.figureIndex = 1\n    self.tableIndex  = 1\n    self.nodeParsers = [\n    exp.SetupFileParser(self),\n    exp.CaptionAttributeParser(self),\n    HtmlAttributeParser(self),\n    exp.ResultsParser(self),\n    hexp.HtmlCommentParser(self),\n    hexp.HtmlTableBlockState(self),\n    hexp.HtmlSourceBlockState(self),\n    hexp.HtmlDynamicBlockState(self),\n    hexp.HtmlQuoteBlockState(self),\n    hexp.HtmlExampleBlockState(self),\n    hexp.HtmlNotesBlockState(self),\n    hexp.HtmlCheckboxListBlockState(self),\n    hexp.HtmlUnorderedListBlockState(self),\n    hexp.HtmlOrderedListBlockState(self),\n    hexp.HtmlExportBlockState(self),\n    hexp.HtmlGenericBlockState(self),\n    exp.DrawerBlockState(self),\n    exp.SchedulingStripper(self),\n    exp.TblFmStripper(self),\n    exp.AttrHtmlStripper(self),\n    exp.AttrOrgStripper(self),\n    exp.KeywordStripper(self),\n    hexp.HtmlEmptyParser(self),\n    hexp.HtmlLinkParser(self),\n    HtmlHrParser(self),\n    HtmlNameParser(self),\n    hexp.HtmlHtmlHtmlParser(self),\n    hexp.HtmlActiveDateParser(self),\n    hexp.HtmlBoldParser(self),\n    hexp.HtmlItalicsParser(self),\n    hexp.HtmlUnderlineParser(self),\n    hexp.HtmlStrikethroughParser(self),\n    hexp.HtmlCodeParser(self),\n    hexp.HtmlVerbatimParser(self),\n    hexp.HtmlTargetParser(self)\n    ]\n  def SetAmInBlock(self,inBlock):\n      self.amInBlock = inBlock\n\n  def AmInBlock(self):\n      return self.amInBlock\n\n  def AddAttrib(self,name,val):\n      if(type(val) == str):\n          self.attribs[name] = val.strip()\n      else:\n          self.attribs[name] = val\n    \n  def GetAttrib(self,name):\n      if(name in self.attribs):\n          return self.attribs[name]\n      return None\n\n  def ClearAttrib(self):\n      self.attribs.clear()\n\n  def AddJs(self,link):\n    self.pre.append(\"    <script type=\\\"text/javascript\\\" src=\\\"\" + link + \"\\\"></script>\\n\")\n\n  def AddStyle(self,link):\n    self.pre.append(\"    <link rel=\\\"stylesheet\\\" href=\\\"\"+link+\"\\\"></link>\\n\")\n\n  def AddInlineStyle(self,content):\n    # <style>\n    #    BLOCK\n    # </style> \n    self.pre.append(\"   <style>\\n{0}\\n   </style>\\n\".format(content))\n\n  def InsertJs(self,content):\n    # <style>\n    #    BLOCK\n    # </style> \n    self.doc.append(\"   <script>\\n{0}\\n   </script>\\n\".format(content))\n\n  def StartHead(self):\n    self.pre.append(\"  <head>\\n\")\n\n  def EndHead(self):\n    data = GetHeaderData(self.style, self.file)\n    self.pre.append(data)\n    self.pre.append(\"  </head>\\n\")\n\n  def AddExportMetaCustom(self):\n    if(self.title):\n      self.pre.append(\"<title>{title}</title>\".format(title=self.title))\n    if(self.author):\n      self.pre.append(\"<meta name=\\\"author\\\" content=\\\"{author}\\\" />\".format(author=self.author))\n\n  def StartDocument(self, file):\n    self.doc.append(\"  <div class=\\\"ready\\\">\\n\")\n\n  def EndDocument(self):\n    self.doc.append(\"  </div>\\n\")\n\n  def StartNodes(self):\n    self.doc.append(\"    <div class=\\\"orgmode\\\">\\n\")\n\n  def EndNodes(self):\n    self.doc.append(\"    </div>\\n\")\n\n  # Per slide properties\n  #:PROPERTIES:\n  #:css_property: value\n  #:END:\n  def StartNode(self,n):\n    properties = \"\"\n    for prop in n.properties:\n      properties = \"{0} {1}=\\\"{2}\\\"\".format(properties, prop, n.properties[prop])\n    self.doc.append(\"      <section {0}>\\n\".format(properties))\n\n  def StartNodeBody(self, n):\n    level = n.level + 1\n    self.doc.append(\"      <div class=\\\"node-body h{level}\\\">\\n\".format(level=level))\n\n  def EndNodeBody(self,n):\n    self.doc.append(\"      </div>\\n\")\n\n  def EndNode(self,n):\n    self.doc.append(\"      </section>\\n\")\n\n  def NodeHeading(self,n):\n    heading = html.escape(n.heading)\n    level = n.level + 1\n    self.doc.append(\"      <h{level} class=\\\"collapsible\\\">{heading}</h{level}>\\n\".format(level=level,heading=heading))\n\n  def ClearAttributes(self):\n    self.attrs = {}\n    self.caption = None\n\n  def AttributesGather(self, l):\n    if(self.PreScanExportCommentsGather(l)):\n      return True\n    m = RE_CAPTION.match(l)\n    if(not hasattr(self, 'caption')):\n      self.caption = None\n    if(m):\n      self.caption = m.captures('caption')[0]\n      return True\n    m = RE_ATTR.match(l)\n    # We capture #+ATTR_HTML: lines\n    if(m):\n      keys = m.captures('name')\n      vals = m.captures('value')\n      if not hasattr(self,'attrs'):\n        self.attrs = {}\n      for i in range(len(keys)):\n        self.attrs[keys[i]] = vals[i]\n      return True\n    # We skip #+ATTR_ORG: lines\n    m = RE_ATTR_ORG.match(l)\n    if(m):\n      return True\n    return False\n\n  def EscAndLinks(self, l):\n    line = html.escape(l)\n    m = RE_LINK.search(line)\n    if(m):\n      link = m.group('link').strip()\n      desc = m.group('desc')\n      if(not desc):\n        desc = link\n      else:\n        desc = desc.strip()\n      if(link.endswith(\".png\") or link.endswith(\".jpg\") or link.endswith(\".jpeg\") or link.endswith(\".gif\")):\n        if(link.startswith(\"file:\")):\n          link = re.sub(r'^file:','',link)  \n        extradata = \"\"  \n        if(self.commentName and self.commentName in link):\n          extradata =  \" \" + self.commentData\n          self.commentName = None\n        if(hasattr(self,'attrs')):\n          for key in self.attrs:\n            extradata += \" \" + str(key) + \"=\\\"\" + str(self.attrs[key]) + \"\\\"\"\n        preamble = \"\"\n        postamble = \"\"\n        if(hasattr(self,'caption') and self.caption):\n          preamble = \"<div class=\\\"figure\\\"><p>\"\n          postamble = \"</p><p><span class=\\\"figure-number\\\">Figure {index}: </span>{caption}</p></div>\".format(index=self.figureIndex,caption=self.caption)\n          self.figureIndex += 1\n        line = RE_LINK.sub(\"{preamble}<img src=\\\"{link}\\\" alt=\\\"{desc}\\\"{extradata}>{postamble}\".format(preamble=preamble,link=link,desc=desc,extradata=extradata,postamble=postamble),line)\n        self.ClearAttributes()\n      else:\n        line = RE_LINK.sub(\"<a href=\\\"{link}\\\">{desc}</a>\".format(link=link,desc=desc),line)\n        self.ClearAttributes()\n    else:\n      line = exp.RE_BOLD.sub(r\"<b>\\1</b>\",line)\n      line = exp.RE_ITALICS.sub(r\"<i>\\1</i>\",line)\n      line = exp.RE_UNDERLINE.sub(r\"<u>\\1</u>\",line)\n      line = exp.RE_STRIKETHROUGH.sub(r\"<strike>\\1</strike>\",line)\n      line = exp.RE_VERBATIM.sub(r\"<pre>\\1</pre>\",line)\n      line = exp.RE_CODE.sub(r\"<code>\\1</code>\",line)\n      line = RE_STARTQUOTE.sub(r\"<blockquote>\",line)\n      line = RE_ENDQUOTE.sub(r\"</blockquote>\",line)\n      line = RE_STARTNOTE.sub(r'<aside class=\"notes\">',line)\n      line = RE_ENDNOTE.sub(r\"</aside>\",line)\n      line = RE_CHECKBOX.sub(r'<input type=\"checkbox\">',line)\n      line = RE_CHECKED_CHECKBOX.sub(r'<input type=\"checkbox\" checked>',line)\n      if(sets.Get(\"htmlExportPartialCheckboxChecked\",True)):\n        line = RE_PARTIAL_CHECKBOX.sub(r'<input type=\"checkbox\" checked>',line)\n      else:\n        line = RE_PARTIAL_CHECKBOX.sub(r'<input type=\"checkbox\">',line)\n      line = exp.RE_HR.sub(r'<hr>',line)\n    return line\n\n  def TextFullEscape(self,text):\n      return html.escape(text)\n\n\n  def Escape(self,str):\n    return self.TextFullEscape(str)\n\n  def NodeBody(self,slide):\n    ilines = slide._lines[1:]\n    for parser in self.nodeParsers:\n        ilines = parser.Handle(ilines, slide)\n    for line in ilines:\n        self.doc.append(self.TextFullEscape(line))\n    return\n    inDrawer = False\n    inResults= False\n    inUl     = 0\n    ulIndent = 0\n    inTable  = False\n    haveTableHeader = False\n    inSrc    = False\n    skipSrc  = False\n    exp      = None\n    for l in slide._lines[1:]:\n      if(self.AttributesGather(l)):\n        continue\n      if(inResults):\n        if(l.strip() == \"\"):\n          inResults = False\n        elif(RE_ENDSRC.search(l) or RE_END_DRAWER_LINE.search(l)):\n          inResults = False\n          continue\n        if(inResults):\n          if(exp == 'code' or exp == 'none'):\n            continue\n          else:\n            line = self.EscAndLinks(l)\n            self.fs.write(\"     \" + line + \"\\n\")\n            continue\n      if(inDrawer):\n        if(RE_END_DRAWER_LINE.search(l)):\n          inDrawer = False\n        continue\n      if(inTable):\n        if(RE_TABLE_ROW.search(l)):\n          if(RE_TABLE_SEPARATOR.search(l)):\n            continue\n          else:\n            tds = l.split('|')\n            if(len(tds) > 3):\n              # An actual table row, build a row\n              self.fs.write(\"    <tr>\\n\")\n              for td in tds[1:-1]:\n                if(haveTableHeader):\n                  self.fs.write(\"     <td>{0}</td>\\n\".format(self.EscAndLinks(td)))\n                else:\n                  self.fs.write(\"     <th>{0}</th>\\n\".format(self.EscAndLinks(td)))\n              haveTableHeader = True\n              # Fill in the tds\n              self.fs.write(\"    </tr>\\n\")\n              continue\n        else:\n          self.fs.write(\"    </table>\\n\")\n          inTable         = False\n          haveTableHeader = False\n      if(inSrc):\n        if(RE_ENDSRC.search(l)):\n          inSrc = False\n          if(skipSrc):\n            skipSrc = False\n            continue\n          self.fs.write(\"    </code></pre>\\n\")\n          continue\n        else:\n          if(not skipSrc):\n            self.fs.write(\"     \" + l + \"\\n\")\n          continue\n      # src block\n      m = RE_STARTSRC.search(l)\n      if(m):\n        inSrc = True\n        language = m.group('lang')\n        paramstr = l[len(m.group(0)):]\n        p = type('', (), {})() \n        src.BuildFullParamList(p,language,paramstr,slide)\n        exp = p.params.Get(\"exports\",None)\n        if(isinstance(exp,list) and len(exp) > 0):\n          exp = exp[0]\n        if(exp == 'results' or exp == 'none'):\n          skipSrc = True\n          continue\n        # Some languages we skip source by default\n        skipLangs = sets.Get(\"htmlDefaultSkipSrc\",[])\n        if((exp == None or exp == \"none\" or exp == \"default\") and language in skipLangs):\n            self.skipSrc = True\n            return\n        # We keep track of the default state and override it to code if present\n        if exp == 'default':\n            exp = 'code'\n        #params = {}\n        #for ps in RE_FN_MATCH.finditer(paramstr):\n        # params[ps.group(1)] = ps.group(2)\n        attribs = \"\"\n        # This is left over from reveal.\n        if(p.params.Get(\"data-line-numbers\",None)):\n          attribs += \" data-line-numbers=\\\"{nums}\\\"\".format(nums=p.params.Get(\"data-line-numbers\",\"\"))\n        self.fs.write(\"    <pre><code language=\\\"{lang}\\\" {attribs}>\\n\".format(lang=mapLanguage(language),attribs=attribs))\n        continue\n      # property drawer\n      if(RE_DRAWER_LINE.search(l)):\n        inDrawer = True\n        continue\n      # scheduling\n      if(RE_SCHEDULING_LINE.search(l)):\n        continue\n      if(RE_RESULTS.search(l)):\n        inResults = True\n        continue\n      m = RE_COMMENT_TAG.search(l)\n      if(m):\n        self.commentData = m.group('props')\n        self.commentName = m.group('name')\n        continue\n\n      m = RE_TABLE_ROW.search(l)\n      if(m):\n        self.fs.write(\"    <table>\\n\")\n        if(hasattr(self,'caption') and self.caption):\n          self.fs.write(\"    <caption class=\\\"t-above\\\"><span class=\\\"table-number\\\">Table {index}:</span>{caption}</caption>\".format(index=self.tableIndex,caption=self.caption))\n          self.tableIndex += 1\n          self.ClearAttributes()\n        if(not RE_TABLE_SEPARATOR.search(l)):\n          tds = l.split('|')\n          if(len(tds) > 3):\n            self.fs.write(\"    <tr>\\n\")\n            for td in tds[1:-1]:\n              self.fs.write(\"     <th>{0}</th>\".format(self.EscAndLinks(td)))\n            self.fs.write(\"    </tr>\\n\")\n          haveTableHeader = True\n        inTable = True\n        continue\n      m = RE_UL.search(l)\n      if(m):\n        thisIndent = len(m.group('indent'))\n        if(not inUl):\n          ulIndent = thisIndent\n          self.fs.write(\"     <ul>\\n\")\n          inUl += 1\n        elif(thisIndent > ulIndent):\n          ulIndent = thisIndent\n          self.fs.write(\"     <ul>\\n\")\n          inUl += 1\n        elif(thisIndent < ulIndent and inUl > 1):\n          inUl -= 1\n          self.fs.write(\"     </ul>\\n\")\n        data = self.EscAndLinks(m.group('data'))\n        self.fs.write(\"     <li>{content}</li>\\n\".format(content=data))\n        continue\n      elif(inUl):\n        while(inUl > 0):\n          inUl -= 1\n          self.fs.write(\"     </ul>\\n\")\n      if(RE_EMPTY_LINE.search(l)):\n        self.fs.write(\"    <br>\\n\")\n      # Normal Write\n      line = self.EscAndLinks(l)\n      self.fs.write(\"     \" + line + \"\\n\")\n    if(inUl):\n      inUl -= 1\n      self.fs.write(\"     </ul>\\n\")\n\n    pass\n\n  def StartBody(self):\n    self.doc.append(\"  <body>\\n\")\n    data = GetHeadingData(self.style, self.file)\n    if(data):\n      self.doc.append(data)\n\n  def EndBody(self):\n    data = GetFootingData(self.style, self.file)\n    if(data):\n      self.doc.append(data)\n    self.doc.append(\"  </body>\\n\")\n\n  def InsertScripts(self,file):\n    #self.InsertJs(GetHighlightJs())\n    self.AddJs('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js')\n    self.doc.append(\"<script>hljs.initHighlightingOnLoad();</script>\\n\")\n    self.InsertJs(GetCollapsibleCode())\n\n  def Postamble(self):\n    self.doc.append(\"<div id=\\\"postamble\\\" class=\\\"status\\\">\")\n    if(self.date):\n      self.doc.append(\"<p class=\\\"date\\\">Date: {date}</p>\".format(date=self.date))\n    if(self.author):\n      self.doc.append(\"<p class=\\\"author\\\">Author: {author}</p>\".format(author=self.author))\n    self.doc.append(\"<p class=\\\"date\\\">Created: {date}</p>\".format(date=str(datetime.datetime.now())))\n    self.doc.append(\"</div>\")\n\n  def BuildDoc(self):\n      out = '\\n'.join(self.pre) + '\\n' + '\\n'.join(self.doc) + '\\n'\n      return out\n\n  def FinishDocCustom(self):\n    self.Postamble()\n    self.doc.append(\"</html>\\n\")\n    self.fs.write(self.BuildDoc())\n\nclass HtmlExportHelper(exp.OrgExportHelper):\n  def __init__(self,view,index):\n    super(HtmlExportHelper,self).__init__(view,index)\n\n  def CustomBuildHead(self):\n    highlight      = exp.GetGlobalOption(self.file,\"HTML_HIGHLIGHT\",\"HtmlHighlight\",\"zenburn\").lower()\n    #self.doc.AddInlineStyle(GetHighlightJsCss(highlight))\n    self.doc.AddStyle('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/default.min.css')\n    self.doc.AddInlineStyle(GetCollapsibleCss())\n    self.doc.AddInlineStyle(GetStyleData(self.doc.style, self.file))\n\n# Export the entire file using our internal exporter\nclass OrgExportFileOrgHtmlCommand(sublime_plugin.TextCommand):\n  def OnDoneSourceBlockExecution(self):\n    # Reload if necessary\n    self.file = db.Get().FindInfo(self.view)\n    doc = None\n    self.style = exp.GetGlobalOption(self.file,\"HTML_STYLE\",\"HtmlStyle\",\"blocky\").lower()\n    log.log(51,\"EXPORT STYLE: \" + self.style)\n    try:\n      outputFilename = exp.ExportFilename(self.view,\".html\", self.suffix)\n      doc            = HtmlDoc(outputFilename, self.file)\n      doc.style      = self.style\n      self.helper    = HtmlExportHelper(self.view, self.index)\n      self.helper.Run(outputFilename, doc)\n    finally:  \n      evt.EmitIf(self.onDone)\n\n\n  def run(self,edit, onDone=None, index=None, suffix=\"\"):\n    self.file = db.Get().FindInfo(self.view)\n    self.onDone = onDone\n    self.suffix = suffix\n    if(index != None):\n      self.index = index\n    else:\n      self.index = None\n    if(self.file is None):\n      log.error(\"Not an org file? Cannot build reveal document\")\n      evt.EmitIf(onDone)  \n      return\n    if(sets.Get(\"htmlExecuteSourceOnExport\",True)):\n      self.view.run_command('org_execute_all_source_blocks',{\"onDone\":evt.Make(self.OnDoneSourceBlockExecution),\"amExporting\": True})\n    else:\n      self.OnDoneSourceBlockExecution()\n\ndef sync_up_on_closed():\n  notice.Get().BuildToday()\n\n\nclass OrgDownloadHighlighJs(sublime_plugin.TextCommand):\n  def run(self,edit):\n    log.info(\"Trying to download highlightjs\")\n    import OrgExtended.orgutil.webpull as wp\n    wp.download_highlightjs()\n\nclass OrgExportSubtreeAsOrgHtmlCommand(sublime_plugin.TextCommand):\n  def OnDone(self):\n    evt.EmitIf(self.onDone)\n\n  def run(self,edit,onDone=None):\n    self.onDone = onDone\n    n = db.Get().AtInView(self.view)\n    if(n == None):\n      log.error(\" Failed to find node! Subtree cannot be exported!\")\n      return\n    index = 0\n    for i in range(0,len(n.env._nodes)):\n      if(n == n.env._nodes[i]):\n        index = i\n    if(index == 0):\n      log.error(\" Failed to find node in file! Something is wrong. Cannot export subtree!\")\n      return\n    self.view.run_command('org_export_file_org_html', {\"onDone\": evt.Make(self.OnDone), \"index\": index, \"suffix\":\"_subtree\"})\n"
  },
  {
    "path": "orghtmlexporter.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nimport regex\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcapture as capture\nimport OrgExtended.orgproperties as props\nimport OrgExtended.orgexporter as exp\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orgplist as plist\nimport OrgExtended.orgsourceblock as src\nimport yaml\nimport sys\nimport subprocess\nimport html\n\nlog = logging.getLogger(__name__)\n\n# <!-- multiple_stores height=\"50%\" width=\"50%\" --> \nRE_COMMENT_TAG = re.compile(r\"^\\s*[<][!][-][-]\\s+(?P<name>[a-zA-Z0-9_-]+)\\s+(?P<props>.*)\\s+[-][-][>]\")\n\n\ndef mapLanguage(lang):\n  if(lang == 'html'):\n    return 'language-html'\n  elif(lang == 'python'):\n    return 'language-python'\n  else:\n    return lang\n\ndef haveLang(lang):\n  return True\n\nclass HtmlSourceBlockState(exp.SourceBlockState):\n    def __init__(self,doc):\n        super(HtmlSourceBlockState,self).__init__(doc)\n        self.skipSrc = False\n\n    def HandleOptions(self):\n        attr = self.e.GetAttrib(\"attr_html\")\n        optionsOp = \"\"\n        if(attr):\n            p = plist.PList.createPList(attr)\n        else:\n            p = plist.PList.createPList(\"\")\n        ops = p.Get(\"options\",None)\n        if(ops):\n            optionsOp = ops\n        caption = self.e.GetAttrib(\"caption\")\n        cc = p.Get(\"caption\",None)\n        if(cc):\n            caption = cc\n        floatOp = GetOption(p,\"float\",None)\n        if(caption and not floatOp):\n            floatOp = \"t\"\n        if(floatOp and floatOp != \"nil\"):\n            if(floatOp == \"multicolumn\"):\n                figure = \"figure*\"\n            elif(floatOp == \"sideways\"):\n                figure = \"sidewaysfigure\" \n            elif(floatOp == \"wrap\"):\n                figure = \"wrapfigure\"\n                figureext = \"{l}\"\n        if(optionsOp.strip() != \"\"):\n            optionsOp = \"[\" + optionsOp + \"]\"\n        # There is a discrepancy between orgmode docs and\n        # actual emacs export.. I need to figure this out so\n        # nuke it for now till I understand it\n        optionsOp = \"\"\n        return (optionsOp,floatOp,caption)\n\n    def HandleEntering(self, m, l, orgnode):\n        self.skipSrc = False\n        language = m.group('lang')\n        paramstr = l[len(m.group(0)):]\n        p = type('', (), {})() \n        src.BuildFullParamList(p,language,paramstr,orgnode)\n        exp = p.params.Get(\"exports\",None)\n        # Have to pass on parameter to the results block\n        self.e.sparams = p\n        if(isinstance(exp,list) and len(exp) > 0):\n            exp = exp[0]\n        if(exp == 'results' or exp == 'none'):\n            self.skipSrc = True\n            return\n        # Some languages we skip source by default\n        skipLangs = sets.Get(\"revealDefaultSkipSrc\",[])\n        if((exp == None or exp == \"none\" or exp == \"default\") and language in skipLangs):\n            self.skipSrc = True\n            return\n        skipLangs = sets.Get(\"htmlDefaultSkipSrc\",[])\n        if((exp == None or exp == \"none\" or exp == \"default\") and language in skipLangs):\n            self.skipSrc = True\n            return\n\n        if exp == 'default':\n            exp = 'code'\n\n        attribs = \"\"\n        if(p.params.Has(\"data-noescape\")):\n            attribs += \" data-noescape\"\n        if(p.params.Has('data-trim')):\n            attribs += \" data-trim\"\n        if(p.params.Has(\"data-line-numbers\")):\n            attribs += \" data-line-numbers=\\\"{nums}\\\"\".format(nums=p.params.Get(\"data-line-numbers\",1))\n        self.options, self.float, self.caption = self.HandleOptions()\n        if(haveLang(language)):\n            self.e.doc.append(\"    <pre><code language=\\\"{language}\\\" {attribs}>\".format(language=mapLanguage(language),attribs=attribs))\n        else:\n            self.e.doc.append(\"    <pre><code {attribs}>\".format(attribs=attribs))\n\n    def HandleExiting(self, m, l , orgnode):\n        if(not self.skipSrc):\n            self.e.doc.append(r\"  </code></pre>\")\n        skipSrc = False\n\n    def HandleIn(self,l, orgnode):\n        if(not self.skipSrc):\n            self.e.doc.append(l)\n\n# Skips over contents not intended for an http buffer\nclass HtmlExportBlockState(exp.ExportBlockState):\n    def __init__(self,doc):\n        super(HtmlExportBlockState,self).__init__(doc)\n        self.skipExport = False\n\n    def HandleEntering(self, m, l, orgnode):\n        self.skipExport = False\n        language = m.group('lang').strip().lower()\n        if(language != \"http\"):\n            self.skipExport = True\n            return\n\n    def HandleExiting(self, m, l , orgnode):\n        self.skipExport = False\n\n    def HandleIn(self,l, orgnode):\n        if(not self.skipExport):\n            self.e.doc.append(l)\n\n\nclass HtmlDynamicBlockState(exp.DynamicBlockState):\n    def __init__(self,doc):\n        super(HtmlDynamicBlockState,self).__init__(doc)\n        self.skip = False\n    def HandleEntering(self,m,l,orgnode):\n        self.skip = False\n        language = m.group('lang')\n        paramstr = l[len(m.group(0)):]\n        p = type('', (), {})() \n        src.BuildFullParamList(p,language,paramstr,orgnode)\n        exp = p.params.Get(\"exports\",None)\n        if(isinstance(exp,list) and len(exp) > 0):\n            exp = exp[0]\n        if(exp == 'results' or exp == 'none'):\n            self.skip = True\n            return\n        self.e.doc.append(r\"  <pre>\")\n    def HandleExiting(self, m, l , orgnode):\n        if(not self.skip):\n            self.e.doc.append(r\"  </pre>\")\n        self.skip = False\n    def HandleIn(self,l, orgnode):\n        if(not self.skip):\n            self.e.doc.append(l)\n\nclass HtmlQuoteBlockState(exp.QuoteBlockState):\n    def __init__(self,doc):\n        super(HtmlQuoteBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.e.doc.append(r\"  <blockquote>\")\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"  </blockquote>\")\n    def HandleIn(self,l, orgnode):\n        self.e.doc.append(l)\n\nclass HtmlNotesBlockState(exp.NotesBlockState):\n    def __init__(self,doc):\n        super(HtmlNotesBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.e.doc.append(\"  <aside class=\\\"notes\\\">\")\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"  </aside>\")\n    def HandleIn(self,l, orgnode):\n        self.e.doc.append(l)\n\nclass HtmlExampleBlockState(exp.ExampleBlockState):\n    def __init__(self,doc):\n        super(HtmlExampleBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.e.doc.append(r\"  <blockquote>\")\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"  </blockquote>\")\n    def HandleIn(self,l, orgnode):\n        self.e.doc.append(l)\n\nclass HtmlGenericBlockState(exp.GenericBlockState):\n    def __init__(self,doc):\n        super(HtmlGenericBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.data = m.group('data').strip().lower()\n        self.e.doc.append(r\"  <pre>\".format(data=self.data))\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"  </pre>\".format(data=self.data))\n    def HandleIn(self,l, orgnode):\n        self.e.doc.append(l)\n\n\nclass HtmlUnorderedListBlockState(exp.UnorderedListBlockState):\n    def __init__(self,doc):\n        super(HtmlUnorderedListBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.e.doc.append(r\"    <ul>\")\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"     </ul>\")\n    def StartHandleItem(self,m,l, orgnode):\n        definit = m.group('definition')\n        if(definit):\n            self.e.doc.append(r\"     <li><b>{definition}</b> \".format(definition=definit))\n        else:\n            self.e.doc.append(r\"     <li> \")\n    def EndHandleItem(self,m,l,orgnode):\n        self.e.doc.append(\"    </li>\")\n\n\nclass HtmlOrderedListBlockState(exp.OrderedListBlockState):\n    def __init__(self,doc):\n        super(HtmlOrderedListBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.e.doc.append(r\"    <ol>\")\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"    </ol>\")\n    def StartHandleItem(self,m,l, orgnode):\n        #data = self.e.Escape(m.group('data'))\n        #self.e.doc.append(r\"     \\item {content}\".format(content=data))\n        definit = m.group('definition')\n        if(definit):\n            self.e.doc.append(r\"     <li><b>{definition}</b> \".format(definition=definit))\n        else:\n            self.e.doc.append(r\"     <li>\")\n    def EndHandleItem(self,m,l,orgnode):\n        self.e.doc.append(\"    </li>\")\n\nclass HtmlCheckboxListBlockState(exp.CheckboxListBlockState):\n    def __init__(self,doc):\n        super(HtmlCheckboxListBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.e.doc.append(r\"    <ul>\")\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"    </ul>\")\n    def StartHandleItem(self,m,l, orgnode):\n        #data = self.e.Escape(m.group('data'))\n        state = m.group('state')\n        definit = m.group('definition')\n        if(definit):\n            #self.e.doc.append(r\"     <li><b>{definition}</b> \".format(definition=definit))\n            if(state == 'x'):\n                self.e.doc.append(\"     <li><input type=\\\"checkbox\\\" checked><b>{definition}</b> \".format(definition=definit))\n            elif(state == '-'):\n                self.e.doc.append(\"     <li><input type=\\\"checkbox\\\"><b>{definition}</b> \".format(definition=definit))\n                #self.e.doc.append(\"     \\item[\\inp] {content}\".format(content=data))\n            else:\n                self.e.doc.append(\"     <li><input type=\\\"checkbox\\\"><b>{definition}</b> \".format(definition=definit))\n        else:\n            if(state == 'x'):\n                self.e.doc.append(\"     <li><input type=\\\"checkbox\\\" checked>\")\n            elif(state == '-'):\n                self.e.doc.append(\"     <li><input type=\\\"checkbox\\\"> \")\n                #self.e.doc.append(\"     \\item[\\inp] {content}\".format(content=data))\n            else:\n                self.e.doc.append(\"     <li><input type=\\\"checkbox\\\"> \")\n    def EndHandleItem(self,m,l,orgnode):\n        self.e.doc.append(\"    </li></input>\")\n\n\nRE_TABLE_SEPARATOR = re.compile(r\"^\\s*[|][-]\")\nclass HtmlTableBlockState(exp.TableBlockState):\n    def __init__(self,doc):\n        super(HtmlTableBlockState,self).__init__(doc)\n        self.tablecnt = 1\n\n    def WriteRow(self,l,orgnode):\n        tds = None\n        if(not RE_TABLE_SEPARATOR.search(l)):\n          tds = l.split('|')\n          if(len(tds) > 3):\n            self.e.doc.append(\"    <tr>\")\n            for td in tds[1:-1]:\n              self.e.doc.append(\"     <th>{0}</th>\".format(self.e.TextFullEscape(td)))\n            self.e.doc.append(\"    </tr>\")\n        else:\n            self.e.doc.append(\"\")\n\n    def HandleEntering(self,m,l,orgnode):\n        attr = self.e.GetAttrib(\"attr_html\")\n        if(attr):\n            p = plist.PList.createPList(attr)\n        else:\n            p = plist.PList.createPList(\"\")\n        caption = self.e.GetAttrib(\"caption\")\n        cc = p.Get(\"caption\",None)\n        if(cc):\n            caption = cc\n        self.e.doc.append(\"  <table>\")\n        if(caption):\n          self.e.doc.append(\"    <caption class=\\\"t-above\\\"><span class=\\\"table-number\\\">Table {index}:</span>{caption}</caption>\".format(index=self.tablecnt,caption=caption))\n        self.WriteRow(l,orgnode)\n        self.e.ClearAttrib()\n\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(\"  </table>\")\n        self.tablecnt += 1\n\n    def HandleIn(self,l, orgnode):\n        self.WriteRow(l, orgnode)\n\nclass HtmlEmptyParser(exp.EmptyParser):\n    def __init__(self,doc):\n        super(HtmlEmptyParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(r\"<br/>\")\n\nclass HtmlActiveDateParser(exp.EmptyParser):\n    def __init__(self,doc):\n        super(HtmlActiveDateParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(r\"<p class=\\\"date\\\">{date}</p>\".format(date=m.group()))\n\nclass HtmlBoldParser(exp.BoldParser):\n    def __init__(self,doc):\n        super(HtmlBoldParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"<b>\\g<data></b>\",m.group()))\n\nclass HtmlItalicsParser(exp.ItalicsParser):\n    def __init__(self,doc):\n        super(HtmlItalicsParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"<i>\\g<data></i>\",m.group()))\n\nclass HtmlUnderlineParser(exp.UnderlineParser):\n    def __init__(self,doc):\n        super(HtmlUnderlineParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"<u>\\g<data></u>\",m.group()))\n\nclass HtmlStrikethroughParser(exp.StrikethroughParser):\n    def __init__(self,doc):\n        super(HtmlStrikethroughParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"<strike>\\g<data></strike>\",m.group()))\n\nclass HtmlCodeParser(exp.CodeParser):\n    def __init__(self,doc):\n        super(HtmlCodeParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"<code>\\g<data></code>\",m.group()))\n\nclass HtmlVerbatimParser(exp.VerbatimParser):\n    def __init__(self,doc):\n        super(HtmlVerbatimParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"<pre>\\g<data></pre>\",m.group()))\n\ndef FindImageFile(view, url):\n    # ABS\n    if(os.path.isabs(url)):\n        return url\n    # Relative\n    if(view != None):\n        curDir = os.path.dirname(view.file_name())\n        filename = os.path.join(curDir, url)\n        if(os.path.isfile(filename)):\n            return filename\n    # In search path\n    searchHere = sets.Get(\"imageSearchPath\",[])\n    for direc in searchHere:\n        filename = os.path.join(direc, url)\n        if(os.path.isfile(filename)):\n            return filename\n    searchHere = sets.Get(\"orgDirs\",[])\n    for direc in searchHere:\n        filename = os.path.join(direc, \"images\", url) \n        if(os.path.isfile(filename)):\n            return filename\n\ndef IsImageFile(fn):\n    # Todo make this configurable\n    if(fn.endswith(\".gif\") or fn.endswith(\".png\") or fn.endswith(\".jpg\") or fn.endswith(\".svg\")):\n        return True\n    return False\n\ndef AddOption(p,name,ops):\n    val = p.Get(name,None)\n    if(val):\n        if(ops != \"\"):\n            ops += \",\"\n        ops += name + \"=\" + val.strip() \n    return ops\n\ndef GetOption(p,name,ops):\n    val = p.Get(name,None)\n    if(val):\n        return val.strip()\n    return ops\n\n# Simple links are easy. The hard part is images, includes and results\nclass HtmlLinkParser(exp.LinkParser):\n    def __init__(self,doc):\n        super(HtmlLinkParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        link = m.group('link').strip()\n        desc = m.group('desc')\n        if(desc):\n            desc = self.e.Escape(desc.strip())\n\n        if(link.startswith(\"file:\")):\n            link = re.sub(r'^file:','',link)\n        view = sublime.active_window().active_view()\n        imgFile = FindImageFile(view,link)\n        if(imgFile and os.path.isfile(imgFile) and IsImageFile(imgFile)):\n            relPath = view.MakeRelativeToMe(imgFile)\n            imagePath = os.path.dirname(relPath)\n            imageToken = os.path.splitext(os.path.basename(relPath))[0]\n            # The figures let this float around to much. I can't control the positioning with\n            # that. Also the scale is crazy at 1.0. So I auto scale to .5? Probably not the best choice.\n            # Attributes will solve this at some point.\n            attr = self.e.GetAttrib(\"attr_reveal\")\n            optionsOp = \"\"\n            floatOp = None\n            figure = \"figure\"\n            align  = \"center\"\n            figureext = \"\"\n            if(attr):\n                p = plist.PList.createPList(attr)\n            else:\n                p = plist.PList.createPList(\"\")\n            ops = p.Get(\"options\",None)\n            if(ops):\n                optionsOp = ops\n            caption = self.e.GetAttrib(\"caption\")\n            cc = p.Get(\"caption\",None)\n            if(cc):\n                caption = cc\n            optionsOp = AddOption(p,\"width\",optionsOp)\n            optionsOp = AddOption(p,\"height\",optionsOp)\n            optionsOp = AddOption(p,\"scale\",optionsOp)\n            val = p.Get(\"center\",None)\n            if(val and val == \"nil\"):\n                align = None\n            if(optionsOp == \"\"):\n                optionsOp = r\"\"\n            extradata = \"\"  \n            tbl = self.e.GetAttrib(\"http_comment\")\n            if(tbl):\n                for cName in tbl.keys():\n                    if(cName in link):\n                        extradata =  \" \" + tbl[cName]\n                        del tbl[cName]\n                        break\n            self.e.doc.append(\"<img src=\\\"{link}\\\" alt=\\\"{desc}\\\"{extradata}/>\".format(link=link,desc=desc,extradata=extradata))\n        else:\n            if(link.startswith(\"http\") or (\"/\" not in link and \"\\\\\" not in link and \".\" not in link)):\n                if(desc):\n                    self.e.doc.append(\"<a href=\\\"{link}\\\">{desc}</a>\".format(link=link,desc=desc))\n                else:\n                    self.e.doc.append(\"<a href=\\\"{link}\\\">{link}</a>\".format(link=link))\n            else:\n                link = re.sub(r\"[:][:][^/].*\",\"\",link)\n                link = link.replace(\"\\\\\",\"/\")\n                text = m.group()\n                if(desc):\n                    self.e.doc.append(\"<a href=\\\"{link}\\\">{desc}</a>\".format(link=link,desc=desc))\n                else:\n                    self.e.doc.append(\"<a href=\\\"{link}\\\">{link}</a>\".format(link=link))\n        self.e.ClearAttrib()\n\n# <<TARGET>>\nclass HtmlTargetParser(exp.TargetParser):\n    def __init__(self,doc):\n        super(HtmlTargetParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(r\"<a name=\\\"{data}\\\"/>\".format(data=m.group('data')))\n\n# Line of html gets emitted\nRE_HTML_HTML = regex.compile(r\"^\\s*[#][+]HTML[:]\\s*(?P<data>.*)\")\nclass HtmlHtmlHtmlParser(exp.LineParser):\n    def __init__(self,doc):\n        super(HtmlHtmlHtmlParser,self).__init__(RE_HTML_HTML, doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(m.group('data').strip())\n\n\n# \nclass HtmlCommentParser(exp.LineParser):\n    def __init__(self,doc):\n        super(HtmlCommentParser,self).__init__(RE_COMMENT_TAG, doc)\n    def HandleLine(self,m,l,n):\n        commentData = m.group('props')\n        commentName = m.group('name')\n        tbl = self.e.GetAttrib(\"http_comment\")\n        if(tbl == None):\n            tbl = {}\n        tbl[commentName] = commentData.strip()\n        self.e.AddAttrib(\"http_comment\", tbl)\n"
  },
  {
    "path": "orginput.sublime-syntax",
    "content": "%YAML1.2\n---\n# See http://www.sublimetext.com/docs/3/syntax.html\nname: orginput\nfile_extensions:\n  - orginput\nscope: source.orginput\nversion: 2\nhidden: true\ncontexts:\n  main:\n    - match: '.*'\n      scope: orginput.text\n"
  },
  {
    "path": "orginsertselected.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\nimport glob\n\nlog = logging.getLogger(__name__)\n\n\n# TODO: Move this to it's own file and give me customId and Tag versions of this.\ninputCommand = None\nclass OrgInput:\n    def __init__(self):\n        self.amRunning = False\n        self.current = None\n        self.havePopup = False\n        self.skipRecalc = False\n        self.isFileBox  = False\n        self.inputpanel = None\n        self.onRecalc   = None\n        global inputCommand\n        inputCommand = self\n\n    def on_done(self, text):\n        global inputCommand\n        inputCommand = None\n        self.inputpanel = None\n        if(None != self.onDone):\n            evt.Get().emit(self.onDone,text)\n\n    def popup(self,content, count = 0):\n        if(None == self.inputpanel):\n            return\n        if(count > 2):\n            return\n        try:\n            if(not self.inputpanel.is_popup_visible()):\n                self.inputpanel.show_popup(content,0,-1) \n                self.havePopup = True\n            else:\n                self.inputpanel.update_popup(content)\n        except Exception as inst:\n            print('Exception on popup? Trying to recreate popup')\n            print(str(inst))\n            self.havePopup = False\n            self.popup(content, count + 1)\n            # This can be brought up after the popup goes away\n            # just ignore it.\n            pass\n\n\n    def redraw(self):\n        if(None == self.inputpanel):\n            return\n        ff = sets.Get(\"input_font_face\",\"Arial\")\n        content = \"<html><body id=\\\"orgselect\\\">\"\n        content += \"\"\"<style>\n        div.orgselect {\n            background-color: #202020;\n            font-family: \"\"\" + ff + \"\"\";\n            padding: 7px;\n            border: 2px solid #73AD21;\n            border-style: none none none solid;\n        }\n        div.currentsel {\n            background-color: #353555;\n        }\n        </style><div class=\\\"orgselect\\\">\"\"\"\n        if(hasattr(self,'matched')):\n            if(not self.current in self.matched and len(self.matched) > 0):\n                self.current = self.matched[0]\n            for i in self.matched:\n                if(i == self.current):\n                    content += \"<div class=\\\"currentsel\\\">\" + i + \"</div>\"\n                else:\n                    content += i + \"<br>\"\n        content += \"</div></body></html>\"\n        #self.inputpanel.show_popup_menu(self.matched,None) \n        #self.inputpanel.show_popup(content,sublime.COOPERATE_WITH_AUTO_COMPLETE,-1) \n        if(None != content and content != \"\"):\n            self.popup(content)\n\n    def findFiles(self,text):\n        self.matched = []\n        if(None != text and len(text) > 1):\n            text = text + \"*\"\n            self.matched = glob.glob(text)\n\n    def recalculate(self,text):\n        if(None == self.inputpanel):\n            return\n        if(None != self.onRecalc):\n            self.matched = [text]\n            return\n        if(not text):\n            return\n        se = re.compile(text.replace(\" \",\".*\"))\n        self.matched = []\n        if(not self.options):\n            return\n        for i in self.options:\n            m = se.search(i)\n            if(m):\n                self.matched.append(i)\n\n    def on_change(self, text):\n        if(None != self.onRecalc):\n            evt.Get().emit(self.onRecalc,text)\n        # When we press down we don't want to recalc the box\n        if(self.skipRecalc):\n            self.skipRecalc = False\n        else:\n            if(self.isFileBox):\n                self.findFiles(text)\n            else:\n                self.recalculate(text)\n        self.redraw()\n\n    def on_cancel(self):\n        global inputCommand\n        inputCommand = None\n        if(self.onDone):\n            evt.Get().emit(self.onDone,None)\n        self.inputpanel.close()\n        self.inputpanel = None\n\n    def down(self):\n        if(not self.amRunning or None == self.inputpanel):\n            return\n        self.skipRecalc = True\n        if(hasattr(self,'matched')):\n            mlen = len(self.matched)\n            for i in range(0,mlen):\n                if(self.matched[i] == self.current):\n                    if(i == (mlen - 1)):\n                        self.current = self.matched[0]\n                    else:\n                        self.current = self.matched[i+1]\n                    self.redraw() \n                    self.inputpanel.ReplaceRegion(self.inputpanel.line(self.inputpanel.text_point(0,0)), self.current)\n                    return\n        self.current = None\n        self.redraw()\n\n    def up(self):\n        if(not self.amRunning or None == self.inputpanel):\n            return\n        self.skipRecalc = True\n        if(hasattr(self,'matched')):\n            mlen = len(self.matched)\n            for i in range(0,mlen):\n                if(self.matched[i] == self.current):\n                    if(i == 0):\n                        self.current = self.matched[mlen - 1]\n                    else:\n                        self.current = self.matched[i-1]\n                    self.redraw() \n                    self.inputpanel.ReplaceRegion(self.inputpanel.line(self.inputpanel.text_point(0,0)), self.current)\n                    return\n        self.current = None\n        self.redraw()\n\n    def run(self, name, options, onDone = None):\n        window = sublime.active_window()\n        self.name    = name\n        self.view    = window.active_view()\n        self.onDone  = onDone\n        self.options = options\n        #self.outputpanel = CreateUniqueViewNamed(\"OrgOptions\")\n        self.inputpanel = self.view.window().show_input_panel(self.name,\"\",self.on_done,self.on_change,self.on_cancel)\n        if(None == self.inputpanel):\n            self.inputpanel = self.view.window().show_input_panel(self.name,\"\",self.on_done,self.on_change,self.on_cancel)\n        self.inputpanel.set_name(\"OrgInput\")\n        self.inputpanel.set_syntax_file(\"Packages/OrgExtended/orginput.sublime-syntax\")\n        self.amRunning = True\n        #self.view.window().show_quick_panel(self.tags, self.on_done, -1, -1)\n\nclass OrgInputDownCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        global inputCommand\n        if(None != inputCommand and inputCommand):\n            inputCommand.down()\n\nclass OrgInputUpCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        global inputCommand\n        if(None != inputCommand and inputCommand):\n            inputCommand.up()\n"
  },
  {
    "path": "orginternalediting.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport OrgExtended.orgparse.node as node\nimport OrgExtended.orgparse.date as orgdate\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\n\n\n\n\n\nclass OrgInternalEraseCommand(sublime_plugin.TextCommand):\n    def run(self, edit, start, end, onDone=None):\n        region = sublime.Region(start, end)\n        self.view.erase(edit, region)\n        # Reload the file automatically when we edit it.\n        file = db.Get().FindInfo(self.view.file_name())\n        if(file != None):\n            file.LoadS(self.view)\n        evt.EmitIf(onDone)\n\nclass OrgInternalReplaceCommand(sublime_plugin.TextCommand):\n    def run(self, edit, start, end, text, onDone=None):\n        region = sublime.Region(start, end)\n        self.view.replace(edit, region, text)\n        # Reload the file automatically when we edit it.\n        file = db.Get().FindInfo(self.view.file_name())\n        if(file != None):\n            file.LoadS(self.view)\n        evt.EmitIf(onDone)\n\nclass OrgInternalInsertCommand(sublime_plugin.TextCommand):\n    def run(self, edit, location, text, onDone=None):\n        self.view.insert(edit, location, text)\n        # Reload the file automatically when we edit it.\n        file = db.Get().FindInfo(self.view.file_name())\n        if(file != None):\n            file.LoadS(self.view)\n        evt.EmitIf(onDone)\n"
  },
  {
    "path": "orginternalhelpers.py",
    "content": "\nimport sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport logging\nimport sys\nimport traceback\nimport yaml\nimport json\n#from jsoncomment import JsonComment\nimport ast\nimport OrgExtended.orgxmlthemeparser as tp\nimport glob\n\nvarre = re.compile(r'var\\((?P<name>[^)]+)\\)')\ncolorre = re.compile(r'#(?P<r>[A-Fa-f0-9][A-Fa-f0-9])(?P<g>[A-Fa-f0-9][A-Fa-f0-9])(?P<b>[A-Fa-f0-9][A-Fa-f0-9])(?P<a>[A-Fa-f0-9][A-Fa-f0-9])?')\n\ntemplate = \"\"\"\n    - match: '{{{{beginsrc}}}}(({match})\\s*)'\n      captures:\n        1: constant.other orgmode.fence.sourceblock\n        2: orgmode.fence.sourceblock\n        3: keyword orgmode.fence.language\n        4: orgmode.fence.sourceblock\n      embed: scope:{source}\n      escape: '{{{{endsrc}}}}'\n      embed_scope: orgmode.sourceblock.content markup.raw.block orgmode.raw.block\n      escape_captures:\n        1: constant.other orgmode.fence.sourceblock\n    - match: '(src_({match}))(\\[[^\\]]+\\])?(\\{{)'\n      captures:\n        1: keyword orgmode.fence.language\n        3: markup.raw.block comment\n        4: constant.other\n      embed: scope:{source}\n      scope: orgmode.sourceblock.inline\n      escape: '(\\}})'\n      escape_captures:\n        1: constant.other\n      embed_scope: markup.raw.block orgmode.raw.block orgmode.sourceblock.content.inline\"\"\"\n\n\nintroBlock = \"\"\"\n\t// GENERATED: By OrgExtended\n\t//\n\t// The generator adds a subset of the orgmode specific scopes.\n\t// The scopes that it has added tend to play an important role\n\t// in making an orgmode buffer operational.\n\t//\n\t// That said, orgmode offers a wide variety of syntax elements for\n\t// you to style as needed. Please see blow for more information\n\t// on some of these scopes.\n\t//\n\t// The preamble scope is one of the more important scopes. In the\n\t// future I hope to produce some ligature fonts that will make the preamble\n\t// scope a thing of the past. For now, the preamble is the scope that hides\n\t// leading stars in your buffer. I find those visually disturbing and\n\t// appreciate working with them being invisible.\n\t//\n\t// The preamble used the pre-defined background color of your theme to\n\t// ensure the stars are invisible.\n\"\"\"\n\n# TODO Create blocks for each of the relevant blocks of markers\n#      Create a set of useful markers with comments about how you can customize them\ncommentBlock = \"\"\"\n\t// GENERATED: By Org Extended\n\t// \n\t// The generator has added a bunch of useful extensions to the color scheme\n\t// That said there is much more than can be done by you to tweak your scheme\n\t// to your hearts content. The following comment block is here to give you\n\t// ideas of what is possible.\n\t//\n\t// On a windows box type Ctrl + Alt + Shift + P\n\t// to get a view of what scopes are in play on the thing you want to style\n\t// This table can help you tweak what you would like to see change\n\t//\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.break\",\n\t//\t\t\"foreground\": \"#ed188a\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.page\",\n\t//\t\t\"foreground\": \"#f5eebf\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.headline\",\n\t//\t\t\"foreground\": \"#14adfa\",\n\t//\t\t\"background\": \"#172822\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.headline2\",\n\t//\t\t\"background\": \"#172822\",\t\t\t\n\t//\t\t\"foreground\": \"#bb86fc\",\n\t//\t\t\"font_style\": \"bold underline\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.headline3\",\n\t//\t\t\"foreground\": \"#03dac5\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.headline4\",\n\t//\t\t\"foreground\": \"#dfe6a1\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.headline5\",\n\t//\t\t\"foreground\": \"#018786\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.headline6\",\n\t//\t\t\"foreground\": \"#afe3de\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t// Links can target these\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.target\",\n\t//\t\t\"foreground\": \"#7c004a\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t// Links can target these\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.target.bracket\",\n\t//\t\t\"foreground\": \"#7c004a\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t// [[LINK]] This is the entire link block\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.link\",\n\t//\t\t\"foreground\": \"#3cd7fa\",\n\t//\t\t\"font_style\": \"\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.link.href\",\n\t//\t\t\"foreground\": \"#9999aa\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.link.text\",\n\t//\t\t\"foreground\": \"#4ce7fd\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//  // Special coloring for email addresses\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.email\",\n\t//\t\t\"foreground\": \"#a188b3\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.deadline\",\n\t//\t\t\"foreground\": \"#d1771d\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.scheduled\",\n\t//\t\t\"foreground\": \"#d1771d\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t// #+PRIORITIES: A B C\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.controltag\",\n\t//\t\t\"foreground\": \"#aaaaaa\",\n\t//\t},\n\t//\t// controltag.text also exists\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.controltag.tag\",\n\t//\t\t\"foreground\": \"#aaaaaa\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t// < DATETIME >\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.datetime\",\n\t//\t\t\"foreground\": \"#b0a497\",\n\t//\t},\n\t//\t// [ DATETIME ]\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.unscheddatetime\",\n\t//\t\t\"foreground\": \"#b0a497\",\n\t//\t},\n\t//\t// CLOSED: SCHEDULED: DEADLINE:\t\t\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.statekeyword\",\n\t//\t\t\"foreground\": \"#d1771d\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.checkbox\",\n\t//\t\t\"foreground\": \"#c9be7b\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.checkbox.checked\",\n\t//\t\t\"foreground\": \"#00FF00\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.checkbox.blocked\",\n\t//\t\t\"foreground\": \"#FF0000\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.tags\",\n\t//\t\t\"foreground\": \"#ded49b\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.tags.headline\",\n\t//\t\t\"foreground\": \"#deff9b\",\n\t//\t},\t\t\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.tack\",\n\t//\t\t\"foreground\": \"#c993c4\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.numberedlist\",\n\t//\t\t\"foreground\": \"#c993c4\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.definition\",\n\t//\t\t\"foreground\": \"#A2E8E4\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.definition.marker\",\n\t//\t\t\"foreground\": \"#E1A2E8\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.follow_up\",\n\t//\t\t\"foreground\": \"#FF0000\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.fence\",\n\t//\t\t\"background\": \"#322830\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.fence.language\",\n\t//\t\t\"background\": \"#322830\",\n\t//\t\t\"foreground\": \"#f1bff2\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.raw.block\",\n\t//\t\t\"background\": \"#252520\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.table.block\",\n\t//\t\t\"background\": \"#272828\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.bold\",\n\t//\t\t\"foreground\": \"#aaffaa\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.italics\",\n\t//\t\t\"foreground\": \"#aaffff\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.underline\",\n\t//\t\t\"foreground\": \"#aaaaff\",\n\t//\t\t\"font_style\": \"underline\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.strikethrough\",\n\t//\t\t\"foreground\": \"#aaaaaa\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.code\",\n\t//\t\t\"foreground\": \"#ffaaff\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgmode.verbatim\",\n\t//\t\t\"foreground\": \"#ffaaaa\",\n\t//\t},\n\"\"\"\n\n\nstateBlock = \"\"\"\n\t// GENERATED: By OrgExtended\n\t//\n\t// States are the build in state flow. While org\n\t// allows you to define your own state flows\n\t// I do not yet have a good way of automatically\n\t// adding those to the syntax and color scheme.\n\t// (I hope to one day have a way to do that)\n\t//\n\t// For now the pre-defined state flows have automatic\n\t// highlighting and any new ones you define will have\n\t// the default. I can of course extend the syntax if desired.\n\"\"\"\n\npriorityBlock = \"\"\"\n\t// GENERATED: By OrgExtended\n\t//\n\t// Much like states I do not have a way to extend the syntax with\n\t// new priorities at this time. I hope to devise a good scheme in\n\t// the future. \n\t//\n\t// That said there is a default set of priorities A,B,C,D,E that\n\t// have automatic coloring. These are the color scheme elements that\n\t// add that coloring.\n\"\"\"\n\nfenceBlock = \"\"\"\n\t// GENERATED: By OrgExtended\n\t//\n\t// Code blocks have a heading BEGIN_SRC and an ending END_SRC\n\t// I find it visually appealing to make these stand out.\n\t// You may have different preferences. NOTE: I use a luminance\n\t// shift expression to make the chosen color work with your color scheme.\n\"\"\"\n\ndatePickerBlock = \"\"\"\n\t// GENERATED: By OrgExtended\n\t// ====== DATE PICKER =====\n\t//\n\t// The date picker is the calendar view widget for selecting dates\n\t// this view has its own color scheme. The defaults are reasonable\n\t// with most color schemes. You may however want to tweak one of these.\n\t//\n\t//\t{\n\t//\t\t\"scope\": \"orgdatepicker.weekendheader\",\n\t//\t\t\"foreground\": \"#5b96f5\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgdatepicker.weekdayheader\",\n\t//\t\t\"foreground\": \"#0762a3\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgdatepicker.monthheader\",\n\t//\t\t\"foreground\": \"#7e4794\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgdatepicker.time\",\n\t//\t\t\"foreground\": \"#aaaaaa\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\"\"\"\n\nagendaIntroBlock = \"\"\"\n\t// GENERATED: By OrgExtended\n\t// ====== AGENDA =====\n\t//\n\t// The agenda has a few unique requirements. It builds some of the blocky\n\t// diagrams using colors that have the same foreground as background.\n\t//\n\t// You can change these colors.\n\"\"\"\n\nagendaHabitBlock = \"\"\"\n\t// GENERATED: By OrgExtended\n\t//\n\t// Habits are a means of tracking repeated tasks in orgmode. The\n\t// agena has limited support for habits. The display shows how often\n\t// you are achieving your habit.\n\"\"\"\n\nagendaWeekEmptyBlock = \"\"\"\n\t// GENERATED: By OrgExtended\n\t// \n\t// The weekly empty scope is how we fill the time blocks\n\t// that are empty in the weekly view. Usually I fill these with\n\t// grey blocks per hour. You may choose otherwise.\n\t// The foreground and background should be the same color\n\t// to avoid showing the control characters.\n\"\"\"\n\nagendaWeekColorsBlock = \"\"\"\n\t// GENERATED: By OrgExtended\n\t// \n\t// The week view uses these numeric week colors to randomly highlight\n\t// tasks to make them appear unique. You can change this pallete as desired.\n\"\"\"\n\nagendaDayColorBlocks = \"\"\"\n\t// GENERATED: By OrgExtended\n\t// \n\t// The day color blocks are used in the day view\n\t// to show how scheduled todos overlap. This is a range\n\t// of colors that show visually how todos fit into your day.\n\t// You can choose the color palette although it is best if\n\t// these colors have the same foreground and background color.\n\"\"\"\n\nagendaNowBlock = \"\"\"\n\t// GENERATED: By OrgExtended\n\t//\n\t// orgagenda.now is the cursor. It is not used by the syntax\n\t// but rather to dynamically insert cursor markers in various\n\t// locations in the agenda. Color as you see fit.\n\"\"\"\n\n\nagendaScopesBlock = \"\"\"\n\t// GENERATED: By OrgExtended\n\t// \n\t// There are more colors you can override in the agenda:\n\t// \n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.header\",\n\t//\t\t\"foreground\": \"#5b96f5\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.dateheader\",\n\t//\t\t\"foreground\": \"#5b96f5\",\n\t//\t\t\"font_style\": \"bold italic underline\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.weekendheader\",\n\t//\t\t\"foreground\": \"#ab96f5\",\n\t//\t\t\"font_style\": \"bold italic underline\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.timeseparator\",\n\t//\t\t\"foreground\": \"#7c7c7d\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.now\",\n\t//\t\t\"foreground\": \"#a88cd4\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.filename\",\n\t//\t\t\"foreground\": \"#76b3ae\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.todo\",\n\t//\t\t\"foreground\": \"#a63229\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.doing\",\n\t//\t\t\"foreground\": \"#d2a2e0\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.blocked\",\n\t//\t\t\"foreground\": \"#FF0000\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.waiting\",\n\t//\t\t\"foreground\": \"#ffff00\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.cancelled\",\n\t//\t\t\"foreground\": \"#bab9b8\",\n\t//\t\t\"font_style\": \"italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.inprogress\",\n\t//\t\t\"foreground\": \"#d2a2e0\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.next\",\n\t//\t\t\"foreground\": \"#3fd9d7\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{   // Hide the week markup in the buffer\n\t//\t\t\"scope\": \"orgagenda.week\",\n\t//\t\t\"foreground\": \"var(bgcol)\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.week.something\",\n\t//\t\t\"foreground\": \"#ffffff\",\n\t//\t\t\"background\": \"#007700\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.week.today\",\n\t//\t\t\"foreground\": \"#f89cf4\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.week.active\",\n\t//\t\t\"foreground\": \"#f8fc00\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.week.activetoday\",\n\t//\t\t\"foreground\": \"#f89cf4\",\n\t//\t\t\"background\": \"#485c00\",\n\t//\t\t\"font_style\": \"bold\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.projecttitle\",\n\t//\t\t\"foreground\": \"#a87932\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.blockseparator\",\n\t//\t\t\"foreground\": \"#4a4a37\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\t//\t{\n\t//\t\t\"scope\": \"orgagenda.monthheader\",\n\t//\t\t\"foreground\": \"#a87932\",\n\t//\t\t\"font_style\": \"bold italic\",\n\t//\t},\n\"\"\"\n\nclass OrgRegenSyntaxTemplateCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\ttemplateFile = os.path.join(sublime.packages_path(),\"OrgExtended\",\"OrgExtended.sublime-syntax-template\")\n\t\toutputFile = os.path.join(sublime.packages_path(),\"OrgExtended\",\"OrgExtended.sublime-syntax\")\n\t\tlanguageList = os.path.join(sublime.packages_path(),\"OrgExtended\",\"languagelist.yaml\")\n\t\ttemplates = \"\"\n\t\twith open(languageList) as file:\n\t\t\tdocuments = yaml.full_load(file)\n\t\t\tfor item in documents:\n\t\t\t\tif 'text' in item:\n\t\t\t\t\titem['source'] = \"text.\" + item['text']\n\t\t\t\telif not 'source' in item:\n\t\t\t\t\titem['source'] = \"source.\" + item['language']\n\t\t\t\telse:\n\t\t\t\t\titem['source'] = \"source.\" + item['source']\n\t\t\t\tif not 'match' in item:\n\t\t\t\t\titem['match'] = item['language']\n\t\t\t\ttemplates += template.format(**item)\n\t\ttemplates += \"\\n\"\n\t\twith open(templateFile) as tfile:\n\t\t\twith open(outputFile, 'w') as ofile:\n\t\t\t\tfor line in tfile.readlines():\n\t\t\t\t\tif(\"{{INSERT_LANGUAGES_HERE}}\" in line):\n\t\t\t\t\t\tofile.write(templates)\n\t\t\t\t\telse:\n\t\t\t\t\t\tofile.write(line)\n\t\t\t#print(templates)\n\ndef findscope(cs, name):\n\tif(name == None):\n\t\treturn None\n\tfor i in cs['rules']:\n\t\tif 'scope' in i and i['scope'] == name:\n\t\t\treturn i\n\treturn None\n\ndef replaceVar(cs,val):\n\tm = varre.match(val)\n\twhile(m):\n\t\tname = m.group('name')\n\t\tdata = cs['variables'][name]\n\t\tval = varre.sub(val,data)\t\n\t\tm = varre.match(val)\n\treturn val\n\ndef expandColor(cs, val):\n\treturn replaceVar(cs,val)\n\ndef getBackground(cs, scope = None):\n\ti = findscope(cs, scope)\n\tif(i):\n\t\tif('background' in i):\n\t\t\treturn expandColor(cs, i['background'])\n\tbg = cs['globals']['background']\n\tif(not bg):\n\t\treturn expandColor(cs, \"#ffffff\")\n\treturn expandColor(cs, bg)\n\nclass OrgCreateColorSchemeFromActiveCommand(sublime_plugin.TextCommand):\n\n\tdef addstates(self, cs):\n\t\tcs['rules'].append({\"COMMENT ORGMODE STATES COMMENT HERE\":\"\"})\n\t\tself.addscope(cs,\"orgmode.state.todo\",      \"#e6ab4c\")\n\t\tself.addscope(cs,\"orgmode.state.blocked\",   \"#FF0000\")\n\t\tself.addscope(cs,\"orgmode.state.done\",      \"#47c94f\")\n\t\tself.addscope(cs,\"orgmode.state.cancelled\", \"#bab9b8\")\n\t\tself.addscope(cs,\"orgmode.state.meeting\",   \"#dec7fc\")\n\t\tself.addscope(cs,\"orgmode.state.phone\",     \"#77ebed\")\n\t\tself.addscope(cs,\"orgmode.state.note\",      \"#d2a2e0\")\n\t\tself.addscope(cs,\"orgmode.state.doing\",     \"#9c9c17\")\n\t\tself.addscope(cs,\"orgmode.state.inprogress\",\"#9c9c17\")\n\t\tself.addscope(cs,\"orgmode.state.next\",      \"#37dae6\")\n\t\tself.addscope(cs,\"orgmode.state.reassigned\",\"#bab9b8\")\n\t\tself.addscope(cs,\"orgmode.state.flag\"      ,\"#77ebed\")\n\t\tself.addscope(cs,\"orgmode.state.cleanup\"   ,\"#e6ab4f\")\n\t\tself.addscope(cs,\"orgmode.state.fixed\"     ,\"#47d04f\")\n\n\tdef addpriorities(self, cs):\n\t\tcs['rules'].append({\"COMMENT ORGMODE PRIORITIES COMMENT HERE\":\"\"})\n\t\tself.addscope(cs,\"orgmode.priority\",\"#c27532\")\n\t\tself.addscope(cs,\"orgmode.priority.value\",\"#f5a55f\")\n\t\tself.addscope(cs,\"orgmode.priority.value.a\",\"#e05a7b\")\n\t\tself.addscope(cs,\"orgmode.priority.value.b\",\"#f59a76\")\n\t\tself.addscope(cs,\"orgmode.priority.value.c\",\"#fab978\")\n\t\tself.addscope(cs,\"orgmode.priority.value.d\",\"#f5d976\")\n\t\tself.addscope(cs,\"orgmode.priority.value.e\",\"#bcbfae\")\n\t\tself.addscope(cs,\"orgmode.priority.value.general\",\"#b59eb5\")\n\n\tdef addagenda(self,cs):\n\t\tcs['rules'].append({\"COMMENT ORGMODE DAYBLOCKS HERE\":\"\"})\n\t\tself.addscope(cs,\"orgagenda.block.1\",\"#623456\",\"#623456\")\n\t\tself.addscope(cs,\"orgagenda.block.2\",\"#007777\",\"#007777\")\n\t\tself.addscope(cs,\"orgagenda.block.3\",\"#999900\",\"#999900\")\n\t\tself.addscope(cs,\"orgagenda.block.4\",\"#007700\",\"#007700\")\n\t\tself.addscope(cs,\"orgagenda.block.5\",\"#aa5522\",\"#aa5522\")\n\t\tself.addscope(cs,\"orgagenda.block.6\",\"#f89cf4\",\"#f89cf4\")\n\t\tself.addscope(cs,\"orgagenda.block.7\",\"#0000ee\",\"#0000ee\")\n\t\t\n\t\tcs['rules'].append({\"COMMENT ORGMODE HABITS HERE\":\"\"})\n\t\tself.addscope(cs,\"orgagenda.habit.didit\",\"#ffffff\",\"#007700\")\n\t\tself.addscope(cs,\"orgagenda.habit.scheduled\",\"#333300\",\"#550000\")\n\t\tself.addscope(cs,\"orgagenda.habit.nothing\",\"#000066\",\"#000066\")\n\n\t\tbg = getBackground(cs)\n\t\tweekEmpty = \"color(\" + bg + \" l(+ 5%))\"\n\t\tcs['rules'].append({\"COMMENT ORGMODE WEEKEMPTY HERE\":\"\"})\n\t\tself.addscope(cs,\"orgagenda.week.empty\", weekEmpty, weekEmpty)\t\n\n\t\tcs['rules'].append({\"COMMENT ORGMODE AGENDA WEEKCOLORS HERE\":\"\"})\n\t\tself.addscope(cs,\"orgagenda.week.done.0\",\"#4f4f4f\")\n\t\tself.addscope(cs,\"orgagenda.week.done.1\",\"#666666\")\n\t\tself.addscope(cs,\"orgagenda.week.0\",\"#550000\")\n\t\tself.addscope(cs,\"orgagenda.week.1\",\"#007700\")\n\t\tself.addscope(cs,\"orgagenda.week.2\",\"#770077\")\n\t\tself.addscope(cs,\"orgagenda.week.3\",\"#0000ff\")\n\t\tself.addscope(cs,\"orgagenda.week.4\",\"#999900\")\n\t\tself.addscope(cs,\"orgagenda.week.5\",\"#007777\")\n\t\tself.addscope(cs,\"orgagenda.week.6\",\"#aa5522\")\n\t\tself.addscope(cs,\"orgagenda.week.7\",\"#cc99cc\")\n\t\tself.addscope(cs,\"orgagenda.week.8\",\"#225522\")\n\t\tself.addscope(cs,\"orgagenda.week.9\",\"#623456\")\n\n\n\t\tself.addscope(cs,\"orgmode.deadline.warning\",\"#999900\",bg)\n\t\tself.addscope(cs,\"orgmode.deadline.overdue\",\"#880088\",bg)\n\t\tself.addscope(cs,\"orgmode.deadline.due\",\"#007700\",bg)\n\n\t\tnow = \"#aaaa00\"\n\t\tif('find_highlight' in cs['globals']):\n\t\t\tnow = cs['globals']['find_highlight']\n\t\tcs['rules'].append({\"COMMENT ORGMODE AGENDA NOW HERE\":\"\"})\n\t\tself.addscope(cs,\"orgagenda.now\",now)\n\n\t\tcs['rules'].append({\"COMMENT ORGMODE AGENDA SCOPES HERE\":\"\"})\n\n\tdef addfences(self, cs):\n\t\tcs['rules'].append({\"COMMENT ORGMODE FENCE COMMENT HERE\":\"\"})\n\t\tbg = getBackground(cs, 'markup.raw.block')\n\t\tbg = \"color(\" + bg + \" l(+ 6%))\"\n\t\tself.addscope(cs,\"orgmode.fence\",None, bg,\"bold\")\n\n\tdef addscope(self, cs, name, fg, bg=None, style=None):\n\t\tif(not findscope(cs, name)):\n\t\t\tscope = {\"scope\": name}\n\t\t\tif(fg):\n\t\t\t\tscope['foreground'] = fg\n\t\t\tif(bg):\n\t\t\t\tscope['background'] = bg\n\t\t\tif(style):\n\t\t\t\tscope['font_style'] = style\n\t\t\tcs['rules'].append(scope)\t\n\n\tdef addpreamble(self, cs):\n\t\tif(not findscope(cs, 'orgmode.preamble')):\n\t\t\tbg = cs['globals']['background']\n\t\t\tcs['rules'].append({\"scope\": \"orgmode.preamble\",\"foreground\": bg, \"background\": bg})\t\n\t\tif('globals' in cs and 'line_highlight' not in cs['globals']):\n\t\t\t# Patch up lineHighlight, I have no idea why the themes seem to be using\n\t\t\t# Camel case for this but this ensures that if the CamelCase version is there\n\t\t\t# we use a color scheme compatible snake case version\n\t\t\tif 'lineHighlight' in cs['globals']:\n\t\t\t\tcs['globals']['line_highlight'] = cs['globals']['lineHighlight']\n\n\tdef run(self, edit):\n\t\tself.settings = sublime.load_settings('Preferences.sublime-settings')\n\t\tself.origColorScheme = self.settings.get(\"color_scheme\",None)\n\t\tif(self.origColorScheme):\n\t\t\tself.colorSchemeData = sublime.load_resource(self.origColorScheme)\n\t\t\tcs = None\n\t\t\tif(\".tmTheme\" in self.origColorScheme):\n\t\t\t\ttry:\n\t\t\t\t\tp = tp.XMLThemeParser(self.colorSchemeData)\n\t\t\t\t\tcs = p.cs\n\t\t\t\texcept:\n\t\t\t\t\tprint(\"Failed to parse tmTheme file: \\n\" + traceback.format_exc())\n\t\t\telse:\n\t\t\t\ttry:\n\t\t\t\t\tcsDat = self.colorSchemeData.replace(\"\\r\",\"\").split('\\n')\n\t\t\t\t\tout = []\n\t\t\t\t\tfor o in csDat:\n\t\t\t\t\t\tif(o.strip().startswith('//') or o.strip() == \"\"):\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\tout.append(o)\n\t\t\t\t\tself.colorSchemeData = '\\n'.join(out)\n\t\t\t\t\tcs = ast.literal_eval(self.colorSchemeData)\n\t\t\t\texcept:\n\t\t\t\t\tprint(\"ERROR: Failed to parse color scheme data\")\n\t\t\t\t\tprint(traceback.format_exc())\n\t\t\t\t\tprint(self.colorSchemeData)\n\t\t\tif(not cs):\n\t\t\t\tprint(\"FAILED TO GENERATE NEW COLOR SCHEME COULD NOT PARSE SCHEME\")\n\t\t\t\treturn\n\t\t\tpath = os.path.join(sublime.packages_path(),\"User\",\"OrgColorSchemes\")\n\t\t\tif(not os.path.exists(path)):\n\t\t\t\tos.mkdir(path)\n\n\t\t\tcs['rules'].append({\"COMMENT ORGMODE INTRO HERE\":\"\"})\n\n\t\t\tself.addpreamble(cs)\n\t\t\tself.addstates(cs)\n\t\t\tself.addfences(cs)\n\t\t\tself.addpriorities(cs)\n\n\n\t\t\tscheme = os.path.basename(self.origColorScheme)\n\t\t\tscheme = os.path.splitext(scheme)[0]\n\t\t\tschemeName = scheme + \"_Org.sublime-color-scheme\"\n\t\t\toutputFile = os.path.join(path, schemeName)\n\t\t\t# ===========================================================\n\t\t\tcs['rules'].append({\"COMMENT ORGMODE SCOPES HERE\":\"\"})\n\t\t\t# ===========================================================\n\t\t\tcs['rules'].append({\"COMMENT ORGMODE DATEPICKER SCOPES HERE\":\"\"})\n\t\t\t# ===========================================================\n\t\t\tcs['rules'].append({\"COMMENT ORGMODE AGENDA INTRO HERE\":\"\"})\n\t\t\t\n\t\t\tself.addagenda(cs)\n\n\t\t\tjsonStr = json.dumps(cs, sort_keys=True, indent=4)\n\n\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE SCOPES HERE\": \"\"',commentBlock)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE INTRO HERE\": \"\"',introBlock)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE FENCE COMMENT HERE\": \"\"',fenceBlock)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE PRIORITIES COMMENT HERE\": \"\"',priorityBlock)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE STATES COMMENT HERE\": \"\"',stateBlock)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE DATEPICKER SCOPES HERE\": \"\"',datePickerBlock)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE AGENDA INTRO HERE\": \"\"',agendaIntroBlock)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE WEEKEMPTY HERE\": \"\"',agendaWeekEmptyBlock)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE DAYBLOCKS HERE\": \"\"',agendaDayColorBlocks)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE HABITS HERE\": \"\"',agendaHabitBlock)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE AGENDA WEEKCOLORS HERE\": \"\"',agendaWeekColorsBlock)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE AGENDA SCOPES HERE\": \"\"',agendaScopesBlock)\n\t\t\tjsonStr = jsonStr.replace('\"COMMENT ORGMODE AGENDA NOW HERE\": \"\"',agendaNowBlock)\n\t\t\t\n\t\t\twith open(outputFile,'w') as ofile:\n\t\t\t\tofile.write(jsonStr)\n\t\t\t\tofile.flush()\n\t\t\tnewColorScheme = \"Packages/User/OrgColorSchemes/\" + schemeName\n\t\t\tprint(\"CHANGING ORIGINAL COLOR SCHEME: \" + self.origColorScheme)\n\t\t\tprint(\"TO COLOR SCHEME: \" + newColorScheme)\n\t\t\t# We need some time for that file to hit the disk before we try to\n\t\t\t# load from them. Sublime is fast so give us a little time here.\n\t\t\tsublime.set_timeout(self.setColorSchemes(newColorScheme), 1000)\n\t\t\t\n\n\tdef setColorSchemes(self, newColorScheme):\n\t\tself.mysettings = sublime.load_settings('OrgExtended.sublime-settings')\n\t\tself.mysettings.set(\"color_scheme\", newColorScheme)\n\t\tsublime.save_settings('OrgExtended.sublime-settings')\n\t\tself.mysettings = sublime.load_settings('orgdatepicker.sublime-settings')\n\t\tself.mysettings.set(\"color_scheme\", newColorScheme)\n\t\tsublime.save_settings('orgdatepicker.sublime-settings')\n\t\tself.mysettings = sublime.load_settings('orgagenda.sublime-settings')\n\t\tself.mysettings.set(\"color_scheme\", newColorScheme)\n\t\tsublime.save_settings('orgagenda.sublime-settings')\n\n\nclass OrgSelectExistingColorSchemeCommand(sublime_plugin.TextCommand):\n\tdef on_done_st4(self, index, modifiers):\n\t\tself.on_done(index)\n\tdef on_done(self, index):\n\t\tif(index < 0):\n\t\t\treturn\n\t\tnewColorScheme = self.files[index]\n\t\tself.mysettings = sublime.load_settings('OrgExtended.sublime-settings')\n\t\tself.mysettings.set(\"color_scheme\", newColorScheme)\n\t\tsublime.save_settings('OrgExtended.sublime-settings')\n\t\tself.mysettings = sublime.load_settings('orgdatepicker.sublime-settings')\n\t\tself.mysettings.set(\"color_scheme\", newColorScheme)\n\t\tsublime.save_settings('orgdatepicker.sublime-settings')\n\t\tself.mysettings = sublime.load_settings('orgagenda.sublime-settings')\n\t\tself.mysettings.set(\"color_scheme\", newColorScheme)\n\t\tsublime.save_settings('orgagenda.sublime-settings')\n\tdef run(self, edit):\n\t\tpath = os.path.join(sublime.packages_path(),\"User\",\"OrgColorSchemes\")\n\t\tself.files = glob.glob(os.path.join(path,\"*.sublime-color-scheme\"))\n\t\ttemp = []\n\t\tfor file in self.files:\n\t\t\tfile = file.replace(sublime.packages_path(),\"\")\n\t\t\tfile = \"Packages\" + file.replace(\"\\\\\",\"/\")\n\t\t\ttemp.append(file)\n\t\tself.files = temp\n\t\tself.files.append(\"Packages/OrgExtended/OrgExtended.sublime-color-scheme\")\n\t\tself.files.append(\"Packages/OrgExtended/OrgExtended-Light.sublime-color-scheme\")\n\t\tif(int(sublime.version()) >= 4096):\n\t\t\tself.view.window().show_quick_panel(self.files, self.on_done_st4, -1, -1)\n\t\telse:\n\t\t\tself.view.window().show_quick_panel(self.files, self.on_done, -1, -1)\n\n\nclass OrgCreateKeymapDocCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tcommandsData = sublime.load_resource(\"Packages/OrgExtended/OrgExtended.sublime-commands\")\n\t\tcommandsData = re.sub(r\"//.*\\n\",\"\\n\",commandsData)\n\t\tcom = ast.literal_eval(commandsData)\n\n\t\tkeymapData = sublime.load_resource(\"Packages/OrgExtended/Default.sublime-keymap\")\n\t\tkeymapData = re.sub(r\"//.*\\n\",\"\",keymapData)\n\t\tkeymapData = re.sub(r\"\\n\\s*\\n\",\"\\n\",keymapData)\n\t\tkeymapData = re.sub(r\"\\r\\s*\\r\",\"\",keymapData)\n\t\tkeys = json.loads(keymapData)\n\t\tcoms = {}\n\t\tfor c in com:\n\t\t\tcmd = c['command']\n\t\t\tcap = c['caption']\n\t\t\tcoms[cmd] = {'cap': cap}\n\n\t\tfor k in keys:\n\t\t\tkks  = k['keys']\t\n\t\t\tcmd  = k['command']\n\t\t\tcntx = \"everywhere\"\n\t\t\tvi   = False\n\t\t\tif('context' in k):\n\t\t\t\tfor i in k['context']:\n\t\t\t\t\tif('key' in i and 'vi_command_mode_aware' == i['key']):\n\t\t\t\t\t\tvi = True\n\t\t\t\t\tif('operand' in i):\n\t\t\t\t\t\tif(isinstance(i['operand'],str)):\n\t\t\t\t\t\t\tcntx = i['operand']\n\t\t\tif(cmd in coms):\n\t\t\t\tif(not 'keys' in coms[cmd]):\n\t\t\t\t\tcoms[cmd]['keys'] = {}\n\t\t\t\tif(vi):\n\t\t\t\t\tcoms[cmd]['keys']['vi'] = kks\n\t\t\t\telse:\n\t\t\t\t\tcoms[cmd]['keys']['norm'] = kks\n\t\t\t\tcoms[cmd]['cntx'] = cntx\n\t\t\t\tcoms[cmd]['vi']   = vi\n\t\t\telse:\n\t\t\t\tif(vi):\n\t\t\t\t\tcoms[cmd] = {'keys': {'vi': kks}, 'cntx': cntx}\n\t\t\t\telse:\n\t\t\t\t\tcoms[cmd] = {'keys': {'norm': kks}, 'cntx': cntx}\n\t\tout = \"\"\n\t\tcontexts = {\"Date Picker\": \"orgdateeditor\", \"Org File\":\"orgmode\", \"Org Agenda\":\"orgagenda\", \"Unbound\":\"\",\"Everywhere\":\"everywhere\", \"Quick Input\": \"orginput\" }\n\t\tfor name,con in contexts.items():\n\t\t\tout += \"* \" + name + \"\\n\"\n\t\t\tout += \" |Normal Keys| Vim Keys | Command|Operation| \\n\"\n\t\t\tout +=\"|-\\n\"\n\t\t\tfor k,i in coms.items():\n\t\t\t\tif(not k.startswith(\"org_\")):\n\t\t\t\t\tcontinue\n\t\t\t\tif(('cntx' in i and con != \"\" and con in i['cntx']) or ('cntx' not in i and con == \"\")): \n\t\t\t\t\tif('keys' in i):\n\t\t\t\t\t\tif('norm' in i['keys']):\n\t\t\t\t\t\t\tout += \"|\" + str(i['keys']['norm']).replace('[','').replace(']','').replace(\"'\",'')\n\t\t\t\t\t\telse:\n\t\t\t\t\t\t\tout += \"|\"\n\t\t\t\t\t\tif('vi' in i['keys']):\n\t\t\t\t\t\t\tout += \"|\" + str(i['keys']['vi']).replace('[','').replace(']','').replace(\"' '\",\"<space>\").replace(\"'\",'')\n\t\t\t\t\t\telse:\n\t\t\t\t\t\t\tout += \"|\"\n\t\t\t\t\telse:\n\t\t\t\t\t\tout += \"||\"\n\t\t\t\t\tif('cap' in i):\n\t\t\t\t\t\tout += \"|\" + i['cap']\n\t\t\t\t\telse:\n\t\t\t\t\t\tout += \"|\"\n\t\t\t\t\tout += \"|\" + k + \"|\\n\"\n\t\t\tout += \"\\n\\n\"\n\t\tself.view.insert(edit,0,out)\n\n\t\tpass\n\n\n\n\n"
  },
  {
    "path": "orglatex.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nimport regex\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcapture as capture\nimport OrgExtended.orgproperties as props\nimport OrgExtended.orgutil.temp as tf\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orgnotifications as notice\nimport OrgExtended.orgextension as ext\nimport OrgExtended.orgsourceblock as src\nimport OrgExtended.orgexporter as exp\nimport OrgExtended.orgplist as plist\nimport yaml\nimport sys\nimport subprocess\nimport html\n\nlog = logging.getLogger(__name__)\n\nlangMap = {\n    \"cpp\": \"C++\",\n    \"python\": \"Python\",\n    \"C\": \"C\",\n    \"perl\": \"Perl\",\n    \"bash\": \"bash\",\n    \"sh\": \"sh\",\n    \"lua\": \"[5.0]Lua\",\n    \"java\": \"Java\",\n    \"php\": \"PHP\",\n    \"xml\": \"XML\",\n    \"lisp\": \"Lisp\",\n    \"sql\": \"SQL\",\n    \"r\": \"R\",\n    \"html\": \"HTML\",\n    \"go\": \"Go\",\n    \"make\": \"make\",\n    \"pascal\": \"Pascal\",\n    \"ruby\": \"Ruby\",\n    \"xsl\": \"XSLT\",\n    \"scala\": \"Scala\",\n    \"erlang\": \"erlang\",\n    \"gnuplot\": \"Gnuplot\",\n}\n\n# overriding it by users settings\nlangMap.update(sets.Get(\"latexListingPackageLang\",langMap))\n\ndef haveLang(lang):\n    return lang in langMap\n\ndef mapLanguage(lang):\n    if(lang in langMap):\n        return langMap[lang]\n    return lang\n\nRE_ATTR = regex.compile(r\"^\\s*[#][+]ATTR_HTML[:](?P<params>\\s+[:](?P<name>[a-zA-Z0-9._-]+)\\s+(?P<value>([^:]|((?<! )[:]))+))+$\")\nRE_ATTR_ORG = regex.compile(r\"^\\s*[#][+]ATTR_ORG[:] \")\nRE_LINK = re.compile(r\"\\[\\[(?P<link>[^\\]]+)\\](\\[(?P<desc>[^\\]]+)\\])?\\]\")\nRE_UL   = re.compile(r\"^(?P<indent>\\s*)(-|[+])\\s+(?P<data>.+)\")\nRE_FN_MATCH = re.compile(r\"\\s*[:]([a-zA-Z0-9-_]+)\\s+([^: ]+)?\\s*\")\nRE_STARTSRC = re.compile(r\"^\\s*#\\+(BEGIN_SRC|begin_src)\\s+(?P<lang>[a-zA-Z0-9]+)\")\nRE_STARTDYN = re.compile(r\"^\\s*#\\+(BEGIN:|begin:)\\s+(?P<lang>[a-zA-Z0-9]+)\")\nRE_ENDSRC = re.compile(r\"^\\s*#\\+(END_SRC|end_src)\")\nRE_ENDDYN = re.compile(r\"^\\s*#\\+(end:|END:)\")\nRE_RESULTS = re.compile(r\"^\\s*#\\+RESULTS.*\")\nRE_TABLE_SEPARATOR = re.compile(r\"^\\s*[|][-]\")\nRE_CHECKBOX         = re.compile(r\"^\\[ \\] \")\nRE_CHECKED_CHECKBOX = re.compile(r\"^\\[[xX]\\] \")\nRE_PARTIAL_CHECKBOX = re.compile(r\"^\\[[-]\\] \")\nRE_EMPTY_LINE = re.compile(r\"^\\s*$\")\n\n\n# <!-- multiple_stores height=\"50%\" width=\"50%\" --> \nRE_COMMENT_TAG = re.compile(r\"^\\s*[<][!][-][-]\\s+(?P<name>[a-zA-Z0-9_-]+)\\s+(?P<props>.*)\\s+[-][-][>]\")\n\n#\\documentclass{article}\n# PREAMBLE\n#\\begin{document}\n#Hello, \\LaTeX\\ world.\n#\\end{document}\n\nsectionTypes = [\nr\"\\chapter{{{heading}}}\",\nr\"\\section{{{heading}}}\",\nr\"\\subsection{{{heading}}}\",\nr\"\\subsubsection{{{heading}}}\",\nr\"\\paragraph{{{heading}}}\",\nr\"\\subparagraph{{{heading}}}\"\n]\n\n\nclass LatexSourceBlockState(exp.SourceBlockState):\n    def __init__(self,doc):\n        super(LatexSourceBlockState,self).__init__(doc)\n        self.skipSrc = False\n\n    def HandleOptions(self):\n        attr = self.e.GetAttrib(\"attr_latex\")\n        optionsOp = \"\"\n        floatOp = None\n        if(attr):\n            p = plist.PList.createPList(attr)\n        else:\n            p = plist.PList.createPList(\"\")\n        ops = p.Get(\"options\",None)\n        if(ops):\n            optionsOp = ops\n        caption = self.e.GetAttrib(\"caption\")\n        cc = p.Get(\"caption\",None)\n        if(cc):\n            caption = cc\n        floatOp = GetOption(p,\"float\",None)\n        if(caption and not floatOp):\n            floatOp = \"t\"\n        if(floatOp and floatOp != \"nil\"):\n            if(floatOp == \"multicolumn\"):\n                figure = \"figure*\"\n            elif(floatOp == \"sideways\"):\n                figure = \"sidewaysfigure\" \n            elif(floatOp == \"wrap\"):\n                figure = \"wrapfigure\"\n                figureext = \"{l}\"\n        if(optionsOp.strip() != \"\"):\n            optionsOp = \"[\" + optionsOp + \"]\"\n        # There is a discrepancy between orgmode docs and\n        # actual emacs export.. I need to figure this out so\n        # nuke it for now till I understand it\n        optionsOp = \"\"\n        return (optionsOp,floatOp,caption)\n\n    def HandleEntering(self, m, l, orgnode):\n        self.skipSrc = False\n        language = m.group('lang')\n        paramstr = l[len(m.group(0)):]\n        p = type('', (), {})() \n        src.BuildFullParamList(p,language,paramstr,orgnode)\n        exp = p.params.Get(\"exports\",None)\n        # Have to pass on parameter to the results block\n        self.e.sparams = p\n        if(isinstance(exp,list) and len(exp) > 0):\n            exp = exp[0]\n        if(exp == 'results' or exp == 'none'):\n            self.skipSrc = True\n            return\n        # Some languages we skip source by default\n        skipLangs = sets.Get(\"latexDefaultSkipSrc\",[])\n        if(exp == None and language == skipLangs):\n            self.skipSrc = True\n            return\n        attribs = \"\"\n        self.options, self.float, self.caption = self.HandleOptions()\n        self.e.doc.append(r\"  \\begin{center}\")\n        self.e.doc.append(r\"  \\centering\")\n        if(haveLang(language)):\n            self.e.doc.append(r\"  \\begin{options}{{lstlisting}}[language={{{lang}}}]\".format(options=self.options,lang=mapLanguage(language)))\n        else:\n            self.e.doc.append(r\"  \\begin{options}{{lstlisting}}\".format(options=self.options))\n\n    def HandleExiting(self, m, l , orgnode):\n        if(not self.skipSrc):\n            self.e.doc.append(r\"  \\end{lstlisting}\")\n            self.e.doc.append(r\"  \\end{center}\")\n        skipSrc = False\n\n    def HandleIn(self,l, orgnode):\n        if(not self.skipSrc):\n            self.e.doc.append(l)\n\n# Skips over contents not intended for a latex buffer\nclass LatexExportBlockState(exp.ExportBlockState):\n    def __init__(self,doc):\n        super(LatexExportBlockState,self).__init__(doc)\n        self.skipExport = False\n\n    def HandleEntering(self, m, l, orgnode):\n        self.skipExport = False\n        language = m.group('lang').strip().lower()\n        if(language != \"latex\"):\n            self.skipExport = True\n            return\n        # We will probably need this in the future.\n        #paramstr = l[len(m.group(0)):]\n        #p = type('', (), {})() \n        #src.BuildFullParamList(p,language,paramstr,orgnode)\n\n    def HandleExiting(self, m, l , orgnode):\n        self.skipExport = False\n\n    def HandleIn(self,l, orgnode):\n        if(not self.skipExport):\n            self.e.doc.append(l)\n\n\nclass LatexDynamicBlockState(exp.DynamicBlockState):\n    def __init__(self,doc):\n        super(LatexDynamicBlockState,self).__init__(doc)\n        self.skip = False\n    def HandleEntering(self,m,l,orgnode):\n        self.skip = False\n        language = m.group('lang')\n        paramstr = l[len(m.group(0)):]\n        p = type('', (), {})() \n        src.BuildFullParamList(p,language,paramstr,orgnode)\n        exp = p.params.Get(\"exports\",None)\n        if(isinstance(exp,list) and len(exp) > 0):\n            exp = exp[0]\n        if(exp == 'results' or exp == 'none'):\n            self.skip = True\n            return\n        self.e.doc.append(r\"  \\begin{verbatim}\")\n    def HandleExiting(self, m, l , orgnode):\n        if(not self.skip):\n            self.e.doc.append(r\"  \\end{verbatim}\")\n        self.skip = False\n    def HandleIn(self,l, orgnode):\n        if(not self.skip):\n            self.e.doc.append(l)\n\nclass LatexQuoteBlockState(exp.QuoteBlockState):\n    def __init__(self,doc):\n        super(LatexQuoteBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.e.doc.append(r\"  \\begin{displayquote}\")\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"  \\end{displayquote}\")\n    def HandleIn(self,l, orgnode):\n        self.e.doc.append(l)\n\nclass LatexExampleBlockState(exp.ExampleBlockState):\n    def __init__(self,doc):\n        super(LatexExampleBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.e.doc.append(r\"  \\begin{verbatim}\")\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"  \\end{verbatim}\")\n    def HandleIn(self,l, orgnode):\n        self.e.doc.append(l)\n\nclass LatexGenericBlockState(exp.GenericBlockState):\n    def __init__(self,doc):\n        super(LatexGenericBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.data = m.group('data').strip().lower()\n        self.e.doc.append(r\"  \\begin{{{data}}}\".format(data=self.data))\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"  \\end{{{data}}}\".format(data=self.data))\n    def HandleIn(self,l, orgnode):\n        self.e.doc.append(l)\n\n\nclass LatexUnorderedListBlockState(exp.UnorderedListBlockState):\n    def __init__(self,doc):\n        super(LatexUnorderedListBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.e.doc.append(r\"    \\begin{itemize}\")\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"     \\end{itemize}\")\n    def StartHandleItem(self,m,l, orgnode):\n        #data = self.e.Escape(m.group('data'))\n        #self.e.doc.append(r\"     \\item {content}\".format(content=data))\n        definit = m.group('definition')\n        if(definit):\n            self.e.doc.append(r\"     \\item``{definition}'' \".format(definition=definit))\n        else:\n            self.e.doc.append(r\"     \\item \")\n\n\nclass LatexOrderedListBlockState(exp.OrderedListBlockState):\n    def __init__(self,doc):\n        super(LatexOrderedListBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.e.doc.append(r\"    \\begin{enumerate}\")\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"     \\end{enumerate}\")\n    def StartHandleItem(self,m,l, orgnode):\n        #data = self.e.Escape(m.group('data'))\n        #self.e.doc.append(r\"     \\item {content}\".format(content=data))\n        definit = m.group('definition')\n        if(definit):\n            self.e.doc.append(r\"     \\item``{definition}'' \".format(definition=definit))\n        else:\n            self.e.doc.append(r\"     \\item \")\n\nclass LatexCheckboxListBlockState(exp.CheckboxListBlockState):\n    def __init__(self,doc):\n        super(LatexCheckboxListBlockState,self).__init__(doc)\n    def HandleEntering(self,m,l,orgnode):\n        self.e.doc.append(r\"    \\begin{todolist}\")\n    def HandleExiting(self, m, l , orgnode):\n        self.e.doc.append(r\"     \\end{todolist}\")\n    def StartHandleItem(self,m,l, orgnode):\n        #data = self.e.Escape(m.group('data'))\n        state = m.group('state')\n        if(state == 'x'):\n            self.e.doc.append(r\"     \\item[\\wontfix] \")\n        elif(state == '-'):\n            self.e.doc.append(r\"     \\item \")\n            #self.e.doc.append(r\"     \\item[\\inp] {content}\".format(content=data))\n        else:\n            self.e.doc.append(r\"     \\item \")\n        #if(state == 'x'):\n        #    self.e.doc.append(r\"     \\item[\\wontfix] {content}\".format(content=data))\n        #elif(state == '-'):\n        #    self.e.doc.append(r\"     \\item {content}\".format(content=data))\n        #    #self.e.doc.append(r\"     \\item[\\inp] {content}\".format(content=data))\n        #else:\n        #    self.e.doc.append(r\"     \\item {content}\".format(content=data))\n\nclass LatexTableBlockState(exp.TableBlockState):\n    def __init__(self,doc):\n        super(LatexTableBlockState,self).__init__(doc)\n        self.tablecnt = 1\n    def HandleEntering(self,m,l,orgnode):\n        attr = self.e.GetAttrib(\"attr_latex\")\n        floatOp = None\n        align  = \"center\"\n        self.modeDelimeterStart = \"\"\n        self.modeDelimeterEnd   = \"\"\n        self.environment = \"tabular\"\n        self.figure = \"center\"\n        figureext = \"\"\n        if(attr):\n            p = plist.PList.createPList(attr)\n        else:\n            p = plist.PList.createPList(\"\")\n        caption = self.e.GetAttrib(\"caption\")\n        cc = p.Get(\"caption\",None)\n        if(cc):\n            caption = cc\n        self.environment = GetOption(p,\"environment\",self.environment)\n        mode = GetOption(p,\"mode\",None)\n        if(mode == \"math\"):\n            self.modeDelimeterStart = r\"\\[\"\n            self.modeDelimeterEnd   = r\"\\]\"\n        if(mode == \"inline-math\"):\n            self.modeDelimeterStart = r\"\\(\"\n            self.modeDelimeterEnd   = r\"\\)\"\n        val = p.Get(\"center\",None)\n        if(val and val == \"nil\"):\n            align = None\n        floatOp = GetOption(p,\"float\",None)\n        if(caption and not floatOp):\n            floatOp = \"t\"\n        if(floatOp and floatOp != \"nil\"):\n            if(floatOp):\n                self.figure = \"table\"\n                figureext = \"[!htp]\"\n            if(floatOp == \"multicolumn\"):\n                self.figure = \"table*\"\n            elif(floatOp == \"sideways\"):\n                self.figure = \"sidewaysfigure\" \n            elif(floatOp == \"wrap\"):\n                self.figure = \"wrapfigure\"\n                figureext = \"{l}\"\n            placement = p.Get(\"placement\",None)\n            if(placement):\n                figureext = placement\n        tabledef = \"\"\n        tds = None\n        if(not RE_TABLE_SEPARATOR.search(l)):\n            tds = l.split('|')\n            if(len(tds) > 1):\n                if(mode == \"math\"):\n                    tabledef = \"\"\n                else:\n                    tabledef = \"{\" + (\"|c\" * (len(tds)-2)) + \"|}\" \n        self.e.doc.append(r\"    \\begin{{{figure}}}{figureext}\".format(figure=self.figure,figureext=figureext))\n        if(caption):\n            self.e.doc.append(r\"    \\caption{{{caption}}}\".format(caption=self.e.GetAttrib('caption')))\n            #self.fs.write(\"    <caption class=\\\"t-above\\\"><span class=\\\"table-number\\\">Table {index}:</span>{caption}</caption>\".format(index=self.tableIndex,caption=self.caption))\n            #self.tableIndex += 1\n        if(align == \"center\" and self.environment == 'tabular'):\n            self.e.doc.append(r\"    \\centering\\renewcommand{\\arraystretch}{1.2}\")\n        self.e.doc.append(self.modeDelimeterStart)\n        self.e.doc.append(r\"    \\begin{{{environment}}}{tabledef}\".format(tabledef=tabledef,environment=self.environment))\n        self.e.ClearAttrib()\n        if(self.environment == 'tabular'):\n            self.e.doc.append(r\"    \\hline\") \n        if(tds):\n            self.HandleData(tds,True)\n    def HandleExiting(self, m, l , orgnode):\n        if(self.environment == 'tabular'):\n            self.e.doc.append(r\"    \\hline\") \n        self.e.doc.append(r\"    \\end{{{environment}}}\".format(environment=self.environment))\n        self.e.doc.append(self.modeDelimeterEnd)\n        self.e.doc.append(r\"    \\label{{table:{cnt}}}\".format(cnt=self.tablecnt))\n        self.e.doc.append(r\"    \\end{{{figure}}}\".format(figure=self.figure))\n        self.tablecnt += 1\n\n    def HandleData(self,tds,head=False): \n        if(len(tds) > 3):\n            # An actual table row, build a row\n            first = True\n            line = \"    \"\n            for td in tds[1:-1]:\n                if(not first):\n                    line += \" & \"\n                first = False\n                if(head and self.environment == 'tabular'):\n                    line += r\"\\textbf{{{data}}}\".format(data=self.e.Escape(td))\n                else:\n                    line += self.e.Escape(td)\n            line += \" \\\\\\\\\"\n            self.e.doc.append(line)\n            haveTableHeader = True\n\n    def HandleIn(self,l, orgnode):\n        if(RE_TABLE_SEPARATOR.search(l)):\n            self.e.doc.append(r'    \\hline')\n        else:\n            tds = l.split('|')\n            self.HandleData(tds)\n\nclass LatexHrParser(exp.HrParser):\n    def __init__(self,doc):\n        super(LatexHrParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(r\"\\newline\\noindent\\rule{\\textwidth}{0.5pt}\")\n\nclass LatexNameParser(exp.NameParser):\n    def __init__(self,doc):\n        super(LatexNameParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(r\"\\label{{{data}}}\".format(data=m.group('data')))\n\n\nclass LatexMathParser(exp.MathParser):\n    def __init__(self,doc):\n        super(LatexMathParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(r\"\\({data}\\)\".format(data=m.group('data')))\n\nclass LatexInlineMathParser(exp.InlineMathParser):\n    def __init__(self,doc):\n        super(LatexInlineMathParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(r\"\\({data}\\)\".format(data=m.group('data')))\n\nclass LatexEqMathParser(exp.EqMathParser):\n    def __init__(self,doc):\n        super(LatexEqMathParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(r\"\\[{data}\\]\".format(data=m.group('data')))\n\nclass LatexEmptyParser(exp.EmptyParser):\n    def __init__(self,doc):\n        super(LatexEmptyParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(r\"\\leavevmode\\newline\")\n\nclass LatexActiveDateParser(exp.EmptyParser):\n    def __init__(self,doc):\n        super(LatexActiveDateParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(r\"\\textit{{{date}}}\".format(date=m.group()))\n\nclass LatexBoldParser(exp.BoldParser):\n    def __init__(self,doc):\n        super(LatexBoldParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"\\\\textbf{\\g<data>}\",m.group()))\n\nclass LatexItalicsParser(exp.ItalicsParser):\n    def __init__(self,doc):\n        super(LatexItalicsParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"\\\\textit{\\g<data>}\",m.group()))\n\nclass LatexUnderlineParser(exp.UnderlineParser):\n    def __init__(self,doc):\n        super(LatexUnderlineParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"\\\\underline{\\g<data>}\",m.group()))\n\nclass LatexStrikethroughParser(exp.StrikethroughParser):\n    def __init__(self,doc):\n        super(LatexStrikethroughParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"\\\\sout{\\g<data>}\",m.group()))\n\nclass LatexCodeParser(exp.CodeParser):\n    def __init__(self,doc):\n        super(LatexCodeParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"\\\\texttt{\\g<data>}\",m.group()))\n\nclass LatexVerbatimParser(exp.VerbatimParser):\n    def __init__(self,doc):\n        super(LatexVerbatimParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(self.sre.sub(r\"\\\\texttt{\\g<data>}\",m.group()))\n\nRE_LATEXKEYWORD = regex.compile(r\"^\\s*\\\\newline\\s*$\")\nclass LatexKeywordParser(exp.SubLineParser):\n    def __init__(self,doc):\n        super(LatexKeywordParser,self).__init__(RE_LATEXKEYWORD,doc)\n    def HandleSegment(self,m,l,orgnode):\n        self.e.doc.append(m.group().strip())\n\ndef FindImageFile(view, url):\n    # ABS\n    if(os.path.isabs(url)):\n        return url\n    # Relative\n    if(view != None):\n        curDir = os.path.dirname(view.file_name())\n        filename = os.path.join(curDir, url)\n        if(os.path.isfile(filename)):\n            return filename\n    # In search path\n    searchHere = sets.Get(\"imageSearchPath\",[])\n    for direc in searchHere:\n        filename = os.path.join(direc, url)\n        if(os.path.isfile(filename)):\n            return filename\n    searchHere = sets.Get(\"orgDirs\",[])\n    for direc in searchHere:\n        filename = os.path.join(direc, \"images\", url) \n        if(os.path.isfile(filename)):\n            return filename\n\ndef IsImageFile(fn):\n    # Todo make this configurable\n    if(fn.endswith(\".gif\") or fn.endswith(\".png\") or fn.endswith(\".jpg\") or fn.endswith(\".svg\")):\n        return True\n    return False\n\ndef AddOption(p,name,ops):\n    val = p.Get(name,None)\n    if(val):\n        if(ops != \"\"):\n            ops += \",\"\n        ops += name + \"=\" + val.strip() \n    return ops\n\ndef GetOption(p,name,ops):\n    val = p.Get(name,None)\n    if(val):\n        return val.strip()\n    return ops\n\n# Simple links are easy. The hard part is images, includes and results\nclass LatexLinkParser(exp.LinkParser):\n    def __init__(self,doc):\n        super(LatexLinkParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        link = m.group('link').strip()\n        desc = m.group('desc')\n        if(desc):\n            desc = self.e.Escape(desc.strip())\n        if(link.startswith(\"file:\")):\n            link = re.sub(r'^file:','',link)\n        view = sublime.active_window().active_view()\n        imgFile = FindImageFile(view,link)\n        if(imgFile and os.path.isfile(imgFile) and IsImageFile(imgFile)):\n            relPath = view.MakeRelativeToMe(imgFile)\n            imagePath = os.path.dirname(relPath)\n            imageToken = os.path.splitext(os.path.basename(relPath))[0]\n            # The figures let this float around to much. I can't control the positioning with\n            # that. Also the scale is crazy at 1.0. So I auto scale to .5? Probably not the best choice.\n            # Attributes will solve this at some point.\n            attr = self.e.GetAttrib(\"attr_latex\")\n            optionsOp = \"\"\n            floatOp = None\n            figure = \"figure\"\n            align  = \"center\"\n            figureext = \"\"\n            if(attr):\n                p = plist.PList.createPList(attr)\n            else:\n                p = plist.PList.createPList(\"\")\n            ops = p.Get(\"options\",None)\n            if(ops):\n                optionsOp = ops\n            caption = self.e.GetAttrib(\"caption\")\n            cc = p.Get(\"caption\",None)\n            if(cc):\n                caption = cc\n            optionsOp = AddOption(p,\"width\",optionsOp)\n            optionsOp = AddOption(p,\"height\",optionsOp)\n            optionsOp = AddOption(p,\"scale\",optionsOp)\n            val = p.Get(\"center\",None)\n            if(val and val == \"nil\"):\n                align = None\n            if(optionsOp == \"\"):\n                optionsOp = r\"width=.8\\linewidth\"\n            if(caption and not floatOp):\n                floatOp = \"t\"\n            if(floatOp and floatOp != \"nil\"):\n                if(floatOp == \"multicolumn\"):\n                    figure = \"figure*\"\n                elif(floatOp == \"sideways\"):\n                    figure = \"sidewaysfigure\" \n                elif(floatOp == \"wrap\"):\n                    figure = \"wrapfigure\"\n                    figureext = \"{l}\"\n                placement = p.Get(\"placement\",None)\n                if(placement):\n                    figureext = placement\n                self.e.doc.append(r\"\\begin{{{figure}}}{figureext}\".format(figure=figure,figureext=figureext))\n                if(align == \"center\"):\n                    self.e.doc.append(r\"\\centering\")\n            self.e.doc.append(r\"\\includegraphics[{options}]{{{name}}}\".format(name=imageToken,options=optionsOp))\n            if(caption):\n                self.e.doc.append(r\"\\caption{{{caption}}}\".format(caption=caption))\n            if(floatOp and floatOp != \"nil\"):\n                self.e.doc.append(r\"\\end{{{figure}}}\".format(figure=figure))\n            if(not imagePath in self.e.imagepaths):\n                self.e.imagepaths.append(imagePath)\n        else:\n            if(link.startswith(\"http\")):\n                if(desc):\n                    self.e.doc.append(r\"\\href{{{link}}}{{{desc}}}\".format(link=link,desc=desc))\n                else:\n                    self.e.doc.append(r\"\\url{{{link}}}\".format(link=link))\n            elif(\"/\" not in link and \"\\\\\" not in link and \".\" not in link):\n                if(desc):\n                    self.e.doc.append(r\"\\hyperref[{link}]{{{desc}}}\".format(link=link,desc=desc))\n                else:\n                    self.e.doc.append(r\"\\hyperref[{link}]{{{desc}}}\".format(link=link,desc=self.e.Escape(link)))\n            else:\n                link = re.sub(r\"[:][:][^/].*\",\"\",link)\n                link = link.replace(\"\\\\\",\"/\")\n                text = m.group()\n                if(desc):\n                    self.e.doc.append(r\"\\href{{{link}}}{{{desc}}}\".format(link=link,desc=desc))\n                else:\n                    self.e.doc.append(r\"\\url{{{link}}}\".format(link=link))\n        self.e.ClearAttrib()\n\n# <<TARGET>>\nclass LatexTargetParser(exp.TargetParser):\n    def __init__(self,doc):\n        super(LatexTargetParser,self).__init__(doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(r\"\\label{{{data}}}\".format(data=m.group('data')))\n\nclass LatexLatexHeaderParser(exp.LatexHeaderParser):\n    def __init__(self,doc):\n        super(LatexLatexHeaderParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.pre.append(m.group('data').strip())\n\nclass LatexLatexClassOptionsParser(exp.LatexClassOptionsParser):\n    def __init__(self,doc):\n        super(LatexLatexClassOptionsParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.documentclass += m.group('data').strip()\n\n# Outputs latex verbatim but in a line\nRE_LATEX_SUBLATEX = regex.compile(r\"[@][@](?P<data>.*)[@][@]\")\nclass LatexLatexSubLatexParser(exp.SubLineParser):\n    def __init__(self,doc):\n        super(LatexLatexSubLatexParser,self).__init__(RE_LATEX_SUBLATEX, doc)\n    def HandleSegment(self,m,l,n):\n        self.e.doc.append(m.group('data').strip())\n\n# Line of latex gets emitted\nRE_LATEX_LATEX = regex.compile(r\"^\\s*[#][+]LATEX[:]\\s*(?P<data>.*)\")\nclass LatexLatexLatexParser(exp.LineParser):\n    def __init__(self,doc):\n        super(LatexLatexLatexParser,self).__init__(RE_LATEX_LATEX, doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(m.group('data').strip())\n\nRE_ATTR_LATEX = regex.compile(r\"^\\s*[#][+]ATTR_LATEX[:]\\s*(?P<data>.*)\")\nclass LatexAttributeParser(exp.AttributeParser):\n    def __init__(self,doc):\n        super(LatexAttributeParser,self).__init__('attr_latex',RE_ATTR_LATEX,doc)\n\nclass LatexDoc(exp.OrgExporter):\n    def __init__(self,filename,file,**kwargs):\n        super(LatexDoc, self).__init__(filename, file, **kwargs)\n        self.file = file\n        self.sparams = None\n        self.documentclass = r'\\documentclass{article}'\n        self.imagepaths = []\n        self.pre      = []\n        self.doc      = []\n        self.attribs  = {}\n        self.amInBlock = False\n        # TODO: Make this configurable\n        self.pre.append(r\"\\usepackage[utf8]{inputenc}\")\n        self.pre.append(r\"\\usepackage{listings}\")\n        self.pre.append(r\"\\usepackage{hyperref}\")\n        self.pre.append(r\"\\usepackage{csquotes}\")\n        self.pre.append(r\"\\usepackage{makecell, caption}\")\n        self.pre.append(r\"\\usepackage[T1]{fontenc}\")\n        self.pre.append(r\"\\usepackage[greek,english]{babel}\")\n        self.pre.append(r\"\\usepackage{CJKutf8}\")\n        self.pre.append(r\"\\usepackage{graphicx}\")\n        self.pre.append(r\"\\usepackage{grffile}\")\n        self.pre.append(r\"\\usepackage{longtable}\")\n        self.pre.append(r\"\\usepackage{wrapfig}\")\n        self.pre.append(r\"\\usepackage{rotating}\")\n        self.pre.append(r\"\\usepackage{textcomp}\")\n        self.pre.append(r\"\\usepackage{capt-of}\")\n        self.pre.append(r\"\\usepackage{amsmath}\")\n        self.pre.append(r\"\\usepackage{amssymb}\")\n        # Needed for strikethrough\n        self.pre.append(r\"\\usepackage[normalem]{ulem}\")\n        # Checkbox Setup\n        self.pre.append(r\"\\usepackage{enumitem,amssymb}\")\n        self.pre.append(r\"\\newlist{todolist}{itemize}{2}\")\n        self.pre.append(r\"\\setlist[todolist]{label=$\\square$}\")\n        self.pre.append(r\"\\usepackage{pifont}\")\n        self.pre.append(r\"\\newcommand{\\cmark}{\\ding{51}}%\")\n        self.pre.append(r\"\\newcommand{\\xmark}{\\ding{55}}%\")\n        self.pre.append(r\"\\newcommand{\\tridot}{\\ding{213}}%\")\n        self.pre.append(r\"\\newcommand{\\inp}{\\rlap{$\\square$}{\\large\\hspace{1pt}\\tridot}}\")\n        self.pre.append(r\"\\newcommand{\\done}{\\rlap{$\\square$}{\\raisebox{2pt}{\\large\\hspace{1pt}\\cmark}}%\")\n        self.pre.append(r\"\\hspace{-2.5pt}}\")\n        self.pre.append(r\"\\newcommand{\\wontfix}{\\rlap{$\\square$}{\\large\\hspace{1pt}\\xmark}}\")\n        #self.pre.append(r\"\\usepackage{flafter}\") \n        self.nodeParsers = [\n        exp.SetupFileParser(self),\n        exp.CaptionAttributeParser(self),\n        LatexAttributeParser(self),\n        exp.ResultsParser(self),\n        LatexTableBlockState(self),\n        LatexSourceBlockState(self),\n        LatexDynamicBlockState(self),\n        LatexQuoteBlockState(self),\n        LatexExampleBlockState(self),\n        LatexCheckboxListBlockState(self),\n        LatexUnorderedListBlockState(self),\n        LatexOrderedListBlockState(self),\n        LatexExportBlockState(self),\n        LatexGenericBlockState(self),\n        exp.DrawerBlockState(self),\n        exp.SchedulingStripper(self),\n        exp.TblFmStripper(self),\n        exp.AttrHtmlStripper(self),\n        exp.AttrOrgStripper(self),\n        exp.KeywordStripper(self),\n        LatexEmptyParser(self),\n        LatexLinkParser(self),\n        LatexHrParser(self),\n        LatexNameParser(self),\n        LatexLatexHeaderParser(self),\n        LatexLatexClassOptionsParser(self),\n        LatexLatexLatexParser(self),\n        LatexActiveDateParser(self),\n        LatexMathParser(self),\n        LatexLatexSubLatexParser(self),\n        LatexInlineMathParser(self),\n        LatexEqMathParser(self),\n        LatexBoldParser(self),\n        LatexItalicsParser(self),\n        LatexUnderlineParser(self),\n        LatexStrikethroughParser(self),\n        LatexCodeParser(self),\n        LatexVerbatimParser(self),\n        LatexKeywordParser(self),\n        LatexTargetParser(self)\n        ]\n\n    def SetAmInBlock(self,inBlock):\n        self.amInBlock = inBlock\n\n    def AmInBlock(self):\n        return self.amInBlock\n\n    def AddAttrib(self,name,val):\n        self.attribs[name] = val.strip()\n    \n    def GetAttrib(self,name):\n        if(name in self.attribs):\n            return self.attribs[name]\n        return None\n\n    def ClearAttrib(self):\n        self.attribs.clear()\n\n    def setClass(self,className):\n        self.documentclass = r'\\documentclass{{{docclass}}}'.format(docclass=className)\n\n    def BuildDoc(self):\n        imagepaths = \"\"\n        if(len(self.imagepaths) > 0):\n            imagepaths = r\"\\graphicspath{\"\n            for i in self.imagepaths:\n                item = i.replace(\"\\\\\",\"/\").strip()\n                if(not item.endswith(\"/\")):\n                    item += \"/\"\n                if(not item.startswith(\".\")):\n                    item = \"./\" + item\n                imagepaths += \"{\" + item + \"}\"\n            imagepaths += \"}\"\n        toc = [r\"\\maketitle\",r\"\\tableofcontents\"]\n        # Use our options to control the title and toc\n        ops = self.file.org.get_comment(\"OPTIONS\",None)\n        if(ops):\n            ops = \" \".join(ops)\n            ops = ops.strip().split(\" \")\n            if(\"toc:nil\" in ops):\n                toc.remove(r\"\\tableofcontents\")\n            if(\"title:nil\" in ops):\n                toc.remove(r\"\\maketitle\")\n            if(\"author:nil\" in ops):\n                for l in self.pre:\n                    if(l.startswith(\"\\\\author\")):\n                        self.pre.remove(l)\n                        break\n            if(\"date:nil\" in ops):\n                for l in self.pre:\n                    if(l.startswith(\"\\\\date\")):\n                        self.pre.remove(l)\n                        break\n                self.pre.append(\"\\\\date{}\")\n            for t in ops:\n                if(t.startswith(\"toc:\")):\n                    v = t.split(\":\")[1].strip()\n                    try:\n                        v = int(v)\n                        if(v > 0):\n                            toc.insert(0,\"\\\\setcounter{{tocdepth}}{{{num}}}\".format(num=v))\n                    except:\n                        pass\n        out = self.documentclass + '\\n' + '\\n'.join(self.pre) + '\\n'+ imagepaths +\"\\n\" +  r'\\begin{document}' + '\\n' + \"\\n\".join(toc) + '\\n' + '\\n'.join(self.doc) + '\\n' + r'\\end{document}' + '\\n'\n        return out\n\n    # Document header metadata should go in here\n    def AddExportMetaCustom(self):\n        if(self.author):\n            self.pre.append(r\"\\author{{{data}}}\".format(data=self.author))\n        if(self.title):\n            self.pre.append(r\"\\title{{{data}}}\".format(data=self.title))\n        if(self.date):\n            self.pre.append(r\"\\date{{{data}}}\".format(data=self.date))\n        pass\n\n    # Setup to start the export of a node\n    def StartNode(self, n):\n        pass \n\n    def Escape(self,str):\n        str,cnt = self.SingleLineReplacements(str)\n        if(0 == cnt):\n            return self.TexFullEscape(str)\n        elif(1 == cnt):\n            return self.TexCommandEscape(str)\n        else:\n            return str\n\n    def TexFullEscape(self,text):\n        conv = {\n        '&': r'\\&',\n        '%': r'\\%',\n        '$': r'\\$',\n        '#': r'\\#',\n        '_': r'\\_',\n        '{': r'\\{',\n        '}': r'\\}',\n        '~': r'\\textasciitilde{}',\n        '^': r'\\^{}',\n        '\\\\': r'\\textbackslash{}',\n        '<': r'\\textless{}',\n        '>': r'\\textgreater{}',\n        }\n\n\n\n        cleanre = re.compile(r'([^\\\\])(\\%|\\&|\\$|\\#|\\_|\\{|\\}|\\~|\\^|\\\\|\\>|\\<)')\n        #print(\"AAA: \" + '|'.join(re.escape(str(key)) for key in sorted(conv.keys(), key = lambda item: - len(item))))\n\n        #cleanre = re.compile('(.)(' + '|'.join(re.escape(str(key)) for key in sorted(conv.keys(), key = lambda item: - len(item))) + \")\")\n        result = cleanre.sub(lambda match: (match.group(1) if match.group(1) else \"\") + conv[match.group(2)] if (match.group(1) and match.group(1) != \"\\\\\") else match.group(), text)        \n        return result\n\n    \n    def TexCommandEscape(self,text):\n        conv = {\n        '&': r'\\&',\n        '%': r'\\%',\n        '$': r'\\$',\n        '#': r'\\#',\n        '_': r'\\_',\n        '~': r'\\textasciitilde{}',\n        '^': r'\\^{}',\n        '<': r'\\textless{}',\n        '>': r'\\textgreater{}',\n        }\n        cleanre = re.compile(r'([^\\\\])(\\%|\\&|\\$|\\#|\\_|\\~|\\^|\\>|\\<)')\n        result = cleanre.sub(lambda match: (match.group(1) if match.group(1) else \"\") + conv[match.group(2)] if (match.group(1) and match.group(1) != \"\\\\\") else match.group(), text)        \n        return result\n        #return cleanre.sub(lambda match: conv[match.group()], text)        \n\n    def SingleLineReplace(self,reg,rep,text,ok):\n        nt = reg.sub(rep,text)\n        ok = ok or nt != text\n        return (nt,ok)\n\n    def SingleLineReplacements(self,text):\n        didRep = 0\n        text = exp.RE_TITLE.sub(\"\",text)\n        text = exp.RE_AUTHOR.sub(\"\",text)\n        text = exp.RE_LANGUAGE.sub(\"\",text)\n        text = exp.RE_EMAIL.sub(\"\",text)\n        text = exp.RE_DATE.sub(\"\",text)\n        m = RE_LINK.search(text)\n        if(m):\n            link = m.group('link').strip()\n            desc = m.group('desc')\n            if(desc):\n                desc = self.TexFullEscape(desc.strip())\n            if(False and (link.endswith(\".png\") or link.endswith(\".jpg\") or link.endswith(\".jpeg\") or link.endswith(\".gif\"))):\n                if(link.startswith(\"file:\")):\n                    link = re.sub(r'^file:','',link)  \n                extradata = \"\"  \n                if(self.commentName and self.commentName in link):\n                    extradata =  \" \" + self.commentData\n                    self.commentName = None\n                if(hasattr(self,'attrs')):\n                    for key in self.attrs:\n                        extradata += \" \" + str(key) + \"=\\\"\" + str(self.attrs[key]) + \"\\\"\"\n                preamble = \"\"\n                postamble = \"\"\n                if(hasattr(self,'caption') and self.caption):\n                    pass\n                    #preamble = \"<div class=\\\"figure\\\"><p>\"\n                    #postamble = \"</p><p><span class=\\\"figure-number\\\">Figure {index}: </span>{caption}</p></div>\".format(index=self.figureIndex,caption=self.caption)\n                    self.figureIndex += 1\n                #text = RE_LINK.sub(\"{preamble}<img src=\\\"{link}\\\" alt=\\\"{desc}\\\"{extradata}>{postamble}\".format(preamble=preamble,link=link,desc=desc,extradata=extradata,postamble=postamble),line)\n                didRep = True\n                #self.ClearAttributes()\n                return (text,2)\n            else:\n                if(link.startswith(\"file:\")):\n                    link = re.sub(r'^file:','',link)  \n                link = re.sub(r\"[:][:][^/].*\",\"\",link)\n                #link = self.TexFullEscape(link)\n                link = link.replace(\"\\\\\",\"/\")\n                if(desc):\n                    traceback.print_stack()\n                    text = RE_LINK.sub(r\"\\\\ref{{{link}}}{{{desc}}}\".format(link=link,desc=desc),text)\n                else:\n                    text = RE_LINK.sub(r\"\\\\ref{{{link}}}\".format(link=link),text)\n                didRep = 2\n                #self.ClearAttributes()\n                return (text,2)\n\n        text,didRep = self.SingleLineReplace(exp.RE_NAME,r\"\\label{\\g<data>}\",text,didRep)\n        text,didRep = self.SingleLineReplace(exp.RE_BOLD,r\"\\\\textbf{\\g<data>}\",text,didRep)\n        text,didRep = self.SingleLineReplace(exp.RE_ITALICS,r\"\\\\textit{\\g<data>}\",text,didRep)\n        text,didRep = self.SingleLineReplace(exp.RE_UNDERLINE,r\"\\underline{\\g<data>}\",text,didRep)\n        text,didRep = self.SingleLineReplace(exp.RE_CODE,r\"\\\\texttt{\\g<data>}\",text,didRep)\n        text,didRep = self.SingleLineReplace(exp.RE_VERBATIM,r\"\\\\texttt{\\g<data>}\",text,didRep)\n        text,didRep = self.SingleLineReplace(exp.RE_HR,r\"\\hrulefill\",text,didRep)\n        return (text,1 if didRep else 0)\n\n    # Export the heading of this node\n    def NodeHeading(self,n):\n        heading = self.Escape(n.heading)\n        level = n.level\n        if(level >= len(sectionTypes)):\n            level = len(sectionTypes)-1\n        self.doc.append(sectionTypes[level].format(heading=heading))\n\n    # We are about to start exporting the nodes body\n    def StartNodeBody(self,n):\n        pass\n\n    def AttributesGather(self, l):\n        return False\n\n\n    def NodeBody(self,n):\n        ilines = n._lines[1:]\n        for parser in self.nodeParsers:\n            ilines = parser.Handle(ilines,n)\n        for line in ilines:\n            self.doc.append(self.TexFullEscape(line))\n\n    # We are done exporting the nodes body so finish it off\n    def EndNodeBody(self,n):\n        pass\n\n    # We are now done the node itself so finish that off\n    def EndNode(self,n):\n        pass\n\n    # def about to start exporting nodes\n    def StartNodes(self):\n        pass\n\n    # done exporting nodes\n    def EndNodes(self):\n        pass\n\n    def StartDocument(self, file):\n        pass\n\n    def EndDocument(self):\n        pass\n\n    def InsertScripts(self,file):\n        pass\n\n    def StartHead(self):\n        pass\n\n    def EndHead(self):\n        pass\n\n    def StartBody(self):\n        pass\n\n    def EndBody(self):\n        pass\n\n    def FinishDocCustom(self):\n        self.fs.write(self.BuildDoc())\n\n    def Execute(self):\n        cmdStr = sets.Get(\"latex2Pdf\",\"C:\\\\texlive\\\\2021\\\\bin\\\\win32\\\\pdflatex.exe\")\n        commandLine = [cmdStr, self.outputFilename]\n        try:\n            startupinfo = subprocess.STARTUPINFO()\n            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n        except:\n            startupinfo = None\n        # cwd=working_dir, env=my_env,\n        #cwd = os.path.join(sublime.packages_path(),\"User\") \n        view = sublime.active_window().active_view()\n        cwd = os.path.dirname(view.file_name())\n        popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n        #popen.wait()\n        (o,e) = popen.communicate()\n        log.debug(o)\n        log.debug(e)\n        #log.debug(o.split('\\n') + e.split('\\n'))\n\n# ============================================================\nclass OrgExportFileAsPdfCommand(sublime_plugin.TextCommand):\n\n    def OnDoneSourceBlockExecution(self):\n        # Reload if necessary\n        self.file = db.Get().FindInfo(self.view)\n        self.doc  = None\n        self.docClass = exp.GetGlobalOption(self.file,\"LATEX_CLASS\",\"latexClass\",\"article\").lower()\n        try:\n            outputFilename = exp.ExportFilename(self.view,\".tex\",self.suffix)\n            self.doc       = LatexDoc(outputFilename,self.file)\n            self.doc.setClass(self.docClass)\n            self.helper    = exp.OrgExportHelper(self.view,self.index)\n            self.helper.Run(outputFilename, self.doc)\n            self.doc.Execute()\n            # TODO: Delete the tex file\n        finally:    \n            evt.EmitIf(self.onDone)\n\n\n    def run(self,edit, onDone=None, index=None, suffix=\"\"):\n        self.file = db.Get().FindInfo(self.view)\n        self.onDone = onDone\n        self.suffix = suffix\n        if(index != None):\n            self.index = index\n        else:\n            self.index = None\n        if(None == self.file):\n            log.error(\"Not an org file? Cannot build reveal document\")\n            evt.EmitIf(onDone)  \n            return\n        if(sets.Get(\"latexExecuteSourceOnExport\",False)):\n            self.view.run_command('org_execute_all_source_blocks',{\"onDone\":evt.Make(self.OnDoneSourceBlockExecution),\"amExporting\": True})\n        else:\n            self.OnDoneSourceBlockExecution()\n\n# ============================================================\nclass OrgExportFileAsLatexCommand(sublime_plugin.TextCommand):\n\n    def OnDoneSourceBlockExecution(self):\n        # Reload if necessary\n        self.file = db.Get().FindInfo(self.view)\n        self.doc  = None\n        self.docClass = exp.GetGlobalOption(self.file,\"LATEX_CLASS\",\"latexClass\",\"article\").lower()\n        try:\n            outputFilename = exp.ExportFilename(self.view,\".tex\",self.suffix)\n            self.doc       = LatexDoc(outputFilename,self.file)\n            self.doc.setClass(self.docClass)\n            self.helper    = exp.OrgExportHelper(self.view,self.index)\n            self.helper.Run(outputFilename, self.doc)\n        finally:    \n            evt.EmitIf(self.onDone)\n\n\n    def run(self,edit, onDone=None, index=None, suffix=\"\"):\n        self.file = db.Get().FindInfo(self.view)\n        self.onDone = onDone\n        self.suffix = suffix\n        if(index != None):\n            self.index = index\n        else:\n            self.index = None\n        if(None == self.file):\n            log.error(\"Not an org file? Cannot build reveal document\")\n            evt.EmitIf(onDone)  \n            return\n        if(sets.Get(\"latexExecuteSourceOnExport\",False)):\n            self.view.run_command('org_execute_all_source_blocks',{\"onDone\":evt.Make(self.OnDoneSourceBlockExecution),\"amExporting\": True})\n        else:\n            self.OnDoneSourceBlockExecution()\n\ndef SetupDnd():\n    import OrgExtended.orgutil.webpull as wp\n    wp.DownloadDnd()\n\nclass OrgExportFileAsDndPdfCommand(sublime_plugin.TextCommand):\n    def run(self,edit, onDone=None, index=None, suffix=\"\"):\n        self.file = db.Get().FindInfo(self.view)\n        self.onDone = onDone\n        self.suffix = suffix\n        SetupDnd()\n\n"
  },
  {
    "path": "orglinks.py",
    "content": "import sublime\nimport sublime_plugin\nimport re\nimport os\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nfrom OrgExtended.orgutil.util import *\nimport logging\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgextension as ext\nfrom collections import defaultdict\nimport struct\nimport imghdr\nimport urllib.request\nimport yaml\nimport OrgExtended.orgneovi as nvi\nimport OrgExtended.pymitter as evt\nfrom   OrgExtended.orgplist import *\nimport OrgExtended.orguniqueview as uview\n\ntry:\n    import importlib\nexcept ImportError:\n    pass\n\nlog = logging.getLogger(__name__)\n\n# This is entirely copied from the wonderful OrgMode plugin\n# found on package control. The orgmode plugin has a great base\n# resolver system. I have copied it and will be extending it\n# somewhat. OrgExtended is not compatible with orgmode\n# so I have had to consume it here rather than just recommend\n# you use it.\n\n\ndef find_all_links(view):\n    links = view.find_by_selector(\"orgmode.link\")\n    return links\n\ndef extract_link(view):\n    pt    = view.sel()[0].begin()\n    links = find_all_links(view)\n    for link in links:\n        if(link.contains(pt)):\n            return link\n    return None\n\n\nDEFAULT_LINK_RESOLVERS = [\n    'internal',\n    'http',\n    'https',\n    'prompt',\n    'jira',\n    'email',\n    'file',\n]\n\navailable_resolvers = ext.find_extension_modules('orgresolver', DEFAULT_LINK_RESOLVERS)\nlinkre              = re.compile(r\"\\[\\[([^\\[\\]]+)\\]\\s*(\\[[^\\[\\]]*\\])?\\]\")\n\n\n# Returns the url from the full link\ndef extract_link_url(str):\n    m = linkre.search(str)\n    return m.group(1) if m is not None else str\n\ndef extract_link_url_from_region(view, region):\n    return extract_link_url(view.substr(region))\n\ndef is_region_link(view, region):\n    return 'orgmode.link' in view.scope_name(region.end())\n\ndef get_link_region_at(view):\n    if(is_region_link(view, view.sel()[0])):\n        return extract_link(view)\n    return None\n\ndef find_image_file(view, url):\n    # ABS\n    if(os.path.isabs(url)):\n        return url\n    # Relative\n    if(view != None):\n        curDir = os.path.dirname(view.file_name())\n        filename = os.path.join(curDir, url)\n        if(os.path.isfile(filename)):\n            return filename\n    # In search path\n    searchHere = sets.Get(\"imageSearchPath\",[])\n    for direc in searchHere:\n        filename = os.path.join(direc, url)\n        if(os.path.isfile(filename)):\n            return filename\n\n    searchHere = sets.Get(\"orgDirs\",[])\n    for direc in searchHere:\n        filename = os.path.join(direc, \"images\", url) \n        if(os.path.isfile(filename)):\n            return filename\n\nRE_TARGET = re.compile(r'<<(?P<target>[^>]+)>>')\nRE_NAMED = re.compile(r'[#][+]NAME[:]\\s*(?P<target>.+)')\ndef CreateLink(view):\n    fn = view.file_name()\n    # Org Files have a LOT more potential for making links!\n    if(util.isPotentialOrgFile(fn)):\n        r = view.curRow()\n        line = view.getLine(r)\n        linet = RE_TARGET.match(line)\n        namet = RE_NAMED.match(line)\n        link = None\n        # have target on this line?\n        if(linet):\n           link = \"[[file:{0}::{1}][{1}]]\".format(view.file_name(),linet.group('target'))\n        # have named object on this line?\n        if(link == None and namet):\n           link = \"[[file:{0}::{1}][{1}]]\".format(view.file_name(),namet.group('target'))\n        n = db.Get().AtInView(view)\n        if(link == None and n and not n.is_root()):\n            p  = n.get_property(\"ID\")\n            cp = n.get_property(\"CUSTOM_ID\")\n            if(p):\n               link = \"[[file:{0}::#{1}][{2}]]\".format(view.file_name(),p,n.heading)\n            # Have custom id?\n            elif(cp):\n               link = \"[[file:{0}::#{1}][{2}]]\".format(view.file_name(),cp,n.heading)\n            # Am near a heading?\n            else:\n               link = \"[[file:{0}::*{1}][{1}]]\".format(view.file_name(),n.heading)\n        # okay then just use row,col\n        if(link == None):\n            r,c = view.curRowCol()\n            link = \"[[file:{0}::{1},{2}][{3}]]\".format(view.file_name(),r,c,os.path.basename(view.file_name()))\n        return link\n    else:\n        # Other file types only have line and column\n        r,c = view.curRowCol()\n        link = \"[[{0}::{1}::{2}][{3}]]\".format(fn,r,c,os.path.basename(fn))\n        return link\n\nclass OrgOpenLinkCommand(sublime_plugin.TextCommand):\n    def resolve(self, content):\n        for resolver in self.resolvers:\n            result = resolver.resolve(content)\n            if result is not None:\n                return resolver, result\n        return None, None\n\n    def is_valid_scope(self, region):\n        return is_region_link(self.view, region)\n\n    def extract_content(self, region):\n        return extract_link_url_from_region(self.view, region)\n\n    def run(self, edit):\n        # reload our resolvers if they are not loaded.\n        #if(not hasattr(self, \"resolvers\")):\n        wanted_resolvers = sets.Get(\"linkResolvers\", DEFAULT_LINK_RESOLVERS)\n        self.resolvers   = [available_resolvers[name].Resolver(self.view) for name in wanted_resolvers]\n\n        # This is goofy. File loads get resolve called that calls extract.\n        # extact may launch the file into sublime. IF we return a path\n        # sublime will call start on the file.\n        view = self.view\n        for sel in view.sel():\n            if not self.is_valid_scope(sel):\n                continue\n            region = extract_link(view) #view.extract_scope(sel.end())\n            content = self.extract_content(region)\n            resolver, newcontent = self.resolve(content)\n            if newcontent is None:\n                log.error(\" Could not resolve link:\\n%s\" % content)\n                sublime.error_message('Could not resolve link:\\n%s' % content)\n                continue\n            resolver.execute(newcontent)\n\nclass OrgCreateLinkCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        link = CreateLink(self.view)\n        sublime.set_clipboard(link)\n        nvi.TestAndSetClip(self.view, link)\n\n\n\n# global magic\nVIEWS_WITH_IMAGES = set()\n\n# Stolen from:\n# https://github.com/renerocksai/sublime_zk/blob/master/sublime_zk.py\n# The excellent work in that system showed a way of using\n# Phantoms to show images inline. This gives us a part of one of Org Modes\n# Most powerful features which is babel modes ability to make diagrams in\n# documents.\nclass ImageHandler:\n    Phantoms = defaultdict(set)\n    Cache    = {}\n\n    @staticmethod\n    def save_cache():\n       user_settings_path = os.path.join(sublime.packages_path(), \"User\",\"OrgExtended_image_cache.yaml\")\n       f = open(user_settings_path,\"w\")\n       data = yaml.dump(ImageHandler.Cache, f)\n       f.close() \n\n    @staticmethod\n    def load_cache():\n        user_settings_path = os.path.join(sublime.packages_path(), \"User\",\"OrgExtended_image_cache.yaml\")\n        if(os.path.isfile(user_settings_path)):\n            stream = open(user_settings_path, 'r')\n            ImageHandler.Cache = yaml.load(stream, Loader=yaml.SafeLoader)\n            stream.close()\n\n    @staticmethod\n    def show_image(region, view, max_width=1024):\n        width = -1\n        height = -1\n        node = db.Get().AtRegion(view,region)\n        if(node):\n            attr = node.get_comment(\"ORG_ATTR\",None)\n            if(attr):\n                params = PList.createPList(attr)\n                try:\n                    width = int(params.Get('width',-1))\n                    height = int(params.Get('height',-1))\n                except:\n                    log.error(\"Could not extract width and height from plist / ORG_ATTR comment\")\n        # If we already have this image then exit out\n        if view.id() in ImageHandler.Phantoms and str(region) in ImageHandler.Phantoms[view.id()]:\n            return\n        url    = extract_link_url_from_region(view, region)\n        # We can only handle links to images this way.\n        if not util.is_image(url):\n            return\n        level  = db.Get().GetIndentForRegion(view, region)\n        indent = \"&nbsp;\" * (level * 2)\n        if url.startswith('http') or url.startswith('https'):\n            img = url\n            local_filename = None\n            if(url in ImageHandler.Cache and os.path.isfile(ImageHandler.Cache[url])):\n                local_filename = ImageHandler.Cache[url]\n                log.debug(\"Loaded from cache: \" + url)\n            else:\n                log.debug(\"Downloaded: \" + url)\n                local_filename, headers = urllib.request.urlretrieve(url)\n                ImageHandler.Cache[url] = local_filename\n                ImageHandler.save_cache()\n            size = ImageHandler.get_image_size(local_filename)\n            ttype = None\n            if None != size:\n                w, h, ttype = size\n                if ttype and ttype == 'svg':\n                    view.erase_phantoms(str(region))\n                    html_img = util.get_as_string(img)\n                    print(html_img)\n                    view.add_phantom(str(region), region, html_img, sublime.LAYOUT_BLOCK)\n                    ImageHandler.Phantoms[view.id()].add(str(region))\n                    return\n                FMT = u'''\n                    {}<img src=\"data:image/{}\" class=\"centerImage\" {}>\n                '''\n            img = ttype + \";base64,\" + util.get_as_base64(img)\n        elif url.startswith(\"file:\"):\n            url = url.replace(\"file:\",\"\")\n            log.debug(\"FILE: \" + url)\n            FMT = '''\n                {}<img src=\"file://{}\" class=\"centerImage\" {}>\n            '''\n            img  = find_image_file(view, url)\n            if(img):\n                size = ImageHandler.get_image_size(img)\n                if(width > 0):\n                    size = [width, size[1], size[2]]\n                if(height > 0):\n                    size = [size[0], height, size[2]]\n            else:\n                size = (100,100,\"png\")\n        else:\n            log.debug(\"local file: \" + url)\n            FMT = '''\n                {}<img src=\"file://{}\" class=\"centerImage\" {}>\n            '''\n            img  = find_image_file(view, url)\n            log.debug(\"local file2: \" + url)\n            size = ImageHandler.get_image_size(img)\n            if(width > 0):\n                size = [width, size[1], size[2]]\n            if(height > 0):\n                size = [size[0], height, size[2]]\n        if not size:\n            return\n        w, h, t = size\n        line_region = view.line(region)\n        imgattr = ImageHandler.check_imgattr(view, line_region, region)\n        if not imgattr:\n            if w > max_width:\n                m = max_width / w\n                h *= m\n                w = max_width\n            imgattr = 'width=\"{}\" height=\"{}\"'.format(w, h)\n\n        view.erase_phantoms(str(region))\n        html_img = FMT.format(indent, img, imgattr)\n        view.add_phantom(str(region), region, html_img, sublime.LAYOUT_BLOCK)\n        ImageHandler.Phantoms[view.id()].add(str(region))\n\n    @staticmethod\n    def hide_image(region, view):\n        try:\n            view.erase_phantoms(str(region))\n            ImageHandler.Phantoms[view.id()].remove(str(region))\n        except:\n            pass\n\n    @staticmethod\n    def show_image_at(view, max_width=1024):\n        reg = get_link_region_at(view)\n        if(reg):\n            ImageHandler.show_image(reg, view)\n\n    @staticmethod\n    def hide_image_at(view, max_width=1024):\n        reg = get_link_region_at(view)\n        if(reg):\n            ImageHandler.hide_image(reg, view)\n\n    @staticmethod\n    def show_images(view, max_width=1024):\n        global VIEWS_WITH_IMAGES\n        skip = 0\n\n        while True:\n            imageRegions = view.find_by_selector('orgmode.link')[skip:]\n            skip += 1\n            if not imageRegions:\n                break\n            region = imageRegions[0]\n            ImageHandler.show_image(region, view, max_width)\n        VIEWS_WITH_IMAGES.add(view.id())\n\n    @staticmethod\n    def check_imgattr(view, line_region, link_region=None):\n        # find attrs for this link\n        full_line = view.substr(line_region)\n        link_till_eol = full_line[link_region.a - line_region.a:]\n        # find attr if present\n        m = re.match(r'.*\\)\\{(.*)\\}', link_till_eol)\n        if m:\n            return m.groups()[0]\n\n    @staticmethod\n    def hide_images(view, edit):\n        for rel_p in ImageHandler.Phantoms[view.id()]:\n            view.erase_phantoms(rel_p)\n        del ImageHandler.Phantoms[view.id()]\n        skip = 0\n        while True:\n            img_regs = view.find_by_selector('orgmode.link.href')[skip:]\n            skip += 1\n            if not img_regs:\n                break\n            region = img_regs[0]\n            rel_p = view.substr(region)\n            if(util.is_image(rel_p)):\n                pass\n                #line_region = view.line(region)\n                #line_str = view.substr(line_region)\n                #view.replace(edit, line_region, line_str.strip())\n        VIEWS_WITH_IMAGES.discard(view.id())\n\n    @staticmethod\n    def get_image_size(img):\n        \"\"\"\n        Determine the image type of img and return its size.\n        \"\"\"\n        #print(\"IMG: \" + img)\n        try:\n            with open(img, 'rb') as f:\n                head = f.read(24)\n                ttype = None\n\n                if b'<svg' in head:\n                    ttype = 'svg'\n                    width, height = (100,100)\n                    return width, height, ttype\n                if len(head) != 24:\n                    return\n                if imghdr.what(img) == 'png':\n                    ttype = \"png\"\n                    check = struct.unpack('>i', head[4:8])[0]\n                    if check != 0x0d0a1a0a:\n                        return\n                    width, height = struct.unpack('>ii', head[16:24])\n                elif imghdr.what(img) == 'gif':\n                    ttype = \"gif\"\n                    width, height = struct.unpack('<HH', head[6:10])\n                elif imghdr.what(img) == 'jpeg':\n                    ttype = \"jpeg\"\n                    try:\n                        f.seek(0)  # Read 0xff next\n                        size = 2\n                        ftype = 0\n                        while not 0xc0 <= ftype <= 0xcf:\n                            f.seek(size, 1)\n                            byte = f.read(1)\n                            while ord(byte) == 0xff:\n                                byte = f.read(1)\n                            ftype = ord(byte)\n                            size = struct.unpack('>H', f.read(2))[0] - 2\n                        # SOFn block\n                        f.seek(1, 1)  # skip precision byte.\n                        height, width = struct.unpack('>HH', f.read(4))\n                    except Exception:\n                        return\n                else:\n                    return\n                return width, height, ttype\n        except:\n            return 100,100,'png'\n\nclass OrgCycleImagesCommand(sublime_plugin.TextCommand):\n    def OnDone(self):\n        self.view.sel().clear()\n        self.view.sel().add(self.cursor)\n        evt.EmitIf(self.onDone)\n\n    def OnShown(self):\n        self.OnDone()\n\n    def OnHidden(self):\n        self.view.run_command(\"org_show_images\",{\"onDone\": evt.Make(self.OnShown)})\n\n    def run(self, edit, onDone=None):\n        self.onDone = onDone\n        self.cursor = self.view.sel()[0]\n        self.view.run_command(\"org_hide_images\",{\"onDone\": evt.Make(self.OnHidden)})\n\nclass OrgShowImagesCommand(sublime_plugin.TextCommand):\n    def run(self, edit,onDone=None):\n        ImageHandler.show_images(self.view)\n        evt.EmitIf(onDone)\n\nclass OrgHideImagesCommand(sublime_plugin.TextCommand):\n    def run(self, edit,onDone=None):\n        ImageHandler.hide_images(self.view, edit)\n        evt.EmitIf(onDone)\n\nclass OrgShowImageCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        ImageHandler.show_image_at(self.view)\n\nclass OrgHideImageCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        ImageHandler.hide_image_at(self.view)\n\n# ON LOAD HANDLER: if startup is set we show or hide the images.\n#+STARTUP: inlineimages\n#+STARTUP: noinlineimages\ndef get_show_images_default():\n    return sets.Get(\"startup\",[\"noinlineimages\"])\n\ndef get_image_startup(node):\n    startupDefault = get_show_images_default()\n    return node.startup(startupDefault)\n\ndef onShutdown():\n    ImageHandler.save_cache()\n\ndef onLoad(view):\n    ImageHandler.load_cache()\n    file = db.Get().FindInfo(view)\n    if(file):\n        startup = get_image_startup(file.org[0])\n        if(Startup.inlineimages in startup):\n            ImageHandler.show_images(view)\n\n\nclass OrgLinkToFileCommand(sublime_plugin.TextCommand):\n    def on_done(self, index, modifiers=None):\n        if(index >= 0):\n            f = self.files[index]\n            link = self.view.MakeRelativeToMe(f[0])\n            desc = os.path.basename(link)\n            if(len(f) > 1):\n                desc = f[1]\n                includeRoamTag = sets.Get(\"insertRoamTagToFileLink\", True)\n                if includeRoamTag is False:\n                    log.error(self.rawTitles[f[0]])\n                    desc = self.rawTitles[f[0]]\n            indent = \"\"\n            node = db.Get().AtInView(self.view)\n            if(node):\n                indent = node.indent()\n            data = r\"{indent}[[file:{link}][{desc}]]\".format(indent=indent, link=link, desc=desc)\n            self.view.run_command(\"org_internal_insert\", {\"location\": self.view.sel()[0].begin(), \"text\": data})\n\n    def run(self, edit):\n        self.files = []\n        self.rawTitles = {}\n        for i in range(0, len(db.Get().Files)):\n            filename = db.Get().Files[i].filename\n            title = \" \".join(db.Get().Files[i].org.get_comment(\"TITLE\", \"\")).strip()\n            self.rawTitles[filename] = title\n            useRoamTags = sets.Get(\"linkFindUseRoamTags\", True)\n            if(useRoamTags):\n                tags = \" \".join(db.Get().Files[i].org.get_comment(\"ROAM_TAGS\", \"\")).strip()\n                if(tags != \"\"):\n                    title = \"(\" + tags + \") \" + title\n            if(title != \"\"):\n                self.files.append([filename, title])\n            else:\n                self.files.append([filename])\n        self.view.window().show_quick_panel(self.files, self.on_done, -1, -1)\n\nclass OrgJumpToBacklinksCommand(sublime_plugin.TextCommand):\n    def on_done(self, index, modifiers=None):\n        if(index >= 0):\n            f = self.links[index]\n            fname = f.fromFile.filename + \":\" + str(f.row)\n            self.view.window().open_file(fname, sublime.ENCODED_POSITION)\n\n    def run(self, edit):\n        self.files = []\n        bl = db.Get().GetBacklinks(self.view)\n        if(bl):\n            self.links = bl\n            for l in bl:\n                title = l.fromFile.org.get_comment(\"TITLE\",[\"\"])[0]\n                desc = l.desc if l.desc else \"\"\n                if(title.strip() != \"\"):\n                    desc = title + \": \" + desc\n                self.files.append([desc, l.link])\n            self.view.window().show_quick_panel(self.files, self.on_done, -1, -1)\n            return\n        log.debug(\"NO BACKLINKS\")\n\n\ndef BuildBacklinksDisplay(view):\n    bl = db.Get().GetBacklinks(view)\n    if(bl):\n        out = str(len(bl)) + \" Backlinks\\n\"\n        files = {}\n        for l in bl:\n            title = l.fromFile.org.get_comment(\"TITLE\",[\"\"])[0]\n            if(title.strip() == \"\"):\n                title = l.desc\n                if(not title):\n                    title = l.link\n            if(not title in files):\n                files[title] = []\n            files[title].append(l)\n        keys = list(files.keys())\n        keys.sort()\n        for k in keys:\n            out += \"\\n\"\n            flist = files[k]\n            flist = sorted(flist,key=lambda x: x.row)\n            f = flist[0] \n            fn = f.fromFile.filename\n            out += \"* {}\\n\".format(k)\n            for f in flist:\n                desc = f.desc\n                if(not desc):\n                    desc = f.link\n                out += \"  - [[file:{}::{}][{}]]\\n\".format(fn,f.row,desc)\n                if(f.linktext != f.text and (len(f.linktext)+5) < len(f.text)):\n                    out += \"    \" + f.text.strip() + \"\\n\"\n        return out\n    return \"0 Backlinks\"\n\ndef UpdateBacklinksForDisplay(view):\n    if(uview.UniqueView.IsShowing(\"Backlinks\")):\n        out = BuildBacklinksDisplay(view)\n        uv = uview.UniqueView.Get(\"Backlinks\",curview=view)\n        uv.view.run_command(\"org_remove_all_folds\")\n        uv.view.set_read_only(False)\n        uv.view.run_command(\"org_internal_replace\", {\"start\": 0, \"end\": uv.view.size(), \"text\": out + \"\\n\"})\n        uv.view.set_read_only(True)\n        uv.view.run_command(\"org_fold_all_links\")\n        uv.view.sel().clear()\n\nclass OrgShowBacklinksCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        out = BuildBacklinksDisplay(self.view)\n        #bl = db.Get().GetBacklinks(self.view)\n        self.uv = uview.UniqueView.Get(\"Backlinks\",curview=self.view)\n        self.uv.view.run_command(\"org_remove_all_folds\")\n        self.uv.view.set_read_only(False)\n        self.uv.view.run_command(\"org_internal_replace\", {\"start\": 0, \"end\": self.uv.view.size(), \"text\": out + \"\\n\"})\n        self.uv.view.set_read_only(True)\n        self.uv.view.run_command(\"org_fold_all_links\")\n        self.uv.view.sel().clear()\n        \nclass OrgSearchLinksCommand(sublime_plugin.TextCommand):\n    def on_done(self, index, modifiers=None):\n        if(self.transientview != None):\n            self.transientview.close()\n            self.transientview = None\n        if(index >= 0):\n            f = self.lobjs[index]\n            fname = f.inFile.filename + \":\" + str(f.row+1)\n            self.view.window().open_file(fname, sublime.ENCODED_POSITION)\n\n    def on_highlighted(self, index, modifiers=None):\n        if(self.transientview != None):\n            self.transientview.close()\n            self.transientview = None\n        if(index >= 0):\n            f = self.lobjs[index]\n            fname = f.inFile.filename + \":\" + str(f.row+1)\n            self.transientview = self.view.window().open_file(fname, sublime.ENCODED_POSITION|sublime.TRANSIENT)\n\n    def run(self, edit):\n        self.links = []\n        self.lobjs = []\n        self.transientview = None\n        files = db.Get().Files\n        if(files):\n            for f in files:\n                lnks = f.org.env.links\n                for l in lnks:\n                    desc = l.desc + \" : \" if l.desc else \"\"\n                    self.links.append([desc + l.link,f.filename])\n                    l.inFile = f\n                    self.lobjs.append(l)\n            self.view.window().show_quick_panel(self.links, self.on_done, -1, -1,self.on_highlighted)\n            return\n"
  },
  {
    "path": "orglist.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.loader as loader\nimport OrgExtended.orgparse.node as node\nimport OrgExtended.orgparse.date as orgdate\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orgproperties as props\nimport OrgExtended.orgdatepicker as datep\nimport OrgExtended.orginsertselected as insSel\nimport OrgExtended.orglinks as orglink\nimport OrgExtended.orgneovi as nvi\nimport OrgExtended.orgagenda as oa\nimport OrgExtended.orgcheckbox as checkbox\nimport OrgExtended.orgnumberedlist as numberedlist\n\nlog = logging.getLogger(__name__)\n\n\nRE_LIST_REPLACE = re.compile(r'\\s*(([0-9]+[.)])|[-+])\\s+')\ndef isListLine(l):\n    return RE_LIST_REPLACE.search(l)\n\nclass ListData:\n    def __init__(self,view=None,pt=None):\n        if(view != None):\n            reg = view.line(pt)\n            line = view.substr(reg)\n            if(numberedlist.isNumberedLine(view,reg)):\n                wasNumbered = True\n                self.data = numberedlist.getListAtPoint(view,pt)\n            elif(checkbox.isUnorderedList(line)):\n                self.data = checkbox.getListAtPoint(view,pt)\n            else:\n                self.data = None\n        else:\n            self.data = [] \n\n    @staticmethod\n    def CreateListFromList(lst):\n        ls = ListData()\n        for l in lst:\n            l = RE_LIST_REPLACE.sub(\"\",l)\n            ls.data.append([None,l])\n        return ls\n\n    def __iter__(self):\n        return self.Iterate()\n\n    def Iterate(self):\n        for row in self.data:\n            yield row[1]\n        return None\n\nRE_ISCOMMENT = re.compile(r\"^\\s*[#][+]\")\ndef LookupNamedListInFile(name):\n    l = None\n    view = sublime.active_window().active_view()\n    if(view):\n        node = db.Get().AtInView(view)\n        if(node):\n            # Look for named objects in the file.\n            names = node.names\n            if(names and name in names):\n                row = names[name]['row']\n                last_row = view.lastRow()\n                for r in range(row,last_row):\n                    pt = view.text_point(r, 0)\n                    line = view.substr(view.line(pt))\n                    m = RE_ISCOMMENT.search(line)\n                    if(m):\n                        continue\n                    elif(line.strip() == \"\"):\n                        continue\n                    else:\n                        row = r\n                        break\n                pt = view.text_point(row,0)\n                reg = view.line(pt)\n                line = view.substr(reg)\n                if(numberedlist.isNumberedLine(view,reg) or checkbox.isUnorderedList(line)):\n                    l = ListData(view,pt)\n    return l\n\ndef IfListExtract(view,pt):\n    l = None\n    reg = view.line(pt)\n    line = view.substr(reg)\n    if(numberedlist.isNumberedLine(view,reg) or checkbox.isUnorderedList(line)):\n        l = ListData(view,pt)\n    return l\n"
  },
  {
    "path": "orgmouse.py",
    "content": "import sublime\nimport sublime_plugin\nimport OrgExtended.pymitter as evt\n\nclass OrgMouseHandlerCommand(sublime_plugin.TextCommand):\n    def run(self, edit, event=None):\n        pt = 0 if not event else self.view.window_to_text((event[\"x\"], event[\"y\"]))\n        evt.Get().emit(\"orgmouse\", pt, self.view, edit)\n\n    def want_event(self):\n        return True\t\n"
  },
  {
    "path": "orgnavigation.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcapture as capture\nimport OrgExtended.orgcheckbox as checkbox\nimport OrgExtended.orgnumberedlist as numberedlist\nimport OrgExtended.orgdynamicblock as dynamic\nimport OrgExtended.orgsourceblock as src\n\nlog = logging.getLogger(__name__)\n\n# Jump to previous heading from current location.\nclass OrgUpCommand(sublime_plugin.TextCommand):\n    def run(self,edit):\n        nav.navigate_up(self.view)\n\nclass OrgDownCommand(sublime_plugin.TextCommand):\n    def run(self,edit):\n        nav.navigate_down(self.view)\n\n\nclass OrgJumpInFileCommand(sublime_plugin.TextCommand):\n    def on_done_st4(self,index,modifers):\n        self.on_done(index)\n    def on_done(self, index):\n        view = self.view\n        (curRow,curCol) = view.curRowCol()\n        node = db.Get().NodeAtIndex(view.file_name(), index)\n        print(str(node))\n        if(node != None):\n            row = node.start_row\n            linePos = view.text_point(row,curCol)\n            view.show_at_center(linePos)\n            view.sel().clear()\n            view.sel().add(linePos)\n        else:\n            view.set_status(\"Error: \", \"filename {0} not found in orgDb\".format(view.file_name()))\n    def run(self, edit):\n        headings = db.Get().Headings(self.view)\n        if(int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(headings, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(headings, self.on_done_st4, -1, -1)\n\nRE_TABLE_MATCH = re.compile(r\"^\\s*\\|\")\ndef table_tabbing(view):\n    cur = view.sel()[0]\n    l = view.line(cur.begin())\n    line = view.substr(l)\n    return RE_TABLE_MATCH.search(line)\n\n\n# Org Mode style tab cycling.\n# Not really navigation but as good a place as any for this\nclass OrgTabCyclingCommand(sublime_plugin.TextCommand):\n    \"\"\"\n    Bind to TAB key, and if the current line is not\n    a headline, a \\t would be inserted?\n    Or do we want something else here?\n    \"\"\"\n    def run(self, edit):\n        # Keep track of if the buffer has changed. The in memory image\n        # will be out of date if it has, so loads it.\n        file = db.Get().FindInfo(self.view.file_name())\n        if(file != None and file.HasChanged(self.view)):\n            file.LoadS(self.view)\n        \n        if(folding.fold_local_cycle(self.view)):\n            return\n        elif(file != None and type(file.AtInView(self.view,db.Get())) is node.OrgRootNode):\n            folding.fold_global_cycle(self.view)\n            return\n        elif(folding.am_in_link(self.view)):\n            folding.toggle_link(self.view)\n            return\n        # In a table, our tab expansion will take priority over Table Editor\n        # So we have to own it and if we are in a table forward the command\n        # All the other commands (at the moment) are okay\n        elif(table_tabbing(self.view)):\n            self.view.run_command(\"table_editor_next_field\")\n        elif(folding.ShouldFoldCheckbox(self.view)):\n            folding.FoldCheckbox(self.view)\n        else:\n            log.debug(\"tab expansion\")\n            self.view.run_command(\"insert_best_completion\", {\"default\": \"\\t\", \"exact\": False})\n            # {\"name\" : \"Packages/vhdl-mode/Snippets/vhdl-header.sublime_snippet\"}\n            #self.view.run_command(\"insert_snippet\") \n            #self.view.insert(edit,self.view.sel()[0].begin(), \"\\t\")\n\n# Global cycling\nclass OrgGlobalTabCyclingCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        folding.fold_global_cycle(self.view)\n\n\n"
  },
  {
    "path": "orgneovi.py",
    "content": "# For NeoVim we have to delay the import because otherwise we would crash.\n# So we try to import within the function after we have detected that neovintageous is installed.\nimport OrgExtended.packagecon as pkgcon\nimport logging\n\nlog = logging.getLogger(__name__)\n\ndef NeoVintageousYank(view, data: str):\n\ttry:\n\t\tfrom NeoVintageous.nv.registers import _set\n\t\t_set(view, '0', [data], True)\n\t\tlog.debug(\"NeoVintageous clipboard should now be set\")\n\texcept:\n\t\tprint('Failed to copy neovintageous could not be referenced')\n\t\tpass\n\n# NeoVintageous Clipboard is not the system clipboard.\n# Which is annoying as hell, but sublime does not have\n# the concept of registers... Sooo, we cheat and poke\n# the NV registers if NV is present.\ndef TestAndSetClip(view, data: str):\n\tif(pkgcon.IsInstalled(\"NeoVintageous\")):\n\t\tNeoVintageousYank(view, data)\n\telse:\n\t\tlog.debug(\"No NeoVintageous - cannot set neovintageous clipboard\")\n\n"
  },
  {
    "path": "orgnotifications.py",
    "content": "import sublime\nimport sublime_plugin\nimport threading, time, signal\nfrom datetime import timedelta\nfrom datetime import datetime\nimport os\nimport sys\nimport OrgExtended.orgagenda as agenda\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nfrom   OrgExtended.orgparse.date import OrgDate\nimport logging\nimport subprocess, os\n\nCHECK_PERIOD = 60*1\n\nlog = logging.getLogger(__name__)\n\nclass Notification(agenda.TodoView):\n\tdef Show(self, notifications, newItem):\n\t\t# Windows notice.\n\t\tn = newItem['node']\n\t\tf = newItem['file']\n\t\theading = \"\"\n\t\tif(n.scheduled):\n\t\t\theading = OrgDate.format_clock(n.scheduled.start,active=False)\n\t\telse:\n\t\t\theading = \"SOON!\"\n\t\tbody = f.AgendaFilenameTag() + \"  \" + n.heading\n\t\tShowBalloon(body, heading)\n\t\t# Show the in sublime version, clear out other\n\t\t# todos and just show our notices.\n\t\tself.entries = []\n\t\tif(notifications and type(notifications) is dict):\n\t\t\tfor key,item in notifications.items():\n\t\t\t\tself.AddEntry(item['node'],item['file'])\n\t\twindow = sublime.active_window() \n\t\twindow.active_view().run_command('org_show_notifications')\n\t\treturn\n\nnotification = None\nclass OrgShowNotifications(sublime_plugin.TextCommand):\n\tdef run(self, edit):\t\n\t\tnotification.DoRenderView(edit)\n\ndef ShowBalloon(todo, time):\n\tlog.debug(\"SHOW BALLOON POPUP\")\n\tformatDict = {\n\t\"time\": time,\n\t\"todo\": todo\n\t}\n\tif(sublime.platform() == 'windows'):\n\t\tcommandLine = sets.Get(\"ExternalNotificationCommand\",[r\"C:\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe\", \"-ExecutionPolicy\", \"Unrestricted\", \".\\\\balloontip.ps1\", \"\\\"{todo}\\\"\", \"\\\"{time}\\\"\"], formatDict)\n\telif(sublime.platform() == 'osx'):\n\t\tcommandLine = sets.Get(\"ExternalNotificationCommand\",['osascript','-e',\"display notification \\\"{time}\\\" with title \\\"{todo}\\\" subtitle \\\"\"+\"Org Mode TODO\"+\"\\\"\"], formatDict)\n\telse:\n\t\tprint(\"ERROR: platform not yet supported for notifications\")\n\t# Expand all potential macros.\n\tfor i in range(len(commandLine)):\n\t\tcommandLine[i] = commandLine[i].format(todo=todo,time=time)\n\ttry:\n\t\tstartupinfo = subprocess.STARTUPINFO()\n\t\tstartupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n\texcept:\n\t\tstartupinfo = None\n\t# cwd=working_dir, env=my_env,\n\tcwd = os.path.join(sublime.packages_path(),\"OrgExtended\") \n\tif(sublime.platform() == 'windows'):\n\t\tpopen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\t\tpopen.wait()\n\telif(sublime.platform() == 'osx'):\n\t\tsubprocess.check_call(commandLine,stderr=subprocess.STDOUT)\n\ndef IsWithinNotificationWindow(n, hours, minutes):\n\tif(not n.scheduled):\n\t\treturn False\n\tnow = datetime.now()\n\thour = now.hour\n\tmins = now.minute\n\tif(n.scheduled.repeating):\n\t\tnext = n.scheduled.next_repeat_from_today\n\t\treturn ((next.hour-hours) == hour and (next.minute - mins) <= minutes) \n\tnext = agenda.EnsureDateTime(n.scheduled.start)\n\treturn ((next.hour-hours) == hour and (next.minute - mins) <= minutes) \n\ndef GetUID(item):\n\tn = item['node']\n\tf = item['file']\n\treturn f.filename + \"@\" + n.get_locator() + \"@\" + str(n.scheduled)\n\nclass NotificationSystem(threading.Thread):\n\tdef __init__(self, interval):\n\t\tthreading.Thread.__init__(self)\n\t\tself.daemon     = False\n\t\tself.stopped    = threading.Event()\n\t\tself.interval   = interval\n\t\tself.today      = None\n\t\tself.notified   = {}\n\t\tself.todaysDate = datetime.now().day\n\t\tself.checkcount = 1\n\t\t\n\tdef stop(self):\n\t\tself.stopped.set()\n\t\tself.join()\n\n\tdef run(self):\n\t\twhile not self.stopped.wait(self.interval.total_seconds()):\n\t\t\tself.CheckNotifications()\n\n\tdef HaveNotifiedFor(self, item):\n\t\treturn GetUID(item) in self.notified\n\n\n\tdef DoNotify(self,item):\n\t\tself.notified[GetUID(item)] = item\n\t\tglobal notification\n\t\tnotification = Notification(\"Notifications\")\n\t\tnotification.Show(self.notified, item)\n\t\t\n\tdef CheckNotifications(self):\n\t\tlog.debug(\"CHECKING...\")\n\t\tif(datetime.now().day > self.todaysDate or self.today == None):\n\t\t\tself.todaysDate = datetime.now().day\n\t\t\tself.notified = {}\n\t\t\tself.BuildToday()\n\t\t# Periodically rebuild the day.\n\t\tif((self.checkcount % 4) == 0):\n\t\t\tself.checkcount += 1\n\t\t\tself.BuildToday()\n\n\t\thours   = sets.Get(\"notifyHoursBefore\", 0)\n\t\tminutes = sets.Get(\"notifyMinsBefore\", 15)\n\t\tfor item in self.today:\n\t\t\tn = item['node']\n\t\t\tif(IsWithinNotificationWindow(n, hours, minutes) and not self.HaveNotifiedFor(item)):\n\t\t\t\tlog.debug(\"DO NOTIFY CALLED\")\n\t\t\t\tself.DoNotify(item)\n\n\tdef AddEntry(self,n,f):\n\t\tself.today.append({'node': n, 'file': f})\n\n\tdef BuildToday(self):\n\t\tself.today = []\n\t\tfor file in db.Get().Files:\n\t\t\tfor n in file.org[1:]:\n\t\t\t\tif(self.TodayCheck(n, file)):\n\t\t\t\t\tself.AddEntry(n, file)\n\n\tdef TodayCheck(self, n, file):\n\t\ttry:\n\t\t\tnow = datetime.now()\n\t\t\treturn (agenda.IsTodo(n) and not agenda.IsDone(n) and not agenda.IsArchived(n) and agenda.IsToday(n, now))\n\t\texcept:\n\t\t\tif(n):\n\t\t\t\tlog.error(\"NOTIFICATIONS FAILED TO PARSE: \" + str(n.heading))\n\t\t\treturn False\n\n\nnotice = None\n\ndef Setup():\n\tglobal notice\n\tcheckPeriod = sets.Get(\"noticePeriod\",1)*60\n\tif(checkPeriod < 60):\n\t\tcheckPeriod = 60\n\tnotice = NotificationSystem(interval=timedelta(seconds=checkPeriod))\n\tnotice.start()\n\tlog.debug(\"NOTIFICATION SYSTEM IS UP AND RUNNING: \" + str(checkPeriod))\n\ndef Get():\n\treturn notice   \n\nclass OrgRebuildNotificationsCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n    \tglobal notice\n    \tif(notice == None):\n    \t\tSetup()\n    \tnotice.BuildToday()\n\n"
  },
  {
    "path": "orgnumberedlist.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcapture as capture\nimport sys\nimport os.path\nimport fnmatch\n\nlog = logging.getLogger(__name__)\n\nRE_HEADING = re.compile('^[*]+ ')\nRE_NUMLINE = re.compile(r\"^\\s*(?P<num>[0-9]+)(?P<sep>[.)])(?P<data>\\s+(([^:]+\\s+)(::))?.*)\")\nRE_NOTHEADERS = re.compile(r'^\\s*[\\#-+|]')\n# Returns a list of regions one per line with the children\n# of the current line. This is done by testing for headings\n# or a change in indent.\ndef findChildrenByIndent(view, region):\n    row, col = view.rowcol(region.begin())\n    line = view.line(region)\n    content = view.substr(line)\n    # print content\n    indent = view.getIndent(content)\n    if(not indent):\n        log.debug(\"Unable to locate indent for line: \" + str(row))\n    indent = len(indent)\n    # print repr(indent)\n    row += 1\n    child_indent = None\n    children = []\n    last_row, _ = view.rowcol(view.size())\n    while row <= last_row:\n        point   = view.text_point(row, 0)\n        line    = view.line(point)\n        content = view.substr(line)\n        cstrip = content.lstrip()\n        if cstrip.startswith(\"*\") or cstrip.startswith('-') or cstrip.startswith('+'):\n            break\n        if RE_NUMLINE.search(content):\n            cur_indent = len(view.getIndent(content))\n            # check for end of descendants\n            if cur_indent < indent:\n                break\n            # only immediate children\n            if child_indent is None:\n                child_indent = cur_indent\n            if cur_indent == child_indent:\n                children.append(line)\n        row += 1\n    return (children, row)\n\ndef UpdateLine(view, edit):\n    crow = view.curRow()\n    parent = view.findParentByIndent(view.curLine(),RE_NOTHEADERS, RE_NUMLINE)\n    prow, _ = view.rowcol(parent.begin())\n    children, erow = findChildrenByIndent(view, view.curLine())\n    cur = 1\n    curIndent = view.getIndent(view.getLine(prow+1))\n    curLen    = len(curIndent)\n    indentStack = []\n    for r in range(prow, erow):\n        line = view.getLine(r)\n        if(r < crow and len(line.strip()) <= 0):\n            continue\n        thisIndent = view.getIndent(line)\n        thisLen    = len(thisIndent)\n        if(thisLen > curLen):\n            indentStack.append((curIndent,curLen, cur))\n            curIndent = thisIndent\n            curLen    = thisLen\n            cur       = 1\n\n        while(thisLen < curLen and len(indentStack) > 0):\n            curIndent, curLen, cur = indentStack.pop()\n\n        if(thisLen == curLen):\n            m = RE_NUMLINE.search(line)\n            if(m):\n                num = int(m.group('num'))\n                if(num != cur):\n                    region = view.lineAt(r)\n                    view.replace(edit, region, '{0}{1}{2}{3}'.format(curIndent, cur, m.group('sep'), m.group('data')))\n                cur += 1\n\n\ndef AppendLine(view, edit, insertHere=True, veryEnd=False):\n    crow = view.curRow()\n    parent = view.findParentByIndent(view.curLine(), RE_NOTHEADERS, RE_NUMLINE)\n    prow, _ = view.rowcol(parent.begin())\n    children, erow = findChildrenByIndent(view, view.curLine())\n    cur = 1\n    curIndent = view.getIndent(view.getLine(crow))\n    curLen    = len(curIndent)\n    indentStack = []\n    sep = '.'\n    for r in range(prow+1, erow+1):\n        line = view.getLine(r)\n        if(r < crow and len(line.strip()) <= 0):\n            continue\n        thisIndent = view.getIndent(line)\n        thisLen    = len(thisIndent)\n        if(thisLen > curLen and veryEnd):\n            indentStack.append((curIndent,curLen, cur))\n            curIndent = thisIndent\n            curLen    = thisLen\n            cur       = 1\n\n        while(thisLen < curLen and len(indentStack) > 0):\n            curIndent, curLen, cur = indentStack.pop()\n\n        if(thisLen == curLen):\n            m = RE_NUMLINE.search(line)\n            if(m and (not insertHere or r <= crow)):\n                num = int(m.group('num'))\n                sep = m.group('sep')\n                if(num != cur):\n                    region = view.lineAt(r)\n                    view.replace(edit, region, '{0}{1}{2}{3}'.format(curIndent, cur, m.group('sep'), m.group('data')))\n                cur += 1\n            else:\n                prefix = \"\"\n                last_row, _ = view.rowcol(view.size())\n                if(r > last_row):\n                    prefix = \"\\n\"\n                point  = view.text_point(r, 0)\n                view.insert(edit,point,'{4}{0}{1}{2}{3}\\n'.format(curIndent, cur, sep, ' ',prefix))\n                view.sel().clear()\n                view.sel().add(point + len(curIndent) + 3)\n                view.run_command('org_update_numbered_list')\n                #UpdateLine(view,edit)\n                return\n        else:\n            prefix = \"\"\n            last_row, _ = view.rowcol(view.size())\n            if(r > last_row):\n                prefix = \"\\n\"\n            point  = view.text_point(r, 0)\n            view.insert(edit,point,'{4}{0}{1}{2}{3}\\n'.format(curIndent, cur, sep, ' ',prefix))\n            view.sel().clear()\n            view.sel().add(point + len(curIndent) + 3)\n            view.run_command('org_update_numbered_list')\n            #UpdateLine(view,edit)\n            return\n    # Okay we didn't insert, have to now\n    last_row, _ = view.rowcol(view.size())\n    prefix = \"\"\n    if(erow > last_row):\n        prefix = \"\\n\"\n        point  = view.size()\n    else:\n        point  = view.text_point(erow, 0)\n        line = view.getLine(erow)\n        newLine = ''\n        if(len(line) > 0):\n            newLine = '\\n'\n    view.insert(edit,point,'{5}{0}{1}{2}{3}{4}'.format(curIndent, cur, sep, ' ', newLine,prefix))\n    view.sel().clear()\n    view.sel().add(point + len(curIndent) + 3)\n    view.run_command('org_update_numbered_list')\n    #UpdateLine(view,edit)\n\ndef getListAtPointForSorting(view,pt=None):\n    if(pt):\n        line = view.line(pt)\n    else:\n        line = view.curLine()\n    #crow = view.curRow()\n    parent = view.findParentByIndent(line, RE_NOTHEADERS, RE_NUMLINE)\n    if(None != parent):\n        prow, _ = view.rowcol(parent.begin())\n        children, erow = findChildrenByIndent(view, parent)\n        sortby = view.getLine(prow)\n        m = RE_NUMLINE.search(sortby)\n        if(m):\n            sortby = m.group('data')\n        things = [[[prow,0],sortby]]\n        for c in children:\n            srow, _ = view.rowcol(c.begin())\n            if(len(things) > 0):\n                things[len(things)-1][0][1] = srow \n            sortby = view.getLine(srow)\n            m = RE_NUMLINE.search(sortby)\n            if(m):\n                sortby = m.group('data')\n            things.append([[srow,0],sortby])\n        if(len(things) > 0):\n            things[len(things)-1][0][1] = erow-1\n        return things\n    return None\n\ndef getListAtPoint(view,pt=None):\n    if(pt):\n        line = view.line(pt)\n    else:\n        line = view.curLine()\n    parent = view.findParentByIndent(line, RE_NOTHEADERS, RE_NUMLINE)\n    if(None != parent):\n        prow, _ = view.rowcol(parent.begin())\n        children, erow = findChildrenByIndent(view, parent)\n        sortby = view.getLine(prow)\n        m = RE_NUMLINE.search(sortby)\n        if(m):\n            sortby = m.group('data')\n        things = []\n        lastAppend = False\n        for c in children:\n            srow, _ = view.rowcol(c.begin())\n            if(lastAppend and len(things) > 0):\n                things[len(things)-1][0][1] = srow \n            sortby = view.getLine(srow)\n            m = RE_NUMLINE.search(sortby)\n            if(m):\n                sortby = m.group('data')\n                things.append([[srow,0],sortby])\n                lastAppend = True\n        if(len(things) > 0):\n            things[len(things)-1][0][1] = erow-1\n        return things\n    return None\n\ndef isNumberedLine(view,sel=None):\n    point = None\n    if(sel == None):\n        row = view.curRow()\n        point = view.text_point(row, 0)\n    else:\n        point = sel.end()\n    line = view.line(point)\n    content = view.substr(line)\n    return RE_NUMLINE.search(content)\n\n\nclass OrgUpdateNumberedListCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        view = self.view\n        UpdateLine(view, edit)\n\n\nclass OrgAppendNumberedListCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        view = self.view\n        AppendLine(view, edit)\n\nclass OrgAppendToEndOfNumberedListCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        view = self.view\n        AppendLine(view, edit,insertHere=False,veryEnd=False)\n\nclass OrgAppendChildToNumberedListCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        view = self.view\n        AppendLine(view, edit,insertHere=False, veryEnd=True)\n"
  },
  {
    "path": "orgpandoc.py",
    "content": "\nimport sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport OrgExtended.orgutil.temp as tf\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcapture as capture\nimport OrgExtended.orgproperties as props\nimport yaml\nimport sys\nimport subprocess\n\nlog = logging.getLogger(__name__)\n\nDEFAULT_COMMANDS = dict(\n\t# Standard universal can opener for OSX.\n\tdarwin=['open'],\n\twin32=['cmd', '/C'],\n\tlinux=['xdg-open'],\n)\n\ndef Execute(op):\n\tcmd = DEFAULT_COMMANDS[sys.platform]\n\tcmd = op\n\tprint(str(cmd))\n\tif sys.platform != 'win32':\n\t\tprocess = subprocess.Popen(\n\t\t\tcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\telse:\n\t\tprocess = subprocess.Popen(\n\t\t\tcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\n\tstdout, stderr = process.communicate()\n\tif stdout:\n\t\tstdout = str(stdout, sys.getfilesystemencoding())\n\t\tsublime.status_message(stdout)\n\t\tprint(stdout)\n\tif stderr:\n\t\tstderr = str(stderr, sys.getfilesystemencoding())\n\t\tsublime.error_message(stderr)\n\ndef GetCssForHtmlExport(style):\n\t# Include user created styles!\n\tcss = os.path.join(sublime.packages_path(),\"OrgExtended\", \"pandoc\", style + \".css\")\n\treturn css\n\ndef GetHeaderData(style):\n\tinHeader = os.path.join(sublime.packages_path(),\"OrgExtended\", \"pandoc\", style + \"_inheader.html\")\n\tif(os.path.isfile(inHeader)):\n\t\treturn [\"-H\", inHeader]\n\ndef Pandoc():\n\treturn sets.Get(\"PandocPath\",r'C:\\Program Files\\Pandoc\\pandoc.exe')\n\n# Export the entire file using pandoc \nclass OrgExportFileAsHtmlCommand(sublime_plugin.TextCommand):\n\tdef run(self,edit):\n\t\tstyle    = sets.Get(\"PandocStyle\",\"blocky\")\n\t\tcss      = GetCssForHtmlExport(style)\n\t\toutFile  = tf.GetViewFileAs(self.view, \".html\")\n\t\tcmd     = [Pandoc(), \"-s\",\"-c\",css]\n\t\tinHeader = GetHeaderData(style)\n\t\tif(inHeader):\n\t\t\tcmd.extend(inHeader)\n\t\tcmd.extend([\"-o\", outFile, self.view.file_name()])\n\t\tprint(cmd)\n\t\tExecute(cmd)\n\t\t#Execute([r'C:\\Program Files\\Pandoc\\pandoc.exe', '-h'])\n\n\nclass OrgExportSubtreeAsHtmlCommand(sublime_plugin.TextCommand):\n\tdef run(self,edit):\n\t\tn = db.Get().AtInView(self.view)\n\t\ts = self.view.text_point(n.start_row,0)\n\t\te = self.view.line(self.view.text_point(n.end_row,0)).end()\n\t\tr = sublime.Region(s,e)\n\t\tct = self.view.substr(r)\n\t\tstart = \"\"\n\t\tif \"#+TITLE:\" not in ct:\n\t\t\tstart = \"#+TITLE: \" + os.path.splitext(os.path.basename(self.view.file_name()))[0]\n\n\t\ttempFile = tf.CreateTempFileFromRegion(self.view, r, \".org\", start)\n\t\toutFile  = tf.GetViewFileAs(self.view, \".html\")\n\t\tstyle = sets.Get(\"PandocStyle\",\"blocky\")\n\t\tcss = GetCssForHtmlExport(style)\n\t\tcmd     = [Pandoc(), \"-s\",\"-c\",css]\n\t\tinHeader = GetHeaderData(style)\n\t\tif(inHeader):\n\t\t\tcmd.extend(inHeader)\n\t\tcmd = cmd.extend([\"-o\", outFile, tempFile])\t\n\t\tExecute(cmd)\n# pandoc -s -o output.html input.txt"
  },
  {
    "path": "orgparse/__init__.py",
    "content": "\n__version__ = '0.1.4dev0'\n__author__ = 'Takafumi Arakaki, Dmitrii Gerasimov'\n__license__ = 'BSD License'\n__all__ = [\"load\", \"loads\", \"loadi\"]\n"
  },
  {
    "path": "orgparse/date.py",
    "content": "import datetime\nimport re\nimport dateutil.rrule as dr\nimport dateutil.parser as dp\nimport dateutil.relativedelta as drel\nimport OrgExtended.orgduration as orgduration\nimport calendar\n\ndef total_seconds(td):\n    \"\"\"Equivalent to `datetime.timedelta.total_seconds`.\"\"\"\n    return float(td.microseconds +\n                 (td.seconds + td.days * 24 * 3600) * 10 ** 6) / 10 ** 6\n\n\ndef total_minutes(td):\n    \"\"\"Alias for ``total_seconds(td) / 60``.\"\"\"\n    return total_seconds(td) / 60\n\n\ndef gene_timestamp_regex(brtype, prefix=None, nocookie=False):\n    \"\"\"\n    Generate timetamp regex for active/inactive/nobrace brace type\n\n    :type brtype: {'active', 'inactive', 'nobrace'}\n    :arg  brtype:\n        It specifies a type of brace.\n        active: <>-type; inactive: []-type; nobrace: no braces.\n\n    :type prefix: str or None\n    :arg  prefix:\n        It will be appended to the head of keys of the \"groupdict\".\n        For example, if prefix is ``'active_'`` the groupdict has\n        keys such as ``'active_year'``, ``'active_month'``, and so on.\n        If it is None it will be set to ``brtype`` + ``'_'``.\n\n    :type nocookie: bool\n    :arg  nocookie:\n        Cookie part (e.g., ``'-3d'`` or ``'+6m'``) is not included if\n        it is ``True``.  Default value is ``False``.\n\n    >>> timestamp_re = re.compile(\n    ...     gene_timestamp_regex('active', prefix=''),\n    ...     re.VERBOSE)\n    >>> timestamp_re.match('no match')  # returns None\n    >>> m = timestamp_re.match('<2010-06-21 Mon>')\n    >>> m.group()\n    '<2010-06-21 Mon>'\n    >>> '{year}-{month}-{day}'.format(**m.groupdict())\n    '2010-06-21'\n    >>> m = timestamp_re.match('<2005-10-01 Sat 12:30 +7m -3d>')\n    >>> from collections import OrderedDict\n    >>> sorted(m.groupdict().items())\n    ... # doctest: +NORMALIZE_WHITESPACE\n    [('day', '01'),\n     ('end_hour', None), ('end_min', None),\n     ('hour', '12'), ('min', '30'),\n     ('month', '10'),\n     ('repeatdwmy', 'm'), ('repeatnum', '7'), ('repeatpre', '+'),\n     ('warndwmy', 'd'), ('warnnum', '3'), ('warnpre', '-'), ('year', '2005')]\n\n    When ``brtype = 'nobrace'``, cookie part cannot be retrieved.\n\n    >>> timestamp_re = re.compile(\n    ...     gene_timestamp_regex('nobrace', prefix=''),\n    ...     re.VERBOSE)\n    >>> timestamp_re.match('no match')  # returns None\n    >>> m = timestamp_re.match('2010-06-21 Mon')\n    >>> m.group()\n    '2010-06-21'\n    >>> '{year}-{month}-{day}'.format(**m.groupdict())\n    '2010-06-21'\n    >>> m = timestamp_re.match('2005-10-01 Sat 12:30 +7m -3d')\n    >>> sorted(m.groupdict().items())\n    ... # doctest: +NORMALIZE_WHITESPACE\n    [('day', '01'),\n     ('end_hour', None), ('end_min', None),\n     ('hour', '12'), ('min', '30'),\n     ('month', '10'), ('year', '2005')]\n    \"\"\"\n\n    if brtype == 'active':\n        (bo, bc) = ('<', '>')\n    elif brtype == 'inactive':\n        (bo, bc) = (r'\\[', r'\\]')\n    elif brtype == 'nobrace':\n        (bo, bc) = ('', '')\n    else:\n        raise ValueError(\"brtype='{0!r}' is invalid\".format(brtype))\n\n    if brtype == 'nobrace':\n        ignore = r'[\\s\\w]'\n    else:\n        ignore = '[^{bc}]'.format(bc=bc)\n\n    if prefix is None:\n        prefix = '{0}_'.format(brtype)\n\n    regex_date_time = r\"\"\"\n        (?P<{prefix}year>\\d{{4}}) -\n        (?P<{prefix}month>\\d{{2}}) -\n        (?P<{prefix}day>\\d{{2}})\n        (  # optional time field\n           ({ignore}+?)\n           (?P<{prefix}hour>\\d{{2}}) :\n           (?P<{prefix}min>\\d{{2}})\n           (  # optional end time range\n               --?\n               (?P<{prefix}end_hour>\\d{{2}}) :\n               (?P<{prefix}end_min>\\d{{2}})\n           )?\n        )?\n        \"\"\"\n    regex_cookie = r\"\"\"\n        (  # optional repeater\n           ({ignore}+?)\n           (?P<{prefix}repeatpre>  [\\.\\+]{{1,2}})\n           (?P<{prefix}repeatnum>  \\d+)\n           (?P<{prefix}repeatdwmy> [dwmy])\n        )?\n        (  # optional warning\n           ({ignore}+?)\n           (?P<{prefix}warnpre>  \\-)\n           (?P<{prefix}warnnum>  \\d+)\n           (?P<{prefix}warndwmy> [dwmy])\n        )?\n        \"\"\"\n    # http://www.pythonregex.com/\n    regex = ''.join([\n        bo,\n        regex_date_time,\n        regex_cookie if nocookie or brtype != 'nobrace' else '',\n        '({ignore}*?)',\n        bc])\n    return regex.format(prefix=prefix, ignore=ignore)\n\n\nTIMESTAMP_NOBRACE_RE = re.compile(\n    gene_timestamp_regex('nobrace', prefix=''),\n    re.VERBOSE)\n\nTIMESTAMP_RE = re.compile(\n    '|'.join((gene_timestamp_regex('active'),\n              gene_timestamp_regex('inactive'))),\n    re.VERBOSE)\ndef copy_repeat_info(f,t):\n    if(f and hasattr(f,'repeat_rule') and f.repeat_rule):\n        t.repeatpre = f.repeatpre\n        t.repeatdwmy  = f.repeatdwmy\n        t.repeat_rule = f.repeat_rule\n        t.freq = f.freq\n\n\ndef get_repeat_info(rv,mdict):\n\n    for prefix in ['active_','inactive_']:\n        if(prefix+'repeatpre' in mdict):\n            repeatpre  = mdict[prefix+'repeatpre']\n            repeatnum  = mdict[prefix+'repeatnum']\n            repeatdwmy = mdict[prefix+'repeatdwmy']\n            if(repeatdwmy is not None and repeatpre is not None):\n                rv.freq = dr.DAILY\n                if(repeatdwmy == 'y'):\n                    rv.freq = dr.YEARLY\n                if(repeatdwmy == 'm'):\n                    rv.freq = dr.MONTHLY\n                if(repeatdwmy == 'w'):\n                    rv.freq = dr.WEEKLY\n                rv.repeatnum = int(repeatnum)\n                if(rv.repeatnum <= 0):\n                    rv.repeatnum = 1\n                # Build an org mode repeat rule\n                rv.repeat_rule = dr.rrule(rv.freq,interval=rv.repeatnum,dtstart=rv.start,cache=True) \n                # This determines what to do when you mark the task as done.\n                # + just bump to the next FIXED interval (even if thats in the past)\n                # ++ bump to the next FIXED interval, in the future. (IE next sunday) even if you missed some.\n                # .+ bump but change the start date to today. \n                rv.repeatpre   = repeatpre\n                rv.repeatdwmy  = repeatdwmy\n        if(prefix+'warnpre' in mdict):\n            warnpre  = mdict[prefix+'warnpre']\n            warnnum  = mdict[prefix+'warnnum']\n            warndwmy = mdict[prefix+'warndwmy']\n            if(warndwmy is not None and warnpre is not None):\n                rv.warnnum = int(warnnum)\n                if(rv.warnnum <= 0):\n                    rv.warnnum = 1\n                rv.wfreq = dr.DAILY\n                rv.warn_rule = datetime.timedelta(days=rv.warnnum)\n                if(warndwmy == 'y'):\n                    rv.warn_rule = datetime.timedelta(years=rv.warnnum)\n                    rv.wfreq = dr.YEARLY\n                if(warndwmy == 'm'):\n                    rv.warn_rule = datetime.timedelta(months=rv.warnnum)\n                    rv.wfreq = dr.MONTHLY\n                if(warndwmy == 'w'):\n                    rv.warn_rule = datetime.timedelta(weeks=rv.warnnum)\n                    rv.wfreq = dr.WEEKLY\n                rv.warnpre   = warnpre\n                rv.warndwmy  = warndwmy\n\nclass OrgDate(object):\n\n    _active_default = True\n    \"\"\"\n    The default active value.\n\n    When the `active` argument to ``__init__`` is ``None``,\n    This value will be used.\n\n    \"\"\"\n\n    def __init__(self, start, end=None, active=None, repeat_rule=None, warn_rule=None):\n        \"\"\"\n        Create :class:`OrgDate` object\n\n        :type start: datetime, date, tuple, int, float or None\n        :type   end: datetime, date, tuple, int, float or None\n        :arg  start: Starting date.\n        :arg    end: Ending date.\n\n        :type active: bool or None\n        :arg  active: Active/inactive flag.\n                      None means using its default value, which\n                      may be different for different subclasses.\n\n        >>> OrgDate(datetime.date(2012, 2, 10))\n        OrgDate((2012, 2, 10))\n        >>> OrgDate((2012, 2, 10))\n        OrgDate((2012, 2, 10))\n        >>> OrgDate((2012, 2))  #doctest: +NORMALIZE_WHITESPACE\n        Traceback (most recent call last):\n            ...\n        ValueError: Automatic conversion to the datetime object\n        requires at least 3 elements in the tuple.\n        Only 2 elements are in the given tuple '(2012, 2)'.\n        >>> OrgDate((2012, 2, 10, 12, 20, 30))\n        OrgDate((2012, 2, 10, 12, 20, 30))\n        >>> OrgDate((2012, 2, 10), (2012, 2, 15), active=False)\n        OrgDate((2012, 2, 10), (2012, 2, 15), False)\n\n        OrgDate can be created using unix timestamp:\n\n        >>> OrgDate(datetime.datetime.fromtimestamp(0)) == OrgDate(0)\n        True\n\n        \"\"\"\n        self._start = self._to_date(start)\n        self._end = self._to_date(end)\n        self._active = self._active_default if active is None else active\n        self.repeat_rule = repeat_rule\n        self.warn_rule = warn_rule\n\n    def __add__(self,o):\n        if(isinstance(o,int)):\n            d = orgduration.OrgDuration.ParseInt(o)\n            td = d.timedelta()\n            return OrgDate(self._start + td,self._end + td if self._end else None,self._active,self.repeat_rule,self.warn_rule)\n        if(isinstance(o,orgduration.OrgDuration)):\n            td = o.timedelta()\n            return OrgDate(self._start + td,self._end + td if self._end else None,self._active,self.repeat_rule,self.warn_rule)\n        return self \n        pass\n    \n    def __sub__(self,o):\n        if(isinstance(o,int)):\n            d = orgduration.OrgDuration.ParseInt(o)\n            td = d.timedelta()\n            return OrgDate(self._start - td,self._end - td if self._end else None,self._active,self.repeat_rule,self.warn_rule)\n        if(isinstance(o,orgduration.OrgDuration)):\n            td = o.timedelta()\n            return OrgDate(self._start - td,self._end - td if self._end else None,self._active,self.repeat_rule,self.warn_rule)\n        return self \n\n    def before_duration(self, duration):\n        return self._start <= (datetime.datetime.now() + duration.timedelta())\n    \n    def after_duration(self, duration):\n        end = self._end if self._end is not None else self._start\n        return end >= (datetime.datetime.now() - duration.timedelta())\n\n    @staticmethod\n    def format_date(now, active):\n        if(active):\n            return now.strftime(\"<%Y-%m-%d %a>\")  \n        else:\n            return now.strftime(\"[%Y-%m-%d %a]\")  \n\n    @staticmethod\n    def format_clock(now, active):\n        if(active):\n            return now.strftime(\"<%Y-%m-%d %a %H:%M>\")  \n        else:\n            return now.strftime(\"[%Y-%m-%d %a %H:%M]\")  \n    \n    @staticmethod\n    def format_clock_with_time_range(s, e, active):\n        if(active):\n            return s.strftime(\"<%Y-%m-%d %a %H:%M-\") + e.strftime(\"%H:%M>\")\n        else:\n            return s.strftime(\"[%Y-%m-%d %a %H:%M-\") + e.strftime(\"%H:%M>\")\n\n    @staticmethod\n    def format_datetime(now):\n        if(isinstance(now,datetime.datetime)):\n            return now.strftime(\"%Y-%m-%d %a %H:%M\")  \n        else:\n            return now.strftime(\"%Y-%m-%d %a\")  \n    \n    @staticmethod\n    def format_duration(d):\n        hours   = d.seconds/3600\n        minutes = (d.seconds/60)%60 \n        return \"{0:02d}:{1:02d}\".format(int(hours),int(minutes))    \n\n    @staticmethod\n    def format_dwim(start, end=None,active=False):\n        if(end):\n            if(isinstance(start, datetime.datetime)):\n                if(end.date() != start.date()):\n                    duration = end - start\n                    return \"{0}--{1} => {2}\".format(\n                        OrgDate.format_clock(start, active), \n                        OrgDate.format_clock(end, active), \n                        OrgDate.format_duration(duration))\n                else:\n                    return OrgDate.format_clock_with_time_range(start,end,active)\n            else:\n                if(end == start):\n                    return OrgDate.format_date(start,active)\n                else:\n                    duration = end - start\n                    return \"{0}--{1} => {2}\".format(\n                        OrgDate.format_date(start, active), \n                        OrgDate.format_date(end, active), \n                        OrgDate.format_duration(duration))\n        else:\n            if(isinstance(start, datetime.datetime)):\n                return OrgDate.format_clock(start, active)\n            else:\n                return OrgDate.format_date(start,active)\n\n    @staticmethod\n    def format_as_clock(start, end=None,active=False):\n        if(end):\n            duration = end - start\n            return \"{0}--{1} => {2}\".format(\n                OrgDate.format_clock(start, active), \n                OrgDate.format_clock(end, active), \n                OrgDate.format_duration(duration))\n        else:\n            return \"{0}--\".format(\n                OrgDate.format_clock(start, active))\n\n    def format_clock_str(self):\n        return OrgDate.format_as_clock(self._start, self._end)\n    \n    def format_datetime_str(self):\n        return OrgDate.format_datetime(self._start)\n\n    @staticmethod\n    def _to_date(date):\n        if isinstance(date, (tuple, list)):\n            if len(date) == 3:\n                return datetime.date(*date)\n            elif len(date) > 3:\n                return datetime.datetime(*date)\n            else:\n                raise ValueError(\n                    \"Automatic conversion to the datetime object \"\n                    \"requires at least 3 elements in the tuple. \"\n                    \"Only {0} elements are in the given tuple '{1}'.\"\n                    .format(len(date), date))\n        elif isinstance(date, (int, float)):\n            return datetime.datetime.fromtimestamp(date)\n        else:\n            return date\n\n    @staticmethod\n    def _date_to_tuple(date):\n        if isinstance(date, datetime.datetime):\n            return tuple(date.timetuple()[:6])\n        elif isinstance(date, datetime.date):\n            return tuple(date.timetuple()[:3])\n\n    def __str__(self):\n        # TODO: Handle recurrence in this!\n        return self.format_dwim(self._start, self._end, self._active)\n\n    def __repr__(self):\n        args = [\n            self.__class__.__name__,\n            self._date_to_tuple(self.start),\n            self._date_to_tuple(self.end) if self.has_end() else None,\n            None if self._active is self._active_default else self._active,\n        ]\n        if args[2] is None and args[3] is None:\n            return '{0}({1!r})'.format(*args)\n        elif args[3] is None:\n            return '{0}({1!r}, {2!r})'.format(*args)\n        else:\n            return '{0}({1!r}, {2!r}, {3!r})'.format(*args)\n\n    def __nonzero__(self):\n        return bool(self._start)\n\n    __bool__ = __nonzero__  # PY3\n\n    def __eq__(self, other):\n        if (isinstance(other, OrgDate) and\n            self._start is None and\n            other._start is None):\n            return True\n        return (isinstance(other, self.__class__) and\n                self._start == other._start and\n                self._end == other._end and\n                self._active == other._active)\n\n    @property\n    def repeating(self):\n        return self.repeat_rule != None\n\n    @property\n    def warning(self):\n        return self.warn_rule != None\n\n    @property\n    def next_repeat_from_now(self):\n        now = datetime.datetime.now()\n        return self.repeat_rule.after(now,inc=True) \n\n    @property\n    def next_repeat_from_today(self):\n        # NOTE: This will be on midnight if the schedule doesn't have a time\n        now = datetime.datetime.now()\n        now = now.replace(hour=0,minute=0,second=0,microsecond=0)\n        return self.repeat_rule.after(now,inc=True) \n\n    def next_repeat_from(self,now):\n        #now = now.replace(hour=0,minute=0,second=0,microsecond=0)\n        return self.repeat_rule.after(now,inc=False) \n\n    @property\n    def deadline_start(self):\n        if(not self.warning):\n            self.warn_rule = datetime.timedelta(days=1)\n        return self.start - self.warn_rule\n\n    @property\n    def start(self):\n        \"\"\"\n        Get date or datetime object\n\n        >>> OrgDate((2012, 2, 10)).start\n        datetime.date(2012, 2, 10)\n        >>> OrgDate((2012, 2, 10, 12, 10)).start\n        datetime.datetime(2012, 2, 10, 12, 10)\n\n        \"\"\"\n        return self._start\n\n    @property\n    def end(self):\n        \"\"\"\n        Get date or datetime object\n\n        >>> OrgDate((2012, 2, 10), (2012, 2, 15)).end\n        datetime.date(2012, 2, 15)\n        >>> OrgDate((2012, 2, 10, 12, 10), (2012, 2, 15, 12, 10)).end\n        datetime.datetime(2012, 2, 15, 12, 10)\n\n        \"\"\"\n        return self._end\n\n    def is_active(self):\n        \"\"\"Return true if the date is active\"\"\"\n        return self._active\n\n    def has_end(self):\n        \"\"\"Return true if it has the end date\"\"\"\n        return bool(self._end)\n\n    def has_time(self):\n        \"\"\"\n        Return true if the start date has time field\n\n        >>> OrgDate((2012, 2, 10)).has_time()\n        False\n        >>> OrgDate((2012, 2, 10, 12, 10)).has_time()\n        True\n\n        \"\"\"\n        return isinstance(self._start, datetime.datetime)\n\n    def has_overlap(self, other):\n        \"\"\"\n        Test if it has overlap with other :class:`OrgDate` instance\n\n        If the argument is not an instance of :class:`OrgDate`, it is\n        converted to :class:`OrgDate` instance by ``OrgDate(other)``\n        first.\n\n        >>> od = OrgDate((2012, 2, 10), (2012, 2, 15))\n        >>> od.has_overlap(OrgDate((2012, 2, 11)))\n        True\n        >>> od.has_overlap(OrgDate((2012, 2, 20)))\n        False\n        >>> od.has_overlap(OrgDate((2012, 2, 11), (2012, 2, 20)))\n        True\n        >>> od.has_overlap((2012, 2, 11))\n        True\n\n        \"\"\"\n        if not isinstance(other, OrgDate):\n            other = OrgDate(other)\n        if self.has_end():\n            return (self._datetime_in_range(other.start) or\n                    self._datetime_in_range(other.end))\n        elif other.has_end():\n            return other._datetime_in_range(self.start)\n        else:\n            # These could be datetime entries\n            # do we care about the hours, probably not!\n            # this is containement and we are just a point\n            # if these are on the same day we are okay.\n            ss = self.start\n            os = other.start\n            if(not type(ss) == datetime.date):\n                ss = ss.date()\n            if(not type(os) == datetime.date):\n                os = os.date()\n            return ss == os\n\n    def after(self, date): \n        if not isinstance(date, (datetime.datetime, datetime.date)):\n            return False\n        asdt = self._as_datetime\n        if asdt(self.start) <= asdt(date):\n            return True\n        return False\n\n    def before(self, date): \n        if not isinstance(date, (datetime.datetime, datetime.date)):\n            return False\n        asdt = self._as_datetime\n        if asdt(self.start) >= asdt(date):\n            return True\n        return False\n\n    def _datetime_in_range(self, date):\n        if not isinstance(date, (datetime.datetime, datetime.date)):\n            return False\n        asdt = self._as_datetime\n        if asdt(self.start) <= asdt(date) <= asdt(self.end):\n            return True\n        return False\n\n    @staticmethod\n    def _as_datetime(date):\n        if isinstance(date, datetime.date):\n            return datetime.datetime(*date.timetuple()[:3])\n        return date\n\n    @staticmethod\n    def _daterange_from_groupdict(dct, prefix=''):\n        start_keys = ['year', 'month', 'day', 'hour'    , 'min']\n        end_keys   = ['year', 'month', 'day', 'end_hour', 'end_min']\n        start_range = list(map(int, filter(None, (dct[prefix + k] for k in start_keys))))\n        end_range   = list(map(int, filter(None, (dct[prefix + k] for k in end_keys))))\n        if len(end_range) < len(end_keys):\n            end_range = None\n        return (start_range, end_range)\n\n    def add_days(self, inc):\n        self._start += datetime.timedelta(days=inc)\n        if(self._end):\n            self._end += datetime.timedelta(days=inc)\n        # TODO: Handle recurrence rules\n\n    def add_hours(self, inc):\n        self._start += datetime.timedelta(hours=inc)\n        if(self._end):\n            self._end += datetime.timedelta(hours=inc)\n    \n    def add_minutes(self, inc):\n        self._start += datetime.timedelta(minutes=inc)\n        if(self._end):\n            self._end += datetime.timedelta(minutes=inc)\n\n    @staticmethod\n    def date_add_months(sourcedate,months):\n        month = sourcedate.month - 1 + months\n        year = sourcedate.year + month // 12\n        month = month % 12 + 1\n        day = min(sourcedate.day,calendar.monthrange(year,month)[1])\n        return datetime.date(year,month,day)\n\n    def add_months(self, inc):\n        forward = True\n        if inc < 0:\n            inc = -inc\n            forward = False\n        for i in range(0,inc):\n            if(forward):\n                smonth = self._start.month\n                syear  = self._start.year\n                self._start += datetime.timedelta(days=calendar.monthrange(syear,smonth)[1])\n                if(self._end):\n                    emonth = self._end.month\n                    eyear  = self._end.year\n                    self._end += datetime.timedelta(days=calendar.monthrange(eyear,emonth)[1])\n            else:\n                # TODO: This does not work\n                # This should be last months day count.\n                smonth = self._start.month - 1\n                syear  = self._start.year\n                if(smonth <= 0):\n                    smonth = 12\n                    syear -= 1\n                self._start -= datetime.timedelta(days=(calendar.monthrange(syear,smonth)[1]))\n                if(self._end):\n                    emonth = self._end.month - 1\n                    eyear  = self._end.year\n                    if(smonth <= 0):\n                        send = 12\n                        send -= 1\n                    self._end -= datetime.timedelta(days=(calendar.monthrange(eyear,emonth)[1]))\n        # TODO: Handle recurrence rules\n\n    @classmethod\n    def _datetuple_from_groupdict(cls, dct, prefix=''):\n        return cls._daterange_from_groupdict(dct, prefix=prefix)[0]\n\n\n    @classmethod\n    def list_from_str(cls, string):\n        \"\"\"\n        Parse string and return a list of :class:`OrgDate` objects\n\n        >>> OrgDate.list_from_str(\"... <2012-02-10 Fri> and <2012-02-12 Sun>\")\n        [OrgDate((2012, 2, 10)), OrgDate((2012, 2, 12))]\n        >>> OrgDate.list_from_str(\"<2012-02-10 Fri>--<2012-02-12 Sun>\")\n        [OrgDate((2012, 2, 10), (2012, 2, 12))]\n        >>> OrgDate.list_from_str(\"<2012-02-10 Fri>--[2012-02-12 Sun]\")\n        [OrgDate((2012, 2, 10)), OrgDate((2012, 2, 12), None, False)]\n        >>> OrgDate.list_from_str(\"this is not timestamp\")\n        []\n        >>> OrgDate.list_from_str(\"<2012-02-11 Sat 10:11--11:20>\")\n        [OrgDate((2012, 2, 11, 10, 11, 0), (2012, 2, 11, 11, 20, 0))]\n        \"\"\"\n        match = TIMESTAMP_RE.search(string)\n        if match:\n            rest = string[match.end():]\n            mdict = match.groupdict()\n            if mdict['active_year']:\n                prefix = 'active_'\n                active = True\n                rangedash = '--<'\n            else:\n                prefix = 'inactive_'\n                active = False\n                rangedash = '--['\n            has_rangedash = rest.startswith(rangedash)\n            match2 = TIMESTAMP_RE.search(rest) if has_rangedash else None\n            if has_rangedash and match2:\n                rest = rest[match2.end():]\n                # no need for check activeness here because of the rangedash\n                mdict2 = match2.groupdict()\n                odate = cls(\n                    cls._datetuple_from_groupdict(mdict, prefix),\n                    cls._datetuple_from_groupdict(mdict2, prefix),\n                    active=active)\n            else:\n                odate = cls(\n                    *cls._daterange_from_groupdict(mdict, prefix),\n                    active=active)\n            get_repeat_info(odate, mdict)\n            # FIXME: treat \"repeater\" and \"warn\"\n            ndate = cls.list_from_str(rest)\n            if len(ndate) > 0:\n                copy_repeat_info(ndate[0], odate)\n            return [odate] + ndate\n        else:\n            return []\n\n\n\n    @classmethod\n    def from_str(cls, string):\n        \"\"\"\n        Parse string and return an :class:`OrgDate` objects.\n\n        >>> OrgDate.from_str('2012-02-10 Fri')\n        OrgDate((2012, 2, 10))\n        >>> OrgDate.from_str('2012-02-10 Fri 12:05')\n        OrgDate((2012, 2, 10, 12, 5, 0))\n\n        \"\"\"\n        match = cls._from_str_re.match(string)\n        if match:\n            mdict = match.groupdict()\n            return cls(cls._datetuple_from_groupdict(mdict),\n                       active=cls._active_default)\n        else:\n            return cls(None)\n\n    _from_str_re = TIMESTAMP_NOBRACE_RE\n\n\ndef compile_sdc_re(sdctype):\n    brtype = 'inactive' if sdctype == 'CLOSED' else 'active'\n    return re.compile(\n        r'^(?!\\#).*{0}:\\s+{1}'.format(\n            sdctype,\n            gene_timestamp_regex(brtype, prefix='', nocookie=True)),\n        re.VERBOSE)\n\n\nclass OrgDateSDCBase(OrgDate):\n\n    _re = None  # override this!\n\n    # FIXME: use OrgDate.from_str\n    @classmethod\n    def from_str(cls, string):\n        match = cls._re.search(string)\n        if match:\n            mdict = match.groupdict()\n            start = cls._datetuple_from_groupdict(mdict)\n            end = None\n            end_hour = mdict['end_hour']\n            end_min  = mdict['end_min']\n            if end_hour is not None and end_min is not None:\n                end_dict = {}\n                end_dict.update(mdict)\n                end_dict.update({'hour': end_hour, 'min': end_min})\n                end = cls._datetuple_from_groupdict(end_dict)\n            rv = cls(start, end, active=cls._active_default)\n\n            repeatpre  = mdict['repeatpre']\n            repeatnum  = mdict['repeatnum']\n            repeatdwmy = mdict['repeatdwmy']\n            if(repeatdwmy is not None and repeatpre is not None):\n                rv.freq = dr.DAILY\n                if(repeatdwmy == 'y'):\n                    rv.freq = dr.YEARLY\n                if(repeatdwmy == 'm'):\n                    rv.freq = dr.MONTHLY\n                if(repeatdwmy == 'w'):\n                    rv.freq = dr.WEEKLY\n                rv.repeatnum = int(repeatnum)\n                if(rv.repeatnum <= 0):\n                    rv.repeatnum = 1\n                # Build an org mode repeat rule\n                rv.repeat_rule = dr.rrule(rv.freq,interval=rv.repeatnum,dtstart=rv.start,cache=True) \n                # This determines what to do when you mark the task as done.\n                # + just bump to the next FIXED interval (even if thats in the past)\n                # ++ bump to the next FIXED interval, in the future. (IE next sunday) even if you missed some.\n                # .+ bump but change the start date to today. \n                rv.repeatpre   = repeatpre\n                rv.repeatdwmy  = repeatdwmy\n\n            warnpre  = mdict['warnpre']\n            warnnum  = mdict['warnnum']\n            warndwmy = mdict['warndwmy']\n            if(warndwmy is not None and warnpre is not None):\n                rv.warnnum = int(warnnum)\n                if(rv.warnnum <= 0):\n                    rv.warnnum = 1\n                rv.wfreq = dr.DAILY\n                rv.warn_rule = datetime.timedelta(days=rv.warnnum)\n                if(warndwmy == 'y'):\n                    rv.warn_rule = datetime.timedelta(years=rv.warnnum)\n                    rv.wfreq = dr.YEARLY\n                if(warndwmy == 'm'):\n                    rv.warn_rule = datetime.timedelta(months=rv.warnnum)\n                    rv.wfreq = dr.MONTHLY\n                if(warndwmy == 'w'):\n                    rv.warn_rule = datetime.timedelta(weeks=rv.warnnum)\n                    rv.wfreq = dr.WEEKLY\n                rv.warnpre   = warnpre\n                rv.warndwmy  = warndwmy\n            return rv\n        else:\n            return cls(None)\n\n\nclass OrgDateScheduled(OrgDateSDCBase):\n    \"\"\"Date object to represent SCHEDULED attribute.\"\"\"\n    _re = compile_sdc_re('SCHEDULED')\n    _active_default = True\n\n\nclass OrgDateDeadline(OrgDateSDCBase):\n    \"\"\"Date object to represent DEADLINE attribute.\"\"\"\n    _re = compile_sdc_re('DEADLINE')\n    _active_default = True\n\n\nclass OrgDateClosed(OrgDateSDCBase):\n    \"\"\"Date object to represent CLOSED attribute.\"\"\"\n    _re = compile_sdc_re('CLOSED')\n    _active_default = False\n\ndef compile_nsdc_re():\n    brtype = 'nobrace' \n    return re.compile(r'^\\s*{0}'.format(gene_timestamp_regex(brtype, prefix='', nocookie=True)),re.VERBOSE)\n\nclass OrgDateFreeFloating(OrgDateSDCBase):\n    _active_default = False\n    _re = compile_nsdc_re()\n\n\n\ndef parse_sdc(string):\n    return (OrgDateScheduled.from_str(string),\n            OrgDateDeadline.from_str(string),\n            OrgDateClosed.from_str(string))\n\n\nclass OrgDateClock(OrgDate):\n\n    \"\"\"\n    Date object to represent CLOCK attributes.\n\n    >>> OrgDateClock.from_str(\n    ...   'CLOCK: [2010-08-08 Sun 17:00]--[2010-08-08 Sun 17:30] =>  0:30')\n    OrgDateClock((2010, 8, 8, 17, 0, 0), (2010, 8, 8, 17, 30, 0))\n\n    \"\"\"\n\n    _active_default = False\n\n    def __init__(self, start, end, duration=None, active=None):\n        \"\"\"\n        Create OrgDateClock object\n        \"\"\"\n        super(OrgDateClock, self).__init__(start, end, active=active)\n        self._duration = duration\n\n    @property\n    def duration(self):\n        \"\"\"\n        Get duration of CLOCK.\n\n        >>> duration = OrgDateClock.from_str(\n        ...   'CLOCK: [2010-08-08 Sun 17:00]--[2010-08-08 Sun 17:30] => 0:30'\n        ... ).duration\n        >>> duration.seconds\n        1800\n        >>> total_minutes(duration)\n        30.0\n\n        \"\"\"\n        return self.end - self.start\n\n    def is_duration_consistent(self):\n        \"\"\"\n        Check duration value of CLOCK line.\n\n        >>> OrgDateClock.from_str(\n        ...   'CLOCK: [2010-08-08 Sun 17:00]--[2010-08-08 Sun 17:30] => 0:30'\n        ... ).is_duration_consistent()\n        True\n        >>> OrgDateClock.from_str(\n        ...   'CLOCK: [2010-08-08 Sun 17:00]--[2010-08-08 Sun 17:30] => 0:15'\n        ... ).is_duration_consistent()\n        False\n\n        \"\"\"\n        return (self._duration is None or\n                self._duration == total_minutes(self.duration))\n\n    @classmethod\n    def from_str(cls, line):\n        \"\"\"\n        Get CLOCK from given string.\n\n        Return three tuple (start, stop, length) which is datetime object\n        of start time, datetime object of stop time and length in minute.\n\n        \"\"\"\n        match = cls._re.search(line)\n        if not match:\n            return cls(None, None)\n        d1 = None\n        d2 = None\n        dd = 0\n        y = match.group('y1')\n        if y:\n            d1 = datetime.datetime(int(y), int(match.group('mo1')), int(match.group('d1')), int(match.group('h1')), int(match.group('m1')))\n        y = match.group('y2')\n        if y:\n            d2 = datetime.datetime(int(y), int(match.group('mo2')), int(match.group('d2')), int(match.group('h2')), int(match.group('m2')))\n        h = match.group('dd1')\n        if h:\n            dd = int(h) * 60 + int(match.group('dd2'))\n        return cls(\n            d1,\n            d2,\n            dd)\n    _re = re.compile(\n        r'^((?!#).*CLOCK\\:\\s+)?'\n        r'\\s*\\[(?P<y1>\\d+)\\-(?P<mo1>\\d+)\\-(?P<d1>\\d+)[^\\]\\d]*(?P<h1>\\d+)\\:(?P<m1>\\d+)\\]--'\n        r'(\\[(?P<y2>\\d+)\\-(?P<mo2>\\d+)\\-(?P<d2>\\d+)[^\\]\\d]*(?P<h2>\\d+)\\:(?P<m2>\\d+)\\]\\s+=>\\s+(?P<dd1>\\d+)\\:(?P<dd2>\\d+))?'\n        )\n\n\nclass OrgDateRepeatedTask(OrgDate):\n\n    \"\"\"\n    Date object to represent repeated tasks.\n    \"\"\"\n\n    _active_default = False\n\n    def __init__(self, start, before, after, active=None):\n        super(OrgDateRepeatedTask, self).__init__(start, active=active)\n        self._before = before\n        self._after = after\n\n    def __repr__(self):\n        args = [self._date_to_tuple(self.start), self.before, self.after]\n        if self._active is not self._active_default:\n            args.append(self._active)\n        return '{0}({1})'.format(\n            self.__class__.__name__, ', '.join(map(repr, args)))\n\n    def __eq__(self, other):\n        return super(OrgDateRepeatedTask, self).__eq__(other) and \\\n            isinstance(other, self.__class__) and \\\n            self._before == other._before and \\\n            self._after == other._after\n\n    @property\n    def before(self):\n        \"\"\"\n        The state of task before marked as done.\n\n        >>> od = OrgDateRepeatedTask((2005, 9, 1, 16, 10, 0), 'TODO', 'DONE')\n        >>> od.before\n        'TODO'\n\n        \"\"\"\n        return self._before\n\n    @property\n    def after(self):\n        \"\"\"\n        The state of task after marked as done.\n\n        >>> od = OrgDateRepeatedTask((2005, 9, 1, 16, 10, 0), 'TODO', 'DONE')\n        >>> od.after\n        'DONE'\n\n        \"\"\"\n        return self._after\n"
  },
  {
    "path": "orgparse/enum.py",
    "content": "class Enum(set):\n    def __getitem__(self, name):\n    \tif name in self:\n    \t\treturn name\n\n    def __getattr__(self, name):\n        if name in self:\n            return name\n        raise AttributeError"
  },
  {
    "path": "orgparse/inline.py",
    "content": "\"\"\"\nOrg-mode inline markup parser.\n\"\"\"\n\nimport re\n\n\ndef to_plain_text(org_text):\n    \"\"\"\n    Convert an org-mode text into a plain text.\n\n    >>> to_plain_text('there is a [[link]] in text')\n    'there is a link in text'\n    >>> to_plain_text('some [[link][more complex link]] here')\n    'some more complex link here'\n    >>> print(to_plain_text('''It can handle\n    ... [[link][multi\n    ... line\n    ... link]].\n    ... See also: [[info:org#Link%20format][info:org#Link format]]'''))\n    It can handle\n    multi\n    line\n    link.\n    See also: info:org#Link format\n\n    \"\"\"\n    return RE_LINK.sub(\n        lambda m: m.group('desc0') or m.group('desc1'),\n        org_text)\n\n\nRE_LINK = re.compile(\n    r\"\"\"\n    (?:\n        \\[ \\[\n            (?P<desc0> [^\\]]+)\n        \\] \\]\n    ) |\n    (?:\n        \\[ \\[\n            (?P<link1> [^\\]]+)\n        \\] \\[\n            (?P<desc1> [^\\]]+)\n        \\] \\]\n    )\n    \"\"\",\n    re.VERBOSE)\n"
  },
  {
    "path": "orgparse/loader.py",
    "content": "# Import README.rst using cog\n# [[[cog\n# from cog import out\n# out('\"\"\"\\n{0}\\n\"\"\"'.format(open('../README.rst').read()))\n# ]]]\n\"\"\"\n===========================================================\n  orgparse - Python module for reading Emacs org-mode files\n===========================================================\n\n\n* `Documentation (Read the Docs) <https://orgparse.readthedocs.org>`_\n* `Repository (at GitHub) <https://github.com/karlicoss/orgparse>`_\n* `PyPI <https://pypi.python.org/pypi/orgparse>`_\n* `Travis CI <https://travis-ci.org/karlicoss/orgparse>`_  |build-status|\n\n.. |build-status|\n   image:: https://travis-ci.org/karlicoss/orgparse.svg?branch=master\n   :target: https://travis-ci.org/karlicoss/orgparse\n\nInstall\n-------\n\n  pip install orgparse\n\n\nUsage\n-----\n\nThere are pretty extensive doctests if you're interested in some specific method. Otherwise here are some example snippets:\n\n\nLoad org node\n^^^^^^^^^^^^^\n::\n\n    from orgparse import load, loads\n\n    load('PATH/TO/FILE.org')\n    load(file_like_object)\n\n    loads('''\n    * This is org-mode contents\n      You can load org object from string.\n    ** Second header\n    ''')\n\n\nTraverse org tree\n^^^^^^^^^^^^^^^^^\n\n>>> root = loads('''\n... * Heading 1\n... ** Heading 2\n... *** Heading 3\n... ''')\n>>> for node in root[1:]:  # [1:] for skipping root itself\n...     print(node)\n* Heading 1\n** Heading 2\n*** Heading 3\n>>> h1 = root.children[0]\n>>> h2 = h1.children[0]\n>>> h3 = h2.children[0]\n>>> print(h1)\n* Heading 1\n>>> print(h2)\n** Heading 2\n>>> print(h3)\n*** Heading 3\n>>> print(h2.get_parent())\n* Heading 1\n>>> print(h3.get_parent(max_level=1))\n* Heading 1\n\n\nAccessing node attributes\n^^^^^^^^^^^^^^^^^^^^^^^^^\n\n>>> root = loads('''\n... * DONE Heading          :TAG:\n...   CLOSED: [2012-02-26 Sun 21:15] SCHEDULED: <2012-02-26 Sun>\n...   CLOCK: [2012-02-26 Sun 21:10]--[2012-02-26 Sun 21:15] =>  0:05\n...   :PROPERTIES:\n...   :Effort:   1:00\n...   :OtherProperty:   some text\n...   :END:\n...   Body texts...\n... ''')\n>>> node = root.children[0]\n>>> node.heading\n'Heading'\n>>> node.scheduled\nOrgDateScheduled((2012, 2, 26))\n>>> node.closed\nOrgDateClosed((2012, 2, 26, 21, 15, 0))\n>>> node.clock\n[OrgDateClock((2012, 2, 26, 21, 10, 0), (2012, 2, 26, 21, 15, 0))]\n>>> bool(node.deadline)   # it is not specified\nFalse\n>>> node.tags == set(['TAG'])\nTrue\n>>> node.get_property('Effort')\n60\n>>> node.get_property('UndefinedProperty')  # returns None\n>>> node.get_property('OtherProperty')\n'some text'\n>>> node.body\n'  Body texts...'\n\n\"\"\"\n# [[[end]]]\n\nimport codecs\n\nimport OrgExtended.orgparse.node as node\nimport OrgExtended.orgparse.utils.py3compat as bs\n#from .node import parse_lines\n#from .utils.py3compat import basestring\nimport OrgExtended.asettings as sets\n\n\ndef bomType(file):\n    \"\"\"\n    returns file encoding string for open() function\n\n    EXAMPLE:\n        bom = bomtype(file)\n        open(file, encoding=bom, errors='ignore')\n    \"\"\"\n\n    f = open(file, 'rb')\n    b = f.read(4)\n    f.close()\n\n    if (b[0:3] == b'\\xef\\xbb\\xbf'):\n        return \"utf8\"\n\n    # Python automatically detects endianess if utf-16 bom is present\n    # write endianess generally determined by endianess of CPU\n    if ((b[0:2] == b'\\xfe\\xff') or (b[0:2] == b'\\xff\\xfe')):\n        return \"utf16\"\n\n    if ((b[0:5] == b'\\xfe\\xff\\x00\\x00') \n              or (b[0:5] == b'\\x00\\x00\\xff\\xfe')):\n        return \"utf32\"\n\n    # If BOM is not provided, then assume its the codepage\n    #     used by your operating system\n    return \"cp1252\"\n    # For the United States its: cp1252\n\ndef load(path):\n    \"\"\"\n    Load org-mode document from a file.\n\n    :type path: str or file-like\n    :arg  path: Path to org file or file-like object of a org document.\n\n    :rtype: :class:`orgparse.node.OrgRootNode`\n\n    \"\"\"\n    try:\n\n        if isinstance(path, bs.basestring):\n            orgfile = codecs.open(path, encoding='utf-8-sig')\n            filename = path\n        else:\n            orgfile = path\n            filename = path.name if hasattr(path, 'name') else '<file-like>'\n        return loadi((l.rstrip('\\n') for l in orgfile.readlines()),filename=filename)\n    except:\n        bom = bomType(path)\n        if isinstance(path, bs.basestring):\n            orgfile = codecs.open(path, encoding=bom)\n            filename = path\n        else:\n            orgfile = path\n            filename = path.name if hasattr(path, 'name') else '<file-like>'\n        return loadi((l.rstrip('\\n') for l in orgfile.readlines()),filename=filename)\n\n\ndef loads(string, filename='<string>'):\n    \"\"\"\n    Load org-mode document from a string.\n\n    :rtype: :class:`orgparse.node.OrgRootNode`\n\n    \"\"\"\n    return loadi(string.splitlines(), filename=filename)\n\n\ndef loadi(lines, filename='<lines>'):\n    \"\"\"\n    Load org-mode document from an iterative object.\n\n    :rtype: :class:`orgparse.node.OrgRootNode`\n\n    \"\"\"\n    # Push our default system wide todo states into the file parser\n    todoStates = sets.Get(\"todoStates\", sets.defaultTodoStates)\n    todos = []\n    dones = []\n    found = False\n    for i in todoStates:\n        if i == \"|\":\n            found = True\n            continue\n        if found:\n            dones.append(i)\n        else:\n            todos.append(i)\n    return node.parse_lines(lines, filename=filename, todos=todos, dones=dones)\n"
  },
  {
    "path": "orgparse/node.py",
    "content": "import re\nimport itertools\nimport sublime\ntry:\n    from collections.abc import Sequence\nexcept ImportError:\n    from collections import Sequence\n\nfrom .date import OrgDate, OrgDateClock, OrgDateRepeatedTask, parse_sdc\nfrom .inline import to_plain_text\nfrom .utils.py3compat import PY3, unicode\nimport copy\nfrom .startup import *\nimport OrgExtended.pymitter as evt\nimport datetime\n\n\nRE_TARGETS = re.compile(r'<<(?P<target>[^>]+)>>')\nRE_COMMENT = re.compile(r'^\\s*[#][+](?P<name>[A-Za-z][A-Za-z0-9_]+)[:]\\s*(?P<val>.*)$')\nRE_TABLE_MATCH = re.compile(r\"^\\s*\\|\")\n\nclass OffsetIter:\n    def __init__(self, lines):\n        self._lines = lines\n        self._cur   = 0\n        self._len   = len(lines)\n\n    def __iter__(self):\n        return self\n\n    @property\n    def offset(self):\n        return self._cur\n\n    def __next__(self):\n        self._cur += 1\n        if self._cur < self._len:\n            return self._lines[self._cur]\n        raise StopIteration\n\ndef lines_to_chunks(lines):\n    chunk = []\n    count = 0\n    start = 0\n    end   = 0\n    for l in lines:\n        if RE_NODE_HEADER.search(l):\n            end = count - 1\n            yield (chunk, start, end)\n            chunk = []\n            start = count\n        chunk.append(l.rstrip())\n        count += 1\n    end = count - 1\n    yield (chunk, start, end)\n\nRE_NODE_HEADER    = re.compile(r\"^\\*+ \")\nRE_HEADER_REPLACE = re.compile(\"^\\\\*+ \") \nRE_INDENT_REPLACE = re.compile(\"^[ \\t]*\")\nRE_DRAWER         = re.compile(\"^\\\\s*:([a-zA-Z][a-zA-Z0-9_-]*):\\\\s*$\")\n\ndef parse_heading_level(heading):\n    \"\"\"\n    Get star-stripped heading and its level\n\n    >>> parse_heading_level('* Heading')\n    ('Heading', 1)\n    >>> parse_heading_level('******** Heading')\n    ('Heading', 8)\n    >>> parse_heading_level('*') # None since no space after star\n    >>> parse_heading_level('*bold*') # None\n    >>> parse_heading_level('not heading')  # None\n\n    \"\"\"\n    try:\n        match = RE_HEADING_STARS.search(heading)\n        if match:\n            return (match.group(2), len(match.group(1)))\n    except:\n        pass\n    return (\" \", 1)\n\nRE_HEADING_STARS = re.compile(r'^(\\*+)\\s+(.*?)\\s*$')\n\n\ndef parse_heading_tags(heading):\n    \"\"\"\n    Get first tags and heading without tags\n\n    >>> parse_heading_tags('HEADING')\n    ('HEADING', [])\n    >>> parse_heading_tags('HEADING :TAG1:TAG2:')\n    ('HEADING', ['TAG1', 'TAG2'])\n    >>> parse_heading_tags('HEADING: this is still heading :TAG1:TAG2:')\n    ('HEADING: this is still heading', ['TAG1', 'TAG2'])\n    >>> parse_heading_tags('HEADING :@tag:_tag_:')\n    ('HEADING', ['@tag', '_tag_'])\n\n    Here is the spec of tags from Org Mode manual:\n\n      Tags are normal words containing letters, numbers, ``_``, and\n      ``@``.  Tags must be preceded and followed by a single colon,\n      e.g., ``:work:``.\n\n      -- (info \"(org) Tags\")\n\n    \"\"\"\n    match = RE_HEADING_TAGS.search(heading)\n    if match:\n        heading = match.group(1)\n        tagstr = match.group(2)\n        tags = tagstr.split(':')\n        evt.Get().emit(\"tagsfound\",tags)\n    else:\n        tags = []\n    return (heading, tags)\n\n# Tags are normal words containing letters, numbers, '_', and '@'. https://orgmode.org/manual/Tags.html\nRE_HEADING_TAGS = re.compile(r'(.*?)\\s*:([\\w@:]+):\\s*$')\n\n\ndef parse_heading_todos(heading, todo_candidates):\n    \"\"\"\n    Get TODO keyword and heading without TODO keyword.\n\n    >>> todos = ['TODO', 'DONE']\n    >>> parse_heading_todos('Normal heading', todos)\n    ('Normal heading', None)\n    >>> parse_heading_todos('TODO Heading', todos)\n    ('Heading', 'TODO')\n\n    \"\"\"\n    for todo in todo_candidates:\n        todows = '{0} '.format(todo)\n        if heading.startswith(todows):\n            return (heading[len(todows):], todo)\n    return (heading, None)\n\n\ndef parse_heading_priority(heading):\n    \"\"\"\n    Get priority and heading without priority field..\n\n    >>> parse_heading_priority('HEADING')\n    ('HEADING', None)\n    >>> parse_heading_priority('[#A] HEADING')\n    ('HEADING', 'A')\n    >>> parse_heading_priority('[#0] HEADING')\n    ('HEADING', '0')\n    >>> parse_heading_priority('[#A]')\n    ('', 'A')\n\n    \"\"\"\n    match = RE_HEADING_PRIORITY.search(heading)\n    if match:\n        return (match.group(2), match.group(1))\n    else:\n        return (heading, None)\n\n\nRE_HEADING_PRIORITY = re.compile(r'^\\s*\\[#([A-Z0-9])\\] ?(.*)$')\n\n\ndef parse_property(line):\n    \"\"\"\n    Get property from given string.\n\n    >>> parse_property(':Some_property: some value')\n    ('Some_property', 'some value')\n    >>> parse_property(':Effort: 1:10')\n    ('Effort', 70)\n\n    \"\"\"\n    prop_key = None\n    prop_val = None\n    match = RE_PROP.search(line)\n    if match:\n        prop_key = match.group(1)\n        prop_val = match.group(2).strip()\n        if prop_key == 'Effort':\n            if (':' in prop_val):\n                (h, m) = prop_val.split(\":\", 2)\n                if h.isdigit() and m.isdigit():\n                    prop_val = int(h) * 60 + int(m)\n        if prop_key is not None and prop_val is None:\n            prop_val = \"\"\n    return (prop_key, prop_val)\n\n\nRE_PROP = re.compile(r'^\\s*:([^ ]+):((\\s|[a-zA-Z0-9\\\"_-]).*?)\\s*$')\n\n\ndef parse_comment(line):\n    \"\"\"\n    Parse special comment such as ``#+SEQ_TODO``\n\n    >>> parse_comment('#+SEQ_TODO: TODO | DONE')\n    ('SEQ_TODO', 'TODO | DONE')\n    >>> parse_comment('# not a special comment')  # None\n\n    \"\"\"\n    m = RE_COMMENT.match(line)\n    if (m):\n        name = m.group('name')\n        val  = m.group('val').strip()\n        return (name, val)\n    # if line.startswith('#+'):\n    #    comment = line.lstrip('#+').split(':', 1)\n    #    if len(comment) == 2:\n    #        return (comment[0], comment[1].strip())\n\n\ndef parse_seq_todo(line):\n    \"\"\"\n    Parse value part of SEQ_TODO/TODO/TYP_TODO comment.\n\n    >>> parse_seq_todo('TODO | DONE')\n    (['TODO'], ['DONE'])\n    >>> parse_seq_todo(' Fred  Sara   Lucy Mike  |  DONE  ')\n    (['Fred', 'Sara', 'Lucy', 'Mike'], ['DONE'])\n    >>> parse_seq_todo('| CANCELED')\n    ([], ['CANCELED'])\n    >>> parse_seq_todo('REPORT(r) BUG(b) KNOWNCAUSE(k) | FIXED(f)')\n    (['REPORT', 'BUG', 'KNOWNCAUSE'], ['FIXED'])\n\n    See also:\n\n    * (info \"(org) Per-file keywords\")\n    * (info \"(org) Fast access to TODO states\")\n\n    \"\"\"\n    todo_done = line.split('|', 1)\n    if len(todo_done) == 2:\n        (todos, dones) = todo_done\n    else:\n        (todos, dones) = (line, '')\n    strip_fast_access_key = lambda x: x.split('(', 1)[0]\n    return (list(map(strip_fast_access_key, todos.split())),\n            list(map(strip_fast_access_key, dones.split())))\n\n\nclass OrgEnv(object):\n\n    \"\"\"\n    Information global to the file (e.g, TODO keywords).\n    \"\"\"\n\n    def __init__(self, todos=[], dones=[],\n                 filename='<undefined>'):\n        self._todos = list(todos)\n        self._dones = list(dones)\n        self._todo_not_specified_in_comment = True\n        self._filename = filename\n        self._nodes = []\n        self._targets = {}\n        self._names = {}\n        self._links = []\n        self.properties = []\n        self.customids = {}\n        self.ids = {}\n        self.NamedObjects = {}\n\n    @property\n    def links(self):\n        return self._links\n\n    @property\n    def targets(self):\n        return self._targets\n\n    @property\n    def names(self):\n        return self._names\n    \n    @property\n    def nodes(self):\n        \"\"\"\n        A list of org nodes.\n\n        >>> OrgEnv().nodes   # default is empty (of course)\n        []\n\n        >>> from orgparse import loads\n        >>> loads('''\n        ... * Heading 1\n        ... ** Heading 2\n        ... *** Heading 3\n        ... ''').env.nodes      # doctest: +ELLIPSIS  +NORMALIZE_WHITESPACE\n        [<orgparse.node.OrgRootNode object at 0x...>,\n         <orgparse.node.OrgNode object at 0x...>,\n         <orgparse.node.OrgNode object at 0x...>,\n         <orgparse.node.OrgNode object at 0x...>]\n\n        \"\"\"\n        return self._nodes\n\n    def add_todo_keys(self, todos, dones):\n        if self._todo_not_specified_in_comment:\n            self._todos = []\n            self._dones = []\n            self._todo_not_specified_in_comment = False\n        self._todos.extend(todos)\n        self._dones.extend(dones)\n\n    @property\n    def todo_keys(self):\n        \"\"\"\n        TODO keywords defined for this document (file).\n\n        >>> env = OrgEnv()\n        >>> env.todo_keys\n        ['TODO']\n\n        \"\"\"\n        return self._todos\n\n    @property\n    def done_keys(self):\n        \"\"\"\n        DONE keywords defined for this document (file).\n\n        >>> env = OrgEnv()\n        >>> env.done_keys\n        ['DONE']\n\n        \"\"\"\n        return self._dones\n\n    @property\n    def all_todo_keys(self):\n        \"\"\"\n        All TODO keywords (including DONEs).\n\n        >>> env = OrgEnv()\n        >>> env.all_todo_keys\n        ['TODO', 'DONE']\n\n        \"\"\"\n        return self._todos + self._dones\n\n    @property\n    def filename(self):\n        \"\"\"\n        Return a path to the source file or similar information.\n\n        If the org objects are not loaded from a file, this value\n        will be a string of the form ``<SOME_TEXT>``.\n\n        :rtype: str\n\n        \"\"\"\n        return self._filename\n\n    # parser\n\n    def from_chunks(self, chunks):\n        yield OrgRootNode.from_chunk(self, next(chunks))\n        for chunk in chunks:\n            yield OrgNode.from_chunk(self, chunk)\n\n\nclass OrgBaseNode(Sequence):\n    \"\"\"\n    Base class for :class:`OrgRootNode` and :class:`OrgNode`\n\n    .. attribute:: env\n\n       An instance of :class:`OrgEnv`.\n       All nodes in a same file shares same instance.\n\n    :class:`OrgBaseNode` is an iterable object:\n\n    >>> from orgparse import loads\n    >>> root = loads('''\n    ... * Heading 1\n    ... ** Heading 2\n    ... *** Heading 3\n    ... * Heading 4\n    ... ''')\n    >>> for node in root:\n    ...     print(node)\n    <BLANKLINE>\n    * Heading 1\n    ** Heading 2\n    *** Heading 3\n    * Heading 4\n\n    Note that the first blank line is due to the root node, as\n    iteration contains the object itself.  To skip that, use\n    slice access ``[1:]``:\n\n    >>> for node in root[1:]:\n    ...     print(node)\n    * Heading 1\n    ** Heading 2\n    *** Heading 3\n    * Heading 4\n\n    It also support sequence protocol.\n\n    >>> print(root[1])\n    * Heading 1\n    >>> root[0] is root  # index 0 means itself\n    True\n    >>> len(root)   # remember, sequence contains itself\n    5\n\n    Note the difference between ``root[1:]`` and ``root[1]``:\n\n    >>> for node in root[1]:\n    ...     print(node)\n    * Heading 1\n    ** Heading 2\n    *** Heading 3\n\n    \"\"\"\n    def find_last_child_index(self):\n        level = self.level\n        start = self._index\n        end = start\n        for i in range(start+1, len(self.env._nodes)):\n            if(self.env._nodes[i]._level <= level):\n                break\n            end = i\n        return end\n\n    def is_last_node(self):\n        return (self.get_sibling_down() == None or self.get_sibling_down() == self)\n\n    def get_comment(self, key, defaultVal):\n        if( key in self._special_comments):\n            return self._special_comments[key]\n        return defaultVal\n   \n    def set_comment(self, key, val):\n        if not key in self._special_comments:\n            self._lines.insert(0,\"#+\" + key + \": \" + val)\n            self._special_comments.setdefault(key, []).append(val)\n            return True\n        else:\n            vl = self._special_comments[key]\n            if val not in vl:\n                for i in range(len(self._lines)):\n                    line = self._lines[i]\n                    if(line.startswith(\"#+FILETAGS\")):\n                        line = line + \" \" + val\n                        self._lines[i] = line\n                        break\n                self._special_comments.setdefault(key, []).append(val)\n                return True\n        return False\n\n    def list_comment(self, key, defaultVal):\n        if(defaultVal == None):\n            defaultVal = []\n        if(self.parent):\n            defaultVal = self.parent.list_comment(key, defaultVal)\n        comment = \" \".join(defaultVal)\n        val = self.get_comment(key,[comment])[0].split(\" \")\n        return val\n\n    @property\n    def targets(self):\n        return self.env._targets\n\n    @property\n    def names(self):\n        return self.env._names\n\n    def archive(self, defaultVal):\n        dval = defaultVal\n        if(self.parent):\n            dval = self.parent.archive(defaultVal)\n        val = self.get_comment(\"ARCHIVE\", [ dval ])\n        return val[0]\n\n    def todo_states(self, defaultVal):\n        dval = defaultVal\n        if(self.parent):\n            dval = self.parent.todo_states(defaultVal)\n        val = self.get_comment(\"TODO\", [ dval ])\n        return val[0]\n\n    def get_last_child(self):\n        pos = self.find_last_child_index()\n        return self.env._nodes[pos]\n   \n\n    def get_sibling_and_child_up(self):\n        idx = 0\n        i = self._index - 1\n        level = self._level\n        while(i > 0):\n            sibling = self.env._nodes[i]\n            if(sibling._level < level):\n                return None\n            if(sibling._level >= level):\n                return sibling\n            i -= 1\n            idx += 1\n        # Return the root node\n        return None\n\n    def get_sibling_up(self):\n        i = self._index - 1\n        level = self._level\n        while(i > 0):\n            sibling = self.env._nodes[i]\n            if(sibling._level < level):\n                return None\n            if(sibling._level == level):\n                return sibling\n            i -= 1\n        # Return the root node\n        return None\n\n    def get_sibling_down(self):\n        i = self._index + 1\n        level = self._level\n        while(i < len(self.env._nodes)):\n            sibling = self.env._nodes[i]\n            if(sibling._level < level):\n                return None\n            if(sibling._level == level):\n                return sibling\n            i += 1\n        # Return the root node\n        return None\n\n\n    def insert_at(self, n, index):\n        if(n == None):\n            return\n\n        if(type(n) is OrgRootNode):\n            n = n.env._nodes[n._index+1] \n\n        if(index == n.index):\n            return\n\n        # IF the location is a child of ME\n        # then I have a problem! I need to\n        # validate for that.\n\n        global RE_HEADER_REPLACE\n        global RE_INDENT_REPLACE\n\n        # I have to copy the node or else\n        # I could have problems pulling it out\n        # of the remote tree and corrupting that.\n        n = copy.copy(n)\n        # Keep a reference around so the target env does not go\n        # away.\n        sourceEnv = n.env\n\n        sibling = self.env._nodes[index]\n\n        level  = sibling.level\n        clevel = n.level\n        ldif   = level - clevel\n        pos    = index\n        #pos = self._index\n        count = 0\n        for cnode in n[0]:\n            count += 1\n            ccn    = copy.copy(cnode)\n            self.env._nodes.insert(pos + count, ccn)\n            ccn._level = ccn._level + ldif\n            ccn._index = pos + count\n            ccn.env    = self.env\n            header     = \"*\" * ccn._level\n            indent     = \" \" * (ccn._level+1)\n            ccn._lines[0] = RE_HEADER_REPLACE.sub(header + \" \", ccn._lines[0])\n            ccn._heading = ccn._lines[0]\n            for i in range(1,len(ccn._lines)):\n                ccn._lines[i] = RE_INDENT_REPLACE.sub(indent, ccn._lines[i])\n        for i in range(pos + count, len(self.env._nodes)):\n            self.env._nodes[i]._index += count\n        # Now setup my new nodes Env properly\n        n.env = self.env\n        # Reset the num_children count, we will recount again, just in case\n        self._count = -1\n\n\n    def insert_child(self, n):\n        if(n == None):\n            return None\n\n        global RE_HEADER_REPLACE\n        global RE_INDENT_REPLACE\n        if(type(n) is OrgRootNode):\n            n = n.env._nodes[n._index+1]\n        n = copy.copy(n)\n        # Keep a reference around so the target env does not go\n        # away.\n        sourceEnv = n.env\n        level = self.level\n        clevel = n.level\n        ldif   = level - clevel + 1\n        pos = self.find_last_child_index()\n        startrow = self._end\n        if(len(self.env._nodes) > pos):\n            startrow = self.env._nodes[pos]._end + 1\n        elif(pos > self._index):\n            startrow = self.env._nodes[pos-1]._end + 1\n        #pos = self._index\n        retNode = None\n        count = 0\n        for cnode in n[0]:\n            count += 1\n            ccn = copy.copy(cnode)\n            self.env._nodes.insert(pos + count, ccn)\n            if(count == 1):\n                retNode = ccn\n            size = ccn.size()\n            # We have to update start end at least\n            ccn._start = startrow\n            ccn._end   = startrow + size\n            # Update property drawer location at least!\n            inprops = False\n            c = 0\n            s = 0\n            for line in ccn._lines:\n                if(inprops):\n                    if(\":END:\" in line):\n                        ccn._property_drawer_location = (ccn._start + s , ccn._start + c)\n                        break\n                elif(\":PROPERTIES:\" in line):\n                    inprops = True\n                    s = c\n                c += 1\n            # fix property drawer lines\n            startrow  += size + 1\n            ccn._level = ccn._level + ldif\n            ccn._index = pos + count\n            ccn.env = self.env\n            header = \"*\" * ccn._level\n            indent = \" \" * (ccn._level+1)\n            newHeading = RE_HEADER_REPLACE.sub(header + \" \", ccn._lines[0])\n            if(len(ccn._lines) > 1):\n                ccn._lines = ccn._lines[1:]\n                ccn._lines.insert(0, newHeading)\n            else:\n                ccn._lines = [newHeading]\n            ccn._heading = ccn._lines[0]\n            for i in range(1,len(ccn._lines)):\n                ccn._lines[i] = RE_INDENT_REPLACE.sub(indent, ccn._lines[i])\n        for i in range(pos + count, len(self.env._nodes)):\n            self.env._nodes[i]._index += count\n        # Now setup my new nodes Env properly\n        n.env = self.env\n        # Reset the num_children count, we will recount again, just in case\n        self._count = -1\n        return retNode\n\n    # Remove this node, and all its children!\n    def remove_node(self):\n        pos = self._index\n        end = pos\n        size = len(self.env._nodes)\n        level = self.level\n        if(pos < (size-1)):\n            for i in range(pos+1,size):\n                # < means higher in hierarchy\n                if(self.env._nodes[i].level <= level):\n                    break\n                end = i\n        #print(\"removing \"+str(pos)+\" to \"+str(end) + \" in \" + str(len(self.env._nodes)))\n        for i in range(end,pos-1,-1):\n            self.env._nodes.pop(i)\n        # Remove the elements.\n        #del self.env._nodes[pos:end+1]\n        # Now update the indexes!\n        size = len(self.env._nodes)\n        for i in range(pos,size):\n            self.env._nodes[i]._index = i\n\n    # NOTE: This will remove all children!\n    def replace_node(self, n):\n        if(type(n) is OrgRootNode):\n            n = n.env._nodes[n._index+1]\n        level = self.level\n        clevel = n.level\n        ldif   = level - clevel\n        pos = self._index\n        count = 0\n        self.remove_node()\n        for cnode in n[0]:\n            self.env._nodes.insert(pos + count, cnode)\n            cnode._level = cnode._level + ldif\n            cnode._index = pos + count\n            count += 1\n        for i in range(pos + count, len(self.env._nodes)):\n            self.env._nodes[i]._index += count\n\n    def __init__(self, env, index=None):\n        \"\"\"\n        Create a :class:`OrgBaseNode` object.\n\n        :type env: :class:`OrgEnv`\n        :arg  env: This will be set to the :attr:`env` attribute.\n\n        \"\"\"\n        self.env = env\n\n        # content\n        self._lines = []\n        # Num children, gets cached.\n        self._count = -1\n        self.lastName = None\n\n        # FIXME: use `index` argument to set index.  (Currently it is\n        # done externally in `parse_lines`.)\n        if index is not None:\n            self._index = index\n            \"\"\"\n            Index of `self` in `self.env.nodes`.\n\n            It must satisfy an equality::\n\n                self.env.nodes[self._index] is self\n\n            This value is used for quick access for iterator and\n            tree-like traversing.\n\n            \"\"\"\n\n    def __iter__(self):\n        yield self\n        level = self.level\n        for node in self.env._nodes[self._index + 1:]:\n            if node.level > level:\n                yield node\n            else:\n                break\n\n    def __len__(self):\n        return sum(1 for _ in self)\n\n    def __nonzero__(self):\n        # As self.__len__ returns non-zero value always this is not\n        # needed.  This function is only for performance.\n        return True\n\n    __bool__ = __nonzero__  # PY3\n\n    def __getitem__(self, key):\n        if isinstance(key, slice):\n            return itertools.islice(self, key.start, key.stop, key.step)\n        elif isinstance(key, int):\n            if key < 0:\n                key += len(self)\n            for (i, node) in enumerate(self):\n                if i == key:\n                    return node\n            raise IndexError(\"Out of range {0}\".format(key))\n        else:\n            raise TypeError(\"Inappropriate type {0} for {1}\"\n                            .format(type(key), type(self)))\n\n    # tree structure\n\n    def _find_same_level(self, iterable):\n        for node in iterable:\n            if node.level < self.level:\n                return\n            if node.level == self.level:\n                return node\n\n    @property\n    def start_row(self):\n        return self._start\n\n    def size(self):\n        return self._end - self._start\n\n    @property\n    def end_row(self):\n        end = self._end\n        midx = self._index\n        idx  = self.find_last_child_index()\n        if(midx != idx):\n            end = self.env._nodes[idx].end_row\n        return end\n\n    @property\n    def local_end_row(self):\n        return self._end\n\n    def recalc_duration(self):\n        self._local_duration = datetime.timedelta(seconds=0)\n        for c in self.clock:\n            self._local_duration += c.duration\n        self._total_duration = copy.copy(self._local_duration)\n        for c in self.children:\n            self._total_duration += c.duration()\n\n    def duration(self):\n        if(not hasattr(self,'_local_duration')):\n            self.recalc_duration()\n        return self._total_duration\n\n    def local_duration(self):\n        if(not hasattr(self,'_local_duration')):\n            self.recalc_duration()\n        return self._local_duration\n\n    @property\n    def end_row(self):\n        end = self._end\n        midx = self._index\n        idx  = self.find_last_child_index()\n        if(midx != idx):\n            end = self.env._nodes[idx].end_row\n        return end\n\n    @property\n    def previous_same_level(self):\n        \"\"\"\n        Return previous node if exists or None otherwise.\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node 1\n        ... * Node 2\n        ... ** Node 3\n        ... ''')\n        >>> (n1, n2, n3) = list(root[1:])\n        >>> n1.previous_same_level is None\n        True\n        >>> n2.previous_same_level is n1\n        True\n        >>> n3.previous_same_level is None  # n2 is not at the same level\n        True\n\n        \"\"\"\n        return self._find_same_level(reversed(self.env._nodes[:self._index]))\n\n    @property\n    def next_same_level(self):\n        \"\"\"\n        Return next node if exists or None otherwise.\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node 1\n        ... * Node 2\n        ... ** Node 3\n        ... ''')\n        >>> (n1, n2, n3) = list(root[1:])\n        >>> n1.next_same_level is n2\n        True\n        >>> n2.next_same_level is None  # n3 is not at the same level\n        True\n        >>> n3.next_same_level is None\n        True\n\n        \"\"\"\n        return self._find_same_level(self.env._nodes[self._index + 1:])\n\n    # FIXME: cache parent node\n    def _find_parent(self):\n        for node in reversed(self.env._nodes[:self._index]):\n            if node.level < self.level:\n                return node\n\n    def get_parent(self, max_level=None):\n        \"\"\"\n        Return a parent node.\n\n        :arg int max_level:\n            In the normally structured org file, it is a level\n            of the ancestor node to return.  For example,\n            ``get_parent(max_level=0)`` returns a root node.\n\n            In general case, it specify a maximum level of the\n            desired ancestor node.  If there is no ancestor node\n            which level is equal to ``max_level``, this function\n            try to find an ancestor node which level is smaller\n            than ``max_level``.\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node 1\n        ... ** Node 2\n        ... ** Node 3\n        ... ''')\n        >>> (n1, n2, n3) = list(root[1:])\n        >>> n1.get_parent() is root\n        True\n        >>> n2.get_parent() is n1\n        True\n        >>> n3.get_parent() is n1\n        True\n\n        For simplicity, accessing :attr:`parent` is alias of calling\n        :meth:`get_parent` without argument.\n\n        >>> n1.get_parent() is n1.parent\n        True\n        >>> root.parent is None\n        True\n\n        This is a little bit pathological situation -- but works.\n\n        >>> root = loads('''\n        ... * Node 1\n        ... *** Node 2\n        ... ** Node 3\n        ... ''')\n        >>> (n1, n2, n3) = list(root[1:])\n        >>> n1.get_parent() is root\n        True\n        >>> n2.get_parent() is n1\n        True\n        >>> n3.get_parent() is n1\n        True\n\n        Now let's play with `max_level`.\n\n        >>> root = loads('''\n        ... * Node 1 (level 1)\n        ... ** Node 2 (level 2)\n        ... *** Node 3 (level 3)\n        ... ''')\n        >>> (n1, n2, n3) = list(root[1:])\n        >>> n3.get_parent() is n2\n        True\n        >>> n3.get_parent(max_level=2) is n2  # same as default\n        True\n        >>> n3.get_parent(max_level=1) is n1\n        True\n        >>> n3.get_parent(max_level=0) is root\n        True\n\n        \"\"\"\n        if max_level is None:\n            max_level = self.level - 1\n        parent = self._find_parent()\n        while parent.level > max_level:\n            parent = parent.get_parent()\n        return parent\n\n    @property\n    def parent(self):\n        \"\"\"\n        Alias of :meth:`get_parent()` (calling without argument).\n        \"\"\"\n        return self.get_parent()\n    # FIXME: cache children nodes\n    def _find_children(self):\n        nodeiter = iter(self.env._nodes[self._index + 1:])\n        try:\n            node = next(nodeiter)\n        except StopIteration:\n            return\n        if node.level <= self.level:\n            return\n        yield node\n        last_child_level = node.level\n        for node in nodeiter:\n            if node.level <= self.level:\n                return\n            if node.level <= last_child_level:\n                yield node\n                last_child_level = node.level\n\n    @property\n    def num_children(self):\n        if(type(self) == OrgRootNode):\n            if(self._count == -1):\n                self._count = 0\n                for i in range(1, len(self.env._nodes)):\n                    if(self.env._nodes[i]._level == 1):\n                        self._count += 1\n            return self._count\n\n        if(self._count == -1):\n            self._count = 0\n            idx   = self._index + 1\n            level = self._level\n            for i in range(self._index + 1, len(self.env._nodes)):\n                if(self.env._nodes[i]._level <= level):\n                    return self._count\n                self._count += 1\n        return self._count\n\n    @property\n    def children(self):\n        \"\"\"\n        A list of child nodes.\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node 1\n        ... ** Node 2\n        ... *** Node 3\n        ... ** Node 4\n        ... ''')\n        >>> (n1, n2, n3, n4) = list(root[1:])\n        >>> (c1, c2) = n1.children\n        >>> c1 is n2\n        True\n        >>> c2 is n4\n        True\n\n        Note the difference to ``n1[1:]``, which returns the Node 3 also.:\n\n        >>> (m1, m2, m3) = list(n1[1:])\n        >>> m2 is n3\n        True\n\n        \"\"\"\n        return list(self._find_children())\n\n    @property\n    def root(self):\n        \"\"\"\n        The root node.\n\n        >>> from orgparse import loads\n        >>> root = loads('* Node 1')\n        >>> n1 = root[1]\n        >>> n1.root is root\n        True\n\n        \"\"\"\n        root = self\n        while True:\n            parent = root.get_parent()\n            if not parent:\n                return root\n            root = parent\n\n    # parser\n\n    @classmethod\n    def from_chunk(cls, env, chunk):\n        lines,start,end = chunk\n        self = cls(env)\n        self._lines = lines\n        self._start = start\n        self._end   = end\n        self._parse_comments()\n        return self\n\n    def is_in(self, line):\n        return line >= self._start and line <= self._end\n\n    def _parse_comments(self):\n        special_comments = {}\n        idx = -1\n        for line in self._lines:\n            idx += 1\n            parsed = parse_comment(line)\n            if parsed:\n                (key, val) = parsed\n                if(key == 'NAME' or key == 'name'):\n                    self.env._names[val] = { \n                    'row': idx + self._start, \n                    'offset': idx \n                    } \n                special_comments.setdefault(key, []).append(val)\n        self._special_comments = special_comments\n        # parse TODO keys and store in OrgEnv\n        for todokey in ['TODO', 'SEQ_TODO', 'TYP_TODO']:\n            for val in special_comments.get(todokey, []):\n                self.env.add_todo_keys(*parse_seq_todo(val))\n\n    # misc\n\n    @property\n    def level(self):\n        \"\"\"\n        Level of this node.\n\n        :rtype: int\n\n        \"\"\"\n        raise NotImplemented\n\n    def _get_tags(self, inher=False):\n        \"\"\"\n        Return tags\n\n        :arg bool inher:\n            Mix with tags of all ancestor nodes if ``True``.\n\n        :rtype: set\n\n        \"\"\"\n        return set()\n\n\n    @property\n    def tags(self):\n        \"\"\"\n        Tag of this and parents node.\n\n        >>> from orgparse import loads\n        >>> n2 = loads('''\n        ... * Node 1    :TAG1:\n        ... ** Node 2   :TAG2:\n        ... ''')[2]\n        >>> n2.tags == set(['TAG1', 'TAG2'])\n        True\n\n        \"\"\"\n        return self._get_tags(inher=True)\n\n    @property\n    def shallow_tags(self):\n        \"\"\"\n        Tags defined for this node (don't look-up parent nodes).\n\n        >>> from orgparse import loads\n        >>> n2 = loads('''\n        ... * Node 1    :TAG1:\n        ... ** Node 2   :TAG2:\n        ... ''')[2]\n        >>> n2.shallow_tags == set(['TAG2'])\n        True\n\n        \"\"\"\n        return self._get_tags(inher=False)\n\n    def is_root(self):\n        \"\"\"\n        Return ``True`` when it is a root node.\n\n        >>> from orgparse import loads\n        >>> root = loads('* Node 1')\n        >>> root.is_root()\n        True\n        >>> n1 = root[1]\n        >>> n1.is_root()\n        False\n\n        \"\"\"\n        return False\n\n    #def __unicode__(self):\n    #    return unicode(\"\\n\").join(self._lines)\n\n    #if PY3:\n    #    __str__ = __unicode__\n    #else:\n    def __str__(self):\n        return \"\\n\".join(self._lines) + \"\\n\"\n\n\nclass OrgRootNode(OrgBaseNode):\n\n    \"\"\"\n    Node to represent a file\n\n    See :class:`OrgBaseNode` for other available functions.\n\n    \"\"\"\n\n    # getter\n\n    @property\n    def level(self):\n        return 0\n\n    def get_parent(self, max_level=None):\n        return None\n\n    # misc\n\n    def is_root(self):\n        return True\n\n    def at(self, line):\n        for n in self.env._nodes:\n            if(n.is_in(line)):\n                return n\n        return None\n\n    def node_at(self, index):\n        if(index >= 0 and index < len(self.env._nodes)):\n            return self.env._nodes[index]\n        return None\n\n    def getFile(self):\n        return self.file\n\n    def setFile(self, file):\n        self.file = file\n\nRE_PROTO = re.compile(r\"^[a-zA-Z][a-zA-Z]+[:]\")\nclass OrgLink:\n    def __init__(self, text, link, desc, row, linktext):\n        self.text = text\n        self.linktext = linktext\n        self.link = link.strip() if link else link\n        self.desc = desc.strip() if desc else desc\n        self.row  = row\n        if(self.link and self.link.startswith(\"file:\")):\n            self.link = self.link[5:]\n        linkifo = self.link.split('::')\n        self.link = linkifo[0]\n        self.localTarget = None \n        if(len(linkifo) > 1):\n            self.localTarget = linkifo[1]\n\n    def IsFile(self):\n        if(self.link.startswith(\"http\")):\n            return False\n        return not RE_PROTO.search(self.link)\n\n\n\nclass OrgNode(OrgBaseNode):\n\n    \"\"\"\n    Node to represent normal org node\n\n    See :class:`OrgBaseNode` for other available functions.\n\n    \"\"\"\n\n    def __init__(self, *args, **kwds):\n        super(OrgNode, self).__init__(*args, **kwds)\n        self._heading = None\n        self._level = None\n        self._tags = None\n        self._todo = None\n        self._priority = None\n        self._properties = {}\n        self._property_offsets = {}\n        self._drawers = None\n        self._blocks = None\n        self._dynamicblocks = None\n        self._property_drawer_location = None\n        self._scheduled = OrgDate(None)\n        self._deadline = OrgDate(None)\n        self._closed = OrgDate(None)\n        self._timestamps = []\n        self._clocklist = []\n        self._body_lines = []\n        self._repeated_tasks = []\n        self._body_lines_start = None\n        self._customid = None\n        self._id = None\n        self._table = None\n\n    @property\n    def customid(self):\n        return self._customid\n    \n    @property\n    def id(self):\n        return self._id\n\n    # Location of the first table in the node\n    # Used for remote references to tables. (ID/CUSTOM_ID + first table)\n    @property\n    def table(self):\n        return self._table\n        \n    @property\n    def property_drawer_location(self):\n        return self._property_drawer_location\n\n    def set_property_drawer_location(self, value):\n        self._property_drawer_location = value\n\n    @property\n    def body_lines_start(self):\n        return self._body_lines_start\n\n    @property\n    def blocks(self):\n        return self._blocks\n\n    @property\n    def dynamicblocks(self):\n        return self._dynamicblocks\n\n    @property\n    def drawers(self):\n        return self._drawers\n\n    @property\n    def full_heading(self):\n        return self._lines[0]\n\n\n    def get_drawer(self,name):\n        for i in self.drawers:\n            if i['name'] == name:\n                return i\n        return None\n    # parser\n\n    def _parse_pre(self):\n        \"\"\"Call parsers which must be called before tree structuring\"\"\"\n        self._parse_heading()\n        # FIXME: make the following parsers \"lazy\"\n        ilines = OffsetIter(self._lines)\n        #try:\n        #    next(ilines)            # skip heading\n        #except StopIteration:\n        #    return\n        # This is creative each parser gets a crack at\n        # each line. The problem is that we can't\n        # tell the offset from the heading\n        gen = self._iparse_sdc(ilines)\n        gen = self._iparse_links(gen, ilines)\n        gen = self._iparse_names(gen, ilines)\n        gen = self._iparse_clock(gen, ilines)\n        gen = self._iparse_tables(gen, ilines)\n        gen = self._iparse_properties(gen, ilines)\n        gen = self._iparse_drawers(gen, ilines)\n        gen = self._iparse_targets(gen, ilines)\n        gen = self._iparse_blocks(gen, ilines)\n        gen = self._iparse_repeated_tasks(gen, ilines)\n        gen = self._iparse_timestamps(gen, ilines)\n        if(self._body_lines_start == None):\n            self._body_lines_start = self._start + ilines.offset + 1\n        self._body_lines = list(gen)\n\n    def _parse_heading(self):\n        heading = self._lines[0]\n        (heading, self._level) = parse_heading_level(heading)\n        (heading, self._tags) = parse_heading_tags(heading)\n        (heading, self._todo) = parse_heading_todos(\n            heading, self.env.all_todo_keys)\n        (heading, self._priority) = parse_heading_priority(heading)\n        self._heading = heading\n\n    # The following ``_iparse_*`` methods are simple generator based\n    # parser.  See ``_parse_pre`` for how it is used.  The principle\n    # is simple: these methods get an iterator and returns an iterator.\n    # If the item returned by the input iterator must be dedicated to\n    # the parser, do not yield the item or yield it as-is otherwise.\n\n    def _iparse_sdc(self, ilines):\n        \"\"\"\n        Parse SCHEDULED, DEADLINE and CLOSED time tamps.\n\n        They are assumed be in the first line.\n\n        \"\"\"\n        try:\n            line = next(ilines)\n        except StopIteration:\n            return\n\n        for i in range(0,3):\n            (scheduled, deadline, closed) = parse_sdc(line)\n\n            if not (scheduled or\n                    deadline or\n                    closed):\n                yield line  # when none of them were found\n            else:\n                if(scheduled):\n                    self._scheduled = scheduled\n                if(deadline):\n                    self._deadline = deadline\n                if(closed):\n                    self._closed = closed \n                try:\n                    line = next(ilines)\n                except StopIteration:\n                    return\n\n        for line in ilines:\n            yield line\n\n    def _iparse_clock(self, ilines, at):\n        self._clocklist = clocklist = []\n        for line in ilines:\n            try:\n                cl = OrgDateClock.from_str(line)\n            except:\n                print(\"FAILED PARSING CLOCK({0}): {1}\".format(at.offset,line))\n            if cl:\n                clocklist.append(cl)\n            else:\n                yield line\n\n    def _iparse_timestamps(self, ilines, at):\n        self._timestamps = timestamps = []\n        timestamps.extend(OrgDate.list_from_str(self._heading))\n        for l in ilines:\n            timestamps.extend(OrgDate.list_from_str(l))\n            yield l\n\n    def _iparse_names(self, ilines, at):\n        for l in ilines:\n            parsed = parse_comment(l)\n            if parsed:\n                (key, val) = parsed\n                if(key == 'NAME' or key == 'name'):\n                    self.lastName = val\n            yield l\n\n    def _iparse_tables(self, ilines, at):\n        in_table = False\n        start = None\n        localStart = None\n        for l in ilines:\n            m = RE_TABLE_MATCH.match(l)\n            if(m):\n                if(not start):\n                    localStart = at.offset\n                    start = self._start + localStart\n                in_table = True\n            else:\n                if(in_table):\n                    in_table = False\n                    localEnd = at.offset\n                    end = self._start + localEnd\n                    name = \"\"\n                    if(self.lastName):\n                        name = self.lastName\n                        self.env.NamedObjects[self.lastName] = {\"type\": \"t\", \"loc\": (start, end), \"nodeoff\": (localStart,localEnd), \"name\": self.lastName}\n                        self.lastName = None\n                    if(None == self._table):\n                        self._table = {\"type\": \"t\", \"loc\": (start, end), \"nodeoff\": (localStart,localEnd),\"name\": name}\n            yield l\n        if(in_table):\n            in_table = False\n            localEnd = at.offset\n            end = self._start + localEnd\n            name = \"\"\n            if(self.lastName):\n                name = self.lastName\n                self.env.NamedObjects[self.lastName] = {\"type\": \"t\", \"loc\": (start, end), \"nodeoff\": (localStart,localEnd), \"name\": self.lastName}\n                self.lastName = None\n            if(None == self._table):\n                self._table = {\"type\": \"t\", \"loc\": (start, end), \"nodeoff\": (localStart,localEnd), \"name\": name}\n\n    def _iparse_properties(self, ilines, at):\n        self._properties = properties = {}\n        self._property_offsets = poff = {}\n        in_property_field = False\n        start = 0\n        end   = 0\n        for line in ilines:\n            if in_property_field:\n                if line.find(\":END:\") >= 0:\n                    end = self._start + at.offset\n                    self._property_drawer_location = (start, end)\n                    self.env.properties.append(self._property_drawer_location)\n                    in_property_field = False\n                    break\n                else:\n                    (key, val) = parse_property(line)\n                    if key:\n                        properties.update({key: val})\n                        if (key.lower() == \"custom_id\"):\n                            self._customid = (val, at.offset)\n                            self.env.customids[val] = (at.offset, self._start)\n                        if (key.lower() == \"id\"):\n                            self._id = (val, at.offset)\n                            self.env.ids[val] = (at.offset, self._start)\n                        poff.update({key: at.offset})\n            elif line.find(\":PROPERTIES:\") >= 0:\n                start = self._start + at.offset\n                in_property_field = True\n            else:\n                yield line\n        for line in ilines:\n            yield line\n    \n    def _iparse_links(self, ilines, at):\n        #self.env._links\n        RE_LINK = re.compile(r\"\\[\\[(?P<link>[^\\]]+)\\](\\[(?P<desc>[^\\]]+)\\])?\\]\")\n        for line in ilines:\n            for m in RE_LINK.finditer(line):\n                row = self._start + at.offset\n                link = OrgLink(line, m.group('link'), m.group('desc'), row, m.group())\n                self.env._links.append(link)\n            yield line\n\n    def _iparse_drawers(self, ilines, at):\n        self._drawers = []\n        drawerName = \"\"\n        in_field = False\n        start    = 0\n        end      = 0\n        for line in ilines:\n            m = RE_DRAWER.search(line)\n            if in_field:\n                if line.find(\":END:\") >= 0:\n                    end = self._start + at.offset\n                    loc = (start, end)\n                    drw = { \"name\":drawerName, \"loc\":loc }\n                    self._drawers.append(drw)\n                    in_field = False\n            elif m != None and m.group(1) != \"PROPERTIES\" and m.group(1) != \"END\":\n                drawerName = m.group(1)\n                start      = self._start + at.offset\n                in_field   = True\n            else:\n                yield line\n        for line in ilines:\n            yield line\n\n    def _iparse_blocks(self, ilines, at):\n        self._blocks = []\n        self._dynamicblocks = []\n        in_block = False\n        in_dynamic_block = False\n        start = 0\n        end   = 0\n        for line in ilines:\n            if in_block:\n                if line.find(\"#+END_\") >= 0 or line.find(\"#+end_\") >= 0:\n                    end = self._start + at.offset\n                    blk = (start, end)\n                    if(self.lastName):\n                        self.env.NamedObjects[self.lastName] = {\"type\": \"b\", \"loc\": blk}\n                        self.lastName = None\n                    self._blocks.append(blk)\n                    in_block = False\n            elif in_dynamic_block:\n                if line.find(\"#+END:\") >= 0 or line.find(\"#+end:\") >= 0:\n                    end = self._start + at.offset\n                    blk = (start, end)\n                    if(self.lastName):\n                        self.env.NamedObjects[self.lastName] = {\"type\": \"db\", \"loc\": blk}\n                        self.lastName = None\n                    self._dynamicblocks.append(blk)\n                    in_dynamic_block = False\n            elif line.find(\"#+BEGIN_\") >= 0 or line.find(\"#+begin_\") >= 0:\n                start = self._start + at.offset\n                in_block = True\n            elif line.find(\"#+BEGIN:\") >= 0 or line.find(\"#+begin:\") >= 0:\n                start = self._start + at.offset\n                in_dynamic_block = True\n            else:\n                yield line\n        for line in ilines:\n            yield line\n\n    def _iparse_targets(self, ilines, at):\n        global RE_TARGETS\n        if(not hasattr(self.env,'_targets')):\n            self.env._targets = {}\n        for line in ilines:\n            m = RE_TARGETS.search(line)\n            if(m):\n                name = m.group('target')\n                row  = self._start + at.offset\n                col  = m.span('target')\n                self.env._targets[name] = {'row': row, 'col': col[0] + 1}\n            yield line\n\n    def _iparse_repeated_tasks(self, ilines, at):\n        self._repeated_tasks = repeated_tasks = []\n        for line in ilines:\n            match = self._repeated_tasks_re.search(line)\n            if match:\n                # FIXME: move this parsing to OrgDateRepeatedTask.from_str\n                mdict = match.groupdict()\n                done_state = mdict['done']\n                todo_state = mdict['todo']\n                date = OrgDate.from_str(mdict['date'])\n                repeated_tasks.append(\n                    OrgDateRepeatedTask(date.start, todo_state, done_state))\n            else:\n                yield line\n\n    _repeated_tasks_re = re.compile(\n        r'''\n        \\s+ - \\s+\n        State \\s+ \"(?P<done> [^\"]+)\" \\s+\n        from  \\s+ \"(?P<todo> [^\"]+)\" \\s+\n        \\[ (?P<date> [^\\]]+) \\]''',\n        re.VERBOSE)\n\n    # getter\n\n    @staticmethod\n    def _get_text(text, format='plain'):\n        if format == 'plain':\n            return to_plain_text(text)\n        elif format == 'raw':\n            return text\n        else:\n            raise ValueError('format={0} is not supported.'.format(format))\n\n    def get_heading(self, format='plain'):\n        \"\"\"\n        Return a string of head text without tags and TODO keywords.\n\n        >>> from orgparse import loads\n        >>> node = loads('* TODO Node 1').children[0]\n        >>> node.get_heading()\n        'Node 1'\n\n        It strips off inline markup by default (``format='plain'``).\n        You can get the original raw string by specifying\n        ``format='raw'``.\n\n        >>> node = loads('* [[link][Node 1]]').children[0]\n        >>> node.get_heading()\n        'Node 1'\n        >>> node.get_heading(format='raw')\n        '[[link][Node 1]]'\n\n        \"\"\"\n        return self._get_text(self._heading, format)\n\n    def get_body(self, format='plain'):\n        \"\"\"\n        Return a string of body text.\n\n        See also: :meth:`get_heading`.\n\n        \"\"\"\n        return self._get_text(\n            '\\n'.join(self._body_lines), format) if self._lines else ''\n\n    @property\n    def heading(self):\n        \"\"\"Alias of ``.get_heading(format='plain')``.\"\"\"\n        return self.get_heading()\n\n    @property\n    def body(self):\n        \"\"\"Alias of ``.get_body(format='plain')``.\"\"\"\n        return self.get_body()\n\n    @property\n    def level(self):\n        return self._level\n        \"\"\"\n        Level attribute of this node.  Top level node is level 1.\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node 1\n        ... ** Node 2\n        ... ''')\n        >>> (n1, n2) = root.children\n        >>> root.level\n        0\n        >>> n1.level\n        1\n        >>> n2.level\n        2\n\n        \"\"\"\n\n    @property\n    def priority(self):\n        \"\"\"\n        Priority attribute of this node.  It is None if undefined.\n\n        >>> from orgparse import loads\n        >>> (n1, n2) = loads('''\n        ... * [#A] Node 1\n        ... * Node 2\n        ... ''').children\n        >>> n1.priority\n        'A'\n        >>> n2.priority is None\n        True\n\n        \"\"\"\n        return self._priority\n\n    def _get_tags(self, inher=False):\n        tags = set(self._tags)\n        if inher:\n            globalTags = self.list_comment(\"FILETAGS\",[])\n            for t in globalTags:\n                if(t):\n                    t = t.strip()\n                    if(t != \"\"):\n                        if ':' in t:\n                            ts = t.split(':')\n                            for tt in ts:\n                                tt = tt.strip()\n                                if tt != \"\":\n                                    tags.add(tt)\n                        else:\n                            tags.add(t)\n            parent = self.get_parent()\n            if parent:\n                return tags | parent._get_tags(inher=True)\n        return tags\n\n\n    def add_tag(self, tag):\n        if(not tag in self._tags):\n            self._tags.append(tag)\n            head = self._lines[0].strip()\n            if(head.endswith(\":\")):\n                self._lines[0] = head + tag.strip() + \":\"\n            else:\n                self._lines[0] = head + \"    :\" + tag.strip() + \":\"\n\n    # Get a unique locator for this heading\n    def get_locator(self):\n        heading = self.heading\n        cur = self\n        while(cur.parent and cur.parent.level > 0):\n            cur = cur.parent\n            heading = cur.heading + \":\" + heading\n        return heading\n\n    @property\n    def todo(self):\n        \"\"\"\n        A TODO keyword of this node if exists or None otherwise.\n\n        >>> from orgparse import loads\n        >>> root = loads('* TODO Node 1')\n        >>> root.children[0].todo\n        'TODO'\n\n        \"\"\"\n        return self._todo\n\n    def update_property(self, key, val):\n        # Do we have this property already?\n        if(not key in self._properties):\n            self._properties[key] = val\n            # No property drawer, just add one.\n            if(not self._property_drawer_location):\n                self._property_drawer_location = (self._start + 1, self._start + 2)\n                i = 1\n                while(len(self._lines) > i and (\"SCHEDULED\" in self._lines[i] or \"DEADLINE\" in self._lines[i])):\n                    i += 1\n                self._lines.insert(i,   \"{0} :PROPERTIES:\".format(\" \" * self._level))\n                self._lines.insert(i+1, \"{0} :END:\".format(\" \" * self._level))\n            # Find property drawer and add this property\n            offset = self._property_drawer_location[0] - self._start + 1\n            self._lines.insert(offset, \"{0} :{1}: {2}\".format(\" \" * self.level,key,val))\n            self._property_drawer_location = (self._property_drawer_location[0], self._property_drawer_location[1] + 1)\n        # We have this property, if it has changed\n        # Modify it.\n        else:\n            offset = self._property_offsets[key]\n            self._properties[key] = val\n            self._lines[offset] = \"{0}  :{1}:{2}\\n\".format(\" \" * self._level,key,val)\n\n\n    def get_property(self, key, val=None):\n        \"\"\"\n        Return property named ``key`` if exists or ``val`` otherwise.\n\n        :arg str key:\n            Key of property.\n\n        :arg val:\n            Default value to return.\n\n        \"\"\"\n        return self._properties.get(key, val)\n\n    @property\n    def properties(self):\n        \"\"\"\n        Node properties as a dictionary.\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node\n        ...   :PROPERTIES:\n        ...   :SomeProperty: value\n        ...   :END:\n        ... ''')\n        >>> root.children[0].properties['SomeProperty']\n        'value'\n\n        \"\"\"\n        return self._properties\n\n    @property\n    def scheduled(self):\n        \"\"\"\n        Return scheduled timestamp\n\n        :rtype: a subclass of :class:`orgparse.date.OrgDate`\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node\n        ...   SCHEDULED: <2012-02-26 Sun>\n        ... ''')\n        >>> root.children[0].scheduled\n        OrgDateScheduled((2012, 2, 26))\n\n        \"\"\"\n        return self._scheduled\n\n    @property\n    def deadline(self):\n        \"\"\"\n        Return deadline timestamp.\n\n        :rtype: a subclass of :class:`orgparse.date.OrgDate`\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node\n        ...   DEADLINE: <2012-02-26 Sun>\n        ... ''')\n        >>> root.children[0].deadline\n        OrgDateDeadline((2012, 2, 26))\n\n        \"\"\"\n        return self._deadline\n\n    @property\n    def closed(self):\n        \"\"\"\n        Return timestamp of closed time.\n\n        :rtype: a subclass of :class:`orgparse.date.OrgDate`\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node\n        ...   CLOSED: [2012-02-26 Sun 21:15]\n        ... ''')\n        >>> root.children[0].closed\n        OrgDateClosed((2012, 2, 26, 21, 15, 0))\n\n        \"\"\"\n        return self._closed\n\n    @property\n    def clock(self):\n        \"\"\"\n        Return a list of clocked timestamps\n\n        :rtype: a list of a subclass of :class:`orgparse.date.OrgDate`\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node\n        ...   CLOCK: [2012-02-26 Sun 21:10]--[2012-02-26 Sun 21:15] =>  0:05\n        ... ''')\n        >>> root.children[0].clock\n        [OrgDateClock((2012, 2, 26, 21, 10, 0), (2012, 2, 26, 21, 15, 0))]\n\n        \"\"\"\n        return self._clocklist\n\n    def get_timestamps(self, active=False, inactive=False,\n                       range=False, point=False):\n        \"\"\"\n        Return a list of timestamps in the body text.\n\n        :type   active: bool\n        :arg    active: Include active type timestamps.\n        :type inactive: bool\n        :arg  inactive: Include inactive type timestamps.\n        :type    range: bool\n        :arg     range: Include timestamps which has end date.\n        :type    point: bool\n        :arg     point: Include timestamps which has no end date.\n\n        :rtype: list of :class:`orgparse.date.OrgDate` subclasses\n\n\n        Consider the following org node:\n\n        >>> from orgparse import loads\n        >>> node = loads('''\n        ... * Node\n        ...   CLOSED: [2012-02-26 Sun 21:15] SCHEDULED: <2012-02-26 Sun>\n        ...   CLOCK: [2012-02-26 Sun 21:10]--[2012-02-26 Sun 21:15] =>  0:05\n        ...   Some inactive timestamp [2012-02-23 Thu] in body text.\n        ...   Some active timestamp <2012-02-24 Fri> in body text.\n        ...   Some inactive time range [2012-02-25 Sat]--[2012-02-27 Mon].\n        ...   Some active time range <2012-02-26 Sun>--<2012-02-28 Tue>.\n        ... ''').children[0]\n\n        The default flags are all off, so it does not return anything.\n\n        >>> node.get_timestamps()\n        []\n\n        You can fetch appropriate timestamps using keyword arguments.\n\n        >>> node.get_timestamps(inactive=True, point=True)\n        [OrgDate((2012, 2, 23), None, False)]\n        >>> node.get_timestamps(active=True, point=True)\n        [OrgDate((2012, 2, 24))]\n        >>> node.get_timestamps(inactive=True, range=True)\n        [OrgDate((2012, 2, 25), (2012, 2, 27), False)]\n        >>> node.get_timestamps(active=True, range=True)\n        [OrgDate((2012, 2, 26), (2012, 2, 28))]\n\n        This is more complex example.  Only active timestamps,\n        regardless of range/point type.\n\n        >>> node.get_timestamps(active=True, point=True, range=True)\n        [OrgDate((2012, 2, 24)), OrgDate((2012, 2, 26), (2012, 2, 28))]\n\n        \"\"\"\n        return [\n            ts for ts in self._timestamps if\n            (((active and hasattr(ts,'is_active') and ts.is_active()) or\n              (inactive and hasattr(ts,'is_active') and not ts.is_active())) and\n             ((range and hasattr(ts,'has_end') and ts.has_end()) or\n              (point and hasattr(ts,'has_end') and not ts.has_end())))]\n\n    @property\n    def datelist(self):\n        \"\"\"\n        Alias of ``.get_timestamps(active=True, inactive=True, point=True)``.\n\n        :rtype: list of :class:`orgparse.date.OrgDate` subclasses\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node with point dates <2012-02-25 Sat>\n        ...   CLOSED: [2012-02-25 Sat 21:15]\n        ...   Some inactive timestamp [2012-02-26 Sun] in body text.\n        ...   Some active timestamp <2012-02-27 Mon> in body text.\n        ... ''')\n        >>> root.children[0].datelist      # doctest: +NORMALIZE_WHITESPACE\n        [OrgDate((2012, 2, 25)),\n         OrgDate((2012, 2, 26), None, False),\n         OrgDate((2012, 2, 27))]\n\n        \"\"\"\n        return self.get_timestamps(active=True, inactive=True, point=True)\n\n    @property\n    def rangelist(self):\n        \"\"\"\n        Alias of ``.get_timestamps(active=True, inactive=True, range=True)``.\n\n        :rtype: list of :class:`orgparse.date.OrgDate` subclasses\n\n        >>> from orgparse import loads\n        >>> root = loads('''\n        ... * Node with range dates <2012-02-25 Sat>--<2012-02-28 Tue>\n        ...   CLOCK: [2012-02-26 Sun 21:10]--[2012-02-26 Sun 21:15] => 0:05\n        ...   Some inactive time range [2012-02-25 Sat]--[2012-02-27 Mon].\n        ...   Some active time range <2012-02-26 Sun>--<2012-02-28 Tue>.\n        ...   Some time interval <2012-02-27 Mon 11:23-12:10>.\n        ... ''')\n        >>> root.children[0].rangelist     # doctest: +NORMALIZE_WHITESPACE\n        [OrgDate((2012, 2, 25), (2012, 2, 28)),\n         OrgDate((2012, 2, 25), (2012, 2, 27), False),\n         OrgDate((2012, 2, 26), (2012, 2, 28)),\n         OrgDate((2012, 2, 27, 11, 23, 0), (2012, 2, 27, 12, 10, 0))]\n\n        \"\"\"\n        return self.get_timestamps(active=True, inactive=True, range=True)\n\n    def has_date(self):\n        \"\"\"\n        Return ``True`` if it has any kind of timestamp\n        \"\"\"\n        return (self.scheduled or\n                self.deadline or\n                self.datelist or\n                self.rangelist)\n\n    @property\n    def repeated_tasks(self):\n        \"\"\"\n        Get repeated tasks marked DONE in a entry having repeater.\n\n        :rtype: list of :class:`orgparse.date.OrgDateRepeatedTask`\n\n        >>> from orgparse import loads\n        >>> node = loads('''\n        ... * TODO Pay the rent\n        ...   DEADLINE: <2005-10-01 Sat +1m>\n        ...   - State \"DONE\"  from \"TODO\"  [2005-09-01 Thu 16:10]\n        ...   - State \"DONE\"  from \"TODO\"  [2005-08-01 Mon 19:44]\n        ...   - State \"DONE\"  from \"TODO\"  [2005-07-01 Fri 17:27]\n        ... ''').children[0]\n        >>> node.repeated_tasks            # doctest: +NORMALIZE_WHITESPACE\n        [OrgDateRepeatedTask((2005, 9, 1, 16, 10, 0), 'TODO', 'DONE'),\n         OrgDateRepeatedTask((2005, 8, 1, 19, 44, 0), 'TODO', 'DONE'),\n         OrgDateRepeatedTask((2005, 7, 1, 17, 27, 0), 'TODO', 'DONE')]\n        >>> node.repeated_tasks[0].before\n        'TODO'\n        >>> node.repeated_tasks[0].after\n        'DONE'\n\n        Repeated tasks in ``:LOGBOOK:`` can be fetched by the same code.\n\n        >>> node = loads('''\n        ... * TODO Pay the rent\n        ...   DEADLINE: <2005-10-01 Sat +1m>\n        ...   :LOGBOOK:\n        ...   - State \"DONE\"  from \"TODO\"  [2005-09-01 Thu 16:10]\n        ...   - State \"DONE\"  from \"TODO\"  [2005-08-01 Mon 19:44]\n        ...   - State \"DONE\"  from \"TODO\"  [2005-07-01 Fri 17:27]\n        ...   :END:\n        ... ''').children[0]\n        >>> node.repeated_tasks            # doctest: +NORMALIZE_WHITESPACE\n        [OrgDateRepeatedTask((2005, 9, 1, 16, 10, 0), 'TODO', 'DONE'),\n         OrgDateRepeatedTask((2005, 8, 1, 19, 44, 0), 'TODO', 'DONE'),\n         OrgDateRepeatedTask((2005, 7, 1, 17, 27, 0), 'TODO', 'DONE')]\n\n        See: `(info \"(org) Repeated tasks\")\n        <http://orgmode.org/manual/Repeated-tasks.html>`_\n\n        \"\"\"\n        return self._repeated_tasks\n\n\ndef parse_lines(lines, filename, todos, dones):\n    env = OrgEnv(filename=filename, todos=todos, dones=dones)\n    # parse into node of list (environment will be parsed)\n    nodelist = list(env.from_chunks(lines_to_chunks(lines)))\n    # parse headings (level, TODO, TAGs, and heading)\n    nodelist[0]._index = 0\n    for (i, node) in enumerate(nodelist[1:], 1):   # nodes except root node\n        node._index = i\n        node._parse_pre()\n    env._nodes = nodelist\n    return nodelist[0]  # root\n\n"
  },
  {
    "path": "orgparse/startup.py",
    "content": "from .enum import Enum\n\n\nStartup = Enum([\"overview\", \"content\", \"showall\", \"showeverything\", \"fold\", \"nofold\", \"noinlineimages\", \"inlineimages\", \"logdone\", \"lognotedone\"])\n\n#+STARTUP: overview\n#+STARTUP: content\n#+STARTUP: showall\n#+STARTUP: showeverything\n#+STARTUP: lognotedone logdone - for closing a task\n"
  },
  {
    "path": "orgparse/sublimenode.py",
    "content": "import sublime\nimport sublime_plugin\nimport os\nfrom OrgExtended.orgutil.addmethod import *\nimport OrgExtended.orgparse.node as node\nimport re\nimport itertools\ntry:\n  from collections.abc import Sequence\nexcept ImportError:\n  from collections import Sequence\nfrom .date import OrgDate, OrgDateClock, OrgDateRepeatedTask, parse_sdc\nfrom .inline import to_plain_text\nfrom .utils.py3compat import PY3, unicode\nimport copy\nfrom .startup import *\nimport OrgExtended.asettings as sets\n\n\n@add_method(node.OrgBaseNode)\ndef priorities(self, defaultValue = None):\n    if(defaultValue == None):\n        defaultValue = [\"A\",\"B\",\"C\",\"D\",\"E\"]\n    priorityValues = sets.Get(\"priorities\", defaultValue)\n    return self.list_comment(\"PRIORITIES\", priorityValues)\n\n\n@add_method(node.OrgBaseNode)\ndef startup(self, defaultVal = None):\n    if(defaultVal == None):\n        defaultVal = []\n    globalStartup = sets.Get(\"startup\",defaultVal)\n    return self.list_comment(\"STARTUP\", globalStartup)\n\n# Returns true if this is more than just a heading\n@add_method(node.OrgBaseNode)\ndef spans_lines(self, view):\n    s = self.start_row\n    e = self.end_row\n    return e > s\n\n@add_method(node.OrgBaseNode)\ndef local_spans_lines(self, view):\n    s = self.start_row\n    e = self.local_end_row\n    return e > s\n\n# returns a sublime region that this node encompases\n# including all children\n@add_method(node.OrgBaseNode)\ndef region(self, view, trimEnd = False):\n    s  = self.start_row\n    e  = self.end_row\n    sp = view.text_point(s,0)\n    r  = view.line(sp)\n    ep = view.text_point(e,0)\n    re = view.line(ep)\n    # Trim whitespace off end if we can\n    if(trimEnd):\n        while(e > s):\n            ep = view.text_point(e,0)\n            re = view.line(ep)\n            sl = view.substr(re)\n            if(sl.strip() != \"\"):\n                break\n            e -= 1\n    return sublime.Region(r.end(),re.end()) \n\n@add_method(node.OrgBaseNode)\ndef local_region(self, view, trimEnd = False):\n    s  = self.start_row\n    e  = self.local_end_row\n    sp = view.text_point(s,0)\n    r  = view.line(sp)\n    ep = view.text_point(e,0)\n    re = view.line(ep)\n    # Trim whitespace off end if we can\n    if(trimEnd):\n        while(e > s):\n            ep = view.text_point(e,0)\n            re = view.line(ep)\n            sl = view.substr(re)\n            if(sl.strip() != \"\"):\n                break\n            e -= 1\n    return sublime.Region(r.end(),re.end())\n\n@add_method(node.OrgBaseNode)\ndef heading_region(self, view):\n    s  = self.start_row\n    sp = view.text_point(s,0)\n    return sublime.Region(sp) \n\n@add_method(node.OrgBaseNode)\ndef is_folded(self, view):\n    reg = self.region(view)\n    return view.isRegionFolded(reg)\n\n@add_method(node.OrgBaseNode)\ndef is_heading_visible(self, view):\n    reg = self.heading_region(view)\n    if(not view.isRegionFolded(reg)):\n        return True\n    return False\n\n@add_method(node.OrgBaseNode)\ndef fold(self, view):\n    if(self.spans_lines(view)):\n        view.fold(self.region(view))\n\n@add_method(node.OrgBaseNode)\ndef fold_content(self, view):\n    if(self.local_spans_lines(view)):\n        view.fold(self.local_region(view))\n\n@add_method(node.OrgBaseNode)\ndef is_content_folded(self, view):\n    if(self.local_spans_lines(view)):\n        return view.isRegionFolded(self.local_region(view))\n    return False\n\n@add_method(node.OrgBaseNode)\ndef unfold(self, view):\n    if(self.spans_lines(view)):\n        reg = self.region(view)\n        if(view.isRegionFolded(reg)):\n            view.unfold(reg)\n        self.fold_drawers(view)\n\n@add_method(node.OrgBaseNode)\ndef has_substance(self):\n    return (self.end_row > self.start_row or self.num_children > 0)\n\n# This will create a sublime region from an item in the\n# view.\n@add_method(node.OrgBaseNode)\ndef create_region_from_item(self, view, item):\n    s  = item[0]\n    e  = item[1]\n    sp = view.text_point(s,0)\n    ep = view.text_point(e,0)\n    r  = view.line(ep)\n    rs = view.line(sp)\n    return sublime.Region(rs.end(),r.end()) \n\n@add_method(node.OrgBaseNode)\ndef get_foldable_blocktype(self, view, row):\n    if(self.blocks):\n        for i in self.blocks:\n            if(i != None and row >= i[0] and row <= i[1]):\n                return self.create_region_from_item(view, i)\n    if(self.dynamicblocks):\n        for i in self.dynamicblocks:\n            if(i != None and row >= i[0] and row <= i[1]):\n                return self.create_region_from_item(view, i)\n    return None\n\n\n@add_method(node.OrgBaseNode)\ndef get_foldable_drawertype(self, view, row):\n    if(self.property_drawer_location):\n        i = self.property_drawer_location\n        if(row >= i[0] and row <= i[1]):\n            return self.create_region_from_item(view, i)\n    if(self.drawers):\n        for d in self.drawers:\n            i = d['loc']\n            if(i != None and row >= i[0] and row <= i[1]):\n                return self.create_region_from_item(view, i)\n\n# For an item IN in the heading this will try to let\n# you fold it.\n@add_method(node.OrgBaseNode)\ndef get_foldable_item_region(self, view, row):\n    if(self.property_drawer_location):\n        i = self.property_drawer_location\n        if(row >= i[0] and row <= i[1]):\n            return self.create_region_from_item(view, i)\n    if(self.blocks):\n        for i in self.blocks:\n            if(i != None and row >= i[0] and row <= i[1]):\n                return self.create_region_from_item(view, i)\n    if(self.dynamicblocks):\n        for i in self.dynamicblocks:\n            if(i != None and row >= i[0] and row <= i[1]):\n                return self.create_region_from_item(view, i)\n    if(self.drawers):\n        for d in self.drawers:\n            i = d['loc']\n            if(i != None and row >= i[0] and row <= i[1]):\n                return self.create_region_from_item(view, i)\n    return None\n\n@add_method(node.OrgBaseNode)\ndef is_item_folded(self, view, row):\n    (row,col) = view.curRowCol()\n    reg = self.get_foldable_item_region(view, row)\n    if(reg != None):\n        return view.isRegionFolded(reg)\n    return False\n\n# Iterate over all foldable items and see if this row is\n# a foldable row in the document.\n@add_method(node.OrgBaseNode)\ndef is_foldable_item(self, view, row):\n    return self.get_foldable_item_region(view, row) != None\n\n# Iterate over all foldable items and see if this row is\n# a foldable row in the document.\n@add_method(node.OrgBaseNode)\ndef is_foldable_drawertype(self, view, row):\n    return self.get_foldable_drawertype(view, row) != None\n\n@add_method(node.OrgBaseNode)\ndef fold_item(self, view, row):\n    reg = self.get_foldable_item_region(view, row)\n    if(reg != None):\n        view.fold(reg)\n\n@add_method(node.OrgBaseNode)\ndef unfold_item(self, view, row):\n    reg = self.get_foldable_item_region(view, row)\n    if(reg != None):\n        view.unfold(reg)\n\n@add_method(node.OrgBaseNode)\ndef properties_region(self, view):\n    s  = self.property_drawer_location[0]\n    e  = self.property_drawer_location[1]\n    sp = view.text_point(s,0)\n    ep = view.text_point(e,0)\n    r  = view.line(ep)\n    rs = view.line(sp)\n    return sublime.Region(rs.end(),r.end()) \n\n@add_method(node.OrgBaseNode)\ndef fold_drawers(self, view):\n    if(hasattr(self,'property_drawer_location') and self.property_drawer_location):\n        view.fold(self.properties_region(view))\n    if(hasattr(self,'drawers') and self.drawers):\n        for d in self.drawers:\n            i = d['loc']\n            view.fold(self.create_region_from_item(view, i))\n\n@add_method(node.OrgBaseNode)\ndef unfold_drawers(self, view):\n    if(self.property_drawer_location):\n        view.unfold(self.properties_region(view))\n    if(self.drawers):\n        for d in self.drawers:\n            i = d['loc']\n            if(i != None and row >= i[0] and row <= i[1]):\n                view.unfold(self.create_region_from_item(view, i))\n\n@add_method(node.OrgBaseNode)\ndef is_properties_folded(self, view):\n    reg = self.properties_region(view)\n    return view.isRegionFolded(reg)\n\n\n@add_method(node.OrgBaseNode)\ndef move_cursor_to(self, view):\n    view.sel().clear()\n    pt = view.text_point(self.start_row,0)\n    view.sel().add(pt)\n\n@add_method(node.OrgBaseNode)\ndef indent(self):\n    level = self.level\n    return (\" \" + (\" \" * level))\n\n"
  },
  {
    "path": "orgparse/utils/__init__.py",
    "content": ""
  },
  {
    "path": "orgparse/utils/_py3compat.py",
    "content": "\"\"\"\nPython 3 compatibility code which is loaded only when from Python 3.\n\"\"\"\n\n\ndef execfile(filename, *args):\n    return exec(\n        compile(open(filename).read(), filename, 'exec'),\n        *args)\n"
  },
  {
    "path": "orgparse/utils/py3compat.py",
    "content": "import sys\n\nPY3 = (sys.version_info[0] >= 3)\n\ntry:\n    # Python 2\n    unicode = unicode\n    basestring = basestring\nexcept NameError:\n    # Python 3\n    basestring = unicode = str\n\nPY3 = (sys.version_info[0] >= 3)\n\nif PY3:\n    from ._py3compat import execfile\nelse:\n    execfile = execfile\n"
  },
  {
    "path": "orgplist.py",
    "content": "import sublime\nimport sublime_plugin\nimport os\nimport base64\nimport urllib.request\nimport OrgExtended.asettings as sets \nimport OrgExtended.orgutil.util as util\nimport uuid\nimport re\nimport logging\n\nfrom OrgExtended.orgutil.addmethod import *\n\nlog = logging.getLogger(__name__)\n\n\nclass ExclusivityLists:\n    def __init__(self):\n        self.lookup = {}\n\n    def Add(self, l):\n        for i in l:\n            self.lookup[i] = l\n\n    def Find(self,k):\n        if(k in self.lookup):\n            return self.lookup[k]\n        return None\n\nclass PListExclusiveLists:\n    def __init__(self):\n        self.keys = {}\n\n    def Add(self,k,ex):\n        self.keys[k] = ex\n\n    def Has(self,k):\n        return k in self.keys\n\n    def AddList(self,k,l):\n        rlist = None\n        if(k in self.keys):\n            rlist = self.keys[k]\n        else:\n            rlist = ExclusivityLists()\n            self.keys[k] = rlist\n        rlist.Add(l)\n\n    def AddBool(self,k):\n        self.AddList(k,['t','true','false','nil','on','yes','no','off'])\n\n    def Get(self,k):\n        if(k in self.keys):\n            return self.keys[k]\n        return None\n\n    def GetParam(self,k,p):\n        l = self.Get(k)\n        if(l):\n            return l.Find(p)\n\n\nRE_FN_MATCH = re.compile(r\"\\s+[:]([a-zA-Z][a-zA-Z0-9-_]*)\\s+(([a-zA-Z][a-zA-Z0-9]*\\s*[=]\\s*[\\\"][^\\\"]+[\\\"])|((([ ](?!:))|[^ ()\\\"])+)|([(][^)]+[)])|([\\\"][^\\\"]+[\\\"]))\")\nclass PList:\n\n\n    def __init__(self,plist):\n        self.params = plist\n        self.exList = PListExclusiveLists()\n\n    def AddExclusiveList(self,el):\n        self.exList = el\n\n    def Get(self, name, defaultValue):\n        if(name in self.params and self.params[name]):\n            v = self.params[name]\n            if(isinstance(v,str)):\n                v = v.strip()\n                if(v.startswith(\"\\\"\")):\n                    v = v[1:]\n                if(v.endswith(\"\\\"\")):\n                    v = v[:-1]\n            return v\n        return defaultValue\n\n    def FormatData(self,x):\n    \tif(x.startswith(\"\\\"\")):\n    \t\tx = x[1:]\n    \tif(x.endswith(\"\\\"\")):\n    \t\tx = x[:-1]\n    \treturn x\n\n    def GetStr(self,name,defaultValue):\n        v = self.Get(name,defaultValue)\n        if(isinstance(v,list)):\n            v = ' '.join(v)\n        return v\n\n    def GetInt(self,name,defaultValue):\n        v = self.Get(name,defaultValue)\n        try:\n            return int(v)\n        except:\n            return defaultValue\n\n    def GetBool(self,name):\n        v = self.Get(name,\"no\")\n        if(isinstance(v,list) and len(v) == 1):\n            v = v[0]\n        if(v and isinstance(v,str)):\n            v = v.lower()\n            if(v == 'yes' or v == 't' or v == 'true' or v == '1' or v == 'on'):\n                return True\n        return False\n\n    def GetFloat(self,name,defaultValue):\n        v = self.Get(name,defaultValue)\n        try:\n            return float(v)\n        except:\n            return defaultValue\n\n    def GetList(self,name,defaultValue):\n        v = self.Get(name,defaultValue)\n        if(not isinstance(v,list)):\n            return util.ToList(v) \n        return v\n\n    def GetIntList(self,name,defaultValue):\n        v = self.Get(name,defaultValue)\n        if(not isinstance(v,list)):\n            return util.ToIntList(v) \n        return v\n\n    def GetDict(self,name,defaultValue):\n        out = {}\n        v = self.Get(name,defaultValue)\n        if(isinstance(v,str)):\n            vs = v.split('=')\n            if(len(vs) == 2):\n                out[vs[0].strip()] = self.FormatData(vs[1].strip())\n                return out\n        if(isinstance(v,list)):\n            for i in v:\n                vs = i.split('=')\n                if(len(vs) == 2):\n                    out[vs[0].strip()] = self.FormatData(vs[1].strip())\n            if(len(out) > 0):\n                return out\n        return defaultValue\n\n    def Add(self,key,val):\n        PList.addToParam(self.params,key,val)\n\n    def Has(self,key):\n        return key in self.params\n    \n    def Replace(self,key,val):\n        self.params[key] = val\n\n    def AddFromPList(self,strData):\n        if(None == strData):\n            return\n        d = PList.plistParse(strData)\n        for k in d:\n            val = d[k]\n            if(isinstance(val,list)):\n                for vv in val:\n                    self.addToParam(self.params,k,vv,self.exList)\n            else:\n                self.addToParam(self.params,k,val,self.exList)\n\n    @staticmethod\n    def addToParam(params,key,val,exList=None):\n        if(isinstance(val,str)):\n            val = val.strip()\n            if(val.startswith(\"\\\"\")):\n                val = val[1:]\n            if(val.endswith(\"\\\"\")):\n                val = val[:-1]\n        if(key in params):\n            v = params[key]\n            # Promote to a list if its just a string.\n            if(isinstance(v,str)):\n                params[key] = []\n                params[key].append(v)\n            if(exList and exList.Has(key)):\n                if(not isinstance(val,list)):\n                    val = util.ToList(val)\n                for vv in val:\n                    eList = exList.GetParam(key,vv)\n                    # Remove exclusive items from the list.\n                    if(eList):\n                        params[key] = list(set(params[key]) - set(eList))\n                    params[key].append(vv)\n            else:\n                params[key].append(val)\n        else:\n            if(exList and exList.Has(key)):\n                if(not isinstance(val,list)):\n                    val = util.ToList(val)\n                for vv in val:\n                    eList = exList.GetParam(key,vv)\n                    # Remove exclusive items from the list.\n                    if(eList and key in params):\n                        params[key] = list(set(params[key]) - set(eList))\n                    elif(not key in params):\n                        params[key] = []\n                    params[key].append(vv)\n            else:\n                params[key] = val\n\n    @staticmethod\n    def plistParse(data):\n        if(isinstance(data,list)):\n            data = \" \".join(data)\n        paramstr = \" \" + data\n        params = {}\n        for m in RE_FN_MATCH.finditer(paramstr):\n            key = m.group(1)\n            val = m.group(2)\n            PList.addToParam(params,key,val)\n        return params\n\n    @staticmethod\n    def createPList(data=None):\n        if(data == None):\n            data = \"\"\n        params = PList.plistParse(data)\n        return PList(params)\n"
  },
  {
    "path": "orgproperties.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgparse.date as orgdate\nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orgduration as dur\nimport uuid\n#import yaml\n\nlog = logging.getLogger(__name__)\n\nRE_SDC = re.compile(r'^\\s*(SCHEDULED|DEADLINE|CLOSED):')\ndef InsertDrawerIfNotPresent(view, node, drawer = \":PROPERTIES:\", onDone=None):\n    if not node or node.is_root():\n        evt.EmitIf(onDone)\n        return False\n    if(drawer == \":PROPERTIES:\"):\n        if(node.property_drawer_location):\n            evt.EmitIf(onDone)\n            return False\n    else:\n        for d in node.drawers:\n            if((\":\" + d[\"name\"] + \":\") == drawer):\n                evt.EmitIf(onDone)\n                return False\n    level = node.level\n    indent = \" \" + (\" \" * level)\n    drawerRow = node.body_lines_start\n    # Properties should be the first drawer...\n    if(drawer != \":PROPERTIES:\" and node.property_drawer_location):\n        drawerRow = node.property_drawer_location[1] + 1\n    # Also skip over SCHEDULED, DEADLINE and CLOSED lines\n    for row in range(drawerRow, node.local_end_row + 1):\n        pt = view.text_point(row, 0)\n        line = view.line(pt)\n        txt = view.substr(line)\n        m = RE_SDC.search(txt)\n        if(not m):\n            drawerRow = row\n            break\n        else:\n            drawerRow = row + 1\n\n    drawerHere = view.text_point(drawerRow, 0)\n    newline = \"\\n\" if view.isBeyondLastRow(drawerRow) else \"\"\n    if(drawer == \":PROPERTIES:\"):\n        node.set_property_drawer_location((drawerRow,drawerRow+1))\n    view.run_command(\"org_internal_insert\", {\"location\": drawerHere, \"text\": newline + indent + drawer +\"\\n\" + indent + \":END:\\n\",\"onDone\":onDone})\n    return True\n\ndef AddProperty(view, node, key, value, onDone=None):\n    if(InsertDrawerIfNotPresent(view, node)):\n        # File is reloaded have to regrab node\n        node = db.Get().At(view, node.start_row)\n    end = node.property_drawer_location[1]\n    pt = view.text_point(end, 0)\n    level = node.level\n    indent = \"   \" + (\" \" * level)\n    view.run_command(\"org_internal_insert\", {\"location\": pt, \"text\": indent + \":\" + str(key) + \": \" + str(value) + \"\\n\", \"onDone\": onDone})\n    node.set_property_drawer_location((node.property_drawer_location[0],node.property_drawer_location[1] + 1))\n\n# KEY has to have : and everything.\ndef AddLogbook(view, node, key, value, onDone=None):\n    if(InsertDrawerIfNotPresent(view, node, \":LOGBOOK:\")):\n        # File is reloaded have to regrab node\n        node = db.Get().At(view, node.start_row)\n    drawer = node.get_drawer(\"LOGBOOK\")\n    loc = drawer['loc']\n    end = loc[1]\n    pt = view.text_point(end, 0)\n    level = node.level\n    indent = \"   \" + (\" \" * level)\n    drawer['loc'] = (loc[0], loc[1] + 1)\n    view.run_command(\"org_internal_insert\", {\"location\": pt, \"text\": indent + str(key) + \" \" + str(value) + \"\\n\", \"onDone\": onDone})\n\n\nRE_PROPERTY_EXTRACT = re.compile(r\"^\\s*:([a-zA-Z0-9_@-]+):\\s*(.*)\")\ndef GetProperty(view, node, key):\n    if(not node or not node.property_drawer_location):\n        return False\n    start = node.property_drawer_location[0]\n    end   = node.property_drawer_location[1]\n    lkey = key.lower()\n    v = None\n    mrow = None\n    # Work backwards, want to find the latest incarnation of this\n    for row in range(end-1, start, -1):\n        line = view.getLine(row)\n        m = RE_PROPERTY_EXTRACT.search(line)\n        if(m != None):\n            k = m.group(1).strip()\n            v = m.group(2).strip()\n            if(k.lower() == lkey):\n                mrow = row\n                break\n    return v\n\ndef UpdateProperty(view, node, key, value, onDone=None):\n    def OnDrawer():\n        # File is reloaded have to regrab node\n        n = db.Get().At(view, node.start_row)\n        if(not n):\n            log.error(\"Failed to look up property drawer! Something is wrong!\")\n        start, end = n.property_drawer_location\n        lkey = key.lower().strip()\n        mrow = None\n        # Work backwards, want to find the latest incarnation of this\n        for row in range(end-1, start, -1):\n            line = view.getLine(row)\n            m = RE_PROPERTY_EXTRACT.search(line)\n            if(m):\n                k = m.group(1).strip()\n                v = m.group(2).strip()\n                if(k.lower() == lkey):\n                    mrow = row\n                    break\n        # We found our property, replace it!\n        if(mrow != None):\n            pt = view.text_point(mrow, 0)\n            rw = view.line(pt)\n            text = \"  {0}:{1}: {2}\".format(n.indent(),key,value)\n            view.ReplaceRegion(rw,text,onDone)\n        # Otherwise add a new property\n        else:\n            AddProperty(view, n, key, value, onDone)\n    InsertDrawerIfNotPresent(view, node, \":PROPERTIES:\", evt.Make(OnDrawer))\n\n\ndef UpdateLogbook(view, node, key, value, onDone=None):\n    if(InsertDrawerIfNotPresent(view, node, \":LOGBOOK:\")):\n        # File is reloaded have to regrab node\n        node = db.Get().At(view, node.start_row)\n    if not node or node.is_root():\n        evt.EmitIf(onDone)\n        return\n    drawer = node.get_drawer(\"LOGBOOK\")\n    loc    = drawer['loc']\n    start  = loc[0]\n    end    = loc[1]\n    lkey   = key.lower()\n    mrow   = None\n    extract = re.compile(r'^\\s*' + key)\n    # Work backwards, want to find the latest incarnation of this\n    for row in range(end-1, start, -1):\n        line = view.getLine(row)\n        m = extract.search(line)\n        if(m != None):\n            mrow = row\n            break\n    level = node.level\n    indent = \"   \" + (\" \" * level)\n    # We found our property, replace it!\n    if(mrow != None):\n        pt = view.text_point(mrow, 0)\n        rw = view.line(pt)\n        view.run_command(\"org_internal_replace\", {\"start\": rw.begin(), \"end\": rw.end(), \"text\": indent + str(key) + \" \" + str(value), \"onDone\": onDone})\n    # Otherwise add a new property\n    else:\n        AddLogbook(view, node, key, value, onDone)\n\ndef RemoveProperty(view, node, key):\n    if(not node or not node.property_drawer_location):\n        return False\n    start = node.property_drawer_location[0]\n    end   = node.property_drawer_location[1]\n    lkey = key.lower()\n    mrow = None\n    # Work backwards, want to find the latest incarnation of this\n    for row in range(end-1, start, -1):\n        line = view.getLine(row)\n        m = RE_PROPERTY_EXTRACT.search(line)\n        if(m != None):\n            k = m.group(1).strip()\n            v = m.group(2).strip()\n            if(k.lower() == lkey):\n                mrow = row\n                break\n    # We found our property, erase it!\n    if(mrow != None):\n        pt = view.text_point(mrow, 0)\n        rw = view.line(pt)\n        view.run_command(\"org_internal_erase\", {\"start\": rw.begin(), \"end\": (rw.end()+1)})\n        node.set_property_drawer_location((node.property_drawer_location[0],node.property_drawer_location[1] - 1))\n        return True\n    return False\n\ndef RemoveLogbook(view, node, key):\n    if(not node):\n        return False\n    drawer = node.get_drawer(\"LOGBOOK\")\n    if(not drawer):\n        return False\n    loc    = drawer['loc']\n    start  = loc[0]\n    end    = loc[1]\n    lkey   = key.lower()\n    mrow   = None\n    # Work backwards, want to find the latest incarnation of this\n    for row in range(end-1, start, -1):\n        line = view.getLine(row)\n        m = re.search(key,line)\n        if(m != None):\n            mrow = row\n            break\n    # We found our property, erase it!\n    if(mrow != None):\n        pt = view.text_point(mrow, 0)\n        rw = view.line(pt)\n        view.run_command(\"org_internal_erase\", {\"start\": rw.begin(), \"end\": (rw.end()+1)})\n        drawer['loc'] = (start,end-1)\n        return True\n    return False\n\ndef GetLogbook(view, node, key):\n    if(not node):\n        return False\n    drawer = node.get_drawer(\"LOGBOOK\")\n    if not drawer:\n        return False\n    loc    = drawer['loc']\n    start  = loc[0]\n    end    = loc[1]\n    lkey   = key.lower()\n    mrow   = None\n    v = False\n    # Work backwards, want to find the latest incarnation of this\n    for row in range(end-1, start, -1):\n        line = view.getLine(row)\n        m = re.search(key,line)\n        if(m != None):\n            mrow = row\n            break\n    if(mrow != None):\n        pt = view.text_point(mrow, 0)\n        rw = view.line(pt)\n        #view.run_command(\"org_internal_erase\", {\"start\": rw.begin(), \"end\": (rw.end()+1)})\n        #drawer['loc'] = (start,end-1)\n        v = re.sub(key,\"\",line).strip()\n    return v\n\n# Removes all instances of a named property from the drawer.\ndef RemoveAllInstances(view, node, key):\n    while(RemoveProperty(view, node, key)):\n        pass\n\n# Removes all instances of a named logbook entry from the drawer.\ndef RemoveAllLogbookInstances(view, node, key):\n    while(RemoveLogbook(view, node, key)):\n        pass\n\n# Insert a new drawer into the node.\nclass OrgInsertDrawerCommand(sublime_plugin.TextCommand):\n    def run(self,edit):\n        self.view.window().show_input_panel(\n                    \"Drawer Name:\",\n                    \"\",\n                    self.createDrawer, None, None)\n\n    def createDrawer(self, drawer):\n        if(not drawer):\n            return\n        node = db.Get().AtInView(self.view)\n        if(node and node.level > 0):\n            InsertDrawerIfNotPresent(self.view, node, \":\" + drawer + \":\")\n\nclass OrgInsertPropertyDrawerCommand(sublime_plugin.TextCommand):\n    def run(self,edit):\n        node = db.Get().AtInView(self.view)\n        if(node and node.level > 0):\n            InsertDrawerIfNotPresent(self.view, node, \":PROPERTIES:\")\n\nclass OrgInsertPropertyCommand(sublime_plugin.TextCommand):\n    def run(self,edit,onDone=None,name=None,value=None):\n        self.onDone=onDone\n        if name != None:\n            self.pname = name\n            if value != None:\n                self.prop = value\n                self.createPropertyV2(self.prop)\n            else:\n                self.createProperty(name)\n        else:\n            self.view.window().show_input_panel(\n                        \"Property Name:\",\n                        \"\",\n                        self.createProperty, None, None)\n\n    def createProperty(self, prop):\n        if(not prop):\n            return\n        self.pname = prop\n        self.view.window().show_input_panel(\n                    \"Property Value:\",\n                    \"\",\n                    self.createPropertyV2, None, None)\n\n    def createPropertyV2(self, prop):\n        if(not prop):\n            return\n        node = db.Get().AtInView(self.view)\n        if(node and node.level > 0):\n            UpdateProperty(self.view, node, self.pname, prop, self.onDone)\n\nclass OrgInsertCreatedPropertyCommand(sublime_plugin.TextCommand):\n    def run(self,edit,onDone=None):\n        self.onDone=onDone\n        now = datetime.datetime.now()\n        toInsert = orgdate.OrgDate.format_clock(now, False)\n        self.view.run_command(\"org_insert_property\", {\"name\": \"Created\",\"value\": toInsert, \"onDone\":onDone})\n\n\nclass OrgInsertEffortCommand(sublime_plugin.TextCommand):\n    def run(self,edit,onDone=None):\n        self.onDone=onDone\n        node = db.Get().AtInView(self.view)\n        if(node and node.level > 0):\n            v = GetProperty(self.view, node, \"EFFORT\")\n            if(not v):\n                v = \"\"\n            self.view.window().show_input_panel(\n                    \"Effort:\",\n                    v,\n                    self.createProperty, None, None)\n\n    def createProperty(self, prop):\n        if(not prop):\n            return\n        isint = False\n        try:\n            i = int(prop)\n            isint = True\n        except:\n            pass\n        if(isint):\n            inc = sets.Get(\"defaultEffortEstimateUnit\",\"d\")\n            prop = prop + inc\n        d = dur.OrgDuration.Parse(prop)\n        if(d):\n            node = db.Get().AtInView(self.view)\n            if(node and node.level > 0):\n                UpdateProperty(self.view, node, \"Effort\", str(d), self.onDone)\n        else:\n            log.error(\"Could not generate effort, please use org duration formation for your estimate\")\n            view.set_status(\"Error: \", prop + \"is not a valid effort, please use org duration formation 1y 1d 1h 1min\")\n            evt.EmitIf(self.onDone)\n\nclass OrgCreateHeadingIdCommand(sublime_plugin.TextCommand):\n    def run(self,edit,onDone=None):\n        self.onDone=onDone\n        node = db.Get().AtInView(self.view)\n        if(node and node.level > 0):\n            v = GetProperty(self.view, node, \"ID\")\n            if(not v):\n                value = uuid.uuid4()\n                UpdateProperty(self.view, node, \"ID\", str(value), self.onDone)\n"
  },
  {
    "path": "orgreadtheorg.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcapture as capture\nimport OrgExtended.orgproperties as props\nimport yaml\nimport sys\nimport subprocess\nimport html\n\nlog = logging.getLogger(__name__)\n\n\n\ndef ReadTheOrgFilename(view):\n\tfn = view.file_name()\n\tfn,ext = os.path.splitext(fn)\n\treturn fn + \".html\"\n\n# Global properties I AT LEAST want to support.\n# Both as a property on the document and in our settings.\n#+OPTIONS: num:nil toc:nil\n#+REVEAL_TRANS: None/Fade/Slide/Convex/Concave/Zoom\n#+REVEAL_THEME: Black/White/League/Sky/Beige/Simple/Serif/Blood/Night/Moon/Solarized\n#+Title: Title of Your Talk\n#+Author: Your Name\n#+Email: Your Email Address or Twitter Handle\n\ndef GetGlobalOption(file, name, settingsName, defaultValue):\n\tvalue = sets.Get(settingsName, defaultValue)\n\tvalue = ' '.join(file.org[0].get_comment(name, [str(value)]))\n\treturn value\n\n\npropMappings = {\n\t\"reveal_background\":              \"data-background-image\",\n\t\"reveal_background_image\":        \"data-background-image\",\n\t\"reveal_background_size\":         \"data-background-size\",\n\t\"reveal_background_trans\":        \"data-background-transition\",\n\t\"reveal_trans\":                   \"data-transition\",\n\t\"reveal_trans_speed\":             \"data-transition-speed\",\n\t\"reveal_background_position\":     \"data-background-position\",\n\t\"reveal_background_repeat\":       \"data-background-repeat\",\n\t\"reveal_background_opacity\":      \"data-background-opacity\",\n\t\"reveal_background_color\":        \"data-background-color\",\n\t\"reveal_background_video\":        \"data-background-video\",\n\t\"reveal_background_video_loop\":   \"data-background-video-loop\",\n\t\"reveal_background_video_muted\":  \"data-background-video-muted\"\n}\n\nRE_SCHEDULING_LINE = re.compile(r\"^\\s*(SCHEDULED|CLOSED|DEADLINE)[:].*\")\nRE_DRAWER_LINE = re.compile(r\"^\\s*[:].+[:]\\s*$\")\nRE_END_DRAWER_LINE = re.compile(r\"^\\s*[:](END|end)[:]\\s*$\")\nRE_LINK = re.compile(r\"\\[\\[(?P<link>[^\\]]+)\\](\\[(?P<desc>[^\\]]+)\\])?\\]\")\nRE_UL   = re.compile(r\"^\\s*(-|[+])\\s+(?P<data>.+)\")\nRE_BOLD = re.compile(r\"\\*(?P<data>.+)\\*\")\nRE_ITALICS = re.compile(r\"/(?P<data>.+)/\")\nRE_UNDERLINE = re.compile(r\"_(?P<data>.+)_\")\nRE_STRIKETHROUGH = re.compile(r\"\\+(?P<data>.+)\\+\")\nRE_CODE = re.compile(r\"~(?P<data>.+)~\")\nRE_VERBATIM = re.compile(r\"=(?P<data>.+)=\")\nRE_STARTQUOTE = re.compile(r\"#\\+(BEGIN_QUOTE|BEGIN_EXAMPLE|BEGIN_VERSE|BEGIN_CENTER|begin_quote|begin_example|begin_verse|begin_center)\")\nRE_ENDQUOTE = re.compile(r\"#\\+(END_QUOTE|END_EXAMPLE|END_VERSE|END_CENTER|end_quote|end_example|end_verse|end_center)\")\nRE_STARTNOTE = re.compile(r\"#\\+(BEGIN_NOTES|begin_notes)\")\nRE_ENDNOTE = re.compile(r\"#\\+(END_NOTES|end_notes)\")\nRE_FN_MATCH = re.compile(r\"\\s*[:]([a-zA-Z0-9-_]+)\\s+([^: ]+)?\\s*\")\nRE_STARTSRC = re.compile(r\"^\\s*#\\+(BEGIN_SRC|begin_src)\\s+(?P<lang>[a-zA-Z0-9]+)\")\nRE_ENDSRC = re.compile(r\"^\\s*#\\+(END_SRC|end_src)\")\nRE_RESULTS = re.compile(r\"^\\s*#\\+RESULTS.*\")\n\n\n# <!-- multiple_stores height=\"50%\" width=\"50%\" --> \nRE_COMMENT_TAG = re.compile(r\"^\\s*[<][!][-][-]\\s+(?P<name>[a-zA-Z0-9_-]+)\\s+(?P<props>.*)\\s+[-][-][>]\")\n\n\ndef mapLanguage(lang):\n\tif(lang == 'html'):\n\t\treturn 'language-html'\n\telif(lang == 'python'):\n\t\treturn 'language-python'\n\telse:\n\t\treturn lang\n\n\n\nclass RevealDoc:\n\tdef __init__(self, filename):\n\t\tself.fs = open(filename,\"w\")\n\t\tself.fs.write(\"<!doctype html>\\n\")\n\t\tself.fs.write(\"<html lang=\\\"en\\\" class>\\n\")\n\t\tself.commentName = None\n\n\tdef AddJs(self,link):\n\t\tself.fs.write(\"    <script type=\\\"text/javascript\\\" src=\\\"\" + link + \"\\\"></script>\\n\")\n\n\tdef AddStyle(self,link):\n\t\tself.fs.write(\"    <link rel=\\\"stylesheet\\\" href=\\\"\"+link+\"\\\">\\n\")\n\n\tdef StartHead(self):\n\t\tself.fs.write(\"  <head>\\n\")\n\n\tdef EndHead(self):\n\t\tself.fs.write(\"  </head>\\n\")\n\n\tdef StartPres(self, file):\n\t\t# This doesn't work have to do it as a parameter!\n\t\ttransition      = GetGlobalOption(file,\"REVEAL_TRANS\",\"RevealTransition\",\"none\").lower()\n\t\ttransitionSpeed = GetGlobalOption(file,\"REVEAL_TRANS_SPEED\",\"RevealTransitionSpeed\",\"default\").lower()\n\t\tself.fs.write(\"  <div class=\\\"reveal slide center has-vertical-slides has-horizontal-slides ready\\\" role=\\\"application\\\" data-transition-speed=\\\"{tspeed}\\\" data-background-transition=\\\"{transition}\\\">\\n\".format(\n\t\t\ttransition=transition,\n\t\t\ttspeed=transitionSpeed))\n\n\tdef EndPres(self):\n\t\tself.fs.write(\"  </div>\\n\")\n\n\tdef StartSlides(self):\n\t\tself.fs.write(\"    <div class=\\\"slides\\\">\\n\")\n\n\tdef EndSlides(self):\n\t\tself.fs.write(\"    </div>\\n\")\n\n\t# Per slide properties\n\t#:PROPERTIES:\n\t#:reveal_background: images/name-of-image\n\t#:reveal_background_size: width-of-image\n\t#:reveal_background_trans: slide\n\t#:END:\n\tdef StartSlide(self,slide):\n\t\t# data-background-trans:        slide\n\t\t# data-background-image \t\tURL of the image to show. GIFs restart when the slide opens.\n\t\t# data-background-size \t        cover \tSee background-size on MDN.\n\t\t# data-background-position \t    center \tSee background-position on MDN.\n\t\t# data-background-repeat \t    no-repeat \tSee background-repeat on MDN.\n\t\t# data-background-opacity\n\t\t# data-background-color\t\n\t\t# data-background-video \t\tA single video source, or a comma separated list of video sources.\n\t\t# data-background-video-loop \tfalse \tFlags if the video should play repeatedly.\n\t\t# data-background-video-muted \tfalse \tFlags if the audio should be muted.\n\t\tproperties = \"\"\n\t\tfor prop in slide.properties:\n\t\t\tif prop in propMappings:\n\t\t\t\tproperties = \"{0} {1}=\\\"{2}\\\"\".format(properties,propMappings[prop],slide.properties[prop])\n\n\t\tself.fs.write(\"      <section {0}>\\n\".format(properties))\n\n\tdef EndSlide(self):\n\t\tself.fs.write(\"      </section>\\n\")\n\n\tdef SlideHeading(self,slide):\n\t\theading = html.escape(slide.heading)\n\t\tlevel = slide.level + 1\n\t\tself.fs.write(\"      <h{level}>{heading}</h{level}>\\n\".format(level=level,heading=heading))\n\n\n\tdef EscAndLinks(self, l):\n\t\tline = html.escape(l)\n\t\tm = RE_LINK.search(line)\n\t\tif(m):\n\t\t\tlink = m.group('link').strip()\n\t\t\tdesc = m.group('desc')\n\t\t\tif(not desc):\n\t\t\t\tdesc = link\n\t\t\telse:\n\t\t\t\tdesc = desc.strip()\n\t\t\tif(link.endswith(\".png\") or link.endswith(\".jpg\") or link.endswith(\".gif\")):\n\t\t\t\tif(link.startswith(\"file:\")):\n\t\t\t\t\tlink = re.sub(r'^file:','',link)\t\n\t\t\t\textradata = \"\"\t\n\t\t\t\tif(self.commentName and self.commentName in link):\n\t\t\t\t\textradata =  \" \" + self.commentData\n\t\t\t\t\tself.commentName = None\n\t\t\t\tline = RE_LINK.sub(\"<img src=\\\"{link}\\\" alt=\\\"{desc}\\\"{extradata}>\".format(link=link,desc=desc,extradata=extradata),line)\n\t\t\telse:\n\t\t\t\tline = RE_LINK.sub(\"<a href=\\\"{link}\\\">{desc}</a>\".format(link=link,desc=desc),line)\n\t\telse:\n\t\t\tline = RE_BOLD.sub(r\"<b>\\1</b>\",line)\n\t\t\tline = RE_ITALICS.sub(r\"<i>\\1</i>\",line)\n\t\t\tline = RE_UNDERLINE.sub(r\"<u>\\1</u>\",line)\n\t\t\tline = RE_STRIKETHROUGH.sub(r\"<strike>\\1</strike>\",line)\n\t\t\tline = RE_VERBATIM.sub(r\"<pre>\\1</pre>\",line)\n\t\t\tline = RE_CODE.sub(r\"<code>\\1</code>\",line)\n\t\t\tline = RE_STARTQUOTE.sub(r\"<blockquote>\",line)\n\t\t\tline = RE_ENDQUOTE.sub(r\"</blockquote>\",line)\n\t\t\tline = RE_STARTNOTE.sub(r'<aside class=\"notes\">',line)\n\t\t\tline = RE_ENDNOTE.sub(r\"</aside>\",line)\n\t\treturn line\n\n\tdef SlideBody(self,slide):\n\t\tinDrawer = False\n\t\tinUl     = False\n\t\tinSrc    = False\n\t\tskipSrc  = False\n\t\tfor l in slide._lines[1:]:\n\t\t\tif(inDrawer):\n\t\t\t\tif(RE_END_DRAWER_LINE.search(l)):\n\t\t\t\t\tinDrawer = False\n\t\t\t\tcontinue\n\t\t\tif(inSrc):\n\t\t\t\tif(RE_ENDSRC.search(l)):\n\t\t\t\t\tinSrc = False\n\t\t\t\t\tif(skipSrc):\n\t\t\t\t\t\tskipSrc = False\n\t\t\t\t\t\tcontinue\n\t\t\t\t\tself.fs.write(\"    </code></pre>\\n\")\n\t\t\t\t\tcontinue\n\t\t\t\telse:\n\t\t\t\t\tif(not skipSrc):\n\t\t\t\t\t\tself.fs.write(\"     \" + l + \"\\n\")\n\t\t\t\t\tcontinue\n\t\t\tm = RE_STARTSRC.search(l)\n\t\t\tif(m):\n\t\t\t\tinSrc = True\n\t\t\t\tif(m.group('lang') == 'plantuml'):\n\t\t\t\t\tskipSrc = True\n\t\t\t\t\tcontinue\n\t\t\t\tparamstr = l[len(m.group(0)):]\n\t\t\t\tparams = {}\n\t\t\t\tfor ps in RE_FN_MATCH.finditer(paramstr):\n\t\t\t\t\tparams[ps.group(1)] = ps.group(2)\n\t\t\t\tattribs = \"\"\n\t\t\t\tif(\"data-noescape\" in params):\n\t\t\t\t\tattribs += \" data-noescape\"\n\t\t\t\tif(\"data-trim\" in params):\n\t\t\t\t\tattribs += \" data-trim\"\n\t\t\t\tif(\"data-line-numbers\" in params):\n\t\t\t\t\tattribs += \" data-line-numbers=\\\"{nums}\\\"\".format(nums=params[\"data-line-numbers\"])\n\t\t\t\tself.fs.write(\"    <pre><code language=\\\"{language}\\\" {attribs}>\\n\".format(language=mapLanguage(m.group('lang')),attribs=attribs))\n\t\t\t\tcontinue\n\t\t\tif(RE_DRAWER_LINE.search(l)):\n\t\t\t\tinDrawer = True\n\t\t\t\tcontinue\n\t\t\tif(RE_SCHEDULING_LINE.search(l)):\n\t\t\t\tcontinue\n\t\t\tif(RE_RESULTS.search(l)):\n\t\t\t\tcontinue\n\t\t\tm = RE_COMMENT_TAG.search(l)\n\t\t\tif(m):\n\t\t\t\tself.commentData = m.group('props')\n\t\t\t\tself.commentName = m.group('name')\n\t\t\t\tcontinue\n\t\t\tm = RE_UL.search(l)\n\t\t\tif(m):\n\t\t\t\tif(not inUl):\n\t\t\t\t\tself.fs.write(\"     <ul>\\n\")\n\t\t\t\t\tinUl = True\n\t\t\t\tdata = self.EscAndLinks(m.group('data'))\n\t\t\t\tself.fs.write(\"     <li>{content}</li>\\n\".format(content=data))\n\t\t\t\tcontinue\n\t\t\telif(inUl):\n\t\t\t\tinUl = False\n\t\t\t\tself.fs.write(\"     </ul>\\n\")\n\t\t\tline = self.EscAndLinks(l)\n\t\t\tself.fs.write(\"     \" + line + \"\\n\")\n\t\tif(inUl):\n\t\t\tinUl = False\n\t\t\tself.fs.write(\"     </ul>\\n\")\n\n\t\tpass\n\n\tdef StartBody(self):\n\t\tself.fs.write(\"  <body style=\\\"transition: -webkit-transform 0.8s ease 0s; transform-origin: 0px 0px;\\\">\\n\")\n\n\tdef EndBody(self):\n\t\tself.fs.write(\"  </body>\\n\")\n\n\tdef Progress(self):\n\t\tself.fs.write(\"  <div class=\\\"progress\\\" style=\\\"display: block;\\\">\\n\")\n\t\tself.fs.write(\"    <span style=\\\"width: 265px;\\\"></span>\\n\")\n\t\tself.fs.write(\"    ::after\\n\")\n\t\tself.fs.write(\"  </div>\")\n\n\tdef Dep(self, file, link, last=False):\n\t\tlocation = \"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/\"\n\t\tlocation = GetGlobalOption(file,\"REVEAL_LOCATION\",\"RevealLocation\",location)\t\n\t\tlocation = location + \"plugin/\"\n\t\tcomma =\",\"\n\t\tif(last):\n\t\t\tcomma = \"\"\n\t\tself.fs.write(\"              { src: '\"+location+link+\"', async: true }\"+comma+\"\\n\") \n\n\tdef RevealScript(self,file):\n\t\tlocation = \"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/\"\n\t\tlocation = GetGlobalOption(file,\"REVEAL_LOCATION\",\"RevealLocation\",location)\t\n\t\tself.fs.write(\"  <script src=\\\"{location}js/reveal.js\\\"></script>\\n\".format(location=location))\n\t\tself.fs.write(\"  <script>\\n\")\n\t\t#self.fs.write(\"       Reveal.initialize();\\n\")\n\t\tself.fs.write(\"      Reveal.initialize({\\n\")\n\t\tself.fs.write(\"          hash: true,\\n\") # Allow browsing back to this slide.\n\t\ttransition      = GetGlobalOption(file,\"REVEAL_TRANS\",\"RevealTransition\",\"none\").lower()\n\t\ttransitionSpeed = GetGlobalOption(file,\"REVEAL_TRANS_SPEED\",\"RevealTransitionSpeed\",\"default\").lower()\n\t\t# Transition style\n\t\tself.fs.write(\"          transition: '{transition}',\\n\".format(transition=transition)) # none/fade/slide/convex/concave/zoom\n\t\tself.fs.write(\"          transitionSpeed: '{transitionSpeed}',\\n\".format(transitionSpeed=transitionSpeed)) # default/fast/slow\n\t\t#self.fs.write(\"          showNotes: false,\\n\")\n\t\tself.fs.write(\"          dependencies: [\\n\") \n\t\tself.Dep(file, \"markdown/marked.js\")\n\t\tself.Dep(file, \"markdown/markdown.js\")\n\t\tself.Dep(file, \"highlight/highlight.js\")\n\t\tself.Dep(file, \"search/search.js\")\n\t\tself.Dep(file, \"zoom-js/zoom.js\")\n\t\tself.Dep(file, \"notes/notes.js\")\n\t\t#self.Dep(\"print-pdf/print-pdf.min.js\")\n\t\tself.Dep(file, \"math/math.js\",True)\n\t\tself.fs.write(\"          ]\\n\") \n\t\tself.fs.write(\"      });\\n\")\n\t\tself.fs.write(\"  </script>\\n\")\n\n\n\tdef Close(self):\n\t\tself.fs.write(\"</html>\\n\")\n\t\tself.fs.close()\n\n\n# Export the entire file using pandoc \nclass OrgExportFileReadTheOrgCommand(sublime_plugin.TextCommand):\n\n\tdef build_head(self, doc):\n\t\t# TODO: Make these configurable about where to pull reveal from.\n\t\t#doc.AddJs(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/plugin/markdown/markdown.min.js\")\n\t\t#doc.AddJs(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/plugin/highlight/highlight.min.js\")\n\t\t#doc.AddJs(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/plugin/search/search.min.js\")\n\t\t#doc.AddJs(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/plugin/zoom-js/zoom.min.js\")\n\t\t#doc.AddJs(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/plugin/notes/notes.min.js\")\n\t\t#doc.AddJs(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/plugin/print-pdf/print-pdf.min.js\")\n\t\t#doc.AddJs(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/plugin/math/math.min.js\")\n\t\t#doc.AddJs(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/lib/js/head.min.js\")\n\t\t#doc.AddJs(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/js/reveal.min.js\")\n\n\t\t# TODO: Make these configurable about where to pull reveal from.\n\t\t#doc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/css/print/pdf.min.css\")\n\t\tdoc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/css/reveal.min.css\")\n\t\tdoc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/css/reset.min.css\")\n\n\n\n\t\t# black: Black background, white text, blue links (default theme)\n\t\t# white: White background, black text, blue links\n\t\t# league: Gray background, white text, blue links (default theme for reveal.js < 3.0.0)\n\t\t# beige: Beige background, dark text, brown links\n\t\t# sky: Blue background, thin dark text, blue links\n\t\t# night: Black background, thick white text, orange links\n\t\t# serif: Cappuccino background, gray text, brown links\n\t\t# simple: White background, black text, blue links\n\t\t# solarized: Cream-colored background, dark green text, blue links\n\t\t# moon: Dark green background.\n\t\ttheme      = GetGlobalOption(self.file,\"REVEAL_THEME\",\"RevealTheme\",\"league\").lower()\n\t\t# TODO: Validate the theme here.\n\t\tdoc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/css/theme/{theme}.min.css\".format(theme=theme))\n\t\tdoc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/css/print/paper.min.css\")\n\n\n\t\thighlight      = GetGlobalOption(self.file,\"REVEAL_HIGHLIGHT\",\"RevealHighlight\",\"zenburn\").lower()\n\t\t#doc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/lib/css/monokai.min.css\")\n\t\t#doc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/lib/css/zenburn.min.css\")\n\t\tdoc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/lib/css/{hl}.min.css\".format(hl=highlight))\n\t\t#doc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/lib/font/league-gothic/league-gothic.min.css\")\n\t\t#doc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/lib/font/source-sans-pro/source-sans-pro.min.css\")\n\t\tself.vlevel = int(GetGlobalOption(self.file,\"REVEAL_VLEVEL\",\"RevealVLevel\",1))\n\n\tdef build_slide(self, doc, slide):\n\t\tif(slide.num_children > 0 and self.vlevel == slide.level):\n\t\t\tdoc.StartSlide(slide)\n\t\tdoc.StartSlide(slide)\n\t\tdoc.SlideHeading(slide)\n\t\tdoc.SlideBody(slide)\n\t\tdoc.EndSlide()\n\t\tfor c in slide.children:\n\t\t\tself.build_slide(doc, c)\n\t\tif(slide.num_children > 0 and self.vlevel == slide.level):\n\t\t\tdoc.EndSlide()\n\n\tdef build_slides(self, doc):\n\t\tnodes = self.file.org\n\t\tfor slide in nodes.children:\n\t\t\tself.build_slide(doc, slide)\n\n\tdef build_pres(self, doc):\n\t\tdoc.StartSlides()\n\t\tself.build_slides(doc)\n\t\tdoc.EndSlides()\n\n\tdef build_body(self, doc):\n\t\tdoc.StartPres(self.file)\n\t\tself.build_pres(doc)\n\t\tdoc.EndPres()\n\t\tdoc.RevealScript(self.file)\n\n\tdef run(self,edit):\n\t\tself.file = db.Get().FindInfo(self.view)\n\t\tif(None == self.file):\n\t\t\tlog.debug(\"Not an org file? Cannot build reveal document\")\n\t\t\treturn\n\t\tdoc = None\n\t\ttry:\n\t\t\tdoc = RevealDoc(RevealFilename(self.view))\n\t\t\tdoc.StartHead()\n\t\t\tself.build_head(doc)\n\t\t\tdoc.EndHead()\n\n\t\t\tdoc.StartBody()\n\t\t\tself.build_body(doc)\n\t\t\tdoc.EndBody()\n\t\tfinally:\t\n\t\t\tif(None != doc):\n\t\t\t\tdoc.Close()\n\n# pandoc -s -o output.html input.txt\n"
  },
  {
    "path": "orgresolver/__init__.py",
    "content": ""
  },
  {
    "path": "orgresolver/abstract.py",
    "content": "# -*- coding: utf-8 -*-\nimport os\nimport sys\nimport subprocess\nimport sublime\n\n\nDEFAULT_OPEN_LINK_COMMANDS = dict(\n    # Standard universal can opener for OSX.\n    darwin=['open'],\n    win32=['cmd', '/C', 'start'],\n    linux=['xdg-open'],\n)\n\n\nclass AbstractLinkResolver(object):\n\n    def __init__(self, view):\n        self.view = view\n        self.settings      = sublime.load_settings('OrgExtended.sublime-settings')\n        self.link_commands = self.settings.get('resolver.abstract.commands', DEFAULT_OPEN_LINK_COMMANDS)\n\n    def extract(self, content):\n        return content\n\n    def replace(self, content):\n        return content\n\n    def resolve(self, content):\n        match = self.extract(content)\n        if not match:\n            return None\n        return self.replace(match)\n\n    def get_link_command(self):\n        platform = sys.platform\n        for key, val in self.link_commands.items():\n            if key in platform:\n                return val\n        return None\n\n    def execute(self, content):\n\n        if os.path.isfile(content) or os.path.isdir(content):\n            content = os.path.normpath(content)\n        else:\n            print('{} does not exist!'.format(content))\n\n        command = self.get_link_command()\n        if not command:\n            sublime.error_message(\n                'Could not get link opener command.\\nPlatform not yet supported.')\n            return None\n\n        if sys.version_info[0] < 3:\n            content = content.encode(sys.getfilesystemencoding())\n\n        cmd = command + [content]\n        arg_list_wrapper = self.settings.get(\n            \"resolver.abstract.arg_list_wrapper\", [])\n        if arg_list_wrapper:\n            cmd = arg_list_wrapper + [' '.join(cmd)]\n            source_filename = '\\\"' + self.view.file_name() + '\\\"'\n            cmd += [source_filename]\n            if sys.platform != 'win32':\n                cmd += ['--origin', source_filename, '--quiet']\n\n        print('*****')\n        print(repr(content), content)\n        print(cmd)\n        sublime.status_message('Executing: %s' % cmd)\n\n        if sys.platform != 'win32':\n            process = subprocess.Popen(\n                cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n            stdout, stderr = process.communicate()\n            if stdout:\n                stdout = str(stdout, sys.getfilesystemencoding())\n                sublime.status_message(stdout)\n            if stderr:\n                stderr = str(stderr, sys.getfilesystemencoding())\n                sublime.error_message(stderr)\n        else:     \n            os.startfile(content)\n\n\nclass AbstractRegexLinkResolver(AbstractLinkResolver):\n\n    def __init__(self, view):\n        self.view = view\n        self.settings      = sublime.load_settings('OrgExtended.sublime-settings')\n        self.link_commands = self.settings.get('resolver.abstract.commands', DEFAULT_OPEN_LINK_COMMANDS)\n        self.regex         = None\n\n    def extract(self, content):\n        if self.regex is None:\n            return content\n        match = self.regex.match(content)\n        return match\n\n    def replace(self, match):\n        return match.groups()[1]\n"
  },
  {
    "path": "orgresolver/email.py",
    "content": "\nimport re\nfrom .abstract import AbstractRegexLinkResolver\n\n\nPATTERN_SETTING = 'resolver.email.pattern'\nPATTERN_DEFAULT = r'^(?P<type>email|mailto):(?P<email>[^/]+)(/(?P<subject>.+))?$'\nURL_SETTING = 'resolver.email.url'\nURL_DEFAULT = 'mailto:%s'\n\n\nclass Resolver(AbstractRegexLinkResolver):\n\n    def __init__(self, view):\n        super(Resolver, self).__init__(view)\n        get = self.settings.get\n        pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)\n        self.regex = re.compile(pattern)\n        self.url = get(URL_SETTING, URL_DEFAULT)\n\n    def replace(self, match):\n        match = match.groupdict()\n        if match['type'] == 'mailto':\n            url = self.url % match['email']\n            if match['subject']:\n                url += '?subject=%s' % match['subject']\n            return url\n        if match['type'] == 'email':\n            return dict(email=match['email'], path=match['subject'])\n\n    def execute(self, content):\n        if isinstance(content, dict) and 'email' in content:\n            import sublime\n            # TODO Implement email opener here.\n            sublime.error_message('Email opener not implemented yet.')\n            raise NotImplemented()\n        else:\n            return super(Resolver, self).execute(content)\n"
  },
  {
    "path": "orgresolver/file.py",
    "content": "\nimport re\nimport os\nfrom fnmatch import fnmatch\nimport sublime\nfrom .abstract import AbstractLinkResolver\nimport OrgExtended.orgdb as db\nfrom OrgExtended.orgutil.util import *\n\nPATTERN_SETTING = 'resolver.local_file.pattern'\nPATTERN_DEFAULT = r'^(file:)?(?P<filepath>.+?)(((::(?P<row>\\d+))(::(?P<col>\\d+))?)|(::\\#(?P<cid>[a-zA-Z0-9!$@%&_-]+))|(::\\*(?P<heading>[a-zA-Z0-9!$@%&_-]+))|(::(?P<textmatch>[a-zA-Z0-9!$@%&_-]+)))?\\s*$'\n\nFORCE_LOAD_SETTING = 'resolver.local_file.force_into_sublime'\nFORCE_LOAD_DEFAULT = ['*.txt', '*.org', '*.py', '*.rb',\n                      '*.html', '*.css', '*.js', '*.php', '*.c', \n                      '*.cpp', '*.h', '*.png', '*.jpg', '*.gif', '*.cs']\n\n\nclass Resolver(AbstractLinkResolver):\n    def tryMatchHeading(self, filepath, heading):\n        fpath = self.view.RelativeTo(filepath).lower()\n        fi = db.Get().FindInfo(fpath)\n        row = None\n        col = None\n        if(fi):\n            for n in fi.org:\n                if not n.is_root() and n.heading == heading:\n                    row = n.start_row + 1\n                    col = 0\n                    if row:\n                        filepath += ':%s' % row\n                    if col:\n                        filepath += ':%s' % col\n                    self.view.window().open_file(filepath, sublime.ENCODED_POSITION)\n                    return True\n        return None\n\n    def tryMatchDirectTarget(self, filepath, val):\n        fpath = self.view.RelativeTo(filepath).lower()\n        fi = db.Get().FindInfo(fpath)\n        if(fi):\n            if(fi.org.targets):\n                if(val in fi.org.targets):\n                    tgt = fi.org.targets[val]\n                    row = tgt['row'] + 1\n                    col = tgt['col']\n                    if row:\n                        filepath += ':{0}'.format(row)\n                    if col:\n                        filepath += ':{0}'.format(col)\n                    self.view.window().open_file(filepath, sublime.ENCODED_POSITION)\n                    return True\n        return None\n\n    def tryMatchNamedObject(self, filepath, val):\n        fpath = self.view.RelativeTo(filepath).lower()\n        fi = db.Get().FindInfo(fpath)\n        if(fi):\n            if(fi.org.names):\n                if(val in fi.org.names):\n                    tgt = fi.org.names[val]\n                    row = tgt['row'] + 1\n                    col = 0\n                    if row:\n                        filepath += ':{0}'.format(row)\n                    if col:\n                        filepath += ':{0}'.format(col)\n                    self.view.window().open_file(filepath, sublime.ENCODED_POSITION)\n                    return True\n        return None\n\n    def __init__(self, view):\n        super(Resolver, self).__init__(view)\n        self.view = view\n        get = self.settings.get\n        pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)\n        self.regex = re.compile(pattern)\n        self.force_load_patterns = get(FORCE_LOAD_SETTING, FORCE_LOAD_DEFAULT)\n\n    def file_is_excluded(self, filepath):\n        self.settings      = sublime.load_settings('OrgExtended.sublime-settings')\n        basename = os.path.basename(filepath)\n        if(isinstance(self.force_load_patterns,str)):\n            self.force_load_patterns = self.force_load_patterns.split(',')\n        for flpattern in self.force_load_patterns:\n            if fnmatch(basename, flpattern):\n                #print('found in force_load_patterns: ' + flpattern + \" \" + basename)\n                return False\n        folder_exclude_patterns = self.settings.get('folder_exclude_patterns')\n        if(folder_exclude_patterns):\n            if(isinstance(folder_exclude_patterns,str)):\n                folder_exclude_patterns = folder_exclude_patterns.split(',')\n            if basename in folder_exclude_patterns:\n                #print('found in folder_exclude_patterns')\n                return True\n        file_exclude_patterns = self.settings.get('file_exclude_patterns')\n        if(file_exclude_patterns):\n            if(isinstance(file_exclude_patterns,str)):\n                file_exclude_patterns = file_exclude_patterns.split(',')\n            for pattern in file_exclude_patterns:\n                if fnmatch(basename, pattern):\n                    #print('found in file_exclude_patterns: ' + str(basename))\n                    return True\n        return False\n\n    def expand_path(self, filepath):\n        if(filepath.startswith(\"file:\")):\n            filepath = filepath.replace(\"file:\",\"\", 1)\n        filepath = os.path.expandvars(filepath)\n        filepath = os.path.expanduser(filepath)\n\n        match = self.regex.match(filepath)\n        if match:\n            filepath, row, col, cid, heading, textmatch = match.group('filepath'), match.group('row'), match.group('col'), match.group('cid'), match.group('heading'), match.group('textmatch')\n        else:\n            row = None\n            col = None\n            cid = None\n            heading = None\n            textmatch = None\n\n        # The presence of a custom ID means we jump\n        # using a different means\n        if(cid):\n            #print(\"File Found ID trying to jump to: \" + cid)\n            db.Get().JumpToAnyId(cid)\n            return True\n        if(heading):\n            #print(\"Found Heading trying to jump to: \" + heading)\n            fpath = self.view.RelativeTo(filepath).lower()\n            fi = db.Get().FindInfo(fpath)\n            if(fi):\n                for n in fi.org:\n                    if not n.is_root() and n.heading == heading:\n                        row = n.start_row + 1\n                        col = 0\n                        break\n        if(textmatch):\n            #print(\"Found Textmatch trying to jump to: \" + textmatch)\n            fpath = self.view.RelativeTo(filepath).lower()\n            if(self.tryMatchDirectTarget(fpath, textmatch)):\n                return True\n            if(self.tryMatchNamedObject(fpath, textmatch)):\n                return True\n            if(self.tryMatchHeading(fpath, textmatch)):\n                return True\n        #print(\"NO TEXT MATCH\")\n        drive, filepath = os.path.splitdrive(filepath)\n        if not filepath.startswith('/') and not filepath.startswith('\\\\'):  # If filepath is relative...\n            cwd = os.path.dirname(self.view.file_name())\n            testfile = os.path.join(cwd, filepath)\n            if os.path.exists(testfile):  # See if it exists here...\n                filepath = testfile\n\n        filepath = ''.join([drive, filepath]) if drive else filepath\n        if not self.file_is_excluded(filepath):\n            if row:\n                filepath += ':%s' % row\n            if col:\n                filepath += ':%s' % col\n            #print(\"Opening file: \" + filepath)\n            self.view.window().open_file(filepath, sublime.ENCODED_POSITION)\n            return True\n        else:\n            #print('file_is_excluded: ' + filepath)\n            return filepath\n\n        return None\n\n    def replace(self, content):\n        content = self.expand_path(content)\n        return content\n\n    def execute(self, content):\n        if content is not True:\n            #print('normal open')\n            return super(Resolver, self).execute(content)\n"
  },
  {
    "path": "orgresolver/http.py",
    "content": "\nimport sys\nimport re\nimport subprocess\nimport sublime\nfrom .abstract import AbstractRegexLinkResolver\n\ntry:\n    import urllib.request, urllib.parse, urllib.error\nexcept ImportError:\n    import urllib\n\n\n\nPATTERN_SETTING = 'resolver.http.pattern'\nPATTERN_DEFAULT = r'^(http):(?P<url>.+)$'\nURL_SETTING = 'resolver.http.url'\nURL_DEFAULT = 'http:%s'\n\n\nDEFAULT_OPEN_HTTP_LINK_COMMANDS = dict(\n    darwin=['open'],\n    win32=['cmd', '/C'],\n    linux=['xdg-open'],\n)\n\n\nclass Resolver(AbstractRegexLinkResolver):\n\n    def __init__(self, view):\n        super(Resolver, self).__init__(view)\n        get = self.settings.get\n        pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)\n        self.regex = re.compile(pattern)\n        self.url = get(URL_SETTING, URL_DEFAULT)\n        self.link_commands = self.settings.get(\n            'resolver.abstract.commands', DEFAULT_OPEN_HTTP_LINK_COMMANDS)\n\n    def replace(self, match):\n        return self.url % match.group('url')\n\n    def execute(self, content):\n        command = self.get_link_command()\n        if not command:\n            sublime.error_message(\n                'Could not get link opener command.\\nNot yet supported.')\n            return None\n            \n        # cmd.exe quote is needed, http://ss64.com/nt/syntax-esc.html\n        # escape these: ^\\  ^&  ^|  ^>  ^<  ^^\n        if sys.platform == 'win32':\n            content = content.replace(\"^\", \"^^\")\n            content = content.replace(\"&\", \"^&\")\n            content = content.replace(\"\\\\\", \"^\\\\\")\n            content = content.replace(\"|\", \"^|\")\n            content = content.replace(\"<\", \"^<\")\n            content = content.replace(\">\", \"^>\")\n\n\n        if sys.version_info[0] < 3:\n            content = content.encode(sys.getfilesystemencoding())\n\n        if sys.platform != 'win32':\n            cmd = command + [content]\n        else:\n            cmd = command + ['start ' + content]\n\n        #print('HTTP*****')\n        #print(repr(content), content)\n        #print(repr(cmd))\n        #print(cmd)\n        sublime.status_message('Executing: %s' % cmd)\n        if sys.platform != 'win32':\n            process = subprocess.Popen(\n                cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n        else:\n            process = subprocess.Popen(\n                cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\n\n        stdout, stderr = process.communicate()\n        if stdout:\n            stdout = str(stdout, sys.getfilesystemencoding())\n            sublime.status_message(stdout)\n        if stderr:\n            stderr = str(stderr, sys.getfilesystemencoding())\n            sublime.error_message(stderr)\n"
  },
  {
    "path": "orgresolver/https.py",
    "content": "\nimport re\nimport sys\nimport subprocess\nimport sublime\nfrom .abstract import AbstractRegexLinkResolver\n\ntry:\n    import urllib.request, urllib.parse, urllib.error\nexcept ImportError:\n    import urllib\n\n\nPATTERN_SETTING = 'resolver.https.pattern'\nPATTERN_DEFAULT = r'^(https):(?P<url>.+)$'\nURL_SETTING = 'resolver.https.url'\nURL_DEFAULT = 'https:%s'\n\nDEFAULT_OPEN_HTTP_LINK_COMMANDS = dict(\n    darwin=['open'],\n    win32=['cmd', '/C'],\n    linux=['xdg-open'],\n)\n\n\nclass Resolver(AbstractRegexLinkResolver):\n\n    def __init__(self, view):\n        super(Resolver, self).__init__(view)\n        get = self.settings.get\n        pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)\n        self.regex = re.compile(pattern)\n        self.url = get(URL_SETTING, URL_DEFAULT)\n        self.link_commands = self.settings.get(\n            'resolver.abstract.commands', DEFAULT_OPEN_HTTP_LINK_COMMANDS)\n\n    def replace(self, match):\n        return self.url % match.group('url')\n\n    def execute(self, content):\n        command = self.get_link_command()\n        if not command:\n            sublime.error_message(\n                'Could not get link opener command.\\nNot yet supported.')\n            return None\n\n        # cmd.exe quote is needed, http://ss64.com/nt/syntax-esc.html\n        # escape these: ^\\  ^&  ^|  ^>  ^<  ^^\n        if sys.platform == 'win32':\n            content = content.replace(\"^\", \"^^\")\n            content = content.replace(\"&\", \"^&\")\n            content = content.replace(\"\\\\\", \"^\\\\\")\n            content = content.replace(\"|\", \"^|\")\n            content = content.replace(\"<\", \"^<\")\n            content = content.replace(\">\", \"^>\")\n\n        if sys.version_info[0] < 3:\n            content = content.encode(sys.getfilesystemencoding())\n\n        if sys.platform != 'win32':\n            cmd = command + [content]\n        else:\n            cmd = command + ['start ' + content]\n\n        #print('HTTP*****')\n        #print(repr(content), content)\n        #print(repr(cmd))\n        #print(cmd)\n        sublime.status_message('Executing: %s' % cmd)\n        if sys.platform != 'win32':\n            process = subprocess.Popen(\n                cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n        else:\n            process = subprocess.Popen(\n                cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\n\n        stdout, stderr = process.communicate()\n        if stdout:\n            stdout = str(stdout, sys.getfilesystemencoding())\n            sublime.status_message(stdout)\n        if stderr:\n            stderr = str(stderr, sys.getfilesystemencoding())\n            sublime.error_message(stderr)\n"
  },
  {
    "path": "orgresolver/internal.py",
    "content": "import re\nimport os\nfrom fnmatch import fnmatch\nimport sublime\nfrom .abstract import AbstractLinkResolver\nimport OrgExtended.orgdb as db\nfrom OrgExtended.orgutil.util import *\n\nPATTERN_SETTING = 'resolver.local_file.pattern'\nPATTERN_DEFAULT = r'^(((::(?P<row>\\d+))(::(?P<col>\\d+))?)|(::\\#(?P<cid>[a-zA-Z0-9!$@%&_-]+))|(::\\*(?P<heading>[a-zA-Z0-9!$@%&_-]+)))?\\s*$'\n\nFORCE_LOAD_SETTING = 'resolver.local_file.force_into_sublime'\n\n\nclass Resolver(AbstractLinkResolver):\n    def __init__(self, view):\n        super(Resolver, self).__init__(view)\n        self.view = view\n        get = self.settings.get\n        pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)\n        self.regex = re.compile(pattern)        \n\n    def is_internal_link(self, filepath):\n    \tfp = filepath.strip()\n    \t# Starts with :: this is DEFINETLY an internal link\n    \tif(len(fp) > 2 and fp.startswith(\"::\")):\n    \t\treturn True\n    \tif('.' in fp):\n    \t\treturn False\n    \tif('/' in fp):\n    \t\treturn False\n    \tif('\\\\' in fp):\n    \t\treturn False\n    \t# File path for sure?\n    \tif(':' in fp):\n    \t\treturn False\n    \tif(os.path.isfile(fp)):\n    \t\treturn False\n    \t# Okay, this PROBABLY is an internal link\n    \t#print('Probably internal link')\n    \treturn True\n\n    def tryMatchHeading(self, heading):\n        fpath = self.view.file_name().lower()\n        fi = db.Get().FindInfo(fpath)\n        row = None\n        col = None\n        if(fi):\n            for n in fi.org:\n                if not n.is_root() and n.heading == heading:\n                    row = n.start_row + 1\n                    col = 0\n                    break\n                    filepath = self.view.file_name()\n                    if row:\n                        filepath += ':%s' % row\n                    if col:\n                        filepath += ':%s' % col\n                    self.view.window().open_file(filepath, sublime.ENCODED_POSITION)\n                    return True\n        return None\n\n    def tryMatchDirectTarget(self, val):\n        fpath = self.view.file_name().lower()\n        fi = db.Get().FindInfo(fpath)\n        if(fi):\n            if(fi.org.targets):\n                if(val in fi.org.targets):\n                    tgt = fi.org.targets[val]\n                    row = tgt['row'] + 1\n                    col = tgt['col']\n                    filepath = self.view.file_name()\n                    if row:\n                        filepath += ':{0}'.format(row)\n                    if col:\n                        filepath += ':{0}'.format(col)\n                    self.view.window().open_file(filepath, sublime.ENCODED_POSITION)\n                    return True\n        return None\n\n    def tryMatchNamedObject(self, val):\n        fpath = self.view.file_name().lower()\n        fi = db.Get().FindInfo(fpath)\n        if(fi):\n            if(fi.org.names):\n                if(val in fi.org.names):\n                    tgt = fi.org.names[val]\n                    row = tgt['row'] + 1\n                    col = 0\n                    filepath = self.view.file_name()\n                    if row:\n                        filepath += ':{0}'.format(row)\n                    if col:\n                        filepath += ':{0}'.format(col)\n                    self.view.window().open_file(filepath, sublime.ENCODED_POSITION)\n                    return True\n        return None\n\n    def expand_path(self, filepath):\n        filepath = os.path.expandvars(filepath)\n        filepath = os.path.expanduser(filepath)\n        if(not self.is_internal_link(filepath)):\n            #print(\"Not an internal link\")\n            return None\n\n        # Check for standard internal link\n        match = self.regex.match(filepath)\n        if match:\n            row, col, cid, heading = match.group('row'), match.group('col'), match.group('cid'), match.group('heading')\n            # The presence of a custom ID means we jump\n            # using a different means\n            if(cid):\n                #print(\"Internal Found ID trying to jump to: \" + cid)\n                db.Get().JumpToAnyId(cid)\n                return True\n            if(heading):\n                return self.tryMatchHeading(heading)\n            return None\n        else:\n            # Okay now the fun starts. We got an unidentifed link, this could be a:\n            # <<>> target\n            # A #+NAME \"ed\" object somewhere\n            # a heading somewhere\n            #\n            # So we have to get creative and go find that.\n            if(self.tryMatchDirectTarget(filepath)):\n                return True\n            if(self.tryMatchNamedObject(filepath)):\n                return True\n            if(self.tryMatchHeading(filepath)):\n                return True\n        return None\n\n    def replace(self, content):\n        content = self.expand_path(content)\n        return content\n\n    def execute(self, content):\n        # Nothing to do here!\n        return content\n        #if content is not True:\n        #    return super(Resolver, self).execute(content)\n"
  },
  {
    "path": "orgresolver/jira.py",
    "content": "\nimport re\nfrom .abstract import AbstractRegexLinkResolver\n\n\nPATTERN_SETTING = 'resolver.jira.pattern'\nPATTERN_DEFAULT = r'^(jira|j):(?P<issue>.+)$'\nURL_SETTING = 'resolver.jira.url'\nURL_DEFAULT = 'http://sandbox.onjira.com/browse/%s'\n\n\nclass Resolver(AbstractRegexLinkResolver):\n\n    def __init__(self, view):\n        super(Resolver, self).__init__(view)\n        get = self.settings.get\n        pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)\n        self.regex = re.compile(pattern)\n        self.url = get(URL_SETTING, URL_DEFAULT)\n\n    def replace(self, match):\n        return self.url % match.group('issue')\n"
  },
  {
    "path": "orgresolver/prompt.py",
    "content": "\nimport re\nimport sys\nimport subprocess\nimport sublime\nfrom .abstract import AbstractRegexLinkResolver\n\nDEFAULT_OPEN_PROMPT_LINK_COMMANDS = dict(\n    darwin=['open', '-a', 'Terminal'],\n    win32=['cmd'],\n    linux=['gnome-terminal'],\n)\n\n\nPATTERN_SETTING = 'resolver.prompt.pattern'\nPATTERN_DEFAULT = r'^(cmd:|prompt:)(?P<path>.+)$'\nPROMPT_SETTING = 'resolver.prompt.path'\nPROMPT_DEFAULT_WIN32 = '%s'\nPROMPT_DEFAULT_LINUX = '--working-directory=%s'\n\n\nclass Resolver(AbstractRegexLinkResolver):\n\n    def __init__(self, view):\n        super(Resolver, self).__init__(view)\n        get = self.settings.get\n        self.link_commands = self.settings.get(\n            'resolver.abstract.commands', DEFAULT_OPEN_PROMPT_LINK_COMMANDS)\n        pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)\n        self.regex = re.compile(pattern)\n        if sys.platform == 'win32' or sys.platform == 'darwin':\n            self.url = get(PROMPT_SETTING, PROMPT_DEFAULT_WIN32)\n        else:\n            self.url = get(PROMPT_SETTING, PROMPT_DEFAULT_LINUX)\n \n    def replace(self, match):\n        return self.url % match.group('path')\n\n    def get_link_command(self):\n        platform = sys.platform\n        for key, val in self.link_commands.items():\n            if key in platform:\n                return val\n        return None\n\n    def execute(self, content):\n        command = self.get_link_command()\n        if not command:\n            sublime.error_message(\n                'Could not get link opener command.\\nNot yet supported.')\n            return None\n\n        if sys.version_info[0] < 3:\n            content = content.encode(sys.getfilesystemencoding())\n\n        if sys.platform != 'win32':\n            cmd = command + [content]\n        else:\n            cmd = 'cmd /C start cmd.exe /K \"cd /d '+content+'\"'\n\n        print('PROMPT*****')\n        print(repr(content))\n        print(cmd)\n        # \\\"cd /d c:\\dev\\apps\\\"' is not recognized as an internal or external command,\n        sublime.status_message('Executing: %s' % cmd)\n        if sys.platform != 'win32':\n            process = subprocess.Popen(\n                cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n        else:\n            process = subprocess.Popen(\n                cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\n\n        stdout, stderr = process.communicate()\n        if stdout:\n            stdout = str(stdout, sys.getfilesystemencoding())\n            sublime.status_message(stdout)\n        if stderr:\n            stderr = str(stderr, sys.getfilesystemencoding())\n            sublime.error_message(stderr)\n"
  },
  {
    "path": "orgrevealjs.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nimport regex\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orgutil.navigation as nav\nimport OrgExtended.orgutil.template as templateEngine\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgfolding as folding\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.orgcapture as capture\nimport OrgExtended.orgproperties as props\nimport OrgExtended.orgexporter as exp\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orgplist as plist\nimport OrgExtended.orghtmlexporter as hexp\nimport yaml\nimport sys\nimport subprocess\nimport html\n\nlog = logging.getLogger(__name__)\n\n\n\ndef RevealFilename(view):\n    fn = view.file_name()\n    fn,ext = os.path.splitext(fn)\n    return fn + \".html\"\n\n# Global properties I AT LEAST want to support.\n# Both as a property on the document and in our settings.\n#+OPTIONS: num:nil toc:nil\n#+REVEAL_TRANS: None/Fade/Slide/Convex/Concave/Zoom\n#+REVEAL_THEME: Black/White/League/Sky/Beige/Simple/Serif/Blood/Night/Moon/Solarized\n#+Title: Title of Your Talk\n#+Author: Your Name\n#+Email: Your Email Address or Twitter Handle\n\ndef GetGlobalOption(file, name, settingsName, defaultValue):\n    value = sets.Get(settingsName, defaultValue)\n    value = ' '.join(file.org[0].get_comment(name, [str(value)]))\n    return value\n\n\npropMappings = {\n    \"reveal_background\":              \"data-background-image\",\n    \"reveal_background_image\":        \"data-background-image\",\n    \"reveal_background_size\":         \"data-background-size\",\n    \"reveal_background_trans\":        \"data-background-transition\",\n    \"reveal_trans\":                   \"data-transition\",\n    \"reveal_trans_speed\":             \"data-transition-speed\",\n    \"reveal_background_position\":     \"data-background-position\",\n    \"reveal_background_repeat\":       \"data-background-repeat\",\n    \"reveal_background_opacity\":      \"data-background-opacity\",\n    \"reveal_background_color\":        \"data-background-color\",\n    \"reveal_background_video\":        \"data-background-video\",\n    \"reveal_background_video_loop\":   \"data-background-video-loop\",\n    \"reveal_background_video_muted\":  \"data-background-video-muted\"\n}\n\nRE_SCHEDULING_LINE = re.compile(r\"^\\s*(SCHEDULED|CLOSED|DEADLINE)[:].*\")\nRE_DRAWER_LINE = re.compile(r\"^\\s*[:].+[:]\\s*$\")\nRE_END_DRAWER_LINE = re.compile(r\"^\\s*[:](END|end)[:]\\s*$\")\nRE_LINK = re.compile(r\"\\[\\[(?P<link>[^\\]]+)\\](\\[(?P<desc>[^\\]]+)\\])?\\]\")\nRE_UL   = re.compile(r\"^\\s*(-|[+])\\s+(?P<data>.+)\")\nRE_BOLD = re.compile(r\"\\*(?P<data>.+)\\*\")\nRE_ITALICS = re.compile(r\"/(?P<data>.+)/\")\nRE_UNDERLINE = re.compile(r\"_(?P<data>.+)_\")\nRE_STRIKETHROUGH = re.compile(r\"\\+(?P<data>.+)\\+\")\nRE_CODE = re.compile(r\"~(?P<data>.+)~\")\nRE_VERBATIM = re.compile(r\"=(?P<data>.+)=\")\nRE_STARTQUOTE = re.compile(r\"#\\+(BEGIN_QUOTE|BEGIN_EXAMPLE|BEGIN_VERSE|BEGIN_CENTER|begin_quote|begin_example|begin_verse|begin_center)\")\nRE_ENDQUOTE = re.compile(r\"#\\+(END_QUOTE|END_EXAMPLE|END_VERSE|END_CENTER|end_quote|end_example|end_verse|end_center)\")\nRE_STARTNOTE = re.compile(r\"#\\+(BEGIN_NOTES|begin_notes)\")\nRE_ENDNOTE = re.compile(r\"#\\+(END_NOTES|end_notes)\")\nRE_FN_MATCH = re.compile(r\"\\s*[:]([a-zA-Z0-9-_]+)\\s+([^: ]+)?\\s*\")\nRE_STARTSRC = re.compile(r\"^\\s*#\\+(BEGIN_SRC|begin_src)\\s+(?P<lang>[a-zA-Z0-9]+)\")\nRE_ENDSRC = re.compile(r\"^\\s*#\\+(END_SRC|end_src)\")\nRE_RESULTS = re.compile(r\"^\\s*#\\+RESULTS.*\")\n\n\n#https://cdn.jsdelivr.net/npm/reveal.js@3.8.0/js/reveal.min.js\ncdn = \"https://cdn.jsdelivr.net/npm/reveal.js\"\n#cdn = \"https://cdnjs.cloudflare.com/ajax/libs/reveal.js\"\nver = \"@4.1.0\"\ncdn = cdn + ver + \"/\"\n\n\ndef mapLanguage(lang):\n    if(lang == 'html'):\n        return 'language-html'\n    elif(lang == 'python'):\n        return 'language-python'\n    else:\n        return lang\n\nclass RevealHrParser(exp.HrParser):\n    def __init__(self,doc):\n        super(RevealHrParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(r\"<hr/>\")\n\nclass RevealNameParser(exp.NameParser):\n    def __init__(self,doc):\n        super(RevealNameParser,self).__init__(doc)\n    def HandleLine(self,m,l,n):\n        self.e.doc.append(r\"<a name=\\\"{data}\\\"/>\".format(data=m.group('data')))\n\n\nRE_ATTR_REVEAL = regex.compile(r\"^\\s*[#][+]ATTR_REVEAL[:]\\s*(?P<data>.*)\")\nclass RevealAttributeParser(exp.AttributeParser):\n    def __init__(self,doc):\n        super(RevealAttributeParser,self).__init__('attr_reveal',RE_ATTR_REVEAL,doc)\n\nclass RevealDoc(exp.OrgExporter):\n    def __init__(self,filename,file,**kwargs):\n        super(RevealDoc, self).__init__(filename, file, **kwargs)\n        self.pre      = []\n        self.doc      = []\n        self.attribs  = {}\n        self.amInBlock = False\n        self.pre.append(\"<!doctype html>\")\n        self.pre.append(\"<html lang=\\\"en\\\" class>\")\n        self.commentName = None\n        self.nodeParsers = [\n        exp.SetupFileParser(self),\n        exp.CaptionAttributeParser(self),\n        RevealAttributeParser(self),\n        exp.ResultsParser(self),\n        hexp.HtmlCommentParser(self),\n        hexp.HtmlTableBlockState(self),\n        hexp.HtmlSourceBlockState(self),\n        hexp.HtmlDynamicBlockState(self),\n        hexp.HtmlQuoteBlockState(self),\n        hexp.HtmlExampleBlockState(self),\n        hexp.HtmlNotesBlockState(self),\n        hexp.HtmlCheckboxListBlockState(self),\n        hexp.HtmlUnorderedListBlockState(self),\n        hexp.HtmlOrderedListBlockState(self),\n        hexp.HtmlExportBlockState(self),\n        hexp.HtmlGenericBlockState(self),\n        exp.DrawerBlockState(self),\n        exp.SchedulingStripper(self),\n        exp.TblFmStripper(self),\n        exp.AttrHtmlStripper(self),\n        exp.AttrOrgStripper(self),\n        exp.KeywordStripper(self),\n        hexp.HtmlEmptyParser(self),\n        hexp.HtmlLinkParser(self),\n        RevealHrParser(self),\n        RevealNameParser(self),\n        hexp.HtmlHtmlHtmlParser(self),\n        hexp.HtmlActiveDateParser(self),\n        hexp.HtmlBoldParser(self),\n        hexp.HtmlItalicsParser(self),\n        hexp.HtmlUnderlineParser(self),\n        hexp.HtmlStrikethroughParser(self),\n        hexp.HtmlCodeParser(self),\n        hexp.HtmlVerbatimParser(self),\n        hexp.HtmlTargetParser(self)\n        ]\n\n    def SetAmInBlock(self,inBlock):\n        self.amInBlock = inBlock\n\n    def AmInBlock(self):\n        return self.amInBlock\n\n    def AddAttrib(self,name,val):\n        if(type(val) == str):\n            self.attribs[name] = val.strip()\n        else:\n            self.attribs[name] = val\n    \n    def GetAttrib(self,name):\n        if(name in self.attribs):\n            return self.attribs[name]\n        return None\n\n    def ClearAttrib(self):\n        self.attribs.clear()\n    def AddJs(self,link):\n        self.pre.append(\"    <script type=\\\"text/javascript\\\" src=\\\"\" + link + \"\\\"></script>\")\n\n    def AddStyle(self,link,id=None):\n        if(id == None):\n            self.pre.append(\"    <link rel=\\\"stylesheet\\\" href=\\\"\"+link+\"\\\">\")\n        else:\n            self.pre.append(\"    <link rel=\\\"stylesheet\\\" href=\\\"\"+link+\"\\\" id=\\\"\"+id+\"\\\">\")\n\n    def AddInlineStyle(self,style):\n        self.pre.append(\"    <style>{}</style>\".format(style))\n    # Okay\n    def StartHead(self):\n        self.pre.append(\"  <head>\")\n        self.pre.append(\"  <meta charset=\\\"utf-8\\\">\")\n        self.pre.append(\"  <meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\\\">\")\n\n    def AddExportMetaCustom(self):\n        self.AddStyle(cdn + \"dist/reset.css\")\n        self.AddStyle(cdn + \"dist/reveal.css\")\n\n        cssData      = GetGlobalOption(self.file,\"REVEAL_CSS\",\"RevealCss\",None)\n        if(cssData):\n            self.AddInlineStyle(cssData)    \n\n\n        # black: Black background, white text, blue links (default theme)\n        # white: White background, black text, blue links\n        # league: Gray background, white text, blue links (default theme for reveal.js < 3.0.0)\n        # beige: Beige background, dark text, brown links\n        # sky: Blue background, thin dark text, blue links\n        # night: Black background, thick white text, orange links\n        # serif: Cappuccino background, gray text, brown links\n        # simple: White background, black text, blue links\n        # solarized: Cream-colored background, dark green text, blue links\n        # moon: Dark green background.\n        theme      = GetGlobalOption(self.file,\"REVEAL_THEME\",\"RevealTheme\",\"league\").lower()\n        # TODO: Validate the theme here.\n        self.AddStyle(cdn + \"dist/theme/{theme}.css\".format(theme=theme),id=\"theme\")\n        #doc.AddStyle(cdn + \"css/print/paper.css\")\n\n\n        highlight      = GetGlobalOption(self.file,\"REVEAL_HIGHLIGHT\",\"RevealHighlight\",\"zenburn\").lower()\n        #doc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/lib/css/monokai.min.css\")\n        #doc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/lib/css/zenburn.min.css\")\n        #doc.AddStyle(\"https://cdn.jsdelivr.net/npm/highlightjs-themes@1.0.0/{hl}.css\".format(hl=highlight),\"highlight-theme\")\n        self.AddStyle(cdn + \"plugin/highlight/{hl}.css\".format(hl=highlight),\"highlight-theme\")\n        \n        #doc.AddStyle(cdn + \"lib/css/{hl}.css\".format(hl=highlight))\n        #doc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/lib/font/league-gothic/league-gothic.min.css\")\n        #doc.AddStyle(\"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/lib/font/source-sans-pro/source-sans-pro.min.css\")\n        self.vlevel = int(GetGlobalOption(self.file,\"REVEAL_VLEVEL\",\"RevealVLevel\",1))\n    # Okay\n    def EndHead(self):\n        self.pre.append(\"  </head>\")\n\n    # Start presentation\n    def StartDocument(self, file):\n        # This doesn't work have to do it as a parameter!\n        transition      = GetGlobalOption(file,\"REVEAL_TRANS\",\"RevealTransition\",\"none\").lower()\n        transitionSpeed = GetGlobalOption(file,\"REVEAL_TRANS_SPEED\",\"RevealTransitionSpeed\",\"default\").lower()\n        self.doc.append(\"  <div class=\\\"reveal slide center has-vertical-slides has-horizontal-slides ready\\\" role=\\\"application\\\" data-transition-speed=\\\"{tspeed}\\\" data-background-transition=\\\"{transition}\\\">\".format(\n            transition=transition,\n            tspeed=transitionSpeed))\n\n    # End presentation\n    def EndDocument(self):\n        self.doc.append(\"  </div>\")\n\n    # Start slides\n    def StartNodes(self):\n        self.doc.append(\"    <div class=\\\"slides\\\">\")\n\n    # End slides\n    def EndNodes(self):\n        self.doc.append(\"    </div>\")\n\n    # Per slide properties\n    #:PROPERTIES:\n    #:reveal_background: images/name-of-image\n    #:reveal_background_size: width-of-image\n    #:reveal_background_trans: slide\n    #:END:\n    def StartNode(self,slide):\n        # data-background-trans:        slide\n        # data-background-image         URL of the image to show. GIFs restart when the slide opens.\n        # data-background-size          cover   See background-size on MDN.\n        # data-background-position      center  See background-position on MDN.\n        # data-background-repeat        no-repeat   See background-repeat on MDN.\n        # data-background-opacity\n        # data-background-color \n        # data-background-video         A single video source, or a comma separated list of video sources.\n        # data-background-video-loop    false   Flags if the video should play repeatedly.\n        # data-background-video-muted   false   Flags if the audio should be muted.\n        properties = \"\"\n        for prop in slide.properties:\n            if prop in propMappings:\n                properties = \"{0} {1}=\\\"{2}\\\"\".format(properties,propMappings[prop],slide.properties[prop])\n\n        self.doc.append(\"      <section {0}>\".format(properties))\n\n    def EndNode(self,slide):\n        self.doc.append(\"      </section>\")\n\n    def NodeHeading(self,slide):\n        heading = html.escape(slide.heading)\n        level = slide.level + 1\n        self.doc.append(\"      <h{level}>{heading}</h{level}>\".format(level=level,heading=heading))\n\n    def TextFullEscape(self,text):\n        return html.escape(text)\n        \n    def Escape(self,str):\n        return self.TextFullEscape(str)\n\n    def NodeBody(self,n):\n        ilines = n._lines[1:]\n        for parser in self.nodeParsers:\n            ilines = parser.Handle(ilines,n)\n        for line in ilines:\n            self.doc.append(self.TextFullEscape(line))\n        return\n\n    def StartBody(self):\n        self.doc.append(\"  <body style=\\\"transition: -webkit-transform 0.8s ease 0s; transform-origin: 0px 0px;\\\">\")\n\n    def EndBody(self):\n        self.doc.append(\"  </body>\")\n\n    def Progress(self):\n        self.doc.append(\"  <div class=\\\"progress\\\" style=\\\"display: block;\\\">\")\n        self.doc.append(\"    <span style=\\\"width: 265px;\\\"></span>\")\n        self.doc.append(\"    ::after\")\n        self.doc.append(\"  </div>\")\n\n    def Dep(self, file, link, last=False):\n        #location = \"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/\"\n        location = cdn\n        location = GetGlobalOption(file,\"REVEAL_LOCATION\",\"RevealLocation\",location)    \n        location = location + \"plugin/\"\n        comma =\",\"\n        if(last):\n            comma = \"\"\n        self.doc.append(\"              { src: '\"+location+link+\"', async: true }\"+comma) \n\n    def SDep(self,js):\n        self.doc.append(\"  <script src=\\\"{location}plugin/{js}\\\"></script>\".format(location=cdn,js=js))\n\n    def InsertScripts(self,file):\n        #location = \"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0/\"\n        location = cdn\n        location = GetGlobalOption(file,\"REVEAL_LOCATION\",\"RevealLocation\",location)    \n        self.doc.append(\"  <script src=\\\"{location}dist/reveal.min.js\\\"></script>\".format(location=location))\n        self.SDep(\"markdown/markdown.js\")\n        self.SDep(\"highlight/highlight.js\")\n        self.SDep(\"search/search.js\")\n        self.SDep(\"zoom/zoom.js\")\n        self.SDep(\"notes/notes.js\")\n        self.SDep(\"math/math.js\")\n        self.doc.append(\"  <script>\")\n        #self.fs.write(\"       Reveal.initialize();\\n\")\n        self.doc.append(\"      Reveal.initialize({\")\n        self.doc.append(\"          hash: true,\") # Allow browsing back to this slide.\n        transition      = GetGlobalOption(file,\"REVEAL_TRANS\",\"RevealTransition\",\"none\").lower()\n        transitionSpeed = GetGlobalOption(file,\"REVEAL_TRANS_SPEED\",\"RevealTransitionSpeed\",\"default\").lower()\n        # Transition style\n        self.doc.append(\"          transition: '{transition}',\".format(transition=transition)) # none/fade/slide/convex/concave/zoom\n        self.doc.append(\"          transitionSpeed: '{transitionSpeed}',\".format(transitionSpeed=transitionSpeed)) # default/fast/slow\n        #self.fs.write(\"          showNotes: false,\\n\")\n        self.doc.append(\"          dependencies: [\") \n        #self.Dep(file, \"markdown/marked.js\")\n        self.Dep(file, \"markdown/markdown.js\")\n        self.Dep(file, \"highlight/highlight.js\")\n        self.Dep(file, \"search/search.js\")\n        #self.Dep(file, \"zoom-js/zoom.js\")\n        self.Dep(file, \"zoom/zoom.js\")\n        self.Dep(file, \"notes/notes.js\")\n        #self.Dep(\"print-pdf/print-pdf.min.js\")\n        self.Dep(file, \"math/math.js\",True)\n        self.doc.append(\"          ],\") \n        self.doc.append(\"          plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]\")\n        self.doc.append(\"      });\")\n        self.doc.append(\"  </script>\")\n\n    def BuildDoc(self):\n        out = '\\n'.join(self.pre) + '\\n' + '\\n'.join(self.doc) + '\\n'\n        return out\n\n    def FinishDocCustom(self):\n        self.fs.write(self.BuildDoc())\n        self.fs.write(\"</html>\\n\")\n\nclass OrgExportFileRevealJsCommand(sublime_plugin.TextCommand):\n    def OnDoneSourceBlockExecution(self):\n        # Reload if necessary\n        self.file = db.Get().FindInfo(self.view)\n        self.doc  = None\n        try:\n            outputFilename = exp.ExportFilename(self.view,\".html\",self.suffix)\n            self.doc = RevealDoc(outputFilename,self.file)\n            self.helper    = exp.OrgExportHelper(self.view,self.index)\n            self.helper.Run(outputFilename, self.doc)\n        finally:    \n            evt.EmitIf(self.onDone)\n\n\n    def run(self,edit, onDone=None, index=None, suffix=\"\"):\n        self.file = db.Get().FindInfo(self.view)\n        self.onDone = onDone\n        self.suffix = suffix\n        global cdn        \n        cdn = GetGlobalOption(self.file,\"REVEAL_LOCATION\",\"RevealLocation\",cdn)\n        if(index != None):\n            self.index = index\n        else:\n            self.index = None\n        if(None == self.file):\n            log.error(\"Not an org file? Cannot build reveal document\")\n            evt.EmitIf(onDone)  \n            return\n        if(sets.Get(\"revealExecuteSourceOnExport\",False)):\n            self.view.run_command('org_execute_all_source_blocks',{\"onDone\":evt.Make(self.OnDoneSourceBlockExecution),\"amExporting\": True})\n        else:\n            self.OnDoneSourceBlockExecution()\n\n# pandoc -s -o output.html input.txt\n"
  },
  {
    "path": "orgsnippets/beancount/transaction.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[\n${YEAR}-${MONTH}-${1:DAY} * \"${2:Name}\" \"${3:Description}\"\n  ${4:From}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t${5:Amount} ${DEFAULT_CURRENCY}\n  ${6:To}\n\n$0\n]]></content>\n    <tabTrigger>StartTransaction</tabTrigger>\n    <scope>source.beancount</scope>\n    <description>Start Transaction</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/capture_heading.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[\n* NOTE ${1:HEADING}\n  :PROPERTIES:\n  :FROM:    [[file:${ORG_FILENAME}:${ORG_LINENUM}][Source]]\n  :CREATED: $ORG_INACTIVE_DATE\n  :END:\n  $0\n  #+begin_src ${2:cpp}\n  $ORG_SELECTION\n  #+end_src\n\n]]></content>\n    <tabTrigger>capture_heading</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>Capture Heading</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/dayPageSnippet.sublime-snippet",
    "content": "\n<snippet>\n    <content><![CDATA[\n#+TITLE:  ${ORG_FILENAME}\n#+AUTHOR: ${ORG_AUTHOR}\n\n* ${1:HEADING}\n  $0\n\n]]></content>\n    <tabTrigger>daypage_create</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>DayPage Heading</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/dynamicblock.sublime-snippet",
    "content": "<snippet>\n    <content>\n    <![CDATA[\n#+BEGIN: ${1:TYPE}\n  $0\n#+END:]]></content>\n    <tabTrigger>&lt;b</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>source block</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/example.sublime-snippet",
    "content": "<snippet>\n    <content>\n    <![CDATA[\n#+BEGIN_EXAMPLE\n  $0\n#+END_EXAMPLE]]></content>\n    <tabTrigger>&lt;e</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>example block</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/heading1.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[\n* ${1:HEADING}]]></content>\n    <tabTrigger>h</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>Heading level 1</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/heading2.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[\n** ${0:HEADING}]]></content>\n    <tabTrigger>hh</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>Heading Level 2</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/heading3.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[\n*** ${0:HEADING}]]></content>\n    <tabTrigger>hhh</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>Heading Level 3</description>\n</snippet>"
  },
  {
    "path": "orgsnippets/heading4.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[\n**** ${0:HEADING}]]></content>\n    <tabTrigger>hhhh</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>Heading Level 4</description>\n</snippet>"
  },
  {
    "path": "orgsnippets/heading5.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[\n***** ${0:HEADING}]]></content>\n    <tabTrigger>hhhhh</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>Heading Level 5</description>\n</snippet>"
  },
  {
    "path": "orgsnippets/link.sublime-snippet",
    "content": "<snippet>\n    <content>\n    <![CDATA[[[$1][$2]] $0]]></content>\n    <tabTrigger>&lt;l</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>link</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/meeting_heading.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[\n* METTING ${1:HEADING}\n  :PROPERTIES:\n  :CREATED: $ORG_INACTIVE_DATE\n  :END:\n  $0\n]]></content>\n    <tabTrigger>meeting_heading</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>Meeting Heading</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/note_heading.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[\n* NOTE ${1:HEADING}\n  :PROPERTIES:\n  :CREATED: $ORG_INACTIVE_DATE\n  :END:\n  $0\n]]></content>\n    <tabTrigger>note_heading</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>Note Heading</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/notes.sublime-snippet",
    "content": "<snippet>\n    <content>\n    <![CDATA[\n#+BEGIN_NOTES\n  $0\n#+END_NOTES]]></content>\n    <tabTrigger>&lt;n</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>notes block</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/page.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[--- ${0:YYYY-MM-DD} ---]]></content>\n    <tabTrigger>p</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>page</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/plain_template.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[\n$0\n]]></content>\n    <tabTrigger>plain_template</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>plain heading</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/quote.sublime-snippet",
    "content": "<snippet>\n    <content>\n    <![CDATA[\n#+BEGIN_QUOTE\n  $0\n#+END_QUOTE]]></content>\n    <tabTrigger>&lt;q</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>quote block</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/src.sublime-snippet",
    "content": "<snippet>\n    <content>\n    <![CDATA[\n#+BEGIN_SRC ${1:TYPE}\n  $0\n#+END_SRC]]></content>\n    <tabTrigger>&lt;s</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>source block</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/tag.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[:${1:TAG}:$0]]></content>\n    <tabTrigger>t</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>tag</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/todo_heading.sublime-snippet",
    "content": "<snippet>\n    <content><![CDATA[\n* TODO ${1:HEADING}\n  :PROPERTIES:\n  :CREATED: $ORG_INACTIVE_DATE\n  :END:\n  $0\n]]></content>\n    <tabTrigger>todo_heading</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>Todo Heading</description>\n</snippet>\n"
  },
  {
    "path": "orgsnippets/verse.sublime-snippet",
    "content": "<snippet>\n    <content>\n    <![CDATA[\n#+BEGIN_VERSE\n  $0\n#+END_VERSE]]></content>\n    <tabTrigger>&lt;v</tabTrigger>\n    <scope>text.orgmode</scope>\n    <description>verse block</description>\n</snippet>\n"
  },
  {
    "path": "orgsourceblock.py",
    "content": "import ast\nimport logging\nimport os\nimport re\nimport tempfile\nimport traceback \nimport hashlib\nimport getpass\nimport datetime\n\nimport OrgExtended.orgdb as db\nimport OrgExtended.orgextension as ext\nimport OrgExtended.orglist as lst\nimport OrgExtended.orgtableformula as tbl\nimport OrgExtended.orgutil.util as util\nimport OrgExtended.pymitter as evt\nimport sublime\nimport sublime_plugin\nfrom   OrgExtended.orgparse.sublimenode import * \nfrom   OrgExtended.orgplist import *\n\n\nlog = logging.getLogger(__name__)\n\nRE_END = re.compile(r\"^\\s*\\#\\+(END_SRC|end_src)\")\nRE_SRC_BLOCK = re.compile(r\"^\\s*\\#\\+(BEGIN_SRC|begin_src)\\s+(?P<name>[^: ]+)\\s*\")\nRE_INL_SRC_BLOCK = re.compile(r\"(?P<block>(SRC_|src_)(?P<name>[a-zA-Z0-9_-]+)(\\[(?P<params>[^\\]]+)\\])?\\{(?P<code>[^}]+)\\})(?P<resblock>\\s*\\{\\{\\{results\\(\\s*=(?P<res>[^)]*)=\\s*\\)\\}\\}\\})?\")\nRE_INL_RESULTS_BLOCK = re.compile(r\"\\{\\{\\{results\\(=(?P<val>.*)=\\)\\}\\}\\}\")\nRE_FN_MATCH = re.compile(r\"\\s*[:]([a-zA-Z0-9-_]+)\\s+([^: ]+)\\s*\")\nRE_RESULTS = re.compile(r\"^\\s*\\#\\+(RESULTS|results)(\\s*\\[\\s*(?P<hash>[a-fA-F0-9]+)\\s*\\]\\s*)?[:]\\s*(?P<comment>[a-zA-Z0-9_-]+)?$\")\nRE_HEADING = re.compile(r\"^[*]+\\s+\")\nRE_PROPERTY_DRAWER = re.compile(r\"^\\s*[:][a-zA-Z0-9]+[:]\\s*$\")\nRE_END_PROPERTY_DRAWER = re.compile(r\"^\\s*[:](END|end)[:]\\s*$\")\nRE_BLOCK = re.compile(r\"^\\s*\\#\\+(BEGIN_|begin_)[a-zA-Z]+\\s+\")\nRE_END_BLOCK = re.compile(r\"^\\s*\\#\\+(END_|end_)[a-zA-Z]+\\s*\")\nRE_IS_BLANK_LINE = re.compile(r\"^\\s*$\")\nRE_FAIL = re.compile(r\"\\b([Ff][Aa][Ii][Ll][Ee][Dd])|([Ff][Aa][Ii][Ll][Uu][Rr][Ee][Ss]?)|([Ff][Aa][Ii][Ll])|([Ee][Rr][Rr][Oo][Rr][Ss]?)\\b\")\nRE_HEADER_PARAMS = re.compile(r\"^\\s*\\#\\+(HEADER|header)[:]\\s*(?P<params>.*)$\")\nRE_TABLE = re.compile(r\"^\\s*[|]\")\nRE_NOWEB = re.compile(r'^\\s*[<][<](?P<noweb>[^>(]+)(\\s*\\(\\s*(?P<params>[^)]*)\\s*\\))?[>][>]')\n\n\n# Interface that can be used to wrap a TableDef OR a simple list\n# Very simple table wrapper!\nclass TableData:\n    def __init__(self,data):\n        self.data = data\n        if(isinstance(self.data,tbl.TableDef)):\n            self.tabledef = True\n        else:\n            self.tabledef = False\n    def Width(self):\n        if(self.tabledef):\n            return self.data.Width()\n        else:\n            return len(self.data[0]) if self.data and len(self.data) > 0 else 0\n    def Height(self):\n        if(self.tabledef):\n            return self.data.Height()\n        else:\n            return len(self.data) if self.data else 0\n    def ForEachRow(self):\n        if(self.tabledef):\n            return self.data.ForEachRow()\n        else:\n            return range(1,self.Height() + 1)\n    def ForEachCol(self):\n        if(self.tabledef):\n            return self.data.ForEachCol()\n        else:\n            return range(1,self.Width() + 1)\n    def GetCell(self,r,c):\n        if(self.tabledef):\n            return tbl.Cell(r,c,self.data).GetVal()\n        else:\n            r -= 1\n            c -= 1\n            if(r >= 0 and r <= self.Height() and c >= 0 and c <= self.Width()):\n                return self.data[r][c]\n            return None\n    @staticmethod\n    def ParseTable(data):\n        if(isinstance(data,str)):\n            data = data.split('\\n')\n        out = []\n        for line in data:\n            lineOut = []\n            cells = line.split('|')\n            for i in range(1,len(cells)-1):\n                c = cells[i].strip()\n                lineOut.append(c)\n            out.append(lineOut)\n        return TableData(out)\n\nclass NoWebRefs:\n    def __init__(self,view):\n        self.refs = {}\n        self.change_count = view.change_count()\n        self.view = view\n\n    def ParseParamsInternal(self,view,pt):\n        row,_ = view.rowcol(pt)\n        language, paramdata, fenceLine = GetModuleAndParams(view,row)\n        if(not language):\n            log.error(\" Could not find language value from source row: \" + str(language))\n            return None\n        log.debug(\" CACHE: {}\".format(fenceLine))\n        p = type('', (), {})() \n        p.s = pt\n        BuildFullParamList(p, language, paramdata)\n        row,_ = view.rowcol(pt)\n        end   = FindEndOfSourceBlock(view,row)\n        if(not end):\n            log.error(\"Could not find the end of the source block! \" + str(end))\n            return None\n        p.refName = p.params.Get('noweb-ref',None)\n        p.at       = pt\n        p.language = language\n        p.end      = end\n        p.start    = row\n        return p\n\n    def ParseParams(self,view,pt):\n        p = self.ParseParamsInternal(view,pt)\n        if(p and p.refName):\n            if(not p.refName in self.refs):\n                self.refs[p.refName] = []\n            self.refs[p.refName].append(p)\n    def Find(self,name):\n        if(name in self.refs):\n            return self.refs[name]\n        else:\n            pt = tbl.LookupNamedSourceBlockInFile(name)\n            if(pt != None):\n                p = self.ParseParamsInternal(self.view,pt)\n                return [p]\n        return None\n\nclass NoWebRefCache:\n    def __init__(self):\n        self.files = {}\n\n    def ParseFile(self,view):\n        filename = view.file_name()\n        if(not filename):\n            return\n        refs = NoWebRefs(view)\n        self.files[filename] = refs\n        last_row = view.endRow()\n        cur      = 0\n        inBlock  = False\n        for r in range(cur,last_row):\n            cur = r\n            pt = view.text_point(r,1)\n            if(not inBlock and IsSourceBlock(view,pt)):\n                refs.ParseParams(view,pt)\n                inBlock = True\n                continue\n            elif(inBlock and IsEndSourceBlock(view,pt)):\n                inBlock = False\n\n    def GetFile(self,view):\n        filename = view.file_name()\n        if(not filename):\n            return None\n        if(not filename in self.files or self.files[filename].change_count < view.change_count()):\n            self.ParseFile(view)\n        return self.files[filename]\n\n\nrefCache = NoWebRefCache()\n\ndef IsSourceBlockStartFence(view,row):\n    line = view.getLine(row)\n    return RE_SRC_BLOCK.search(line)\n\ndef IsSourceBlock(view,at=None):\n    if(None == at):\n        at = view.sel()[0].begin()\n    return (view.match_selector(at,'orgmode.fence.sourceblock') or view.match_selector(at,'orgmode.sourceblock.content'))\n\ndef IsEndSourceBlock(view,at=None):\n    if(None == at):\n        at = view.sel()[0].begin()\n    row,_ = view.rowcol(at)\n    line = view.getLine(row)\n    return RE_END.search(line)\n\n# inline source blocks are inline with the text: src_python[:var x=5]{print('hello'+str(x))}\ndef IsInlineSourceBlock(view,at=None):\n    if(None == at):\n        at = view.sel()[0].begin()\n    return (view.match_selector(at,'orgmode.sourceblock.inline') or view.match_selector(at,'orgmode.sourceblock.content.inline'))\n\ndef IsSourceFence(view,row):\n    #line = view.getLine(view.curRow())\n    line = view.getLine(row)\n    return RE_SRC_BLOCK.search(line) or RE_END.search(line)\n\n\ndef HasFailure(output):\n    os = \" \".join(output)\n    return RE_FAIL.search(os)\n\nRE_TEXT_PREFIX = re.compile(r'^\\s*[:]\\s')\ndef IsPrefixedTextBlob(view,pt):\n    line = view.line(pt)\n    line = view.substr(line)\n    return RE_TEXT_PREFIX.search(line)\n\nclass TextDef:\n    def __init__(self,view=None,pt=None):\n        self.lines = []\n        if(None != view):\n            row,_        = view.rowcol(pt)\n            last_row = view.lastRow()\n            for r in range(row,last_row+1):\n                point = view.text_point(r,0)\n                line = view.line(point)\n                line = view.substr(line)\n                line = RE_TEXT_PREFIX.sub(\"\",line)\n                if(line.strip() == \"\"):\n                    break\n                self.lines.append(line)\n\n    @staticmethod\n    def CreateTextFromText(txt):\n        tdef = TextDef()\n        for t in txt:\n            t = RE_TEXT_PREFIX.sub(\"\",t)\n            tdef.lines.append(t)\n        return tdef\n\ndef ProcessPotentialFileOrgOutput(cmd):\n    outputs = list(filter(None, cmd.outputs)) \n    if(cmd.params and cmd.params.Get('file',None)):\n        out = cmd.params.Get('file',None)\n        if(hasattr(cmd,'output') and cmd.output):\n            if(not out or HasFailure(cmd.output)):\n                out = cmd.output\n        if(out):\n            sourcepath = os.path.dirname(cmd.sourcefile)\n            destFile    = os.path.join(sourcepath,out)\n            destFile = os.path.relpath(destFile, sourcepath)\n            if(out and not HasFailure(outputs)):\n                outputs = []\n            outputs.append(\"[[file:\" + destFile + \"]]\")\n            return outputs,destFile\n\n\ndef BuildFullParamList(cmd,language,cmdArgs,node=None):\n    # First Add from global settings\n    # First Add from PROPERTIES\n    # Global properties are all controlled from our settings file.\n    plist = PList.createPList()\n    # The exclusion list forces replacement of keywords in the plist\n    # Each of these are exclusive.\n    # Collection\n    plist.exList.AddList('results',['output','value'])\n    # Type\n    plist.exList.AddList('results',['table','vector','list','scalar','file', 'verbatim'])\n    # Format\n    plist.exList.AddList('results',['code','drawer','html','latex','link','graphics','org','pp','raw'])\n    # Handling\n    plist.exList.AddList('results',['silent','replace','prepend','append'])\n    # Exports\n    plist.exList.AddList('exports',['code','results','both','none', 'default'])\n    plist.exList.AddBool('cache')\n    plist.exList.AddBool('noweb')\n    plist.exList.AddList('eval',['never','no','query','never-export','no-export','query-export'])\n    defaultPlist = sets.Get(\"orgBabelDefaultHeaderArgs\",\":session none :results replace :exports default :cache no :noweb no\")\n    plist.AddFromPList(defaultPlist)\n    view = None\n    if(node == None):\n        view = sublime.active_window().active_view()\n    if(view or node):\n        plist.AddFromPList(sets.Get('babel-args',None))\n        plist.AddFromPList(sets.Get('babel-args-'+language,None))\n        if(node == None):\n            node = db.Get().AtPt(view,cmd.s)\n        if(node):\n            props = node.get_comment('PROPERTY',None)\n            if(props):\n                for prop in props:\n                    prop = prop.strip()\n                    if(prop.startswith('header-args:' + language + \":\")):\n                        plist.AddFromPList(prop.replace('header-args:'+language+\":\",\"\"))\n                    elif(prop.startswith('header-args:')):\n                        plist.AddFromPList(prop.replace('header-args:',\"\"))\n            pname = 'header-args:' + language\n            if('header-args' in node.properties):\n                #print(str(node.properties['header-args']))\n                plist.AddFromPList(node.properties['header-args'])\n            if(pname in node.properties):\n                plist.AddFromPList(node.properties[pname])\n            if('var' in node.properties):\n                vs = node.properties['var'].strip()\n                plist.Add('var',vs)\n    # At this point we have added all the global properties.\n    # We need to check if there is a header block somewhere near us.\n    if(node):\n        header = node.get_comment(\"HEADER\",None)\n        if(header and view):\n            # We have to scan for it!\n            sr,_ = view.rowcol(cmd.s)\n            for r in range(sr,node.start_row,-1):\n                line = view.getLine(r)\n                if(RE_HEADING.search(line) or RE_END.search(line) or RE_END_PROPERTY_DRAWER.search(line) or RE_TABLE.search(line)):\n                    break\n                m = RE_HEADER_PARAMS.search(line)\n                if(m):\n                    plist.AddFromPList(m.group('params'))\n                    break\n    plist.AddFromPList(cmdArgs)\n    cmd.params = plist\n\n# Determine the output handler to user from our parameters\ndef SetupOutputHandler(cmd,skipFile = False):\n    res = cmd.params.GetStr('results','')\n    if(not skipFile and cmd.params.Has('file')):\n        return FileHandler(cmd,cmd.params)\n    elif(re.search(r'\\btable\\b',res) or re.search(r'\\bvector\\b',res)):\n        return TableHandler(cmd,cmd.params)\n    elif(re.search(r'\\braw\\b',res)):\n        return RawHandler(cmd,cmd.params)\n    elif(re.search(r'\\blist\\b',res)):\n        return ListHandler(cmd,cmd.params)\n    # Verbatim is the default\n    # Scalar is also allowed for this\n    else:\n        return TextHandler(cmd,cmd.params)\n\n# Determine the output formatter to used based on our parameters\ndef SetupOutputFormatter(cmd):\n    res = cmd.params.GetStr('results','')\n    if(re.search(r'\\bdrawer\\b',res)):\n        return DrawerFormatter(cmd)\n    elif(re.search(r'\\bcode\\b', res)):\n        return CodeFormatter(cmd)\n    elif(re.search(r'\\borg\\b', res)):\n        return OrgFormatter(cmd)\n    elif(re.search(r'\\bhtml\\b', res)):\n        return HtmlFormatter(cmd)\n    elif(re.search(r'\\blatex\\b', res)):\n        return LatexFormatter(cmd)\n    # Raw is the default\n    else:\n        return None\n\ndef GetGeneratorForRow(table,params,r):\n    for c in range(1,table.Width()+1):\n        yield table.GetCellText(r,c)\n\ndef GetGeneratorForTable(table,params):\n    for r in range(1,table.Height()+1):\n        yield GetGeneratorForRow(table,params,r)\n\ndef IsOutputEmpty(output):\n    if(output == None):\n        return True\n    if(isinstance(output,str)):\n        return output.strip() == \"\"\n    if(isinstance(output,list)):\n        if(len(output) == 0):\n            return True\n        for o in output:\n            if(o.strip() != \"\"):\n                return False\n        return True\n    return False\n\n# We want to first build up the full list of vars\n# from options, comments, properties and everything else\n#\n# Then any var we want to post process them so they become\n# data sources that reference their various potential\n# locations.\ndef ProcessPossibleSourceObjects(cmd,language,cmdArgs):\n    #BuildFullParamList(cmd,language,cmdArgs)\n    var = cmd.params.Get('var',None)\n    cmd.deferedSources = 0\n    hadDeferred = False\n    if(var):\n        for k in var:\n            n = var[k]\n            if(isinstance(n,tbl.Cell)):\n                n = str(n)\n                var[k] = n\n            if(not util.numberCheck(n)):\n                td = tbl.LookupTableFromNamedObject(n)\n                if(td):\n                    # I think it's better to just pass through the table here.\n                    # Each language may want to do something very different and abstracting away\n                    # What the data source actually is may actually be a disservice\n                    #var[k] = GetGeneratorForTable(td,cmd.params)\n                    var[k] = TableData(td)\n                else:\n                    l = lst.LookupNamedListInFile(n)\n                    if(l):\n                        var[k] = l\n                    else:\n                        pt = tbl.LookupNamedSourceBlockInFile(n)\n                        if(None != pt):\n                            if(not n in cmd.sourcefns):\n                                cmd.deferedSources += 1\n                                hadDeferred = True\n                                cmd.sourcefns[n] = {'at': pt, 'key': k,'name': n}\n                                cmd.view.run_command('org_execute_source_block',{'at':pt, 'onDoneResultsPos': evt.Make(cmd.OnDoneFunction), 'onDoneFnName': n})\n    return hadDeferred\n\nclass ResultsFormatter:\n    def __init__(self,cmd):\n        self.cmd = cmd\n    def SetIndent(self,level):\n        self.level = level\n    def GetIndent(self):\n        return (\" \" * self.level) + \" \"\n    def FormatOutput(self,output):\n        return (output,0)\n\nclass DrawerFormatter(ResultsFormatter):\n    def __init__(self,cmd):\n        super(DrawerFormatter,self).__init__(cmd)\n\n    def FormatOutput(self,output):\n        output = \":results:\\n\" + self.GetIndent() + output + \"\\n\" + self.GetIndent() + \":end:\"\n        return (output,1)\n\nclass CodeFormatter(ResultsFormatter):\n    def __init__(self,cmd):\n        super(CodeFormatter,self).__init__(cmd)\n\n    def FormatOutput(self,output):\n        output = \"#+begin_src \"+self.cmd.language+\"\\n\" + self.GetIndent() + output + \"\\n\" + self.GetIndent() + \"#+end_src\"\n        return (output,1)\n\nclass HtmlFormatter(ResultsFormatter):\n    def __init__(self,cmd):\n        super(HtmlFormatter,self).__init__(cmd)\n\n    def FormatOutput(self,output):\n        output = \"#+begin_src html\\n\" + self.GetIndent() + output + \"\\n\" + self.GetIndent() + \"#+end_src\"\n        return (output,1)\n\nclass LatexFormatter(ResultsFormatter):\n    def __init__(self,cmd):\n        super(LatexFormatter,self).__init__(cmd)\n\n    def FormatOutput(self,output):\n        output = \"#+begin_src latex\\n\" + self.GetIndent() + output + \"\\n\" + self.GetIndent() + \"#+end_src\"\n        return (output,1)\n\nclass OrgFormatter(ResultsFormatter):\n    def __init__(self,cmd):\n        super(OrgFormatter,self).__init__(cmd)\n\n    def FormatOutput(self,output):\n        output = \"#+begin_src org\\n\" + self.GetIndent() + output + \"\\n\" + self.GetIndent() + \"#+end_src\"\n        return (output,1)\n\nclass ResultsHandler:\n    def __init__(self, cmd, params):\n        self.params = params\n        self.cmd    = cmd\n    def SetIndent(self,level):\n        self.level = level\n    def GetIndent(self):\n        if(self.level == 0):\n            return \"\"\n        else:\n            return (\" \" * self.level) + \" \"\n    def FormatOutput(self, output):\n        pass\n    def PostProcess(self, view, outPos, onDone):\n        onDone()\n\nclass TextHandler(ResultsHandler):\n    def __init__(self,cmd,params):\n        super(TextHandler,self).__init__(cmd,params)\n\n    def GetIndent(self):\n        if(self.level == 0):\n            return \"\"\n        if(not self.cmd.outFormatter):\n            return (\" \" * self.level) + \" : \"\n        else:\n            return (\" \" * self.level) + \" \"\n\n    def FormatOutput(self, output):\n        indent = \"\\n\"+ self.GetIndent()\n        be = len(output)-1\n        for i in range(len(output)-1,0,-1):\n            if(output[i].strip() == \"\"):\n                be = i\n            else:\n                break\n        if(be > 0):\n            output = output[0:be]\n        output = indent.join(output).rstrip()\n        output = output.lstrip()\n        if(not self.cmd.outFormatter):\n            return \": \" + output\n        else:\n            return output\n\nclass ListHandler(ResultsHandler):\n    def __init__(self,cmd,params):\n        super(ListHandler,self).__init__(cmd,params)\n\n    def GetIndent(self):\n        if(self.level == 0):\n            return \"- \"\n        return (\" \" * self.level) + \" - \"\n\n    def FormatOutput(self, output):\n        indent = \"\\n\"+ self.GetIndent()\n        # Strip whitespace from the end of this.\n        be = len(output)-1\n        for i in range(len(output)-1,0,-1):\n            if(output[i].strip() == \"\"):\n                be = i\n            else:\n                break\n        if(be > 0):\n            output = output[0:be]\n        # Try to convert AST to list.\n        for i in range(0,len(output)):\n            try:\n                l = ast.literal_eval(output[i])\n                if(isinstance(l,list)):\n                    del output[i]\n                    for r in reversed(l):\n                        output.insert(i,str(r))\n            except:\n                #print(\"EXCEPTION\")\n                #print(traceback.format_exc())\n                pass\n        output = indent.join(output).rstrip()\n        output = output.lstrip()\n        return \"- \" + output\n\nclass RawHandler(ResultsHandler):\n    def __init__(self,cmd,params):\n        super(RawHandler,self).__init__(cmd,params)\n\n    def FormatOutput(self, output):\n        indent = \"\\n\"+ self.GetIndent()\n        be = len(output)-1\n        for i in range(len(output)-1,0,-1):\n            if(output[i].strip() == \"\"):\n                be = i\n            else:\n                break\n        if(be > 0):\n            output = output[0:be]\n        output = indent.join(output).rstrip()\n        output = output.lstrip()\n        return output\n\nclass FileHandler(ResultsHandler):\n    def __init__(self,cmd, params):\n        super(FileHandler,self).__init__(cmd,params)\n\n    def FormatOutput(self, output):\n        out,fname = ProcessPotentialFileOrgOutput(self.cmd)\n        indent = \"\\n\"+ self.GetIndent()\n        rawoutput = output\n        if(not hasattr(self.cmd.curmod,\"GeneratesImages\") or not self.cmd.curmod.GeneratesImages(self)):\n            dn = os.path.dirname(fname)\n            p = os.path.dirname(self.cmd.sourcefile)\n            fp = os.path.join(p,dn)\n            if(fp.strip() != \"\"):\n                os.makedirs(fp, exist_ok=True)\n            ffname = os.path.join(p,fname)\n            with open(ffname,'w') as f:\n                # We setup an output handler for the file.\n                outHandler = SetupOutputHandler(self.cmd, True)\n                outHandler.SetIndent(0)\n                rawoutput = outHandler.FormatOutput(rawoutput)\n                f.write(rawoutput)\n            # TODO Modify file attribs of generated file.\n            #st = os.stat(fname)\n            #os.chmod(fname, st.st_mode | stat.S_IEXEC)\n        output = indent.join(out).rstrip()\n        return output.lstrip()\n\n\nclass TableHandler(ResultsHandler):\n    def __init__(self,cmd,params):\n        super(TableHandler,self).__init__(cmd,params)\n        self.isTable = False\n\n    def FormatOutput(self, output):\n        indent = \"\\n\"+ self.GetIndent()\n        output = indent.join(output).rstrip()\n        if(IsOutputEmpty(output)):\n            return output\n        output,self.isTable = tbl.TableConversion(self.level,output)\n        output = output.strip()\n        return output\n\n    def PostProcess(self, view, outPos, onDone):\n        if(not self.cmd.CheckResultsFor('silent') and None == self.cmd.silent and self.isTable):\n            view.sel().clear()\n            view.sel().add(outPos)\n            view.run_command(\"table_editor_align\")\n            sublime.set_timeout(onDone,1)\n        else:\n            sublime.set_timeout(onDone,1)\n\n\n\nclass OrgExecuteSourceBlockCommand(sublime_plugin.TextCommand):\n    def run(self,edit, onDone=None, onDoneResultsPos=None,onDoneFnName=None,at=None,silent=None,onAdjustParams=None,skipSaveWarning=None,amExporting=False):\n        value = str(uuid.uuid4())\n        self.exc = OrgExecuteSourceBlock(self.view,value)\n        self.exc.run(edit,onDone,onDoneResultsPos,onDoneFnName,at,silent,onAdjustParams,skipSaveWarning,amExporting)\n\n\ndef FormatParam(x):\n    if(x.startswith(\"\\\"\")):\n        x = x[1:]\n    if(x.endswith(\"\\\"\")):\n        x = x[:-1]\n    return x\n\ndef GetDict(strData):\n    rc = {}\n    vals = strData.strip().split(',')\n    for va in vals:\n        if(va.strip() != \"\"):\n            if(\"=\" in va):\n                k,v = va.strip().split('=')\n                rc[k.strip()] = v.strip()\n            else:\n                log.error(\" Params are not valid: \" + str(va))\n    return rc\n\ndef FindEndOfSourceBlock(view,row):\n    end   = None\n    erow  = view.endRow()\n    for rw in range(row,erow+1):\n        line = view.substr(view.line(view.text_point(rw,0)))\n        if(RE_END.search(line)):\n            end = rw\n            break\n    if(not end):\n        log.error(\"Could not locate #+END_SRC tag\")\n        return None\n    return end\n\ndef HasModule(fname):\n    builtInModules = sets.Get(\"builtinSourceBlockHandlers\",[])\n    extensions = ext.find_extension_modules('orgsrc', builtInModules)\n    aliases = sets.Get(\"builtinSourceBlockAliases\",{})\n    if(fname in aliases):\n        fname = aliases[fname]\n    return fname in extensions\n\ndef GetModule(fname):\n    builtInModules = sets.Get(\"builtinSourceBlockHandlers\",[])\n    extensions = ext.find_extension_modules('orgsrc', builtInModules)\n    aliases = sets.Get(\"builtinSourceBlockAliases\",{})\n    if(fname in aliases):\n        fname = aliases[fname]\n    return extensions[fname]\n\ndef GetModuleAndParams(view,row):\n    pt = view.text_point(row,0)\n    line = view.substr(view.line(pt))\n    m = RE_SRC_BLOCK.search(line)\n    if(not m):\n        log.error(\"FAILED TO PARSE SOURCE BLOCK: @\" + str(row) + \" \" + line + \"\\n\" )\n        log.debug(\"FAILURE AT:\\n\"+ '\\n'.join(traceback.format_stack()))\n        return (None, None, None)\n    fnname = m.group('name')\n    log.debug(\"SRC NAME: \" + fnname)\n    paramdata = line[len(m.group(0)):]\n    # Now find me that function!\n    if(not HasModule(fnname)):\n        log.error(\"Function not found in src folder! Cannot execute!\")\n        return (None, None, None)\n    return (fnname,paramdata,line)\n\nRE_FUNCTION=re.compile(r'\\s+[#][+][Cc][Aa][Ll][Ll][:]\\s*(?P<name>[a-zA-Z][a-zA-Z0-9_-]+)\\s*\\((?P<params>[^)]*)\\)')\ndef IsCallCommentBlock(view):\n    line = view.substr(view.line(view.sel()[0]))\n    return RE_FUNCTION.search(line)\n\nclass OrgExecuteCallCommentCommand(sublime_plugin.TextCommand):\n    def run(self,edit,onDone=None):\n        exc = ExecuteCallComment(self.view)\n        exc.run(edit,onDone)\n\nclass ExecuteCallComment:\n    def __init__(self,view):\n        self.view = view\n\n    def OnReplaced(self):\n        evt.EmitIfParams(self.onDone)\n\n    def OnDoneFunction(self,otherParams=None):\n        if('postFormat' in otherParams):\n            postFormat = otherParams['postFormat']\n            self.view.run_command(\"org_internal_replace\", {\"start\": self.resultsStartPt, \"end\": self.resultsEndPt, \"text\": postFormat,\"onDone\": evt.Make(self.OnReplaced)})\n\n    def AdjustParams(self,otherParams=None):\n        if('cmd' in otherParams):\n            cmd = otherParams['cmd']\n            self.cmd = cmd\n            var = cmd.params.Get('var',None)\n            if(var):\n                for k in self.params:\n                    var[k] = self.params[k]\n\n    def run(self,edit, onDone=None):\n        self.onDone = onDone\n        # TODO: Parse Params\n        self.sourcefns      = {}\n        self.deferedSources = 0\n        hasDeferred         = False\n        reg = self.view.sel()[0]\n        row,_ = self.view.rowcol(reg.begin())\n        line = self.view.substr(self.view.line(reg))\n        m = RE_FUNCTION.search(line)\n        if(m):\n            n = m.group('name')\n            ps = m.group('params')\n            self.params = GetDict(ps)\n            pt = tbl.LookupNamedSourceBlockInFile(n)\n            self.s = reg.begin()\n            if(None != pt):\n                self.startRow = row\n                self.endRow   = row\n                FindResults(self,edit,reg.begin(),False)\n                if(not n in self.sourcefns):\n                    self.deferedSources += 1\n                    hadDeferred = True\n                    self.sourcefns[n] = {'at': pt, 'name': n}\n                    self.view.run_command('org_execute_source_block',{'at':pt, 'onDoneResultsPos': evt.Make(self.OnDoneFunction), 'onDoneFnName': n, 'onAdjustParams': evt.Make(self.AdjustParams), 'silent': True})\n\ndef EndResults(self,rw):\n    self.endResults     = rw\n    self.resultsStartPt = self.view.text_point(self.startResults+1,0)\n    self.resultsEndPt   = self.view.text_point(self.endResults,0)\n    self.resultsRegion  = sublime.Region(self.resultsStartPt, self.resultsEndPt)\n\ndef FindResults(self,edit,at,checkSilent=True):\n    self.createdResults = False\n    row              = self.endRow+1\n    fileEndRow,_     = self.view.rowcol(self.view.size())\n    inResults        = False\n    inPropertyDrawer = False\n    inBlock          = False\n    m                = None\n    self.resultsHash        = None\n    for rw in range(row, fileEndRow):\n        line = self.view.substr(self.view.line(self.view.text_point(rw,0)))\n        if(not inResults):\n            m = RE_RESULTS.search(line)\n            if(m):\n                self.resultsHash = m.group('hash')\n                self.startResults = rw\n                inResults = True\n                continue\n        if(RE_FUNCTION.search(line)):\n            if(inResults):\n                EndResults(self,rw)\n                return True\n            else:\n                break\n        # A new heading ends the results.\n        if(RE_HEADING.search(line)):\n            if(inResults):\n                EndResults(self,rw)\n                return True\n            else:\n                break\n        if(RE_PROPERTY_DRAWER.search(line)):\n            if(inResults and not inPropertyDrawer):\n                inPropertyDrawer = True\n                continue\n            else:\n                break\n        if(RE_BLOCK.search(line)):\n            if(inResults and not inBlock):\n                inBlock = True\n                continue\n            else:\n                break\n        if(inResults and not inBlock and not inPropertyDrawer and inResults and RE_IS_BLANK_LINE.search(line)):\n            EndResults(self,rw)\n            return True\n        if(inPropertyDrawer and RE_END_PROPERTY_DRAWER.search(line)):\n            EndResults(self,rw+1)\n            return True\n        if(inBlock and RE_END_BLOCK.search(line)):\n            EndResults(self,rw+1)\n            return True\n    # We just hit the end of the file.\n    if(inResults):\n        EndResults(self,fileEndRow)\n        return True\n    # We hit the end of the file and didn't find a results tag.\n    # We need to make one.\n    if(not inResults):\n        log.debug(\"Could not locate #+RESULTS tag adding one!\")\n        if(self.endRow == self.view.endRow()):\n            pt = self.view.text_point(self.endRow,0)\n            pt = self.view.line(pt).end()\n        else:\n            pt = self.view.text_point(self.endRow,0)\n            pt = self.view.line(pt).end() + 1\n        indent = db.Get().AtPt(self.view,at).indent()\n        if(not checkSilent or not self.CheckResultsFor('silent') and self.silent == None and not self.CheckEval(('no','never'))):\n            self.view.insert(edit, pt, \"\\n\" +indent+ \"#+RESULTS:\\n\")\n        self.startResults   = self.endRow + 2 \n        self.endResults     = self.startResults + 1\n        self.resultsStartPt = self.view.text_point(self.startResults+1,0)\n        self.resultsEndPt   = self.view.text_point(self.endResults,0)\n        self.resultsRegion  = sublime.Region(self.resultsStartPt, self.resultsEndPt)\n        self.createdResults = True\n        return True\n# ============================================================\nclass OrgExecuteSourceBlock:\n\n    def __init__(self,view,id):\n        self.id = id\n        self.view = view\n\n    def CheckResultsFor(self,val):\n        res = self.params.Get('results',[])\n        return (val in res)\n    \n    def CheckEval(self,val):\n        evalParam = self.params.Get('eval',[])\n        if(isinstance(val,list) or isinstance(val,tuple)):\n            for x in val:\n                if( x in evalParam):\n                    return True\n        else:\n            if(val in evalParam):\n                return True\n        return False\n\n    def OnDone(self):\n        evt.EmitIf(self.onDone)\n        if(self.silent != None):\n            evt.EmitIfParams(self.onDoneResultsPos,postFormat=self.formattedOutput,preFormat=self.preFormattedOutput,name=self.onDoneFnName)\n        else:\n            self.resultsTxtStart = self.view.text_point(self.resultsTxtStartRow,self.resultsTxtStartCol)\n            evt.EmitIfParams(self.onDoneResultsPos,pos=self.resultsTxtStart,name=self.onDoneFnName)\n\n    def OnPostProcess(self):\n        self.curPt = self.view.sel()[0]\n        self.resultsTxtStart = self.view.text_point(self.resultsTxtStartRow,self.resultsTxtStartCol)\n        self.outHandler.PostProcess(self.view, self.resultsTxtStart, self.OnPostPostProcess)\n\n    def OnPostPostProcess(self):\n        if(hasattr(self.curmod,\"GeneratesImages\") and self.curmod.GeneratesImages(self)):\n            self.view.run_command(\"org_cycle_images\",{\"onDone\": evt.Make(self.OnDone)})\n        else:\n            self.OnDone()\n\n    def OnReplaced(self):\n        if(hasattr(self.curmod,\"PostExecute\")):\n            self.curmod.PostExecute(self)\n        self.OnPostProcess()\n\n    def OnWarningSaved(self):\n        if(self.view.is_dirty()):\n            self.view.set_status(\"Error: \",\"Failed to save the view. ABORT, cannot execute source block since it is dirty\")\n            log.error(\"Failed to save the view. ABORT, cannot execute source code\")\n            return\n        self.view.run_command(\"org_execute_source_block\", {\"onDone\": self.onDone})\n\n    def run(self, edit, onDone=None, onDoneResultsPos=None,onDoneFnName=None,at=None,silent=None,onAdjustParams=None,skipSaveWarning=None,amExporting=False):\n        self.onDone = onDone\n        self.onDoneResultsPos = onDoneResultsPos\n        self.onDoneFnName=onDoneFnName\n        self.silent = silent\n        self.onAdjustParams = onAdjustParams\n        self.amExporting = amExporting\n        self.resultsTxtStartRow = 0\n        self.resultsTxtStartCol = 0\n        view = self.view\n        if(at == None):\n            at = view.sel()[0].begin()\n        row = 0\n        if(IsSourceBlock(view,at)):\n            #if(view.match_selector(at,'orgmode.fence.sourceblock') or view.match_selector(at,'orgmode.sourceblock.content')):\n            # Scan up till we find the start of the block.\n            row,_ = view.rowcol(at)\n            while(row > 0):\n                if(IsSourceFence(view, row)):\n                    at = sublime.Region(view.text_point(row,1),view.text_point(row,1))\n                    break\n                row -= 1\n            # Okay we have a dynamic block, now we need to know where it ends.\n            start = at\n            end   = FindEndOfSourceBlock(view,row)\n            if(not end):\n                log.error(\"Could not find end of source block\")\n                self.OnDone()\n                return\n\n            # Okay now we have a start and end to build a region out of.\n            # time to run a command and try to get the output.\n            self.language, self.paramdata, fenceLine = GetModuleAndParams(view,row)\n            if(not self.language):\n                self.OnDone()\n                return\n\n            # Start setting up our execution state.\n            self.curmod   = GetModule(self.language)\n            self.startRow = row + 1\n            self.endRow   = end\n            self.s        = view.text_point(self.startRow,0)\n            self.e        = view.text_point(self.endRow,0)\n            self.region   = sublime.Region(self.s,self.e)\n            self.sourcefile = view.file_name()\n            self.sourcefns = {}\n            # Sanity check that the file exists on disk\n            if(not self.sourcefile or not os.path.exists(self.sourcefile)):\n                self.view.set_status(\"Error: \",\"Your source org file must exist on disk. ABORT.\")\n                log.error(\"Your source org file must exist on disk to generate images. The path is used when setting up relative paths.\")\n                self.OnDone()\n                return\n            if(not skipSaveWarning and view.is_dirty()):\n                log.warning(\"Your source file has unsaved changes. We cannot run source modifications without saving the buffer.\")\n                view.run_command(\"save\", {\"async\": False})\n                sublime.set_timeout(self.OnWarningSaved,1)\n                return\n            BuildFullParamList(self,self.language,self.paramdata)\n            # We need to find and or buid a results block\n            # so we can replace it with the results.\n            # ORG is super flexible about this, we are NOT!\n            FindResults(self,edit,self.s)\n            # TODO: Early out if this is a chain and we have already computed our\n            #       results.\n            self.source = None\n            if(self.params.GetBool('noweb')):\n                self.NoWebPhase()\n            else:\n                self.ParamsPhase()\n        else:\n            log.error(\"NOT in A Source Block, nothing to run, place cursor on first line of source block\")\n\n    # Each remote noweb call will hit this when complete. We integrate the results\n    # back into our source block that we are constructing.\n    def NoWebSourceDone(self,otherParams=None):\n        self.deferredNoWeb -= 1\n        name = otherParams['name']\n        res = self.nowebfn[name]\n        result = res['result']\n        r      = res['r']\n        idx    = res['idx']\n        # Insert the output from our execution into our results\n        if('preFormat' in otherParams):\n            preFormat = otherParams['preFormat']\n            result[idx] = preFormat\n        # Paste our results into our source block where it belongs line by line\n        if(len(result) > 0):\n            self.source[r] = result[0]\n            result = result[1:]\n            if(len(result) > 0):\n                for i in range(len(result)):\n                    self.source.insert(r+i+1,result[i])\n        # If this was the LAST source block executing then join up our source block\n        # and prepare for the full parameters phase!\n        if(self.deferredNoWeb <= 0):\n            self.source = '\\n'.join(self.source)\n            self.ParamsPhase()\n    \n    # NoWeb <<my-function(x=1) calls another block but\n    # with different params. This adjusts those params\n    # during the remote call.\n    def NoWebAdjustParams(self,otherParams=None):\n        # Punch our noweb parameters into the remote blocks\n        # parameter list!\n        if('cmd' in otherParams):\n            cmd = otherParams['cmd']\n            var = cmd.params.Get('var',None)\n            name = otherParams['name']\n            if(var and name in self.nowebfn):\n                res = self.nowebfn[name]\n                ps  = res['ps']\n                if(ps): \n                    params = GetDict(ps)\n                    for k in params:\n                        var[k] = params[k]\n\n    # If the :noweb yes param is turned on \n    # Then we need to replace any <<NAME>> blocks\n    # in our source code.\n    def NoWebPhase(self):\n        self.deferredNoWeb = 0\n        self.nowebfn = {}\n        sp = self.view.text_point(self.startRow,0)\n        ep = self.view.line(self.view.text_point(self.endRow,0)).end()\n        myRegion = sublime.Region(sp,ep)\n        self.source = self.view.substr(self.region).split('\\n')\n        hadAnyDeferred = False\n        for r in range(len(self.source)-1,-1,-1):\n            txt = self.source[r]\n            m = RE_NOWEB.search(txt)\n            if(m):\n                ps = m.group('params')\n                if(None != ps):\n                    continue\n                nw = m.group('noweb')\n                href = refCache.GetFile(self.view)\n                ref = href.Find(nw)\n                if(ref):\n                    result = []\n                    for rr in ref:\n                        s = self.view.text_point(rr.start+1,0)\n                        e = self.view.line(self.view.text_point(rr.end-1,0)).end()\n                        if(myRegion.contains(s)):\n                            continue\n                        cpFrom = self.view.substr(sublime.Region(s,e))\n                        result.append(cpFrom.rstrip())\n                    if(len(result) > 0):\n                        self.source[r] = result[0]\n                        result = result[1:]\n                        if(len(result) > 0):\n                            for i in range(len(result)):\n                                self.source.insert(r+i+1,result[i])\n                else:\n                    log.error(\" NoWeb: No match for reference\")\n        for r in range(len(self.source)-1,-1,-1):\n            txt = self.source[r]\n            m = RE_NOWEB.search(txt)\n            if(m):\n                ps = m.group('params')\n                if(ps == None):\n                    continue\n                href = refCache.GetFile(self.view)\n                nw = m.group('noweb')\n                ref = href.Find(nw)\n                if(ref):\n                    result = []\n                    for rr in ref:\n                        hadAnyDeferred = True\n                        self.deferredNoWeb += 1\n                        # Reserve a slot to insert into!\n                        idx = len(result)\n                        result.append(\"\")\n                        name = 'result_' + str(idx) + '_' + str(r)\n                        self.nowebfn[name] = {'idx': idx, 'result': result,'r': r, 'ps': ps}\n                        self.view.run_command('org_execute_source_block',{'at':rr.at, 'silent': True, 'onDoneResultsPos': evt.Make(self.NoWebSourceDone),\"onAdjustParams\": evt.Make(self.NoWebAdjustParams), 'onDoneFnName': name})\n                else:\n                    log.error(\" NoWeb: No match for reference\")\n        if(not hadAnyDeferred):\n            self.source = '\\n'.join(self.source)\n            self.ParamsPhase()\n\n    # We have parameters BUT we do not have the full story\n    # There are elements in there that may require deferred execution!\n    #\n    # Also these are OUR params not necessarily the ones from our caller if we are\n    # being evaluated from a call.\n    # \n    #   ParamPhase --> #+CALL::onAdjustParams() // set my params from your scope\n    #\n    #   ProcessPossibleSourceObjects --> Evaluate other source blocks\n    #                                          |\n    #            OnDoneFunction     <---------+\n    def ParamsPhase(self):\n            view = self.view\n            # Turn our variable table into a dictionary\n            var = self.params.GetDict('var',None)\n            if(var):\n                self.params.Replace('var',var)\n            # If we are being called from elsewhere let the caller adjust our parameter list\n            evt.EmitIfParams(self.onAdjustParams,cmd=self,name=self.onDoneFnName)\n            # Setup formatting and parameters now that we have execution state. \n            if(ProcessPossibleSourceObjects(self,self.language,self.paramdata)):\n                # We are deferred! We do not continue form here!\n                return\n            else:\n                self.QueryCheckExecute()\n\n    def AmExporting(self):\n        return self.amExporting\n\n    # We may not want to execute. This is a barrier to ACTUALLY executing this block!\n    # We support querying the user and just bailing if need be.\n    def QueryCheckExecute(self):\n        if(self.CheckEval('query') or (self.CheckEval('query-export') and self.AmExporting())):\n            if(sublime.DIALOG_YES == sublime.yes_no_cancel_dialog(\"Should we execute\", \"Yes Please\", \"No Thank You\")):\n                self.Execute()\n            else:\n                self.resultsTxtStartRow, self.resultsTxtStartCol = self.view.rowcol(self.resultsStartPt)\n                self.OnDone()\n        else:\n            self.Execute()\n\n    # Param() - paramters referencing other source blocks will call this back\n    #           when evaluation is complete.\n    def OnDoneFunction(self,otherParams=None):\n        #results = otherParams['results']\n        name    = otherParams['name']\n        # Process the source here!\n        var = self.params.Get('var',None) \n        fn = self.sourcefns[name]\n        # Our goal is determine what is at results location\n        # convert it and insert it into var.\n        if('pos' in otherParams):\n            pos = otherParams['pos']\n            if(tbl.isTable(self.view,pos)):\n                td = tbl.create_table(self.view, pos)\n                var[fn['key']] = TableData(td)\n            else:\n                l = lst.IfListExtract(self.view, pos)\n                if(l):\n                    var[fn['key']] = l\n                else:\n                    # Assume blank text\n                    txt = TextDef(self.view,pos)\n                    l = \"\\n\".join(txt.lines)\n                    l = l.strip()\n                    var[fn['key']] = l\n        # We didn't output, so we have to parse the contents\n        # but not from the buffer\n        if('preFormat' in otherParams):\n            preFormat = otherParams['preFormat']\n            preFormat1 = preFormat.split('\\n')\n            preFormat = []\n            for l in preFormat1:\n                preFormat.append(l.strip())\n            if(lst.isListLine(preFormat[0])):\n                l = lst.ListData.CreateListFromList(preFormat)\n                var[fn['key']] = l\n            elif(tbl.isTableLine(preFormat[0])):\n                td = TableData.ParseTable(preFormat)\n                var[fn['key']] = td\n            else:\n                t = TextDef.CreateTextFromText(preFormat)\n                l = \"\\n\".join(t.lines)\n                l = l.strip()\n                var[fn['key']] = l\n            pass\n        # TODO: Handle lists, text and other things.\n        self.deferedSources -= 1\n        if(self.deferedSources <= 0):\n            FindResults(self,0,self.s)\n            self.QueryCheckExecute()\n\n    def OnCached(self):\n        self.formattedOutput    = self.view.substr(self.resultsRegion)\n        self.preFormattedOutput = self.formattedOutput\n        res = self.formattedOutput.split('\\n')\n        if(len(res) >= 2):\n            if(re.search(r\"\\s*(([:]results[:])|[#][+]begin_)\",res[0])):\n                self.preFormattedOutput = '\\n'.join(res[1:-1])\n        ## Keep track of this so we know where we are inserting the text.\n        self.OnReplaced()\n\n    def Execute(self):\n            view = self.view\n            self.outHandler   = SetupOutputHandler(self)\n            self.outFormatter = SetupOutputFormatter(self)\n            self.hashVal      = None\n            # Compute our expected results location. We may need to adjust\n            # it based on formatting later though.\n            n                 = db.Get().AtPt(view,self.s)\n            self.level        = n.level\n            self.resultsTxtStartRow, self.resultsTxtStartCol = self.view.rowcol(self.resultsStartPt + self.level + 1)\n\n            # If we have a never eval param this block is NOT ALLOWED\n            # to be executed! So we bail!\n            if(self.CheckEval(('no','never'))):\n                self.OnDone()\n                return\n\n            # Run the \"writer\"\n            self.outputs = \"Did not execute, something is wrong!\"\n            if(hasattr(self.curmod,\"Execute\")):\n                # Okay now time to replace the contents of the block\n                if(self.source == None):\n                    self.source = view.substr(self.region)\n                if(hasattr(self.curmod,\"PreProcessSourceFile\")):\n                    self.curmod.PreProcessSourceFile(self)\n                if(self.params.GetBool('cache')):\n                    self.hashVal = hashlib.sha1(bytes(self.source,'utf-8')).hexdigest()\n                    if(self.hashVal == self.resultsHash):\n                        log.warning(' Hash matches, skipping execution')\n                        self.OnCached()\n                        return\n                    #print(self.hashVal)\n                # Is this a file backed execution?\n                if(hasattr(self.curmod,\"Extension\")):\n                    tmp = tempfile.NamedTemporaryFile(delete=False,suffix=self.curmod.Extension(self))\n                    try:\n                        self.filename = tmp.name\n                        if(hasattr(self.curmod,\"WrapStart\")):\n                            tmp.write((self.curmod.WrapStart(self) + \"\\n\").encode(\"ascii\"))\n                        tmp.write(self.source.encode('ascii'))\n                        if(hasattr(self.curmod,\"WrapEnd\")):\n                            tmp.write((\"\\n\" + self.curmod.WrapEnd(self)).encode(\"ascii\"))\n                        tmp.close() \n                        self.outputs = self.curmod.Execute(self,sets)\n                    except:\n                        log.debug(\" \" + traceback.format_exc())\n                    finally:\n                        pass\n                # This is an inline execution\n                else:\n                    self.filename = None\n                    self.outputs = self.curmod.Execute(self,sets)\n                log.debug(\"OUTPUT: \" + str(self.outputs))\n            else:\n                log.error(\"No execute in module, abort\")\n                return\n            # Reformat adding indents to each line!\n            # No bad formatting allowed!\n            self.outHandler.SetIndent(n.level)\n            if(self.outFormatter):\n                self.outFormatter.SetIndent(n.level)\n            output = self.outHandler.FormatOutput(self.outputs)\n            self.preFormattedOutput = output\n            rowadjust = 0\n            if(self.outFormatter):\n                output,rowadjust = self.outFormatter.FormatOutput(output)\n            # If our formatter wrapped us we have to adjust our text point for post processing\n            # and results text.\n            if(rowadjust > 0):\n                self.resultsTxtStartRow += rowadjust\n            ## Keep track of this so we know where we are inserting the text.\n            self.formattedOutput = (\" \" * self.level + \" \") + output+'\\n'\n            if(self.CheckResultsFor('silent') or self.silent == True):\n                # We only echo to the console in silent mode.\n                print(self.formattedOutput)\n                self.silent = True\n                self.OnReplaced()\n            # Add after other text\n            elif(self.CheckResultsFor('append')):\n                self.view.run_command(\"org_internal_replace\", {\"start\": self.resultsEndPt, \"end\": self.resultsEndPt, \"text\": self.formattedOutput,\"onDone\": evt.Make(self.OnReplaced)})\n            # Add before other text\n            elif(self.CheckResultsFor('prepend')):\n                self.view.run_command(\"org_internal_replace\", {\"start\": self.resultsStartPt, \"end\": self.resultsStartPt, \"text\": self.formattedOutput,\"onDone\": evt.Make(self.OnReplaced)})\n            # Replace mode\n            else:\n                # Hash means we have to update the hash!\n                if(self.hashVal):\n                    row,col = view.rowcol(self.resultsStartPt)\n                    row -= 1\n                    self.resultsStartPt = view.text_point(row,col)\n                    self.formattedOutput = (\" \" * self.level + \" \") + \"#+RESULTS[{}]:\\n\".format(self.hashVal) + self.formattedOutput\n                self.view.run_command(\"org_internal_replace\", {\"start\": self.resultsStartPt, \"end\": self.resultsEndPt, \"text\": self.formattedOutput,\"onDone\": evt.Make(self.OnReplaced)})\n\n# ============================================================\nclass OrgExecuteInlineSourceBlock:\n\n    def __init__(self,view,id):\n        self.id = id\n        self.view = view\n\n    def FindInlineResults(self):\n        self.startResults   = self.row\n        self.endResults     = self.row\n        if(self.m.group('resblock')):\n            self.resultsStartPt = self.view.text_point(self.row, self.m.start('resblock'))\n            self.resultsEndPt   = self.view.text_point(self.row, self.m.end('resblock'))\n            self.resultsRegion  = sublime.Region(self.resultsStartPt, self.resultsEndPt)\n            self.createdResults = False\n        else:\n            self.resultsStartPt = self.view.text_point(self.row, self.m.end('code') + 1)\n            self.resultsEndPt   = self.view.text_point(self.row, self.m.end('code') + 1)\n            self.resultsRegion  = sublime.Region(self.resultsStartPt, self.resultsEndPt)\n            self.createdResults = True\n\n    def CheckResultsFor(self,val):\n        res = self.params.Get('results',[])\n        return (val in res)\n\n    def OnDone(self):\n        evt.EmitIf(self.onDone)\n        if(self.silent != None):\n            evt.EmitIfParams(self.onDoneResultsPos,postFormat=self.formattedOutput,preFormat=self.preFormattedOutput,name=self.onDoneFnName)\n        else:\n            self.resultsTxtStart = self.view.text_point(self.resultsTxtStartRow,self.resultsTxtStartCol)\n            evt.EmitIfParams(self.onDoneResultsPos,pos=self.resultsTxtStart,name=self.onDoneFnName)\n\n    def OnPostProcess(self):\n        self.curPt = self.view.sel()[0]\n        self.resultsTxtStart = self.view.text_point(self.resultsTxtStartRow,self.resultsTxtStartCol)\n        self.outHandler.PostProcess(self.view, self.resultsTxtStart, self.OnPostPostProcess)\n\n    def OnPostPostProcess(self):\n        if(hasattr(self.curmod,\"GeneratesImages\") and self.curmod.GeneratesImages(self)):\n            self.view.run_command(\"org_cycle_images\",{\"onDone\": evt.Make(self.OnDone)})\n        else:\n            self.OnDone()\n\n    def OnReplaced(self):\n        if(hasattr(self.curmod,\"PostExecute\")):\n            self.curmod.PostExecute(self)\n        self.OnPostProcess()\n\n    def OnWarningSaved(self):\n        if(self.view.is_dirty()):\n            self.view.set_status(\"Error: \",\"Failed to save the view. ABORT, cannot execute source block since it is dirty\")\n            log.error(\"Failed to save the view. ABORT, cannot execute source code\")\n            return\n        self.view.run_command(\"org_execute_inline_source_block\", {\"onDone\": self.onDone})\n\n    def run(self, edit, onDone=None, onDoneResultsPos=None,onDoneFnName=None,at=None,silent=None,onAdjustParams=None,skipSaveWarning=None):\n        self.onDone           = onDone\n        self.onDoneResultsPos = onDoneResultsPos\n        self.onDoneFnName     =onDoneFnName\n        self.silent = silent\n        self.onAdjustParams = onAdjustParams\n        view = self.view\n        if(at == None):\n            at = view.sel()[0].begin()\n        if(IsInlineSourceBlock(view,at)):\n            # Scan up till we find the start of the block.\n            row,col = view.rowcol(at)\n            line = view.getLine(row)\n            self.m = None\n            for tm in RE_INL_SRC_BLOCK.finditer(line):\n                if(tm.start('block') <= col and tm.end('block') >= col):\n                    self.m = tm\n                    break\n            if(self.m == None):\n                log.warning(\"Failed to execute inline script block could not locate bounds\")\n                return\n            \n            start = self.m.start('code')\n            end   = self.m.end('code') \n\n            self.paramdata = tm.group('params')\n            self.language  = tm.group('name')\n            self.row       = row\n\n            # Okay now we have a start and end to build a region out of.\n            # time to run a command and try to get the output.\n            if(not HasModule(self.language)):\n                log.error(\"Function not found in src folder! Cannot execute!\")\n                self.OnDone()\n                return\n\n            # Start setting up our execution state.\n            self.curmod   = GetModule(self.language)\n            self.startRow = row\n            self.endRow   = row\n            self.s        = view.text_point(row,start)\n            self.e        = view.text_point(row,end)\n            self.region   = sublime.Region(self.s,self.e)\n            self.sourcefile = view.file_name()\n            self.sourcefns = {}\n            # Sanity check that the file exists on disk\n            if(not self.sourcefile or not os.path.exists(self.sourcefile)):\n                self.view.set_status(\"Error: \",\"Your source org file must exist on disk. ABORT.\")\n                log.error(\"Your source org file must exist on disk to generate images. The path is used when setting up relative paths.\")\n                self.OnDone()\n                return\n            if(not skipSaveWarning and view.is_dirty()):\n                log.warning(\"Your source file has unsaved changes. We cannot run source modifications without saving the buffer.\")\n                view.run_command(\"save\", {\"async\": False})\n                sublime.set_timeout(self.OnWarningSaved,1)\n                return\n            BuildFullParamList(self,self.language,self.paramdata)\n            # We need to find and or buid a results block\n            # so we can replace it with the results.\n            # ORG is super flexible about this, we are NOT!\n            self.FindInlineResults()\n            self.ParamsPhase()\n        else:\n            log.error(\"NOT in A Source Block, nothing to run, place cursor on first line of source block\")\n\n    # We have parameters BUT we do not have the full story\n    # There are elements in there that may require deferred execution!\n    #\n    # Also these are OUR params not necessarily the ones from our caller if we are\n    # being evaluated from a call.\n    # \n    #   ParamPhase --> #+CALL::onAdjustParams() // set my params from your scope\n    #\n    #   ProcessPossibleSourceObjects --> Evaluate other source blocks\n    #                                          |\n    #            OnDoneFunction     <---------+\n    def ParamsPhase(self):\n            view = self.view\n            # Turn our variable table into a dictionary\n            var = self.params.GetDict('var',None)\n            if(var):\n                self.params.Replace('var',var)\n            # If we are being called from elsewhere let the caller adjust our parameter list\n            evt.EmitIfParams(self.onAdjustParams,cmd=self)\n            # Setup formatting and parameters now that we have execution state. \n            if(ProcessPossibleSourceObjects(self,self.language,self.paramdata)):\n                # We are deferred! We do not continue form here!\n                return\n            else:\n                self.Execute()\n    # Param() - paramters referencing other source blocks will call this back\n    #           when evaluation is complete.\n    def OnDoneFunction(self,otherParams=None):\n        #results = otherParams['results']\n        name    = otherParams['name']\n        #print(\"DONE: \" + str(results))\n        #print(\"DONE2: \" + str(name))\n        #print(\"SOURCES: \" + str(self.sourcefns))\n        # Process the source here!\n        var = self.params.Get('var',None) \n        fn = self.sourcefns[name]\n        # Our goal is determine what is at results location\n        # convert it and insert it into var.\n        if('pos' in otherParams):\n            pos = otherParams['pos']\n            if(tbl.isTable(self.view,pos)):\n                td = tbl.create_table(self.view, pos)\n                var[fn['key']] = TableData(td)\n            else:\n                l = lst.IfListExtract(self.view, pos)\n                if(l):\n                    var[fn['key']] = l\n                else:\n                    # Assume blank text\n                    txt = TextDef(self.view,pos)\n                    l = \"\\n\".join(txt.lines)\n                    l = l.strip()\n                    var[fn['key']] = l\n        # We didn't output, so we have to parse the contents\n        # but not from the buffer\n        if('preFormat' in otherParams):\n            preFormat = otherParams['preFormat']\n            preFormat1 = preFormat.split('\\n')\n            preFormat = []\n            for l in preFormat1:\n                preFormat.append(l.strip())\n            if(lst.isListLine(preFormat[0])):\n                l = lst.ListData.CreateListFromList(preFormat)\n                var[fn['key']] = l\n            elif(tbl.isTableLine(preFormat[0])):\n                td = TableData.ParseTable(preFormat)\n                var[fn['key']] = td\n            else:\n                t = TextDef.CreateTextFromText(preFormat)\n                l = \"\\n\".join(t.lines)\n                l = l.strip()\n                var[fn['key']] = l\n            pass\n        # TODO: Handle lists, text and other things.\n        self.deferedSources -= 1\n        if(self.deferedSources <= 0):\n            self.FindInlineResults()\n            self.Execute()\n    def Execute(self):\n            view = self.view\n            self.outHandler   = RawHandler(self, self.params)\n\n            if(hasattr(self.curmod,\"Execute\")):\n                # Okay now time to replace the contents of the block\n                self.source = view.substr(self.region)\n                if(hasattr(self.curmod,\"PreProcessSourceFile\")):\n                    self.curmod.PreProcessSourceFile(self)\n                if(hasattr(self.curmod,\"Extension\")):\n                    tmp = tempfile.NamedTemporaryFile(delete=False,suffix=self.curmod.Extension(self))\n                    try:\n                        self.filename = tmp.name\n                        if(hasattr(self.curmod,\"WrapStart\")):\n                            tmp.write((self.curmod.WrapStart(self) + \"\\n\").encode(\"ascii\"))\n                        tmp.write(self.source.encode('ascii'))\n                        if(hasattr(self.curmod,\"WrapEnd\")):\n                            tmp.write((\"\\n\" + self.curmod.WrapEnd(self)).encode(\"ascii\"))\n                        tmp.close() \n                        self.outputs = self.curmod.Execute(self,sets)\n                    except:\n                        log.debug(\" \" + traceback.format_exc())\n                    finally:\n                        pass\n                else:\n                    self.filename = None\n                    self.outputs = self.curmod.Execute(self,sets)\n                log.debug(\"OUTPUT: \" + str(self.outputs))\n            else:\n                log.error(\"No execute in module, abort\")\n                return\n            self.level = 0\n            self.outHandler.SetIndent(0)\n            output = self.outHandler.FormatOutput(self.outputs)\n            self.preFormattedOutput = output\n            self.resultsTxtStartRow,self.resultsTxtStartCol = self.view.rowcol(self.resultsStartPt)\n            self.resultsTxtStart = self.resultsStartPt\n            self.formattedOutput = \" {{{results(=\" + output.replace(\"\\n\",\"\") + \"=)}}} \"\n            if(self.CheckResultsFor('silent') or self.silent == True):\n                # We only echo to the console in silent mode.\n                print(str(output))\n                self.silent = True\n                self.OnReplaced()\n            # We only support replace mode for inline source blocks\n            self.view.run_command(\"org_internal_replace\", {\"start\": self.resultsStartPt, \"end\": self.resultsEndPt, \"text\": self.formattedOutput,\"onDone\": evt.Make(self.OnReplaced)})\n\n# ================================================================================\nclass OrgExecuteInlineSourceBlockCommand(sublime_plugin.TextCommand):\n    def run(self,edit, onDone=None, onDoneResultsPos=None,onDoneFnName=None,at=None,silent=None,onAdjustParams=None,skipSaveWarning=None):\n        value = str(uuid.uuid4())\n        self.exc = OrgExecuteInlineSourceBlock(self.view,value)\n        self.exc.run(edit,onDone,onDoneResultsPos,onDoneFnName,at,silent,onAdjustParams,skipSaveWarning)\n\n# ================================================================================\nclass OrgExecuteAllSourceBlocksCommand(sublime_plugin.TextCommand):\n    def ContinueRun(self):\n        # I have to go bottom to top \n        for r in range(self.cur,0,-1):\n            self.cur = r\n            pt = self.view.text_point(r,0)\n            line = self.view.line(pt)\n            txt = self.view.substr(line)\n            if(self.inBlock and IsSourceBlockStartFence(self.view,r)):\n                self.cur -= 1\n                self.view.run_command('org_execute_source_block',{\"at\":pt,\"onDone\":evt.Make(self.ContinueRun),\"amExporting\":self.amExporting,\"skipSaveWarning\": True})\n                self.inBlock = False\n                break\n            elif(not self.inBlock and IsEndSourceBlock(self.view,pt)):\n                self.inBlock = True\n        if(self.cur <= 1):\n            evt.EmitIf(self.onDone)\n\n    def run(self,edit,at=None,onDone=None,amExporting=False):\n        # Do we want to avoid re-execution?\n        self.last_row = self.view.endRow()\n        self.cur = self.last_row\n        self.inBlock = False\n        self.onDone = onDone\n        self.amExporting = amExporting\n        self.ContinueRun()\n\n\n\n# ================================================================================\nclass OrgTangleFileCommand(sublime_plugin.TextCommand):\n    def OnDone(self):\n        evt.EmitIf(self.onDone)\n\n    def CheckResultsFor(self,val):\n        res = self.params.Get('results',[])\n        return (val in res)\n\n    def ParseFile(self,at):\n        view = self.view\n        if(IsSourceBlock(view,at)):\n            filename = self.view.file_name()\n\n            # Okay we have a dynamic block, now we need to know where it ends.\n            start   = at\n            row,col = view.rowcol(at)\n            end = FindEndOfSourceBlock(view,row)\n            if(not end):\n                return\n            # Okay now we have a start and end to build a region out of.\n            # time to run a command and try to get the output.\n            self.language, self.paramdata, fenceLine = GetModuleAndParams(view,row)\n            if(not self.language):\n                return\n\n            log.debug(\" TANGLE: {}\".format(fenceLine))\n\n            # Start setting up our execution state.\n            self.curmod   = GetModule(self.language)\n            self.startRow = row + 1\n            self.endRow   = end\n            self.s        = view.text_point(self.startRow,0)\n            self.e        = view.text_point(self.endRow,0)\n            self.region   = sublime.Region(self.s,self.e)\n            self.sourcefile = view.file_name()\n            self.sourcefns = {}\n            # We mark as silent so we don't execute here.\n            self.silent    = True\n            BuildFullParamList(self,self.language,self.paramdata)\n            #FindResults(self,edit,self.s)\n            var = self.params.GetDict('var',None)\n            if(var):\n                self.params.Replace('var',var)\n            #if(self.CheckEval(('no','never'))):\n            #    return\n            if(not self.params.Get('tangle',None) or not self.params.GetBool('tangle')):\n                return\n            # Run the \"writer\"\n            if(hasattr(self.curmod,\"Execute\")):\n                # Okay now time to replace the contents of the block\n                self.source = view.substr(self.region)\n                self.source = re.sub(r\"^(\\s+)(.*)$\",\n                    lambda m: re.sub(\"^\" + \" \"*len(m.group(1)),\"\",m.group(2),flags=re.MULTILINE)\n                    ,self.source,flags=re.MULTILINE|re.DOTALL)\n                if(hasattr(self.curmod,\"PreProcessSourceFile\")):\n                    self.curmod.PreProcessSourceFile(self)\n                # Is this a file backed execution?\n                if(hasattr(self.curmod,\"Extension\")):\n                    filename = os.path.splitext(filename)[0]+self.curmod.Extension(self)\n                    try:\n                        if(hasattr(self.curmod,\"WrapStart\")):\n                            self.source = ((self.curmod.WrapStart(self) + \"\\n\").encode(\"ascii\")) + self.source\n                        if(hasattr(self.curmod,\"WrapEnd\")):\n                            self.source += ((\"\\n\" + self.curmod.WrapEnd(self)).encode(\"ascii\"))\n                    except:\n                        log.debug(\" \" + traceback.format_exc())\n                else:\n                    filename = os.path.splitext(filename)[0]+\".py\"\n                comStart = None\n                if(hasattr(self.curmod,\"LineCommentPrefix\")):\n                    comStart = self.curmod.LineCommentPrefix()\n                    temp = \"\\n{} -- Line: {}\\n\".format(comStart,str(self.startRow))\n                    self.source = temp + self.source\n\n                if(not filename in self.fileData):\n                    if(comStart):\n                        dt = datetime.datetime.now()\n                        dateString = dt.strftime(\"%Y %m %d %a %H:%M\")\n                        temp = \"{} Generated From: {}\\n{} Author: {}\\n{} Date: {}\\n\".format(comStart,view.file_name(),comStart,getpass.getuser(),comStart,dateString)\n                        self.source = temp + self.source\n                    self.fileData[filename] = self.source\n                else:\n                    self.fileData[filename] += self.source\n                #log.debug(\"TANGLE: \" + str(self.source)\n        else:\n            log.error(\"NOT in A Source Block, nothing to run, place cursor on first line of source block\")\n\n    def ContinueRun(self):\n        for r in range(self.cur,self.last_row):\n            self.cur = r\n            pt = self.view.text_point(r,1)\n            if(not self.inBlock and IsSourceBlock(self.view,pt)):\n                self.ParseFile(pt)\n                self.inBlock = True\n                continue\n            elif(self.inBlock and IsEndSourceBlock(self.view,pt)):\n                self.inBlock = False\n        for filename in self.fileData:\n            with open(filename,\"w\") as f:\n                f.write(self.fileData[filename])\n                #print(\"WROTE: \" + filename)\n        if(self.cur >= self.last_row):\n            self.OnDone()\n\n    def run(self,edit,onDone=None):\n        self.fileData = {}\n        self.onDone = onDone\n        self.last_row = self.view.endRow()\n        self.cur = 0\n        self.inBlock = False\n        self.ContinueRun()\n"
  },
  {
    "path": "orgsrc/beancount.py",
    "content": "import sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nimport OrgExtended.orgtableformula as fml\nimport OrgExtended.orgsourceblock as src\nimport OrgExtended.orgparse.date as odate\nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orglist as lst\n\n# Javascript Babel Mode\n\ndef FormatText(txt):\n    if(isinstance(txt,str)):\n        txt = txt.strip()\n        return \"'\" + txt + \"'\"\n    return txt\n\n\ndef HandleValue(cmd):\n    if(cmd.CheckResultsFor('value')):\n        out = \"function OrgExtendedJavascriptWrapperFunction() {\\n\"\n        outs = cmd.source.split('\\n')\n        for o in outs:\n            out += \" \" + o + \"\\n\"\n        out += '}\\n'\n        out += \"let orgExtendedWrapperVar = OrgExtendedJavascriptWrapperFunction();\\nconsole.log('RETURNVALUESTART\\n');\\nconsole.log(orgExtendedWrapperVar);\\nconsole.log('\\n');\\nconsole.log('RETURNVALUEEND\\n');\\n\"\n        cmd.source = out\n\ndef PreProcessSourceFile(cmd):\n    HandleValue(cmd)\n    var = cmd.params.Get('var',None)\n    if(var):\n        out = \"\"\n        for k in var:\n            v = var[k]\n            if(isinstance(v,src.TableData)):\n                out += \"let \" + str(k) + \" = [\"\n                fr = True\n                for r in v.ForEachRow():\n                    first = True\n                    out += '[' if fr else \",[\"\n                    fr = False\n                    for c in v.ForEachCol():\n                        txt = v.GetCell(r,c)\n                        out += (',' if not first else \"\") + str(FormatText(txt))\n                        first = False\n                    out += ']'\n                out += \"];\\n\"\n            elif(isinstance(v,lst.ListData)):\n                out += \"let \" + str(k) + \" = [\"\n                first = True\n                for txt in v:\n                    out += (',' if not first else \"\") + str(FormatText(txt))\n                    first = False\n                out += \"];\\n\"\n            elif(isinstance(v,int) or isinstance(v,float) or (isinstance(v,str) and util.numberCheck(v))):\n                out += \"let \" + str(k) + \" = \" + str(v) + \";\\n\"\n            elif(isinstance(v,str)):\n                out += \"let \" + str(k) + \" = \\'\" + str(v) + \"\\';\\n\"\n        cmd.source = out + cmd.source\n\n\ndef Extension(cmd):\n    return \".beancount\"\n\ndef LineCommentPrefix():\n    return \"//\"\n    \n# Actually do the work, return an array of output.\ndef Execute(cmd,sets):\n    appPath = sets.Get(\"beancountPath\",\"C:\\\\Program Files\\\\nodejs\\\\node.exe\")\n    commandLine = [jsPath, cmd.filename]\n    try:\n        startupinfo = subprocess.STARTUPINFO()\n        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n    except:\n        startupinfo = None\n    # cwd=working_dir, env=my_env,\n    cwd = os.path.join(sublime.packages_path(),\"User\") \n    popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    #popen.wait()\n    (o,e) = popen.communicate()\n    if(cmd.CheckResultsFor('value')):\n        out = []\n        outs = o.split('\\n')\n        seenStart = False\n        for oo in outs:\n            if(oo.strip() == \"RETURNVALUESTART\"):\n                seenStart = True\n                continue\n            if(oo.strip() == \"RETURNVALUEEND\"):\n                seenStart = False\n                continue\n            if(seenStart):\n                out.append(oo)\n        return out + e.split('\\n')\n\n    return o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n    pass\n"
  },
  {
    "path": "orgsrc/cmd.py",
    "content": "import sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nimport OrgExtended.orgtableformula as fml\nimport OrgExtended.orgsourceblock as src\nimport OrgExtended.orgparse.date as odate\nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orglist as lst\n\n# Cmd Babel Mode\n\ndef FormatText(txt):\n    if(isinstance(txt,str)):\n        txt = txt.strip()\n        return \"'\" + txt + \"'\"\n    return txt\n\n\ndef HandleValue(cmd):\n    if(cmd.CheckResultsFor('value')):\n        out = \"\\nsetlocal\\n\"\n        out += \"CALL :OrgExtendedBatchWrapperFunction orgExtendedWrapperVar\\n\"\n        out += \"echo RETURNVALUESTART\\n\"\n        out += \"echo %orgExtendedWrapperVar%\\n\"\n        out += \"echo RETURNVALUEEND\\n\"\n        out += \"EXIT /B %ERRORLEVEL%\\n\"\n        out += \":OrgExtendedBatchWrapperFunction\\n\"\n        outs = cmd.source.split('\\n')\n        for o in outs:\n            out += \" \" + o + \"\\n\"\n        out += 'EXIT /B 0\\n'\n        cmd.source = out\n\ndef PreProcessSourceFile(cmd):\n    HandleValue(cmd)\n    var = cmd.params.Get('var',None)\n    if(var):\n        out = \"\"\n        for k in var:\n            v = var[k]\n            if(isinstance(v,src.TableData)):\n                out += \"set \" + str(k) + \"_width=\" + str(v.Width()) + \"\\n\"\n                out += \"set \" + str(k) + \"_height=\" + str(v.Height()) + \"\\n\"\n                for r in v.ForEachRow():\n                    for c in v.ForEachCol():\n                        txt = v.GetCell(r,c)\n                        out += \"set \" + str(k) + \"[\" + str(r) + \",\" + str(c) + \"]=\" + str(FormatText(txt)) + \"\\n\"\n            elif(isinstance(v,lst.ListData)):\n                out += \"set \" + str(k) + \"_len=\" + str(v.Length()) + \"\\n\"\n                out += \"set \" + str(k) + \"=[\" \n                first = True\n                for txt in v:\n                    out += (',' if not first else \"\") + str(FormatText(txt))\n                    first = False\n                out += \"]\\n\"\n            elif(isinstance(v,int) or isinstance(v,float) or (isinstance(v,str) and util.numberCheck(v))):\n                out += \"set /A \" + str(k) + \"=\" + str(v) + \"\\n\"\n            elif(isinstance(v,str)):\n                out += \"set \" + str(k) + \"=\" + str(v) + \"\\n\"\n        cmd.source = out + cmd.source\n        print(str(cmd.source))\n\n\ndef Extension(cmd):\n    return \".bat\"\n\ndef LineCommentPrefix():\n    return \"REM\"\n    \n# Actually do the work, return an array of output.\ndef Execute(cmd,sets):\n    commandLine = [r\"C:\\\\Windows\\\\system32\\\\cmd.exe\",\"/Q\", \"/C\", cmd.filename]\n    try:\n        startupinfo = subprocess.STARTUPINFO()\n        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n    except:\n        startupinfo = None\n    # cwd=working_dir, env=my_env,\n    cwd = os.path.join(sublime.packages_path(),\"User\") \n    popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    #popen.wait()\n    (o,e) = popen.communicate()\n    if(cmd.CheckResultsFor('value')):\n        out = []\n        outs = o.split('\\n')\n        seenStart = False\n        for oo in outs:\n            if(oo.strip() == \"RETURNVALUESTART\"):\n                seenStart = True\n                continue\n            if(oo.strip() == \"RETURNVALUEEND\"):\n                seenStart = False\n                continue\n            if(seenStart):\n                out.append(oo)\n        return out + e.split('\\n')\n\n    return o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n    pass\n"
  },
  {
    "path": "orgsrc/csharp.py",
    "content": "import sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nimport OrgExtended.orgtableformula as fml\nimport OrgExtended.orgsourceblock as src\nimport OrgExtended.orgparse.date as odate\nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orglist as lst\n\n# C# Babel Mode\n\ndef FormatText(txt):\n    if(isinstance(txt,str)):\n        txt = txt.strip()\n        return \"\\\"\" + txt + \"\\\"\"\n    return txt\n\n\ndef HandleValue(cmd):\n    if(cmd.CheckResultsFor('value')):\n        out = \"object OrgExtendedWrapperFunction() {\\n\"\n        outs = cmd.source.split('\\n')\n        for o in outs:\n            out += \" \" + o + \"\\n\"\n        out += '}\\n'\n        out += \"var orgExtendedWrapperVar = OrgExtendedWrapperFunction();\\nConsole.Writeline(\\\"RETURNVALUESTART\\\");\\nConsole.Writeline(orgExtendedWrapperVar.ToString());\\nConsole.Writeline(\\\"\\\");\\nConsole.Writeline(\\\"RETURNVALUEEND\\\");\\n\"\n        cmd.source = out\n\ndef PreProcessSourceFile(cmd):\n    HandleValue(cmd)\n    var = cmd.params.Get('var',None)\n    if(var):\n        out = \"\"\n        for k in var:\n            v = var[k]\n            if(isinstance(v,src.TableData)):\n                out += \"var[,] \" + str(k) + \" = {\"\n                fr = True\n                for r in v.ForEachRow():\n                    first = True\n                    out += '{' if fr else \",{\"\n                    fr = False\n                    for c in v.ForEachCol():\n                        txt = v.GetCell(r,c)\n                        out += (',' if not first else \"\") + str(FormatText(txt))\n                        first = False\n                    out += ']'\n                out += \"};\\n\"\n            elif(isinstance(v,lst.ListData)):\n                out += \"var[] \" + str(k) + \" = {\"\n                first = True\n                for txt in v:\n                    out += (',' if not first else \"\") + str(FormatText(txt))\n                    first = False\n                out += \"};\\n\"\n            elif(isinstance(v,int) or isinstance(v,float) or (isinstance(v,str) and util.numberCheck(v))):\n                out += \"var \" + str(k) + \" = \" + str(v) + \";\\n\"\n            elif(isinstance(v,str)):\n                out += \"var \" + str(k) + \" = \\\"\" + str(v) + \"\\\";\\n\"\n        cmd.source = out + cmd.source\n        print(\"OUT: \" + str(cmd.source))\n\n\ndef Extension(cmd):\n    return \".cs\"\n\ndef LineCommentPrefix():\n    return \"//\"\n\n\ndef CreateProject(cmd, sets, outPath):\n    ppath = sets.Get(\"dotnetPath\",\"C:\\\\Program Files\\\\dotnet\\\\dotnet.exe\")\n    commandLine = [ppath, \"new\", \"console\", \"--name\", projectName]\n    try:\n        startupinfo = subprocess.STARTUPINFO()\n        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n    except:\n        startupinfo = None\n    # cwd=working_dir, env=my_env,\n    cwd = os.path.join(sublime.packages_path(),\"User\") \n    popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n# Actually do the work, return an array of output.\ndef Execute(cmd,sets):\n    ppath = sets.Get(\"dotnetPath\",\"C:\\\\Program Files\\\\dotnet\\\\dotnet.exe\")\n    commandLine = [ppath, cmd.filename]\n    try:\n        startupinfo = subprocess.STARTUPINFO()\n        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n    except:\n        startupinfo = None\n    # cwd=working_dir, env=my_env,\n    cwd = os.path.join(sublime.packages_path(),\"User\") \n    popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    #popen.wait()\n    (o,e) = popen.communicate()\n    if(cmd.CheckResultsFor('value')):\n        out = []\n        outs = o.split('\\n')\n        seenStart = False\n        for oo in outs:\n            if(oo.strip() == \"RETURNVALUESTART\"):\n                seenStart = True\n                continue\n            if(oo.strip() == \"RETURNVALUEEND\"):\n                seenStart = False\n                continue\n            if(seenStart):\n                out.append(oo)\n        return out + e.split('\\n')\n\n    return o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n    pass\n"
  },
  {
    "path": "orgsrc/ditaa.py",
    "content": "\n\n\nimport sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nfrom shutil import copyfile\nimport OrgExtended.asettings as sets\n\n# Python Babel Mode\ndef Extension(cmd):\n\treturn \".ditaa\"\n\n# Actually do the work, return an array of output.\ndef Execute(cmd,sets):\n\tjarfile = sets.Get(\"ditaa\",None)\n\tif(jarfile == None):\n\t\tprint(\"ERROR: cannot find ditaa jar file. Please setup the ditaa key in your settings file\")\n\t\treturn [\"ERROR - missing ditaa.jar file\"]\n\tcmd.output = cmd.params.Get('file','diagram.png')\n\toutpath     = os.path.dirname(cmd.filename)\n\tsourcepath = os.path.dirname(cmd.sourcefile)\n\t#commandLine = [r\"java\", \"-jar\", jarfile, mypath, \"-o\", output]\n\n\tjava = \"java\"\n\tjava = sets.Get(\"java\", java)\n\tcommandLine = [java, \"-jar\", jarfile, cmd.filename, \"-o\"]\n\tprint(str(commandLine))\n\t#commandLine = [r\"java\", \"-jar\", jarfile, \"-help\"]\n\ttry:\n\t\tstartupinfo = subprocess.STARTUPINFO()\n\t\tstartupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n\texcept:\n\t\tstartupinfo = None\n\t# cwd=working_dir, env=my_env,\n\tos.makedirs(outpath, exist_ok=True)\n\tcwd = os.path.join(sublime.packages_path(),\"User\") \n\tpopen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n\t#popen.wait()\n\t(o,e) = popen.communicate()\n\t\n\tconvertFile = os.path.join(outpath,os.path.splitext(os.path.basename(cmd.filename))[0] + \".png\")\n\tdestFile    = os.path.join(sourcepath,cmd.output)\n\tcopyfile(convertFile, destFile)\n\t#print(str(os.path.basename(cmd.sourcefile)))\n\t#print(str(os.path.splitext(cmd.filename)))\n\t#print(str(os.path.splitext(cmd.sourcefile)))\n\t#destFile = os.path.relpath(destFile, sourcepath)\n\tout = o\n\to = \"\"\n\t#o = \"[[file:\" + destFile + \"]]\"\n\tif(\"error\" in out or \"failed\" in out or \"Failed\" in out or \"Error\" in out or \"not\" in out):\n\t\to = o +out\n\treturn o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n\tpass\n\n# Create one of these and return true if we should show images after a execution.\ndef GeneratesImages(cmd):\n\treturn True"
  },
  {
    "path": "orgsrc/gnuplot.py",
    "content": "import sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nfrom shutil import move\nimport types\nimport OrgExtended.orgtableformula as fml\nimport OrgExtended.orgparse.date as odate\nimport traceback\nimport datetime\n\n# GNU Plot Babel Mode\n\ndef GetTerminalFromOutputFile(filename):\n    out = \"\"\n    if(filename):\n        ff,ext = os.path.splitext(filename)\n        if(ext == '.png'):\n            out += 'set term png \\n'\n        if(ext == '.jpg' or ext == '.jpeg'):\n            out += 'set term jpeg \\n'\n        if(ext == '.gif'):\n            out += 'set term gif \\n'\n        if(ext == '.html'):\n            out += 'set term canvas \\n'\n        if(ext == '.txt'):\n            out += 'set term dumb \\n'\n        if(ext == '.svg'):\n            out += 'set term svg \\n'\n        if(ext == '.ps'):\n            out += 'set term postscript \\n'\n    return out\n\n\ndef FormatDateTime(now):\n    if(isinstance(now,datetime.datetime)):\n        return now.strftime(\"%Y-%m-%d %H:%M\")  \n    else:\n        return now.strftime(\"%Y-%m-%d\")  \n\ndef FormatText(txt):\n    txt = txt.strip()\n    try:\n        rc = odate.OrgDate.list_from_str(txt)\n        if(len(rc) > 0):\n            return FormatDateTime(rc[0].start).strip()\n    except:\n        #print(\"FAILED FORMAT: \" + str(traceback.format_exc()))\n        pass\n    if(\" \" in txt):\n        txt = \"\\\"\" + txt + \"\\\"\"\n    return txt\n\ndef PreProcessSourceFile(cmd):\n    filename = cmd.params.Get('file',None)\n    var = cmd.params.Get('var',None)\n    if(var):\n        out = \"\"\n        for k in var:\n            v = var[k]\n            if(isinstance(v,fml.TableDef)):\n                out += \"$\" + str(k) + \" << EOD\\n\"\n                for r in v.ForEachRow():\n                    first = True\n                    for c in v.ForEachCol():\n                        txt = v.GetCellText(r,c)\n                        out += ('\\t' if not first else \"\") + FormatText(txt)\n                        first = False\n                    out += '\\n'\n                out += \"EOD\\n\"\n        cmd.source = out + cmd.source\n    if(filename):\n        out = GetTerminalFromOutputFile(filename)\n        cmd.output = filename\n        out += \"set output \\\"\" + filename.replace(\"\\\\\",\"\\\\\\\\\") + \"\\\"\\n\"\n        # Append the source output information\n        cmd.source = out + cmd.source\n\ndef Extension(cmd):\n    return \".gplt\"\n\n# Actually do the work, return an array of output.\ndef Execute(cmd, sets):\n    plotcmd = sets.Get(\"gnuplot\",r\"C:\\Program Files\\gnuplot\\bin\\gnuplot.exe\")\n    commandLine = [plotcmd, \"-c\", cmd.filename]\n    try:\n        startupinfo = subprocess.STARTUPINFO()\n        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n    except:\n        startupinfo = None\n    # cwd=working_dir, env=my_env,\n    cwd = os.path.join(sublime.packages_path(),\"User\") \n    popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    (o,e) = popen.communicate()\n    \n    #outpath     = os.path.dirname(cmd.filename)\n    sourcepath = os.path.dirname(cmd.sourcefile)\n    relpath = os.path.join(cwd,cmd.output)\n    if(os.path.exists(relpath)):\n        destFile    = os.path.join(sourcepath,cmd.output)\n        if(destFile != relpath):\n            move(relpath, destFile)\n\n    return o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n    pass\n"
  },
  {
    "path": "orgsrc/graphviz.py",
    "content": "\nimport sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nfrom shutil import copyfile\nimport OrgExtended.asettings as sets\nimport platform\n\n# Python Babel Mode\ndef Extension(cmd):\n\treturn \".dot\"\n\n# Actually do the work, return an array of output.\ndef Execute(cmd,sets):\n\texe = sets.Get(\"graphviz\",None)\n\tif(exe == None):\n\t\tprint(\"ERROR: cannot find graphviz executable file. Please setup the graphviz key in your settings file\")\n\t\treturn [\"ERROR - missing graphviz executable file\"]\n\toutput = \"diagram\"\n\tformat = cmd.params.Get('fmt',\"png\")\n\tengine = cmd.params.Get('engine',\"default\")\n\toutput = output + \".\" + format\n\tcmd.output = cmd.params.Get('file',output)\n\n\tif(engine != \"default\"):\n\t\tif(platform.system() == \"Windows\"):\n\t\t\tif(not engine.endswith(\".exe\")):\n\t\t\t\tengine = engine + \".exe\"\n\t\texe = os.path.join(os.path.dirname(exe),engine)\n\toutpath     = os.path.dirname(cmd.filename)\n\tsourcepath = os.path.dirname(cmd.sourcefile)\n\tdestFile    = os.path.join(sourcepath,cmd.output)\n\tcommandLine = [exe, \"-T\" + format, cmd.filename, \"-o\", destFile]\n\t#print(str(commandLine))\n\t#commandLine = [r\"java\", \"-jar\", jarfile, \"-help\"]\n\ttry:\n\t\tstartupinfo = subprocess.STARTUPINFO()\n\t\tstartupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n\texcept:\n\t\tstartupinfo = None\n\t# cwd=working_dir, env=my_env,\n\tos.makedirs(os.path.dirname(destFile), exist_ok=True)\n\tcwd = os.path.join(sublime.packages_path(),\"User\") \n\tpopen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n\t#popen.wait()\n\t(o,e) = popen.communicate()\n\t\n\t#convertFile = os.path.join(outpath,os.path.splitext(os.path.basename(cmd.filename))[0] + \".png\")\n\t#copyfile(convertFile, destFile)\n\t#print(str(os.path.basename(cmd.sourcefile)))\n\t#print(str(os.path.splitext(cmd.filename)))\n\t#print(str(os.path.splitext(cmd.sourcefile)))\n\t#destFile = os.path.relpath(destFile, sourcepath)\n\t#o = \"[[file:\" + destFile + \"]]\" + o\n\treturn o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n\tpass\n\n# Create one of these and return true if we should show images after a execution.\ndef GeneratesImages(cmd):\n\treturn True\n"
  },
  {
    "path": "orgsrc/javascript.py",
    "content": "import sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nimport OrgExtended.orgtableformula as fml\nimport OrgExtended.orgsourceblock as src\nimport OrgExtended.orgparse.date as odate\nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orglist as lst\n\n# Javascript Babel Mode\n\ndef FormatText(txt):\n    if(isinstance(txt,str)):\n        txt = txt.strip()\n        return \"'\" + txt + \"'\"\n    return txt\n\n\ndef HandleValue(cmd):\n    if(cmd.CheckResultsFor('value')):\n        out = \"function OrgExtendedJavascriptWrapperFunction() {\\n\"\n        outs = cmd.source.split('\\n')\n        for o in outs:\n            out += \" \" + o + \"\\n\"\n        out += '}\\n'\n        out += \"let orgExtendedWrapperVar = OrgExtendedJavascriptWrapperFunction();\\nconsole.log('RETURNVALUESTART\\n');\\nconsole.log(orgExtendedWrapperVar);\\nconsole.log('\\n');\\nconsole.log('RETURNVALUEEND\\n');\\n\"\n        cmd.source = out\n\ndef PreProcessSourceFile(cmd):\n    HandleValue(cmd)\n    var = cmd.params.Get('var',None)\n    if(var):\n        out = \"\"\n        for k in var:\n            v = var[k]\n            if(isinstance(v,src.TableData)):\n                out += \"let \" + str(k) + \" = [\"\n                fr = True\n                for r in v.ForEachRow():\n                    first = True\n                    out += '[' if fr else \",[\"\n                    fr = False\n                    for c in v.ForEachCol():\n                        txt = v.GetCell(r,c)\n                        out += (',' if not first else \"\") + str(FormatText(txt))\n                        first = False\n                    out += ']'\n                out += \"];\\n\"\n            elif(isinstance(v,lst.ListData)):\n                out += \"let \" + str(k) + \" = [\"\n                first = True\n                for txt in v:\n                    out += (',' if not first else \"\") + str(FormatText(txt))\n                    first = False\n                out += \"];\\n\"\n            elif(isinstance(v,int) or isinstance(v,float) or (isinstance(v,str) and util.numberCheck(v))):\n                out += \"let \" + str(k) + \" = \" + str(v) + \";\\n\"\n            elif(isinstance(v,str)):\n                out += \"let \" + str(k) + \" = \\'\" + str(v) + \"\\';\\n\"\n        cmd.source = out + cmd.source\n\n\ndef Extension(cmd):\n    return \".js\"\n\ndef LineCommentPrefix():\n    return \"//\"\n    \n# Actually do the work, return an array of output.\ndef Execute(cmd,sets):\n    jsPath = sets.Get(\"nodejsPath\",\"C:\\\\Program Files\\\\nodejs\\\\node.exe\")\n    commandLine = [jsPath, cmd.filename]\n    try:\n        startupinfo = subprocess.STARTUPINFO()\n        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n    except:\n        startupinfo = None\n    # cwd=working_dir, env=my_env,\n    cwd = os.path.join(sublime.packages_path(),\"User\") \n    popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    #popen.wait()\n    (o,e) = popen.communicate()\n    if(cmd.CheckResultsFor('value')):\n        out = []\n        outs = o.split('\\n')\n        seenStart = False\n        for oo in outs:\n            if(oo.strip() == \"RETURNVALUESTART\"):\n                seenStart = True\n                continue\n            if(oo.strip() == \"RETURNVALUEEND\"):\n                seenStart = False\n                continue\n            if(seenStart):\n                out.append(oo)\n        return out + e.split('\\n')\n\n    return o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n    pass\n"
  },
  {
    "path": "orgsrc/mermaid.py",
    "content": "import sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nfrom shutil import copyfile\nimport OrgExtended.asettings as sets\n\n# Mermaid Babel Mode\ndef Extension(cmd):\n\treturn \".mmd\"\n\n# Actually do the work, return an array of output.\ndef Execute(cmd,sets):\n\tmmdc = sets.Get(\"mermaid\",'C:\\\\Users\\\\ihdav\\\\node_modules\\\\.bin\\\\mmdc.ps1')\n\tif(mmdc == None):\n\t\tprint(\"ERROR: cannot find mmdc file. Please setup the mermaid key in your settings file\")\n\t\treturn [\"ERROR - missing mermaid file\"]\n\tcmd.output = cmd.params.Get('file','diagram.png')\n\toutpath     = os.path.dirname(cmd.filename)\n\tsourcepath = os.path.dirname(cmd.sourcefile)\n\tconvertFile = os.path.join(outpath,os.path.splitext(os.path.basename(cmd.filename))[0] + \".png\")\n\tdestFile    = os.path.join(sourcepath,cmd.output)\n\tbasedir = os.path.dirname(mmdc)\n\tif sys.platform == 'win32':\n\t\tcommandLine = [\"powershell\",mmdc, \"-i\", cmd.filename, \"-o\", '\"' + destFile + '\"']\n\telse:\n\t\tcommandLine = [mmdc, \"-i\", cmd.filename, \"-o\", '\"' + destFile + '\"']\n\t\n\tprint(str(commandLine))\n\ttry:\n\t\tstartupinfo = subprocess.STARTUPINFO()\n\t\tstartupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n\texcept:\n\t\tstartupinfo = None\n\t# cwd=working_dir, env=my_env,\n\tos.makedirs(outpath, exist_ok=True)\n\t#cwd = os.path.join(sublime.packages_path(),\"User\") \n\tcwd = basedir + \"/../..\"\n\tpopen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n\t(o,e) = popen.communicate()\n\t\n\tout = o\n\to = \"\"\n\treturn o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n\tpass\n\n# Create one of these and return true if we should show images after a execution.\ndef GeneratesImages(cmd):\n\treturn True\n"
  },
  {
    "path": "orgsrc/perl.py",
    "content": "import sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nimport OrgExtended.orgtableformula as fml\nimport OrgExtended.orgsourceblock as src\nimport OrgExtended.orgparse.date as odate\nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orglist as lst\n\n# Javascript Babel Mode\n\ndef FormatText(txt):\n    if(isinstance(txt,str)):\n        txt = txt.strip()\n        return \"\\\"\" + txt + \"\\\"\"\n    return txt\n\n\ndef HandleValue(cmd):\n    if(cmd.CheckResultsFor('value')):\n        out = \"sub OrgExtendedPerlWrapperFunction() {\\n\"\n        outs = cmd.source.split('\\n')\n        for o in outs:\n            out += \" \" + o + \"\\n\"\n        out += '}\\n'\n        out += \"$orgExtendedWrapperVar = OrgExtendedPerlWrapperFunction();\\nprint \\\"RETURNVALUESTART\\n\\\";\\nprint \\\"$orgExtendedWrapperVar\\\";\\nprint \\\"\\n\\\";\\nprint \\\"RETURNVALUEEND\\n\\\";\\n\"\n        cmd.source = out\n\ndef PreProcessSourceFile(cmd):\n    HandleValue(cmd)\n    var = cmd.params.Get('var',None)\n    if(var):\n        out = \"\"\n        for k in var:\n            v = var[k]\n            if(isinstance(v,src.TableData)):\n                out += \"@\" + str(k) + \" = (\"\n                fr = True\n                for r in v.ForEachRow():\n                    first = True\n                    out += '[' if fr else \",[\"\n                    fr = False\n                    for c in v.ForEachCol():\n                        txt = v.GetCell(r,c)\n                        out += (',' if not first else \"\") + str(FormatText(txt))\n                        first = False\n                    out += ']'\n                out += \");\\n\"\n            elif(isinstance(v,lst.ListData)):\n                out += \"@\" + str(k) + \" = (\"\n                first = True\n                for txt in v:\n                    out += (',' if not first else \"\") + str(FormatText(txt))\n                    first = False\n                out += \");\\n\"\n            elif(isinstance(v,int) or isinstance(v,float) or (isinstance(v,str) and util.numberCheck(v))):\n                out += \"$\" + str(k) + \" = \" + str(v) + \";\\n\"\n            elif(isinstance(v,str)):\n                out += \"$\" + str(k) + \" = \\\"\" + str(v) + \"\\\";\\n\"\n        cmd.source = out + cmd.source\n        #print(\"OUT: \" + str(cmd.source))\n\n\ndef Extension(cmd):\n    return \".pl\"\n\ndef LineCommentPrefix():\n    return \"#\"\n    \n# Actually do the work, return an array of output.\ndef Execute(cmd,sets):\n    ppath = sets.Get(\"perlPath\",\"C:\\\\Program Files\\\\Git\\\\usr\\\\bin\\\\perl.exe\")\n    commandLine = [ppath, cmd.filename]\n    try:\n        startupinfo = subprocess.STARTUPINFO()\n        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n    except:\n        startupinfo = None\n    # cwd=working_dir, env=my_env,\n    cwd = os.path.join(sublime.packages_path(),\"User\") \n    popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    #popen.wait()\n    (o,e) = popen.communicate()\n    if(cmd.CheckResultsFor('value')):\n        out = []\n        outs = o.split('\\n')\n        seenStart = False\n        for oo in outs:\n            if(oo.strip() == \"RETURNVALUESTART\"):\n                seenStart = True\n                continue\n            if(oo.strip() == \"RETURNVALUEEND\"):\n                seenStart = False\n                continue\n            if(seenStart):\n                out.append(oo)\n        return out + e.split('\\n')\n\n    return o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n    pass\n"
  },
  {
    "path": "orgsrc/plantuml.py",
    "content": "\nimport sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nfrom shutil import copyfile\nimport OrgExtended.asettings as sets\n\n# Python Babel Mode\ndef Extension(cmd):\n\treturn \".pu\"\n\ndef WrapStart(cmd):\n\treturn \"@startuml\"\n\ndef WrapEnd(cmd):\n\treturn \"@enduml\"\n\n# Actually do the work, return an array of output.\ndef Execute(cmd,sets):\n\tjarfile = sets.Get(\"plantuml\",None)\n\tif(jarfile == None):\n\t\tprint(\"ERROR: cannot find plantuml jar file. Please setup the plantuml key in your settings file\")\n\t\treturn [\"ERROR - missing plantuml.jar file\"]\n\tcmd.output = cmd.params.Get('file',\"diagram.png\")\n\toutpath    = os.path.dirname(cmd.filename)\n\tsourcepath = os.path.dirname(cmd.sourcefile)\n\tcommandLine = [r\"java\", \"-jar\", jarfile, cmd.filename]\n\ttry:\n\t\tstartupinfo = subprocess.STARTUPINFO()\n\t\tstartupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n\texcept:\n\t\tstartupinfo = None\n\tcwd = os.path.join(sublime.packages_path(),\"User\") \n\tpopen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n\t(o,e) = popen.communicate()\n\t\n\tconvertFile = os.path.join(outpath,os.path.splitext(os.path.basename(cmd.filename))[0] + \".png\")\n\tdestFile    = os.path.normpath(os.path.join(sourcepath,cmd.output))\n\tos.makedirs(os.path.dirname(destFile), exist_ok=True)\n\tcopyfile(convertFile, destFile)\n\treturn o.split('\\n') + e.split('\\n')\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n\tpass\n\n# Create one of these and return true if we should show images after a execution.\ndef GeneratesImages(cmd):\n\treturn True"
  },
  {
    "path": "orgsrc/powershell.py",
    "content": "import sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nimport OrgExtended.orgtableformula as fml\nimport OrgExtended.orgsourceblock as src\nimport OrgExtended.orgparse.date as odate\nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orglist as lst\n\n# Python Babel Mode\n\ndef FormatText(txt):\n    if(isinstance(txt,str)):\n        txt = txt.strip()\n        return \"'\" + txt + \"'\"\n    return txt\n\n\ndef HandleValue(cmd):\n    if(cmd.CheckResultsFor('value')):\n        out = \"function OrgExtendedPowershellWrapperFunction {\\n\"\n        outs = cmd.source.split('\\n')\n        for o in outs:\n            out += \" \" + o + \"\\n\"\n        out += '}\\n'\n        out += \"$orgExtendedWrapperVar = OrgExtendedPowershellWrapperFunction\\nWrite-Host RETURNVALUESTART\\nWrite-Host $orgExtendedWrapperVar\\nWrite-Host RETURNVALUEEND\\n\"\n        cmd.source = out\n\ndef PreProcessSourceFile(cmd):\n    HandleValue(cmd)\n    var = cmd.params.Get('var',None)\n    if(var):\n        out = \"\"\n        for k in var:\n            v = var[k]\n            if(isinstance(v,src.TableData)):\n                out += \"$\" + str(k) + \" = @(\"\n                fr = True\n                for r in v.ForEachRow():\n                    first = True\n                    out += '(' if fr else \",(\"\n                    fr = False\n                    for c in v.ForEachCol():\n                        txt = v.GetCell(r,c)\n                        out += (',' if not first else \"\") + str(FormatText(txt))\n                        first = False\n                    out += ')'\n                out += \")\\n\"\n            if(isinstance(v,fml.TableDef)):\n                out += \"$\" + str(k) + \" = @(\"\n                fr = True\n                for r in v.ForEachRow():\n                    first = True\n                    out += '(' if fr else \",(\"\n                    fr = False\n                    for c in v.ForEachCol():\n                        txt = fml.Cell(r,c,v).GetVal()\n                        out += (',' if not first else \"\") + str(FormatText(txt))\n                        first = False\n                    out += ')'\n                out += \")\\n\"\n            elif(isinstance(v,lst.ListData)):\n                out += \"$\" + str(k) + \" = @(\"\n                first = True\n                for txt in v:\n                    out += (',' if not first else \"\") + str(FormatText(txt))\n                    first = False\n                out += \")\\n\"\n            elif(isinstance(v,int) or isinstance(v,float) or (isinstance(v,str) and util.numberCheck(v))):\n                out += \"$\" + str(k) + \" = \" + str(v) + \"\\n\"\n            elif(isinstance(v,str)):\n                out += \"$\" + str(k) + \" = \\'\" + str(v) + \"\\'\\n\"\n        cmd.source = out + cmd.source\n\n\ndef Extension(cmd):\n    return \".ps1\"\n\ndef LineCommentPrefix():\n    return \"#\"\n    \n# Actually do the work, return an array of output.\ndef Execute(cmd,sets):\n    commandLine = [r\"C:\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe\", \"-ExecutionPolicy\", \"Unrestricted\", cmd.filename]\n    try:\n        startupinfo = subprocess.STARTUPINFO()\n        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n    except:\n        startupinfo = None\n    # cwd=working_dir, env=my_env,\n    cwd = os.path.join(sublime.packages_path(),\"User\") \n    popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    #popen.wait()\n    (o,e) = popen.communicate()\n    if(cmd.CheckResultsFor('value')):\n        out = []\n        outs = o.split('\\n')\n        seenStart = False\n        for oo in outs:\n            if(oo.strip() == \"RETURNVALUESTART\"):\n                seenStart = True\n                continue\n            if(oo.strip() == \"RETURNVALUEEND\"):\n                seenStart = False\n                continue\n            if(seenStart):\n                out.append(oo)\n        return out + e.split('\\n')\n\n    return o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n    pass\n"
  },
  {
    "path": "orgsrc/python.py",
    "content": "import sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport OrgExtended.orgtableformula as fml\nimport OrgExtended.orgsourceblock as src\nimport OrgExtended.orglist as lst\nimport OrgExtended.orgparse.date as odate\nimport OrgExtended.orgutil.util as util\n\n# Python Babel Mode\ndef FormatText(txt):\n    if(isinstance(txt,str)):\n        txt = txt.strip()\n        return \"'\" + txt + \"'\"\n    return txt\n\ndef HandleValue(cmd):\n    if(cmd.CheckResultsFor('value')):\n        out = \"def OrgExtendedPythonWrapperFunction():\\n\"\n        outs = cmd.source.split('\\n')\n        leadingIndent = \"\"\n        if(len(outs) > 0):\n            leadingIndent = re.match(r\"\\s*\", outs[0]).group()\n        for vaDefs in cmd.varsDefs:\n            out += \"    \" + leadingIndent + vaDefs + \"\\n\"\n        for o in outs:\n            out += \"    \" + o + \"\\n\"\n        out += \"\\n\\norgExtendedPythonReturnVar = OrgExtendedPythonWrapperFunction()\\n\"\n        cmd.source = out\n\ndef PreProcessSourceFile(cmd):\n    var = cmd.params.Get('var',None)\n    cmd.varsDefs = []\n    out = \"\"\n    if(var):\n        for k in var:\n            v = var[k]\n            if(isinstance(v,src.TableData)):\n                out += str(k) + \" = [\\n\"\n                cmd.varsDefs.append(\"global \" + str(k))\n                fr = True\n                for r in v.ForEachRow():\n                    first = True\n                    out += '[' if fr else \",[\"\n                    fr = False\n                    for c in v.ForEachCol():\n                        txt = v.GetCell(r,c)\n                        out += (',' if not first else \"\") + str(FormatText(txt))\n                        first = False\n                    out += ']'\n                out += \"]\\n\"\n            if(isinstance(v,fml.TableDef)):\n                out += str(k) + \" = [\\n\"\n                cmd.varsDefs.append(\"global \" + str(k))\n                fr = True\n                for r in v.ForEachRow():\n                    first = True\n                    out += '[' if fr else \",[\"\n                    fr = False\n                    for c in v.ForEachCol():\n                        txt = fml.Cell(r,c,v).GetVal()\n                        out += (',' if not first else \"\") + str(FormatText(txt))\n                        first = False\n                    out += ']'\n                out += \"]\\n\"\n            elif(isinstance(v,lst.ListData)):\n                out += str(k) + \" = [\\n\"\n                cmd.varsDefs.append(\"global \" + str(k))\n                first = True\n                for txt in v:\n                    out += (',' if not first else \"\") + str(FormatText(txt))\n                    first = False\n                out += \"]\\n\"\n            elif(isinstance(v,int) or isinstance(v,float) or (isinstance(v,str) and util.numberCheck(v))):\n                out += str(k) + \" = \" + str(v) + \"\\n\"\n                cmd.varsDefs.append(\"global \" + str(k))\n            elif(isinstance(v,str)):\n                out += str(k) + \" = \\'\" + str(v) + \"\\'\\n\"\n                cmd.varsDefs.append(\"global \" + str(k))\n    HandleValue(cmd)\n    if(out != \"\"):\n        cmd.source = out + cmd.source\n\ndef LineCommentPrefix():\n    return \"#\"\n\n\n# Actually do the work, return an array of output.\ndef Execute(cmd, sets):\n    # create file-like string to capture output\n    codeOut = io.StringIO()\n    codeErr = io.StringIO()\n    code    = cmd.source\n    # capture output and errors\n    oldOut     = sys.stdout\n    oldErr     = sys.stderr\n    sys.stdout = codeOut\n    sys.stderr = codeErr\n    ret = None\n    loc = {}\n    loc['orgExtendedPythonReturnVar'] = None\n    loc['view'] = sublime.active_window().active_view()\n    loc['window'] = sublime.active_window()\n    globs = globals()\n    try:\n        if(not cmd.CheckResultsFor('value')):\n            code = re.sub(r\"^(\\s+)(.*)$\",\n                    lambda m: re.sub(\"^\" + \" \"*len(m.group(1)),\"\",m.group(2),flags=re.MULTILINE)\n                    ,code,flags=re.MULTILINE|re.DOTALL)\n        exec(code,globs,loc)\n    except Exception as ex:\n        # If we throw during the run we need to catch it\n        # and try to handle it here.\n        print(\"EXCEPTION DURING RUN:\")\n        print(type(ex))\n        print(ex.args)\n\n    # restore stdout and stderr\n    #sys.stdout = sys.__stdout__\n    #sys.stderr = sys.__stderr__\n    sys.stdout = oldOut\n    sys.stderr = oldErr\n\n    e = codeErr.getvalue()\n    #print(\"error:\\n%s\\n\" % e)\n    o = codeOut.getvalue()\n    #print(\"output:\\n%s\" % o)\n    codeOut.close()\n    codeErr.close()\n    if(cmd.CheckResultsFor('value')):\n        if(loc['orgExtendedPythonReturnVar'] == None):\n            if(e.strip()+o.strip() != \"\"):\n                return o.split('\\n') + e.split('\\n')\n        return [ str(loc['orgExtendedPythonReturnVar']) ]\n        #return [ str(globs) ]\n    else:\n        return o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n    pass\n"
  },
  {
    "path": "orgsrc/sh.py",
    "content": "import sublime\nimport sublime_plugin\nimport sys\nimport io\nimport re\nimport logging\nimport subprocess, os\nimport threading, time, signal\nimport OrgExtended.orgtableformula as fml\nimport OrgExtended.orgsourceblock as src\nimport OrgExtended.orgparse.date as odate\nimport OrgExtended.orgutil.util as util\nimport OrgExtended.orglist as lst\n\n# Bash Babel Mode\n\ndef FormatText(txt):\n    if(isinstance(txt,str)):\n        txt = txt.strip()\n        #return \"'\" + txt + \"'\"\n    return txt\n\n\ndef HandleValue(cmd):\n    if(cmd.CheckResultsFor('value')):\n        out = \"OrgExtendedBashWrapperFunction () {\\n\"\n        outs = cmd.source.split('\\n')\n        for o in outs:\n            out += \" \" + o + \"\\n\"\n        out += '}\\n'\n        out += \"OrgExtendedBashWrapperFunction\\norgExtendedWrapperVar=$?\\necho RETURNVALUESTART\\necho ${orgExtendedWrapperVar}\\necho RETURNVALUEEND\\n\"\n        cmd.source = out\n\ndef PreProcessSourceFile(cmd):\n    HandleValue(cmd)\n    var = cmd.params.Get('var',None)\n    if(var):\n        out = \"\"\n        for k in var:\n            v = var[k]\n            if(isinstance(v,src.TableData)):\n                out += str(k) + \"=$(cat <<'END_HERE_DOC'\\n\"\n                for r in v.ForEachRow():\n                    first = True\n                    for c in v.ForEachCol():\n                        txt = v.GetCell(r,c)\n                        out += ('\\t' if not first else \"\") + str(FormatText(txt))\n                        first = False\n                    out += '\\n'\n                out += \"END_HERE_DOC\\n)\\n\"\n            elif(isinstance(v,lst.ListData)):\n                out += str(k) + \"=(\"\n                first = True\n                for txt in v:\n                    out += (' ' if not first else \"\") + str(FormatText(txt))\n                    first = False\n                out += \")\\n\"\n            elif(isinstance(v,int) or isinstance(v,float) or (isinstance(v,str) and util.numberCheck(v))):\n                out += str(k) + \"=\" + str(v) + \"\\n\"\n            elif(isinstance(v,str)):\n                out += str(k) + \"=\\'\" + str(v) + \"\\'\\n\"\n        cmd.source = out + cmd.source\n\n\ndef Extension(cmd):\n    return \".sh\"\n\ndef LineCommentPrefix():\n    return \"#\"\n\ndef GetCommandLine(cmd,sets):\n    filename = cmd.filename\n    if(sublime.platform() == 'windows'):\n        bashLocation = sets.Get(\"bashPath\",r\"C:\\\\Windows\\\\System32\\\\wsl.exe\")\n        filename = filename.replace(\"C:\\\\\",\"/mnt/c/\").replace(\"c:\\\\\",\"/mnt/c/\").replace(\"\\\\\",\"/\")\n    else:\n        bashLocation = sets.Get(\"bashPath\",r\"/bin/bash\")\n    commandLine = [bashLocation, filename]\n    return commandLine\n\n    \n# Actually do the work, return an array of output.\ndef Execute(cmd,sets):\n    commandLine = GetCommandLine(cmd,sets)\n    try:\n        startupinfo = subprocess.STARTUPINFO()\n        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n    except:\n        startupinfo = None\n    # cwd=working_dir, env=my_env,\n    cwd = os.path.join(sublime.packages_path(),\"User\") \n    popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    #popen.wait()\n    (o,e) = popen.communicate()\n    if(cmd.CheckResultsFor('value')):\n        out = []\n        outs = o.split('\\n')\n        seenStart = False\n        for oo in outs:\n            if(oo.strip() == \"RETURNVALUESTART\"):\n                seenStart = True\n                continue\n            if(oo.strip() == \"RETURNVALUEEND\"):\n                seenStart = False\n                continue\n            if(seenStart):\n                out.append(oo)\n        return out + e.split('\\n')\n\n    return o.split('\\n') + e.split('\\n')\n\n\n# Run after results are in the buffer. We can do whatever\n# Is needed to the buffer post execute here.\ndef PostExecute(cmd):\n    pass\n"
  },
  {
    "path": "orgswiper.py",
    "content": "import calendar\nimport sublime\nimport sublime_plugin\nimport datetime\nfrom OrgExtended.orgparse.date import *\nimport OrgExtended.pymitter as evt\n\ndef CreateUniqueViewNamed(name, mapped=None):\n\t# Close the view if it exists\n\twin = sublime.active_window()\n\tfor view in win.views():\n\t\tif view.name() == name:\n\t\t\twin.focus_view(view)\n\t\t\twin.run_command('close')\n\twin.run_command('new_file')\n\tview = win.active_view()\n\tview.set_name(name)\n\t# TODO: Change this.\n\tview.set_syntax_file(\"Packages/OrgExtended/orgdatepicker.sublime-syntax\")\n\t#ViewMappings[view.name()] = mapped\n\treturn view\n\nclass SwiperView:\n\tdef __init__(self,sourceView):\n\t\tself.sourceView = sourceView\n\t\tself.view = CreateUniqueViewNamed(\"swiper\")\n        # Create new window\n        #self.window.run_command(\"new_window\")\n        # Open the current file in the new window\n        #sublime.windows()[-1:][0].open_file(self.window.active_view().file_name())\n\tdef SetView(self, view):\n\t\tself.output = view\n\n\n\tdef SetStartRow(self, row):\n\t\tself.startrow = row\n\n\tdef DateToRegion(self, date):\n\t\t# Convert \n\t\tmonthIndex = (date.month - self.midmonth + 1)\n\t\tif(monthIndex < 0 or monthIndex >= len(self.monthdata)):\n\t\t\treturn\n\t\tmonthData = self.monthdata[monthIndex]\n\t\tweekIndex = 0\n\t\tdayIndex  = 0\n\t\tfor weekId in range(0,len(monthData)):\n\t\t\tweekData = monthData[weekId]\n\t\t\tfor dayId in range(0,len(weekData)):\n\t\t\t\tday = weekData[dayId]\n\t\t\t\tif(day == date.day):\n\t\t\t\t\tweekIndex = weekId\n\t\t\t\t\tdayIndex  = dayId\n\t\t# 2 row heading?\n\t\t# We should have an offset? Probably\n\t\trow = self.headingLines + weekIndex\n\t\tcol = monthIndex * self.columnsPerMonth + dayIndex*self.columnsPerDay\n\t\t#print(\"ROW: \" + str(row) + \" COL: \" + str(col))\n\t\ts = self.output.text_point(row,col)\n\t\te = self.output.text_point(row,col+2)\n\t\treturn sublime.Region(s, e)\n\n\tdef HighlightDay(self, date):\n\t\treg = self.DateToRegion(date)\n\t\tself.output.add_regions(\"cur\",[reg],\"orgdatepicker.monthheader\",\"\",sublime.DRAW_NO_OUTLINE)\t\n\n\tdef AddToDayHighlights(self, date, key, highlight, drawtype = sublime.DRAW_NO_OUTLINE):\n\t\treg = self.DateToRegion(date)\n\t\tregs = self.output.get_regions(key)\n\t\tif not regs:\n\t\t\tregs = []\n\t\tregs.append(reg)\n\t\tself.output.add_regions(key,regs,highlight,\"\",drawtype)\t\n\n\n\tdef MapRowColToDate(self,row,col):\n\t\tweekid   = int(row - self.headingLines)\n\t\tmonthid  = int(col / self.columnsPerMonth)\n\t\tdayid    = int((col % self.columnsPerMonth) / self.columnsPerDay)\n\t\tday      = self.monthdata[monthid][weekid][dayid]\n\t\tmonth    = monthid + self.midmonth - 1\n\t\tyear     = self.cdate.start.year\n\t\ttime     = self.cdate.start.time()\n\t\tduration = None\n\t\tif(time):\n\t\t\tresult = datetime.datetime(year, month, day, time.hour, time.minute, time.second, time.microsecond)\n\t\telse:\n\t\t\tresult = datetime.datetime(year, month, day)\n\t\treturn result\n\n\n\tdef MoveCDateToNextDay(self):\n\t\tself.cdate.add_days(1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToPrevDay(self):\n\t\tself.cdate.add_days(-1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToNextWeek(self):\n\t\tself.cdate.add_days(7)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToPrevWeek(self):\n\t\tself.cdate.add_days(-7)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToNextMonth(self):\n\t\tself.cdate.add_months(1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef MoveCDateToPrevMonth(self):\n\t\tself.cdate.add_months(-1)\n\t\tself.ReShow()\n\t\tself.HighlightDay(self.cdate.start)\n\n\tdef ReShow(self):\n\t\tnow = self.cdate.start\n\t\tmid = (now.month - self.midmonth + 1)\n\t\tif(mid < 0 or mid > 2):\n\t\t\tself.Render(now)\n\t\t\tself.ResetRenderState()\n\n\t@staticmethod\n\tdef NextMonth(now):\n\t\tmonth = now.month + 1\n\t\tyear  = now.year\n\t\tif(month > 12):\n\t\t\tyear += 1\n\t\t\tmonth = 1\n\t\treturn (month, year)\n\n\t@staticmethod\n\tdef PrevMonth(now):\n\t\tmonth = now.month - 1\n\t\tyear  = now.year\n\t\tif(month <= 0):\n\t\t\tyear -= 1\n\t\t\tmonth = 12\n\t\treturn (month, year)\n\n\tdef Render(self,now):\n\t\tc = calendar.TextCalendar(calendar.SUNDAY)\n\t\tstr = c.formatmonth(now.year, now.month)\n\t\tcalendar.setfirstweekday(calendar.SUNDAY)\n\t\tself.midmonth  = now.month\n\t\tpmonth, pyear = DateView.PrevMonth(now)\n\t\tnmonth, nyear = DateView.NextMonth(now)\n\t\tself.monthdata = [ calendar.monthcalendar(pyear, pmonth),\n\t\t\t\t\t\t   calendar.monthcalendar(now.year, now.month),\n\t\t\t\t\t\t   calendar.monthcalendar(nyear, nmonth)]\n\t\t#print(str)\n\t\tm2 = str.split('\\n')\n\t\tmonth, year = DateView.NextMonth(now)\n\t\tstr = c.formatmonth(year, month)\n\t\t#print(str)\n\t\tm3 = str.split('\\n')\n\t\tmonth, year = DateView.PrevMonth(now)\n\t\tstr = c.formatmonth(year, month)\n\t\t#print(str)\n\t\tm1 = str.split('\\n')\n\n\t\tself.output.set_read_only(False)\n\t\tself.output.sel().clear()\n\t\tpt = self.output.text_point(self.startrow,0)\n\t\tself.output.sel().add(pt)\n\t\tl = max(len(m1),len(m2),len(m3))\n\t\tself.endrow = self.startrow + l\n\t\trow = self.startrow\n\t\tfor i in range(0,l):\n\t\t\tpt = self.output.text_point(row,0)\n\t\t\trow += 1\n\t\t\tml1 = m1[i] if i < len(m1) else \"\"\n\t\t\tml2 = m2[i] if i < len(m2) else \"\"\n\t\t\tml3 = m3[i] if i < len(m3) else \"\"\n\t\t\tline = \"{0:30}{1:30}{2:30}\".format(ml1,ml2,ml3)\n\t\t\tlreg = self.output.line(pt)\n\t\t\tlreg = sublime.Region(lreg.begin(), lreg.end() + 1)\n\t\t\tself.output.ReplaceRegion(lreg, line + \"\\n\")\n\n\t\tself.HighlightDay(now)\n\n\tdef ResetRenderState(self):\n\t\tself.output.set_read_only(True)\n\t\tself.output.set_scratch(True)\n\t\tself.output.set_name(\"DatePicker\")\n\n\nclass DatePicker:\n\tdef on_done(self, text):\n\t\tself.dateView.output.close()\n\t\tprint(\"INPUT DONE\")\n\t\tif(self.onDone):\n\t\t\tevt.Get().emit(self.onDone, self.dateView.cdate)\n\n\tdef on_canceled(self):\n\t\tself.dateView.output.close()\n\t\tif(self.onDone):\n\t\t\tevt.Get().emit(self.onDone, None)\n\n\tdef on_changed(self, text):\n\t\tprint(\"CHANGED: \" + text)\n\t\tself.dateView.cdate = OrgDateFreeFloating.from_str(text)\n\t\tif(self.dateView.cdate):\n\t\t\tself.dateView.HighlightDay(self.dateView.cdate.start)\n\t\tself.dateView.ReShow()\n\n\tdef __init__(self):\n\t\tself.dateView = DateView()\n\t\tself.months = []\n\n\tdef MapRowColToNewDate(self,row,col):\n\t\ttime     = self.dateView.cdate.start.time()\n\t\tduration = None\n\t\tif(self.dateView.cdate.has_end()):\n\t\t\tduration = self.dateView.cdate.end - self.dateView.cdate.start\n\t\tself.dateView.cdate._start = self.dateView.MapRowColToDate(row,col)\n\t\tif(duration):\n\t\t\tself.dateView.cdate._end = self.dateView.cdate.start + duration\n\t\tself.inputpane.ReplaceRegion(self.inputpane.line(self.inputpane.text_point(0,0)), OrgDate.format_datetime(self.dateView.cdate.start))\n\t\tself.HighlightDay(self.dateView.cdate.start)\n\n\tdef RefreshInputPanelFromDateView(self):\n\t\tself.inputpane.ReplaceRegion(self.inputpane.line(self.inputpane.text_point(0,0)), OrgDate.format_datetime(self.dateView.cdate.start))\n\n\tdef MoveNextDay(self):\n\t\tself.dateView.MoveCDateToNextDay()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MovePrevDay(self):\n\t\tself.dateView.MoveCDateToPrevDay()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MoveNextWeek(self):\n\t\tself.dateView.MoveCDateToNextWeek()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MovePrevWeek(self):\n\t\tself.dateView.MoveCDateToPrevWeek()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MoveNextMonth(self):\n\t\tself.dateView.MoveCDateToNextMonth()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef MovePrevMonth(self):\n\t\tself.dateView.MoveCDateToPrevMonth()\n\t\tself.RefreshInputPanelFromDateView()\n\n\tdef Show(self,now, onDone):\n\t\tself.onDone\t= onDone\n\t\twindow      = sublime.active_window()\n\t\tself.output = CreateUniqueViewNamed(\"DatePicker\")\n\t\tself.dateView.SetView(self.output)\n\t\tself.dateView.Render(now)\n\t\tself.dateView.ResetRenderState()\n\t\tcurstr = OrgDate.format_datetime(now)\n\t\tself.cdate = OrgDateFreeFloating.from_str(curstr)\n\t\tself.inputpane = window.show_input_panel(\n\t\t\t\t\t\"Date:\",\n\t\t\t\t\tcurstr,\n\t\t\t\t\tself.on_done,\n\t\t\t\t\tself.on_changed,\n\t\t\t\t\tself.on_canceled)\n\t\tpt = self.inputpane.text_point(0,0)\n\t\tself.inputpane.set_syntax_file(\"Packages/OrgExtended/orgdateeditor.sublime-syntax\")\n\n# =============================================================\ndatePicker = None\n\ndef is_pt_date_view(view, pt):\n    return 'source.orgdatepicker' in view.scope_name(pt)\n\ndef onMouse(pt, view, edit):\n    if(not is_pt_date_view(view, pt)):\n    \treturn\n    row, col = view.rowcol(pt)\n    if(datePicker):\n    \tdatePicker.MapRowColToNewDate(row,col)\n    # TODO Convert point back to a date and push that into\n    #      the input box.\n\ndef SetupMouse():\n\tevt.Get().on(\"orgmouse\",onMouse)\n\n\nclass AOrgDatePickerCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker = DatePicker()\n\t\tdatePicker.Show(datetime.datetime.now(),None)\n\nclass AOrgDatePickerNextDayCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MoveNextDay()\n\nclass AOrgDatePickerPrevDayCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MovePrevDay()\n\nclass AOrgDatePickerPrevWeekCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MovePrevWeek()\n\nclass AOrgDatePickerNextWeekCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tprint(\"NEXT WEEK 1\")\n\t\tglobal datePicker\n\t\tdatePicker.MoveNextWeek()\n\nclass AOrgDatePickerPrevMonthCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MovePrevMonth()\n\nclass AOrgDatePickerNextMonthCommand(sublime_plugin.TextCommand):\n\tdef run(self, edit):\n\t\tglobal datePicker\n\t\tdatePicker.MoveNextMonth()\n\ndef Pick(onDone):\n\tglobal datePicker\n\tdatePicker = DatePicker()\n\tdatePicker.Show(datetime.datetime.now(), onDone)\n"
  },
  {
    "path": "orgtableformula.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\n# from pathlib import Path\nimport os\n# import fnmatch\n# import OrgExtended.orgparse.node as node\nimport OrgExtended.orgutil.util as util\nimport logging\n# import sys\nimport traceback\nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orginsertselected as ins\nimport OrgExtended.simple_eval as simpev\nimport OrgExtended.orgextension as ext\nimport OrgExtended.orgparse.date as orgdate\nimport OrgExtended.orgduration as orgduration\nimport OrgExtended.orgtableplot as orgplot\nimport OrgExtended.orglinks as olinks\nimport math\nimport random\nimport ast\n# import operator as op\n# import subprocess\n# import platform\n# import time\n# import json\n# import ast\n# import random\n\nrandom.seed()\nRE_TABLE_LINE   = re.compile(r'\\s*[|]')\nRE_PRINTFSTYLE = re.compile(r\"(?P<formatter>[%][0-9]*\\.[0-9]+f)\")\nRE_ISCOMMENT = re.compile(r\"^\\s*[#][+]\")\nRE_AUTOLINE = re.compile(r\"^\\s*[|]\\s*[#]\\s*[|]\")\nRE_AUTOCOMPUTE = re.compile(r\"^\\s*[|]\\s*(?P<a>[#_$^*!/ ])\\s*[|]\")\nRE_END_BLOCK   = re.compile(r'^\\s*[#][+](END|end)[:]\\s*')\nMAX_STRING_LENGTH = 100000\nMAX_COMPREHENSION_LENGTH = 10000\nMAX_POWER = 4000000  # highest exponent\n\nhighlightEnabled = True\n\nlog = logging.getLogger(__name__)\n\n\ndef isTable(view, at=None):\n    if (at is None):\n        at = view.sel()[0].end()\n    names = view.scope_name(at)\n    return 'orgmode.table' in names\n\n\ndef isTableFormula(view):\n    names = view.scope_name(view.sel()[0].end())\n    return 'orgmode.tblfm' in names\n\n\ndef isTableLine(line):\n    return RE_TABLE_LINE.search(line)\n\n\ndef isAutoComputeRow(view):\n    return RE_AUTOLINE.search(view.curLineText()) is not None\n\n\nopsTable = None\n\n\ndef GetOps():\n    global opsTable\n    if (opsTable is None):\n        o = simpev.DEFAULT_OPERATORS.copy()\n        o[ast.Mult]  = safe_mult\n        o[ast.Add]   = safe_add\n        o[ast.Pow]   = safe_pow\n        o[ast.Sub]   = tsub\n        o[ast.Div]   = tdiv\n        o[ast.Mod]   = tmod\n        o[ast.Eq]    = teq\n        o[ast.NotEq] = tneq\n        o[ast.Gt]    = tgt\n        o[ast.Lt]    = tlt\n        o[ast.GtE]   = tge\n        o[ast.LtE]   = tle\n        o[ast.Not]   = tnot\n        o[ast.USub]  = tusub\n        o[ast.UAdd]  = tuadd\n        opsTable     = o\n    return opsTable\n\n\ndef add_dynamic_symbols(s):\n    exts = sets.Get(\"enableTableExtensions\", None)\n    if (exts):\n        dynamic = ext.find_extension_modules('orgtable', [])\n        for k in dynamic.keys():\n            if (hasattr(dynamic[k], \"AddSymbols\")):\n                try:\n                    dynamic[k].AddSymbols(s)\n                except Exception:\n                    log.error(\"Failed to add symbols from: \" + str(k) + \"\\n\" + traceback.format_exc())\n            else:\n                if (not hasattr(dynamic[k], \"Execute\")):\n                    log.warning(\"Dynamic table module does not have method AddSymbols, cannot use: \" + k)\n\n\nconstsTable = None\n\n\ndef GetConsts():\n    global constsTable\n    reloadExtensions = sets.Get(\"forceLoadExternalExtensions\", False)\n    if (constsTable is None or reloadExtensions):\n        n = simpev.DEFAULT_NAMES.copy()\n        n['pi']     = 3.1415926535897932385\n        n['t']      = True\n        n['true']   = True\n        n['True']   = True\n        n['false']  = False\n        n['False']  = False\n        n['nil']    = None\n        n['None']   = None\n        add_dynamic_symbols(n)\n        constsTable = n\n    return constsTable\n\n\n# These are table extensions you would like to add\n# for performance reasons we only reload them when you start sublime\n# you can however turn on forceLoadExternalExtensions to reload the\n# extension dynamically ALL THE TIME. do not leave that one though!\ndef add_dynamic_functions(f):\n    exts = sets.Get(\"enableTableExtensions\",None)\n    if(exts):\n        dynamic = ext.find_extension_modules('orgtable', [])\n        for k in dynamic.keys():\n            if(hasattr(dynamic[k],\"Execute\")):\n                f[k] = dynamic[k].Execute\n            else:\n                if(not hasattr(dynamic[k],\"AddSymbols\")):\n                    log.warning(\"Dynamic table module does not have method Execute, cannot use: \" + k)\n\n\nfunctionsTable = None\ndef GetFunctions():\n    global functionsTable\n    reloadExtensions = sets.Get(\"forceLoadExternalExtensions\",False)\n    if(functionsTable == None or reloadExtensions):\n        f = simpev.DEFAULT_FUNCTIONS.copy()\n        f['vmean'] = vmean\n        f['vmedian'] = vmedian\n        f['vmax'] = vmax\n        f['vmin'] = vmin\n        f['vsum'] = vsum\n        f['vsumifeq'] = vsumifeq\n        f['vsumifgt'] = vsumifgt\n        f['vsumiflt'] = vsumiflt\n        f['vsumifgteq'] = vsumifgteq\n        f['vsumiflteq'] = vsumiflteq\n        f['tan'] = tan\n        f['cos'] = cos\n        f['sin'] = sin\n        f['atan'] = atan\n        f['acos'] = acos\n        f['asin'] = asin\n        f['tanh'] = tanh\n        f['cosh'] = cosh\n        f['sinh'] = sinh\n        f['atanh'] = atanh\n        f['acosh'] = acosh\n        f['asinh'] = asinh\n        f['degrees'] = degrees\n        f['radians'] = radians\n        f['exp'] = exp\n        f['sqrt'] = sqrt\n        f['pow'] = pow\n        f['log'] = mylog\n        f['log10'] = mylog10\n        f['log2'] = mylog2\n        f['floor'] = myfloor\n        f['ceil'] = myceil\n        f['round'] = myround\n        f['trunc'] = mytrunc\n        f['remote'] = remote\n        f['now'] = mynow\n        f['year'] = myyear\n        f['day'] = myday\n        f['month'] = mymonth\n        f['hour'] = myhour\n        f['minute'] = myminute\n        f['second'] = mysecond\n        f['time'] = mytime\n        f['date'] = mydate\n        f['weekday'] = myweekday\n        f['yearday'] = myyearday\n        f['duration'] = myduration\n        f['randomf'] = randomFloat\n        f['random'] = randomDigit\n        f['abs'] = myabs\n        f['bool'] = mybool\n        f['int'] = myint\n        f['float'] = myfloat\n        f['highlight'] = myhighlight\n        f['red'] = myred\n        f['green'] = mygreen\n        f['yellow'] = myyellow\n        f['blue'] = myblue\n        f['cyan'] = mycyan\n        f['purple'] = mypurple\n        f['orange'] = myorange\n        f['pink'] = mypink\n        f['gradient'] = mygradient\n        f['filename'] = mylocalfile\n        add_dynamic_functions(f)\n        functionsTable = f\n    return functionsTable\n\nclass TableCache:\n    def __init__(self):\n        self.cachedTables = {}\n        self.change_count = -1\n\n    def _ViewName(self,view):\n        name = view.file_name()\n        if(not name):\n            name = \"view_\" + view.id()\n        return name\n\n    def _FindTable(self,row,view):\n        name = self._ViewName(view)\n        if(not name in self.cachedTables):\n            self.cachedTables[name] = {'cnt': view.change_count(), 'tbls': []}\n        cache = self.cachedTables[name]\n        cnt = cache['cnt']\n        if(cnt >= view.change_count()):\n            tcache = cache['tbls']\n            for t in tcache:\n                if row >= t[0][0] and row <= t[0][1]:\n                    return t[1]\n        else:\n            self.change_count = view.change_count()\n            self.cachedTables[name] = {'cnt': view.change_count(), 'tbls': []}\n        return None\n\n    def GetTable(self,view,at=None):\n        row = view.curRow()\n        if(at != None):\n            row,_ = view.rowcol(at)\n        td = self._FindTable(row,view)\n        if(not td):\n            td = create_table(view,at)\n            name = self._ViewName(view)\n            self.cachedTables[name]['tbls'].append(((td.start,td.end),td))\n        return td\n\ntableCache = TableCache()\n\ndef TableConversion(indentDepth,data):\n    # figure out what our separator is.\n    # replace the separator with |\n    indent = \"\"\n    if(indentDepth > 0):\n        indent = (\" \" * indentDepth) + \" \"\n    try:\n        # Try AST and see if we can parse it that way.\n        # This if for things like: [[a,b,c],[1,2,3],[4,5,6]]\n        l = ast.literal_eval(data)\n        d = \"\"\n        if(isinstance(l,list)):\n            for r in l:\n                if (isinstance(r,list)):\n                    d += indent + \"|\"\n                    for c in r:\n                        d += str(c) + \"|\"\n                else:\n                    d += \"|\" + str(r) + \"|\"\n                d += \"\\n\"\n            return (d, True)\n    except:\n        # It is okay if we fail.\n        pass\n    # Nope use the heuristic processing way.\n    lines = data.split('\\n')\n    separator = ','\n    possibles = {\",\": [], \";\": [], \"\\t\": [], \" \": []}\n    for l in lines:\n        if(l.strip() == \"\"):\n            continue\n        for k,v in possibles.items():\n            v.append(l.count(k))\n    vars = {}\n    for k,d in possibles.items():\n        s = sum(d) \n        mean = s / len(d)\n        if(mean > 0):\n            variance = math.sqrt(sum([ (x-mean)*(x-mean) for x in d ]) / len(d))\n            vars[k] = variance\n    #print(str(vars))\n    separator = min(vars, key=vars.get) \n    # We prefer comma if the variance is the same for the min and comma.\n    if(separator != ',' and ',' in vars and vars[','] == vars[separator]):\n        separator = ','\n    log.info(\"SEPARATOR CHOSEN: \" + separator)\n    data = \"\"\n    for l in lines:\n        if(l.strip() == \"\"):\n            continue\n        data += indent + '|' + l.strip().replace(separator,'|') + '|\\n'\n    return (data, True)\n\n\ndef insert_file_data(indentDepth, data, view, edit, onDone=None, replace=False):\n    data,_ = TableConversion(indentDepth, data)\n    if(replace):\n        view.run_command(\"org_internal_replace\", {\"start\": view.sel()[0].begin(), \"end\": view.sel()[0].end(), \"text\": data, \"onDone\": onDone})\n    else:\n        view.run_command(\"org_internal_insert\", {\"location\": view.sel()[0].begin(), \"text\": data, \"onDone\": onDone})\n\n\nclass OrgConvertSelectionToTableCommand(sublime_plugin.TextCommand):\n    def OnDone(self):\n        self.view.sel().clear()\n        self.view.sel().add(sublime.Region(self.pos.begin() +1, self.pos.begin()+1))\n        self.view.run_command('table_editor_next_field')\n        evt.EmitIf(self.onDone)\n\n    def run(self, edit, onDone=None):\n        self.edit = edit\n        self.onDone = onDone\n        self.pos = self.view.sel()[0]\n        curNode = db.Get().AtInView(self.view)\n        level = 1\n        if(None != curNode):\n            level = curNode.level\n        fileData = self.view.substr(self.view.sel()[0])\n        if(len(fileData) > 6):\n            insert_file_data(level,fileData,self.view, self.edit, evt.Make(self.OnDone), True)\n\ntable_phantoms = []\n\nclass OrgHideTableRowsCommand(sublime_plugin.TextCommand):\n    def OnDone(self):\n        evt.EmitIf(self.onDone)\n    def run(self, edit, onDone=None):\n        self.onDone = onDone\n        for f in table_phantoms:\n            self.view.erase_phantoms(f)\n        self.OnDone()\n\n\nclass OrgShowTableRowsCommand(sublime_plugin.TextCommand):\n    def OnDone(self):\n        evt.EmitIf(self.onDone)\n\n    def ToRomanNumeral(self,input):\n        if not 0 < input < 4000:\n            raise ValueError(\"Argument must be between 1 and 3999\")\n        ints = (1000, 900,  500, 400, 100,  90, 50,  40, 10,  9,   5,  4,   1)\n        nums = ('M',  'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')\n        result = []\n        for i in range(len(ints)):\n            count = int(input / ints[i])\n            result.append(nums[i] * count)\n            input -= ints[i] * count\n        return ''.join(result)\n\n    def RowToCellRow(self,r):\n        for i in range(1,len(self.td.lineToRow)+1):\n            if(self.td.lineToRow[i] == r):\n                return str(i)\n        count = 0;\n        for h in self.td.hlines:\n            if h == r:\n                return self.ToRomanNumeral(count+1)\n            ++count\n        return \"U\"\n    def run(self, edit, onDone=None):\n        self.onDone = onDone\n        self.td = create_table(self.view)\n        if(self.td):\n            hline = self.td.start-1\n            if(self.td.hlines and len(self.td.hlines) > 0):\n                hline = self.td.hlines[0]\n            line = self.view.line(self.view.text_point(self.td.start,0))\n            indent = self.view.substr(line).find(\"|\")\n            for r in range(self.td.start,self.td.end+1):\n                pt = self.view.text_point(r,indent)\n                region = sublime.Region(pt,pt)\n                idx = self.RowToCellRow(r)\n                body = \"\"\"\n                <body id=\"table-index-popup\">\n                <style>\n                    div.heading {{\n                        color: #880077;\n                        padding: 0px;\n                        font-weight: bold;\n                        }}\n                </style>\n                <div class=\"heading\">{0}</div>\n                </body>\n                \"\"\".format(idx)\n                key = \"table_\" + str(self.td.start) + \"_row_\" + str(r)\n                table_phantoms.append(key)\n                self.view.add_phantom(\"table_\" + str(self.td.start) + \"_row_\" + str(r),region,body,sublime.LAYOUT_INLINE)\n                for c in range(1,self.td.Width()+1):\n                    if(not idx.isnumeric()):\n                        break\n                    #print(\"II: \" + str(idx) + \"x\" + str(c))\n                    reg = self.td.FindCellRegion(int(idx),c)\n                    if(not reg):\n                        continue\n                    row,col = self.view.rowcol(reg.begin())\n                    pt1 = self.view.text_point(row,col)\n                    pt2 = self.view.text_point(self.td.end,col)\n                    region = sublime.Region(pt1,pt1)\n                    body = \"\"\"\n                    <body id=\"table-index-popup\">\n                    <style>\n                        div.heading {{\n                            color: #880077;\n                            padding: 0px;\n                            font-weight: bold;\n                            }}\n                    </style>\n                    <div class=\"heading\">{0}</div>\n                    </body>\n                    \"\"\".format(c)\n                    key = \"table_\" + str(self.td.start) + \"_row_\"+str(r)+\"_col_\" + str(c)\n                    table_phantoms.append(key)\n                    self.view.add_phantom(key,region,body,sublime.LAYOUT_INLINE)\n                #p = Phantom(region, content, sublime.LAYOUT_INLINE)\n                #phantoms.append(p)\n        self.OnDone()\n\nclass OrgPlotTableCommand(sublime_plugin.TextCommand):\n    def OnDone(self):\n        if(None != self.origCur):\n            self.view.sel().clear()\n            self.view.sel().add(self.origCur)\n        evt.EmitIf(self.onDone)\n\n    def run(self, edit, onDone=None):\n        self.onDone = onDone\n        if(self.view.sel()):\n            self.origCur = self.view.sel()[0]\n        row = self.view.curRow()\n        line = self.view.getLine(row)\n        if(\"#+PLOT:\" in line):\n            pt = self.view.text_point(row,0)\n            while(not isTable(self.view,pt)):\n                row += 1\n                pt = self.view.text_point(row,0)\n            self.origCur = pt\n            self.view.sel().clear()\n            self.view.sel().add(self.origCur)\n        self.td = create_table(self.view)\n        orgplot.plot_table_command(self.td,self.view) \n        self.edit = edit\n        self.view.run_command(\"org_cycle_images\",{\"onDone\": evt.Make(self.OnDone)})\n\n# Grab the function table and dump a table of all the functions and their doc strings.\n# Build a table of that information.\nclass OrgDocTableCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        td = create_table(self.view)\n        out = \"\"\n        keys = list(td.functions.keys())\n        keys.sort()\n        for k in keys:\n            v = td.functions[k]\n            if(k == \"ridx\" or k == \"cidx\" or k == \"symorcell\" or k == \"getcell\" or k == \"getcolcell\" or k == \"getrowcell\"):\n                continue\n            if(not v.__doc__):\n                out += \"  - \" + k + \" :: \" +  \"Not Yet Documented \\n\"\n            else:\n                out += \"  - \" + k + \" :: \" + str(v.__doc__).replace(\"\\n\",\"\\n      \") + \"\\n\"\n        out += \"----------------------NAMES--------------------------------\\n\"\n        for k,v in td.names.items():\n            out += \"  - \" + k + \" :: \" +  str(v) + \" \\n\"\n        self.view.insert(edit,self.view.line(self.view.size()).begin(),out)\n\n\nclass OrgImportTableFromCsvCommand(sublime_plugin.TextCommand):\n    def OnFile(self, filename=None):\n        self.inHan = None\n        if(None == filename):\n            return\n        if(os.path.exists(filename) and os.path.isfile(filename)):\n            fileData = \"\"\n            with open(filename,'r') as f:\n                fileData = f.read()\n            self.pos = self.view.sel()[0]\n            curNode = db.Get().AtInView(self.view)\n            level = 1\n            if(None != curNode):\n                level = curNode.level\n            insert_file_data(level,fileData,self.view, self.edit, evt.Make(self.OnDone))\n\n    def OnDone(self):\n        self.view.sel().clear()\n        self.view.sel().add(sublime.Region(self.pos.begin() +1, self.pos.end()+1))\n        self.view.run_command('table_editor_next_field')\n        evt.EmitIf(self.onDone)\n\n    def run(self, edit, onDone=None):\n        self.edit = edit\n        self.onDone = onDone\n        self.inHan = ins.OrgInput()\n        self.inHan.isFileBox = True\n        self.inHan.run(\"CSV\", None, evt.Make(self.OnFile))\n\nclass OrgInsertBlankTableCommand(sublime_plugin.TextCommand):\n    def OnDims(self, text):\n        if(text == None):\n            return\n        dims = text.split('x')\n        if(len(dims) != 2):\n            log.error(\"DIMENSIONS ARE NOT RIGHT!\")\n            return\n        w = int(dims[0])\n        h = int(dims[1])\n        curNode = db.Get().AtInView(self.view)\n        level = 1\n        if(None != curNode):\n            level = curNode.level\n        indent = (\" \" * level) + \" \"\n        data = \"\"\n        for y in range(0,h+1):\n            line = indent + \"|\"\n            for x in range(0,w):\n                line += \"|\"\n            data += line + '\\n'\n            if(y == 0):\n                data += '|-\\n'\n        self.pos = self.view.sel()[0]\n        self.view.run_command(\"org_internal_insert\", {\"location\": self.view.sel()[0].begin(), \"text\": data, \"onDone\": self.onDone})\n        self.OnDone()\n\n    def OnDone(self):\n        self.view.sel().clear()\n        self.view.sel().add(sublime.Region(self.pos.begin() +1, self.pos.end()+1))\n        self.view.run_command('table_editor_next_field')\n        evt.EmitIf(self.onDone)\n\n    def run(self, edit, onDone=None):\n        self.edit = edit\n        self.onDone = onDone\n        self.input = ins.OrgInput()\n        self.input.run(\"WxH\", None, evt.Make(self.OnDims))\n\nRE_TABLE_HLINE  = re.compile(r'\\s*[|][-][+-]*[|]')\nRE_FMT_LINE     = re.compile(r'\\s*[#][+](TBLFM|tblfm)[:]\\s*(?P<expr>.*)')\nRE_TARGET       = re.compile(r'\\s*(([@](?P<rowonly>[-]?[0-9><]+))|([$](?P<colonly>[-]?[0-9><]+))|([@](?P<row>[-]?[0-9><]+)[$](?P<col>[-]?[0-9><]+)))\\s*$')\nRE_NAMED_TARGET = re.compile(r'\\s*[$](?P<name>[a-zA-Z][a-zA-Z0-9]+)')\ndef formula_rowcol(expr,table):\n    fields = expr.split('=')\n    if(len(fields) < 2):\n        return (None, None, None)\n    target = fields[0]\n    formula = \"=\".join(fields[1:]) if len(fields[1:]) > 1 else fields[1]\n    targets = target.split('..')\n    if(len(targets)==2):\n        r1 = formula_rowcol(targets[0] + \"=\",table)\n        r2 = formula_rowcol(targets[1] + \"=\",table)\n        return [r1[0] + r2[0],formula,None]\n    m = RE_TARGET.search(target)\n    if(m):\n        row = m.group('row')\n        col = m.group('col')\n        if not row and not col:\n            row = m.group('rowonly')\n            if(row):\n                if(isNumeric(row)):\n                    row = int(row)\n                col = '*'\n                return [[row,col],formula,None]\n            else:\n                col = m.group('colonly')\n                if(isNumeric(col)):\n                    col = int(col)\n                row = '*'\n                return [[row,col],formula,None]\n        else:\n            if(isNumeric(row)):\n                row = int(row)\n            if(isNumeric(col)):\n                col = int(col)\n            return [[row,col],formula,None]\n    else:\n        mn = RE_NAMED_TARGET.search(target)\n        if(mn):\n            cell = table.symbolOrCell(mn.group('name').strip())\n            if(isinstance(cell,Cell)):\n                return [[cell.r,cell.c],formula,cell.rowFilter]\n    return (None, None, None)\n\ndef isNumeric(v):\n    return v.strip().lstrip('-').lstrip('+').isnumeric()\n\ndef isFunc(v):\n    return 'ridx()' in v or 'cidx()' in v\n\nRE_TARGET_A  = re.compile(r'\\s*(([@](?P<row>(?P<rsign>[+-])?([0-9]+)|([>]+)|([<]+)|[#])[$](?P<col>((?P<csign>[+-])?([0-9]+)|([>]+)|([<]+)|[#])|(ridx\\(\\))|(cidx\\(\\))))|([@](?P<rowonly>((?P<rosign>[+-])?([0-9]+)|([>]+)|([<]+)|[#])|(ridx\\(\\))|(cidx\\(\\))))|([$](?P<colonly>((?P<cosign>[+-])?([0-9]+)|([>]+)|([<]+)|[#])|(ridx\\(\\))|(cidx\\(\\)))))(?P<end>[^@$]|$)')\nRE_ROW_TOKEN = re.compile(r'[@][#]')\nRE_COL_TOKEN = re.compile(r'[$][#]')\nRE_SYMBOL_OR_CELL_NAME = re.compile(r'[$](?P<name>[a-zA-Z][a-zA-Z0-9_-]*)')\ndef replace_cell_references(expr):\n    #print(\"EXPS: \" + str(expr))\n    while(True):\n        expr = RE_ROW_TOKEN.sub('ridx()',expr)\n        expr = RE_COL_TOKEN.sub('cidx()',expr)\n        m = RE_TARGET_A.search(expr)\n        if(m):\n            row = m.group('row')\n            col = m.group('col')\n            rs  = m.group('rsign')\n            cs  = m.group('csign')\n            end = m.group('end')\n            if(not end):\n                end = \"\"\n            if not row and not col:\n                row = m.group('rowonly')\n                if(row):\n                    rs = m.group('rosign')\n                    rs = '1' if rs else '0'\n                    if(isNumeric(row) or isFunc(row)):\n                        expr = RE_TARGET_A.sub(' getrowcell(' + str(row) + ',' + rs + ') ' + end,expr,1)\n                    else:\n                        expr = RE_TARGET_A.sub(' getrowcell(\\'' + str(row) + '\\''+\",\"+rs+') ' + end,expr,1)\n                else:\n                    col = m.group('colonly')\n                    cs = m.group('cosign')\n                    cs = '1' if cs else '0'\n                    if(isNumeric(col) or isFunc(col)):\n                        expr = RE_TARGET_A.sub(' getcolcell(' + str(col) + ',' + cs + ') ' + end,expr,1)\n                    else:\n                        expr = RE_TARGET_A.sub(' getcolcell(\\'' + str(col) + '\\'' +\",\"+cs+ ') ' + end,expr,1)\n            else:\n                rowmarkers = '' if isNumeric(row) or isFunc(row) else '\\''\n                colmarkers = '' if isNumeric(col) or isFunc(col) else '\\''\n                cs = '1' if cs else '0'\n                rs = '1' if rs else '0'\n                expr = RE_TARGET_A.sub(' getcell(' + rowmarkers + str(row) + rowmarkers + \",\" + rs + \",\" + colmarkers + str(col) + colmarkers + \",\" + cs + \") \" + end,expr,1)\n        else:\n            break\n    while(True):\n        m = RE_SYMBOL_OR_CELL_NAME.search(expr)\n        if(m):\n            name = m.group('name')\n            expr = RE_SYMBOL_OR_CELL_NAME.sub(' symorcell(\\'' + name + '\\') ',expr,1)\n        else:\n            break\n    #print(\"EXP: \" + str(expr))\n    return expr\n\ndef formula_sources(expr):\n    ms = RE_TARGET.findall(expr)\n    matches = []\n    for m in ms:\n        row = m.group('row')\n        col = m.group('col')\n        if not row and not col:\n            row = m.group('rowonly')\n            if(row):\n                row = int(row)\n                col = '*'\n                matches.append([row,col])\n            else:\n                col = m.group('colonly')\n                col = int(col)\n                row = '*'\n                matches.append([row,col])\n        else:\n            row = int(row)\n            col = int(col)\n            matches.append([row,col])\n    return matches\n\n# ============================================================\nclass Formula:\n    def __init__(self,raw, expr, reg, formatters, table):\n        self.raw = raw\n        self.table = table\n        self.formatters = formatters\n        self.printfout = None\n        if(self.formatters):\n            m = RE_PRINTFSTYLE.search(self.formatters)\n            if(m):\n                self.printfout = m.group('formatter')\n        self.target, self.expr, self.rowFilter = formula_rowcol(expr,table)\n        # print(\"TARGET: \" + str(self.target) + \" -> \" + str(expr))\n        # Never allow our expr to be empty. If we failed to parse it our EXPR is current cell value\n        if(self.expr == None):\n            self.expr = \"$0\"\n        if(self.target == None):\n            self.target = \"@0$0\"\n        self.expr = replace_cell_references(self.expr.replace(\"..\",\"//\"))\n        self.formula   = expr\n        self.reg = reg \n    def EmptyIsZero(self):\n        return 'N' in self.formatters\n\ndef CellRowIterator(table,start,end, arit=None, brit=None):\n    c = table.CurCol()\n    if not arit:\n        arit = NullFilter()\n    if not brit:\n        brit = NullFilter()\n    if(start < table.StartRow()):\n        start = table.StartRow()\n    for r in range(start,end+1):\n        if(table.ShouldIgnoreRow(r) or arit.filter(r) or brit.filter(r)):\n            continue\n        cell = Cell(r,c,table)\n        yield cell\n\ndef CellColIterator(table,start,end):\n    r = table.CurRow()\n    for c in range(start,end+1):\n        cell = Cell(r,c,table)\n        yield cell\n\ndef CellBoxIterator(table,a,b):\n    sr = a.GetRow()\n    er = b.GetRow()\n    if(a.GetRow() > b.GetRow()):\n        sr = b.GetRow()\n        er = a.GetRow()\n    sc = a.GetCol()\n    ec = b.GetCol()\n    if(a.GetCol() > b.GetCol()):\n        sc = b.GetCol()\n        ec = a.GetCol()\n    if(sr < table.StartRow()):\n        sr = table.StartRow()\n    for r in range(sr,er+1):\n        if(table.ShouldIgnoreRow(r) or a.ShouldIgnoreRow(r) or b.ShouldIgnoreRow(r)):\n            continue\n        for c in range(sc,ec+1):\n            cell = Cell(r,c,table)\n            yield cell\n\ndef CellIterator(table,cell):\n    r = cell.r\n    c = cell.c\n    filter = cell.rowFilter\n    if(None == filter):\n        filter = NullFilter()\n    if(r == '*'):\n        rrange = range(table.StartRow(),table.Height()+1)\n    else:\n        rrange = range(cell.GetRow(),cell.GetRow()+1)\n    if(c == '*'):\n        crange = range(table.StartCol(),table.Width()+1)\n    else:\n        crange = range(cell.GetCol(),cell.GetCol()+1)\n    for r in rrange:\n        if(table.ShouldIgnoreRow(r) or filter.filter(r)):\n            continue\n        for c in crange:\n            cell = Cell(r,c,table)\n            yield cell\n\ndef RCIterator(table,r,c):\n    if(r == '*'):\n        rrange = range(table.StartRow(),table.Height()+1)\n    else:\n        rrange = range(r,r+1)\n    if(c == '*'):\n        crange = range(table.StartCol(),table.Width()+1)\n    else:\n        crange = range(c,c+1)\n    for r in rrange:\n        if(table.ShouldIgnoreRow(r)):\n            continue\n        for c in crange:\n            yield [r,c]\n\n# ============================================================\n# This represents a cell REFERENCE in the table.\n# It has a reference to the table itself and looks\n# up the actual data dynamically WHEN ASKED TO!\n# That is important since the current target changes\n# and many cell references are RELATIVE to the current\n# target.\nclass Cell:\n    def __init__(self,r,c,table,rrelative=0,crelative=0,rowFilter=None):\n        self.r = r\n        self.c = c\n        self.table = table\n        self.rrelative = rrelative\n        self.crelative = crelative\n        self.rowFilter = rowFilter\n\n    def __str__(self):\n        return self.GetText()\n\n    def __eq__(self, other):\n        if isinstance(other, Cell):\n            if self.r == other.r and self.c == other.c:\n                return True\n            return self.GetText() == other.GetText()\n        return NotImplemented\n\n    def rc(self):\n        return (self.r,self.c)\n\n    def ShouldIgnoreRow(self, r):\n        if(self.rowFilter):\n            rv = self.rowFilter.filter(r)\n            return rv\n        return False\n\n    def GetTable(self):\n        return self.table\n\n    def GetRow(self,height=None):\n        r = None\n        # We have to allow someone to pass in the height\n        # because remote tables don't like to be truncated\n        # to a local tables height!\n        if(height == None):\n            height = self.table.Height()\n        if(isinstance(self.r,str)):\n            if(self.r == \"*\"):\n                r = self.table.CurRow()\n            elif(self.r.startswith('>')):\n                cnt = len(self.r.strip())\n                r = height - (cnt-1)\n            elif(self.r.startswith(\"<\")):\n                cnt = len(self.r.strip())\n                r = self.table.StartRow() + (cnt-1)\n            else:\n                if(util.numberCheck(self.r)):\n                    r = int(self.r)\n        elif(self.r < 0 or self.rrelative):\n            r = self.table.CurRow() + self.r\n        elif(self.r == 0):\n            return self.table.CurRow()\n        else:\n            r = self.r\n        if(None == r):\n            r = self.table.CurRow()\n        if(r < 1):\n            r = 1\n        if(r > height):\n            r = height\n        return r\n\n    def GetCol(self,width=None):\n        c = None\n        # We have to allow someone to pass in the width\n        # because remote tables don't like to be truncated\n        # to a local tables width!\n        if(width==None):\n            width = self.table.Width()\n        if(isinstance(self.c,str)):\n            if(self.c == \"*\"):\n                c = self.table.CurCol()\n            elif(self.c.startswith(\">\")):\n                cnt = len(self.c.strip())\n                c = width - (cnt-1)\n            elif(self.c.startswith(\"<\")):\n                cnt = len(self.c.strip())\n                c = self.table.StartCol() + (cnt-1)\n            else:\n                if(util.numberCheck(self.c)):\n                    c = int(self.c)\n        elif(self.c < 0 or self.crelative):\n            c = self.table.CurCol() + self.c\n        elif(self.c == 0):\n            return self.table.CurCol()\n        else:\n            c = self.c\n        if(None == c):\n            c = self.table.CurCol()\n        if(c < 1):\n            c = 1\n        if(c > width):\n            c = width\n        return c\n\n    def GetText(self):\n        return self.table.GetCellText(self.GetRow(), self.GetCol())\n\n    def GetInt(self):\n        return int(self.GetText())\n\n    def GetFloat(self):\n        return float(self.GetText())\n\n    def GetVal(self):\n        txt = self.GetText().strip()\n        if(util.numberCheck(txt)):\n            if('.' in txt):\n                return float(txt)\n            return int(txt)\n        if(txt.endswith(\"%\")):\n            t = txt[:-1]\n            if(util.numberCheck(t)):\n                f = float(t)\n                f = (f / 100.0)\n                return f\n        l = txt.lower()\n        if(l == \"true\" or l == \"t\"):\n            return True\n        if(l == \"false\"):\n            return False\n        return txt\n    \n    def GetNum(self):\n        txt = self.GetText().strip()\n        if(util.numberCheck(txt)):\n            if('.' in txt):\n                return float(txt)\n            return int(txt)\n        if(txt.endswith(\"%\")):\n            t = txt[:-1]\n            if(util.numberCheck(t)):\n                f = float(t)\n                f = (f / 100.0)\n                return f\n        return 0\n\ndef GetVal(i):\n    if(isinstance(i,Cell)):\n        return i.GetVal()\n    return i\n\ndef GetNum(i):\n    if(isinstance(i,Cell)):\n        return i.GetNum()\n    return i\n\n# ============================================================\n#  Functions\n# ============================================================\n\nRE_END = re.compile(r\"^\\s*\\#\\+(END_SRC|end_src)\")\nRE_SRC_BLOCK = re.compile(r\"^\\s*\\#\\+(BEGIN_SRC|begin_src)\\s+(?P<name>[^: ]+)\\s*\")\ndef IsSourceFence(view,row):\n    #line = view.getLine(view.curRow())\n    line = view.getLine(row)\n    return RE_SRC_BLOCK.search(line) or RE_END.search(line)\n\nRE_ISCOMMENT = re.compile(r\"^\\s*[#][+]\")\ndef LookupNamedSourceBlockInFile(name):\n    view = sublime.active_window().active_view()\n    if(view):\n        node = db.Get().AtInView(view)\n        if(node):\n            # Look for named objects in the file.\n            names = node.names\n            if(names and name in names):\n                row = names[name]['row']\n                last_row = view.lastRow()\n                for r in range(row,last_row):\n                    if(IsSourceFence(view,r)):\n                        row = r\n                        break\n                    pt = view.text_point(r, 0)\n                    line = view.substr(view.line(pt))\n                    m = RE_ISCOMMENT.search(line)\n                    if(m):\n                        continue\n                    elif(line.strip() == \"\"):\n                        continue\n                    else:\n                        row = r\n                        break\n                pt = view.text_point(row,0)\n                reg = view.line(pt)\n                line = view.substr(reg)\n                if(IsSourceFence(view,row)):\n                    return pt\n    return None\n\n# This class lets us run an arbitrary source block\n# and place the result of that into a cell.\nclass SourceBlockExecute:\n    def __init__(self,cell):\n        self.cell = cell\n        self.r = cell.GetRow()\n        self.c = cell.GetCol()\n        self.i = cell.table.GetActiveFormula()\n        self.gotVal = False\n        self.val = None\n\n    def OnDoneFunction(self,otherParams=None):\n        print(\"ON DONE FNCT\")\n        if('preFormat' in otherParams):\n            data = otherParams['preFormat']\n            print(\"PRE FORMAT: \" + str(data))\n            table = self.cell.table\n            reg = table.FindCellRegion(self.r,self.c)\n            fmt = table.FormulaFormatter(self.i)\n            if(data and isinstance(data,float) and fmt and \"%\" in fmt):\n                data = fmt % data\n            print(\"REPLACING WITH: \" + str(data))\n            self.val = str(data)\n            if(self.gotVal):\n                sublime.active_window().active_view().run_command(\"org_internal_replace\", {\"start\": reg.begin(), \"end\": reg.end(), \"text\": str(data)})\n\n    def __getitem__(self,index):\n        if(self.val):\n            try:\n                l = ast.literal_eval(self.val)\n                rv = l[index]\n                self.gotVal = True\n                return rv\n            except:\n                pass\n        return \"<SBE>\"\n\n    def __str__(self):\n        self.gotVal = True\n        if(self.val):\n            return str(self.val)\n        else:\n            return \"<SBE>\"\n\n    def AdjustParams(self,otherParams=None):\n        if('cmd' in otherParams):\n            cmd = otherParams['cmd']\n            self.cmd = cmd\n            # We hack the results to be raw and silent with no formatting\n            # output or value is not something we want to overwrite\n            res = cmd.params.Get('results',None)\n            if(res):\n                if('value' in res):\n                    cmd.params.Replace('results',['raw','silent','value'])\n                else:\n                    cmd.params.Replace('results',['raw','silent','output'])\n            else:\n                cmd.params.Replace('results',['raw', 'silent'])\n            var = cmd.params.Get('var',None)\n            if(var):\n                for k in self.params:\n                    var[k] = self.params[k]\n\n    def run(self, name, kwargs):\n        self.params = kwargs\n        self.sourcefns = {}\n        pt = LookupNamedSourceBlockInFile(name)\n        if(None != pt):\n            if(not name in self.sourcefns):\n                self.sourcefns[name] = {'at': pt, 'name': name}\n                sublime.active_window().active_view().run_command('org_execute_source_block',{'at':pt, 'onDoneResultsPos': evt.Make(self.OnDoneFunction), 'onDoneFnName': name, 'onAdjustParams': evt.Make(self.AdjustParams), 'silent': True, 'skipSaveWarning': True})\n\n\n\ndef myabs(a):\n    \"\"\"Convert value to a positive value\"\"\"\n    return abs(GetVal(a))\n\ndef safe_mult(a, b):  # pylint: disable=invalid-name\n    if hasattr(a, '__len__') and b * len(a) > MAX_STRING_LENGTH:\n        raise IterableTooLong('Sorry, I will not evalute something that long.')\n    if hasattr(b, '__len__') and a * len(b) > MAX_STRING_LENGTH:\n        raise IterableTooLong('Sorry, I will not evalute something that long.')\n    a = GetVal(a)\n    b = GetVal(b)\n    if(isinstance(a,float) or isinstance(b,float)):\n        if(isinstance(a,str) or isinstance(b,str)):\n            return 0\n    return a * b\n\ndef safe_pow(a, b):  # pylint: disable=invalid-name\n    a = GetVal(a)\n    b = GetVal(b)\n    if abs(a) > MAX_POWER or abs(b) > MAX_POWER:\n        raise NumberTooHigh(\"Sorry! I don't want to evaluate {0} ** {1}\"\n                            .format(a, b))\n    return a ** b\n\n\ndef safe_add(a, b):  # pylint: disable=invalid-name\n    if hasattr(a, '__len__') and hasattr(b, '__len__'):\n        if len(a) + len(b) > MAX_STRING_LENGTH:\n            raise IterableTooLong(\"Sorry, adding those two together would\"\n                                  \" make something too long.\")\n    a = GetVal(a)\n    b = GetVal(b)\n    return a + b\n\ndef tsub(a, b):  # pylint: disable=invalid-name\n    return GetVal(a) - GetVal(b)\n\ndef tdiv(a, b):  # pylint: disable=invalid-name\n    return GetNum(a) / GetNum(b)\n\ndef tmod(a, b):  # pylint: disable=invalid-name\n    return GetVal(a) % GetVal(b)\n\ndef teq(a,b):\n    return GetVal(a) == GetVal(b)\n\ndef tneq(a,b):\n    return GetVal(a) != GetVal(b)\n\ndef tgt(a,b):\n    return GetVal(a) > GetVal(b)\n\ndef tlt(a,b):\n    return GetVal(a) < GetVal(b)\n\ndef tge(a,b):\n    return GetVal(a) >= GetVal(b)\n\ndef tle(a,b):\n    return GetVal(a) <= GetVal(b)\n\ndef tnot(a):\n    return not GetVal(a)\n\ndef tusub(a):\n    return - GetVal(a)\n\ndef tuadd(a):\n    return + GetVal(a)\n\ndef vmean(rng):\n    \"\"\"Computes the average value of a column or row. Takes a range of cells\"\"\"\n    n = 0\n    s = 0\n    for i in rng:\n        num = GetNum(i)\n        s += num\n        n += 1\n    if(n != 0):\n        return float(s) / float(n)\n    return 0\n\ndef vsum(rng):\n    \"\"\"Computes the sum of a range of cells\"\"\"\n    s = 0\n    for i in rng:\n        s += GetNum(i)\n    return s\n\n# Only adds a row from rng to the sum if a and b are equal.\ndef vsumifeq(a,b,rng,*opt):\n    \"\"\"Computes the sum of a range of cells where a == b last parameter of o means b is relative to original offset\"\"\"\n    s = 0\n    for i in rng:\n        a_r = a.GetTable().CurRow()\n        a_c = a.GetTable().CurCol()\n        b_r = b.GetTable().CurRow()\n        b_c = b.GetTable().CurCol()\n        i_r = i.GetRow()\n        i_c = i.GetCol()\n        a.GetTable().SetCurRow(i_r)\n        a.GetTable().SetCurCol(i_c)\n        va = GetVal(a)\n        vb = None\n        if opt == None or len(opt) == 0:\n            vb = GetVal(b)\n        a.GetTable().SetCurRow(a_r)\n        a.GetTable().SetCurCol(a_c)\n        b.GetTable().SetCurRow(b_r)\n        b.GetTable().SetCurCol(b_c)\n        if opt != None and len(opt) > 0:\n            vb = GetVal(b)\n        if va == vb:\n            s += GetNum(i)\n    return s\n\n# Only adds a row from rng to the sum if a > b.\ndef vsumifgt(a,b,rng):\n    \"\"\"Computes the sum of a range of cells where a > b\"\"\"\n    s = 0\n    for i in rng:\n        r = a.GetTable().CurRow()\n        c = a.GetTable().CurCol()\n        cr = i.GetRow()\n        cc = i.GetCol()\n        a.GetTable().SetCurRow(cr)\n        a.GetTable().SetCurCol(cc)\n        va = GetVal(a)\n        vb = GetVal(b)\n        a.GetTable().SetCurRow(c)\n        a.GetTable().SetCurCol(r)\n        if va > GetVal(vb):\n            s += GetNum(i)\n    return s\n\n# Only adds a row from rng to the sum if a < b.\ndef vsumiflt(a,b,rng):\n    \"\"\"Computes the sum of a range of cells where a < b\"\"\"\n    s = 0\n    for i in rng:\n        r = a.GetTable().CurRow()\n        c = a.GetTable().CurCol()\n        cr = i.GetRow()\n        cc = i.GetCol()\n        a.GetTable().SetCurRow(cr)\n        a.GetTable().SetCurCol(cc)\n        va = GetVal(a)\n        vb = GetVal(b)\n        a.GetTable().SetCurRow(c)\n        a.GetTable().SetCurCol(r)\n        if va < GetVal(vb):\n            s += GetNum(i)\n    return s\n\n# Only adds a row from rng to the sum if a <= b.\ndef vsumiflteq(a,b,rng):\n    \"\"\"Computes the sum of a range of cells where a <= b\"\"\"\n    s = 0\n    for i in rng:\n        r = a.GetTable().CurRow()\n        c = a.GetTable().CurCol()\n        cr = i.GetRow()\n        cc = i.GetCol()\n        a.GetTable().SetCurRow(cr)\n        a.GetTable().SetCurCol(cc)\n        va = GetVal(a)\n        vb = GetVal(b)\n        a.GetTable().SetCurRow(c)\n        a.GetTable().SetCurCol(r)\n        if va <= GetVal(vb):\n            s += GetNum(i)\n    return s\n\n# Only adds a row from rng to the sum if a >= b.\ndef vsumifgteq(a,b,rng):\n    \"\"\"Computes the sum of a range of cells where a >= b\"\"\"\n    s = 0\n    for i in rng:\n        r = a.GetTable().CurRow()\n        c = a.GetTable().CurCol()\n        cr = i.GetRow()\n        cc = i.GetCol()\n        a.GetTable().SetCurRow(cr)\n        a.GetTable().SetCurCol(cc)\n        va = GetVal(a)\n        vb = GetVal(b)\n        a.GetTable().SetCurRow(c)\n        a.GetTable().SetCurCol(r)\n        if va >= GetVal(vb):\n            s += GetNum(i)\n    return s\n\ndef vmedian(rng):\n    \"\"\"Computes the median (middle) value of a sorted range of cells\"\"\"\n    data = list(rng)\n    for i in range(0,len(data)):\n        data[i] = GetVal(data[i])\n    data.sort()\n    dl = len(data)\n    v = math.floor(dl/2)\n    if(dl == 1):\n        return data[0]\n    if(v*2 != dl):\n        return data[v]\n    else:\n        if(v <= 0):\n            return data[0]\n        return (GetNum(data[v-1]) + GetNum(data[v]))/2.0\n\ndef vmax(rng):\n    \"\"\"Computes the max value of a range of cells\"\"\"\n    m = -999999999\n    for i in rng:\n        num = GetNum(i)\n        if(num > m):\n            m = num\n    return m\n\ndef vmin(rng):\n    \"\"\"Computes the minimum value of a range of cells\"\"\"\n    m = 999999999\n    for i in rng:\n        num = GetNum(i)\n        if(num < m):\n            m = num\n    return m\n\ndef mybool(num):\n    \"\"\"Explicitly convert value to a boolean value if possible\"\"\"\n    v = GetVal(num)\n    if(isinstance(v,str)):\n        l = v.lower()\n        if(l == \"true\" or l == \"t\"):\n            return True\n    if(v):\n        return True\n    return False\n\ndef myint(num):\n    \"\"\"Force a value to an integer\"\"\"\n    v = GetVal(num)\n    try:\n        return int(v)\n    except:\n        return 0\n\ndef myfloat(num):\n    \"\"\"Force a value to a float\"\"\"\n    v = GetVal(num)\n    try:\n        return float(v)\n    except:\n        return 0.0\n\ndef ClearAllOldCellHighlights():\n    colors = [\"green\",\"red\",\"orang\",\"whit\",\"black\",\"purpl\",\"yellow\",\"cyan\",\"blu\"]\n    for color in colors:\n        hname = \"myhighlight_\" + color\n        if color == \"whit\":\n            style = \"region.foreground\"\n        style = \"region.\" + color + \"ish\"\n        sublime.active_window().active_view().add_regions(hname,[],style,\"\",sublime.DRAW_NO_OUTLINE)\ndef ClearRegionFromOldHighlights(table,reg,newcolor):\n    colors = [\"green\",\"red\",\"orang\",\"whit\",\"black\",\"purpl\",\"yellow\",\"cyan\",\"blu\"]\n    for color in colors:\n        if(color == newcolor):\n            continue\n        hname = \"myhighlight_\" + color\n        regs = sublime.active_window().active_view().get_regions(hname)\n        if(reg in regs):\n            regs.remove(reg)\n            style = \"region.\" + color + \"ish\"\n            if color == \"whit\":\n                style = \"region.foreground\"\n            sublime.active_window().active_view().add_regions(hname,regs,style,\"\",sublime.DRAW_NO_OUTLINE)\n\ndef postedithighlight(table,r,c,color,value):\n    color = color.strip()\n    if color.endswith(\"e\"):\n        color = color[:-1]\n    style = \"region.\" + color + \"ish\"\n    if color == \"whit\":\n        style = \"region.foreground\"\n    reg = table.FindCellRegion(r,c)\n    hname = \"myhighlight_\" + color\n    regs = sublime.active_window().active_view().get_regions(hname)\n    if(not reg in regs):\n        regs.append(reg)\n        ClearRegionFromOldHighlights(table,reg,color)\n    sublime.active_window().active_view().add_regions(hname,regs,style,\"\",sublime.DRAW_NO_OUTLINE)\ndef myhighlight(cell,color,value=\"\"):\n    \"\"\"highlight(cell,color,text) highlights a cell to one of: green,red,orange,white,black,purple,yellow,cyan and returns the text specified\"\"\"\n    #sublime.active_window().active_view().add_regions(\"myhighlight\",[],\"\",\"\",sublime.DRAW_SOLID_UNDERLINE)\n    a = cell.GetRow()\n    b = cell.GetCol()\n    cell.table.SetPostExecuteHook(lambda table,x=cell.GetRow(),y=cell.GetCol(),c=color,v=value: postedithighlight(table,x,y,c,v))\n    return value\n\ndef myred(cell):\n    \"\"\"equivalent to highlight($x,red,$x) \"\"\"\n    return myhighlight(cell,\"red\",cell)\n\ndef mygreen(cell):\n    \"\"\"equivalent to highlight($x,green,$x) \"\"\"\n    return myhighlight(cell,\"green\",cell)\n\ndef myyellow(cell):\n    \"\"\"equivalent to highlight($x,yellow,$x) \"\"\"\n    return myhighlight(cell,\"yellow\",cell)\n\ndef myblue(cell):\n    \"\"\"equivalent to highlight($x,blue,$x) \"\"\"\n    return myhighlight(cell,\"blue\",cell)\n\ndef mycyan(cell):\n    \"\"\"equivalent to highlight($x,cyan,$x) \"\"\"\n    return myhighlight(cell,\"cyan\",cell)\n\ndef mypurple(cell):\n    \"\"\"equivalent to highlight($x,purple,$x) \"\"\"\n    return myhighlight(cell,\"purple\",cell)\n\ndef myorange(cell):\n    \"\"\"equivalent to highlight($x,purple,$x) \"\"\"\n    return myhighlight(cell,\"purple\",cell)\n\ndef mypink(cell):\n    \"\"\"equivalent to highlight($x,purple,$x) \"\"\"\n    return myhighlight(cell,\"pink\",cell)\ndef mygradient(cell, progress, *colors):\n    \"\"\"Cell is expected to be a value between 1 and 100, gradient will color the cell proportionally from an array of color names [] \"\"\"\n    val = GetVal(progress)\n    if not colors or len(colors) < 0:\n        return GetVal(cell)\n    idx = int((val/100.0)*len(colors))\n    if idx >= len(colors):\n        idx = len(colors) - 1\n    if idx < 0:\n        idx = 0\n    return myhighlight(cell,colors[idx],cell)\n\ndef myfloor(num):\n    \"\"\"Force a value to the previous integer\"\"\"\n    v = GetNum(num)\n    if(isinstance(v,float)):\n        return math.floor(v)\n    return num \n\ndef myceil(num):\n    \"\"\"Force a value to the next integer\"\"\"\n    v = GetNum(num)\n    if(isinstance(v,float)):\n        return math.ceil(v)\n    return num \n\ndef myround(num):\n    \"\"\"Round to the nearest integer\"\"\"\n    v = GetNum(num)\n    if(isinstance(v,float)):\n        return round(v,0)\n    return num \n\ndef mytrunc(num):\n    \"\"\"Round down to the nearest int\"\"\"\n    v = GetNum(num)\n    if(isinstance(v,float)):\n        return int(v)\n    return num \n\ndef GetTime(dt):\n    if(isinstance(dt,Cell)):\n        dt = mydate(dt)\n    if(isinstance(dt,list) and len(dt) > 0):\n        dt = dt[0]\n    if(isinstance(dt,orgdate.OrgDate)):\n        dt = dt.start\n    return dt\n\ndef mynow():\n    \"\"\"Returns the current date time\"\"\"\n    return orgdate.OrgDate(datetime.datetime.now())\n\ndef myyear(dt):\n    \"\"\"Get the year value from a datetime  - datetime.time().year\"\"\"\n    dt = GetTime(dt)\n    return dt.year\n\ndef myday(dt):\n    \"\"\"Get the day value from a datetime  - datetime.time().day\"\"\"\n    dt = GetTime(dt)\n    return dt.day\n\ndef mymonth(dt):\n    \"\"\"Get the month value from a datetime - datetime.time().month\"\"\"\n    dt = GetTime(dt)\n    return dt.month\n\ndef myhour(dt):\n    \"\"\"Get the hours value from a datetime - datetime.time().hour\"\"\"\n    dt = GetTime(dt)\n    return dt.hour\n\ndef myminute(dt):\n    \"\"\"Get the minutes value from a datetime - datetime.time().minute\"\"\"\n    dt = GetTime(dt)\n    return dt.minute\n\ndef mysecond(dt):\n    \"\"\"Get the seconds value from a datetime - datetime.time().second\"\"\"\n    dt = GetTime(dt)\n    return dt.second\n\ndef myweekday(dt):\n    \"\"\"Get an index for the day of the week where monday is 0\"\"\"\n    dt = GetTime(dt)\n    return dt.date().weekday()\n\ndef myyearday(dt):\n    \"\"\"Get the numerical day of the year where jan 1 is 1\"\"\"\n    dt = GetTime(dt)\n    return dt.timetuple().tm_yday\n\ndef mytime(dt):\n    \"\"\"Return the current time from a datetime object time(datetime)\"\"\"\n    dt = GetTime(dt)\n    return dt.time()\n\nLINK_RE = re.compile(r'^\\s*\\[\\[(file:)?(?P<filepath>.+?)(((::(?P<row>\\d+))(::(?P<col>\\d+))?)|(::\\#(?P<cid>[a-zA-Z0-9!$@%&_-]+))|(::\\*(?P<heading>[a-zA-Z0-9!$@%&_-]+))|(::(?P<textmatch>[a-zA-Z0-9!$@%&_-]+)))?\\s*\\]\\s*(\\]|\\s*\\[.*\\])')\ndef mylocalfile(obj):\n    \"\"\"Convert a local filename or link into an absolute filename\"\"\"\n    txt = GetVal(obj)\n    m = LINK_RE.search(txt)\n    if(m):\n        txt = m.group('filepath')\n    txt = txt.strip()\n    # We assume this is an abs path\n    if(txt.startswith('/') or (len(txt) > 3 and txt[2] == ':' and (txt[3] == '\\\\' or txt[3] == '/'))):\n        return txt\n    else:\n        p = sublime.active_window().active_view().file_name()\n        if(p):\n            p = os.path.dirname(p)\n            txt = os.path.normpath(os.path.join(p,txt))\n    return txt\n\n# Not currently used, the python if is forced on us due to the use\n# of the AST backend. I could convert from this to that with an RE\n# but I am not yet sure that's a good idea.\ndef myif(test,a,b=None):\n    v = GetVal(test)\n    if(isinstance(v,str)):\n        if(v.strip() != \"\"):\n            return a\n        else:\n            return b\n    elif(isinstance(v,int)):\n        if(v):\n            return a\n        else:\n            return b\n    else:\n        if(test):\n            return a\n        return b\n\ndef myduration(dt):\n    \"\"\"Convert to a timespan value\"\"\"\n    if(isinstance(dt,Cell)):\n        return orgduration.OrgDuration.Parse(dt.GetText())\n    if(isinstance(dt,str)):\n        return orgduration.OrgDuration.Parse(dt)\n    return dt\n\ndef mydate(dt):\n    \"\"\"Convert string to a date value\"\"\"\n    if(isinstance(dt,Cell)):\n        rc = orgdate.OrgDate.list_from_str(dt.GetText())\n        if(len(rc) == 0):\n            log.debug(\"ERROR: date function failed to parse date? \" + str(dt.GetText()))\n            traceback.print_stack()\n        if(len(rc) == 1):\n            return rc[0]\n        return rc\n    if(isinstance(dt,str)):\n        rc = orgdate.OrgDate.list_from_str(dt)\n        if(len(rc) == 1):\n            return rc[0]\n        return rc\n    elif(isinstance(dt,datetime.datetime)):\n        return dt.date()\n    elif(isinstance(dt,datetime.date)):\n        return dt\n    return None\n\ndef randomDigit(start, end):\n    \"\"\"Returns a random value in a range specified start..end\"\"\"\n    return random.randint(GetVal(start),GetVal(end))\n\ndef randomFloat():\n    \"\"\"Returns a random value from 0..1\"\"\"\n    return random.randint(0,1000000)/1000000.0\n\ndef degrees(cell):\n    \"\"\"Convert from radians to degress\"\"\"\n    return math.degrees(GetNum(cell))\n\ndef radians(cell):\n    \"\"\"Convert from degrees to radians\"\"\"\n    return math.radians(GetNum(cell))\n\ndef tan(cell):\n    \"\"\"Return the tangent of x radians.\"\"\"\n    return math.tan(GetNum(cell))\n\ndef sin(cell):\n    \"\"\"Return the sine of x radians.\"\"\"\n    return math.sin(GetNum(cell))\n\ndef cos(cell):\n    \"\"\"Return the cosine of x radians.\"\"\"\n    return math.cos(GetNum(cell))\n\ndef atan(cell):\n    \"\"\"Return the arc tangent of x radians.\"\"\"\n    return math.atan(GetNum(cell))\n\ndef asin(cell):\n    \"\"\"Return the arc sine of x radians.\"\"\"\n    return math.asin(GetNum(cell))\n\ndef acos(cell):\n    \"\"\"Return the arc cosine of x radians.\"\"\"\n    return math.acos(GetNum(cell))\n\ndef tanh(cell):\n    \"\"\"Return the hyperbolic tangent of x.\"\"\"\n    return math.tanh(GetNum(cell))\n\ndef sinh(cell):\n    \"\"\"Return the hyperbolic sine of x.\"\"\"\n    return math.sinh(GetNum(cell))\n\ndef cosh(cell):\n    \"\"\"Return the hyperbolic cosine of x.\"\"\"\n    return math.cosh(GetNum(cell))\n\ndef atanh(cell):\n    \"\"\"Return the inverse hyperbolic tangent of x.\"\"\"\n    return math.atanh(GetNum(cell))\n\ndef asinh(cell):\n    \"\"\"Return the inverse hyperbolic sine of x.\"\"\"\n    return math.asinh(GetNum(cell))\n\ndef acosh(cell):\n    \"\"\"Return the inverse hyperbolic cosine of x.\"\"\"\n    return math.acosh(GetNum(cell))\n\ndef exp(cell):\n    \"\"\"Return e raised to the power x, where e = 2.718281\"\"\"\n    return math.exp(GetNum(cell))\n\ndef pow(x,y):\n    \"\"\"Return x raised to the power y\"\"\"\n    return math.pow(GetNum(x),GetNum(y))\n\ndef mylog(x):\n    \"\"\"Return the natural logarithm of x (to base e).\"\"\"\n    return math.log(x)\n\ndef mylog10(x):\n    \"\"\"Return the base-10 logarithm of x.\"\"\"\n    return math.log10(x)\n\ndef mylog2(x):\n    \"\"\"Return the base-2 logarithm of x.\"\"\"\n    return math.log2(x)\n\ndef sqrt(x):\n    \"\"\"Return the square root of x.\"\"\"\n    return math.sqrt(x)\n\ndef LookupNamedTableInFile(name):\n    td = None\n    view = sublime.active_window().active_view()\n    if(view):\n        node = db.Get().AtInView(view)\n        if(node):\n            # Look for named objects in the file.\n            names = node.names\n            if(names and name in names):\n                row = names[name]['row']\n                last_row = view.lastRow()\n                for r in range(row,last_row):\n                    pt = view.text_point(r, 0)\n                    line = view.substr(view.line(pt))\n                    m = RE_ISCOMMENT.search(line)\n                    if(m):\n                        continue\n                    elif(line.strip() == \"\"):\n                        continue\n                    else:\n                        row = r\n                        break\n                pt = view.text_point(row,0)\n                if(isTable(view, pt)):\n                    td = create_table(view,pt)\n    return td\n\ndef LookupTableFromId(name):\n    td = None\n    file, row = db.Get().FindByAnyId(name)\n    if(file):\n        node = file.At(row)\n        if(node and node.table):\n            td = create_table_from_node(node, node.table['nodeoff'][0])\n    return td\n\ndef LookupTableFromNamedObject(name):\n    # First search for a named table from the ID\n    td = LookupNamedTableInFile(name)\n    if(not td):\n        # Okay use the custom ID rule to try to get the\n        # table.\n        td = LookupTableFromId(name)\n    return td\n\ndef remote(name,cellRef):\n    \"\"\"remote('table-name OR custom-id-value',cellRef) returns a cell from a remote table.\n       table-name only works local to a file while custom-id or id will look up the first table\n       in a heading marked with that id.\n    \"\"\"\n    td = LookupTableFromNamedObject(name)\n    if(td):\n        text = td.GetCellText(cellRef.GetRow(td.Height()),cellRef.GetCol(td.Width()))\n        return text\n    return \"<UNK REF>\"\n\n# ============================================================\nclass RangeExprOnNonCells(simpev.InvalidExpression):\n    def __init__(self,name,expression):\n        self.name = name\n        self.message = \"both sides of a range expression must be a cell definition\"\n        self.expression = expression\n        # pylint: disable=bad-super-call\n        super(RangeExprOnNonCells, self).__init__(self.message)\n\n# These filters are used for naming cells above or below a certain point.\n# The symbolOrCell system uses this when iterating to filter out cells that\n# do not belong.\nclass NullFilter:\n    def filter(self,x):\n        return False\nclass AboveFilter:\n    def __init__(self,r):\n        self.r = r\n    def filter(self,x):\n        return x >= self.r\nclass BelowFilter:\n    def __init__(self,r):\n        self.r = r\n    def filter(self,x):\n        return x <= self.r\n\ndef checkPassed(txt):\n    txt = GetVal(txt)\n    if(isinstance(txt,str)):\n        txt = txt.strip()\n        return txt != \"<ERR>\" and txt != \"<UNK REF>\"\n    return txt\n\n# ============================================================\nclass TableDef(simpev.SimpleEval):\n    def range_expr(self,a,b):\n        if(isinstance(a,Cell) and isinstance(b,Cell)):\n            if(a.r == \"*\" and b.r == \"*\"):\n                return CellColIterator(a.table, a.GetCol(), b.GetCol())\n            elif(a.c == \"*\" and b.c == \"*\"):\n                return CellRowIterator(a.table, a.GetRow(), b.GetRow(), a.rowFilter, b.rowFilter)\n            elif(a.r != '*' and b.r != '*' and a.c != '*' and b.c != '*'):\n                return CellBoxIterator(a.table,a,b)\n            else:\n                raise RangeExprOnNonCells(\"End cells must be wild of same type\", \"range expression is invalid\")\n        else:\n            raise RangeExprOnNonCells(str(a), \"range expression is invalid\")\n\n    def mysbe(table, name,**kwargs):\n        view = sublime.active_window().active_view()\n        cell = Cell(table.CurRow(),table.CurCol(),table)\n        sbe = SourceBlockExecute(cell)\n        sbe.run(name,kwargs)\n        print(name)\n        print(str(kwargs))\n        return sbe\n\n    def mypassed(table,test,cell=None):\n        if(not cell):\n            cell = Cell(table.CurRow(),table.CurCol(),table)\n        if(checkPassed(test)):\n            return myhighlight(cell,\"green\",\"PASSED\")\n        else:\n            return myhighlight(cell,\"red\",\"FAILED\")\n\n    def SetPostExecuteHook(self,fun):\n        self.postExecute.append(fun)\n\n    def ForEachRow(self):\n        return range(1,self.Height() + 1)\n    \n    def ForEachCol(self):\n        return range(1,self.Width() + 1)\n\n    def ShouldIgnoreRow(self,row):\n        return row in self.ignoreRows\n\n    def ridx(self):\n        return self.CurRow()\n    \n    def cidx(self):\n        return self.CurCol()\n\n    def getrowcell(self,r,relative):\n        return Cell(r,'*',self,relative,0)\n\n    def getcolcell(self,c,relative):\n        return Cell('*',c,self,0,relative)\n\n    def getcell(self,r,rrelative,c,crelative):\n        return Cell(r,c,self,rrelative,crelative)\n\n    def symbolOrCell(self,name):\n        if name in self.nameToCell:\n            return self.nameToCell[name]\n        if(name in self.consts):\n            v = self.consts[name].strip()\n            if(util.numberCheck(v)):\n                if('.' in v):\n                    return float(v)\n                else:\n                    return int(v)\n            return v\n\n    def ClearAllRegions(self):\n        for r in range(1,(self.end+2)-self.start):\n            self.view.erase_regions(\"cell_\"+str(r))\n            if(not self.linedef):\n                continue\n            for c in range(1,len(self.linedef)):\n                self.view.erase_regions(\"cell__\"+str(c))\n                self.view.erase_regions(\"cell_\"+str(r)+\"_\"+str(c))\n        for i in range(0,self.NumFormulas()):\n            self.view.erase_regions(\"fmla_\"+str(i))\n\n\n    def add_functions(self,f):\n        f['ridx']       = self.ridx\n        f['cidx']       = self.cidx\n        f['symorcell']  = self.symbolOrCell\n        f['getcell']    = self.getcell\n        f['getrowcell'] = self.getrowcell\n        f['getcolcell'] = self.getcolcell\n        f['passed']     = self.mypassed\n        f['sbe']        = self.mysbe\n\n\n    def __init__(self,view, start,end,linedef):\n        self.names     = GetConsts().copy()\n        self.operators = GetOps().copy()\n        self.operators[ast.FloorDiv] = self.range_expr\n        self.functions = GetFunctions().copy()\n        self.add_functions(self.functions)\n        super(TableDef,self).__init__(self.operators, self.functions, self.names)\n        self.curRow  = 0\n        self.curCol  = 0\n        self.start   = start\n        self.end     = end\n        self.view    = view\n        self.linedef = linedef\n        self.cellToFormula = None\n        self.accessList    = []\n        self.consts        = {}\n        self.emptyiszero   = False\n        self.startCol      = 1\n\n    def RecalculateTableDimensions(self):\n        res = recalculate_linedef(self.view,self.start)\n        if(res == None):\n            log.error(\"FAILURE TO RECALCULATE LINE DEFINITION FOR TABLE. Something is wrong!\")\n        else:\n            self.linedef = res\n\n    def Width(self):\n        if(not self.linedef):\n            return 0\n        return len(self.linedef) - 1\n\n    def Height(self):\n        return self.rowCount\n\n    def StartRow(self):\n        return self.startRow\n\n    def StartCol(self):\n        return self.startCol\n\n    def SetCurRow(self,r):\n        self.curRow = r\n    \n    def SetCurCol(self,c):\n        self.curCol = c\n\n    def CurRow(self):\n        return self.curRow\n\n    def CurCol(self):\n        return self.curCol\n\n    def GetActiveFormula(self):\n        return self.activeFormula\n\n    def SetActiveFormula(self,i):\n        self.activeFormula = i\n\n    def GetCellText(self,r,c):\n        self.accessList.append([r,c])\n        if(isinstance(self.view,sublime.View)):\n            reg = self.FindCellRegion(r,c)\n            if(reg):\n                text = self.view.substr(reg)\n                if(self.emptyiszero and text.strip() == \"\"):\n                    return \"0\"\n                return text.strip()\n            if(self.emptyiszero):\n                return \"0\"\n        else:\n            row,cs,ce = self.FindCellNodeRegion(r,c)\n            text = self.view._lines[row]\n            cell = text[cs+1:ce].strip()\n            if(self.emptyiszero and cell == \"\"):\n                return \"0\"\n            return cell\n        return \"\"\n    def FindCellRegion(self,r,c):\n        if(not r in self.lineToRow):\n            return None\n        row = self.lineToRow[r]\n        #row = self.start + (r-1)       # 1 is zero\n        colstart = self.linedef[c-1] \n        colend   = self.linedef[c]\n        return sublime.Region(self.view.text_point(row,colstart+1),self.view.text_point(row,colend)) \n    def FindCellNodeRegion(self,r,c):\n        if(not r in self.lineToRow):\n            return None\n        row = self.lineToRow[r]\n        #row = self.start + (r-1)       # 1 is zero\n        colstart = self.linedef[c-1] \n        colend   = self.linedef[c]\n        return (row,colstart,colend)\n        return sublime.Region(self.view.text_point(row,colstart+1),self.view.text_point(row,colend)) \n    def HighlightCells(self, cells,color):\n        for cell in cells:\n            it = RCIterator(self,cell[0],cell[1])\n            for cc in it:\n                reg = self.FindCellRegion(*cc)\n                if(reg):\n                    style = \"orgagenda.week.\" + str(color)\n                    self.view.add_regions(\"cell_\"+str(cc[0])+\"_\"+str(cc[1]),[reg],style,\"\",sublime.DRAW_NO_FILL)\n    \n    def HighlightCell(self, r,c , color):\n        reg = self.FindCellRegion(r,c)\n        if(reg):\n            style = \"orgagenda.week.\" + str(color)\n            self.view.add_regions(\"cell_\"+str(r)+\"_\"+str(c),[reg],style,\"\",sublime.DRAW_NO_FILL)\n\n    def HighlightFormulaRegion(self,i,color=3):\n        style = \"orgagenda.week.\" + str(color)\n        if(self.formulas and i >= 0 and i < len(self.formulas)):\n            reg = self.formulas[i].reg\n            if(reg):\n                self.view.add_regions(\"fmla_\"+str(i),[reg],style,\"\",sublime.DRAW_NO_FILL)\n\n    def NumFormulas(self):\n        return len(self.formulas) \n\n    def CursorToFormula(self):\n        fm = self.formulaLine\n        rc = self.view.curRowCol()\n        if(not rc): \n            return None\n        row,col = rc\n        if(row != self.formulaRow):\n            return None\n        segs = fm.split('::')\n        acc = 0\n        for idx in range(0,len(segs)):\n            if(col >= acc and col < acc+len(segs[idx])):\n                return idx\n            acc += len(segs[idx]) + 2\n        return None\n\n    def ReplaceFormula(self,i,formula):\n        fmla = self.formulas[i]\n        self.view.run_command(\"org_internal_replace\", {\"start\": fmla.reg.begin(), \"end\": fmla.reg.end(), \"text\": formula})\n\n    def AddNewFormula(self, formula):\n        pt = None\n        if(self.NumFormulas() > 0):\n            pt = self.formulas[self.NumFormulas()-1].reg.end()\n            formula = \"::\" + formula\n        else:\n            pt = self.view.text_point(self.end,0)\n            ll = self.view.line(pt)\n            line = self.view.substr(ll)\n            indentCount = 0\n            while(indentCount < 20 and line[indentCount] == ' ' or line[indentCount] == '\\t'):\n                indentCount += 1\n            indent = ' ' * indentCount\n            formula = \"\\n\" + indent + \"#+TBLFM:\" + formula\n            pt = ll.end()\n        self.view.run_command(\"org_internal_insert\", {\"location\": pt, \"text\": formula})\n\n    def IsRowAboveHLine(self, r):\n        if r >= 1 and r < len(self.lineToRow):\n            realRow = self.lineToRow[r]\n            hline = realRow + 1\n            for x in self.hlines:\n                if hline == x:\n                    return True\n        return False\n\n    def RowToCellRow(self,r):\n        for i in range(1,len(self.lineToRow)+1):\n            if(i in self.lineToRow and self.lineToRow[i] == r):\n                return i\n        return 1\n\n    def FindCellColFromCol(self,c):\n        if self.linedef == None:\n            return 1\n        for i in range(0,len(self.linedef)-1):\n            if(c >= self.linedef[i] and c < self.linedef[i+1]):\n                return i+1\n        if(not self.linedef or (len(self.linedef) > 1 and c < self.linedef[0])):\n            return 1\n        return len(self.linedef)-1\n\n    def CursorToCell(self):\n        rc = self.view.curRowCol()\n        if(rc):\n            row,col = rc\n            r = self.RowToCellRow(row)\n            c = self.FindCellColFromCol(col)\n            return [r,c]\n        return None\n\n    def CellToFormula(self, cell):\n        r,c = cell\n        if(self.cellToFormula):\n            if(r in self.cellToFormula and c in self.cellToFormula[r]):\n                return self.cellToFormula[r][c]\n        return None\n\n    def HighlightFormula(self, i):\n        self.PreExecute()\n        if(not hasattr(self,'highlight') or self.highlight):\n            it = SingleFormulaIterator(self,i)\n            for n in it:\n                r,c,val,reg,_ = n\n                # This is important, the cell COULD return a cell\n                # until we convert it to a string that cell will not\n                # necessarily be touched so the accessList will not be\n                # correct.\n                valStr = str(val)\n                self.HighlightCells(self.accessList,1)\n                self.HighlightCells([[r,c]],2)\n        self.HighlightFormulaRegion(i)\n        self.PostExecute()\n\n    def GetFormula(self,i):\n        return self.formulas[i]\n    \n    def AddTemporaryFormula(self,fm):\n        raw = fm.strip()\n        formatters = fm.split(';')\n        if(len(formatters) > 1):\n            fm = formatters[0]\n            formatters = formatters[1]\n        else:\n            formatters = \"\"\n        self.formulas.append(Formula(raw,fm, sublime.Region(self.view.text_point(0,0),self.view.text_point(0,0)),formatters,self))\n        return len(self.formulas)-1\n\n    def RemoveTemporaryFormula(self):\n        del self.formulas[len(self.formulas)-1]\n\n    def FormulaTarget(self, i):\n        dm = self.formulas[i]\n        return dm.target\n\n    def FormulaTargetRowFilter(self, i):\n        dm = self.formulas[i]\n        return dm.rowFilter\n\n    def ValidateFormulaCells(self,i):\n        if(\"INVALID\" in self.formulas[i].formula):\n            sublime.status_message(\"ORG Table WARNING: Formula {0} is targetting an invalid cell!\".format(i))\n\n    def FormulaTargetCellIterator(self, i):\n        target = self.FormulaTarget(i)\n        rowFilter = self.FormulaTargetRowFilter(i)\n        self.ValidateFormulaCells(i)\n        if(len(target) == 4):\n            cellStart = Cell(target[0],target[1],self,rowFilter = rowFilter)\n            cellEnd = Cell(target[2],target[3],self,rowFilter = rowFilter)\n            cellIterator = CellBoxIterator(self,cellStart,cellEnd)\n        else:\n            cell = Cell(target[0],target[1],self,rowFilter=rowFilter)\n            cellIterator = CellIterator(self,cell)\n        return cellIterator\n\n    def IsSingleTargetFormula(self,i):\n        target = self.FormulaTarget(i)\n        if(len(target) == 2 and isinstance(target[0],int) and isinstance(target[1],int)):\n            return True\n        return False \n\n    def AddCellToFormulaMap(self,cell,i):\n        r,c = 1,1\n        if(isinstance(cell,Cell)):\n            r = cell.r\n            c = cell.c\n        else:\n            r,c = cell\n        if(not r in self.cellToFormula):\n            self.cellToFormula[r] = {}\n        self.cellToFormula[r][c] = i\n\n    def BuildCellToFormulaMap(self):\n        self.cellToFormula = {}\n        for i in range(0,self.NumFormulas()):\n            if(not self.IsSingleTargetFormula(i)):\n                it = self.FormulaTargetCellIterator(i)\n                if(it):\n                    for c in it:\n                        self.AddCellToFormulaMap(c,i)\n        for i in range(0,self.NumFormulas()):\n            if(self.IsSingleTargetFormula(i)):\n                it = self.FormulaTargetCellIterator(i)\n                if(it):\n                    for c in it:\n                        self.AddCellToFormulaMap(c,i)\n    \n    def BuildNameMap(self):\n        self.nameToCell = {}\n        for r,row in self.colNames:\n            for c in range(1,self.Width()+1):\n                txt = self.GetCellText(r,c).strip()\n                if(not txt == \"\" and txt[0].isalpha()):\n                    self.nameToCell[txt] = Cell('*', c, self)\n        for r,row in self.nameRowsAbove:\n            for c in range(1,self.Width()+1):\n                txt = self.GetCellText(r,c).strip()\n                if(not txt == \"\" and txt[0].isalpha()):\n                    f = AboveFilter(r)\n                    self.nameToCell[txt] = Cell('*', c, self, rowFilter = f)\n        for r,row in self.nameRowsBelow:\n            for c in range(1,self.Width()+1):\n                txt = self.GetCellText(r,c).strip()\n                if(not txt == \"\" and txt[0].isalpha()):\n                    f = BelowFilter(r)\n                    self.nameToCell[txt] = Cell('*', c, self, rowFilter = f)\n\n    def PreExecute(self):\n        self.postExecute = []\n\n    def PostExecute(self):\n        for fun in self.postExecute:\n            fun(self)\n\n    def Execute(self, i):\n        self.accessList = []\n        try:\n            self.emptyiszero = self.formulas[i].EmptyIsZero()\n            val = self.eval(self.formulas[i].expr)\n            if(val and isinstance(val,Cell)):\n                val = val.GetVal()\n            return val\n        except:\n            log.error(\"TABLE ERROR: %s\",traceback.format_exc())\n            return \"<ERR>\"\n\n    def GetFormulaAt(self):\n        cell = self.CursorToCell()\n        if(cell):\n            formulaIdx = self.CellToFormula(cell)\n            return formulaIdx\n        return None\n    def FormulaFormatter(self,i):\n        dm = self.formulas[i]\n        return dm.printfout\n\n\ndef findOccurrences(s, ch):\n    return [i for i, letter in enumerate(s) if letter == ch]\n\ndef find_formula(view):\n    row = view.curRow()\n    last_row = view.lastRow()\n    for r in range(row,last_row):\n        pt = view.text_point(r, 0)\n        line = view.substr(view.line(pt))\n        m = RE_FMT_LINE.search(line)\n        if(m):\n            return m.group('expr').split('::')\n        elif(RE_TABLE_LINE.search(line)):\n            continue\n        else:\n            return None\ndef recalculate_linedef(view,row):\n    if(isinstance(view,sublime.View)):\n        pt = view.text_point(row, 0)\n        line = view.substr(view.line(pt))\n        linedef = None\n        if(not RE_TABLE_HLINE.search(line) and RE_TABLE_LINE.search(line)):\n            linedef = findOccurrences(line,'|')\n        return linedef\n    else:\n        line = view._lines[row]\n        linedef = None\n        if(not RE_TABLE_HLINE.search(line) and RE_TABLE_LINE.search(line)):\n            linedef = findOccurrences(line,'|')\n        return linedef\n\n# ====================================================================\n# CREATE TABLE\n# ====================================================================\ndef create_table(view, at=None):\n    row = view.curRow()\n    if(at != None):\n        row,_ = view.rowcol(at)\n    start_row = row\n    last_row = view.lastRow()\n    end = last_row\n    start = row\n    linedef = None\n    formula = None\n    hlines = []\n    lineToRow = {}\n    endHeader = 1\n    formulaRow = None\n    formulaLine = None\n    for r in range(row-1,0,-1):\n        pt = view.text_point(r, 0)\n        line = view.substr(view.line(pt))\n        if(RE_TABLE_LINE.search(line) or RE_TABLE_HLINE.search(line) or RE_END_BLOCK.search(line)):\n            continue\n        row = r+1\n        break\n    start = row\n    rowNum = 0\n    lastRow = 0\n    spacesRow = 0\n    isAdvanced = False\n    autoCompute = []\n    namesRowsAbove = []\n    namesRowsBelow = []\n    colNames       = []\n    parameters     = []\n    ignore = []\n    ignoreRows = {}\n    for r in range(row,last_row+1):\n        rowNum += 1\n        pt = view.text_point(r, 0)\n        line = view.substr(view.line(pt))\n        m = RE_FMT_LINE.search(line)\n        # Found a table hline. These don't get counted\n        if(RE_TABLE_HLINE.search(line)):\n            hlines.append(r)\n            rowNum -= 1\n            if(endHeader == 1):\n                endHeader = (r - start) + 1\n            continue\n        # Found a table line match and continue\n        elif(RE_TABLE_LINE.search(line)):\n            if(None == linedef):\n                linedef = findOccurrences(line,'|')\n            # Is this an advanced table? If so we have to handle things\n            # in a special way!\n            mm = RE_AUTOCOMPUTE.search(line) \n            if(mm):\n                char = mm.group('a')\n                if(char != ' '):\n                    isAdvanced = True\n                # Name row\n                if(char == '!'):\n                    ignoreRows[rowNum] = r\n                    ignore.append((rowNum,r))\n                    colNames.append((rowNum,r))\n                    pass\n                # Auto compute row\n                elif(char == \"#\"):\n                    autoCompute.append(rowNum)\n                # compute row\n                elif(char == \"*\"):\n                    pass\n                # Skip row\n                elif(char == \"/\"):\n                    ignoreRows[rowNum] = r\n                    ignore.append((rowNum,r))\n                    pass\n                # Name below\n                elif(char == \"_\"):\n                    ignoreRows[rowNum] = r\n                    namesRowsBelow.append((rowNum,r))\n                    ignore.append((rowNum,r))\n                    pass\n                # Name above\n                elif(char == \"^\"):\n                    ignoreRows[rowNum] = r\n                    namesRowsAbove.append((rowNum,r))\n                    ignore.append((rowNum,r))\n                    pass\n                elif(char == \"$\"):\n                    ignoreRows[rowNum] = r\n                    parameters.append((rowNum,r))\n                    ignore.append((rowNum,r))\n                else:\n                    ignoreRows[rowNum] = r\n                    ignore.append((rowNum,r))\n                    pass\n                lineToRow[rowNum] = r\n            else:\n                lineToRow[rowNum] = r\n            continue\n        # Found a formula break!\n        elif(m):\n            formula = m.group('expr').split('::')\n            formulaRow = r\n            formulaLine = line\n            if(lastRow == 0):\n                end = r-1\n                lastRow = rowNum - 1\n            break\n        else:\n            endb = RE_END_BLOCK.search(line)\n            # We keep going for blank lines allowing #TBLFM lines with spaces to\n            # be okay OR tables inside dynamic blocks (RE above)\n            if(line.strip() == \"\" or endb):\n                if(lastRow == 0):\n                    spacesRow = r\n                    end = r-1\n                    lastRow = rowNum - 1\n                continue\n            else:\n                if(lastRow == 0):\n                    end = r-1\n                    lastRow = rowNum - 1\n            break\n    for r in range(row,0,-1):\n        pt = view.text_point(r, 0)\n        line = view.substr(view.line(pt))\n        if(RE_TABLE_LINE.search(line)):\n            continue\n        else:\n            start = r+1\n            break\n    td = TableDef(view, start, end, linedef)\n    td.hlines = hlines\n    td.startRow = endHeader\n    td.spacesRow = spacesRow\n    #td.linedef = linedef\n    td.formulas = []\n    td.formulaRow    = formulaRow\n    td.formulaLine   = formulaLine\n    td.lineToRow     = lineToRow\n    td.rowCount      = lastRow\n    td.autoCompute   = autoCompute\n    td.nameRowsAbove = namesRowsAbove\n    td.nameRowsBelow = namesRowsBelow\n    td.colNames      = colNames\n    td.highlight     = True\n    if(isAdvanced):\n        td.ignore        = ignore\n        td.ignoreRows    = ignoreRows\n    else:\n        td.ignore     = []\n        td.ignoreRows = {}\n    if(isAdvanced):\n        td.startCol = 2\n        td.BuildNameMap()\n    if(td):\n        node = db.Get().At(view, start_row)\n        if(node):\n            constants = node.list_comment('CONSTANTS',[])\n            consts = {}\n            if(constants and len(constants) > 0):\n                for con in constants:\n                    cs = con.split('=')\n                    if(len(cs) == 2):\n                        name = cs[0].strip()\n                        val  = cs[1].strip()\n                        consts[name] = val\n            if(hasattr(node,'properties')):\n                props = node.properties\n                if('NoTableHighlight' in props):\n                    td.highlight = False\n                if(props and len(props) > 0):\n                    for k,v in props.items():\n                        consts['PROP_'+k] = v\n            td.consts = consts\n        if(parameters and len(parameters) > 0):\n            for prow in parameters:\n                for c in range(2,td.Width()):\n                    txt = td.GetCellText(prow[0],c).strip()\n                    if('=' in txt):\n                        ps = txt.split(' ')\n                        if(len(ps) < 1):\n                            continue\n                        for p in ps:\n                            pp = p.split('=')\n                            if(len(pp) == 2):\n                                td.consts[pp[0].strip()] = pp[1].strip()\n    if(formula):\n        sre = re.compile(r'\\s*[#][+]((TBLFM)|(tblfm))[:]')\n        first = sre.match(formulaLine)\n        if(first):\n            lastend = len(first.group(0))\n            xline = sre.sub('',formulaLine)\n            las = xline.split('::')\n            index = 0\n            for fm in formula:\n                raw = fm.strip()\n                formatters = fm.split(';')\n                if(len(formatters) > 1):\n                    fm = formatters[0]\n                    formatters = formatters[1]\n                else:\n                    formatters = \"\"\n                fend = lastend+len(las[index])\n                td.formulas.append(Formula(raw,fm, sublime.Region(view.text_point(formulaRow,lastend),view.text_point(formulaRow,fend)),formatters,td))\n                index += 1\n                lastend = fend + 2\n        td.BuildCellToFormulaMap()\n    # \n    return td\n\n\n# CREATE TABLE FROM NODE\n# Figure out a way to get rid of this duplication!\n# ====================================================================\ndef create_table_from_node(node, row):\n    start_row = row\n    lineData = node._lines\n    last_row  = len(lineData)\n    end = last_row\n    start = row\n    linedef = None\n    formula = None\n    hlines = []\n    lineToRow = {}\n    endHeader = 1\n    formulaRow = None\n    formulaLine = None\n    for r in range(row - 1, 0, -1):\n        line = lineData[r]\n        if (RE_TABLE_LINE.search(line) or RE_TABLE_HLINE.search(line) or RE_END_BLOCK.search(line)):\n            continue\n        row = r + 1\n        break\n    start = row\n    rowNum = 0\n    lastRow = 0\n    spacesRow = 0\n    isAdvanced = False\n    autoCompute = []\n    namesRowsAbove = []\n    namesRowsBelow = []\n    colNames       = []\n    parameters     = []\n    ignore = []\n    ignoreRows = {}\n    for r in range(row, last_row):\n        rowNum += 1\n        line = lineData[r]\n        m = RE_FMT_LINE.search(line)\n        # Found a table hline. These don't get counted\n        if (RE_TABLE_HLINE.search(line)):\n            hlines.append(r)\n            rowNum -= 1\n            if (endHeader == 1):\n                endHeader = (r - start) + 1\n            continue\n        # Found a table line match and continue\n        elif (RE_TABLE_LINE.search(line)):\n            if (linedef is None):\n                linedef = findOccurrences(line, '|')\n            # Is this an advanced table? If so we have to handle things\n            # in a special way!\n            mm = RE_AUTOCOMPUTE.search(line)\n            if (mm):\n                char = mm.group('a')\n                if (char != ' '):\n                    isAdvanced = True\n                # Name row\n                if (char == '!'):\n                    ignoreRows[rowNum] = r\n                    ignore.append((rowNum, r))\n                    colNames.append((rowNum, r))\n                    pass\n                # Auto compute row\n                elif (char == \"#\"):\n                    autoCompute.append(rowNum)\n                # compute row\n                elif (char == \"*\"):\n                    pass\n                # Skip row\n                elif (char == \"/\"):\n                    ignoreRows[rowNum] = r\n                    ignore.append((rowNum, r))\n                    pass\n                # Name below\n                elif (char == \"_\"):\n                    ignoreRows[rowNum] = r\n                    namesRowsBelow.append((rowNum, r))\n                    ignore.append((rowNum, r))\n                    pass\n                # Name above\n                elif (char == \"^\"):\n                    ignoreRows[rowNum] = r\n                    namesRowsAbove.append((rowNum, r))\n                    ignore.append((rowNum, r))\n                    pass\n                elif (char == \"$\"):\n                    ignoreRows[rowNum] = r\n                    parameters.append((rowNum, r))\n                    ignore.append((rowNum, r))\n                else:\n                    ignoreRows[rowNum] = r\n                    ignore.append((rowNum, r))\n                    pass\n                lineToRow[rowNum] = r\n            else:\n                lineToRow[rowNum] = r\n            continue\n        # Found a formula break!\n        elif (m):\n            formula = m.group('expr').split('::')\n            formulaRow = r\n            formulaLine = line\n            if (lastRow == 0):\n                end = r - 1\n                lastRow = rowNum - 1\n            break\n        else:\n            endb = RE_END_BLOCK.search(line)\n            # We keep going for blank lines allowing #TBLFM lines with spaces to\n            # be okay OR tables inside dynamic blocks (RE above)\n            if (line.strip() == \"\" or endb):\n                if (lastRow == 0):\n                    spacesRow = r\n                    if (lastRow == 0):\n                        end = r - 1\n                        lastRow = rowNum - 1\n                continue\n            else:\n                if (lastRow == 0):\n                    end = r - 1\n                    lastRow = rowNum - 1\n            break\n    for r in range(row, 0, -1):\n        line = lineData[r]\n        if (RE_TABLE_LINE.search(line)):\n            continue\n        else:\n            start = r + 1\n            break\n    td = TableDef(node, start, end, linedef)\n    td.hlines = hlines\n    td.startRow = endHeader\n    td.spacesRow = spacesRow\n    # td.linedef = linedef\n    td.formulas = []\n    td.formulaRow    = formulaRow\n    td.formulaLine   = formulaLine\n    td.lineToRow     = lineToRow\n    td.rowCount      = lastRow\n    td.autoCompute   = autoCompute\n    td.nameRowsAbove = namesRowsAbove\n    td.nameRowsBelow = namesRowsBelow\n    td.colNames      = colNames\n    if (isAdvanced):\n        td.ignore        = ignore\n        td.ignoreRows    = ignoreRows\n    else:\n        td.ignore     = []\n        td.ignoreRows = {}\n    if (isAdvanced):\n        td.startCol = 2\n        td.BuildNameMap()\n    if (td):\n        if (node):\n            constants = node.list_comment('CONSTANTS', [])\n            consts = {}\n            if (constants and len(constants) > 0):\n                for con in constants:\n                    cs = con.split('=')\n                    if (len(cs) == 2):\n                        name = cs[0].strip()\n                        val  = cs[1].strip()\n                        consts[name] = val\n            if (hasattr(node, 'properties')):\n                props = node.properties\n                if (props and len(props) > 0):\n                    for k, v in props.items():\n                        consts['PROP_' + k] = v\n            td.consts = consts\n        if (parameters and len(parameters) > 0):\n            for prow in parameters:\n                for c in range(2, td.Width()):\n                    txt = td.GetCellText(prow[0], c).strip()\n                    if ('=' in txt):\n                        ps = txt.split(' ')\n                        if (len(ps) < 1):\n                            continue\n                        for p in ps:\n                            pp = p.split('=')\n                            if (len(pp) == 2):\n                                td.consts[pp[0].strip()] = pp[1].strip()\n    if (formula):\n        sre = re.compile(r'\\s*[#][+]((TBLFM)|(tblfm))[:]')\n        first = sre.match(formulaLine)\n        if (first):\n            lastend = len(first.group(0))\n            xline = sre.sub('', formulaLine)\n            las = xline.split('::')\n            index = 0\n            for fm in formula:\n                raw = fm.strip()\n                formatters = fm.split(';')\n                if (len(formatters) > 1):\n                    fm = formatters[0]\n                    formatters = formatters[1]\n                else:\n                    formatters = \"\"\n                fend = lastend + len(las[index])\n                td.formulas.append(Formula(raw, fm, None, formatters, td))\n                index += 1\n                lastend = fend + 2\n        td.BuildCellToFormulaMap()\n    return td\n\n\ndef SingleFormulaIterator(table, i):\n    table.SetActiveFormula(i)\n    cellIterator = table.FormulaTargetCellIterator(i)\n    for cell in cellIterator:\n        r, c = cell.rc()\n        table.SetCurRow(r)\n        table.SetCurCol(c)\n        val = table.Execute(i)\n        yield [r, c, val, table.FindCellRegion(r, c), table.FormulaFormatter(i)]\n\n\ndef FormulaIterator(table):\n    for i in range(0, table.NumFormulas()):\n        table.SetActiveFormula(i)\n        cellIterator = table.FormulaTargetCellIterator(i)\n        for cell in cellIterator:\n            r, c = cell.rc()\n            table.SetCurRow(r)\n            table.SetCurCol(c)\n            val = table.Execute(i)\n            yield (r, c, val, table.FindCellRegion(r, c), table.FormulaFormatter(i))\n    return None\n\n\ndef RandomRowFromTable(tableid):\n    tbl = LookupTableFromNamedObject(tableid)\n    if tbl:\n        numRows = tbl.Height()\n        random.seed()\n        row = random.randrange(1, numRows)\n        cnt = 0\n        while tbl.IsRowAboveHLine(row) or tbl.ShouldIgnoreRow(row):\n            row = random.randrange(1, numRows)\n            cnt += 1\n            if cnt > 100:\n                return \"[NO MATCH]\"\n        ret = \"|\"\n        for i in range(1, tbl.Width() + 1):\n            txt = tbl.GetCellText(row, i)\n            ret += txt + \"|\"\n        return ret\n\n\n# ================================================================================\nclass OrgInsertRandomRowFromTableCommand(sublime_plugin.TextCommand):\n    def on_done_st4(self, index, modifers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        if (index < 0):\n            evt.EmitIf(self.onDone)\n            return\n        rowText = RandomRowFromTable(self.ids[index])\n        self.view.run_command(\"org_internal_insert\", {\"location\": self.view.sel()[0].begin(), \"text\": rowText, \"onDone\": self.onDone})\n\n    def run(self, edit, tblName=None, onDone=None):\n        self.onDone = onDone\n        self.ids = list(db.Get().GetIds())\n        if (tblName is None):\n            if (int(sublime.version()) <= 4096):\n                self.view.window().show_quick_panel(self.ids, self.on_done, -1, -1)\n            else:\n                self.view.window().show_quick_panel(self.ids, self.on_done_st4, -1, -1)\n\n\n# ================================================================================\nclass OrgExecuteFormulaCommand(sublime_plugin.TextCommand):\n    def on_reformat(self):\n        self.td.RecalculateTableDimensions()\n        self.process_next()\n\n    def on_done_cell(self):\n        self.view.sel().clear()\n        self.view.sel().add(self.result[3])\n        #self.view.run_command('table_editor_next_field')\n        self.view.run_command('table_editor_align')\n        sublime.set_timeout(self.on_reformat,1)\n\n    def process_next(self):\n        self.result = next(self.it,None)\n        if(None == self.result):\n            self.on_done()\n            return\n        r,c,val,reg,fmt = self.result\n        if(val and isinstance(val,float) and fmt and \"%\" in fmt):\n            val = fmt % val\n        #print(\"REPLACING WITH: \" + str(val))\n        self.view.run_command(\"org_internal_replace\", {\"start\": reg.begin(), \"end\": reg.end(), \"text\": str(val), \"onDone\": evt.Make(self.on_done_cell)})\n\n    def on_done(self):\n        global highlightEnabled\n        highlightEnabled = True\n        self.td.PostExecute()\n        if(None != self.origCur):\n            self.view.sel().clear()\n            self.view.sel().add(self.origCur)\n        evt.EmitIf(self.onDone)\n\n    def on_formula_copy_done(self):\n        if(None != self.at):\n            self.view.sel().clear()\n            self.view.sel().add(self.at)\n        # Working on formula handling\n        self.td = create_table(self.view)\n        self.td.ClearAllRegions()\n        self.td.PreExecute()\n        formulaIdx = self.td.GetFormulaAt()\n        self.it = SingleFormulaIterator(self.td,formulaIdx)\n        self.process_next()\n\n    def run(self, edit,onDone=None,skipFormula=None,at=None,clearHighlights=True):\n        global highlightEnabled\n        highlightEnabled = False\n        self.at = at\n        if(self.view.sel()):\n            self.origCur = self.view.sel()[0]\n        if(clearHighlights):\n            ClearAllOldCellHighlights()\n        self.onDone = onDone\n        if(skipFormula):\n            self.on_formula_copy_done()\n        else:\n            self.view.run_command('org_fill_in_formula_from_cell',{\"onDone\": evt.Make(self.on_formula_copy_done), \"at\": at,\"clearHighlights\":clearHighlights})\n        #td.HighlightFormula(i)\n# ================================================================================\nclass OrgExecuteTableCommand(sublime_plugin.TextCommand):\n    def on_reformat(self):\n        self.td.RecalculateTableDimensions()\n        self.process_next()\n\n    def on_done_cell(self):\n        self.view.sel().clear()\n        self.view.sel().add(self.result[3])\n        #self.view.run_command('table_editor_next_field')\n        self.view.run_command('table_editor_align')\n        sublime.set_timeout(self.on_reformat,1)\n\n    def process_next(self):\n        self.result = next(self.it,None)\n        if(None == self.result):\n            self.on_done()\n            return\n        r,c,val,reg,fmt = self.result\n        if(val and isinstance(val,float) and fmt and \"%\" in fmt):\n            val = fmt % val\n        #print(\"REPLACING WITH: \" + str(val))\n        self.view.run_command(\"org_internal_replace\", {\"start\": reg.begin(), \"end\": reg.end(), \"text\": str(val), \"onDone\": evt.Make(self.on_done_cell)})\n\n    def on_done(self):\n        global highlightEnabled\n        highlightEnabled = True\n        self.td.PostExecute()\n        if(None != self.origCur):\n            self.view.sel().clear()\n            self.view.sel().add(self.origCur)\n        evt.EmitIf(self.onDone)\n\n    def on_formula_copy_done(self):\n        if(None != self.at):\n            self.view.sel().clear()\n            self.view.sel().add(self.at)\n        # Working on formula handling\n        self.td = create_table(self.view)\n        self.td.ClearAllRegions()\n        self.td.PreExecute()\n        self.it = FormulaIterator(self.td)\n        self.process_next()\n\n    def run(self, edit,onDone=None,skipFormula=None,at=None,clearHighlights=True):\n        global highlightEnabled\n        highlightEnabled = False\n        self.at = at\n        if(self.view.sel()):\n            self.origCur = self.view.sel()[0]\n        if(clearHighlights):\n            ClearAllOldCellHighlights()\n        self.onDone = onDone\n        if(skipFormula):\n            self.on_formula_copy_done()\n        else:\n            self.view.run_command('org_fill_in_formula_from_cell',{\"onDone\": evt.Make(self.on_formula_copy_done), \"at\": at,\"clearHighlights\":clearHighlights})\n        #td.HighlightFormula(i)\n\n\n# ================================================================================\nclass OrgExecuteAllTablesCommand(sublime_plugin.TextCommand):\n\n    def continueRun(self):\n        for r in range(self.cur,self.last_row):\n            self.cur = r\n            pt = self.view.text_point(r,1)\n            if(not self.inTable and isTable(self.view,pt)):\n                self.view.run_command('org_execute_table',{\"at\":pt,\"onDone\":evt.Make(self.continueRun),\"clearHighlights\":False})\n                self.inTable = True\n                break\n            elif(self.inTable and not isTable(self.view,pt)):\n                self.inTable = False\n\n    def run(self,edit,at=None):\n        ClearAllOldCellHighlights()\n        global tableCache\n        self.last_row = self.view.endRow()\n        self.cur = 0\n        self.inTable = False\n        self.continueRun()\n\n\n# ================================================================================\nclass OrgClearTableRegionsCommand(sublime_plugin.TextCommand):\n    def run(self,edit,at=None):\n        global tableCache\n        self.td = tableCache.GetTable(self.view,at)\n        if(self.td):\n            self.td.ClearAllRegions()\n\n# ================================================================================\nclass OrgHighlightFormulaCommand(sublime_plugin.TextCommand):\n    def run(self,edit):\n        global tableCache\n        td = tableCache.GetTable(self.view)\n        if(td):\n            td.ClearAllRegions()\n            i = td.CursorToFormula()\n            if(None != i):\n                td.HighlightFormula(i)\n\n# ================================================================================\nclass OrgHighlightCellCommand(sublime_plugin.TextCommand):\n    def run(self,edit):\n        if(not sets.Get(\"tableShowCursor\", True)):\n            return\n        global tableCache\n        td = tableCache.GetTable(self.view)\n        if(td):\n            rv = td.CursorToCell()\n            if(rv):\n                r,c = rv\n                td.HighlightCell(r, c, 10)\n\n# ================================================================================\nclass OrgHighlightFormulaFromCellCommand(sublime_plugin.TextCommand):\n    def run(self,edit):\n        global tableCache\n        td = tableCache.GetTable(self.view)\n        if(td):\n            td.ClearAllRegions()\n            formulaIdx = td.GetFormulaAt()\n            if(None != formulaIdx):\n                td.HighlightFormula(formulaIdx)\n\n\n# ================================================================================\nclass OrgEditFormulaForCellCommand(sublime_plugin.TextCommand):\n    def run(self,edit,onDone=None):\n        global tableCache\n        td = tableCache.GetTable(self.view)\n        if(td):\n            td.ClearAllRegions()\n            formulaIdx = td.GetFormulaAt()\n            if(None != formulaIdx):\n                r,c = td.CursorToCell()\n                fml = td.GetFormula(formulaIdx)\n                reg = td.FindCellRegion(r,c)\n                self.view.run_command(\"org_internal_replace\", {\"start\": reg.begin(), \"end\": reg.end(), \"text\": str(fml.raw), \"onDone\": onDone})\n\n# ================================================================================\nclass OrgClearCellCommand(sublime_plugin.TextCommand):\n    def on_done(self):\n        self.view.run_command('table_editor_align')\n        evt.EmitIf(self.onDone)\n    def run(self,edit,onDone=None):\n        global tableCache\n        self.onDone = onDone\n        td = tableCache.GetTable(self.view)\n        if(td):\n            td.ClearAllRegions()\n            r,c = td.CursorToCell()\n            reg = td.FindCellRegion(r,c)\n            self.view.run_command(\"org_internal_replace\", {\"start\": reg.begin(), \"end\": reg.end(), \"text\": \"\", \"onDone\": evt.Make(self.on_done)})\n\n# ================================================================================\nclass OrgExecOnColumnCommand(sublime_plugin.TextCommand):\n    def on_reformat(self):\n        self.td.RecalculateTableDimensions()\n        self.process_next()\n\n    def on_done_cell(self):\n        self.view.sel().clear()\n        self.view.sel().add(self.result[3])\n        #self.view.run_command('table_editor_next_field')\n        self.view.run_command('table_editor_align')\n        sublime.set_timeout(self.on_reformat,1)\n\n    def process_next(self):\n        self.result = next(self.it,None)\n        if(None == self.result):\n            self.on_done()\n            return\n        r,c,val,reg,fmt = self.result\n        if(val and isinstance(val,float) and fmt and \"%\" in fmt):\n            val = fmt % val\n            #print(\"REPLACING WITH: \" + str(val))\n        self.view.run_command(\"org_internal_replace\", {\"start\": reg.begin(), \"end\": reg.end(), \"text\": str(val), \"onDone\": evt.Make(self.on_done_cell)})\n\n    def on_expr(self,text):\n        if(text.strip() != \"\"):\n            idx=self.td.AddTemporaryFormula(\"@\"+str(self.r) + \"$\" + str(self.c) + \"..\" +\"@\"+str(self.td.Height()) + \"$\" + str(self.c) + \"=\" + text)\n            if(None != idx):\n                self.it = SingleFormulaIterator(self.td, idx)\n                self.process_next()\n\n    def on_done(self):\n        self.view.run_command('table_editor_align')\n        self.RemoveTemporaryFormula()\n        evt.EmitIf(self.onDone)\n\n    def run(self,edit,onDone=None):\n        global tableCache\n        self.onDone = onDone\n        td = tableCache.GetTable(self.view)\n        if(td):\n            self.td = td\n            td.ClearAllRegions()\n            self.r,self.c = td.CursorToCell()\n            self.view.window().show_input_panel(\"Expr: \",\"\", self.on_expr, None, None)\n\n# ================================================================================\nclass OrgTableAutoComputeCommand(sublime_plugin.TextCommand):\n    def on_reformat(self):\n        self.on_done()\n\n    def on_done_cell(self):\n        self.view.sel().clear()\n        self.view.sel().add(self.result[3])\n        self.view.run_command('table_editor_align')\n        sublime.set_timeout(self.on_reformat,1)\n\n    def on_done(self):\n        global highlightEnabled\n        highlightEnabled = True\n        if(isTableFormula(self.view)):\n            self.view.run_command(\"org_highlight_formula\")\n        elif(isTable(self.view)):\n            self.view.run_command(\"org_highlight_formula_from_cell\")\n            self.view.run_command(\"org_highlight_cell\")\n        evt.EmitIf(self.onDone)\n\n    def on_aligned(self):\n        td = tableCache.GetTable(self.view)\n        if(td):\n            cell = td.CursorToCell()\n            formulaIdx = td.GetFormulaAt()\n            if(None != formulaIdx):\n                it = SingleFormulaIterator(td,formulaIdx)\n                for n in it:\n                    r,c,val,reg,_ = n\n                    if(r == cell[0] and c == cell[1]):\n                        self.result = n\n                        fmt = td.FormulaFormatter(formulaIdx)\n                        if(val and isinstance(val,float) and fmt and \"%\" in fmt):\n                            val = fmt % val\n                        self.view.run_command(\"org_internal_replace\", {\"start\": reg.begin(), \"end\": reg.end(), \"text\": str(val), \"onDone\": evt.Make(self.on_done_cell)})\n\n    def run(self,edit,onDone = None):\n        global highlightEnabled\n        global tableCache\n        self.onDone = onDone\n        highlightEnabled = False\n        self.view.run_command('table_editor_align')\n        sublime.set_timeout(self.on_aligned,1)\n\n\n# ================================================================================\nclass OrgFillInFormulaFromCellCommand(sublime_plugin.TextCommand):\n    def on_reformat(self):\n        td = create_table(self.view)\n        cell = td.CursorToCell()\n        if(cell):\n            r,c = cell\n            txt = td.GetCellText(r,c).strip()\n            formula = None\n            rangeFml = False\n            # Direct targeted formula\n            if(txt.startswith(\":=\")):\n                formula = \"@\" + str(r) + \"$\" + str(c) + txt[1:]\n            # Row targeted formula\n            if(txt.startswith(\">=\")):\n                formula = \"@\" + str(r) + txt[1:]\n            # Column formula\n            if(txt.startswith(\"=\")):\n                formula = \"$\" + str(c) + txt\n                rangeFml = True\n            if(formula):\n                formulaIdx = td.CellToFormula(cell)\n                if(None != formulaIdx):\n                    td.ReplaceFormula(formulaIdx,formula)\n                else:\n                    td.AddNewFormula(formula)\n        if(self.onDone):\n            if(None != self.origCur):\n                self.view.sel().clear()\n                self.view.sel().add(self.origCur)\n            evt.EmitIf(self.onDone)\n        else:\n            self.view.run_command('org_execute_table',{'skipFormula': True,'at': self.at})\n\n    def run(self,edit,onDone=None,at=None,clearHighlights=True):\n        self.onDone = onDone\n        self.origCur = None\n        self.at = at\n        if(self.view.sel()):\n            self.origCur = self.view.sel()[0]\n        if(None != at):\n            self.view.sel().clear()\n            self.view.sel().add(at)\n        if(clearHighlights):\n            ClearAllOldCellHighlights()\n        if(isTable(self.view)):\n            while(not isTable(self.view) or isTableFormula(self.view)):\n                # Cannot align on the table formula line\n                row = self.view.curRow()\n                pt = self.view.text_point(row-1,0)\n                self.view.sel().clear()\n                self.view.sel().add(pt)\n        self.view.run_command('table_editor_align')\n        sublime.set_timeout(self.on_reformat,1)\n\n\n# ================================================================================\nclass TableEventListener(sublime_plugin.ViewEventListener):\n\n    @classmethod\n    def is_applicable(cls, settings):\n        # 4095 seems to crash when querying settings\n        if(int(sublime.version()) != 4095):\n            try:\n                return not \"not here\" in settings.get(\"orgDirs\",\"not here\")\n            except:\n                return False\n        else:\n            return False\n\n    def __init__(self, view):\n        super(TableEventListener, self).__init__(view)\n        self.showing = False\n        self.at = None\n        self.lastpt = None\n        global tableCache\n        self.tableCache = tableCache\n        self.updating = None\n  \n    def GetTable(self):\n        if(isTable(self.view)):\n            return tableCache.GetTable(self.view)\n        return None\n\n    def on_query_completions(self, prefix, locations):\n        if not self.view.match_selector(locations[0], \"text.orgmode\"):\n            return []\n        self.files = []\n        if(self.view.match_selector(locations[0],\"orgmode.link\")):\n            line = self.view.substr(self.view.line(locations[0]))\n            lastsq = len(line)-1\n            pp = None\n            for i in range(len(line)-1,0,-1):\n                if(line[i] == ']'):\n                    lastsq = i\n                if(line[i] == '[' and i > 0 and line[i-1] == '['):\n                    pp = line[i+1:lastsq]\n                    break\n            if(None == pp):\n                return []\n            for i in range(0,len(db.Get().Files)):\n                filename = db.Get().Files[i].filename\n                if(re.search(\".*\"+pp+\".*\",filename)):\n                    self.files.append([os.path.basename(filename),\"file:\"+self.view.MakeRelativeToMe(filename)+\"][$0\"])\n        if(int(sublime.version()) <= 4096):\n            return (self.files,sublime.INHIBIT_EXPLICIT_COMPLETIONS|sublime.INHIBIT_WORD_COMPLETIONS)\n        else:\n            return (self.files,sublime.INHIBIT_EXPLICIT_COMPLETIONS|sublime.INHIBIT_WORD_COMPLETIONS|sublime.DYNAMIC_COMPLETIONS)\n\n        \n\n    def on_selection_modified(self):\n        global highlightEnabled\n        if(not highlightEnabled):\n            return\n        if(self.lastpt and self.lastpt == self.view.sel()[0].begin()):\n            return\n        self.lastpt = self.view.sel()[0].begin()\n        if(isTableFormula(self.view)):\n            self.view.run_command(\"org_highlight_formula\")\n            self.at = self.view.sel()[0].begin()\n            self.showing = True\n        elif(isTable(self.view)):\n            self.view.run_command(\"org_highlight_formula_from_cell\")\n            self.view.run_command(\"org_highlight_cell\")\n            if(not self.at):\n                self.at = self.view.sel()[0].begin()\n            self.showing = True\n        elif(self.showing):\n            self.view.run_command(\"org_clear_table_regions\", {'at': self.at})\n            self.showing = False\n\n    def wasFirstRow(self):\n        return self.preCell[0] <= 1\n    \n    def wasLastRow(self,td):\n        rc = self.preCell[0] >= td.Height()\n        return rc\n\n    def wasFirstCol(self):\n        return self.preCell[1] <= 1\n    \n    def wasLastCol(self,td):\n        return self.preCell[1] >= td.Width()\n\n    def wasPostToHLine(self):\n        r = self.preRow\n        prior = r-1\n        return (prior in self.hlines)\n    \n    def wasPreToHLine(self):\n        r = self.preRow\n        pre = r+1\n        rc = (pre in self.hlines)\n        return rc\n\n    def wasHLine(self):\n        r = self.preRow\n        rc = (r in self.hlines)\n        return rc\n\n    def on_activated(self):\n        if(not self.updating and util.isPotentialOrgFile(self.view.file_name()) and sets.Get(\"backlinksUpdate\",True)):\n            # We do this to avoid recursive update on refocus\n            self.updating = True\n            olinks.UpdateBacklinksForDisplay(self.view)\n            self.updating = False\n\n    def on_text_command(self, command_name, args=None):\n        if('table_editor' in command_name):\n            td = self.GetTable()\n            self.preCell = None\n            self.preRow,col = self.view.curRowCol()\n            if(td):\n                self.preCell = td.CursorToCell()\n                self.hlines  = td.hlines\n                if(isAutoComputeRow(self.view)):\n                    self.view.run_command(\"org_table_auto_compute\")\n    def on_post_text_command(self, command_name, args= None):\n        global highlightEnabled\n        if(not highlightEnabled):\n            return\n        if(hasattr(self,'preCell') and self.preCell != None):\n            if('table_editor_move_row_up' == command_name):\n                # Also if pre was an hline\n                if(self.wasFirstRow() or self.wasHLine() or self.wasPostToHLine()):\n                    return\n                # 2 rows flipped\n                td = self.GetTable()\n                RE_ROW = re.compile(\"[@](?P<num>[0-9]+)\")\n                line = td.formulaLine\n                out = \"\"\n                last = 0\n                for m in RE_ROW.finditer(line):\n                    s = m.span()\n                    num = int(m.group('num'))\n                    if(num == self.preCell[0]):\n                        newNum = num - 1\n                        out += line[last:s[0]] + \"@\" + str(newNum)\n                        last = s[1]\n                    elif(num == (self.preCell[0]-1)):\n                        newNum = num + 1\n                        out += line[last:s[0]] + \"@\" + str(newNum)\n                        last = s[1]\n                    else:\n                        out += line[last:s[1]]\n                        last = s[1]\n                out += line[last:]\n                lineReg = self.view.line(self.view.text_point(td.formulaRow,0))\n                self.view.run_command(\"org_internal_replace\", {\"start\": lineReg.begin(), \"end\": lineReg.end(), \"text\": out})\n            elif('table_editor_move_row_down' == command_name):\n                # Also if pre was an hline\n                td = self.GetTable()\n                if(self.wasLastRow(td) or self.wasHLine() or self.wasPreToHLine()):\n                    return\n                # 2 rows flipped\n                RE_ROW = re.compile(\"[@](?P<num>[0-9]+)\")\n                line = td.formulaLine\n                out = \"\"\n                last = 0\n                for m in RE_ROW.finditer(line):\n                    s = m.span()\n                    num = int(m.group('num'))\n                    if(num == self.preCell[0]):\n                        newNum = num + 1\n                        out += line[last:s[0]] + \"@\" + str(newNum)\n                        last = s[1]\n                    elif(num == (self.preCell[0]+1)):\n                        newNum = num - 1\n                        out += line[last:s[0]] + \"@\" + str(newNum)\n                        last = s[1]\n                    else:\n                        out += line[last:s[1]]\n                        last = s[1]\n                out += line[last:]\n                lineReg = self.view.line(self.view.text_point(td.formulaRow,0))\n                self.view.run_command(\"org_internal_replace\", {\"start\": lineReg.begin(), \"end\": lineReg.end(), \"text\": out})\n            elif('table_editor_move_column_left' == command_name):\n                if(self.wasFirstCol()):\n                    return\n                # 2 cols flipped\n                td = self.GetTable()\n                RE_ROW = re.compile(\"[$](?P<num>[0-9]+)\")\n                line = td.formulaLine\n                out = \"\"\n                last = 0\n                for m in RE_ROW.finditer(line):\n                    s = m.span()\n                    num = int(m.group('num'))\n                    if(num == self.preCell[1]):\n                        newNum = num - 1\n                        out += line[last:s[0]] + \"$\" + str(newNum)\n                        last = s[1]\n                    elif(num == (self.preCell[1]-1)):\n                        newNum = num + 1\n                        out += line[last:s[0]] + \"$\" + str(newNum)\n                        last = s[1]\n                    else:\n                        out += line[last:s[1]]\n                        last = s[1]\n                out += line[last:]\n                lineReg = self.view.line(self.view.text_point(td.formulaRow,0))\n                self.view.run_command(\"org_internal_replace\", {\"start\": lineReg.begin(), \"end\": lineReg.end(), \"text\": out})\n            elif('table_editor_move_column_right' == command_name):\n                td = self.GetTable()\n                if(self.wasLastCol(td)):\n                    return\n                # 2 cols flipped\n                RE_ROW = re.compile(\"[$](?P<num>[0-9]+)\")\n                line = td.formulaLine\n                out = \"\"\n                last = 0\n                for m in RE_ROW.finditer(line):\n                    s = m.span()\n                    num = int(m.group('num'))\n                    if(num == self.preCell[1]):\n                        newNum = num + 1\n                        out += line[last:s[0]] + \"$\" + str(newNum)\n                        last = s[1]\n                    elif(num == (self.preCell[1]+1)):\n                        newNum = num - 1\n                        out += line[last:s[0]] + \"$\" + str(newNum)\n                        last = s[1]\n                    else:\n                        out += line[last:s[1]]\n                        last = s[1]\n                out += line[last:]\n                lineReg = self.view.line(self.view.text_point(td.formulaRow,0))\n                self.view.run_command(\"org_internal_replace\", {\"start\": lineReg.begin(), \"end\": lineReg.end(), \"text\": out})\n            elif('table_editor_kill_row' == command_name):\n                # This has a problem! It doesn't move the formula up!\n                # I am going to have to find the formula and delete the blank lines so it gets moved!\n                td = self.GetTable()\n                RE_ROW = re.compile(\"[@](?P<num>[0-9]+)\")\n                line = td.formulaLine\n                out = \"\"\n                last = 0\n                for m in RE_ROW.finditer(line):\n                    s = m.span()\n                    num = int(m.group('num'))\n                    if(num > self.preCell[0]):\n                        newNum = num - 1\n                        out += line[last:s[0]] + \"@\" + str(newNum)\n                        last = s[1]\n                    if(num == self.preCell[0]):\n                        out += line[last:s[0]] + \"@INVALID\"\n                        last = s[1]\n                    else:\n                        out += line[last:s[1]]\n                        last = s[1]\n                out += line[last:]\n                lineReg = self.view.line(self.view.text_point(td.formulaRow,0))\n                spacesReg = lineReg\n                if(td.spacesRow > 0):\n                    spacesReg = self.view.line(self.view.text_point(td.spacesRow,0))\n                self.view.run_command(\"org_internal_replace\", {\"start\": spacesReg.begin(), \"end\": lineReg.end(), \"text\": out})\n            elif('table_editor_insert_row' == command_name):\n                td = self.GetTable()\n                RE_ROW = re.compile(\"[@](?P<num>[0-9]+)\")\n                line = td.formulaLine\n                out = \"\"\n                last = 0\n                for m in RE_ROW.finditer(line):\n                    s = m.span()\n                    num = int(m.group('num'))\n                    if(num >= self.preCell[0]):\n                        newNum = num + 1\n                        out += line[last:s[0]] + \"@\" + str(newNum)\n                        last = s[1]\n                    else:\n                        out += line[last:s[1]]\n                        last = s[1]\n                out += line[last:]\n                lineReg = self.view.line(self.view.text_point(td.formulaRow,0))\n                self.view.run_command(\"org_internal_replace\", {\"start\": lineReg.begin(), \"end\": lineReg.end(), \"text\": out})\n            elif('table_editor_delete_column' == command_name):\n                td = self.GetTable()\n                RE_ROW = re.compile(\"[$](?P<num>[0-9]+)\")\n                line = td.formulaLine\n                out = \"\"\n                last = 0\n                for m in RE_ROW.finditer(line):\n                    s = m.span()\n                    num = int(m.group('num'))\n                    if(num > self.preCell[1]):\n                        newNum = num - 1\n                        out += line[last:s[0]] + \"$\" + str(newNum)\n                        last = s[1]\n                    if(num == self.preCell[1]):\n                        out += line[last:s[0]] + \"$INVALID\"\n                        last = s[1]\n                    else:\n                        out += line[last:s[1]]\n                        last = s[1]\n                out += line[last:]\n                lineReg = self.view.line(self.view.text_point(td.formulaRow,0))\n                self.view.run_command(\"org_internal_replace\", {\"start\": lineReg.begin(), \"end\": lineReg.end(), \"text\": out})\n            elif('table_editor_insert_column' == command_name):\n                td = self.GetTable()\n                RE_ROW = re.compile(\"[$](?P<num>[0-9]+)\")\n                line = td.formulaLine\n                out = \"\"\n                last = 0\n                for m in RE_ROW.finditer(line):\n                    s = m.span()\n                    num = int(m.group('num'))\n                    if(num >= self.preCell[1]):\n                        newNum = num + 1\n                        out += line[last:s[0]] + \"$\" + str(newNum)\n                        last = s[1]\n                    else:\n                        out += line[last:s[1]]\n                        last = s[1]\n                out += line[last:]\n                lineReg = self.view.line(self.view.text_point(td.formulaRow,0))\n                self.view.run_command(\"org_internal_replace\", {\"start\": lineReg.begin(), \"end\": lineReg.end(), \"text\": out})\n\n\n"
  },
  {
    "path": "orgtableplot.py",
    "content": "\nimport sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nimport OrgExtended.orgutil.util as util\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orginsertselected as ins\nimport OrgExtended.simple_eval as simpev\nimport OrgExtended.orgextension as ext\nimport OrgExtended.orgparse.date as orgdate\nimport OrgExtended.orgduration as orgduration\nimport math\nimport random\nimport ast\nimport operator as op\nimport subprocess\nimport platform\nimport time\n\n\ndef plot_write_table_data_to(params,table,f,r,c,first=False):\n    txt = table.GetCellText(r,c).strip()\n    if(first):\n        if((r == 1 and table.StartRow() != 1) and not (\"include\" in params and \"header\" in params[\"include\"])):\n            f.write(\"#\")\n    else:\n        f.write(\"\\t\")\n    if(not util.numberCheck(txt) and \" \" in txt or \"\\t\" in txt):\n        f.write(\"\\\"\"+ txt + \"\\\"\")\n    else:\n        f.write(txt)\n\ndef plot_build_data_file(table,params):\n    filename = params['_filename']\n    datafile = os.path.join(params['_sourcepath'],os.path.splitext(filename)[0]+\".data\")\n    params['_datafile'] = datafile\n    # Maybe skip the first column if it has lables\n    startCol = 1\n    #for r in range(1,table.Height() + 1):\n    #    if(not isNumeric(table.GetCellText(r,1).strip())):\n    #        startCol += 1\n    #        break\n    ind = startCol\n    if('ind' in params):\n        if(startCol > 1):\n            ind = int(params['ind'])+1\n        else:\n            ind = int(params['ind'])\n    usingVals = range(startCol, table.Width()+1)\n    if('deps' in params):\n        deps = params['deps']\n        usingVals = util.ToIntList(deps)\n\n    with open(datafile,\"w\") as f:\n        for r in range(1,table.Height()+1):\n            c = ind\n            plot_write_table_data_to(params,table,f,r,c,first=True)\n            # Eventually we will need to do this with a user specified range.\n            for c in usingVals:\n                if(c != ind):\n                    plot_write_table_data_to(params,table,f,r,c)\n            f.write(\"\\n\")\n    return datafile\n\ndef plot_param(p,n,defaultVal):\n    v = defaultVal\n    if(n in p):\n        v = p[n]\n    return v\n\ndef plot_quote(v):\n    if not \"\\\"\" in v:\n        v = \"\\\"\" + v + \"\\\"\"\n    return v\n\ndef find_in_using(idx,usings):\n    for i in range(0,len(usings)):\n        if(usings[i] == idx):\n            return i + 2\n\ndef plot_build_command_file(table, params):\n    filename = params['_filename']\n    gpltfile = os.path.join(params['_sourcepath'],os.path.splitext(filename)[0]+\".gplt\")\n    params['_gpltfile'] = gpltfile\n    dataFile = params['_datafile']\n    filename = params['_filename']\n    withstmt = \" notitle \"\n    usingVals = []\n    with open(gpltfile,\"w\") as f:\n        title = plot_quote(plot_param(params,'title',\"Table Data\"))\n        f.write('set title ' + title + \"\\n\")\n        ff,ext = os.path.splitext(filename)\n        if(ext == '.png'):\n            f.write('set term png \\n')\n        if(ext == '.jpg' or ext == '.jpeg'):\n            f.write('set term jpeg \\n')\n        if(ext == '.gif'):\n            f.write('set term gif \\n')\n        if(ext == '.html'):\n            f.write('set term canvas \\n')\n        if(ext == '.txt'):\n            f.write('set term dumb \\n')\n        if(ext == '.svg'):\n            f.write('set term svg \\n')\n        if(ext == '.ps'):\n            f.write('set term postscript \\n')\n\n        if(filename != \"viewer\"):\n            f.write('set output ' + plot_quote(filename.replace('\\\\','\\\\\\\\')) + \"\\n\")\n        if('deps' in params):\n            deps = params['deps']\n            t = deps.replace('(',\"\").replace(\")\",\"\")\n            ts = re.split(r'\\s+',t)\n            for x in ts:\n                if(x.strip() != \"\"):\n                    usingVals.append(int(x.strip()))\n        ind = 1\n        if('unset' in params):\n            for x in params['unset']:\n                f.write('unset ' + x + '\\n')\n        if('set' in params):\n            for x in params['set']:\n                f.write('set ' + x + '\\n')\n        for x,y in params.items():\n            if(isinstance(y,str)):\n                y = y.strip()\n            if(x == \"using\"):\n                withstmt = \" \" + y.replace(\"\\\"\",\"\") + \" \"\n            if(x == \"with\"):\n                if(y == 'histograms'):\n                    count = 1\n                    first = True\n                    for i in usingVals:\n                        count = count + 1\n                        seriesTitle = table.GetCellText(1,i).strip()\n                        if(seriesTitle != \"\"):\n                            seriesTitle = \"\\\"\" + seriesTitle + \"\\\"\"\n                        else:\n                            seriesTitle = \"\\\"col \"+str(i)+\"\\\"\"\n                        if(not first):\n                            withstmt += \",\\\"\\\" using \" + str(count) + \" with histograms title \" + seriesTitle + \" \"\n                        else:\n                            withstmt = \" using \" + str(count) + \" with histograms title \" + seriesTitle + \" \"\n                    continue\n                if(y == 'candlesticks'):\n                    count = 0\n                    for idx in range(0,len(usingVals),4):\n                        count = count*4 + ind + 1\n                        i = usingVals[idx]\n                        seriesTitle = table.GetCellText(1,i).strip()\n                        if(seriesTitle != \"\"):\n                            seriesTitle = \"\\\"\" + seriesTitle + \"\\\"\"\n                        else:\n                            seriesTitle = \"\\\"series\"+str(i)+\"\\\"\"\n                        withstmt = \" using \" + str(ind)+\":\"+str(count)+\":\"+str(count+1)+\":\"+str(count+2)+\":\"+str(count+3) + \" with \"+y+\" title \" + seriesTitle + \" \"\n                    continue\n                else:\n                    count = 1\n                    first = True\n                    for i in usingVals:\n                        count = count + 1\n                        seriesTitle = table.GetCellText(1,i).strip()\n                        if(seriesTitle != \"\"):\n                            seriesTitle = \"\\\"\" + seriesTitle + \"\\\"\"\n                        else:\n                            seriesTitle = \"\\\"series\"+str(i)+\"\\\"\"\n                        if(not first):\n                            withstmt += \",\\\"\\\" using \" + str(ind)+\":\"+str(count) + \" with \"+y+\" title \" + seriesTitle + \" \"\n                        else:\n                            withstmt = \" using \" + str(ind)+\":\"+str(count) + \" with \"+y+\" title \" + seriesTitle + \" \"\n                        first = False\n            #elif not x.startswith(\"_\") and x != 'set':\n            #    f.write(x + \" \" + y + \"\\n\")\n        f.write('plot ' + plot_quote(dataFile.replace('\\\\','\\\\\\\\')) + withstmt + '\\n')\n        pass\n\ndef plot_get_params(table,view):\n    dt = datetime.datetime.now()\n    sourcepath = os.path.dirname(view.file_name())\n    filename = \"plot_\" + str(dt.year) + \"_\" + str(dt.month) + \"_\" + str(dt.day) + \"_\" + str(dt.time().hour) + \"_\" + str(dt.time().minute) + \"_\" + str(dt.time().second) + \".png\"\n    params = {}\n    params['_filename'] = os.path.join(sourcepath,filename)\n    params['_sourcepath'] = sourcepath\n    row = view.curRow()\n    node = db.Get().At(view, row)\n    if(node):\n        plot = \" \" + node.get_comment('PLOT',\"\")[0]\n        ps     = re.split(r'\\s+[a-zA-Z][a-zA-Z0-9]+[:]',plot) \n        ps = ps[1:]\n        keys   = [m.group(0) for m in re.finditer(r'\\s+[a-zA-Z][a-zA-Z0-9]+[:]',plot)]\n        #keys   = [m.group(0) for m in re.finditer(r'(^|\\s+)[^: ]+[:]',plot)]\n        for i in range(0,len(keys)):\n            k = keys[i].strip()\n            if(k.endswith(':')):\n                k = k[:-1]\n            v = ps[i].strip()\n            if(k == 'set'):\n                if(not 'set' in params):\n                    params['set'] = []\n                params['set'].append(v.replace(\"\\\"\",\"\"))\n                continue\n            if(k == 'unset'):\n                if(not 'unset' in params):\n                    params['unset'] = []\n                params['unset'].append(v.replace(\"\\\"\",\"\"))\n                continue\n            if(k == 'file'):\n                filename = v\n                if(filename == \"viewer\"):\n                    params[\"_filename\"] = \"viewer\"\n                    continue\n                sourcepath = os.path.dirname(filename)\n                if(len(sourcepath) > 2):\n                    params['_sourcepath'] = sourcepath\n                    params['_filename'] = filename\n                else:\n                    params['_filename'] = os.path.join(params['_sourcepath'],filename)\n                continue\n            else:\n                params[k] = v\n    return params\n\nRE_SRC_BLOCK = re.compile(r\"^\\s*\\#\\+(BEGIN_SRC|begin_src)\\s+(?P<name>[^: ]+)\\s*\")\nRE_RESULTS = re.compile(r\"^\\s*\\#\\+(RESULTS|results)[:]\\s*$\")\nRE_HEADING = re.compile(r\"^[*]+\\s+\")\nRE_PROPERTY_DRAWER = re.compile(r\"^\\s*[:][a-zA-Z0-9]+[:]\\s*$\")\nRE_BLOCK = re.compile(r\"^\\s*\\#\\+(BEGIN_|begin_)[a-zA-Z]+\\s+\")\nRE_IS_BLANK_LINE = re.compile(r\"^\\s*$\")\ndef plot_find_results(table,view):\n    row = view.curRow()\n    node = db.Get().At(view, row)\n    if(node):\n        row              = table.end + 1\n        fileEndRow,_     = view.rowcol(view.size())\n        inResults        = False\n        inPropertyDrawer = False\n        inBlock          = False\n        startResults     = None\n        for rw in range(row, fileEndRow):\n            line = view.substr(view.line(view.text_point(rw,0)))\n            if(not inResults and RE_RESULTS.search(line)):\n                startResults = rw\n                inResults = True\n                continue\n            # A new heading ends the results.\n            if(RE_HEADING.search(line) or RE_PROPERTY_DRAWER.search(line) or RE_BLOCK.search(line)):\n                if(inResults):\n                    table.resultsRegion = sublime.Region(view.text_point(startResults,0),view.text_point(rw,0)-1)\n                    return True\n                else:\n                    break\n            if(inResults and RE_IS_BLANK_LINE.search(line)):\n                table.resultsRegion = sublime.Region(view.text_point(startResults,0),view.text_point(rw,0)-1)\n                return True\n        # We just hit the end of the file.\n        if(inResults):\n            table.resultsRegion = sublime.Region(view.text_point(startResults,0),view.line(view.text_point(fileEndRow,0)).end())\n            return True\n        # We hit the end of the file and didn't find a results tag.\n        # We need to make one.\n        if(not inResults):\n            table.resultsRegion = sublime.Region(view.text_point(table.end+2,0),view.text_point(table.end+2,0))\n            return False\nppp = None\ndef plot_table_command(table,view):\n    # First get parameters\n    ps = plot_get_params(table,view)\n    # Next build the data file\n    datafile = plot_build_data_file(table,ps)\n    # Next build the plot command file\n    plot_build_command_file(table,ps)\n    # Shell out to gnu plot\n    plotcmd = sets.Get(\"gnuplot\",r\"C:\\Program Files\\gnuplot\\bin\\gnuplot.exe\")\n    output = ps['_filename']\n\n    outpath    = os.path.dirname(output)\n    sourcepath = os.path.dirname(view.file_name())\n    commandLine = [plotcmd, \"-c\", ps['_gpltfile'] ]\n    try:\n        startupinfo = subprocess.STARTUPINFO()\n        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n    except:\n        startupinfo = None\n    cwd = os.path.join(sublime.packages_path(),\"User\") \n    if(output == \"viewer\" and platform.system() == \"Windows\"):\n        global ppp\n        ppp = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n        o = \"\"\n        e = \"\"\n    else:\n        popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n        (o,e) = popen.communicate()\n    print(\"Attempting to plot data from table:\")\n    print(\"STDOUT: \\n\" + str(o))\n    print(\"STDERR: \\n\" + str(e))\n    cullTempFiles = True\n    if(cullTempFiles):\n        if(os.path.exists(ps['_datafile'])):\n            os.remove(ps['_datafile']) \n        if(os.path.exists(ps['_gpltfile'])):\n            os.remove(ps['_gpltfile']) \n    row = view.curRow()\n    node = db.Get().At(view, row)\n    level = 1\n    indent = \" \"\n    if(node):\n        level = node.level\n        indent = \" \" * level + \" \"\n    o = indent + \"#+RESULTS:\\n\"+indent+\"[[file:\" + output.replace(\"\\\\\",\"/\") + \"]]\"\n    if(output != \"viewer\"):\n        have = plot_find_results(table,view)\n        if(not have):\n            o = \"\\n\" + o\n        view.run_command(\"org_internal_replace\", {\"start\": table.resultsRegion.begin(), \"end\": table.resultsRegion.end(), \"text\": o})\n    print(o)\n    #return o.split('\\n') + e.split('\\n')\n\n\n\n"
  },
  {
    "path": "orgtimechart.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nfrom   OrgExtended.orgparse.sublimenode import * \nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orgduration as dur\nimport OrgExtended.orgagenda as ag\nimport uuid\nimport subprocess\n\n\nlog = logging.getLogger(__name__)\n\n\nclass OrgTimesheet(ag.TodoView):\n    def __init__(self, name, setup=True, **kwargs):\n        super(OrgTimesheet, self).__init__(name, False, **kwargs)\n\n    def InsertTableHeadings(self, edit):\n        self.view.insert(edit, self.view.sel()[0].begin(), \"|Name|Estimate|Start|End|Dep|Assigned|Spent|X|\\n|-\\n\")\n\n    # Dependencies are marked with the AFTER tag or an ORDERED list.\n    def GetAfter(self, n):\n        dep = n.get_property(\"AFTER\", \"\")\n        if dep and not dep == \"\":\n            file, at = db.Get().FindByAnyId(dep)\n            if file:\n                dep = file.At(at)\n            else:\n                dep = None\n        if not dep or dep == \"\":\n            t = n\n            while t.parent is not None and not t.parent.is_root():\n                orde = t.parent.get_property(\"ORDERED\", None)\n                print(\"PROP: \" + str(orde))\n                if orde is not None:\n                    dep = n.get_sibling_and_child_up()\n                    # Chain to parent in ORDERED setup.\n                    if dep is None and t != n:\n                        dep = n.parent\n                    break\n                t = t.parent\n        return dep\n\n    def GetGlobalProperty(self, name, n, ass):\n        props = n.list_comment('PROPERTY', None)\n        if (props):\n            for i in range(0, len(props), 2):\n                prop = props[i]\n                prop = prop.strip()\n                if (prop.startswith('ASSIGNED') and len(props) > i + 1):\n                    ass = props[i + 1]\n                    return ass\n        return ass\n\n    def GetAssigned(self, n):\n        ass = sets.Get(\"timesheetDefaultAssigned\", \"\")\n        ass = self.GetGlobalProperty(\"ASSIGNED\", n, ass)\n        ass = n.get_property(\"ASSIGNED\", ass)\n        return ass\n\n    def GetSection(self, n):\n        ass = sets.Get(\"timesheetDefaultSection\", None)\n        ass = self.GetGlobalProperty(\"SECTION\", n, ass)\n        if n.parent is not None:\n            ass = n.parent.get_property(\"SECTION\", ass)\n        ass = n.get_property(\"SECTION\", ass)\n        return ass\n\n    def GetClockingData(self, n):\n        if n.clock:\n            return n.duration()\n        return \"\"\n\n    def PreprocessAfter(self):\n        for entry in self.entries:\n            n        = entry['node']\n            sec = self.GetSection(n)\n            if sec:\n                entry['section'] = sec\n            dep = self.GetAfter(n)\n            if dep:\n                entry['after'] = dep\n                index = 0\n                for dp in self.entries:\n                    index += 1\n                    d = dp['node']\n                    if d == dep:\n                        entry['after_offset'] = index\n                        entry['after_name'] = dep.heading\n\n    def RenderSheet(self, edit, view):\n        self.view = view\n        self.InsertTableHeadings(edit)\n        newEntries = []\n        self.PreprocessAfter()\n\n        for entry in self.entries:\n            n        = entry['node']\n            filename = entry['file'].AgendaFilenameTag()\n            estimate = n.get_property(\"EFFORT\", \"\")\n            dt = None\n            timestamps = n.get_timestamps(active=True, point=True, range=True)\n            end = \"\"\n            start = \"\"\n            if timestamps and len(timestamps) > 0:\n                dt = timestamps[0].start\n            if n.deadline:\n                dt = n.deadline.start\n            if n.scheduled:\n                dt = n.scheduled.start\n            if dt:\n                start = dt.strftime(\"<%Y-%m-%d>\")\n                if estimate != \"\":\n                    duration = dur.OrgDuration.Parse(estimate)\n                    endtm = dt + duration.timedelta()\n                    end = endtm.strftime(\"<%Y-%m-%d>\")  \n                    pass\n            else:\n                start = \"\"\n            done = \"\"\n            if ag.IsDone(n):\n                done = \"x\"\n\n            spent = self.GetClockingData(n)\n            dependenton = entry['after_offset'] if 'after_offset' in entry else \"\"\n            # TODO: Adjust index to match table separators\n            assigned = self.GetAssigned(n)\n            self.view.insert(edit, self.view.sel()[0].begin(), \"|{0:15}|{1:12}|{2}|{3}|{4}|{5}|{6}|{7}|\\n\".format(n.heading,estimate,start,end,dependenton,assigned,spent,done))\n\n    def RenderMermaidGanttFile(self):\n        tpath = sets.Get(\"timesheetPath\", None)\n        if tpath is None:\n            print(\"ERROR CANNOT RENDER MERMAID WITHOUT timesheetPath in config as destination for file\")\n            return\n        if not os.path.exists(tpath):\n            os.makedirs(tpath)\n        filename = os.path.join(tpath, \"schedule.mermaid\")\n        with open(filename, \"w\") as f:\n            self.CreateMermaidGanttFile(f)\n        self.GenerateMermaidGanttChartFromFile(filename)\n\n    def GenerateMermaidGanttChartFromFile(self, filename):\n        # To install on mac or linux:\n        # npm install @mermaid-js/mermaid-cli\n        # if sys.platform == 'darwin':\n        #    mmdc = \"./node_modules/.bin/mmdc\"\n        # elif sys.platform == 'win32':\n        #    mmdc = \"C:\\\\Users\\\\ihdav\\\\node_modules\\\\.bin\\\\mmdc.ps1\"\n        print(\"Trying to render: \" + filename)\n        execs = sets.Get(\"mermaidPath\", None)\n        tpath = sets.Get(\"timesheetPath\", None)\n        if execs is None:\n            print(\"CANNOT RENDER MERMAID WITHOUT mmdc command line tool. Please install mermaid-cli and fill in mermaidPath\")\n            return\n        outputFilename = os.path.join(tpath, \"project_schedule.png\")\n        # inputFilename = \"D:\\\\Git\\\\notes\\\\worklog\\\\schedule.mermaid\"\n        if sys.platform == 'win32':\n            commandLine = [\"powershell.exe\", execs, \"-i\", filename, \"-o\", outputFilename, \"--width\", \"2500\", \"--height\", \"1024\"]\n        elif sys.platform == 'darwin':\n            commandLine = [execs, \"-i\", filename, \"-o\", outputFilename, \"--width\", \"2500\", \"--height\", \"1024\"]\n        try:\n            startupinfo = subprocess.STARTUPINFO()\n            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW\n        except Exception:\n            startupinfo = None\n        view = sublime.active_window().active_view()\n        fn = view.file_name()\n        cwd = tpath\n        if fn is not None:\n            cwd = os.path.dirname(fn)\n        popen = subprocess.Popen(commandLine, universal_newlines=True, cwd=cwd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n        # popen.wait()\n        (o, e) = popen.communicate()\n        log.debug(o)\n        log.debug(e)\n\n    def RenderGoogleGanttFile(self):\n        tpath = sets.Get(\"timesheetPath\", None)\n        if tpath is None:\n            print(\"ERROR CANNOT RENDER GOOGLE GANTT WITHOUT timesheetPath in config\")\n            return\n        if not os.path.exists(tpath):\n            os.makedirs(tpath)\n        filename = os.path.join(tpath, \"project_schedule.html\")\n        with open(filename, \"w\") as f:\n            self.CreateGoogleGanttFile(f)\n\n    def CreateGoogleGanttFile(self, f):\n        self.PreprocessAfter()\n        import re\n        idx = 0\n        f.write(\"\"\"\n<html>\n<head>\n  <!-- <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css2?family=Source%20Sans%20Pro\">  -->\n  <script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>\n\n<style>\ntext {\n  font-family: \"Sofia\" !important;\n}\nbody {\n  font-family: \"Sofia\", sans-serif;\n}\n</style>\n  <script type=\"text/javascript\">\n    google.charts.load('current', {'packages':['gantt']});\n    google.charts.setOnLoadCallback(drawChart);\n\n    function daysToMilliseconds(days) {\n      return days * 24 * 60 * 60 * 1000;\n    }\n\n    function drawChart() {\n\n      var data = new google.visualization.DataTable();\n      data.addColumn('string', 'Task ID');\n      data.addColumn('string', 'Task Name');\n      data.addColumn('string', 'Resource');\n      data.addColumn('date', 'Start Date');\n      data.addColumn('date', 'End Date');\n      data.addColumn('number', 'Duration');\n      data.addColumn('number', 'Percent Complete');\n      data.addColumn('string', 'Dependencies');\n      data.addRows([\"\"\")\n\n        curSection = None\n        for entry in self.entries:\n            n        = entry['node']\n            filename = entry['file'].AgendaFilenameTag()\n            section  = entry['section'] if 'section' in entry else None\n            estimate = n.get_property(\"EFFORT\", \"\")\n            dt = None\n            timestamps = n.get_timestamps(active=True,point=True,range=True)\n            end = None\n            start = None\n            duration = \"1\"\n            if estimate != \"\":\n                duration = dur.OrgDuration.Parse(estimate).days()\n            if timestamps and len(timestamps) > 0:\n                dt = timestamps[0].start\n            if n.deadline:\n                dt = n.deadline.start\n            if n.scheduled:\n                dt = n.scheduled.start\n            if dt:\n                start = dt\n                if estimate != \"\":\n                    duration = dur.OrgDuration.Parse(estimate)\n                    end = dt + duration.timedelta()\n                    duration = duration.days()\n                    pass\n            else:\n                start = None\n            done = False\n            percentDone = 0\n            if ag.IsDone(n):\n                done = True\n                percentDone = 100\n\n            resource=\"active\"\n\n            spent = self.GetClockingData(n)\n            dependenton = entry['after_name'] if 'after_name' in entry else None\n            assigned = self.GetAssigned(n)\n            idx += 1\n            if(idx > 0):\n                #if(done):\n                #    continue\n                #if(curSection != section and section != None):\n                #    f.write(\"section {name}\\n\".format(name=section))\n                #    curSection = section\n                date = start\n                dep = dependenton\n                if assigned and assigned.strip() != None:\n                    resource = assigned.strip()\n                if done:\n                    resource = \"done\"\n                if (date == \"\"):\n                    date = sets.Get(\"timesheetDefaultStartDate\",\"2021-05-18\")\n                if start:\n                    start = \"new Date({year},{month},{day})\".format(year=start.year,month=start.month,day=start.day)\n                else:\n                    start = \"null\"\n                if end:\n                    end = \"new Date({year},{month},{day})\".format(year=end.year,month=end.month,day=end.day)\n                else:\n                    end = \"null\"\n                line = \"\"\n                if idx != 1:\n                    line += \",\"\n                if (dep != None and dep != \"\"):\n                    line += \"[\\\"{name}\\\",\\\"{name}\\\",\\\"{resource}\\\", {start},{end},daysToMilliseconds({duration}),{percent},\\\"{after}\\\"]\\n\".format(name=n.heading,idx=idx,after=str(dep),duration=duration,start=start,end=end,percent=percentDone,resource=resource)\n                else:\n                    line += \"[\\\"{name}\\\",\\\"{name}\\\",\\\"{resource}\\\", {start},{end},daysToMilliseconds({duration}),{percent},null]\\n\".format(name=n.heading,idx=idx,start=start,end=end,duration=duration,percent=percentDone,resource=resource)\n                f.write(line)\n        # colorByRowLabel: true \n        f.write(\"\"\"]);\nvar options = {\n        'font-family': 'Sofia',\n        height: 1200,\n        is3D: true,\n        title: 'Hello World',\n        gantt: {\n          trackHeight: 30,\n        }\n      };\n\n      var chart = new google.visualization.Gantt(document.getElementById('chart_div'));\n\n      chart.draw(data, options);\n    }\n  </script>\n</head>\n<body>\n  <div id=\"chart_div\"></div>\n</body>\n</html>\n\"\"\")\n        \n    # This is REALLY rough it gives us a non functional, really basic view.\n    def CreateMermaidGanttFile(self,f):\n        self.PreprocessAfter()\n        import re\n        idx = 0\n        f.write(\"gantt\\n\")\n        f.write(\"\\tdateFormat YYYY-MM-DD\\n\")\n        f.write(\"\\taxisFormat %m-%d\\n\")\n        f.write(\"\\ttitle Bench Schedule\\n\")\n        f.write(\"\\ttodayMarker off\\n\")\n        f.write(\"\\texcludes    weekends\\n\")\n        curSection = None\n        for entry in self.entries:\n            n        = entry['node']\n            filename = entry['file'].AgendaFilenameTag()\n            section  = entry['section'] if 'section' in entry else None\n            estimate = n.get_property(\"EFFORT\", \"\")\n            dt = None\n            timestamps = n.get_timestamps(active=True, point=True, range=True)\n            end = \"\"\n            start = \"\"\n            duration = \"1d\"\n            if estimate != \"\":\n                duration = dur.OrgDuration.Parse(estimate)\n            if timestamps and len(timestamps) > 0:\n                dt = timestamps[0].start\n            if n.deadline:\n                dt = n.deadline.start\n            if n.scheduled:\n                dt = n.scheduled.start\n            if dt:\n                start = dt.strftime(\"%Y-%m-%d\")\n                if estimate != \"\":\n                    duration = dur.OrgDuration.Parse(estimate)\n                    endtm = dt + duration.timedelta()\n                    end = endtm.strftime(\"%Y-%m-%d\")  \n                    pass\n            else:\n                start = \"\"\n            ## spent = self.GetClockingData(n)\n            dependenton = entry['after_offset'] if 'after_offset' in entry else \"\"\n            # TODO: Adjust index to match table separators\n            assigned = self.GetAssigned(n)\n            #self.view.insert(edit, self.view.sel()[0].begin(), \"|{0:15}|{1:12}|{2}|{3}|{4}|{5}|{6}|{7}|\\n\".format(n.heading,estimate,start,end,dependenton,assigned,spent,done))\n            idx += 1\n            if (idx > 0):\n                if (curSection != section and section is not None):\n                    f.write(\"section {name}\\n\".format(name=section))\n                    curSection = section\n                date = start\n                dep = dependenton\n                prefix = \"\"\n                if (ag.IsDone(n)):\n                    prefix = \"done,\"\n                if (assigned == 'D'):\n                    prefix = \"done,\"\n                if (assigned == 'A'):\n                    prefix += \"active,\"\n                if (assigned == 'C'):\n                    prefix += 'crit,'\n                if (assigned == 'M'):\n                    prefix += 'milestone,'\n                if (assigned == 'X'):\n                    prefix += 'crit,done,'\n                if (assigned == 'Y'):\n                    prefix += 'crit,active,'\n                if (date == \"\"):\n                    date = sets.Get(\"timesheetDefaultStartDate\", \"2023-01-02\")\n                line = \"\"\n                if (dep is not None and dep != \"\"):\n                    line = \"\\t{name}\\t:{prefix}{idx},{start},{duration}\\n\".format(prefix=prefix,name=n.heading,idx=idx,start=\"after \" + str(dep),duration=duration)\n                else:\n                    line = \"\\t{name}\\t:{prefix}{idx},{start},{duration}\\n\".format(prefix=prefix,name=n.heading,idx=idx,start=date,duration=duration)\n                f.write(line)\n    def FilterEntry(self, n, filename):\n        return (ag.IsDone(n) or ag.IsTodo(n)) and not ag.IsProject(n) and not ag.IsArchived(n)\n\n# ================================================================================\nclass TimesheetRegistry:\n    def __init__(self):\n        self.KnownViews = {}\n        self.AddView(\"Todos\", OrgTimesheet)\n\n    def AddView(self,name,cls):\n        self.KnownViews[name] = cls\n\n    # ViewName: <NAME> <ARGS> : <NAME> <ARGS>\n    def ParseArgs(self, n ):\n        tokens = n.split(':')\n        name = tokens[0].strip()\n        args = {}\n        i = 1\n        while(i < len(tokens)):\n            p = tokens[i].strip()\n            if(len(p) > 0):\n                idx = p.find(' ')\n                if(idx > 0):\n                    pname = p[:idx].strip()\n                    pval = p[idx:].strip()\n                    args[pname] = pval\n                    #print(pname + \" -> \" + pval)\n                else:\n                    args[p] = True\n            i += 1\n        return (name, args)\n\n    def CreateCompositeView(self,views,name=\"Timesheet\"):\n        vlist = []\n        for v in views:\n            n, args = self.ParseArgs(v)\n            # For timesheets we ONLY have the one view.\n            # We may need to pull the filter from the other known views in the future?\n            n = \"Todos\"\n            vv = None\n            if(args == None):\n                vv = self.KnownViews[n](n, False)\n            else:\n                vv = self.KnownViews[n](n, False, **args)\n            if(vv):\n                return vv\n        return None\n\ntimesheetRegistry = TimesheetRegistry()\n\n\nclass OrgInsertTimesheetCommand(sublime_plugin.TextCommand):\n    def run(self, edit, toShow=None, onDone=None):\n        self.onDone = onDone\n        self.pos = self.view.sel()[0]\n        self.views = sets.Get(\"AgendaCustomViews\", {\"Default\": [\"Todos\"]})\n        self.keys = list(self.views.keys())\n        self.edit = edit\n        ag.ReloadAllUnsavedBuffers()\n        if toShow is None:\n            toShow = \"Default\"\n        nameOfShow = toShow\n        self.views = self.views[nameOfShow]\n        ts = timesheetRegistry.CreateCompositeView(self.views, nameOfShow)\n        ts.FilterEntries()\n        ts.RenderSheet(edit, self.view)\n        self.view.sel().clear()\n        self.view.sel().add(self.pos)\n        self.view.run_command('table_editor_next_field')\n        evt.EmitIf(self.onDone)\n\n\nclass OrgChooseTimesheetCommand(sublime_plugin.TextCommand):\n    def on_done_st4(self, index, modifers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        if (index < 0):\n            return\n        key = self.keys[index]\n        self.view.run_command(\"org_insert_timesheet\", {\"toShow\": key, \"onDone\": self.onDone})\n\n    def run(self, edit, toShow=None, onDone=None):\n        self.onDone = onDone\n        self.pos = self.view.sel()[0]\n        self.views = sets.Get(\"AgendaCustomViews\", {\"Default\": [\"Todos\"]})\n        self.keys = list(self.views.keys())\n        self.edit = edit\n        if (int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(self.keys, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(self.keys, self.on_done_st4, -1, -1)\n\n\nclass OrgGenerateMermaidGanttChart(sublime_plugin.TextCommand):\n\n    def on_done_st4(self, index, modifers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        if (index < 0):\n            return\n        key = self.keys[index]\n        self.Run(key)\n\n    def Run(self, nameOfShow):\n        ag.ReloadAllUnsavedBuffers()\n        self.views = self.views[nameOfShow]\n        print(\"Creating composite view\")\n        ts = timesheetRegistry.CreateCompositeView(self.views, nameOfShow)\n        print(\"Filtering entries\")\n        ts.FilterEntries()\n        print(\"Rendering mermaid\")\n        ts.RenderMermaidGanttFile()\n        print(\"Done rendering...\")\n        evt.EmitIf(self.onDone)\n\n    def run(self, edit, toShow=None, onDone=None):\n        self.onDone = onDone\n        self.pos = self.view.sel()[0]\n        self.views = sets.Get(\"AgendaCustomViews\", {\"Default\": [\"Todos\"]})\n        self.keys = list(self.views.keys())\n        if toShow is not None:\n            self.Run(toShow)\n            return\n        if (int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(self.keys, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(self.keys, self.on_done_st4, -1, -1)\n\n\nclass OrgGenerateGoogleGanttChart(sublime_plugin.TextCommand):\n\n    def on_done_st4(self, index, modifers):\n        self.on_done(index)\n\n    def on_done(self, index):\n        if (index < 0):\n            return\n        key = self.keys[index]\n        self.Run(key)\n\n    def Run(self, nameOfShow):\n        ag.ReloadAllUnsavedBuffers()\n        self.views = self.views[nameOfShow]\n        ts = timesheetRegistry.CreateCompositeView(self.views, nameOfShow)\n        ts.FilterEntries()\n        ts.RenderGoogleGanttFile()\n        evt.EmitIf(self.onDone)\n\n    def run(self, edit, toShow=None, onDone=None):\n        self.onDone = onDone\n        self.pos = self.view.sel()[0]\n        self.views = sets.Get(\"AgendaCustomViews\", {\"Default\": [\"Todos\"]})\n        self.keys = list(self.views.keys())\n        if toShow is not None:\n            self.Run(toShow)\n            return\n        if (int(sublime.version()) <= 4096):\n            self.view.window().show_quick_panel(self.keys, self.on_done, -1, -1)\n        else:\n            self.view.window().show_quick_panel(self.keys, self.on_done_st4, -1, -1)\n\n    # def run(self, edit, onDone=None):\n    #     self.onDone = onDone\n    #     self.views = sets.Get(\"AgendaCustomViews\",{ \"Default\": [\"Calendar\", \"Day\", \"Blocked Projects\", \"Next Tasks\", \"Loose Tasks\"]})\n    #     self.keys = list(self.views.keys())\n    #     if(int(sublime.version()) <= 4096):\n    #         self.view.window().show_quick_panel(self.keys, self.on_done, -1, -1)\n    #     else:\n    #         self.view.window().show_quick_panel(self.keys, self.on_done_st4, -1, -1)\n"
  },
  {
    "path": "orgtrello.py",
    "content": "try:\n    import sublime\n    import sublime_plugin\n    from Trello.trello import TrelloCommand\n    import requests\n    from Trello.trello import TrelloCommand\n    from Trello.lib.trollop.lib import *\n    from Trello.trello_cache import TrelloCache\n    from Trello.operations import BoardOperation, CardOperation\n    import OrgExtended.orgutil.util as util\n    import OrgExtended.orgdb as db\n    from OrgExtended.orgutil.addmethod import *\n    import OrgExtended.orgparse.node as node\n    import OrgExtended.orgparse.date as odate\n    import datetime\n    import dateutil.parser as dp\n\n    def CreateUniqueViewNamed(name):\n        # Return the view if it exists\n        win = sublime.active_window()\n        for view in win.views():\n            if view.name() == name:\n                win.focus_view(view)\n                return view\n        win.run_command('new_file')\n        view = win.active_view()\n        view.set_name(name)\n        view.set_syntax_file(\"Packages/OrgExtended/OrgExtended.sublime-syntax\")\n        return view\n\n    # @add_property_getter(Card, \"due\")\n    # def cardDue(self):\n    #     if(not hasattr(self,\"_due\")):\n    #         self._due = DateField(\"due\")\n    #     return self._due\n\n    # @add_property_getter(CheckItem, \"due\")\n    # def checkItemDue(self):\n    #     if(not hasattr(self,\"_due\")):\n    #         self._due = DateField(\"due\")\n    #     return self._due\n    \n    # @add_property_getter(CheckItem, \"state\")\n    # def checkItemState(self):\n    #     if(not hasattr(self,\"_state\")):\n    #         self._state = Field(\"state\")\n    #     return self._state\n\n    @add_method(node.OrgBaseNode)\n    def trellotag(self, defaultVal = None):\n        if(defaultVal == None):\n            defaultVal = []\n        globalStartup = sets.Get(\"trello\",defaultVal)\n        return self.list_comment(\"TRELLO\", globalStartup)\n\n    class OrgTrelloBaseCommand(TrelloCommand):\n        def work(self, connection):\n            try:\n                self.Member = connection.me\n                # Grab the boards list. We will use thit to try to match up\n                # with current document for a board update OR for authoring a new board\n                # page interactively.\n                self.Boards = self.Member.boards\n                self.Board = None\n                node = db.Get().RootInView(self.view)\n                if(node != None):\n                    trellotag = node.trellotag()\n                    if(len(trellotag != 0)):\n                        # TODO: Edit check?\n                        #       I shouldn't do this if you have edits to the\n                        #       current buffer\n                        self.BoardId = trellotag[0]\n                        self.Board   = self.Member.get_board(self.BoardId)\n                self.safe_work(connection)\n            except requests.exceptions.HTTPError as e:\n                self.show_token_expired_help(e)\n                raise e\n        def safe_work(self, connection):\n            # Override me\n            pass\n\n\n\n    class OrgTrelloSyncBoardCommand(OrgTrelloBaseCommand):\n        def safe_work(self, connection):\n            update = False\n            if(self.Board != None):\n                update = True\n                # Clear current view\n                self.view.EraseAll()\n                # Rebuild the board in this view.\n                self.CreateBoardInView(self.view, board)\n            if(not update):\n                self.AuthorNewBoard()\n\n        def AuthorNewBoard(self):\n            self.BoardsList = []\n            for b in self.Boards:\n                self.BoardsList.append(b.name)\n            self.show_quick_panel(self.BoardsList, self.OnCreateBoardPage)\n\n        def OnCreateBoardPage(self, index):\n            if(index >= 0):\n                board = self.Boards[index]\n                v = CreateUniqueViewNamed(\"trello_\" + board.name + \".org\")\n                self.CreateBoardInView(v, board)\n\n        def CreateBoardInView(self, v, board):\n            #print(board.goo())\n            v.InsertEnd(\"#+TITLE: Trello - {}\\n\".format(board.name))\n            v.InsertEnd(\"#+TRELLO: {}\\n\".format(board._id))\n            v.InsertEnd(\"\\n\")\n            for l in board.lists:\n                v.InsertEnd(\"* {} {}\\n\".format(\"DONE\" if l.closed else \"TODO\",l.name))\n                v.InsertEnd(\"  :PROPERTIES:\\n\")\n                v.InsertEnd(\"    :TRELLOID: {}\\n\".format(l._id))\n                v.InsertEnd(\"  :END:\\n\")\n                for c in l.cards:\n                    #print(c.goo())\n                    if(not hasattr(c,\"due\")):\n                        c.due = c._data['due']\n                        #c.due = DateField('due')\n                    v.InsertEnd(\"** {} {}{}\\n\".format(\"DONE\" if c.closed else \"TODO\", c.name.ljust(70), (\":\" + \":\".join([str(x['color']) for x in c.labels]) + \":\") if c.labels else \"\"))                    \n                    if(c.due != None):\n                        v.InsertEnd(\"   SCHEDULED: {}\\n\".format(odate.OrgDate.format_date(dp.parse(str(c.due)),True)))\n                    v.InsertEnd(\"   :PROPERTIES:\\n\")\n                    v.InsertEnd(\"     :TRELLOID: {}\\n\".format(c._id))\n                    v.InsertEnd(\"     :URL: [[{}][Card]]\\n\".format(c.short_url))\n                    if(len(c.members) > 0):\n                        v.InsertEnd(\"     :MEMBERS: {}\\n\".format(\",\".join([x.username for x in c.members])))\n                    v.InsertEnd(\"   :END:\\n\")\n                    if(c.desc):\n                        v.InsertEnd(\"   \" + c.desc.replace(\"\\n\",\"\\n   \") + \"\\n\")\n                    clists = c.checklists\n                    for clist in clists:\n                        clist.rname = clist._data['name']\n                        v.InsertEnd(\"*** {} [%]\\n\".format(clist.rname))\n                        for it in clist.checkItems:\n                            if not hasattr(it,'state'):\n                                it.state = it._data['state']\n                                #it.state = Field('state')\n                            if not hasattr(it,'rname'):\n                                it.rname = it._data['name']\n                            v.InsertEnd(\"    - [{}] {}\\n\".format(' ' if it.state == 'incomplete' else 'x',it.rname))\n                    comments = c.comments()\n                    for com in comments:\n                        v.InsertEnd(\"*** From {}\\n\".format(com[\"username\"]))\n                        v.InsertEnd(\"    {}\\n\".format(com[\"text\"]))\n            v.run_command('org_recalc_all_checkbox_summaries')\n            v.run_command('org_fold_all')\n\n\n    class OrgTrelloAddCardCommand(OrgTrelloBaseCommand):\n        def safe_work(self, connection):\n            pass\n\n\nexcept ImportError as err:\n    print(\"Install the Trello Package to add trello support to OrgExtended for SublimeText \\n  >> \" + str(err))\n\n\n    \n"
  },
  {
    "path": "orguniqueview.py",
    "content": "import sublime, sublime_plugin\nimport logging\n\nlog = logging.getLogger(__name__)\n\n\nViewMappings = {}\n\ndef CreateUniqueViewNamed(name, syntax):\n    # Close the view if it exists\n    win = sublime.active_window()\n    for view in win.views():\n        if view.name() == name:\n            win.focus_view(view)\n            win.run_command('close')\n    win.run_command('new_file')\n    view = win.active_view()\n    view.set_name(name)\n    view.set_syntax_file(\"Packages/OrgExtended/{}.sublime-syntax\".format(syntax))\n    return view\n\ndef CreateOrFindUniqueViewNamed(name, syntax):\n    # Return the view if it exists\n    win = sublime.active_window()\n    for view in win.views():\n        if view.name() == name:\n            win.focus_view(view)\n            return view\n    win.run_command('new_file')\n    view = win.active_view()\n    view.set_name(name)\n    view.set_syntax_file(\"Packages/OrgExtended/{}.sublime-syntax\".format(syntax))\n    return view\n    \ndef IsViewActuallyActive(name):\n    win = sublime.active_window()\n    for view in win.views():\n        if view.name() == name:\n            return True\n    return False\n\ndef MoveViewToOtherGroup(view,myview):\n    window = sublime.active_window()\n    if (window.num_groups() < 2):\n        #self.window.run_command('clone_file')\n        window.set_layout({\n            \"cols\": [0.0, 0.5, 1.0],\n            \"rows\": [0.0, 1.0],\n            \"cells\": [[0, 0, 1, 1], [1, 0, 2, 1]]\n            })\n        mygroup    = 0\n        othergroup = 1\n    else:\n        window.focus_view(view)\n        mygroup    = 1\n        othergroup = 0\n        if (window.get_view_index(myview)[0] == 0):\n            othergroup = 1\n            mygroup    = 0\n    window.focus_view(view)\n    window.run_command('move_to_group', {'group': othergroup})\n    window.run_command('focus_group', {'group': mygroup})\n    window.focus_view(myview)\n\nclass UniqueView:\n    def __init__(self, name, syntax, reuse=False,curview=None):\n        self.name = name\n        if(reuse):\n            self._view = CreateOrFindUniqueViewNamed(name,syntax=syntax)\n        else:\n            self._view = CreateUniqueViewNamed(name,syntax=syntax)\n        self._view.set_name(self.name)\n        if(curview != None):\n            MoveViewToOtherGroup(self._view,curview)\n        self._view.set_read_only(True)\n        self._view.set_scratch(True)\n        # View mappings is required so we can return the \n        # UniqueView rather than the view\n        ViewMappings[name] = self\n\n    @property\n    def view(self):\n        return self._view\n\n    @staticmethod\n    def Get(name,syntax=\"OrgExtended\",reuse=True,curview=None):\n        if(name in ViewMappings and IsViewActuallyActive(name)):\n            return ViewMappings[name]\n        else:\n            return UniqueView(name,syntax,reuse,curview)\n\n    @staticmethod\n    def IsShowing(name):\n        return IsViewActuallyActive(name)\n"
  },
  {
    "path": "orgunittests.py",
    "content": "import sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport OrgExtended.orgparse.node as node\nimport OrgExtended.orgutil.util as util\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgdb as db\nimport OrgExtended.asettings as sets\nimport OrgExtended.pymitter as evt\nimport OrgExtended.orginsertselected as ins\nimport OrgExtended.simple_eval as simpev\nimport OrgExtended.orgextension as ext\nimport OrgExtended.orgparse.date as orgdate\nimport OrgExtended.orgduration as orgduration\nfrom   OrgExtended.orgplist import *\nimport math\nimport random\nimport ast\nimport operator as op\nimport subprocess\nimport platform\nimport time\n\n\nclass OrgPlistTestCommand(sublime_plugin.TextCommand):\n    def run(self,edit):\n    \t# Test the plist parsing utilities \n        p = PList.createPList(\":width 10 :height 20\")\n        util.TEST(\"plist int1\",p.GetInt('width',-1),10,\"Width did not come back propperly\")\n        util.TEST(\"plist int2\",p.GetInt('height',-1),20,\"Height did not come back propperly\")\n\n        util.TEST(\"plist intstr1\",p.Get('width',-1),\"10\",\"Width did not come back propperly\")\n        util.TEST(\"plist intstr2\",p.Get('height',-1),\"20\",\"Height did not come back propperly\")\n\n        p = PList.createPList(\":width 10.5 :height 20.2\")\n        util.TEST(\"plist float1\",p.GetFloat('width',-1),10.5,\"Width did not come back propperly\")\n        util.TEST(\"plist float2\",p.GetFloat('height',-1),20.2,\"Height did not come back propperly\")\n\n        p = PList.createPList(\":param (1 2 3 4) :param2 ( 5 6) :param3 (7 8 )\")\n        util.TEST(\"plist list1\",p.Get('param',None),\"(1 2 3 4)\",\"List test\")\n        util.TEST(\"plist list2\",p.Get('param2',None),\"( 5 6)\",\"List param 2 test\")\n        util.TEST(\"plist list3\",p.Get('param3',None),\"(7 8 )\",\"List param 3 test\")\n\n        util.TEST(\"plist intlist1\",p.GetIntList('param',None),[1,2,3,4],\"List test\")\n        util.TEST(\"plist intlist2\",p.GetIntList('param2',None),[5,6],\"List param 2 test\")\n        util.TEST(\"plist intlist3\",p.GetIntList('param3',None),[7,8],\"List param 3 test\")\n\n        util.TEST(\"plist liststr1\",p.GetList('param',None),['1','2','3','4'],\"List test\")\n        util.TEST(\"plist liststr2\",p.GetList('param2',None),['5','6'],\"List param 2 test\")\n        util.TEST(\"plist liststr3\",p.GetList('param3',None),['7','8'],\"List param 3 test\")\n\n        p = PList.createPList(\":param \\\"Hello World\\\" :param2 \\\"Yet Again\\\"\")\n        util.TEST(\"plist string1\",p.Get('param',None),\"Hello World\",\"List string 1 test\")\n        util.TEST(\"plist string1\",p.Get('param2',None),\"Yet Again\",\"List string 1 test\")\n\n        p = PList.createPList(\":var a=b :var c=d :var e=f :other hello\")\n        util.TEST(\"plist list dict\",p.Get('var',None),['a=b','c=d','e=f'],\"List dict test 1\")\n        util.TEST(\"plist dict\",p.GetDict('var',None),{'a':'b','c':'d','e':'f'},\"Dict test 1\")\n        util.TEST(\"plist dict other\",p.Get('other',None),\"hello\",\"Dict other test 1\")\n\n        p = PList.createPList(\":a on :b off :c t :d false\")\n        util.TEST(\"plist a bool\",p.GetBool('a'),True,\"Bool a tests\")\n        util.TEST(\"plist b bool\",p.GetBool('b'),False,\"Bool b tests\")\n        util.TEST(\"plist c bool\",p.GetBool('c'),True,\"Bool c tests\")\n        util.TEST(\"plist d bool\",p.GetBool('d'),False,\"Bool d tests\")\n\n        p = PList.createPList()\n        p.exList.AddList('say',['hello','world','exclusive'])\n        p.AddFromPList(\":say hello world\")\n        p.AddFromPList(\":say hello world exclusive\")\n        util.TEST('exclusiveList',p.Get('say',None),['exclusive'],\"test it\")\n\n"
  },
  {
    "path": "orgutil/__init__.py",
    "content": ""
  },
  {
    "path": "orgutil/addmethod.py",
    "content": "import os\nfrom functools import wraps # This convenience func preserves name and docstring\n\n\n# Decorator that helps me extend classes.\n# I am using this to extend sublime a bit\n# and add some mechanisms to orgparse without\n# adding sublime specific components to node.\ndef add_method(cls):\n    def decorator(func):\n        setattr(cls, func.__name__, func)\n    return decorator\n\ndef add_property_getter(cls, pname):\n    def decorator(func):\n        setattr(cls, pname, property(func))\n    return decorator"
  },
  {
    "path": "orgutil/asciiclock.py",
    "content": "#-*- coding: utf-8 -*-\n#-----------------------------------------------------------------------\n# Author: delimitry\n#         https://github.com/delimitry/ascii_clock\n#-----------------------------------------------------------------------\n\nimport os\nimport time\nimport math\nimport datetime\n\nclass AsciiCanvas(object):\n    \"\"\"\n    ASCII canvas for drawing in console using ASCII chars\n    \"\"\"\n\n    def __init__(self, cols, lines, fill_char=' '):\n        \"\"\"\n        Initialize ASCII canvas\n        \"\"\"\n        if cols < 1 or cols > 1000 or lines < 1 or lines > 1000:\n            raise Exception('Canvas cols/lines must be in range [1..1000]')\n        self.cols = cols\n        self.lines = lines\n        if not fill_char:\n            fill_char = ' '\n        elif len(fill_char) > 1:\n            fill_char = fill_char[0]\n        self.fill_char = fill_char\n        self.canvas = [[fill_char] * (cols) for _ in range(lines)]\n\n    def clear(self):\n        \"\"\"\n        Fill canvas with empty chars\n        \"\"\"\n        self.canvas = [[self.fill_char] * (self.cols) for _ in range(self.lines)]\n\n    def print_out(self):\n        \"\"\"\n        Print out canvas to console\n        \"\"\"\n        print(self.get_canvas_as_str())\n\n    def add_line(self, x0, y0, x1, y1, fill_char='o'):\n        \"\"\"\n        Add ASCII line (x0, y0 -> x1, y1) to the canvas, fill line with `fill_char`\n        \"\"\"\n        if not fill_char:\n            fill_char = 'o'\n        elif len(fill_char) > 1:\n            fill_char = fill_char[0]\n        if x0 > x1:\n            # swap A and B\n            x1, x0 = x0, x1\n            y1, y0 = y0, y1\n        # get delta x, y\n        dx = x1 - x0\n        dy = y1 - y0\n        # if a length of line is zero just add point\n        if dx == 0 and dy == 0:\n            if self.check_coord_in_range(x0, y0):\n                self.canvas[y0][x0] = fill_char\n            return\n        # when dx >= dy use fill by x-axis, and use fill by y-axis otherwise\n        if abs(dx) >= abs(dy):\n            for x in range(x0, x1 + 1):\n                y = y0 if dx == 0 else y0 + int(round((x - x0) * dy / float((dx))))\n                if self.check_coord_in_range(x, y):\n                    self.canvas[y][x] = fill_char\n        else:\n            if y0 < y1:\n                for y in range(y0, y1 + 1):\n                    x = x0 if dy == 0 else x0 + int(round((y - y0) * dx / float((dy))))\n                    if self.check_coord_in_range(x, y):\n                        self.canvas[y][x] = fill_char\n            else:\n                for y in range(y1, y0 + 1):\n                    x = x0 if dy == 0 else x1 + int(round((y - y1) * dx / float((dy))))\n                    if self.check_coord_in_range(x, y):\n                        self.canvas[y][x] = fill_char\n\n    def add_text(self, x, y, text):\n        \"\"\"\n        Add text to canvas at position (x, y)\n        \"\"\"\n        for i, c in enumerate(text):\n            if self.check_coord_in_range(x + i, y):\n                self.canvas[y][x + i] = c\n\n    def add_rect(self, x, y, w, h, fill_char=' ', outline_char='o'):\n        \"\"\"\n        Add rectangle filled with `fill_char` and outline with `outline_char`\n        \"\"\"\n        if not fill_char:\n            fill_char = ' '\n        elif len(fill_char) > 1:\n            fill_char = fill_char[0]\n        if not outline_char:\n            outline_char = 'o'\n        elif len(outline_char) > 1:\n            outline_char = outline_char[0]\n        for px in range(x, x + w):\n            for py in range(y, y + h):\n                if self.check_coord_in_range(px, py):\n                    if px == x or px == x + w - 1 or py == y or py == y + h - 1:\n                        self.canvas[py][px] = outline_char\n                    else:\n                        self.canvas[py][px] = fill_char\n\n    def add_nine_patch_rect(self, x, y, w, h, outline_3x3_chars=None):\n        \"\"\"\n        Add nine-patch rectangle\n        \"\"\"\n        default_outline_3x3_chars = (\n            '.', '-', '.', \n            '|', ' ', '|', \n            '`', '-', \"'\"\n        )\n        if not outline_3x3_chars:\n            outline_3x3_chars = default_outline_3x3_chars\n        # filter chars\n        filtered_outline_3x3_chars = []\n        for index, char in enumerate(outline_3x3_chars[0:9]):\n            if not char:\n                char = default_outline_3x3_chars[index]\n            elif len(char) > 1:\n                char = char[0]\n            filtered_outline_3x3_chars.append(char)\n        for px in range(x, x + w):\n            for py in range(y, y + h):\n                if self.check_coord_in_range(px, py):\n                    if px == x and py == y:\n                        self.canvas[py][px] = filtered_outline_3x3_chars[0]\n                    elif px == x and y < py < y + h - 1:\n                        self.canvas[py][px] = filtered_outline_3x3_chars[3]\n                    elif px == x and py == y + h - 1:\n                        self.canvas[py][px] = filtered_outline_3x3_chars[6]\n                    elif x < px < x + w - 1 and py == y:\n                        self.canvas[py][px] = filtered_outline_3x3_chars[1]\n                    elif x < px < x + w - 1 and py == y + h - 1:\n                        self.canvas[py][px] = filtered_outline_3x3_chars[7]\n                    elif px == x + w - 1 and py == y:\n                        self.canvas[py][px] = filtered_outline_3x3_chars[2]\n                    elif px == x + w - 1 and y < py < y + h - 1:\n                        self.canvas[py][px] = filtered_outline_3x3_chars[5]\n                    elif px == x + w - 1 and py == y + h - 1:\n                        self.canvas[py][px] = filtered_outline_3x3_chars[8]\n                    else:\n                        self.canvas[py][px] = filtered_outline_3x3_chars[4]\n\n    def check_coord_in_range(self, x, y):\n        \"\"\"\n        Check that coordinate (x, y) is in range, to prevent out of range error\n        \"\"\"\n        return 0 <= x < self.cols and 0 <= y < self.lines\n\n    def get_canvas_as_str(self):\n        \"\"\"\n        Return canvas as a string\n        \"\"\"\n        return '\\n'.join([''.join(col) for col in self.canvas])\n\n    def __str__(self):\n        \"\"\"\n        Return canvas as a string\n        \"\"\"\n        return self.get_canvas_as_str()\n\n    def get_row(self, i):\n    \trows = [''.join(col) for col in self.canvas]\n    \tif(i > 0 and i < len(rows)):\n    \t\treturn rows[i]\n    \treturn ''\n\nx_scale_ratio = 1.75\n\n\ndef draw_second_hand(ascii_canvas, seconds, length, fill_char):\n    \"\"\"\n    Draw second hand\n    \"\"\"\n    x0 = int(math.ceil(ascii_canvas.cols / 2.0))\n    y0 = int(math.ceil(ascii_canvas.lines / 2.0))\n    x1 = x0 + int(math.cos((seconds + 45) * 6 * math.pi / 180) * length * x_scale_ratio)\n    y1 = y0 + int(math.sin((seconds + 45) * 6 * math.pi / 180) * length)\n    ascii_canvas.add_line(int(x0), int(y0), int(x1), int(y1), fill_char=fill_char)\n\n\ndef draw_minute_hand(ascii_canvas, minutes, length, fill_char):\n    \"\"\"\n    Draw minute hand\n    \"\"\"\n    x0 = int(math.ceil(ascii_canvas.cols / 2.0))\n    y0 = int(math.ceil(ascii_canvas.lines / 2.0))\n    x1 = x0 + int(math.cos((minutes + 45) * 6 * math.pi / 180) * length * x_scale_ratio)\n    y1 = y0 + int(math.sin((minutes + 45) * 6 * math.pi / 180) * length)\n    ascii_canvas.add_line(int(x0), int(y0), int(x1), int(y1), fill_char=fill_char)\n\n\ndef draw_hour_hand(ascii_canvas, hours, minutes, length, fill_char):\n    \"\"\"\n    Draw hour hand\n    \"\"\"\n    x0 = int(math.ceil(ascii_canvas.cols / 2.0))\n    y0 = int(math.ceil(ascii_canvas.lines / 2.0))\n    total_hours = hours + minutes / 60.0\n    x1 = x0 + int(math.cos((total_hours + 45) * 30 * math.pi / 180) * length * x_scale_ratio)\n    y1 = y0 + int(math.sin((total_hours + 45) * 30 * math.pi / 180) * length)\n    ascii_canvas.add_line(int(x0), int(y0), int(x1), int(y1), fill_char=fill_char)\n\n\ndef draw_clock_face(ascii_canvas, radius, mark_char):\n    \"\"\"\n    Draw clock face with hour and minute marks\n    \"\"\"\n    x0 = ascii_canvas.cols // 2\n    y0 = ascii_canvas.lines // 2\n    # draw marks first\n    for mark in range(1, 12 * 5 + 1):\n        x1 = x0 + int(math.cos((mark + 45) * 6 * math.pi / 180) * radius * x_scale_ratio)\n        y1 = y0 + int(math.sin((mark + 45) * 6 * math.pi / 180) * radius)\n        if mark % 5 != 0:\n            ascii_canvas.add_text(x1, y1, mark_char)\n    # start from 1 because at 0 index - 12 hour\n    for mark in range(1, 12 + 1):\n        x1 = x0 + int(math.cos((mark + 45) * 30 * math.pi / 180) * radius * x_scale_ratio)\n        y1 = y0 + int(math.sin((mark + 45) * 30 * math.pi / 180) * radius)\n        ascii_canvas.add_text(x1, y1, '%s' % mark)\n\n\ndef draw_clock(now, cols, lines):\n    \"\"\"\n    Draw clock\n    \"\"\"\n    if cols < 25 or lines < 25:\n        print('Too little columns/lines for print out the clock!')\n        return None\n    # Yes we want just plain date not\n    # datetime here to match.\n    if type(now) == datetime.date:\n        return None\n    # prepare chars\n    single_line_border_chars = ('.', '-', '.', '|', ' ', '|', '`', '-', \"'\")\n    second_hand_char = '.'\n    minute_hand_char = 'o'\n    hour_hand_char = 'O'\n    mark_char = '`'\n    if os.name == 'nt':\n        single_line_border_chars = ('.', '-', '.', '|', ' ', '|', '`', '-', \"'\")  # ('\\xDA', '\\xC4', '\\xBF', '\\xB3', '\\x20', '\\xB3', '\\xC0', '\\xC4', '\\xD9')\n        second_hand_char = '.'  # '\\xFA'\n        minute_hand_char = 'o'  # '\\xF9'\n        hour_hand_char = 'O'  # 'o'\n        mark_char = '`'  # '\\xF9'\n    # create ascii canvas for clock and eval vars\n    ascii_canvas = AsciiCanvas(cols, lines)\n    center_x = int(math.ceil(cols / 2.0))\n    center_y = int(math.ceil(lines / 2.0))\n    radius = center_y - 5\n    second_hand_length = int(radius / 1.17)\n    minute_hand_length = int(radius / 1.25)\n    hour_hand_length = int(radius / 1.95)\n    # add clock region and clock face\n    #ascii_canvas.add_rect(5, 3, int(math.floor(cols / 2.0)) * 2 - 9, int(math.floor(lines / 2.0)) * 2 - 5)\n    draw_clock_face(ascii_canvas, radius, mark_char)\n    #now = datetime.datetime.now()\n    # add regions with weekday and day if possible\n    if center_x > 25:\n        left_pos = int(radius * x_scale_ratio) / 2 - 4\n        ascii_canvas.add_nine_patch_rect(int(center_x + left_pos), int(center_y - 1), 5, 3, single_line_border_chars)\n        ascii_canvas.add_text(int(center_x + left_pos + 1), int(center_y), now.strftime('%a'))\n        ascii_canvas.add_nine_patch_rect(int(center_x + left_pos + 5), int(center_y - 1), 4, 3, single_line_border_chars)\n        ascii_canvas.add_text(int(center_x + left_pos + 1 + 5), int(center_y), now.strftime('%d'))\n    # add clock hands\n    #draw_second_hand(ascii_canvas, now.second, second_hand_length, fill_char=second_hand_char)\n    draw_minute_hand(ascii_canvas, now.minute, minute_hand_length, fill_char=minute_hand_char)\n    draw_hour_hand(ascii_canvas, now.hour, now.minute, hour_hand_length, fill_char=hour_hand_char)\n    # print out canvas\n    return ascii_canvas\n    #ascii_canvas.print_out()\n\n\n# def main():\n#     lines = 40\n#     cols = int(lines * x_scale_ratio)\n#     # set console window size and screen buffer size\n#     if os.name == 'nt':\n#         os.system('mode con: cols=%s lines=%s' % (cols + 1, lines + 1))\n#     while True:\n#        os.system('cls' if os.name == 'nt' else 'clear')\n#        draw_clock(cols, lines)\n#        time.sleep(0.2)\n\n"
  },
  {
    "path": "orgutil/navigation.py",
    "content": "import sublime\nimport sublime_plugin\nimport OrgExtended.orgparse.node as node\nimport OrgExtended.orgutil.util as util\n\n\ndef navigate_up(view):\n    (curRow,curCol) = view.curRowCol()\n    while(curRow >= 0):\n        curRow -= 1\n        linePos = view.text_point(curRow,0)\n        pos = view.line(linePos)\n        lineText = view.substr(pos)\n        if node.RE_NODE_HEADER.search(lineText): \n            view.show_at_center(linePos)\n            view.sel().clear()\n            view.sel().add(linePos)\n            break\n\ndef navigate_down(view):\n    (curRow,curCol) = view.curRowCol()\n    max = view.line_count()\n    while(curRow < max):\n        curRow += 1\n        linePos = view.text_point(curRow,curCol)\n        pos = view.line(linePos)\n        lineText = view.substr(pos)\n        if node.RE_NODE_HEADER.search(lineText): \n            view.show_at_center(linePos)\n            view.sel().clear()\n            view.sel().add(linePos)\n            break"
  },
  {
    "path": "orgutil/temp.py",
    "content": "import sublime\nimport sublime_plugin\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport logging\nimport sys\nimport traceback \nimport tempfile\nfrom shutil import copyfile\n\nlog = logging.getLogger(__name__)\n\ndef CreateTempFile(source, suffix=\".temp\",start=None, end=None):\n\tfilename = None\n\ttmp = tempfile.NamedTemporaryFile(delete=False,suffix=suffix)\n\ttry:\n\t\tif(start):\n\t\t\ttmp.write((start + \"\\n\").encode(\"utf-8\"))\n\t\ttmp.write(source.encode('utf-8'))\n\t\tif(end):\n\t\t\ttmp.write((\"\\n\" + end).encode(\"utf-8\"))\n\t\tfilename = tmp.name\n\t\ttmp.close()\t\n\texcept:\n\t\tres = traceback.format_exc()\n\t\tlog.debug(\"Failed to create temp file: \" + str(tmp.name) + \"\\n\" + str(res))\n\t\tpass\n\treturn filename\n\ndef CreateTempFileFromRegion(view, region,suffix=\".temp\",start=None, end=None):\n\tcontent = view.substr(region)\n\treturn CreateTempFile(content,suffix,start,end)\n\ndef GetViewFileAs(view,extension):\n\tsourcepath = os.path.dirname(view.file_name())\n\treturn os.path.join(sourcepath,os.path.splitext(os.path.basename(view.file_name()))[0] + extension)\n\ndef CopyTempToViewDir(view,tempfile,asfile):\n\tsourcepath = os.path.dirname(view.file_name())\n\tdestFile   = os.path.join(sourcepath,asfile)\n\tcopyfile(tempfile, destFile)\n\treturn destFile\n"
  },
  {
    "path": "orgutil/template.py",
    "content": "import string\nimport sublime\nimport sublime_plugin\nimport datetime\nimport re\n\n\ncur1 = re.compile('\\\\$0')\n\n# A really quick and dirty template mechanism.\n# Stolen from: https://makina-corpus.com/blog/metier/2016/the-worlds-simplest-python-template-engine\n#              https://github.com/ebrehault/superformatter\nclass TemplateFormatter(string.Formatter):\n    def __init__(self, resolver=None):\n        super(TemplateFormatter, self).__init__()\n        self.resolver = resolver\n    def format_field(self, value, spec):\n        # REPITITION\n        #>>> sf.format('''Table of contents:\n        #{chapters:repeat:Chapter {{item}}\n        #}''', chapters=[\"I\", \"II\", \"III\", \"IV\"])\n        #'''Table of contents:\n        #Chapter I\n        #Chapter II\n        #Chapter III\n        #Chapter IV\n        #'''\n        if spec.startswith('repeat'):\n            template = spec.partition(':')[-1]\n            if type(value) is dict:\n                value = value.items()\n            return ''.join([template.format(item=item) for item in value])\n        # FUNCTION CALLS\n        #>>> sf.format('My name is {name.upper:call}', name=\"eric\")\n        #'My name is ERIC'\n        elif spec == 'call':\n            return value()\n        # OPTIONAL EXPANSION\n        #>>> sf.format('Action: Back / Logout {manager:if:/ Delete {id}}', manager=True, id=34)\n        #'Action: Back / Logout / Delete 34'        \n        elif spec.startswith('if'):\n            return (value and spec.partition(':')[-1]) or ''\n        else:\n            return super(TemplateFormatter, self).format_field(value, spec)\n    def get_value(self, key, args, kwargs):\n        if(str(key)):\n            if(key in kwargs):\n                return kwargs[key]\n            if(self.resolver):\n                return str(self.resolver(key,None))\n            return None\n        else:\n            return args[key]\n\ndef ExpandTemplate(view, template, format={},resolver=None):\n    # Supported expansions\n    formatDict = {\n    \"date\": str(datetime.date.today()),\n    \"time\": datetime.datetime.now().strftime(\"%H:%M:%S\"),\n    #\"datetime\": str(datetime.datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")),\n    \"datetime\": str(datetime.datetime.now().strftime(\"%Y-%m-%d %a %H:%M\")),\n    \"file\": str(view.file_name()),\n    \"clipboard\": sublime.get_clipboard()\n    }\n\n    if(format != None):\n        formatDict.update(format) \n\n    formatter = TemplateFormatter(resolver)\n    template  = formatter.format(template, **formatDict)\n\n    global cur1\n    mat = cur1.search(template)\n    pos = -1\n    if(mat != None):\n    \tpos = mat.start(0)\n    \ttemplate = cur1.sub('',template)\n    return (template, pos)\n\n\n"
  },
  {
    "path": "orgutil/util.py",
    "content": "import sublime\nimport sublime_plugin\nimport os\nimport base64\nimport urllib.request\nimport OrgExtended.asettings as sets \nimport uuid\nimport re\nimport logging\n\nfrom OrgExtended.orgutil.addmethod import *\n\nlog = logging.getLogger(__name__)\n\ndef isPotentialOrgFile(filename):\n    if(not filename):\n        return False\n    fn = os.path.splitext(filename)\n    exts = sets.Get(\"validOrgExtensions\",[\".org\", \".org_archive\"])\n    return (len(fn) > 1 and (fn[1] in exts))\n\ndef isOrgSyntax(fileOrView):\n    if(type(fileOrView) is sublime.View):\n        cur = fileOrView.sel()[0]\n        names = fileOrView.scope_name(cur.begin())\n        return 'text.orgmode' in names\n    return False\n\ndef isPotentialOrgFileOrBuffer(fileOrView):\n    if(isOrgSyntax(fileOrView)):\n        return True\n    if(type(fileOrView) is sublime.View and fileOrView.file_name()):\n        return isPotentialOrgFile(fileOrView.file_name())\n    elif(type(fileOrView) is str):\n        return isPotentialOrgFile(fileOrView)\n    return False\n\n\n# The safest way to check if a string is numeric or not seems to be this way.\n# Seems super slow to me. I might right an RE for this in the future.\ndef numberCheck(v):\n    try:\n        float(v)\n        return True\n    except:\n        return False\n\ndef isView(fileOrView):\n    return (type(fileOrView) is sublime.View)\n\ndef getTempBufferId(view):\n    return \"buffer_\" + str(view.id())\n\ndef getKey(fileOrView):\n    if(isView(fileOrView)):\n        id = fileOrView.file_name()\n        if(not id):\n            return getTempBufferId(fileOrView)\n        return id.lower()\n    else:\n        return fileOrView.lower()\n\n# Sublime doesn't seem to have svg support in minihtml?\nimage_extensions = [\".jpg\", \".png\", \".gif\"]\n\ndef is_image(url):\n    for ext in image_extensions:\n        if(url.endswith(ext)):\n            return True\n    return False\n\ndef get_as_base64(url):\n    image = urllib.request.urlopen(url)\n    return base64.encodestring(image.read()).decode('ascii').replace('\\n', '')\n\ndef get_as_string(url):\n    image = urllib.request.urlopen(url)\n    return image.read().decode('ascii').replace('\\n', '')\n\ndef RandomString():\n    randomString = uuid.uuid4().hex\n    return randomString.lower()\n\n\n# Extension methods for View.\n# These just make life a little cleaner\n@add_method(sublime.View)\ndef line_count(self):\n    return self.rowcol(self.size())[0] + 1\n\n@add_method(sublime.View)\ndef curRowCol(self):\n    try:\n        if(len(self.sel())>0):\n           return self.rowcol(self.sel()[0].begin())\n    except:\n        pass\n    return None\n\n@add_method(sublime.View)\ndef curRow(self):\n    return self.rowcol(self.sel()[0].begin())[0]\n\n@add_method(sublime.View)\ndef lastRow(self):\n    last_row, _ = self.rowcol(self.size())\n    return last_row\n\n# Returns a region that is the current line\n@add_method(sublime.View)\ndef curLine(self):\n    row = self.curRow()\n    pt = self.text_point(row, 0)\n    return self.line(pt)\n\n# Returns a region that is the current line\n@add_method(sublime.View)\ndef curLineText(self):\n    return self.substr(self.curLine())\n\n@add_method(sublime.View)\ndef lineAt(self,row):\n    pt = self.text_point(row, 0)\n    return self.line(pt)\n\n@add_method(sublime.View)\ndef endRow(self):\n    return self.rowcol(self.size())[0]\n\n@add_method(sublime.View)\ndef isRegionFolded(self, region):\n    for i in self.folded_regions():\n        if i.contains(region):\n            return True\n    return False\n\n@add_method(sublime.View)\ndef getSourceScope(view):\n    all_scopes = view.scope_name(view.sel()[0].begin())\n    split_scopes = all_scopes.split(\" \")\n    for scope in split_scopes:\n        if scope.find(\"source.\") != -1  or \\\n         scope.find(\"embedding.\") != -1 or \\\n         scope.find(\"text.\") != -1:\n            return scope\n    return None\n\nRE_INDENT  = re.compile(r'^(\\s*).*$')\n# RETURNS: a string with the indent of this line.\n@add_method(sublime.View)\ndef getIndent(view, regionOrLine):\n    content = regionOrLine\n    if isinstance(regionOrLine, sublime.Region):\n        content = view.substr(regionOrLine)\n    match = RE_INDENT.match(content)\n    if(match):\n        return match.group(1)\n    else:\n        log.debug(\"Could not match indent: \" + content)\n        return \"\"\n\n# Extract a line of text at row\n# from the buffer\n@add_method(sublime.View)\ndef getLine(view, row):\n    pt = view.text_point(row, 0)\n    reg = view.line(pt)\n    if(reg.begin() == reg.end()):\n        return \"\"\n    if(reg.begin() >= view.size()):\n        return \"\"\n    return view.substr(reg)\n\nRE_HEADING = re.compile('^[*]+ ')\n# Try to find the parent of a region (by indent)\n# parent\n#   of\n#   a\n#   region\n#   search up\n@add_method(sublime.View)\ndef findParentByIndent(view, region, exceptionRe=None, headingRe=None):\n    row, col = view.rowcol(region.begin() + 1)\n    content  = view.substr(view.line(region))\n    indent   = len(view.getIndent(content))\n    row     -= 1\n    found    = False\n    lastHeading = row\n    # Look upward \n    while row >= 0:\n        content = view.getLine(row)\n        if len(content.strip()):\n            if(headingRe and headingRe.search(content)):\n                lastHeading = row\n            if(RE_HEADING.search(content) or exceptionRe and exceptionRe.search(content)):\n                if(not headingRe):\n                    lastHeading = row\n                found = True\n                break\n            cur_indent = len(view.getIndent(content))\n            if cur_indent < indent:\n                if(not headingRe):\n                    lastHeading = row\n                found = True\n                break\n        row -= 1\n    if found:\n        # return the parent we found.\n        return view.line(view.text_point(lastHeading,0))\n    return None\n\n\n@add_method(sublime.View)\ndef getLineAndRegion(view, row):\n    pt = view.text_point(row, 0)\n    reg = view.line(pt)\n    return (reg,view.substr(reg))\n\n# Is this the last point in the buffer\n@add_method(sublime.View)\ndef isBeyondLastRow(view,row):\n    return view.rowcol(view.size())[0] < row\n\n@add_method(sublime.View)\ndef ReplaceRegion(view, reg, text, onDone=None):\n    view.run_command(\"org_internal_replace\", {\"start\": reg.begin(), \"end\": reg.end(), \"text\": text, \"onDone\": onDone})\n\n@add_method(sublime.View)\ndef Insert(view, pt, text, onDone=None): \n    view.run_command(\"org_internal_insert\", {\"location\": pt, \"text\": text, \"onDone\": onDone})\n\n@add_method(sublime.View)\ndef Erase(view, reg, onDone=None): \n    view.run_command(\"org_internal_erase\", {\"start\": reg.begin(),\"end\": reg.end(), \"onDone\": onDone})\n\n@add_method(sublime.View)\ndef EraseAll(view, onDone=None): \n    view.run_command(\"org_internal_erase\", {\"start\": 0,\"end\": view.size(), \"onDone\": onDone})\n\n@add_method(sublime.View)\ndef InsertEnd(view, text, onDone=None): \n    view.run_command(\"org_internal_insert\", {\"location\": view.size(), \"text\": text, \"onDone\": onDone})\n\n# Takes a filename and returns it with a path relative to our view\n@add_method(sublime.View)\ndef RelativeTo(view, filepath):\n    fp = filepath.strip()\n    # We can't handle absolute paths at the moment\n    if(len(fp) > 2 and fp[0] == '/' or fp[1] == ':'):\n        return fp\n    return os.path.normpath(os.path.join(os.path.dirname(view.file_name()), fp))\n\n# Returns path as a relative path relative to the current view\n@add_method(sublime.View)\ndef MakeRelativeToMe(view, path):\n    current_directory = os.path.dirname(view.file_name())\n    return os.path.relpath(path, current_directory)\n\n# ============================================================\n\n@add_method(sublime.Region)\ndef IncEnd(reg): \n    return sublime.Region(reg.begin(), reg.end() + 1)\n\n# Convert a list string: (a b c d) to an actual list\nspacesplit = re.compile(r\"\\s+\")\ndef ToIntList(val):\n    t = val.replace('(',\"\").replace(\")\",\"\")\n    ts = spacesplit.split(t)\n    vals = []\n    for x in ts:\n        if(x.strip() != \"\"):\n            vals.append(int(x.strip()))\n    return vals\n\ndef ToList(val):\n    t = val.replace('(',\"\").replace(\")\",\"\")\n    ts = spacesplit.split(t)\n    vals = []\n    for x in ts:\n        if(x.strip() != \"\"):\n            vals.append(x.strip())\n    return vals\n\n\ndef TEST(NAME,GOT,T,ERR):\n    if(T != GOT):\n        log.error(\" [FAILED] \" + NAME + \" \" + str(ERR) + \" WANTED: \" + str(T) + \" GOT: \" + str(GOT))\n    else:\n        log.info(\" [PASSED] \" + NAME)"
  },
  {
    "path": "orgutil/webpull.py",
    "content": "# Download highlight js IF we need it!\nimport sublime\nimport sublime_plugin\nimport datetime\nimport re\nfrom pathlib import Path\nimport os\nimport fnmatch\nimport logging\nimport sys\nimport traceback \nimport OrgExtended.orgextension as ext\nimport yaml\nimport sys\nimport subprocess\nimport html\n\nlog = logging.getLogger(__name__)\n\ndef ensure_dir(file_path):\n    directory = os.path.dirname(file_path)\n    if not os.path.exists(directory):\n        os.makedirs(directory)\n\ndef download_highlightjs():\n\tusers = os.path.join(ext.GetUserFolder(),\"highlightjs\")\n\tif(os.path.exists(users)):\n\t\tlog.info(' download_highlighjs - highlightjs folder exists not downloading')\n\t\treturn\n\timport requests\n\t# We have to get the csrf token out of the document\n\t# <input type=\"hidden\" name=\"csrfmiddlewaretoken\" value=\"kn9otxuIzP289hae1RbmrU9fbWoMBgqpWEwctR7pAZL2tq5q6uZKyOmufJ1SWrtA\">\t\n\tr = requests.get('https://highlightjs.org/download')\n\tmatcher = re.compile('^[ \t]*<input[ ]+type=\\\"hidden\\\"[ ]+name=\\\"csrfmiddlewaretoken\\\"[ ]+value=\\\"([^\\\"]+)\\\"')\n\tcookie = r.headers['Set-Cookie']\n\tcookie = cookie[0:cookie.find(';')]\n\tcsrftoken = \"\"\n\tfor l in r.text.split('\\n'):\n\t\tm = matcher.match(l)\n\t\tif(m):\n\t\t\tcsrftoken = str(m.groups(1)[0])\n\tpayload = {\n\t'csrfmiddlewaretoken': csrftoken,\n\t'properties.js': 'on',\n\t'apache.js': 'on',\n\t'bash.js': 'on',\n\t'c.js': 'on',\n\t'csharp.js': 'on',\n\t'cpp.js': 'on',\n\t'c-like.js': 'on',\n\t'css.js': 'on',\n\t'coffeescript.js': 'on',\n\t'diff.js': 'on',\n\t'go.js': 'on',\n\t'xml.js': 'on',\n\t'http.js': 'on',\n\t'json.js': 'on',\n\t'java.js': 'on',\n\t'javascript.js': 'on',\n\t'kotlin.js': 'on',\n\t'less.js': 'on',\n\t'lua.js': 'on',\n\t'makefile.js': 'on',\n\t'markdown.js': 'on',\n\t'nginx.js': 'on',\n\t'objectivec.js': 'on',\n\t'php.js': 'on',\n\t'php-template.js': 'on',\n\t'perl.js': 'on',\n\t'plaintext.js': 'on',\n\t'python.js': 'on',\n\t'python-repl.js': 'on',\n\t'ruby.js': 'on',\n\t'rust.js': 'on',\n\t'scss.js': 'on',\n\t'sql.js': 'on',\n\t'shell.js': 'on',\n\t'swift.js': 'on',\n\t'ini.js': 'on',\n\t'typescript.js': 'on',\n\t'yaml.js': 'on',\n\t'cmake.js': 'on',\n\t'lisp.js': 'on',\n\t'powershell.js': 'on'\n\t}\n\tr = requests.post('https://highlightjs.org/download/',data = payload, headers = {'cookie': cookie, 'Referer': 'https://highlightjs.org/download', 'content-type': 'application/x-www-form-urlencoded'})\n\tif(not 'Content-Type' in r.headers or r.headers['Content-Type'] != 'application/zip'):\n\t\tlog.error(\"Cannot finish highligh js download, download was not a zip file\")\n\t\tlog.error(str(r.headers))\n\t\treturn\n\timport zipfile\n\timport io\n\tos.mkdir(users)\t\n\tothersep = '/'\n\tif(os.sep == othersep):\n\t\tothersep = '\\\\'\n\tz = zipfile.ZipFile(io.BytesIO(r.content))\n\tfor info in z.infolist():\n\t\tdata = z.read(info.filename)   # Reads the data from the file\n\t\tfname = info.filename.replace(othersep, os.sep)\n\t\tfilename = os.path.join(users, fname)\n\t\tensure_dir(filename)\n\t\tfile = open(filename, \"wb\")\n\t\tfile.write(data)\n\t\tfile.close()\t\n\tz.close() \n\tlog.debug(\"Zip file unzipped\")\n\ndef GetZip(url):\n\timport requests\n\tpayload = \"\"\n\tr = requests.get(url)\n\tif(not 'Content-Type' in r.headers or r.headers['Content-Type'] != 'application/zip'):\n\t\tlog.error(\"Cannot finish download, download was not a zip file\")\n\t\tlog.error(str(r.headers))\n\t\treturn None\n\tprint(\"Downloaded zip\")\n\treturn r\n\ndef UnzipRequest(r, targetDir):\n\timport zipfile\n\timport io\n\tos.mkdir(targetDir)\t\n\tothersep = '/'\n\tif(os.sep == othersep):\n\t\tothersep = '\\\\'\n\tz = zipfile.ZipFile(io.BytesIO(r.content))\n\tfor info in z.infolist():\n\t\tdata = z.read(info.filename)   # Reads the data from the file\n\t\tfname = info.filename.replace(othersep, os.sep)\n\t\tfilename = os.path.join(targetDir, fname)\n\t\tensure_dir(filename)\n\t\tfile = open(filename, \"wb\")\n\t\tfile.write(data)\n\t\tfile.close()\t\n\tz.close()\n\ndef DownloadDnd():\n\tr = GetZip('https://github.com/rpgtex/DND-5e-LaTeX-Template/archive/master.zip')\n\tif r != None:\n\t\tUnzipRequest(r)\n\t#unzip -d \"$(kpsewhich -var-value TEXMFHOME)/tex/latex/\" master.zip\n\t#cd \"$(kpsewhich -var-value TEXMFHOME)/tex/latex/\"\n\t#mv DND-5e-LaTeX-Template-master dnd\t"
  },
  {
    "path": "orgxmlthemeparser.py",
    "content": "import os\nfrom xml.etree import ElementTree\nfrom collections import OrderedDict\n\nimport sublime\n\n\nSTYLE_TEMPLATE = \"\"\"\n <dict>\n    <key>name</key>\n    <string>{name}</string>\n    <key>scope</key>\n    <string>{scope}</string>\n    <key>settings</key>\n    <dict>\n{properties}\n    </dict>\n</dict>\n\"\"\"\n\nPROPERTY_TEMPLATE = \"\"\"\n        <key>{key}</key>\n        <string>{value}</string>\n\"\"\"\n\nclass XMLThemeParser:\n    def __init__(self, themeText):\n        self.cs = {}\n        self.plist = ElementTree.XML(themeText)\n        styles = self.plist.find(\"./dict/array\")\n        assert styles\n        self.styles = styles\n        globalsVals = self.styles[0]\n        gv = {}\n        k = None\n        for p in globalsVals:\n            if p.tag == \"dict\":\n                for v in p:\n                    if v.tag == \"key\":\n                        k = v.text\n                    if v.tag == \"string\":\n                        gv[k] = v.text\n        self.cs['globals'] = gv\n        rules = []\n        for d in self.styles[1:]:\n            r = {}\n            for p in d:\n                if p.tag == \"key\":\n                    k = p.text\n                if p.tag == \"string\":\n                    if k == \"name\" or k == 'scope':\n                        r[k] = p.text\n                if p.tag == \"dict\" and k == \"settings\":\n                    dk = None\n                    for c in p:\n                        if c.tag == \"key\":\n                            k = c.text\n                        if c.tag == \"string\":\n                            if k == 'fontStyle':\n                                k = \"font_style\"\n                            r[k] = c.text\n            rules.append(r)\n        self.cs['rules'] = rules\n\n\n    # def _add_scoped_style(self, name, scope, **kwargs):\n    #     properties = \"\".join(PROPERTY_TEMPLATE.format(key=k, value=v) for k, v in kwargs.items())\n    #     new_style = STYLE_TEMPLATE.format(name=name, scope=scope, properties=properties)\n    #     self.styles.append(ElementTree.XML(new_style))\n\n    # def write_new_theme(self, name):\n    #     full_path = os.path.join(sublime.packages_path(), self.get_theme_path(name))\n\n    #     with file.safe_open(full_path, \"wb\", buffering=0) as out_f:\n    #         out_f.write(STYLES_HEADER.encode(\"utf-8\"))\n    #         out_f.write(ElementTree.tostring(self.plist, encoding=\"utf-8\"))"
  },
  {
    "path": "packagecon.py",
    "content": "# Package Control\nimport os\nimport sublime\n\nPCKGCTRL_SETTINGS = \"Package Control.sublime-settings\"\nTABLE_PACKAGE     = \"Table Editor\"\nPS_PACKAGE        = \"PowerShell\"\n#      support the languages and grammars we support.\n\ndef IsInstalled(pkg):\n\tsettings = sublime.load_settings(PCKGCTRL_SETTINGS)\n\treturn pkg in set(settings.get(\"installed_packages\", []))\n\n#def IsPkgInstalled(pkgName):\n#\tsettings = sublime.load_settings(PCKGCTRL_SETTINGS)\n#\treturn pkgName in set(settings.get(\"installed_packages\", []))\n\ndef Install(pkg):\n\tprint(\"Installing `{}` ..\".format(pkg))\n\tsublime.active_window().run_command(\"advanced_install_package\", {\"packages\": pkg})\n\t#Hide()\n\ndef Hide():\n\tsublime.active_window().active_view().hide_popup()\n\n\n\n"
  },
  {
    "path": "pandoc/blocky.css",
    "content": "/*\n * I add this to html files generated with pandoc.\n */\n\nhtml {\n  font-size: 100%;\n  overflow-y: scroll;\n  -webkit-text-size-adjust: 100%;\n  -ms-text-size-adjust: 100%;\n}\n\nbody {\n  color: #444;\n  background-color: #ddd;\n  font-size: 12px;\n  line-height: 1.7;\n  padding: 1em;\n  margin: auto;\n  max-width: 42em;\n  /*background: #fefefe;*/\n  font-family: 'Montserrat', sans-serif;\n}\n\na {\n  /*#0645cd;*/\n  color:  #1e74ac;\n  text-decoration: underline;\n  text-decoration-style: dotted;\n  font-weight: bold;\n}\n\na:visited {\n  color: #0b0090;\n}\n\na:hover {\n  color: #06e;\n}\n\na:active {\n  color: #faa700;\n}\n\na:focus {\n  outline: thin dotted;\n}\n\n*::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\n*::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\na::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\na::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\np {\n  margin: 1em 0;\n}\n\nimg {\n  max-width: 100%;\n}\n\nh1, h2, h3, h4, h5, h6 {\n  color: #1e747c;\n  line-height: 125%;\n  margin-top: 2em;\n  font-weight: normal;\n  font-family: 'Bebas Neue', cursive;\n  border-left-color: #1e747c;\n  border-left-style: solid;\n  border-left-width: 4px;\n  padding-left: 12px;\n}\n\nh4, h5, h6 {\n  color:aaa;\n  font-weight: bold;\n}\n\nh1 {\n  font-size: 2.5em;\n}\n\nh2 {\n  font-size: 2em;\n}\n\nh3 {\n  font-size: 1.5em;\n}\n\nh4 {\n  font-size: 1.2em;\n}\n\nh5 {\n  font-size: 1em;\n}\n\nh6 {\n  font-size: 0.9em;\n}\n\nblockquote {\n  color: #765037;\n  margin: 0;\n  padding-left: 2em;\n  border-left: 0.3em #474356 solid;\n}\n\nhr {\n  display: block;\n  height: 2px;\n  border: 0;\n  border-top: 1px solid #aaa;\n  border-bottom: 1px solid #eee;\n  margin: 1em 0;\n  padding: 0;\n}\n\npre, code, kbd, samp {\n  color: #66402f;\n  font-family: monospace, monospace;\n  _font-family: 'courier new', monospace;\n  font-size: 0.98em;\n  background: #ccc;\n}\n\npre {\n  white-space: pre;\n  white-space: pre-wrap;\n  word-wrap: break-word;\n}\n\nb, strong {\n  font-weight: bold;\n}\n\ndfn {\n  font-style: italic;\n}\n\nins {\n  background: #ff9;\n  color: #000;\n  text-decoration: none;\n}\n\nmark {\n  background: #ff0;\n  color: #000;\n  font-style: italic;\n  font-weight: bold;\n}\n\nsub, sup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nul, ol {\n  margin: 1em 0;\n  padding: 0 0 0 2em;\n}\n\nli p:last-child {\n  margin-bottom: 0;\n}\n\nul ul, ol ol {\n  margin: .3em 0;\n}\n\ndl {\n  margin-bottom: 1em;\n}\n\ndt {\n  font-weight: bold;\n  margin-bottom: .8em;\n}\n\ndd {\n  margin: 0 0 .8em 2em;\n}\n\ndd:last-child {\n  margin-bottom: 0;\n}\n\nimg {\n  border: 0;\n  -ms-interpolation-mode: bicubic;\n  /*vertical-align: middle;*/\n}\n\nfigure {\n  display: block;\n  text-align: center;\n  margin: 1em 0;\n}\n\nfigure img {\n  border: none;\n  margin: 0 auto;\n}\n\nfigcaption {\n  font-size: 0.8em;\n  font-style: italic;\n  margin: 0 0 .8em;\n}\n\ntable {\n  margin-bottom: 2em;\n  border-bottom: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n  border-top: 1px solid #ddd;\n  border-spacing: 0;\n  border-collapse: collapse;\n}\n\ntable th {\n  padding: .2em 1em;\n  background-color: #bbb;\n  border-top: 1px solid #ddd;\n  border-left: 1px solid #aaa;\n}\n\ntable td {\n  padding: .2em 1em;\n  border-top: 1px dotted #aaa;\n  border-left: 1px solid #ddd;\n  vertical-align: top;\n}\n\n.author {\n  font-size: 1.2em;\n  text-align: center;\n}\n\n@media only screen and (min-width: 480px) {\n  body {\n    font-size: 14px;\n  }\n}\n@media only screen and (min-width: 768px) {\n  body {\n    font-size: 16px;\n  }\n}\n@media print {\n  * {\n    background: transparent !important;\n    color: black !important;\n    filter: none !important;\n    -ms-filter: none !important;\n  }\n\n  body {\n    font-size: 12pt;\n    max-width: 100%;\n  }\n\n  a, a:visited {\n    text-decoration: underline;\n  }\n\n  hr {\n    height: 1px;\n    border: 0;\n    border-bottom: 1px solid black;\n  }\n\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n\n  .ir a:after, a[href^=\"javascript:\"]:after, a[href^=\"#\"]:after {\n    content: \"\";\n  }\n\n  pre, blockquote {\n    border: 1px solid #999;\n    padding-right: 1em;\n    page-break-inside: avoid;\n  }\n\n  tr, img {\n    page-break-inside: avoid;\n  }\n\n  img {\n    max-width: 100% !important;\n  }\n\n  @page :left {\n    margin: 15mm 20mm 15mm 10mm;\n}\n\n  @page :right {\n    margin: 15mm 10mm 15mm 20mm;\n}\n\n  p, h2, h3 {\n    orphans: 3;\n    widows: 3;\n  }\n\n  h2, h3 {\n    page-break-after: avoid;\n  }\n}"
  },
  {
    "path": "pandoc/blocky_inheader.html",
    "content": "<link href=\"https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Montserrat&display=swap\" rel=\"stylesheet\">\n<!--font-family: 'Bebas Neue', cursive;-->\n<!--font-family: 'Montserrat', sans-serif;-->"
  },
  {
    "path": "pandoc.css",
    "content": "body {\n    margin: auto;\n    padding-right: 1em;\n    padding-left: 1em;\n    max-width: 44em; \n    border-left: 1px solid black;\n    border-right: 1px solid black;\n    color: black;\n    font-family: Verdana, sans-serif;\n    font-size: 100%;\n    line-height: 140%;\n    color: #333; \n}\npre {\n    border: 1px dotted gray;\n    background-color: #ececec;\n    color: #1111111;\n    padding: 0.5em;\n}\ncode {\n    font-family: monospace;\n}\nh1 a, h2 a, h3 a, h4 a, h5 a { \n    text-decoration: none;\n    color: #7a5ada; \n}\nh1, h2, h3, h4, h5 { font-family: verdana;\n                     font-weight: bold;\n                     border-bottom: 1px dotted black;\n                     color: #7a5ada; }\nh1 {\n        font-size: 130%;\n}\n\nh2 {\n        font-size: 110%;\n}\n\nh3 {\n        font-size: 95%;\n}\n\nh4 {\n        font-size: 90%;\n        font-style: italic;\n}\n\nh5 {\n        font-size: 90%;\n        font-style: italic;\n}\n\nh1.title {\n        font-size: 200%;\n        font-weight: bold;\n        padding-top: 0.2em;\n        padding-bottom: 0.2em;\n        text-align: left;\n        border: none;\n}\n\ndt code {\n        font-weight: bold;\n}\ndd p {\n        margin-top: 0;\n}\n\n#footer {\n        padding-top: 1em;\n        font-size: 70%;\n        color: gray;\n        text-align: center;\n        }"
  },
  {
    "path": "pandoc2.css",
    "content": "/*\n * I add this to html files generated with pandoc.\n */\n\nhtml {\n  font-size: 100%;\n  overflow-y: scroll;\n  -webkit-text-size-adjust: 100%;\n  -ms-text-size-adjust: 100%;\n}\n\nbody {\n  color: #444;\n  font-family: Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif;\n  font-size: 12px;\n  line-height: 1.7;\n  padding: 1em;\n  margin: auto;\n  max-width: 42em;\n  background: #fefefe;\n}\n\na {\n  color: #0645ad;\n  text-decoration: none;\n}\n\na:visited {\n  color: #0b0080;\n}\n\na:hover {\n  color: #06e;\n}\n\na:active {\n  color: #faa700;\n}\n\na:focus {\n  outline: thin dotted;\n}\n\n*::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\n*::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #000;\n}\n\na::-moz-selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\na::selection {\n  background: rgba(255, 255, 0, 0.3);\n  color: #0645ad;\n}\n\np {\n  margin: 1em 0;\n}\n\nimg {\n  max-width: 100%;\n}\n\nh1, h2, h3, h4, h5, h6 {\n  color: #111;\n  line-height: 125%;\n  margin-top: 2em;\n  font-weight: normal;\n}\n\nh4, h5, h6 {\n  font-weight: bold;\n}\n\nh1 {\n  font-size: 2.5em;\n}\n\nh2 {\n  font-size: 2em;\n}\n\nh3 {\n  font-size: 1.5em;\n}\n\nh4 {\n  font-size: 1.2em;\n}\n\nh5 {\n  font-size: 1em;\n}\n\nh6 {\n  font-size: 0.9em;\n}\n\nblockquote {\n  color: #666666;\n  margin: 0;\n  padding-left: 3em;\n  border-left: 0.5em #EEE solid;\n}\n\nhr {\n  display: block;\n  height: 2px;\n  border: 0;\n  border-top: 1px solid #aaa;\n  border-bottom: 1px solid #eee;\n  margin: 1em 0;\n  padding: 0;\n}\n\npre, code, kbd, samp {\n  color: #000;\n  font-family: monospace, monospace;\n  _font-family: 'courier new', monospace;\n  font-size: 0.98em;\n}\n\npre {\n  white-space: pre;\n  white-space: pre-wrap;\n  word-wrap: break-word;\n}\n\nb, strong {\n  font-weight: bold;\n}\n\ndfn {\n  font-style: italic;\n}\n\nins {\n  background: #ff9;\n  color: #000;\n  text-decoration: none;\n}\n\nmark {\n  background: #ff0;\n  color: #000;\n  font-style: italic;\n  font-weight: bold;\n}\n\nsub, sup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nul, ol {\n  margin: 1em 0;\n  padding: 0 0 0 2em;\n}\n\nli p:last-child {\n  margin-bottom: 0;\n}\n\nul ul, ol ol {\n  margin: .3em 0;\n}\n\ndl {\n  margin-bottom: 1em;\n}\n\ndt {\n  font-weight: bold;\n  margin-bottom: .8em;\n}\n\ndd {\n  margin: 0 0 .8em 2em;\n}\n\ndd:last-child {\n  margin-bottom: 0;\n}\n\nimg {\n  border: 0;\n  -ms-interpolation-mode: bicubic;\n  vertical-align: middle;\n}\n\nfigure {\n  display: block;\n  text-align: center;\n  margin: 1em 0;\n}\n\nfigure img {\n  border: none;\n  margin: 0 auto;\n}\n\nfigcaption {\n  font-size: 0.8em;\n  font-style: italic;\n  margin: 0 0 .8em;\n}\n\ntable {\n  margin-bottom: 2em;\n  border-bottom: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n  border-spacing: 0;\n  border-collapse: collapse;\n}\n\ntable th {\n  padding: .2em 1em;\n  background-color: #eee;\n  border-top: 1px solid #ddd;\n  border-left: 1px solid #ddd;\n}\n\ntable td {\n  padding: .2em 1em;\n  border-top: 1px solid #ddd;\n  border-left: 1px solid #ddd;\n  vertical-align: top;\n}\n\n.author {\n  font-size: 1.2em;\n  text-align: center;\n}\n\n@media only screen and (min-width: 480px) {\n  body {\n    font-size: 14px;\n  }\n}\n@media only screen and (min-width: 768px) {\n  body {\n    font-size: 16px;\n  }\n}\n@media print {\n  * {\n    background: transparent !important;\n    color: black !important;\n    filter: none !important;\n    -ms-filter: none !important;\n  }\n\n  body {\n    font-size: 12pt;\n    max-width: 100%;\n  }\n\n  a, a:visited {\n    text-decoration: underline;\n  }\n\n  hr {\n    height: 1px;\n    border: 0;\n    border-bottom: 1px solid black;\n  }\n\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n\n  .ir a:after, a[href^=\"javascript:\"]:after, a[href^=\"#\"]:after {\n    content: \"\";\n  }\n\n  pre, blockquote {\n    border: 1px solid #999;\n    padding-right: 1em;\n    page-break-inside: avoid;\n  }\n\n  tr, img {\n    page-break-inside: avoid;\n  }\n\n  img {\n    max-width: 100% !important;\n  }\n\n  @page :left {\n    margin: 15mm 20mm 15mm 10mm;\n}\n\n  @page :right {\n    margin: 15mm 10mm 15mm 20mm;\n}\n\n  p, h2, h3 {\n    orphans: 3;\n    widows: 3;\n  }\n\n  h2, h3 {\n    page-break-after: avoid;\n  }\n}"
  },
  {
    "path": "pandoc3.css",
    "content": "/*!\n  This is a modified version of Bootstrap.\n  Bootstrap code comes first, customizations are at the end of the file.\n*/\n\n/*!\n * Bootstrap v2.3.2\n *\n * Copyright 2012 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Designed and built with all the love in the world @twitter by @mdo and @fat.\n */\n.clearfix {\n  *zoom: 1;\n}\n.clearfix:before,\n.clearfix:after {\n  display: table;\n  content: \"\";\n  line-height: 0;\n}\n.clearfix:after {\n  clear: both;\n}\n.hide-text {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n.input-block-level {\n  display: block;\n  width: 100%;\n  min-height: 30px;\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nnav,\nsection {\n  display: block;\n}\naudio,\ncanvas,\nvideo {\n  display: inline-block;\n  *display: inline;\n  *zoom: 1;\n}\naudio:not([controls]) {\n  display: none;\n}\nhtml {\n  font-size: 100%;\n  -webkit-text-size-adjust: 100%;\n  -ms-text-size-adjust: 100%;\n}\na:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\na:hover,\na:active {\n  outline: 0;\n}\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\nsup {\n  top: -0.5em;\n}\nsub {\n  bottom: -0.25em;\n}\nimg {\n  /* Responsive images (ensure images don't scale beyond their parents) */\n\n  max-width: 100%;\n  /* Part 1: Set a maxium relative to the parent */\n\n  width: auto\\9;\n  /* IE7-8 need help adjusting responsive images */\n\n  height: auto;\n  /* Part 2: Scale the height according to the width, otherwise you get stretching */\n\n  vertical-align: middle;\n  border: 0;\n  -ms-interpolation-mode: bicubic;\n}\n#map_canvas img,\n.google-maps img {\n  max-width: none;\n}\nbutton,\ninput,\nselect,\ntextarea {\n  margin: 0;\n  font-size: 100%;\n  vertical-align: middle;\n}\nbutton,\ninput {\n  *overflow: visible;\n  line-height: normal;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n}\nlabel,\nselect,\nbutton,\ninput[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"],\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  cursor: pointer;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\ninput[type=\"search\"]::-webkit-search-decoration,\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\ntextarea {\n  overflow: auto;\n  vertical-align: top;\n}\n@media print {\n  * {\n    text-shadow: none !important;\n    color: #000 !important;\n    background: transparent !important;\n    box-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  .ir a:after,\n  a[href^=\"javascript:\"]:after,\n  a[href^=\"#\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  @page  {\n    margin: 0.5cm;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n}\nbody {\n  margin: 0;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 20px;\n  color: #333333;\n  background-color: #ffffff;\n}\na {\n  color: #0088cc;\n  text-decoration: none;\n}\na:hover,\na:focus {\n  color: #005580;\n  text-decoration: underline;\n}\n.img-rounded {\n  -webkit-border-radius: 6px;\n  -moz-border-radius: 6px;\n  border-radius: 6px;\n}\n.img-polaroid {\n  padding: 4px;\n  background-color: #fff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n  -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.img-circle {\n  -webkit-border-radius: 500px;\n  -moz-border-radius: 500px;\n  border-radius: 500px;\n}\n.row {\n  margin-left: -20px;\n  *zoom: 1;\n}\n.row:before,\n.row:after {\n  display: table;\n  content: \"\";\n  line-height: 0;\n}\n.row:after {\n  clear: both;\n}\n[class*=\"span\"] {\n  float: left;\n  min-height: 1px;\n  margin-left: 20px;\n}\n.container,\n.navbar-static-top .container,\n.navbar-fixed-top .container,\n.navbar-fixed-bottom .container {\n  width: 940px;\n}\n.span12 {\n  width: 940px;\n}\n.span11 {\n  width: 860px;\n}\n.span10 {\n  width: 780px;\n}\n.span9 {\n  width: 700px;\n}\n.span8 {\n  width: 620px;\n}\n.span7 {\n  width: 540px;\n}\n.span6 {\n  width: 460px;\n}\n.span5 {\n  width: 380px;\n}\n.span4 {\n  width: 300px;\n}\n.span3 {\n  width: 220px;\n}\n.span2 {\n  width: 140px;\n}\n.span1 {\n  width: 60px;\n}\n.offset12 {\n  margin-left: 980px;\n}\n.offset11 {\n  margin-left: 900px;\n}\n.offset10 {\n  margin-left: 820px;\n}\n.offset9 {\n  margin-left: 740px;\n}\n.offset8 {\n  margin-left: 660px;\n}\n.offset7 {\n  margin-left: 580px;\n}\n.offset6 {\n  margin-left: 500px;\n}\n.offset5 {\n  margin-left: 420px;\n}\n.offset4 {\n  margin-left: 340px;\n}\n.offset3 {\n  margin-left: 260px;\n}\n.offset2 {\n  margin-left: 180px;\n}\n.offset1 {\n  margin-left: 100px;\n}\n.row-fluid {\n  width: 100%;\n  *zoom: 1;\n}\n.row-fluid:before,\n.row-fluid:after {\n  display: table;\n  content: \"\";\n  line-height: 0;\n}\n.row-fluid:after {\n  clear: both;\n}\n.row-fluid [class*=\"span\"] {\n  display: block;\n  width: 100%;\n  min-height: 30px;\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  float: left;\n  margin-left: 2.127659574468085%;\n  *margin-left: 2.074468085106383%;\n}\n.row-fluid [class*=\"span\"]:first-child {\n  margin-left: 0;\n}\n.row-fluid .controls-row [class*=\"span\"] + [class*=\"span\"] {\n  margin-left: 2.127659574468085%;\n}\n.row-fluid .span12 {\n  width: 100%;\n  *width: 99.94680851063829%;\n}\n.row-fluid .span11 {\n  width: 91.48936170212765%;\n  *width: 91.43617021276594%;\n}\n.row-fluid .span10 {\n  width: 82.97872340425532%;\n  *width: 82.92553191489361%;\n}\n.row-fluid .span9 {\n  width: 74.46808510638297%;\n  *width: 74.41489361702126%;\n}\n.row-fluid .span8 {\n  width: 65.95744680851064%;\n  *width: 65.90425531914893%;\n}\n.row-fluid .span7 {\n  width: 57.44680851063829%;\n  *width: 57.39361702127659%;\n}\n.row-fluid .span6 {\n  width: 48.93617021276595%;\n  *width: 48.88297872340425%;\n}\n.row-fluid .span5 {\n  width: 40.42553191489362%;\n  *width: 40.37234042553192%;\n}\n.row-fluid .span4 {\n  width: 31.914893617021278%;\n  *width: 31.861702127659576%;\n}\n.row-fluid .span3 {\n  width: 23.404255319148934%;\n  *width: 23.351063829787233%;\n}\n.row-fluid .span2 {\n  width: 14.893617021276595%;\n  *width: 14.840425531914894%;\n}\n.row-fluid .span1 {\n  width: 6.382978723404255%;\n  *width: 6.329787234042553%;\n}\n.row-fluid .offset12 {\n  margin-left: 104.25531914893617%;\n  *margin-left: 104.14893617021275%;\n}\n.row-fluid .offset12:first-child {\n  margin-left: 102.12765957446808%;\n  *margin-left: 102.02127659574467%;\n}\n.row-fluid .offset11 {\n  margin-left: 95.74468085106382%;\n  *margin-left: 95.6382978723404%;\n}\n.row-fluid .offset11:first-child {\n  margin-left: 93.61702127659574%;\n  *margin-left: 93.51063829787232%;\n}\n.row-fluid .offset10 {\n  margin-left: 87.23404255319149%;\n  *margin-left: 87.12765957446807%;\n}\n.row-fluid .offset10:first-child {\n  margin-left: 85.1063829787234%;\n  *margin-left: 84.99999999999999%;\n}\n.row-fluid .offset9 {\n  margin-left: 78.72340425531914%;\n  *margin-left: 78.61702127659572%;\n}\n.row-fluid .offset9:first-child {\n  margin-left: 76.59574468085106%;\n  *margin-left: 76.48936170212764%;\n}\n.row-fluid .offset8 {\n  margin-left: 70.2127659574468%;\n  *margin-left: 70.10638297872339%;\n}\n.row-fluid .offset8:first-child {\n  margin-left: 68.08510638297872%;\n  *margin-left: 67.9787234042553%;\n}\n.row-fluid .offset7 {\n  margin-left: 61.70212765957446%;\n  *margin-left: 61.59574468085106%;\n}\n.row-fluid .offset7:first-child {\n  margin-left: 59.574468085106375%;\n  *margin-left: 59.46808510638297%;\n}\n.row-fluid .offset6 {\n  margin-left: 53.191489361702125%;\n  *margin-left: 53.085106382978715%;\n}\n.row-fluid .offset6:first-child {\n  margin-left: 51.063829787234035%;\n  *margin-left: 50.95744680851063%;\n}\n.row-fluid .offset5 {\n  margin-left: 44.68085106382979%;\n  *margin-left: 44.57446808510638%;\n}\n.row-fluid .offset5:first-child {\n  margin-left: 42.5531914893617%;\n  *margin-left: 42.4468085106383%;\n}\n.row-fluid .offset4 {\n  margin-left: 36.170212765957444%;\n  *margin-left: 36.06382978723405%;\n}\n.row-fluid .offset4:first-child {\n  margin-left: 34.04255319148936%;\n  *margin-left: 33.93617021276596%;\n}\n.row-fluid .offset3 {\n  margin-left: 27.659574468085104%;\n  *margin-left: 27.5531914893617%;\n}\n.row-fluid .offset3:first-child {\n  margin-left: 25.53191489361702%;\n  *margin-left: 25.425531914893618%;\n}\n.row-fluid .offset2 {\n  margin-left: 19.148936170212764%;\n  *margin-left: 19.04255319148936%;\n}\n.row-fluid .offset2:first-child {\n  margin-left: 17.02127659574468%;\n  *margin-left: 16.914893617021278%;\n}\n.row-fluid .offset1 {\n  margin-left: 10.638297872340425%;\n  *margin-left: 10.53191489361702%;\n}\n.row-fluid .offset1:first-child {\n  margin-left: 8.51063829787234%;\n  *margin-left: 8.404255319148938%;\n}\n[class*=\"span\"].hide,\n.row-fluid [class*=\"span\"].hide {\n  display: none;\n}\n[class*=\"span\"].pull-right,\n.row-fluid [class*=\"span\"].pull-right {\n  float: right;\n}\n.container {\n  margin-right: auto;\n  margin-left: auto;\n  *zoom: 1;\n}\n.container:before,\n.container:after {\n  display: table;\n  content: \"\";\n  line-height: 0;\n}\n.container:after {\n  clear: both;\n}\n.container-fluid {\n  padding-right: 20px;\n  padding-left: 20px;\n  *zoom: 1;\n}\n.container-fluid:before,\n.container-fluid:after {\n  display: table;\n  content: \"\";\n  line-height: 0;\n}\n.container-fluid:after {\n  clear: both;\n}\np {\n  margin: 0 0 10px;\n}\n.lead {\n  margin-bottom: 20px;\n  font-size: 21px;\n  font-weight: 200;\n  line-height: 30px;\n}\nsmall {\n  font-size: 85%;\n}\nstrong {\n  font-weight: bold;\n}\nem {\n  font-style: italic;\n}\ncite {\n  font-style: normal;\n}\n.muted {\n  color: #999999;\n}\na.muted:hover,\na.muted:focus {\n  color: #808080;\n}\n.text-warning {\n  color: #c09853;\n}\na.text-warning:hover,\na.text-warning:focus {\n  color: #a47e3c;\n}\n.text-error {\n  color: #b94a48;\n}\na.text-error:hover,\na.text-error:focus {\n  color: #953b39;\n}\n.text-info {\n  color: #3a87ad;\n}\na.text-info:hover,\na.text-info:focus {\n  color: #2d6987;\n}\n.text-success {\n  color: #468847;\n}\na.text-success:hover,\na.text-success:focus {\n  color: #356635;\n}\n.text-left {\n  text-align: left;\n}\n.text-right {\n  text-align: right;\n}\n.text-center {\n  text-align: center;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n  margin: 10px 0;\n  font-family: inherit;\n  font-weight: bold;\n  line-height: 20px;\n  color: inherit;\n  text-rendering: optimizelegibility;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small {\n  font-weight: normal;\n  line-height: 1;\n  color: #999999;\n}\nh1,\nh2,\nh3 {\n  line-height: 40px;\n}\nh1 {\n  font-size: 38.5px;\n}\nh2 {\n  font-size: 31.5px;\n}\nh3 {\n  font-size: 24.5px;\n}\nh4 {\n  font-size: 17.5px;\n}\nh5 {\n  font-size: 14px;\n}\nh6 {\n  font-size: 11.9px;\n}\nh1 small {\n  font-size: 24.5px;\n}\nh2 small {\n  font-size: 17.5px;\n}\nh3 small {\n  font-size: 14px;\n}\nh4 small {\n  font-size: 14px;\n}\n.page-header {\n  padding-bottom: 9px;\n  margin: 20px 0 30px;\n  border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n  padding: 0;\n  margin: 0 0 10px 25px;\n}\nul ul,\nul ol,\nol ol,\nol ul {\n  margin-bottom: 0;\n}\nli {\n  line-height: 20px;\n}\nul.unstyled,\nol.unstyled {\n  margin-left: 0;\n  list-style: none;\n}\nul.inline,\nol.inline {\n  margin-left: 0;\n  list-style: none;\n}\nul.inline > li,\nol.inline > li {\n  display: inline-block;\n  *display: inline;\n  /* IE7 inline-block hack */\n\n  *zoom: 1;\n  padding-left: 5px;\n  padding-right: 5px;\n}\ndl {\n  margin-bottom: 20px;\n}\ndt,\ndd {\n  line-height: 20px;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 10px;\n}\n.dl-horizontal {\n  *zoom: 1;\n}\n.dl-horizontal:before,\n.dl-horizontal:after {\n  display: table;\n  content: \"\";\n  line-height: 0;\n}\n.dl-horizontal:after {\n  clear: both;\n}\n.dl-horizontal dt {\n  float: left;\n  width: 160px;\n  clear: left;\n  text-align: right;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n.dl-horizontal dd {\n  margin-left: 180px;\n}\nhr {\n  margin: 20px 0;\n  border: 0;\n  border-top: 1px solid #eeeeee;\n  border-bottom: 1px solid #ffffff;\n}\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #999999;\n}\nabbr.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\nblockquote {\n  padding: 0 0 0 15px;\n  margin: 0 0 20px;\n  border-left: 5px solid #eeeeee;\n}\nblockquote p {\n  margin-bottom: 0;\n  font-size: 17.5px;\n  font-weight: 300;\n  line-height: 1.25;\n}\nblockquote small {\n  display: block;\n  line-height: 20px;\n  color: #999999;\n}\nblockquote small:before {\n  content: '\\2014 \\00A0';\n}\nblockquote.pull-right {\n  float: right;\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid #eeeeee;\n  border-left: 0;\n}\nblockquote.pull-right p,\nblockquote.pull-right small {\n  text-align: right;\n}\nblockquote.pull-right small:before {\n  content: '';\n}\nblockquote.pull-right small:after {\n  content: '\\00A0 \\2014';\n}\nq:before,\nq:after,\nblockquote:before,\nblockquote:after {\n  content: \"\";\n}\naddress {\n  display: block;\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 20px;\n}\ncode,\npre {\n  padding: 0 3px 2px;\n  font-family: Monaco, Menlo, Consolas, \"Courier New\", monospace;\n  font-size: 12px;\n  color: #333333;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\ncode {\n  padding: 2px 4px;\n  color: #d14;\n  background-color: #f7f7f9;\n  border: 1px solid #e1e1e8;\n  white-space: nowrap;\n}\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 20px;\n  word-break: break-all;\n  word-wrap: break-word;\n  white-space: pre;\n  white-space: pre-wrap;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\npre.prettyprint {\n  margin-bottom: 20px;\n}\npre code {\n  padding: 0;\n  color: inherit;\n  white-space: pre;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border: 0;\n}\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\ntable {\n  max-width: 100%;\n  background-color: transparent;\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n.table {\n  width: 100%;\n  margin-bottom: 20px;\n}\n.table th,\n.table td {\n  padding: 8px;\n  line-height: 20px;\n  text-align: left;\n  vertical-align: top;\n  border-top: 1px solid #dddddd;\n}\n.table th {\n  font-weight: bold;\n}\n.table thead th {\n  vertical-align: bottom;\n}\n.table caption + thead tr:first-child th,\n.table caption + thead tr:first-child td,\n.table colgroup + thead tr:first-child th,\n.table colgroup + thead tr:first-child td,\n.table thead:first-child tr:first-child th,\n.table thead:first-child tr:first-child td {\n  border-top: 0;\n}\n.table tbody + tbody {\n  border-top: 2px solid #dddddd;\n}\n.table .table {\n  background-color: #ffffff;\n}\n.table-condensed th,\n.table-condensed td {\n  padding: 4px 5px;\n}\n.table-bordered {\n  border: 1px solid #dddddd;\n  border-collapse: separate;\n  *border-collapse: collapse;\n  border-left: 0;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n.table-bordered th,\n.table-bordered td {\n  border-left: 1px solid #dddddd;\n}\n.table-bordered caption + thead tr:first-child th,\n.table-bordered caption + tbody tr:first-child th,\n.table-bordered caption + tbody tr:first-child td,\n.table-bordered colgroup + thead tr:first-child th,\n.table-bordered colgroup + tbody tr:first-child th,\n.table-bordered colgroup + tbody tr:first-child td,\n.table-bordered thead:first-child tr:first-child th,\n.table-bordered tbody:first-child tr:first-child th,\n.table-bordered tbody:first-child tr:first-child td {\n  border-top: 0;\n}\n.table-bordered thead:first-child tr:first-child > th:first-child,\n.table-bordered tbody:first-child tr:first-child > td:first-child,\n.table-bordered tbody:first-child tr:first-child > th:first-child {\n  -webkit-border-top-left-radius: 4px;\n  -moz-border-radius-topleft: 4px;\n  border-top-left-radius: 4px;\n}\n.table-bordered thead:first-child tr:first-child > th:last-child,\n.table-bordered tbody:first-child tr:first-child > td:last-child,\n.table-bordered tbody:first-child tr:first-child > th:last-child {\n  -webkit-border-top-right-radius: 4px;\n  -moz-border-radius-topright: 4px;\n  border-top-right-radius: 4px;\n}\n.table-bordered thead:last-child tr:last-child > th:first-child,\n.table-bordered tbody:last-child tr:last-child > td:first-child,\n.table-bordered tbody:last-child tr:last-child > th:first-child,\n.table-bordered tfoot:last-child tr:last-child > td:first-child,\n.table-bordered tfoot:last-child tr:last-child > th:first-child {\n  -webkit-border-bottom-left-radius: 4px;\n  -moz-border-radius-bottomleft: 4px;\n  border-bottom-left-radius: 4px;\n}\n.table-bordered thead:last-child tr:last-child > th:last-child,\n.table-bordered tbody:last-child tr:last-child > td:last-child,\n.table-bordered tbody:last-child tr:last-child > th:last-child,\n.table-bordered tfoot:last-child tr:last-child > td:last-child,\n.table-bordered tfoot:last-child tr:last-child > th:last-child {\n  -webkit-border-bottom-right-radius: 4px;\n  -moz-border-radius-bottomright: 4px;\n  border-bottom-right-radius: 4px;\n}\n.table-bordered tfoot + tbody:last-child tr:last-child td:first-child {\n  -webkit-border-bottom-left-radius: 0;\n  -moz-border-radius-bottomleft: 0;\n  border-bottom-left-radius: 0;\n}\n.table-bordered tfoot + tbody:last-child tr:last-child td:last-child {\n  -webkit-border-bottom-right-radius: 0;\n  -moz-border-radius-bottomright: 0;\n  border-bottom-right-radius: 0;\n}\n.table-bordered caption + thead tr:first-child th:first-child,\n.table-bordered caption + tbody tr:first-child td:first-child,\n.table-bordered colgroup + thead tr:first-child th:first-child,\n.table-bordered colgroup + tbody tr:first-child td:first-child {\n  -webkit-border-top-left-radius: 4px;\n  -moz-border-radius-topleft: 4px;\n  border-top-left-radius: 4px;\n}\n.table-bordered caption + thead tr:first-child th:last-child,\n.table-bordered caption + tbody tr:first-child td:last-child,\n.table-bordered colgroup + thead tr:first-child th:last-child,\n.table-bordered colgroup + tbody tr:first-child td:last-child {\n  -webkit-border-top-right-radius: 4px;\n  -moz-border-radius-topright: 4px;\n  border-top-right-radius: 4px;\n}\n.table-striped tbody > tr:nth-child(odd) > td,\n.table-striped tbody > tr:nth-child(odd) > th {\n  background-color: #f9f9f9;\n}\n.table-hover tbody tr:hover > td,\n.table-hover tbody tr:hover > th {\n  background-color: #f5f5f5;\n}\ntable td[class*=\"span\"],\ntable th[class*=\"span\"],\n.row-fluid table td[class*=\"span\"],\n.row-fluid table th[class*=\"span\"] {\n  display: table-cell;\n  float: none;\n  margin-left: 0;\n}\n.table td.span1,\n.table th.span1 {\n  float: none;\n  width: 44px;\n  margin-left: 0;\n}\n.table td.span2,\n.table th.span2 {\n  float: none;\n  width: 124px;\n  margin-left: 0;\n}\n.table td.span3,\n.table th.span3 {\n  float: none;\n  width: 204px;\n  margin-left: 0;\n}\n.table td.span4,\n.table th.span4 {\n  float: none;\n  width: 284px;\n  margin-left: 0;\n}\n.table td.span5,\n.table th.span5 {\n  float: none;\n  width: 364px;\n  margin-left: 0;\n}\n.table td.span6,\n.table th.span6 {\n  float: none;\n  width: 444px;\n  margin-left: 0;\n}\n.table td.span7,\n.table th.span7 {\n  float: none;\n  width: 524px;\n  margin-left: 0;\n}\n.table td.span8,\n.table th.span8 {\n  float: none;\n  width: 604px;\n  margin-left: 0;\n}\n.table td.span9,\n.table th.span9 {\n  float: none;\n  width: 684px;\n  margin-left: 0;\n}\n.table td.span10,\n.table th.span10 {\n  float: none;\n  width: 764px;\n  margin-left: 0;\n}\n.table td.span11,\n.table th.span11 {\n  float: none;\n  width: 844px;\n  margin-left: 0;\n}\n.table td.span12,\n.table th.span12 {\n  float: none;\n  width: 924px;\n  margin-left: 0;\n}\n.table tbody tr.success > td {\n  background-color: #dff0d8;\n}\n.table tbody tr.error > td {\n  background-color: #f2dede;\n}\n.table tbody tr.warning > td {\n  background-color: #fcf8e3;\n}\n.table tbody tr.info > td {\n  background-color: #d9edf7;\n}\n.table-hover tbody tr.success:hover > td {\n  background-color: #d0e9c6;\n}\n.table-hover tbody tr.error:hover > td {\n  background-color: #ebcccc;\n}\n.table-hover tbody tr.warning:hover > td {\n  background-color: #faf2cc;\n}\n.table-hover tbody tr.info:hover > td {\n  background-color: #c4e3f3;\n}\n.nav {\n  margin-left: 0;\n  margin-bottom: 20px;\n  list-style: none;\n}\n.nav > li > a {\n  display: block;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n.nav > li > a > img {\n  max-width: none;\n}\n.nav > .pull-right {\n  float: right;\n}\n.nav-header {\n  display: block;\n  padding: 3px 15px;\n  font-size: 11px;\n  font-weight: bold;\n  line-height: 20px;\n  color: #999999;\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);\n  text-transform: uppercase;\n}\n.nav li + .nav-header {\n  margin-top: 9px;\n}\n.nav-list {\n  padding-left: 15px;\n  padding-right: 15px;\n  margin-bottom: 0;\n}\n.nav-list > li > a,\n.nav-list .nav-header {\n  margin-left: -15px;\n  margin-right: -15px;\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);\n}\n.nav-list > li > a {\n  padding: 3px 15px;\n}\n.nav-list > .active > a,\n.nav-list > .active > a:hover,\n.nav-list > .active > a:focus {\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n  background-color: #0088cc;\n}\n.nav-list [class^=\"icon-\"],\n.nav-list [class*=\" icon-\"] {\n  margin-right: 2px;\n}\n.nav-list .divider {\n  *width: 100%;\n  height: 1px;\n  margin: 9px 1px;\n  *margin: -5px 0 5px;\n  overflow: hidden;\n  background-color: #e5e5e5;\n  border-bottom: 1px solid #ffffff;\n}\n.nav-tabs,\n.nav-pills {\n  *zoom: 1;\n}\n.nav-tabs:before,\n.nav-pills:before,\n.nav-tabs:after,\n.nav-pills:after {\n  display: table;\n  content: \"\";\n  line-height: 0;\n}\n.nav-tabs:after,\n.nav-pills:after {\n  clear: both;\n}\n.nav-tabs > li,\n.nav-pills > li {\n  float: left;\n}\n.nav-tabs > li > a,\n.nav-pills > li > a {\n  padding-right: 12px;\n  padding-left: 12px;\n  margin-right: 2px;\n  line-height: 14px;\n}\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n  margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  line-height: 20px;\n  border: 1px solid transparent;\n  -webkit-border-radius: 4px 4px 0 0;\n  -moz-border-radius: 4px 4px 0 0;\n  border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover,\n.nav-tabs > li > a:focus {\n  border-color: #eeeeee #eeeeee #dddddd;\n}\n.nav-tabs > .active > a,\n.nav-tabs > .active > a:hover,\n.nav-tabs > .active > a:focus {\n  color: #555555;\n  background-color: #ffffff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n  cursor: default;\n}\n.nav-pills > li > a {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  margin-top: 2px;\n  margin-bottom: 2px;\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  border-radius: 5px;\n}\n.nav-pills > .active > a,\n.nav-pills > .active > a:hover,\n.nav-pills > .active > a:focus {\n  color: #ffffff;\n  background-color: #0088cc;\n}\n.nav-stacked > li {\n  float: none;\n}\n.nav-stacked > li > a {\n  margin-right: 0;\n}\n.nav-tabs.nav-stacked {\n  border-bottom: 0;\n}\n.nav-tabs.nav-stacked > li > a {\n  border: 1px solid #ddd;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n}\n.nav-tabs.nav-stacked > li:first-child > a {\n  -webkit-border-top-right-radius: 4px;\n  -moz-border-radius-topright: 4px;\n  border-top-right-radius: 4px;\n  -webkit-border-top-left-radius: 4px;\n  -moz-border-radius-topleft: 4px;\n  border-top-left-radius: 4px;\n}\n.nav-tabs.nav-stacked > li:last-child > a {\n  -webkit-border-bottom-right-radius: 4px;\n  -moz-border-radius-bottomright: 4px;\n  border-bottom-right-radius: 4px;\n  -webkit-border-bottom-left-radius: 4px;\n  -moz-border-radius-bottomleft: 4px;\n  border-bottom-left-radius: 4px;\n}\n.nav-tabs.nav-stacked > li > a:hover,\n.nav-tabs.nav-stacked > li > a:focus {\n  border-color: #ddd;\n  z-index: 2;\n}\n.nav-pills.nav-stacked > li > a {\n  margin-bottom: 3px;\n}\n.nav-pills.nav-stacked > li:last-child > a {\n  margin-bottom: 1px;\n}\n.nav-tabs .dropdown-menu {\n  -webkit-border-radius: 0 0 6px 6px;\n  -moz-border-radius: 0 0 6px 6px;\n  border-radius: 0 0 6px 6px;\n}\n.nav-pills .dropdown-menu {\n  -webkit-border-radius: 6px;\n  -moz-border-radius: 6px;\n  border-radius: 6px;\n}\n.nav .dropdown-toggle .caret {\n  border-top-color: #0088cc;\n  border-bottom-color: #0088cc;\n  margin-top: 6px;\n}\n.nav .dropdown-toggle:hover .caret,\n.nav .dropdown-toggle:focus .caret {\n  border-top-color: #005580;\n  border-bottom-color: #005580;\n}\n/* move down carets for tabs */\n.nav-tabs .dropdown-toggle .caret {\n  margin-top: 8px;\n}\n.nav .active .dropdown-toggle .caret {\n  border-top-color: #fff;\n  border-bottom-color: #fff;\n}\n.nav-tabs .active .dropdown-toggle .caret {\n  border-top-color: #555555;\n  border-bottom-color: #555555;\n}\n.nav > .dropdown.active > a:hover,\n.nav > .dropdown.active > a:focus {\n  cursor: pointer;\n}\n.nav-tabs .open .dropdown-toggle,\n.nav-pills .open .dropdown-toggle,\n.nav > li.dropdown.open.active > a:hover,\n.nav > li.dropdown.open.active > a:focus {\n  color: #ffffff;\n  background-color: #999999;\n  border-color: #999999;\n}\n.nav li.dropdown.open .caret,\n.nav li.dropdown.open.active .caret,\n.nav li.dropdown.open a:hover .caret,\n.nav li.dropdown.open a:focus .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n  opacity: 1;\n  filter: alpha(opacity=100);\n}\n.tabs-stacked .open > a:hover,\n.tabs-stacked .open > a:focus {\n  border-color: #999999;\n}\n.tabbable {\n  *zoom: 1;\n}\n.tabbable:before,\n.tabbable:after {\n  display: table;\n  content: \"\";\n  line-height: 0;\n}\n.tabbable:after {\n  clear: both;\n}\n.tab-content {\n  overflow: auto;\n}\n.tabs-below > .nav-tabs,\n.tabs-right > .nav-tabs,\n.tabs-left > .nav-tabs {\n  border-bottom: 0;\n}\n.tab-content > .tab-pane,\n.pill-content > .pill-pane {\n  display: none;\n}\n.tab-content > .active,\n.pill-content > .active {\n  display: block;\n}\n.tabs-below > .nav-tabs {\n  border-top: 1px solid #ddd;\n}\n.tabs-below > .nav-tabs > li {\n  margin-top: -1px;\n  margin-bottom: 0;\n}\n.tabs-below > .nav-tabs > li > a {\n  -webkit-border-radius: 0 0 4px 4px;\n  -moz-border-radius: 0 0 4px 4px;\n  border-radius: 0 0 4px 4px;\n}\n.tabs-below > .nav-tabs > li > a:hover,\n.tabs-below > .nav-tabs > li > a:focus {\n  border-bottom-color: transparent;\n  border-top-color: #ddd;\n}\n.tabs-below > .nav-tabs > .active > a,\n.tabs-below > .nav-tabs > .active > a:hover,\n.tabs-below > .nav-tabs > .active > a:focus {\n  border-color: transparent #ddd #ddd #ddd;\n}\n.tabs-left > .nav-tabs > li,\n.tabs-right > .nav-tabs > li {\n  float: none;\n}\n.tabs-left > .nav-tabs > li > a,\n.tabs-right > .nav-tabs > li > a {\n  min-width: 74px;\n  margin-right: 0;\n  margin-bottom: 3px;\n}\n.tabs-left > .nav-tabs {\n  float: left;\n  margin-right: 19px;\n  border-right: 1px solid #ddd;\n}\n.tabs-left > .nav-tabs > li > a {\n  margin-right: -1px;\n  -webkit-border-radius: 4px 0 0 4px;\n  -moz-border-radius: 4px 0 0 4px;\n  border-radius: 4px 0 0 4px;\n}\n.tabs-left > .nav-tabs > li > a:hover,\n.tabs-left > .nav-tabs > li > a:focus {\n  border-color: #eeeeee #dddddd #eeeeee #eeeeee;\n}\n.tabs-left > .nav-tabs .active > a,\n.tabs-left > .nav-tabs .active > a:hover,\n.tabs-left > .nav-tabs .active > a:focus {\n  border-color: #ddd transparent #ddd #ddd;\n  *border-right-color: #ffffff;\n}\n.tabs-right > .nav-tabs {\n  float: right;\n  margin-left: 19px;\n  border-left: 1px solid #ddd;\n}\n.tabs-right > .nav-tabs > li > a {\n  margin-left: -1px;\n  -webkit-border-radius: 0 4px 4px 0;\n  -moz-border-radius: 0 4px 4px 0;\n  border-radius: 0 4px 4px 0;\n}\n.tabs-right > .nav-tabs > li > a:hover,\n.tabs-right > .nav-tabs > li > a:focus {\n  border-color: #eeeeee #eeeeee #eeeeee #dddddd;\n}\n.tabs-right > .nav-tabs .active > a,\n.tabs-right > .nav-tabs .active > a:hover,\n.tabs-right > .nav-tabs .active > a:focus {\n  border-color: #ddd #ddd #ddd transparent;\n  *border-left-color: #ffffff;\n}\n.nav > .disabled > a {\n  color: #999999;\n}\n.nav > .disabled > a:hover,\n.nav > .disabled > a:focus {\n  text-decoration: none;\n  background-color: transparent;\n  cursor: default;\n}\n.navbar {\n  overflow: visible;\n  margin-bottom: 20px;\n  *position: relative;\n  *z-index: 2;\n}\n.navbar-inner {\n  min-height: 40px;\n  padding-left: 20px;\n  padding-right: 20px;\n  background-color: #fafafa;\n  background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));\n  background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2);\n  background-image: -o-linear-gradient(top, #ffffff, #f2f2f2);\n  background-image: linear-gradient(to bottom, #ffffff, #f2f2f2);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);\n  border: 1px solid #d4d4d4;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);\n  -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);\n  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);\n  *zoom: 1;\n}\n.navbar-inner:before,\n.navbar-inner:after {\n  display: table;\n  content: \"\";\n  line-height: 0;\n}\n.navbar-inner:after {\n  clear: both;\n}\n.navbar .container {\n  width: auto;\n}\n.nav-collapse.collapse {\n  height: auto;\n  overflow: visible;\n}\n.navbar .brand {\n  float: left;\n  display: block;\n  padding: 10px 20px 10px;\n  margin-left: -20px;\n  font-size: 20px;\n  font-weight: 200;\n  color: #777777;\n  text-shadow: 0 1px 0 #ffffff;\n}\n.navbar .brand:hover,\n.navbar .brand:focus {\n  text-decoration: none;\n}\n.navbar-text {\n  margin-bottom: 0;\n  line-height: 40px;\n  color: #777777;\n}\n.navbar-link {\n  color: #777777;\n}\n.navbar-link:hover,\n.navbar-link:focus {\n  color: #333333;\n}\n.navbar .divider-vertical {\n  height: 40px;\n  margin: 0 9px;\n  border-left: 1px solid #f2f2f2;\n  border-right: 1px solid #ffffff;\n}\n.navbar .btn,\n.navbar .btn-group {\n  margin-top: 5px;\n}\n.navbar .btn-group .btn,\n.navbar .input-prepend .btn,\n.navbar .input-append .btn,\n.navbar .input-prepend .btn-group,\n.navbar .input-append .btn-group {\n  margin-top: 0;\n}\n.navbar-form {\n  margin-bottom: 0;\n  *zoom: 1;\n}\n.navbar-form:before,\n.navbar-form:after {\n  display: table;\n  content: \"\";\n  line-height: 0;\n}\n.navbar-form:after {\n  clear: both;\n}\n.navbar-form input,\n.navbar-form select,\n.navbar-form .radio,\n.navbar-form .checkbox {\n  margin-top: 5px;\n}\n.navbar-form input,\n.navbar-form select,\n.navbar-form .btn {\n  display: inline-block;\n  margin-bottom: 0;\n}\n.navbar-form input[type=\"image\"],\n.navbar-form input[type=\"checkbox\"],\n.navbar-form input[type=\"radio\"] {\n  margin-top: 3px;\n}\n.navbar-form .input-append,\n.navbar-form .input-prepend {\n  margin-top: 5px;\n  white-space: nowrap;\n}\n.navbar-form .input-append input,\n.navbar-form .input-prepend input {\n  margin-top: 0;\n}\n.navbar-search {\n  position: relative;\n  float: left;\n  margin-top: 5px;\n  margin-bottom: 0;\n}\n.navbar-search .search-query {\n  margin-bottom: 0;\n  padding: 4px 14px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 13px;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-border-radius: 15px;\n  -moz-border-radius: 15px;\n  border-radius: 15px;\n}\n.navbar-static-top {\n  position: static;\n  margin-bottom: 0;\n}\n.navbar-static-top .navbar-inner {\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n  margin-bottom: 0;\n}\n.navbar-fixed-top .navbar-inner,\n.navbar-static-top .navbar-inner {\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom .navbar-inner {\n  border-width: 1px 0 0;\n}\n.navbar-fixed-top .navbar-inner,\n.navbar-fixed-bottom .navbar-inner {\n  padding-left: 0;\n  padding-right: 0;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n}\n.navbar-static-top .container,\n.navbar-fixed-top .container,\n.navbar-fixed-bottom .container {\n  width: 940px;\n}\n.navbar-fixed-top {\n  top: 0;\n}\n.navbar-fixed-top .navbar-inner,\n.navbar-static-top .navbar-inner {\n  -webkit-box-shadow: 0 1px 10px rgba(0,0,0,.1);\n  -moz-box-shadow: 0 1px 10px rgba(0,0,0,.1);\n  box-shadow: 0 1px 10px rgba(0,0,0,.1);\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n}\n.navbar-fixed-bottom .navbar-inner {\n  -webkit-box-shadow: 0 -1px 10px rgba(0,0,0,.1);\n  -moz-box-shadow: 0 -1px 10px rgba(0,0,0,.1);\n  box-shadow: 0 -1px 10px rgba(0,0,0,.1);\n}\n.navbar .nav {\n  position: relative;\n  left: 0;\n  display: block;\n  float: left;\n  margin: 0 10px 0 0;\n}\n.navbar .nav.pull-right {\n  float: right;\n  margin-right: 0;\n}\n.navbar .nav > li {\n  float: left;\n}\n.navbar .nav > li > a {\n  float: none;\n  padding: 10px 15px 10px;\n  color: #777777;\n  text-decoration: none;\n  text-shadow: 0 1px 0 #ffffff;\n}\n.navbar .nav .dropdown-toggle .caret {\n  margin-top: 8px;\n}\n.navbar .nav > li > a:focus,\n.navbar .nav > li > a:hover {\n  background-color: transparent;\n  color: #333333;\n  text-decoration: none;\n}\n.navbar .nav > .active > a,\n.navbar .nav > .active > a:hover,\n.navbar .nav > .active > a:focus {\n  color: #555555;\n  text-decoration: none;\n  background-color: #e5e5e5;\n  -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);\n  -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);\n  box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);\n}\n.navbar .btn-navbar {\n  display: none;\n  float: right;\n  padding: 7px 10px;\n  margin-left: 5px;\n  margin-right: 5px;\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #ededed;\n  background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));\n  background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5);\n  background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5);\n  background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);\n  border-color: #e5e5e5 #e5e5e5 #bfbfbf;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  *background-color: #e5e5e5;\n  /* Darken IE7 buttons by default so they stand out more given they won't have borders */\n\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);\n  -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);\n  box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);\n}\n.navbar .btn-navbar:hover,\n.navbar .btn-navbar:focus,\n.navbar .btn-navbar:active,\n.navbar .btn-navbar.active,\n.navbar .btn-navbar.disabled,\n.navbar .btn-navbar[disabled] {\n  color: #ffffff;\n  background-color: #e5e5e5;\n  *background-color: #d9d9d9;\n}\n.navbar .btn-navbar:active,\n.navbar .btn-navbar.active {\n  background-color: #cccccc \\9;\n}\n.navbar .btn-navbar .icon-bar {\n  display: block;\n  width: 18px;\n  height: 2px;\n  background-color: #f5f5f5;\n  -webkit-border-radius: 1px;\n  -moz-border-radius: 1px;\n  border-radius: 1px;\n  -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);\n  -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);\n  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);\n}\n.btn-navbar .icon-bar + .icon-bar {\n  margin-top: 3px;\n}\n.navbar .nav > li > .dropdown-menu:before {\n  content: '';\n  display: inline-block;\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid #ccc;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  position: absolute;\n  top: -7px;\n  left: 9px;\n}\n.navbar .nav > li > .dropdown-menu:after {\n  content: '';\n  display: inline-block;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #ffffff;\n  position: absolute;\n  top: -6px;\n  left: 10px;\n}\n.navbar-fixed-bottom .nav > li > .dropdown-menu:before {\n  border-top: 7px solid #ccc;\n  border-top-color: rgba(0, 0, 0, 0.2);\n  border-bottom: 0;\n  bottom: -7px;\n  top: auto;\n}\n.navbar-fixed-bottom .nav > li > .dropdown-menu:after {\n  border-top: 6px solid #ffffff;\n  border-bottom: 0;\n  bottom: -6px;\n  top: auto;\n}\n.navbar .nav li.dropdown > a:hover .caret,\n.navbar .nav li.dropdown > a:focus .caret {\n  border-top-color: #333333;\n  border-bottom-color: #333333;\n}\n.navbar .nav li.dropdown.open > .dropdown-toggle,\n.navbar .nav li.dropdown.active > .dropdown-toggle,\n.navbar .nav li.dropdown.open.active > .dropdown-toggle {\n  background-color: #e5e5e5;\n  color: #555555;\n}\n.navbar .nav li.dropdown > .dropdown-toggle .caret {\n  border-top-color: #777777;\n  border-bottom-color: #777777;\n}\n.navbar .nav li.dropdown.open > .dropdown-toggle .caret,\n.navbar .nav li.dropdown.active > .dropdown-toggle .caret,\n.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret {\n  border-top-color: #555555;\n  border-bottom-color: #555555;\n}\n.navbar .pull-right > li > .dropdown-menu,\n.navbar .nav > li > .dropdown-menu.pull-right {\n  left: auto;\n  right: 0;\n}\n.navbar .pull-right > li > .dropdown-menu:before,\n.navbar .nav > li > .dropdown-menu.pull-right:before {\n  left: auto;\n  right: 12px;\n}\n.navbar .pull-right > li > .dropdown-menu:after,\n.navbar .nav > li > .dropdown-menu.pull-right:after {\n  left: auto;\n  right: 13px;\n}\n.navbar .pull-right > li > .dropdown-menu .dropdown-menu,\n.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu {\n  left: auto;\n  right: 100%;\n  margin-left: 0;\n  margin-right: -1px;\n  -webkit-border-radius: 6px 0 6px 6px;\n  -moz-border-radius: 6px 0 6px 6px;\n  border-radius: 6px 0 6px 6px;\n}\n.navbar-inverse .navbar-inner {\n  background-color: #1b1b1b;\n  background-image: -moz-linear-gradient(top, #222222, #111111);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));\n  background-image: -webkit-linear-gradient(top, #222222, #111111);\n  background-image: -o-linear-gradient(top, #222222, #111111);\n  background-image: linear-gradient(to bottom, #222222, #111111);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);\n  border-color: #252525;\n}\n.navbar-inverse .brand,\n.navbar-inverse .nav > li > a {\n  color: #999999;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .brand:hover,\n.navbar-inverse .nav > li > a:hover,\n.navbar-inverse .brand:focus,\n.navbar-inverse .nav > li > a:focus {\n  color: #ffffff;\n}\n.navbar-inverse .brand {\n  color: #999999;\n}\n.navbar-inverse .navbar-text {\n  color: #999999;\n}\n.navbar-inverse .nav > li > a:focus,\n.navbar-inverse .nav > li > a:hover {\n  background-color: transparent;\n  color: #ffffff;\n}\n.navbar-inverse .nav .active > a,\n.navbar-inverse .nav .active > a:hover,\n.navbar-inverse .nav .active > a:focus {\n  color: #ffffff;\n  background-color: #111111;\n}\n.navbar-inverse .navbar-link {\n  color: #999999;\n}\n.navbar-inverse .navbar-link:hover,\n.navbar-inverse .navbar-link:focus {\n  color: #ffffff;\n}\n.navbar-inverse .divider-vertical {\n  border-left-color: #111111;\n  border-right-color: #222222;\n}\n.navbar-inverse .nav li.dropdown.open > .dropdown-toggle,\n.navbar-inverse .nav li.dropdown.active > .dropdown-toggle,\n.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle {\n  background-color: #111111;\n  color: #ffffff;\n}\n.navbar-inverse .nav li.dropdown > a:hover .caret,\n.navbar-inverse .nav li.dropdown > a:focus .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret {\n  border-top-color: #999999;\n  border-bottom-color: #999999;\n}\n.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret,\n.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret,\n.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n.navbar-inverse .navbar-search .search-query {\n  color: #ffffff;\n  background-color: #515151;\n  border-color: #111111;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);\n  -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);\n  box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);\n  -webkit-transition: none;\n  -moz-transition: none;\n  -o-transition: none;\n  transition: none;\n}\n.navbar-inverse .navbar-search .search-query:-moz-placeholder {\n  color: #cccccc;\n}\n.navbar-inverse .navbar-search .search-query:-ms-input-placeholder {\n  color: #cccccc;\n}\n.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder {\n  color: #cccccc;\n}\n.navbar-inverse .navbar-search .search-query:focus,\n.navbar-inverse .navbar-search .search-query.focused {\n  padding: 5px 15px;\n  color: #333333;\n  text-shadow: 0 1px 0 #ffffff;\n  background-color: #ffffff;\n  border: 0;\n  -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);\n  -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);\n  box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);\n  outline: 0;\n}\n.navbar-inverse .btn-navbar {\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #0e0e0e;\n  background-image: -moz-linear-gradient(top, #151515, #040404);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));\n  background-image: -webkit-linear-gradient(top, #151515, #040404);\n  background-image: -o-linear-gradient(top, #151515, #040404);\n  background-image: linear-gradient(to bottom, #151515, #040404);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);\n  border-color: #040404 #040404 #000000;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  *background-color: #040404;\n  /* Darken IE7 buttons by default so they stand out more given they won't have borders */\n\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.navbar-inverse .btn-navbar:hover,\n.navbar-inverse .btn-navbar:focus,\n.navbar-inverse .btn-navbar:active,\n.navbar-inverse .btn-navbar.active,\n.navbar-inverse .btn-navbar.disabled,\n.navbar-inverse .btn-navbar[disabled] {\n  color: #ffffff;\n  background-color: #040404;\n  *background-color: #000000;\n}\n.navbar-inverse .btn-navbar:active,\n.navbar-inverse .btn-navbar.active {\n  background-color: #000000 \\9;\n}\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, 0.15);\n}\n.well-large {\n  padding: 24px;\n  -webkit-border-radius: 6px;\n  -moz-border-radius: 6px;\n  border-radius: 6px;\n}\n.well-small {\n  padding: 9px;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n@-ms-viewport {\n  width: device-width;\n}\n.hidden {\n  display: none;\n  visibility: hidden;\n}\n.visible-phone {\n  display: none !important;\n}\n.visible-tablet {\n  display: none !important;\n}\n.hidden-desktop {\n  display: none !important;\n}\n.visible-desktop {\n  display: inherit !important;\n}\n@media (min-width: 768px) and (max-width: 979px) {\n  .hidden-desktop {\n    display: inherit !important;\n  }\n  .visible-desktop {\n    display: none !important ;\n  }\n  .visible-tablet {\n    display: inherit !important;\n  }\n  .hidden-tablet {\n    display: none !important;\n  }\n}\n@media (max-width: 767px) {\n  .hidden-desktop {\n    display: inherit !important;\n  }\n  .visible-desktop {\n    display: none !important;\n  }\n  .visible-phone {\n    display: inherit !important;\n  }\n  .hidden-phone {\n    display: none !important;\n  }\n}\n.visible-print {\n  display: none !important;\n}\n@media print {\n  .visible-print {\n    display: inherit !important;\n  }\n  .hidden-print {\n    display: none !important;\n  }\n}\n@media (max-width: 767px) {\n  body {\n    padding-left: 20px;\n    padding-right: 20px;\n  }\n  .navbar-fixed-top,\n  .navbar-fixed-bottom,\n  .navbar-static-top {\n    margin-left: -20px;\n    margin-right: -20px;\n  }\n  .container-fluid {\n    padding: 0;\n  }\n  .dl-horizontal dt {\n    float: none;\n    clear: none;\n    width: auto;\n    text-align: left;\n  }\n  .dl-horizontal dd {\n    margin-left: 0;\n  }\n  .container {\n    width: auto;\n  }\n  .row-fluid {\n    width: 100%;\n  }\n  .row,\n  .thumbnails {\n    margin-left: 0;\n  }\n  .thumbnails > li {\n    float: none;\n    margin-left: 0;\n  }\n  [class*=\"span\"],\n  .uneditable-input[class*=\"span\"],\n  .row-fluid [class*=\"span\"] {\n    float: none;\n    display: block;\n    width: 100%;\n    margin-left: 0;\n    -webkit-box-sizing: border-box;\n    -moz-box-sizing: border-box;\n    box-sizing: border-box;\n  }\n  .span12,\n  .row-fluid .span12 {\n    width: 100%;\n    -webkit-box-sizing: border-box;\n    -moz-box-sizing: border-box;\n    box-sizing: border-box;\n  }\n  .row-fluid [class*=\"offset\"]:first-child {\n    margin-left: 0;\n  }\n  .input-large,\n  .input-xlarge,\n  .input-xxlarge,\n  input[class*=\"span\"],\n  select[class*=\"span\"],\n  textarea[class*=\"span\"],\n  .uneditable-input {\n    display: block;\n    width: 100%;\n    min-height: 30px;\n    -webkit-box-sizing: border-box;\n    -moz-box-sizing: border-box;\n    box-sizing: border-box;\n  }\n  .input-prepend input,\n  .input-append input,\n  .input-prepend input[class*=\"span\"],\n  .input-append input[class*=\"span\"] {\n    display: inline-block;\n    width: auto;\n  }\n  .controls-row [class*=\"span\"] + [class*=\"span\"] {\n    margin-left: 0;\n  }\n  .modal {\n    position: fixed;\n    top: 20px;\n    left: 20px;\n    right: 20px;\n    width: auto;\n    margin: 0;\n  }\n  .modal.fade {\n    top: -100px;\n  }\n  .modal.fade.in {\n    top: 20px;\n  }\n}\n@media (max-width: 480px) {\n  .nav-collapse {\n    -webkit-transform: translate3d(0, 0, 0);\n  }\n  .page-header h1 small {\n    display: block;\n    line-height: 20px;\n  }\n  input[type=\"checkbox\"],\n  input[type=\"radio\"] {\n    border: 1px solid #ccc;\n  }\n  .form-horizontal .control-label {\n    float: none;\n    width: auto;\n    padding-top: 0;\n    text-align: left;\n  }\n  .form-horizontal .controls {\n    margin-left: 0;\n  }\n  .form-horizontal .control-list {\n    padding-top: 0;\n  }\n  .form-horizontal .form-actions {\n    padding-left: 10px;\n    padding-right: 10px;\n  }\n  .media .pull-left,\n  .media .pull-right {\n    float: none;\n    display: block;\n    margin-bottom: 10px;\n  }\n  .media-object {\n    margin-right: 0;\n    margin-left: 0;\n  }\n  .modal {\n    top: 10px;\n    left: 10px;\n    right: 10px;\n  }\n  .modal-header .close {\n    padding: 10px;\n    margin: -10px;\n  }\n  .carousel-caption {\n    position: static;\n  }\n}\n@media (min-width: 768px) and (max-width: 979px) {\n  .row {\n    margin-left: -20px;\n    *zoom: 1;\n  }\n  .row:before,\n  .row:after {\n    display: table;\n    content: \"\";\n    line-height: 0;\n  }\n  .row:after {\n    clear: both;\n  }\n  [class*=\"span\"] {\n    float: left;\n    min-height: 1px;\n    margin-left: 20px;\n  }\n  .container,\n  .navbar-static-top .container,\n  .navbar-fixed-top .container,\n  .navbar-fixed-bottom .container {\n    width: 724px;\n  }\n  .span12 {\n    width: 724px;\n  }\n  .span11 {\n    width: 662px;\n  }\n  .span10 {\n    width: 600px;\n  }\n  .span9 {\n    width: 538px;\n  }\n  .span8 {\n    width: 476px;\n  }\n  .span7 {\n    width: 414px;\n  }\n  .span6 {\n    width: 352px;\n  }\n  .span5 {\n    width: 290px;\n  }\n  .span4 {\n    width: 228px;\n  }\n  .span3 {\n    width: 166px;\n  }\n  .span2 {\n    width: 104px;\n  }\n  .span1 {\n    width: 42px;\n  }\n  .offset12 {\n    margin-left: 764px;\n  }\n  .offset11 {\n    margin-left: 702px;\n  }\n  .offset10 {\n    margin-left: 640px;\n  }\n  .offset9 {\n    margin-left: 578px;\n  }\n  .offset8 {\n    margin-left: 516px;\n  }\n  .offset7 {\n    margin-left: 454px;\n  }\n  .offset6 {\n    margin-left: 392px;\n  }\n  .offset5 {\n    margin-left: 330px;\n  }\n  .offset4 {\n    margin-left: 268px;\n  }\n  .offset3 {\n    margin-left: 206px;\n  }\n  .offset2 {\n    margin-left: 144px;\n  }\n  .offset1 {\n    margin-left: 82px;\n  }\n  .row-fluid {\n    width: 100%;\n    *zoom: 1;\n  }\n  .row-fluid:before,\n  .row-fluid:after {\n    display: table;\n    content: \"\";\n    line-height: 0;\n  }\n  .row-fluid:after {\n    clear: both;\n  }\n  .row-fluid [class*=\"span\"] {\n    display: block;\n    width: 100%;\n    min-height: 30px;\n    -webkit-box-sizing: border-box;\n    -moz-box-sizing: border-box;\n    box-sizing: border-box;\n    float: left;\n    margin-left: 2.7624309392265194%;\n    *margin-left: 2.709239449864817%;\n  }\n  .row-fluid [class*=\"span\"]:first-child {\n    margin-left: 0;\n  }\n  .row-fluid .controls-row [class*=\"span\"] + [class*=\"span\"] {\n    margin-left: 2.7624309392265194%;\n  }\n  .row-fluid .span12 {\n    width: 100%;\n    *width: 99.94680851063829%;\n  }\n  .row-fluid .span11 {\n    width: 91.43646408839778%;\n    *width: 91.38327259903608%;\n  }\n  .row-fluid .span10 {\n    width: 82.87292817679558%;\n    *width: 82.81973668743387%;\n  }\n  .row-fluid .span9 {\n    width: 74.30939226519337%;\n    *width: 74.25620077583166%;\n  }\n  .row-fluid .span8 {\n    width: 65.74585635359117%;\n    *width: 65.69266486422946%;\n  }\n  .row-fluid .span7 {\n    width: 57.18232044198895%;\n    *width: 57.12912895262725%;\n  }\n  .row-fluid .span6 {\n    width: 48.61878453038674%;\n    *width: 48.56559304102504%;\n  }\n  .row-fluid .span5 {\n    width: 40.05524861878453%;\n    *width: 40.00205712942283%;\n  }\n  .row-fluid .span4 {\n    width: 31.491712707182323%;\n    *width: 31.43852121782062%;\n  }\n  .row-fluid .span3 {\n    width: 22.92817679558011%;\n    *width: 22.87498530621841%;\n  }\n  .row-fluid .span2 {\n    width: 14.3646408839779%;\n    *width: 14.311449394616199%;\n  }\n  .row-fluid .span1 {\n    width: 5.801104972375691%;\n    *width: 5.747913483013988%;\n  }\n  .row-fluid .offset12 {\n    margin-left: 105.52486187845304%;\n    *margin-left: 105.41847889972962%;\n  }\n  .row-fluid .offset12:first-child {\n    margin-left: 102.76243093922652%;\n    *margin-left: 102.6560479605031%;\n  }\n  .row-fluid .offset11 {\n    margin-left: 96.96132596685082%;\n    *margin-left: 96.8549429881274%;\n  }\n  .row-fluid .offset11:first-child {\n    margin-left: 94.1988950276243%;\n    *margin-left: 94.09251204890089%;\n  }\n  .row-fluid .offset10 {\n    margin-left: 88.39779005524862%;\n    *margin-left: 88.2914070765252%;\n  }\n  .row-fluid .offset10:first-child {\n    margin-left: 85.6353591160221%;\n    *margin-left: 85.52897613729868%;\n  }\n  .row-fluid .offset9 {\n    margin-left: 79.8342541436464%;\n    *margin-left: 79.72787116492299%;\n  }\n  .row-fluid .offset9:first-child {\n    margin-left: 77.07182320441989%;\n    *margin-left: 76.96544022569647%;\n  }\n  .row-fluid .offset8 {\n    margin-left: 71.2707182320442%;\n    *margin-left: 71.16433525332079%;\n  }\n  .row-fluid .offset8:first-child {\n    margin-left: 68.50828729281768%;\n    *margin-left: 68.40190431409427%;\n  }\n  .row-fluid .offset7 {\n    margin-left: 62.70718232044199%;\n    *margin-left: 62.600799341718584%;\n  }\n  .row-fluid .offset7:first-child {\n    margin-left: 59.94475138121547%;\n    *margin-left: 59.838368402492065%;\n  }\n  .row-fluid .offset6 {\n    margin-left: 54.14364640883978%;\n    *margin-left: 54.037263430116376%;\n  }\n  .row-fluid .offset6:first-child {\n    margin-left: 51.38121546961326%;\n    *margin-left: 51.27483249088986%;\n  }\n  .row-fluid .offset5 {\n    margin-left: 45.58011049723757%;\n    *margin-left: 45.47372751851417%;\n  }\n  .row-fluid .offset5:first-child {\n    margin-left: 42.81767955801105%;\n    *margin-left: 42.71129657928765%;\n  }\n  .row-fluid .offset4 {\n    margin-left: 37.01657458563536%;\n    *margin-left: 36.91019160691196%;\n  }\n  .row-fluid .offset4:first-child {\n    margin-left: 34.25414364640884%;\n    *margin-left: 34.14776066768544%;\n  }\n  .row-fluid .offset3 {\n    margin-left: 28.45303867403315%;\n    *margin-left: 28.346655695309746%;\n  }\n  .row-fluid .offset3:first-child {\n    margin-left: 25.69060773480663%;\n    *margin-left: 25.584224756083227%;\n  }\n  .row-fluid .offset2 {\n    margin-left: 19.88950276243094%;\n    *margin-left: 19.783119783707537%;\n  }\n  .row-fluid .offset2:first-child {\n    margin-left: 17.12707182320442%;\n    *margin-left: 17.02068884448102%;\n  }\n  .row-fluid .offset1 {\n    margin-left: 11.32596685082873%;\n    *margin-left: 11.219583872105325%;\n  }\n  .row-fluid .offset1:first-child {\n    margin-left: 8.56353591160221%;\n    *margin-left: 8.457152932878806%;\n  }\n  input,\n  textarea,\n  .uneditable-input {\n    margin-left: 0;\n  }\n  .controls-row [class*=\"span\"] + [class*=\"span\"] {\n    margin-left: 20px;\n  }\n  input.span12,\n  textarea.span12,\n  .uneditable-input.span12 {\n    width: 710px;\n  }\n  input.span11,\n  textarea.span11,\n  .uneditable-input.span11 {\n    width: 648px;\n  }\n  input.span10,\n  textarea.span10,\n  .uneditable-input.span10 {\n    width: 586px;\n  }\n  input.span9,\n  textarea.span9,\n  .uneditable-input.span9 {\n    width: 524px;\n  }\n  input.span8,\n  textarea.span8,\n  .uneditable-input.span8 {\n    width: 462px;\n  }\n  input.span7,\n  textarea.span7,\n  .uneditable-input.span7 {\n    width: 400px;\n  }\n  input.span6,\n  textarea.span6,\n  .uneditable-input.span6 {\n    width: 338px;\n  }\n  input.span5,\n  textarea.span5,\n  .uneditable-input.span5 {\n    width: 276px;\n  }\n  input.span4,\n  textarea.span4,\n  .uneditable-input.span4 {\n    width: 214px;\n  }\n  input.span3,\n  textarea.span3,\n  .uneditable-input.span3 {\n    width: 152px;\n  }\n  input.span2,\n  textarea.span2,\n  .uneditable-input.span2 {\n    width: 90px;\n  }\n  input.span1,\n  textarea.span1,\n  .uneditable-input.span1 {\n    width: 28px;\n  }\n}\n@media (min-width: 1200px) {\n  .row {\n    margin-left: -30px;\n    *zoom: 1;\n  }\n  .row:before,\n  .row:after {\n    display: table;\n    content: \"\";\n    line-height: 0;\n  }\n  .row:after {\n    clear: both;\n  }\n  [class*=\"span\"] {\n    float: left;\n    min-height: 1px;\n    margin-left: 30px;\n  }\n  .container,\n  .navbar-static-top .container,\n  .navbar-fixed-top .container,\n  .navbar-fixed-bottom .container {\n    width: 1170px;\n  }\n  .span12 {\n    width: 1170px;\n  }\n  .span11 {\n    width: 1070px;\n  }\n  .span10 {\n    width: 970px;\n  }\n  .span9 {\n    width: 870px;\n  }\n  .span8 {\n    width: 770px;\n  }\n  .span7 {\n    width: 670px;\n  }\n  .span6 {\n    width: 570px;\n  }\n  .span5 {\n    width: 470px;\n  }\n  .span4 {\n    width: 370px;\n  }\n  .span3 {\n    width: 270px;\n  }\n  .span2 {\n    width: 170px;\n  }\n  .span1 {\n    width: 70px;\n  }\n  .offset12 {\n    margin-left: 1230px;\n  }\n  .offset11 {\n    margin-left: 1130px;\n  }\n  .offset10 {\n    margin-left: 1030px;\n  }\n  .offset9 {\n    margin-left: 930px;\n  }\n  .offset8 {\n    margin-left: 830px;\n  }\n  .offset7 {\n    margin-left: 730px;\n  }\n  .offset6 {\n    margin-left: 630px;\n  }\n  .offset5 {\n    margin-left: 530px;\n  }\n  .offset4 {\n    margin-left: 430px;\n  }\n  .offset3 {\n    margin-left: 330px;\n  }\n  .offset2 {\n    margin-left: 230px;\n  }\n  .offset1 {\n    margin-left: 130px;\n  }\n  .row-fluid {\n    width: 100%;\n    *zoom: 1;\n  }\n  .row-fluid:before,\n  .row-fluid:after {\n    display: table;\n    content: \"\";\n    line-height: 0;\n  }\n  .row-fluid:after {\n    clear: both;\n  }\n  .row-fluid [class*=\"span\"] {\n    display: block;\n    width: 100%;\n    min-height: 30px;\n    -webkit-box-sizing: border-box;\n    -moz-box-sizing: border-box;\n    box-sizing: border-box;\n    float: left;\n    margin-left: 2.564102564102564%;\n    *margin-left: 2.5109110747408616%;\n  }\n  .row-fluid [class*=\"span\"]:first-child {\n    margin-left: 0;\n  }\n  .row-fluid .controls-row [class*=\"span\"] + [class*=\"span\"] {\n    margin-left: 2.564102564102564%;\n  }\n  .row-fluid .span12 {\n    width: 100%;\n    *width: 99.94680851063829%;\n  }\n  .row-fluid .span11 {\n    width: 91.45299145299145%;\n    *width: 91.39979996362975%;\n  }\n  .row-fluid .span10 {\n    width: 82.90598290598291%;\n    *width: 82.8527914166212%;\n  }\n  .row-fluid .span9 {\n    width: 74.35897435897436%;\n    *width: 74.30578286961266%;\n  }\n  .row-fluid .span8 {\n    width: 65.81196581196582%;\n    *width: 65.75877432260411%;\n  }\n  .row-fluid .span7 {\n    width: 57.26495726495726%;\n    *width: 57.21176577559556%;\n  }\n  .row-fluid .span6 {\n    width: 48.717948717948715%;\n    *width: 48.664757228587014%;\n  }\n  .row-fluid .span5 {\n    width: 40.17094017094017%;\n    *width: 40.11774868157847%;\n  }\n  .row-fluid .span4 {\n    width: 31.623931623931625%;\n    *width: 31.570740134569924%;\n  }\n  .row-fluid .span3 {\n    width: 23.076923076923077%;\n    *width: 23.023731587561375%;\n  }\n  .row-fluid .span2 {\n    width: 14.52991452991453%;\n    *width: 14.476723040552828%;\n  }\n  .row-fluid .span1 {\n    width: 5.982905982905983%;\n    *width: 5.929714493544281%;\n  }\n  .row-fluid .offset12 {\n    margin-left: 105.12820512820512%;\n    *margin-left: 105.02182214948171%;\n  }\n  .row-fluid .offset12:first-child {\n    margin-left: 102.56410256410257%;\n    *margin-left: 102.45771958537915%;\n  }\n  .row-fluid .offset11 {\n    margin-left: 96.58119658119658%;\n    *margin-left: 96.47481360247316%;\n  }\n  .row-fluid .offset11:first-child {\n    margin-left: 94.01709401709402%;\n    *margin-left: 93.91071103837061%;\n  }\n  .row-fluid .offset10 {\n    margin-left: 88.03418803418803%;\n    *margin-left: 87.92780505546462%;\n  }\n  .row-fluid .offset10:first-child {\n    margin-left: 85.47008547008548%;\n    *margin-left: 85.36370249136206%;\n  }\n  .row-fluid .offset9 {\n    margin-left: 79.48717948717949%;\n    *margin-left: 79.38079650845607%;\n  }\n  .row-fluid .offset9:first-child {\n    margin-left: 76.92307692307693%;\n    *margin-left: 76.81669394435352%;\n  }\n  .row-fluid .offset8 {\n    margin-left: 70.94017094017094%;\n    *margin-left: 70.83378796144753%;\n  }\n  .row-fluid .offset8:first-child {\n    margin-left: 68.37606837606839%;\n    *margin-left: 68.26968539734497%;\n  }\n  .row-fluid .offset7 {\n    margin-left: 62.393162393162385%;\n    *margin-left: 62.28677941443899%;\n  }\n  .row-fluid .offset7:first-child {\n    margin-left: 59.82905982905982%;\n    *margin-left: 59.72267685033642%;\n  }\n  .row-fluid .offset6 {\n    margin-left: 53.84615384615384%;\n    *margin-left: 53.739770867430444%;\n  }\n  .row-fluid .offset6:first-child {\n    margin-left: 51.28205128205128%;\n    *margin-left: 51.175668303327875%;\n  }\n  .row-fluid .offset5 {\n    margin-left: 45.299145299145295%;\n    *margin-left: 45.1927623204219%;\n  }\n  .row-fluid .offset5:first-child {\n    margin-left: 42.73504273504273%;\n    *margin-left: 42.62865975631933%;\n  }\n  .row-fluid .offset4 {\n    margin-left: 36.75213675213675%;\n    *margin-left: 36.645753773413354%;\n  }\n  .row-fluid .offset4:first-child {\n    margin-left: 34.18803418803419%;\n    *margin-left: 34.081651209310785%;\n  }\n  .row-fluid .offset3 {\n    margin-left: 28.205128205128204%;\n    *margin-left: 28.0987452264048%;\n  }\n  .row-fluid .offset3:first-child {\n    margin-left: 25.641025641025642%;\n    *margin-left: 25.53464266230224%;\n  }\n  .row-fluid .offset2 {\n    margin-left: 19.65811965811966%;\n    *margin-left: 19.551736679396257%;\n  }\n  .row-fluid .offset2:first-child {\n    margin-left: 17.094017094017094%;\n    *margin-left: 16.98763411529369%;\n  }\n  .row-fluid .offset1 {\n    margin-left: 11.11111111111111%;\n    *margin-left: 11.004728132387708%;\n  }\n  .row-fluid .offset1:first-child {\n    margin-left: 8.547008547008547%;\n    *margin-left: 8.440625568285142%;\n  }\n  input,\n  textarea,\n  .uneditable-input {\n    margin-left: 0;\n  }\n  .controls-row [class*=\"span\"] + [class*=\"span\"] {\n    margin-left: 30px;\n  }\n  input.span12,\n  textarea.span12,\n  .uneditable-input.span12 {\n    width: 1156px;\n  }\n  input.span11,\n  textarea.span11,\n  .uneditable-input.span11 {\n    width: 1056px;\n  }\n  input.span10,\n  textarea.span10,\n  .uneditable-input.span10 {\n    width: 956px;\n  }\n  input.span9,\n  textarea.span9,\n  .uneditable-input.span9 {\n    width: 856px;\n  }\n  input.span8,\n  textarea.span8,\n  .uneditable-input.span8 {\n    width: 756px;\n  }\n  input.span7,\n  textarea.span7,\n  .uneditable-input.span7 {\n    width: 656px;\n  }\n  input.span6,\n  textarea.span6,\n  .uneditable-input.span6 {\n    width: 556px;\n  }\n  input.span5,\n  textarea.span5,\n  .uneditable-input.span5 {\n    width: 456px;\n  }\n  input.span4,\n  textarea.span4,\n  .uneditable-input.span4 {\n    width: 356px;\n  }\n  input.span3,\n  textarea.span3,\n  .uneditable-input.span3 {\n    width: 256px;\n  }\n  input.span2,\n  textarea.span2,\n  .uneditable-input.span2 {\n    width: 156px;\n  }\n  input.span1,\n  textarea.span1,\n  .uneditable-input.span1 {\n    width: 56px;\n  }\n  .thumbnails {\n    margin-left: -30px;\n  }\n  .thumbnails > li {\n    margin-left: 30px;\n  }\n  .row-fluid .thumbnails {\n    margin-left: 0;\n  }\n}\n@media (max-width: 979px) {\n  body {\n    padding-top: 0;\n  }\n  .navbar-fixed-top,\n  .navbar-fixed-bottom {\n    position: static;\n  }\n  .navbar-fixed-top {\n    margin-bottom: 20px;\n  }\n  .navbar-fixed-bottom {\n    margin-top: 20px;\n  }\n  .navbar-fixed-top .navbar-inner,\n  .navbar-fixed-bottom .navbar-inner {\n    padding: 5px;\n  }\n  .navbar .container {\n    width: auto;\n    padding: 0;\n  }\n  .navbar .brand {\n    padding-left: 10px;\n    padding-right: 10px;\n    margin: 0 0 0 -5px;\n  }\n  .nav-collapse {\n    clear: both;\n  }\n  .nav-collapse .nav {\n    float: none;\n    margin: 0 0 10px;\n  }\n  .nav-collapse .nav > li {\n    float: none;\n  }\n  .nav-collapse .nav > li > a {\n    margin-bottom: 2px;\n  }\n  .nav-collapse .nav > .divider-vertical {\n    display: none;\n  }\n  .nav-collapse .nav .nav-header {\n    color: #777777;\n    text-shadow: none;\n  }\n  .nav-collapse .nav > li > a,\n  .nav-collapse .dropdown-menu a {\n    padding: 9px 15px;\n    font-weight: bold;\n    color: #777777;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n  }\n  .nav-collapse .btn {\n    padding: 4px 10px 4px;\n    font-weight: normal;\n    -webkit-border-radius: 4px;\n    -moz-border-radius: 4px;\n    border-radius: 4px;\n  }\n  .nav-collapse .dropdown-menu li + li a {\n    margin-bottom: 2px;\n  }\n  .nav-collapse .nav > li > a:hover,\n  .nav-collapse .nav > li > a:focus,\n  .nav-collapse .dropdown-menu a:hover,\n  .nav-collapse .dropdown-menu a:focus {\n    background-color: #f2f2f2;\n  }\n  .navbar-inverse .nav-collapse .nav > li > a,\n  .navbar-inverse .nav-collapse .dropdown-menu a {\n    color: #999999;\n  }\n  .navbar-inverse .nav-collapse .nav > li > a:hover,\n  .navbar-inverse .nav-collapse .nav > li > a:focus,\n  .navbar-inverse .nav-collapse .dropdown-menu a:hover,\n  .navbar-inverse .nav-collapse .dropdown-menu a:focus {\n    background-color: #111111;\n  }\n  .nav-collapse.in .btn-group {\n    margin-top: 5px;\n    padding: 0;\n  }\n  .nav-collapse .dropdown-menu {\n    position: static;\n    top: auto;\n    left: auto;\n    float: none;\n    display: none;\n    max-width: none;\n    margin: 0 15px;\n    padding: 0;\n    background-color: transparent;\n    border: none;\n    -webkit-border-radius: 0;\n    -moz-border-radius: 0;\n    border-radius: 0;\n    -webkit-box-shadow: none;\n    -moz-box-shadow: none;\n    box-shadow: none;\n  }\n  .nav-collapse .open > .dropdown-menu {\n    display: block;\n  }\n  .nav-collapse .dropdown-menu:before,\n  .nav-collapse .dropdown-menu:after {\n    display: none;\n  }\n  .nav-collapse .dropdown-menu .divider {\n    display: none;\n  }\n  .nav-collapse .nav > li > .dropdown-menu:before,\n  .nav-collapse .nav > li > .dropdown-menu:after {\n    display: none;\n  }\n  .nav-collapse .navbar-form,\n  .nav-collapse .navbar-search {\n    float: none;\n    padding: 10px 15px;\n    margin: 10px 0;\n    border-top: 1px solid #f2f2f2;\n    border-bottom: 1px solid #f2f2f2;\n    -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n    -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n    box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n  }\n  .navbar-inverse .nav-collapse .navbar-form,\n  .navbar-inverse .nav-collapse .navbar-search {\n    border-top-color: #111111;\n    border-bottom-color: #111111;\n  }\n  .navbar .nav-collapse .nav.pull-right {\n    float: none;\n    margin-left: 0;\n  }\n  .nav-collapse,\n  .nav-collapse.collapse {\n    overflow: hidden;\n    height: 0;\n  }\n  .navbar .btn-navbar {\n    display: block;\n  }\n  .navbar-static .navbar-inner {\n    padding-left: 10px;\n    padding-right: 10px;\n  }\n}\n@media (min-width: 980px) {\n  .nav-collapse.collapse {\n    height: auto !important;\n    overflow: visible !important;\n  }\n}\n\n\n/* CUSTOMIZATIONS */\n.doc-title { float: left; display: block; padding: 10px 20px 10px; margin-left: -20px;\n  font-size: 20px; font-weight: 200; color: #777777; text-shadow: 0 1px 0 #ffffff; }\n.doc-info .navbar-text { padding: 0 15px; }\nh1 a { color: #333; } h2 a { color: #333; } h3 a { color: #333; }\nh4 a { color: #333; } h5 a { color: #333; } h6 a { color: #333; }\nh1:hover a { color: #333; } h2:hover a { color: #333; } h3:hover a { color: #333; }\nh4:hover a { color: #333; } h5:hover a { color: #333; } h6:hover a { color: #333; }\n.toc { margin-top: 10px; }\n.toc, .toc ul { padding: 0; }\n.toc ul { margin-left: 0; margin-bottom: 20px; list-style: none; }\n.toc ul > li > a { display: block; }\n.toc ul > li > a:hover,\n.toc ul > li > a:focus { text-decoration: none; background-color: #eeeeee; }\n.toc ul { margin-bottom: 0; }\n.toc ul > li > a, .toc ul > li > a { padding: 3px 15px; }"
  },
  {
    "path": "pandoc4.css",
    "content": "@charset \"UTF-8\";\n/* github-markdown.css -- MIT License:\n   Copyright (c) 2017 Tristano Ajmone.\n   Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)\n   Copyright (c) 2017 GitHub Inc.\n*/\n.markdown-body {\n  -ms-text-size-adjust: 100%;\n  -webkit-text-size-adjust: 100%;\n  line-height: 1.5;\n  color: #24292e;\n  font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n  font-size: 16px;\n  line-height: 1.5;\n  word-wrap: break-word;\n  box-sizing: border-box;\n  min-width: 200px;\n  max-width: 980px;\n  margin: 0 auto;\n  padding: 45px;\n}\n.markdown-body a {\n  color: #0366d6;\n  background-color: transparent;\n  text-decoration: none;\n  -webkit-text-decoration-skip: objects;\n}\n.markdown-body a:active, .markdown-body a:hover {\n  outline-width: 0;\n}\n.markdown-body a:hover {\n  text-decoration: underline;\n}\n.markdown-body a:not([href]) {\n  color: inherit;\n  text-decoration: none;\n}\n.markdown-body strong {\n  font-weight: 600;\n}\n.markdown-body h1,\n.markdown-body h2,\n.markdown-body h3,\n.markdown-body h4,\n.markdown-body h5,\n.markdown-body h6 {\n  margin-top: 24px;\n  margin-bottom: 16px;\n  font-weight: 600;\n  line-height: 1.25;\n}\n.markdown-body h1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n  padding-bottom: 0.3em;\n  border-bottom: 1px solid #eaecef;\n}\n.markdown-body h2 {\n  padding-bottom: 0.3em;\n  font-size: 1.5em;\n  border-bottom: 1px solid #eaecef;\n}\n.markdown-body h3 {\n  font-size: 1.25em;\n}\n.markdown-body h4 {\n  font-size: 1em;\n}\n.markdown-body h5 {\n  font-size: 0.875em;\n}\n.markdown-body h6 {\n  font-size: 0.85em;\n  color: #6a737d;\n}\n.markdown-body img {\n  border-style: none;\n}\n.markdown-body svg:not(:root) {\n  overflow: hidden;\n}\n.markdown-body code,\n.markdown-body kbd,\n.markdown-body pre {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n.markdown-body hr {\n  box-sizing: content-box;\n  height: 0.25em;\n  margin: 24px 0;\n  padding: 0;\n  overflow: hidden;\n  background-color: #e1e4e8;\n  border: 0;\n}\n.markdown-body hr::before {\n  display: table;\n  content: \"\";\n}\n.markdown-body hr::after {\n  display: table;\n  clear: both;\n  content: \"\";\n}\n.markdown-body input {\n  margin: 0;\n  overflow: visible;\n  font: inherit;\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n.markdown-body [type=checkbox] {\n  box-sizing: border-box;\n  padding: 0;\n}\n.markdown-body * {\n  box-sizing: border-box;\n}\n.markdown-body p {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\n.markdown-body blockquote {\n  margin: 0;\n}\n.markdown-body ul,\n.markdown-body ol {\n  padding-left: 2em;\n  margin-top: 0;\n  margin-bottom: 0;\n}\n.markdown-body ul ol,\n.markdown-body ol ol {\n  list-style-type: lower-roman;\n}\n.markdown-body ul ul,\n.markdown-body ul ol,\n.markdown-body ol ul,\n.markdown-body ol ol {\n  margin-top: 0;\n  margin-bottom: 0;\n}\n.markdown-body ul ul ol,\n.markdown-body ul ol ol,\n.markdown-body ol ul ol,\n.markdown-body ol ol ol {\n  list-style-type: lower-alpha;\n}\n.markdown-body li > p {\n  margin-top: 16px;\n}\n.markdown-body li + li {\n  margin-top: 0.25em;\n}\n.markdown-body dd {\n  margin-left: 0;\n}\n.markdown-body dl {\n  padding: 0;\n}\n.markdown-body dl dt {\n  padding: 0;\n  margin-top: 16px;\n  font-size: 1em;\n  font-style: italic;\n  font-weight: 600;\n}\n.markdown-body dl dd {\n  padding: 0 16px;\n  margin-bottom: 16px;\n}\n.markdown-body code {\n  font-family: \"SFMono-Regular\", Consolas, \"Liberation Mono\", Menlo, Courier, monospace;\n  font-size: 12px;\n}\n.markdown-body pre {\n  margin-top: 0;\n  margin-bottom: 0;\n  font: 12px \"SFMono-Regular\", Consolas, \"Liberation Mono\", Menlo, Courier, monospace;\n}\n.markdown-body p,\n.markdown-body blockquote,\n.markdown-body ul,\n.markdown-body ol,\n.markdown-body dl,\n.markdown-body table,\n.markdown-body pre {\n  margin-top: 0;\n  margin-bottom: 16px;\n}\n.markdown-body blockquote {\n  padding: 0 1em;\n  color: #6a737d;\n  border-left: 0.25em solid #dfe2e5;\n}\n.markdown-body blockquote > :first-child {\n  margin-top: 0;\n}\n.markdown-body blockquote > :last-child {\n  margin-bottom: 0;\n}\n.markdown-body kbd {\n  display: inline-block;\n  padding: 3px 5px;\n  font-size: 11px;\n  line-height: 10px;\n  color: #444d56;\n  vertical-align: middle;\n  background-color: #fafbfc;\n  border: solid 1px #c6cbd1;\n  border-bottom-color: #959da5;\n  border-radius: 3px;\n  box-shadow: inset 0 -1px 0 #959da5;\n}\n.markdown-body table {\n  display: block;\n  width: 100%;\n  overflow: auto;\n  border-spacing: 0;\n  border-collapse: collapse;\n}\n.markdown-body table th {\n  font-weight: 600;\n}\n.markdown-body table th, .markdown-body table td {\n  padding: 6px 13px;\n  border: 1px solid #dfe2e5;\n}\n.markdown-body table tr {\n  background-color: #fff;\n  border-top: 1px solid #c6cbd1;\n}\n.markdown-body table tr:nth-child(2n) {\n  background-color: #f6f8fa;\n}\n.markdown-body img {\n  max-width: 100%;\n  box-sizing: content-box;\n  background-color: #fff;\n}\n.markdown-body code {\n  padding: 0;\n  padding-top: 0.2em;\n  padding-bottom: 0.2em;\n  margin: 0;\n  font-size: 85%;\n  background-color: rgba(27, 31, 35, 0.05);\n  border-radius: 3px;\n}\n.markdown-body code::before,\n.markdown-body code::after {\n  letter-spacing: -0.2em;\n  content: \" \";\n}\n.markdown-body pre {\n  word-wrap: normal;\n}\n.markdown-body pre > code {\n  padding: 0;\n  margin: 0;\n  font-size: 100%;\n  word-break: normal;\n  white-space: pre;\n  background: transparent;\n  border: 0;\n}\n.markdown-body .highlight {\n  margin-bottom: 16px;\n}\n.markdown-body .highlight pre {\n  margin-bottom: 0;\n  word-break: normal;\n}\n.markdown-body .highlight pre,\n.markdown-body pre {\n  padding: 16px;\n  overflow: auto;\n  font-size: 85%;\n  line-height: 1.45;\n  background-color: #f6f8fa;\n  border-radius: 3px;\n}\n.markdown-body pre code {\n  display: inline;\n  max-width: auto;\n  padding: 0;\n  margin: 0;\n  overflow: visible;\n  line-height: inherit;\n  word-wrap: normal;\n  background-color: transparent;\n  border: 0;\n}\n.markdown-body pre code::before,\n.markdown-body pre code::after {\n  content: normal;\n}\n.markdown-body .full-commit .btn-outline:not(:disabled):hover {\n  color: #005cc5;\n  border-color: #005cc5;\n}\n.markdown-body kbd {\n  display: inline-block;\n  padding: 3px 5px;\n  font: 11px \"SFMono-Regular\", Consolas, \"Liberation Mono\", Menlo, Courier, monospace;\n  line-height: 10px;\n  color: #444d56;\n  vertical-align: middle;\n  background-color: #fcfcfc;\n  border: solid 1px #c6cbd1;\n  border-bottom-color: #959da5;\n  border-radius: 3px;\n  box-shadow: inset 0 -1px 0 #959da5;\n}\n.markdown-body :checked + .radio-label {\n  position: relative;\n  z-index: 1;\n  border-color: #0366d6;\n}\n.markdown-body .task-list-item {\n  list-style-type: none;\n}\n.markdown-body .task-list-item + .task-list-item {\n  margin-top: 3px;\n}\n.markdown-body .task-list-item input {\n  margin: 0 0.2em 0.25em -1.6em;\n  vertical-align: middle;\n}\n.markdown-body::before {\n  display: table;\n  content: \"\";\n}\n.markdown-body::after {\n  display: table;\n  clear: both;\n  content: \"\";\n}\n.markdown-body > *:first-child {\n  margin-top: 0 !important;\n}\n.markdown-body > *:last-child {\n  margin-bottom: 0 !important;\n}\n\n.Alert,\n.Warning,\n.Error,\n.Success,\n.Note {\n  padding: 11px;\n  margin-bottom: 24px;\n  border-style: solid;\n  border-width: 1px;\n  border-radius: 4px;\n}\n.Alert p,\n.Warning p,\n.Error p,\n.Success p,\n.Note p {\n  margin-top: 0;\n}\n.Alert p:last-child,\n.Warning p:last-child,\n.Error p:last-child,\n.Success p:last-child,\n.Note p:last-child {\n  margin-bottom: 0;\n}\n\n.Alert {\n  color: #224466;\n  background-color: #E2EEF9;\n  border-color: #BAC6D3;\n}\n\n.Warning {\n  color: #4C4A42;\n  background-color: #FFF9EA;\n  border-color: #DFD8C2;\n}\n\n.Error {\n  color: #991111;\n  background-color: #FCDEDE;\n  border-color: #D2B2B2;\n}\n\n.Success {\n  color: #22662C;\n  background-color: #E2F9E5;\n  border-color: #BAD3BE;\n}\n\n.Note {\n  color: #2F363D;\n  background-color: #F6F8FA;\n  border-color: #D5D8DA;\n}\n\n.Alert h1,\n.Alert h2,\n.Alert h3,\n.Alert h4,\n.Alert h5,\n.Alert h6 {\n  color: #224466;\n  margin-bottom: 0;\n}\n\n.Warning h1,\n.Warning h2,\n.Warning h3,\n.Warning h4,\n.Warning h5,\n.Warning h6 {\n  color: #4C4A42;\n  margin-bottom: 0;\n}\n\n.Error h1,\n.Error h2,\n.Error h3,\n.Error h4,\n.Error h5,\n.Error h6 {\n  color: #991111;\n  margin-bottom: 0;\n}\n\n.Success h1,\n.Success h2,\n.Success h3,\n.Success h4,\n.Success h5,\n.Success h6 {\n  color: #22662C;\n  margin-bottom: 0;\n}\n\n.Note h1,\n.Note h2,\n.Note h3,\n.Note h4,\n.Note h5,\n.Note h6 {\n  color: #2F363D;\n  margin-bottom: 0;\n}\n\n.Alert h1:first-child,\n.Alert h2:first-child,\n.Alert h3:first-child,\n.Alert h4:first-child,\n.Alert h5:first-child,\n.Alert h6:first-child {\n  margin-top: 0;\n}\n\n.Warning h1:first-child,\n.Warning h2:first-child,\n.Warning h3:first-child,\n.Warning h4:first-child,\n.Warning h5:first-child,\n.Warning h6:first-child {\n  margin-top: 0;\n}\n\n.Error h1:first-child,\n.Error h2:first-child,\n.Error h3:first-child,\n.Error h4:first-child,\n.Error h5:first-child,\n.Error h6:first-child {\n  margin-top: 0;\n}\n\n.Success h1:first-child,\n.Success h2:first-child,\n.Success h3:first-child,\n.Success h4:first-child,\n.Success h5:first-child,\n.Success h6:first-child {\n  margin-top: 0;\n}\n\n.Note h1:first-child,\n.Note h2:first-child,\n.Note h3:first-child,\n.Note h4:first-child,\n.Note h5:first-child,\n.Note h6:first-child {\n  margin-top: 0;\n}\n\nh1.title,\np.subtitle {\n  text-align: center;\n}\n\nh1.title.followed-by-subtitle {\n  margin-bottom: 0;\n}\n\np.subtitle {\n  font-size: 1.5em;\n  font-weight: 600;\n  line-height: 1.25;\n  margin-top: 0;\n  margin-bottom: 16px;\n  padding-bottom: 0.3em;\n}\n\ndiv.line-block {\n  white-space: pre-line;\n}\n\n/*# sourceMappingURL=GitHub.css.map */"
  },
  {
    "path": "pandoc5.css",
    "content": "/*! normalize.css v2.1.3 | MIT License | git.io/normalize */\n\n/* ==========================================================================\n   HTML5 display definitions\n   ========================================================================== */\n\n/**\n * Correct `block` display not defined in IE 8/9.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n    display: block;\n}\n\n/**\n * Correct `inline-block` display not defined in IE 8/9.\n */\n\naudio,\ncanvas,\nvideo {\n    display: inline-block;\n}\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n    display: none;\n    height: 0;\n}\n\n/**\n * Address `[hidden]` styling not present in IE 8/9.\n * Hide the `template` element in IE, Safari, and Firefox < 22.\n */\n\n[hidden],\ntemplate {\n    display: none;\n}\n\n/* ==========================================================================\n   Base\n   ========================================================================== */\n\n/**\n * 1. Set default font family to sans-serif.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n    font-family: sans-serif; /* 1 */\n    -ms-text-size-adjust: 100%; /* 2 */\n    -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/**\n * Remove default margin.\n */\n\nbody {\n    margin: 0;\n}\n\n/* ==========================================================================\n   Links\n   ========================================================================== */\n\n/**\n * Remove the gray background color from active links in IE 10.\n */\n\na {\n    background: transparent;\n}\n\n/**\n * Address `outline` inconsistency between Chrome and other browsers.\n */\n\na:focus {\n    outline: thin dotted;\n}\n\n/**\n * Improve readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n    outline: 0;\n}\n\n/* ==========================================================================\n   Typography\n   ========================================================================== */\n\n/**\n * Address variable `h1` font-size and margin within `section` and `article`\n * contexts in Firefox 4+, Safari 5, and Chrome.\n */\n\nh1 {\n    font-size: 2em;\n    margin: 0.67em 0;\n}\n\n/**\n * Address styling not present in IE 8/9, Safari 5, and Chrome.\n */\n\nabbr[title] {\n    border-bottom: 1px dotted;\n}\n\n/**\n * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.\n */\n\nb,\nstrong {\n    font-weight: bold;\n}\n\n/**\n * Address styling not present in Safari 5 and Chrome.\n */\n\ndfn {\n    font-style: italic;\n}\n\n/**\n * Address differences between Firefox and other browsers.\n */\n\nhr {\n    -moz-box-sizing: content-box;\n    box-sizing: content-box;\n    height: 0;\n}\n\n/**\n * Address styling not present in IE 8/9.\n */\n\nmark {\n    background: #ff0;\n    color: #000;\n}\n\n/**\n * Correct font family set oddly in Safari 5 and Chrome.\n */\n\ncode,\nkbd,\npre,\nsamp {\n    font-family: monospace, serif;\n    font-size: 1em;\n}\n\n/**\n * Improve readability of pre-formatted text in all browsers.\n */\n\npre {\n    white-space: pre-wrap;\n}\n\n/**\n * Set consistent quote types.\n */\n\nq {\n    quotes: \"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\";\n}\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\n\nsmall {\n    font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n    font-size: 75%;\n    line-height: 0;\n    position: relative;\n    vertical-align: baseline;\n}\n\nsup {\n    top: -0.5em;\n}\n\nsub {\n    bottom: -0.25em;\n}\n\n/* ==========================================================================\n   Embedded content\n   ========================================================================== */\n\n/**\n * Remove border when inside `a` element in IE 8/9.\n */\n\nimg {\n    border: 0;\n}\n\n/**\n * Correct overflow displayed oddly in IE 9.\n */\n\nsvg:not(:root) {\n    overflow: hidden;\n}\n\n/* ==========================================================================\n   Figures\n   ========================================================================== */\n\n/**\n * Address margin not present in IE 8/9 and Safari 5.\n */\n\nfigure {\n    margin: 0;\n}\n\n/* ==========================================================================\n   Forms\n   ========================================================================== */\n\n/**\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n    border: 1px solid #c0c0c0;\n    margin: 0 2px;\n    padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct `color` not being inherited in IE 8/9.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n    border: 0; /* 1 */\n    padding: 0; /* 2 */\n}\n\n/**\n * 1. Correct font family not being inherited in all browsers.\n * 2. Correct font size not being inherited in all browsers.\n * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.\n */\n\nbutton,\ninput,\nselect,\ntextarea {\n    font-family: inherit; /* 1 */\n    font-size: 100%; /* 2 */\n    margin: 0; /* 3 */\n}\n\n/**\n * Address Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\nbutton,\ninput {\n    line-height: normal;\n}\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.\n * Correct `select` style inheritance in Firefox 4+ and Opera.\n */\n\nbutton,\nselect {\n    text-transform: none;\n}\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n *    `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n    -webkit-appearance: button; /* 2 */\n    cursor: pointer; /* 3 */\n}\n\n/**\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\nhtml input[disabled] {\n    cursor: default;\n}\n\n/**\n * 1. Address box sizing set to `content-box` in IE 8/9/10.\n * 2. Remove excess padding in IE 8/9/10.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n    box-sizing: border-box; /* 1 */\n    padding: 0; /* 2 */\n}\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n    -webkit-appearance: textfield; /* 1 */\n    -moz-box-sizing: content-box;\n    -webkit-box-sizing: content-box; /* 2 */\n    box-sizing: content-box;\n}\n\n/**\n * Remove inner padding and search cancel button in Safari 5 and Chrome\n * on OS X.\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n    -webkit-appearance: none;\n}\n\n/**\n * Remove inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n    border: 0;\n    padding: 0;\n}\n\n/**\n * 1. Remove default vertical scrollbar in IE 8/9.\n * 2. Improve readability and alignment in all browsers.\n */\n\ntextarea {\n    overflow: auto; /* 1 */\n    vertical-align: top; /* 2 */\n}\n\n/* ==========================================================================\n   Tables\n   ========================================================================== */\n\n/**\n * Remove most spacing between table cells.\n */\n\ntable {\n    border-collapse: collapse;\n    border-spacing: 0;\n}\n\n.go-top {\nposition: fixed;\nbottom: 2em;\nright: 2em;\ntext-decoration: none;\nbackground-color: #E0E0E0;\nfont-size: 12px;\npadding: 1em;\ndisplay: inline;\n}\n\n/* Github css */\n\nhtml,body{        margin: auto;\n    padding-right: 1em;\n    padding-left: 1em;\n    max-width: 144em; color:black;}*:not('#mkdbuttons'){margin:0;padding:0}body{font:13.34px helvetica,arial,freesans,clean,sans-serif;-webkit-font-smoothing:subpixel-antialiased;line-height:1.4;padding:3px;background:#fff;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px}p{margin:1em 0}a{color:#4183c4;text-decoration:none}body{background-color:#fff;padding:30px;margin:15px;font-size:14px;line-height:1.6}body>*:first-child{margin-top:0!important}body>*:last-child{margin-bottom:0!important}@media screen{body{box-shadow:0 0 0 1px #cacaca,0 0 0 4px #eee}}h1,h2,h3,h4,h5,h6{margin:20px 0 10px;padding:0;font-weight:bold;-webkit-font-smoothing:subpixel-antialiased;cursor:text}h1{font-size:28px;color:#000}h2{font-size:24px;border-bottom:1px solid #ccc;color:#000}h3{font-size:18px;color:#333}h4{font-size:16px;color:#333}h5{font-size:14px;color:#333}h6{color:#777;font-size:14px}p,blockquote,table,pre{margin:15px 0}ul{padding-left:30px}ol{padding-left:30px}ol li ul:first-of-type{margin-top:0}hr{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;border:0 none;color:#ccc;height:4px;padding:0}body>h2:first-child{margin-top:0;padding-top:0}body>h1:first-child{margin-top:0;padding-top:0}body>h1:first-child+h2{margin-top:0;padding-top:0}body>h3:first-child,body>h4:first-child,body>h5:first-child,body>h6:first-child{margin-top:0;padding-top:0}a:first-child h1,a:first-child h2,a:first-child h3,a:first-child h4,a:first-child h5,a:first-child h6{margin-top:0;padding-top:0}h1+p,h2+p,h3+p,h4+p,h5+p,h6+p,ul li>:first-child,ol li>:first-child{margin-top:0}dl{padding:0}dl dt{font-size:14px;font-weight:bold;font-style:italic;padding:0;margin:15px 0 5px}dl dt:first-child{padding:0}dl dt>:first-child{margin-top:0}dl dt>:last-child{margin-bottom:0}dl dd{margin:0 0 15px;padding:0 15px}dl dd>:first-child{margin-top:0}dl dd>:last-child{margin-bottom:0}blockquote{border-left:4px solid #DDD;padding:0 15px;color:#777}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}table{border-collapse:collapse;border-spacing:0;font-size:100%;font:inherit}table th{font-weight:bold;border:1px solid #ccc;padding:6px 13px}table td{border:1px solid #ccc;padding:6px 13px}table tr{border-top:1px solid #ccc;background-color:#fff}table tr:nth-child(2n){background-color:#f8f8f8}img{max-width:100%}code,tt{margin:0 2px;padding:0 5px;white-space:nowrap;border:1px solid #eaeaea;background-color:#f8f8f8;border-radius:3px;font-family:Consolas,'Liberation Mono',Courier,monospace;font-size:12px;color:#333}pre>code{margin:0;padding:0;white-space:pre;border:0;background:transparent}.highlight pre{background-color:#f8f8f8;border:1px solid #ccc;font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px}pre{background-color:#f8f8f8;border:1px solid #ccc;font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px}pre code,pre tt{background-color:transparent;border:0}.poetry pre{font-family:Georgia,Garamond,serif!important;font-style:italic;font-size:110%!important;line-height:1.6em;display:block;margin-left:1em}.poetry pre code{font-family:Georgia,Garamond,serif!important;word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-moz-hyphens:auto;hyphens:auto;white-space:pre-wrap}sup,sub,a.footnote{font-size:1.4ex;height:0;line-height:1;vertical-align:super;position:relative}sub{vertical-align:sub;top:-1px}@media print{body{background:#fff}img,pre,blockquote,table,figure{page-break-inside:avoid}body{background:#fff;border:0}code{background-color:#fff;color:#333!important;padding:0 .2em;border:1px solid #dedede}pre{background:#fff}pre code{background-color:white!important;overflow:visible}}@media screen{body.inverted{color:#eee!important;border-color:#555;box-shadow:none}.inverted body,.inverted hr .inverted p,.inverted td,.inverted li,.inverted h1,.inverted h2,.inverted h3,.inverted h4,.inverted h5,.inverted h6,.inverted th,.inverted .math,.inverted caption,.inverted dd,.inverted dt,.inverted blockquote{color:#eee!important;border-color:#555;box-shadow:none}.inverted td,.inverted th{background:#333}.inverted h2{border-color:#555}.inverted hr{border-color:#777;border-width:1px!important}::selection{background:rgba(157,193,200,0.5)}h1::selection{background-color:rgba(45,156,208,0.3)}h2::selection{background-color:rgba(90,182,224,0.3)}h3::selection,h4::selection,h5::selection,h6::selection,li::selection,ol::selection{background-color:rgba(133,201,232,0.3)}code::selection{background-color:rgba(0,0,0,0.7);color:#eee}code span::selection{background-color:rgba(0,0,0,0.7)!important;color:#eee!important}a::selection{background-color:rgba(255,230,102,0.2)}.inverted a::selection{background-color:rgba(255,230,102,0.6)}td::selection,th::selection,caption::selection{background-color:rgba(180,237,95,0.5)}.inverted{background:#0b2531;background:#252a2a}.inverted body{background:#252a2a}.inverted a{color:#acd1d5}}.highlight .c{color:#998;font-style:italic}.highlight .err{color:#a61717;background-color:#e3d2d2}.highlight .k,.highlight .o{font-weight:bold}.highlight .cm{color:#998;font-style:italic}.highlight .cp{color:#999;font-weight:bold}.highlight .c1{color:#998;font-style:italic}.highlight .cs{color:#999;font-weight:bold;font-style:italic}.highlight .gd{color:#000;background-color:#fdd}.highlight .gd .x{color:#000;background-color:#faa}.highlight .ge{font-style:italic}.highlight .gr{color:#a00}.highlight .gh{color:#999}.highlight .gi{color:#000;background-color:#dfd}.highlight .gi .x{color:#000;background-color:#afa}.highlight .go{color:#888}.highlight .gp{color:#555}.highlight .gs{font-weight:bold}.highlight .gu{color:#800080;font-weight:bold}.highlight .gt{color:#a00}.highlight .kc,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr{font-weight:bold}.highlight .kt{color:#458;font-weight:bold}.highlight .m{color:#099}.highlight .s{color:#d14}.highlight .na{color:#008080}.highlight .nb{color:#0086b3}.highlight .nc{color:#458;font-weight:bold}.highlight .no{color:#008080}.highlight .ni{color:#800080}.highlight .ne,.highlight .nf{color:#900;font-weight:bold}.highlight .nn{color:#555}.highlight .nt{color:#000080}.highlight .nv{color:#008080}.highlight .ow{font-weight:bold}.highlight .w{color:#bbb}.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:#099}.highlight .sb,.highlight .sc,.highlight .sd,.highlight .s2,.highlight .se,.highlight .sh,.highlight .si,.highlight .sx{color:#d14}.highlight .sr{color:#009926}.highlight .s1{color:#d14}.highlight .ss{color:#990073}.highlight .bp{color:#999}.highlight .vc,.highlight .vg,.highlight .vi{color:#008080}.highlight .il{color:#099}.highlight .gc{color:#999;background-color:#eaf2f5}.type-csharp .highlight .k,.type-csharp .highlight .kt{color:#00F}.type-csharp .highlight .nf{color:#000;font-weight:normal}.type-csharp .highlight .nc{color:#2b91af}.type-csharp .highlight .nn{color:#000}.type-csharp .highlight .s,.type-csharp .highlight .sc{color:#a31515}"
  },
  {
    "path": "pandoc6.css",
    "content": "/* For smart quotes */\nq { quotes: \"“\" \"”\" \"‘\" \"’\"; }\n\n/* Override section behavior.\n * We only want the top-level <section> to have padding.\n * This makes it easier to work with --section-divs. */\nsection {\n  padding-top: initial;\n  padding-bottom: initial;\n}\narticle > section {\n  padding-top: 1rem;\n  padding-bottom: 1rem;\n}\n\n/* Make byline (date and/or author) small */\np.byline { font-size: 1.2rem; }\n\n\n/* Simulate Pandoc's table output styles */\ntable {\n  border-top: 2px solid black;\n  border-bottom: 2px solid black;\n}\nth {\n  border-bottom: 1px solid black;\n}\ntd, th {\n  font-size: 1.4rem;\n  padding: 10px;\n  text-align: left;\n}\n\n/* Allow tables to be full width\n * if they're wrapped in a figure.fullwidth\n * (Easier to insert from Pandoc than manually adding table) */\nfigure.fullwidth table {\n  width: 90%;\n}\n\n@media (max-width: 760px) {\n  figure.fullwidth table {\n    width: 100%;\n  }\n}\n\n/* Code blocks\n *\n * Code blocks with a language look like div.sourceCode > pre.sourceCode\n * Otherwise, it's just a pre (without .sourceCode) */\ndiv.sourceCode,\npre:not(.sourceCode) {\n  padding: 1.4rem;\n  margin: -0.7rem -1.4rem;\n  width: 55%;\n  font-size: 0.9rem;\n  overflow-x: auto;\n}\n\ndiv.sourceCode code,\npre:not(.sourceCode) code {\n  font-size: 0.9rem;\n}\n\n.fullwidth div.sourceCode,\n.fullwidth pre:not(.sourceCode) {\n  width: 100%;\n}\n\n@media (max-width: 760px) {\n  div.sourceCode,\n  pre:not(.sourceCode) {\n    width: 100%;\n  }\n}\n\n/* Math formatting */\n.katex {\n  font-size: inherit !important;\n}\n\n/* Wrap long URLs in references */\n#refs a {\n  word-wrap: break-word;\n  overflow-wrap: break-word;\n}"
  },
  {
    "path": "pymitter.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n\n\"\"\"\npymitter\nPython port of the extended Node.js EventEmitter 2 approach providing\nnamespaces, wildcards and TTL.\n\"\"\"\n\n\n__author__     = \"Marcel Rieger\"\n__copyright__  = \"Copyright 2014, Marcel Rieger\"\n__credits__    = [\"Marcel Rieger\"]\n__license__    = \"MIT\"\n__maintainer__ = \"Marcel Rieger\"\n__status__     = \"Development\"\n__version__    = \"0.2.3\"\n__all__        = [\"EventEmitter\"]\n\n\n# python imports\nfrom time import time\n\n\nclass EventEmitter(object):\n\n    __CBKEY  = \"__callbacks\"\n    __WCCHAR = \"*\"\n\n    def __init__(self, **kwargs):\n        \"\"\" EventEmitter(wildcard=False, delimiter=\".\", new_listener=False,\n                         max_listeners=-1)\n        The EventEmitter class.\n        Please always use *kwargs* in the constructor.\n        - *wildcard*: When *True*, wildcards are used.\n        - *delimiter*: The delimiter to seperate event namespaces.\n        - *new_listener*: When *True*, the \"new_listener\" event is emitted every\n          time a new listener is registered with arguments *(func, event=None)*.\n        - *max_listeners*: Maximum number of listeners per event. Negativ values\n          mean infinity.\n        \"\"\"\n        super(EventEmitter, self).__init__()\n\n        self.wildcard      = kwargs.get(\"wildcard\", False)\n        self.__delimiter   = kwargs.get(\"delimiter\", \".\")\n        self.new_listener  = kwargs.get(\"new_listener\", False)\n        self.max_listeners = kwargs.get(\"max_listeners\", -1)\n\n        self.__tree = self.__new_branch()\n\n    @property\n    def delimiter(self):\n        \"\"\"\n        *delimiter* getter.\n        \"\"\"\n        return self.__delimiter\n\n    @classmethod\n    def __new_branch(cls):\n        \"\"\"\n        Returns a new branch. Basically, a branch is just a dictionary with\n        a special item *__CBKEY* that holds registered functions. All other\n        items are used to build a tree structure.\n        \"\"\"\n        return { cls.__CBKEY: [] }\n\n    def __find_branch(self, event):\n        \"\"\"\n        Returns a branch of the tree stucture that matches *event*. Wildcards\n        are not applied.\n        \"\"\"\n        parts = event.split(self.delimiter)\n\n        if self.__CBKEY in parts:\n            return None\n\n        branch = self.__tree\n        for p in parts:\n            if p not in branch:\n                return None\n            branch = branch[p]\n\n        return branch\n\n    @classmethod\n    def __remove_listener(cls, branch, func):\n        \"\"\"\n        Removes a listener given by its function from a branch.\n        \"\"\"\n        listeners = branch[cls.__CBKEY]\n\n        indexes = [i for i, l in enumerate(listeners) if l.func == func]\n        indexes.reverse()\n\n        for i in indexes:\n            listeners.pop(i)\n\n    @classmethod\n    def __remove_all_listeners(cls, branch):\n        \"\"\"\n        Removes a listener given by its function from a branch.\n        \"\"\"\n        listeners = branch[cls.__CBKEY]\n\n        indexes = [i for i, l in enumerate(listeners)]\n        indexes.reverse()\n\n        for i in indexes:\n            listeners.pop(i)\n\n    def on(self, event, func=None, ttl=-1):\n        \"\"\"\n        Registers a function to an event. When *func* is *None*, decorator\n        usage is assumed. *ttl* defines the times to listen. Negative values\n        mean infinity. Returns the function.\n        \"\"\"\n        def _on(func):\n            if not hasattr(func, \"__call__\"):\n                return func\n\n            parts = event.split(self.delimiter)\n\n            if self.__CBKEY in parts:\n                return func\n\n            branch = self.__tree\n            for p in parts:\n                branch = branch.setdefault(p, self.__new_branch())\n\n            listeners = branch[self.__CBKEY]\n\n            if 0 <= self.max_listeners <= len(listeners):\n                return func\n\n            listener = Listener(func, event, ttl)\n            listeners.append(listener)\n\n            if self.new_listener:\n                self.emit(\"new_listener\", func, event)\n\n            return func\n\n        if func is not None:\n            return _on(func)\n        else:\n            return _on\n\n    def once(self, *args, **kwargs):\n        \"\"\"\n        Registers a function to an event with *ttl = 1*. See *on*. Returns the\n        function.\n        \"\"\"\n        if len(args) == 3:\n            args[2] = 1\n        else:\n            kwargs[\"ttl\"] = 1\n        return self.on(*args, **kwargs)\n\n    def on_any(self, func=None):\n        \"\"\"\n        Registers a function that is called every time an event is emitted.\n        When *func* is *None*, decorator usage is assumed. Returns the function.\n        \"\"\"\n        def _on_any(func):\n            if not hasattr(func, \"__call__\"):\n                return func\n\n            listeners = self.__tree[self.__CBKEY]\n\n            if 0 <= self.max_listeners <= len(listeners):\n                return func\n\n            listener = Listener(func, None, -1)\n            listeners.append(listener)\n\n            if self.new_listener:\n                self.emit(\"new_listener\", func)\n\n            return func\n\n        if func is not None:\n            return _on_any(func)\n        else:\n            return _on_any\n\n\n    def clear_listeners(self, event):\n        branch = self.__find_branch(event)\n        if branch is None:\n            return\n        self.__remove_all_listeners(branch)\n\n\n    def off(self, event, func=None):\n        \"\"\"\n        Removes a function that is registered to an event. When *func* is\n        *None*, decorator usage is assumed. Returns the function.\n        \"\"\"\n        def _off(func):\n            branch = self.__find_branch(event)\n            if branch is None:\n                return func\n\n            self.__remove_listener(branch, func)\n\n            return func\n\n        if func is not None:\n            return _off(func)\n        else:\n            return _off\n\n    def off_any(self, func=None):\n        \"\"\"\n        Removes a function that was registered via *on_any*. When *func* is\n        *None*, decorator usage is assumed. Returns the function.\n        \"\"\"\n        def _off_any(func):\n            self.__remove_listener(self.__tree, func)\n\n            return func\n\n        if func is not None:\n            return _off_any(func)\n        else:\n            return _off_any\n\n    def off_all(self):\n        \"\"\"\n        Removes all registerd functions.\n        \"\"\"\n        del self.__tree\n        self.__tree = self.__new_branch()\n\n    def listeners(self, event):\n        \"\"\"\n        Returns all functions that are registered to an event. Wildcards are not\n        applied.\n        \"\"\"\n        branch = self.__find_branch(event)\n        if branch is None:\n            return []\n\n        return [l.func for l in branch[self.__CBKEY]]\n\n    def listeners_any(self):\n        \"\"\"\n        Returns all functions that were registered using *on_any*.\n        \"\"\"\n        return [l.func for l in self.__tree[self.__CBKEY]]\n\n    def listeners_all(self):\n        \"\"\"\n        Returns all registered functions.\n        \"\"\"\n        listeners = self.__tree[self.__CBKEY][:]\n\n        branches = self.__tree.values()\n        for b in branches:\n            if not isinstance(b, dict):\n                continue\n\n            branches.extend(b.values())\n\n            listeners.extend(b[self.__CBKEY])\n\n        return [l.func for l in listeners]\n\n    def emit(self, event, *args, **kwargs):\n        \"\"\"\n        Emits an event. All functions of events that match *event* are invoked\n        with *args* and *kwargs* in the exact order of their registration.\n        Wildcards might be applied.\n        \"\"\"\n        parts = event.split(self.delimiter)\n\n        if self.__CBKEY in parts:\n            return\n\n        listeners = self.__tree[self.__CBKEY][:]\n\n        branches = [self.__tree]\n\n        for p in parts:\n            _branches = []\n            for branch in branches:\n                for k, b in branch.items():\n                    if k == self.__CBKEY:\n                        continue\n                    if k == p:\n                        _branches.append(b)\n                    elif self.wildcard:\n                        if p == self.__WCCHAR or k == self.__WCCHAR:\n                            _branches.append(b)\n            branches = _branches\n\n        for b in branches:\n            listeners.extend(b[self.__CBKEY])\n\n        listeners.sort(key=lambda l: l.time)\n\n        remove = [l for l in listeners if not l(*args, **kwargs)]\n\n        for l in remove:\n            self.off(l.event, func=l.func)\n\n\nclass Listener(object):\n\n    def __init__(self, func, event, ttl):\n        \"\"\"\n        The Listener class.\n        Listener instances are simple structs to handle functions and their ttl\n        values.\n        \"\"\"\n        super(Listener, self).__init__()\n\n        self.func  = func\n        self.event = event\n        self.ttl   = ttl\n\n        self.time = time()\n\n    def __call__(self, *args, **kwargs):\n        \"\"\"\n        Invokes the wrapped function. If the ttl value is non-negative, it is\n        decremented by 1. In this case, returns *False* if the ttl value\n        approached 0. Returns *True* otherwise.\n        \"\"\"\n        self.func(*args, **kwargs)\n\n        if self.ttl > 0:\n            self.ttl -= 1\n            if self.ttl == 0:\n                return False\n\n        return True\n\n\n\n\neventEmitter = EventEmitter()\n\ndef Get():\n    return eventEmitter\n\ndef EmitIf(onDone):\n    if(onDone):\n        eventEmitter.emit(onDone)\n\ndef EmitIfParams(onDone,**kwargs):\n    if(onDone):\n        eventEmitter.emit(onDone,kwargs)\n\nimport OrgExtended.orgutil.util as util\n\ndef Make(func):\n    eventName = util.RandomString()\n    eventEmitter.once(eventName, func)\n    return eventName\n"
  },
  {
    "path": "readtheorg/htmlize.css",
    "content": ".org-bold { /* bold */ font-weight: bold; }\n.org-bold-italic { /* bold-italic */ font-weight: bold; font-style: italic; }\n.org-buffer-menu-buffer { /* buffer-menu-buffer */ font-weight: bold; }\n.org-builtin { /* font-lock-builtin-face */ color: #7a378b; }\n.org-button { /* button */ text-decoration: underline; }\n.org-calendar-today { /* calendar-today */ text-decoration: underline; }\n.org-change-log-acknowledgement { /* change-log-acknowledgement */ color: #b22222; }\n.org-change-log-conditionals { /* change-log-conditionals */ color: #a0522d; }\n.org-change-log-date { /* change-log-date */ color: #8b2252; }\n.org-change-log-email { /* change-log-email */ color: #a0522d; }\n.org-change-log-file { /* change-log-file */ color: #0000ff; }\n.org-change-log-function { /* change-log-function */ color: #a0522d; }\n.org-change-log-list { /* change-log-list */ color: #a020f0; }\n.org-change-log-name { /* change-log-name */ color: #008b8b; }\n.org-comint-highlight-input { /* comint-highlight-input */ font-weight: bold; }\n.org-comint-highlight-prompt { /* comint-highlight-prompt */ color: #00008b; }\n.org-comment { /* font-lock-comment-face */ color: #999988; font-style: italic; }\n.org-comment-delimiter { /* font-lock-comment-delimiter-face */ color: #999988; font-style: italic; }\n.org-completions-annotations { /* completions-annotations */ font-style: italic; }\n.org-completions-common-part { /* completions-common-part */ color: #000000; background-color: #ffffff; }\n.org-completions-first-difference { /* completions-first-difference */ font-weight: bold; }\n.org-constant { /* font-lock-constant-face */ color: #008b8b; }\n.org-diary { /* diary */ color: #ff0000; }\n.org-diff-context { /* diff-context */ color: #7f7f7f; }\n.org-diff-file-header { /* diff-file-header */ background-color: #b3b3b3; font-weight: bold; }\n.org-diff-function { /* diff-function */ background-color: #cccccc; }\n.org-diff-header { /* diff-header */ background-color: #cccccc; }\n.org-diff-hunk-header { /* diff-hunk-header */ background-color: #cccccc; }\n.org-diff-index { /* diff-index */ background-color: #b3b3b3; font-weight: bold; }\n.org-diff-nonexistent { /* diff-nonexistent */ background-color: #b3b3b3; font-weight: bold; }\n.org-diff-refine-change { /* diff-refine-change */ background-color: #d9d9d9; }\n.org-dired-directory { /* dired-directory */ color: #0000ff; }\n.org-dired-flagged { /* dired-flagged */ color: #ff0000; font-weight: bold; }\n.org-dired-header { /* dired-header */ color: #228b22; }\n.org-dired-ignored { /* dired-ignored */ color: #7f7f7f; }\n.org-dired-mark { /* dired-mark */ color: #008b8b; }\n.org-dired-marked { /* dired-marked */ color: #ff0000; font-weight: bold; }\n.org-dired-perm-write { /* dired-perm-write */ color: #b22222; }\n.org-dired-symlink { /* dired-symlink */ color: #a020f0; }\n.org-dired-warning { /* dired-warning */ color: #ff0000; font-weight: bold; }\n.org-doc { /* font-lock-doc-face */ color: #8b2252; }\n.org-escape-glyph { /* escape-glyph */ color: #a52a2a; }\n.org-file-name-shadow { /* file-name-shadow */ color: #7f7f7f; }\n.org-flyspell-duplicate { /* flyspell-duplicate */ color: #cdad00; font-weight: bold; text-decoration: underline; }\n.org-flyspell-incorrect { /* flyspell-incorrect */ color: #ff4500; font-weight: bold; text-decoration: underline; }\n.org-fringe { /* fringe */ background-color: #f2f2f2; }\n.org-function-name { /* font-lock-function-name-face */ color: teal; }\n.org-header-line { /* header-line */ color: #333333; background-color: #e5e5e5; }\n.org-help-argument-name { /* help-argument-name */ font-style: italic; }\n.org-highlight { /* highlight */ background-color: #b4eeb4; }\n.org-holiday { /* holiday */ background-color: #ffc0cb; }\n.org-isearch { /* isearch */ color: #b0e2ff; background-color: #cd00cd; }\n.org-isearch-fail { /* isearch-fail */ background-color: #ffc1c1; }\n.org-italic { /* italic */ font-style: italic; }\n.org-keyword { /* font-lock-keyword-face */ color: #0086b3; }\n.org-lazy-highlight { /* lazy-highlight */ background-color: #afeeee; }\n.org-link { /* link */ color: #0000ff; text-decoration: underline; }\n.org-link-visited { /* link-visited */ color: #8b008b; text-decoration: underline; }\n.org-log-edit-header { /* log-edit-header */ color: #a020f0; }\n.org-log-edit-summary { /* log-edit-summary */ color: #0000ff; }\n.org-log-edit-unknown-header { /* log-edit-unknown-header */ color: #b22222; }\n.org-match { /* match */ background-color: #ffff00; }\n.org-next-error { /* next-error */ background-color: #eedc82; }\n.org-nobreak-space { /* nobreak-space */ color: #a52a2a; text-decoration: underline; }\n.org-org-archived { /* org-archived */ color: #7f7f7f; }\n.org-org-block { /* org-block */ color: #7f7f7f; }\n.org-org-block-begin-line { /* org-block-begin-line */ color: #b22222; }\n.org-org-block-end-line { /* org-block-end-line */ color: #b22222; }\n.org-org-checkbox { /* org-checkbox */ font-weight: bold; }\n.org-org-checkbox-statistics-done { /* org-checkbox-statistics-done */ color: #228b22; font-weight: bold; }\n.org-org-checkbox-statistics-todo { /* org-checkbox-statistics-todo */ color: #ff0000; font-weight: bold; }\n.org-org-clock-overlay { /* org-clock-overlay */ background-color: #ffff00; }\n.org-org-code { /* org-code */ color: #7f7f7f; }\n.org-org-column { /* org-column */ background-color: #e5e5e5; }\n.org-org-column-title { /* org-column-title */ background-color: #e5e5e5; font-weight: bold; text-decoration: underline; }\n.org-org-date { /* org-date */ color: #a020f0; text-decoration: underline; }\n.org-org-document-info { /* org-document-info */ color: #191970; }\n.org-org-document-info-keyword { /* org-document-info-keyword */ color: #7f7f7f; }\n.org-org-document-title { /* org-document-title */ color: #191970; font-size: 144%; font-weight: bold; }\n.org-org-done { /* org-done */ color: #228b22; font-weight: bold; }\n.org-org-drawer { /* org-drawer */ color: #0000ff; }\n.org-org-ellipsis { /* org-ellipsis */ color: #b8860b; text-decoration: underline; }\n.org-org-footnote { /* org-footnote */ color: #a020f0; text-decoration: underline; }\n.org-org-formula { /* org-formula */ color: #b22222; }\n.org-org-headline-done { /* org-headline-done */ color: #bc8f8f; }\n.org-org-hide { /* org-hide */ color: #ffffff; }\n.org-org-latex-and-export-specials { /* org-latex-and-export-specials */ color: #8b4513; }\n.org-org-level-1 { /* org-level-1 */ color: #0000ff; }\n.org-org-level-2 { /* org-level-2 */ color: #a0522d; }\n.org-org-level-3 { /* org-level-3 */ color: #a020f0; }\n.org-org-level-4 { /* org-level-4 */ color: #b22222; }\n.org-org-level-5 { /* org-level-5 */ color: #228b22; }\n.org-org-level-6 { /* org-level-6 */ color: #008b8b; }\n.org-org-level-7 { /* org-level-7 */ color: #7a378b; }\n.org-org-level-8 { /* org-level-8 */ color: #8b2252; }\n.org-org-link { /* org-link */ color: #0000ff; text-decoration: underline; }\n.org-org-meta-line { /* org-meta-line */ color: #b22222; }\n.org-org-mode-line-clock { /* org-mode-line-clock */ color: #000000; background-color: #bfbfbf; }\n.org-org-mode-line-clock-overrun { /* org-mode-line-clock-overrun */ color: #000000; background-color: #ff0000; }\n.org-org-quote { /* org-quote */ color: #7f7f7f; }\n.org-org-scheduled { /* org-scheduled */ color: #006400; }\n.org-org-scheduled-previously { /* org-scheduled-previously */ color: #b22222; }\n.org-org-scheduled-today { /* org-scheduled-today */ color: #006400; }\n.org-org-sexp-date { /* org-sexp-date */ color: #a020f0; }\n.org-org-special-keyword { /* org-special-keyword */ color: #a020f0; }\n.org-org-table { /* org-table */ color: #0000ff; }\n.org-org-tag { /* org-tag */ font-weight: bold; }\n.org-org-target { /* org-target */ text-decoration: underline; }\n.org-org-time-grid { /* org-time-grid */ color: #b8860b; }\n.org-org-todo { /* org-todo */ color: #ff0000; font-weight: bold; }\n.org-org-upcoming-deadline { /* org-upcoming-deadline */ color: #b22222; }\n.org-org-verbatim { /* org-verbatim */ color: #7f7f7f; }\n.org-org-verse { /* org-verse */ color: #7f7f7f; }\n.org-org-warning { /* org-warning */ color: #ff0000; font-weight: bold; }\n.org-outline-1 { /* outline-1 */ color: #0000ff; }\n.org-outline-2 { /* outline-2 */ color: #a0522d; }\n.org-outline-3 { /* outline-3 */ color: #a020f0; }\n.org-outline-4 { /* outline-4 */ color: #b22222; }\n.org-outline-5 { /* outline-5 */ color: #228b22; }\n.org-outline-6 { /* outline-6 */ color: #008b8b; }\n.org-outline-7 { /* outline-7 */ color: #7a378b; }\n.org-outline-8 { /* outline-8 */ color: #8b2252; }\n.org-preprocessor { /* font-lock-preprocessor-face */ color: #7a378b; }\n.org-query-replace { /* query-replace */ color: #b0e2ff; background-color: #cd00cd; }\n.org-regexp-grouping-backslash { /* font-lock-regexp-grouping-backslash */ font-weight: bold; }\n.org-regexp-grouping-construct { /* font-lock-regexp-grouping-construct */ font-weight: bold; }\n.org-region { /* region */ background-color: #eedc82; }\n.org-secondary-selection { /* secondary-selection */ background-color: #ffff00; }\n.org-shadow { /* shadow */ color: #7f7f7f; }\n.org-show-paren-match { /* show-paren-match */ background-color: #40e0d0; }\n.org-show-paren-mismatch { /* show-paren-mismatch */ color: #ffffff; background-color: #a020f0; }\n.org-string { /* font-lock-string-face */ color: #dd1144; }\n.org-tool-bar { /* tool-bar */ color: #000000; background-color: #bfbfbf; }\n.org-tooltip { /* tooltip */ color: #000000; background-color: #ffffe0; }\n.org-trailing-whitespace { /* trailing-whitespace */ background-color: #ff0000; }\n.org-type { /* font-lock-type-face */ color: #228b22; }\n.org-underline { /* underline */ text-decoration: underline; }\n.org-variable-name { /* font-lock-variable-name-face */ color: teal; }\n.org-warning { /* font-lock-warning-face */ color: #ff0000; font-weight: bold; }\n.org-widget-button { /* widget-button */ font-weight: bold; }\n.org-widget-button-pressed { /* widget-button-pressed */ color: #ff0000; }\n.org-widget-documentation { /* widget-documentation */ color: #006400; }\n.org-widget-field { /* widget-field */ background-color: #d9d9d9; }\n.org-widget-inactive { /* widget-inactive */ color: #7f7f7f; }\n.org-widget-single-line-field { /* widget-single-line-field */ background-color: #d9d9d9; }\n"
  },
  {
    "path": "readtheorg/readtheorg.css",
    "content": "@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic|Roboto+Slab:400,700|Inconsolata:400,700);\n@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css);\n\nh1,h2,h3,h4,h5,h6,legend{\n    font-family:\"Roboto Slab\",\"ff-tisa-web-pro\",\"Georgia\",Arial,sans-serif;\n    font-weight:700;\n    margin-top:0;\n}\n\nh1{\n    font-size:175%;\n}\n\n.subtitle{\n    font-size:95%; /* of h1 */\n}\n\nh2{\n    font-size:150%;\n}\n\nh3{\n    font-size:125%;\n}\n\nh4{\n    font-size:115%;\n}\n\nh5{\n    font-size:110%;\n}\n\nh6{\n    font-size:100%;\n}\n\nh4,h5,h6{\n    color:#2980B9;\n    font-weight:300;\n}\n\nhtml{\n    -ms-text-size-adjust:100%;\n    -webkit-text-size-adjust:100%;\n    font-size:100%;\n    height:100%;\n    overflow-x:hidden;\n}\n\nbody{\n    background:#edf0f2;\n    color:#404040;\n    font-family:\"Lato\",\"proxima-nova\",\"Helvetica Neue\",Arial,sans-serif;\n    font-weight:normal;\n    margin:0;\n    min-height:100%;\n    overflow-x:hidden;\n}\n\n#content{\n    background:#fcfcfc;\n    height:100%;\n    margin-left:300px;\n    /* margin:auto; */\n    max-width:800px;\n    min-height:100%;\n    padding:1.618em 3.236em;\n}\n\np{\n    font-size:16px;\n    line-height:24px;\n    margin:0px 0px 24px 0px;\n}\n\nb,strong{\n    font-weight:bold}\n\nblockquote{\n    background-color: #F0F0F0;\n    border-left:5px solid #CCCCCC;\n    font-style:italic;\n    line-height:24px;\n    margin:0px 0px 24px 0px;\n    /* margin-left:24px; */\n    padding: 6px 20px;\n}\n\nul,ol,dl{\n    line-height:24px;\n    list-style-image:none;\n    /* list-style:none; */\n    margin:0px 0px 24px 0px;\n    padding:0;\n}\n\nli{\n    margin-left: 24px;\n}\n\ndd{\n    margin:0;\n}\n\n#content .section ul,#content .toctree-wrapper ul,article ul{\n    list-style:disc;\n    line-height:24px;\n    margin-bottom:24px}\n\n#content .section ul li,#content .toctree-wrapper ul li,article ul li{\n    list-style:disc;\n    margin-left:24px}\n\n#content .section ul li p:last-child,#content .toctree-wrapper ul li p:last-child,article ul li p:last-child{\n                                                                                                                                  margin-bottom:0}\n\n#content .section ul li ul,#content .toctree-wrapper ul li ul,article ul li ul{\n    margin-bottom:0}\n\n#content .section ul li li,#content .toctree-wrapper ul li li,article ul li li{\n    list-style:circle}\n\n#content .section ul li li li,#content .toctree-wrapper ul li li li,article ul li li li{\n    list-style:square}\n\n#content .section ul li ol li,#content .toctree-wrapper ul li ol li,article ul li ol li{\n    list-style:decimal}\n\n#content .section ol,#content ol,article ol{\n    list-style:decimal;\n    line-height:24px;\n    margin-bottom:24px}\n\n#content .section ol li,#content ol li,article ol li{\n    list-style:decimal;\n    margin-left:24px}\n\n#content .section ol li p:last-child,#content ol li p:last-child,article ol li p:last-child{\n                                                                                                                           margin-bottom:0}\n\n#content .section ol li ul,#content ol li ul,article ol li ul{\n    margin-bottom:0}\n\n#content .section ol li ul li,#content ol li ul li,article ol li ul li{\n    list-style:disc}\n\ndl dt{\n    font-weight:bold;\n}\n\ndl p,dl table,dl ul,dl ol{\n    margin-bottom:12px !important;\n}\n\ndl dd{\n    margin:0 0 12px 24px;\n}\n\n@media print{\n    .codeblock,pre.src{\n        white-space:pre.src-wrap}\n}\n\n@media print{\n    html,body,section{\n        background:none !important}\n\n    *{\n        box-shadow:none !important;\n        text-shadow:none !important;\n        filter:none !important;\n        -ms-filter:none !important}\n\n    a,a:visited{\n          text-decoration:underline}\n\n    pre.src,blockquote{\n        page-break-inside:avoid}\n\n    thead{\n        display:table-header-group}\n\n    tr,img{\n        page-break-inside:avoid}\n\n    img{\n        max-width:100% !important}\n\n    @page{\n        margin:0.5cm}\n\n    p,h2,h3{\n        orphans:3;\n        widows:3}\n\n    h2,h3{\n        page-break-after:avoid}\n}\n\n@media print{\n    #postamble{\n        display:none}\n\n    #content{\n        margin-left:0}\n}\n\n@media print{\n    #table-of-contents{\n        display:none}\n\n    @page{\n        size: auto;\n        margin: 25mm 25mm 25mm 25mm;}\n\n    body {\n        margin: 0px;}\n}\n\n@media screen and (max-width: 768px){\n}\n\n@media only screen and (max-width: 480px){\n}\n\n@media screen and (max-width: 768px){\n    .tablet-hide{\n        display:none}\n}\n\n@media screen and (max-width: 480px){\n    .mobile-hide{\n        display:none}\n}\n\n@media screen and (max-width: 480px){\n}\n\n@media screen and (max-width: 768px){\n    #content{\n        margin-left:0}\n\n    #content #content{\n        padding:1.618em}\n\n    #content.shift{\n        position:fixed;\n        min-width:100%;\n        left:85%;\n        top:0;\n        height:100%;\n        overflow:hidden}\n}\n\n@media screen and (min-width: 1400px){\n    #content{\n        background:rgba(0,0,0,0.05)}\n\n    #content{\n        background:#fcfcfc}\n}\n\n@media screen and (max-width: 768px){\n    #copyright{\n        width:85%;\n        display:none}\n\n    #copyright.shift{\n        display:block}\n\n    img{\n        width:100%;\n        height:auto}\n}\n\n@media screen and (max-width: 480px){\n    #content .sidebar{\n        width:100%}\n}\n\ncode{\n    background:#fff;\n    border:solid 1px #e1e4e5;\n    /* color:#000;  for clickable code */\n    font-family:Consolas,\"Andale Mono WT\",\"Andale Mono\",\"Lucida Console\",\"Lucida Sans Typewriter\",\"DejaVu Sans Mono\",\"Bitstream Vera Sans Mono\",\"Liberation Mono\",\"Nimbus Mono L\",Monaco,\"Courier New\",Courier,monospace;\n    font-size:75%;\n    max-width:100%;\n    overflow-x:auto;\n    padding:0 5px;\n    white-space:nowrap;\n}\n\n.codeblock-example{\n    border:1px solid #e1e4e5;\n    border-bottom:none;\n    padding:24px;\n    padding-top:48px;\n    font-weight:500;\n    background:#fff;\n    position:relative}\n\n.codeblock-example:after{\n    content:\"Example\";\n    position:absolute;\n    top:0px;\n    left:0px;\n    background:#9B59B6;\n    color:#fff;\n    padding:6px 12px}\n\n.codeblock-example.prettyprint-example-only{\n    border:1px solid #e1e4e5;\n    margin-bottom:24px}\n\n.codeblock,pre.src,#content .literal-block{\n    border:1px solid #e1e4e5;\n    padding:12px;\n    overflow-x:auto;\n    background:#fff;\n    margin:1px 0 24px 0}\n\npre.src{\n    /* color:#404040; */\n    display:block;\n    font-family:Consolas,\"Andale Mono WT\",\"Andale Mono\",\"Lucida Console\",\"Lucida Sans Typewriter\",\"DejaVu Sans Mono\",\"Bitstream Vera Sans Mono\",\"Liberation Mono\",\"Nimbus Mono L\",Monaco,\"Courier New\",Courier,monospace;\n    font-size:12px;\n    line-height:1.5;\n    margin:1px 0px 24px 0px;\n    overflow:auto;\n    padding:12px;\n    white-space:pre;\n}\n\n.example{\n    background:#f3f6f6;\n    border:1px solid #e1e4e5;\n    color:#404040;\n    font-size: 12px;\n    line-height: 1.5;\n    margin-bottom:24px;\n    padding:12px;\n}\n\ntable{\n    border-collapse:collapse;\n    border-spacing:0;\n    empty-cells:show;\n    margin-bottom:24px;\n    border-bottom:1px solid #e1e4e5;\n}\n\ntd{\n    vertical-align:top}\n\ntable td,table th{\n    font-size:90%;\n    margin:0;\n    overflow:visible;\n    padding:8px 16px;\n    background-color:white;\n    border:1px solid #e1e4e5;\n}\n\ntable thead th{\n    font-weight:bold;\n    border-top:3px solid #e1e4e5;\n    border-bottom:1px solid #e1e4e5;\n}\n\ntable caption{\n    color:#000;\n    font:italic 85%/1 arial,sans-serif;\n    padding:1em 0;\n}\n\ntable tr:nth-child(2n-1) td{\n    background-color:#f3f6f6;\n}\n\ntable tr:nth-child(2n) td{\n    background-color:white;\n}\n\n.figure p{\n    color:#000;\n    font:italic 85%/1 arial,sans-serif;\n    padding:1em 0;\n}\n\n.rotate-90{\n    -webkit-transform:rotate(90deg);\n    -moz-transform:rotate(90deg);\n    -ms-transform:rotate(90deg);\n    -o-transform:rotate(90deg);\n    transform:rotate(90deg);\n}\n\n.rotate-270{\n    -webkit-transform:rotate(270deg);\n    -moz-transform:rotate(270deg);\n    -ms-transform:rotate(270deg);\n    -o-transform:rotate(270deg);\n    transform:rotate(270deg);\n}\n\n#toggle-sidebar,\n#table-of-contents .close-sidebar {\n    display: none;\n}\n\n@media screen and (max-width: 768px) {\n    #table-of-contents {\n        display: none;\n        width: 60%;\n    }\n\n    #table-of-contents h2 a {\n        display: block;\n    }\n\n    #table-of-contents:target {\n        display: block;\n    }\n\n    #copyright, #postamble {\n        display: none;\n    }\n\n    #toggle-sidebar {\n        background-color: #2980B9;\n        display: block;\n        margin-bottom: 1.6em;\n        padding: 0.6em;\n        text-align: center;\n    }\n\n    #toggle-sidebar h2 {\n        background-color:#2980B9;\n        width:100%;\n        height:50px;\n        left:0;\n        top:0;\n        color: white;\n        font-size: 100%;\n        line-height: 50px;\n        position:fixed;\n        margin: 0;\n        padding: 0;\n        opacity:0.7;\n        z-index: 10;\n    }\n\n    #table-of-contents .close-sidebar {\n       color: rgba(255, 255, 255, 0.3);\n       display: inline-block;\n       margin: 0px 10px 0px 45px;\n       padding: 10px;\n    }\n}\n\n*{\n    -webkit-box-sizing:border-box;\n    -moz-box-sizing:border-box;\n    box-sizing:border-box;\n}\n\nfigcaption,figure,footer,header,hgroup,nav{\n    display:block}\n\nins{\n    background:#ff9;\n    color:#000;\n    text-decoration:none}\n\nmark{\n    background:#ff0;\n    color:#000;\n    font-style:italic;\n    font-weight:bold}\n\nsmall{\n    font-size:85%}\n\nsub,sup{\n    font-size:75%;\n    line-height:0;\n    position:relative;\n    vertical-align:baseline}\n\nsup{\n    top:-0.5em}\n\nsub{\n    bottom:-0.25em}\n\nimg{\n    -ms-interpolation-mode:bicubic;\n    vertical-align:middle;\n    max-width:100%}\n\nsvg:not(:root){\n    overflow:hidden}\n\nfigure{\n    margin:0}\n\nlabel{\n    cursor:pointer}\n\nlegend{\n    border:0;\n    margin-left:-7px;\n    padding:0;\n    white-space:normal}\n\n.fa:before,#content .admonition-title:before,#content h1 .headerlink:before,#content h2 .headerlink:before,#content h3 .headerlink:before,#content h4 .headerlink:before,#content h5 .headerlink:before,#content h6 .headerlink:before,#content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,#content .note,#content .attention,#content .caution,#content .danger,#content .error,#content .hint,#content .important,#content .tip,#content .warning,#content .seealso,#content .admonitiontodo,.btn,input[type=\"text\"],input[type=\"password\"],input[type=\"email\"],input[type=\"url\"],input[type=\"date\"],input[type=\"month\"],input[type=\"time\"],input[type=\"datetime\"],input[type=\"datetime-local\"],input[type=\"week\"],input[type=\"number\"],input[type=\"search\"],input[type=\"tel\"],input[type=\"color\"],select,textarea,#table-of-contents li.on a,#table-of-contents li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{\n    -webkit-font-smoothing:antialiased}\n\n/*!\n *  Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */@font-face{\n    font-family:'FontAwesome';\n    src:url(\"../fonts/fontawesome-webfont.eot?v=4.1.0\");\n    src:url(\"../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0\") format(\"embedded-opentype\"),url(\"../fonts/fontawesome-webfont.woff?v=4.1.0\") format(\"woff\"),url(\"../fonts/fontawesome-webfont.ttf?v=4.1.0\") format(\"truetype\"),url(\"../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular\") format(\"svg\");\n    font-weight:normal;\n    font-style:normal}\n\n.fa,#content .admonition-title,.icon{\n    display:inline-block;\n    font-family:FontAwesome;\n    font-style:normal;\n    font-weight:normal;\n    line-height:1;\n    -webkit-font-smoothing:antialiased;\n    -moz-osx-font-smoothing:grayscale}\n\n.fa-ul{\n    padding-left:0;\n    margin-left:2.14286em;\n    list-style-type:none}\n\n.fa-ul>li{\n    position:relative}\n\n.fa-li{\n    position:absolute;\n    left:-2.14286em;\n    width:2.14286em;\n    top:0.14286em;\n    text-align:center}\n\n.fa-li.fa-lg{\n    left:-1.85714em}\n\n.fa-border{\n    padding:.2em .25em .15em;\n    border:solid 0.08em #eee;\n    border-radius:.1em}\n\n.fa,#content .admonition-title{\n    font-family:inherit}\n\n.fa:before,#content .admonition-title:before{\n    font-family:\"FontAwesome\";\n    display:inline-block;\n    font-style:normal;\n    font-weight:normal;\n    line-height:1;\n    text-decoration:inherit}\n\na .fa,a #content .admonition-title,#content a .admonition-title{\n    display:inline-block;\n    text-decoration:inherit}\n\n.nav #content .admonition-title,#content .nav .admonition-title,.nav .icon{\n    display:inline}\n\n.wy-alert,#content .note,#content .attention,#content .caution,#content .danger,#content .error,#content .hint,#content .important,#content .tip,#content .warning,#content .seealso,#content .admonitiontodo{\n    padding:12px;\n    line-height:24px;\n    margin-bottom:24px;\n    /* background:#e7f2fa; */\n}\n\n.wy-alert-title,#content .admonition-title{\n    color:#fff;\n    font-weight:bold;\n    display:block;\n    color:#fff;\n    /* background:#6ab0de; */\n    /* margin:-12px; */\n    padding:6px 12px;\n    margin-bottom:0px}\n\n#content .danger,#content .error{\n    background:#fdf3f2}\n\n.wy-alert.wy-alert-warning,#content .wy-alert-warning.note,#content .attention,#content .caution,#content .wy-alert-warning.danger,#content .wy-alert-warning.error,#content .wy-alert-warning.hint,#content .wy-alert-warning.important,#content .wy-alert-warning.tip,#content .warning,#content .wy-alert-warning.seealso,#content .admonitiontodo{\n    background:#ffedcc}\n\n#content .admonition-title.note:before, #content .admonition-title.seealso:before,\n#content .admonition-title.warning:before, #content .admonition-title.caution:before,\n#content .admonition-title.attention:before,\n#content .admonition-title.tip:before, #content .admonition-title.hint:before,\n#content .admonition-title.important:before,\n#content .admonition-title.error:before, #content .admonition-title.danger:before{\n    font-family:FontAwesome;\n    content: \"\";}\n\n#content .note,#content .seealso{\n    background:#e7f2fa}\n\n.wy-alert p:last-child,#content .note p:last-child,#content .attention p:last-child,#content .caution p:last-child,#content .danger p:last-child,#content .error p:last-child,#content .hint p:last-child,#content .important p:last-child,#content .tip p:last-child,#content .warning p:last-child,#content .seealso p:last-child,#content .admonitiontodo p:last-child{\n    margin-bottom:0}\n\n#content .admonition-title.tip,#content .admonition-title.important,#content .admonition-title.hint{\n    line-height: 1;\n    background:#1abc9c}\n\n#content .important,#content .tip,#content .hint{\n    background:#dbfaf4}\n\n#content .admonition-title.note,#content .admonition-title.seealso{\n    line-height: 1;\n    background:#6ab0de}\n\n#content .admonition-title.warning,#content .admonition-title.caution,#content .admonition-title.attention{\n    line-height: 1;\n    background:#F0B37E}\n\n#content .admonition-title.error,#content .admonition-title.danger{\n    line-height: 1;\n    background:#f29f97}\n\nlegend{\n    display:block;\n    width:100%;\n    border:0;\n    padding:0;\n    white-space:normal;\n    margin-bottom:24px;\n    font-size:150%;\n    *margin-left:-7px}\n\nlabel{\n    display:block;\n    margin:0 0 0.3125em 0;\n    color:#333;\n    font-size:90%}\n\na{\n    color:#2980B9;\n    text-decoration:none;\n    cursor:pointer}\n\n\na:hover,a:active{\n    outline:0;\n}\n\na:hover{\n    color:#3091d1}\n\na:visited{\n    color:#9B59B6}\n\n.left{\n    text-align:left}\n\n.center{\n    text-align:center}\n\n.right{\n    text-align:right}\n\nhr{\n    display:block;\n    height:1px;\n    border:0;\n    border-top:1px solid #e1e4e5;\n    margin:24px 0;\n    padding:0}\n\n#table-of-contents li{\n    list-style:none;\n    margin-left: 0px;\n}\n\n#table-of-contents header{\n    height:32px;\n    display:inline-block;\n    line-height:32px;\n    padding:0 1.618em;\n    display:block;\n    font-weight:bold;\n    text-transform:uppercase;\n    font-size:80%;\n    color:#2980B9;\n    white-space:nowrap}\n\n#table-of-contents ul{\n    margin-bottom:0}\n\n#table-of-contents li.divide-top{\n    border-top:solid 1px #404040}\n\n#table-of-contents li.divide-bottom{\n    border-bottom:solid 1px #404040}\n\n#table-of-contents li.current{\n    background:#e3e3e3}\n\n#table-of-contents li.current a{\n    color:gray;\n    border-right:solid 1px #c9c9c9;\n    padding:0.4045em 2.427em}\n\n#table-of-contents li.current a:hover{\n    background:#d6d6d6}\n\n#table-of-contents li a{\n    /* color:#404040; */\n    padding:0.4045em 1.618em;\n    position:relative;\n    /* background:#fcfcfc; */\n    border:none;\n    /* border-bottom:solid 1px #c9c9c9; */\n    /* border-top:solid 1px #c9c9c9; */\n    padding-left:1.618em -4px}\n\n#table-of-contents li.on a:hover,#table-of-contents li.current>a:hover{\n    background:#fcfcfc}\n\n#table-of-contents li ul li a{\n    /* background:#c9c9c9; */\n    padding:0.4045em 2.427em}\n\n#table-of-contents li ul li ul li a{\n    padding:0.4045em 3.236em}\n\n#table-of-contents li.current ul{\n    display:block}\n\n/* #table-of-contents li ul{ */\n/*     margin-bottom:0; */\n/*     display:none} */\n\n#table-of-contents .local-toc li ul{\n    display:block}\n\n#table-of-contents li ul li a{\n    margin-bottom:0;\n    color:#b3b3b3;\n    font-weight:normal}\n\n#table-of-contents a{\n    display:inline-block;\n    line-height:18px;\n    padding:0.4045em 1.618em;\n    display:block;\n    position:relative;\n    font-size:90%;\n    color:#b3b3b3;\n    direction: ltr;\n}\n\n#table-of-contents a:hover{\n    background-color:#4e4a4a;\n    cursor:pointer}\n\n/* #text-table-of-contents { */\n/*     overflow:scroll; */\n/* } */\n\n#table-of-contents{\n    position:fixed;\n    top:0;\n    left:0;\n    width:300px;\n    overflow-x:hidden;\n    overflow-y:scroll;\n    height:100%;\n    background:#343131;\n    z-index:200;\n    scrollbar-base-color: #1F1D1D;\n    scrollbar-arrow-color: #b3b3b3;\n    scrollbar-shadow-color: #1F1D1D;\n    scrollbar-track-color : #343131;\n}\n\n#table-of-contents h2{\n    z-index:200;\n    background-color:#2980B9;\n    text-align:center;\n    padding:0.809em;\n    display:block;\n    color:#fcfcfc;\n    font-size: 100%;\n    margin-bottom:0.809em}\n\nul.nav li ul li {\n    display: none;\n}\n\nul.nav li ul li ul li {\n    display: none;\n}\n\nul.nav li.active ul li {\n    display: inline;\n}\n\nul.nav li.active ul li ul li {\n    display: inline;\n}\n\nul.nav li.active ul li a {\n    background-color: #E3E3E3;\n    color: #8099B0;\n    border-right:solid 1px #c9c9c9 !important;\n}\n\nul.nav li.active ul li.active a {\n    background-color: #C9C9C9;\n    color: black !important;\n    font-weight: bold !important;\n}\n\nul.nav li.active ul li.active ul li.active a {\n    color: black !important;\n    font-weight: bold !important;\n    display: block !important;\n}\n\nul.nav li.active ul li.active ul li a {\n    color: #808080 !important;\n    font-weight: normal !important;\n    display: block !important;\n}\n\nul.nav li.active ul li ul li a {\n    display: none !important;\n}\n\n/* ul.nav li ul li ul li { */\n/*     display: none !important; /\\* as long as nav is on multiple levels of ul *\\/ */\n/*     /\\* display: none; /\\* as long as nav is on multiple levels of ul *\\\\/ *\\/ */\n/* } */\n\nul.nav li ul li ul li ul li {\n    display: none !important; /* as long as nav is on multiple levels of ul */\n    /* display: none; /* as long as nav is on multiple levels of ul *\\/ */\n}\n\nul.nav li.active > a {\n    border-bottom:solid 1px #c9c9c9 !important; /* XXX Restrict it to 2nd level */\n    border-right:solid 1px #c9c9c9 !important;\n}\n\nul.nav li.active a {\n    color: gray !important;\n    font-weight:bold;\n    background-color: white;\n    border-right:solid 0px white !important;\n}\n\nul.nav > li.active > a {\n    color: black !important;\n}\n\nfooter{\n    color:#999}\n\nfooter p{\n    margin-bottom:12px}\n\n#copyright, #postamble{\n    position:fixed;\n    bottom:0;\n    left:0;\n    width:300px;\n    color:#fcfcfc;\n    background:#1f1d1d;\n    border-top:solid 10px #343131;\n    font-family:\"Lato\",\"proxima-nova\",\"Helvetica Neue\",Arial,sans-serif;\n    font-size: 90%;\n    z-index:400;\n    padding:12px;\n}\n\n#postamble .author {\n    font-size: 100%;\n    margin-bottom: 0px;\n}\n\n#postamble .date {\n    font-size: 90%;\n    margin-bottom: 0px;\n    color: #27AE60;\n}\n\n#postamble .creator,#postamble .validation {\n    display:none;\n}\n\n#copyright a{\n    color:#2980B9;\n    text-decoration:none}\n\n#copyright .rst-current-version{\n    padding:12px;\n    background-color:#272525;\n    display:block;\n    text-align:right;\n    font-size:90%;\n    cursor:pointer;\n    color:#27AE60;\n    *zoom:1}\n\n#content img{\n    max-width:100%;\n}\n\n#content div.figure{\n    margin-bottom:24px}\n\n#content div.figure.align-center{\n    text-align:center}\n\n#content .section>img,#content .section>a>img{\n    margin-bottom:24px}\n\n.verse{\n    border-left:5px solid #6AB0DE;\n    background-color: #E7F2FA;\n    padding: 6px 20px;\n    font-style:italic;\n}\n\n#content .note .last,#content .attention .last,#content .caution .last,#content .danger .last,#content .error .last,#content .hint .last,#content .important .last,#content .tip .last,#content .warning .last,#content .seealso .last,#content .admonitiontodo .last{\n    margin-bottom:0}\n\n#content .admonition-title:before{\n    margin-right:4px}\n\n#content .section ol p,#content .section ul p{\n    margin-bottom:12px}\n\n#content h1 .headerlink,#content h2 .headerlink,#content h3 .headerlink,#content h4 .headerlink,#content h5 .headerlink,#content h6 .headerlink,#content dl dt .headerlink{\n    display:none;\n    visibility:hidden;\n    font-size:14px}\n\n#content h1 .headerlink:after,#content h2 .headerlink:after,#content h3 .headerlink:after,#content h4 .headerlink:after,#content h5 .headerlink:after,#content h6 .headerlink:after,#content dl dt .headerlink:after{\n    visibility:visible;\n    content:\"\";\n    font-family:FontAwesome;\n    display:inline-block}\n\n#content h1:hover .headerlink,#content h2:hover .headerlink,#content h3:hover .headerlink,#content h4:hover .headerlink,#content h5:hover .headerlink,#content h6:hover .headerlink,#content dl dt:hover .headerlink{\n    display:inline-block}\n\n#content .sidebar{\n    float:right;\n    width:40%;\n    display:block;\n    margin:0 0 24px 24px;\n    padding:24px;\n    background:#f3f6f6;\n    border:solid 1px #e1e4e5}\n\n#content .sidebar p,#content .sidebar ul,#content .sidebar dl{\n    font-size:90%}\n\n#content .sidebar .last{\n    margin-bottom:0}\n\n#content .sidebar .sidebar-title{\n    display:block;\n    font-family:\"Roboto Slab\",\"ff-tisa-web-pro\",\"Georgia\",Arial,sans-serif;\n    font-weight:bold;\n    background:#e1e4e5;\n    padding:6px 12px;\n    margin:-24px;\n    margin-bottom:24px;\n    font-size:100%}\n\n#content .highlighted{\n    background:#F1C40F;\n    display:inline-block;\n    font-weight:bold;\n    padding:0 6px}\n\n#content .footnote-reference,#content .citation-reference{\n    vertical-align:super;\n    font-size:90%}\n\nspan[id*='MathJax-Span']{\n    color:#404040}\n\n.math{\n    text-align:center}\n\n#footnotes{\n    border-top:1px solid #e1e4e5;\n    padding-top: 36px;\n}\n\nh2.footnotes{\n    display:none;\n}\n\n.footnum, .footref{\n    color: #2980b9;\n    font-size: 170%;\n    font-family:\"Lato\",\"proxima-nova\",\"Helvetica Neue\",Arial,sans-serif;\n}\n\n.footnum:before, .footref:before{\n    content:\"[\";\n}\n\n.footnum:after, .footref:after{\n    content:\"]\";\n}\n\n.footpara {\n    color: #999;\n    font-size: 90%;\n    font-family:\"Lato\",\"proxima-nova\",\"Helvetica Neue\",Arial,sans-serif;\n    padding-bottom: 8px;\n    padding-left: 16px;\n    padding-right: 16px;\n    padding-top: 8px;\n    line-height: 1.25em;\n    /* display: inline; */\n}\n\n.todo{\n    background-color: #f29f97;\n    padding: 0px 4px;\n    color: #fff;\n}\n\n.WAIT, .nilWAIT{\n    background-color: #6AB097;\n}\n\n.done{\n    background-color: #6ab0de;\n    padding: 0px 4px;\n    color: #fff;\n}\n\n.tag span {\n    background-color: #EDEDED;\n    border: 1px solid #EDEDED;\n    color: #939393;\n    cursor: pointer;\n    display: block;\n    float: right;\n    font-size: 80%;\n    font-weight: normal;\n    margin: 0 3px;\n    padding: 1px 2px;\n    border-radius: 10px;\n}\n\n.tag .FLAGGED {\n    background-color: #DB2D27;\n    border: 1px solid #DB2D27;\n    color: white;\n    font-weight: bold;\n}\n\n.timestamp {\n    font-family: Consolas,\"Andale Mono WT\",\"Andale Mono\",\"Lucida Console\",\"Lucida Sans Typewriter\",\"DejaVu Sans Mono\",\"Bitstream Vera Sans Mono\",\"Liberation Mono\",\"Nimbus Mono L\",Monaco,\"Courier New\",Courier,monospace;\n    font-size: 90%;\n    color: navy;\n}\n\n.nav .timestamp {\n    color: inherit;\n}\n\n.inlinetask {\n    background: #FFF9E3;  /* url(dialog-todo.png) no-repeat 10px 8px; */\n    border: 3px solid #FFEB8E;\n    /* border-right-style: none; */\n    /* border-left-style: none; */\n    /* padding: 10px 20px 10px 60px; */\n    padding: 9px 12px;\n    margin-bottom: 24px;\n    font-family:\"Roboto Slab\",\"ff-tisa-web-pro\",\"Georgia\",Arial,sans-serif}\n"
  },
  {
    "path": "readtheorg/readtheorg.js",
    "content": "$(function() {\n    $('.note').before(\"<p class='admonition-title note'>Note</p>\");\n    $('.seealso').before(\"<p class='admonition-title seealso'>See also</p>\");\n    $('.warning').before(\"<p class='admonition-title warning'>Warning</p>\");\n    $('.caution').before(\"<p class='admonition-title caution'>Caution</p>\");\n    $('.attention').before(\"<p class='admonition-title attention'>Attention</p>\");\n    $('.tip').before(\"<p class='admonition-title tip'>Tip</p>\");\n    $('.important').before(\"<p class='admonition-title important'>Important</p>\");\n    $('.hint').before(\"<p class='admonition-title hint'>Hint</p>\");\n    $('.error').before(\"<p class='admonition-title error'>Error</p>\");\n    $('.danger').before(\"<p class='admonition-title danger'>Danger</p>\");\n});\n\n$( document ).ready(function() {\n\n    // Shift nav in mobile when clicking the menu.\n    $(document).on('click', \"[data-toggle='wy-nav-top']\", function() {\n      $(\"[data-toggle='wy-nav-shift']\").toggleClass(\"shift\");\n      $(\"[data-toggle='rst-versions']\").toggleClass(\"shift\");\n    });\n    // Close menu when you click a link.\n    $(document).on('click', \".wy-menu-vertical .current ul li a\", function() {\n      $(\"[data-toggle='wy-nav-shift']\").removeClass(\"shift\");\n      $(\"[data-toggle='rst-versions']\").toggleClass(\"shift\");\n    });\n    $(document).on('click', \"[data-toggle='rst-current-version']\", function() {\n      $(\"[data-toggle='rst-versions']\").toggleClass(\"shift-up\");\n    });\n    // Make tables responsive\n    $(\"table.docutils:not(.field-list)\").wrap(\"<div class='wy-table-responsive'></div>\");\n});\n\n$( document ).ready(function() {\n    $('#text-table-of-contents ul').first().addClass('nav');\n                                        // ScrollSpy also requires that we use\n                                        // a Bootstrap nav component.\n    $('body').scrollspy({target: '#text-table-of-contents'});\n\n    // DON'T add sticky table headers (Fix issue #69?)\n    // $('table').stickyTableHeaders();\n\n    // set the height of tableOfContents\n    var $postamble = $('#postamble');\n    var $tableOfContents = $('#table-of-contents');\n    $tableOfContents.css({paddingBottom: $postamble.outerHeight()});\n\n    // add TOC button\n    var toggleSidebar = $('<div id=\"toggle-sidebar\"><a href=\"#table-of-contents\"><h2>Table of Contents</h2></a></div>');\n    $('#content').prepend(toggleSidebar);\n\n    // add close button when sidebar showed in mobile screen\n    var closeBtn = $('<a class=\"close-sidebar\" href=\"#\">Close</a>');\n    var tocTitle = $('#table-of-contents').find('h2');\n    tocTitle.append(closeBtn);\n});\n\nwindow.SphinxRtdTheme = (function (jquery) {\n    var stickyNav = (function () {\n        var navBar,\n            win,\n            stickyNavCssClass = 'stickynav',\n            applyStickNav = function () {\n                if (navBar.height() <= win.height()) {\n                    navBar.addClass(stickyNavCssClass);\n                } else {\n                    navBar.removeClass(stickyNavCssClass);\n                }\n            },\n            enable = function () {\n                applyStickNav();\n                win.on('resize', applyStickNav);\n            },\n            init = function () {\n                navBar = jquery('nav.wy-nav-side:first');\n                win    = jquery(window);\n            };\n        jquery(init);\n        return {\n            enable : enable\n        };\n    }());\n    return {\n        StickyNav : stickyNav\n    };\n}($));\n"
  },
  {
    "path": "readtheorg/rtd-full.css",
    "content": "﻿*{\n    -webkit-box-sizing:border-box;\n    -moz-box-sizing:border-box;\n    box-sizing:border-box}\n\narticle,aside,details,figcaption,figure,footer,header,hgroup,nav,section{\n    display:block}\n\naudio,canvas,video{\n    display:inline-block;\n    *display:inline;\n    *zoom:1}\n\naudio:not([controls]){\n    display:none}\n\n[hidden]{\n    display:none}\n\n*{\n    -webkit-box-sizing:border-box;\n    -moz-box-sizing:border-box;\n    box-sizing:border-box}\n\nhtml{\n    font-size:100%;\n    -webkit-text-size-adjust:100%;\n    -ms-text-size-adjust:100%}\n\nbody{\n    margin:0}\n\na:hover,a:active{\n            outline:0}\n\nabbr[title]{\n    border-bottom:1px dotted}\n\nb,strong{\n    font-weight:bold}\n\nblockquote{\n    margin:0}\n\ndfn{\n    font-style:italic}\n\nins{\n    background:#ff9;\n    color:#000;\n    text-decoration:none}\n\nmark{\n    background:#ff0;\n    color:#000;\n    font-style:italic;\n    font-weight:bold}\n\npre,code,.rst-content tt,kbd,samp{\n    font-family:monospace,serif;\n    _font-family:\"courier new\",monospace;\n    font-size:1em}\n\npre{\n    white-space:pre}\n\nq{\n    quotes:none}\n\nq:before,q:after{\n             content:\"\";\n             content:none}\n\nsmall{\n    font-size:85%}\n\nsub,sup{\n    font-size:75%;\n    line-height:0;\n    position:relative;\n    vertical-align:baseline}\n\nsup{\n    top:-0.5em}\n\nsub{\n    bottom:-0.25em}\n\nul,ol,dl{\n    margin:0;\n    padding:0;\n    list-style:none;\n    list-style-image:none}\n\nli{\n    list-style:none}\n\ndd{\n    margin:0}\n\nimg{\n    border:0;\n    -ms-interpolation-mode:bicubic;\n    vertical-align:middle;\n    max-width:100%}\n\nsvg:not(:root){\n    overflow:hidden}\n\nfigure{\n    margin:0}\n\nform{\n    margin:0}\n\nfieldset{\n    border:0;\n    margin:0;\n    padding:0}\n\nlabel{\n    cursor:pointer}\n\nlegend{\n    border:0;\n    *margin-left:-7px;\n    padding:0;\n    white-space:normal}\n\nbutton,input,select,textarea{\n    font-size:100%;\n    margin:0;\n    vertical-align:baseline;\n    *vertical-align:middle}\n\nbutton,input{\n    line-height:normal}\n\nbutton,input[type=\"button\"],input[type=\"reset\"],input[type=\"submit\"]{\n    cursor:pointer;\n    -webkit-appearance:button;\n    *overflow:visible}\n\nbutton[disabled],input[disabled]{\n    cursor:default}\n\ninput[type=\"checkbox\"],input[type=\"radio\"]{\n    box-sizing:border-box;\n    padding:0;\n    *width:13px;\n    *height:13px}\n\ninput[type=\"search\"]{\n    -webkit-appearance:textfield;\n    -moz-box-sizing:content-box;\n    -webkit-box-sizing:content-box;\n    box-sizing:content-box}\n\ninput[type=\"search\"]::-webkit-search-decoration,input[type=\"search\"]::-webkit-search-cancel-button{\n    -webkit-appearance:none}\n\nbutton::-moz-focus-inner,input::-moz-focus-inner{\n    border:0;\n    padding:0}\n\ntextarea{\n    overflow:auto;\n    vertical-align:top;\n    resize:vertical}\n\ntable{\n    border-collapse:collapse;\n    border-spacing:0}\n\ntd{\n    vertical-align:top}\n\n.chromeframe{\n    margin:0.2em 0;\n    background:#ccc;\n    color:#000;\n    padding:0.2em 0}\n\n.ir{\n    display:block;\n    border:0;\n    text-indent:-999em;\n    overflow:hidden;\n    background-color:transparent;\n    background-repeat:no-repeat;\n    text-align:left;\n    direction:ltr;\n    *line-height:0}\n\n.ir br{\n    display:none}\n\n.hidden{\n    display:none !important;\n    visibility:hidden}\n\n.visuallyhidden{\n    border:0;\n    clip:rect(0 0 0 0);\n    height:1px;\n    margin:-1px;\n    overflow:hidden;\n    padding:0;\n    position:absolute;\n    width:1px}\n\n.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{\n    clip:auto;\n    height:auto;\n    margin:0;\n    overflow:visible;\n    position:static;\n    width:auto}\n\n.invisible{\n    visibility:hidden}\n\n.relative{\n    position:relative}\n\nbig,small{\n    font-size:100%}\n\n@media print{\n    html,body,section{\n        background:none !important}\n\n    *{\n        box-shadow:none !important;\n        text-shadow:none !important;\n        filter:none !important;\n        -ms-filter:none !important}\n\n    a,a:visited{\n          text-decoration:underline}\n\n    .ir a:after,a[href^=\"javascript:\"]:after,a[href^=\"#\"]:after{\n                                                 content:\"\"}\n\n    pre,blockquote{\n        page-break-inside:avoid}\n\n    thead{\n        display:table-header-group}\n\n    tr,img{\n        page-break-inside:avoid}\n\n    img{\n        max-width:100% !important}\n\n    @page{\n        margin:0.5cm}\n\n    p,h2,h3{\n        orphans:3;\n        widows:3}\n\n    h2,h3{\n        page-break-after:avoid}\n\n}\n\n.fa:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.btn,input[type=\"text\"],input[type=\"password\"],input[type=\"email\"],input[type=\"url\"],input[type=\"date\"],input[type=\"month\"],input[type=\"time\"],input[type=\"datetime\"],input[type=\"datetime-local\"],input[type=\"week\"],input[type=\"number\"],input[type=\"search\"],input[type=\"tel\"],input[type=\"color\"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{\n    -webkit-font-smoothing:antialiased}\n\n.clearfix{\n    *zoom:1}\n\n.clearfix:before,.clearfix:after{\n    display:table;\n    content:\"\"}\n\n.clearfix:after{\n    clear:both}\n\n/*!\n *  Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */@font-face{\n    font-family:'FontAwesome';\n    src:url(\"../fonts/fontawesome-webfont.eot?v=4.1.0\");\n    src:url(\"../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0\") format(\"embedded-opentype\"),url(\"../fonts/fontawesome-webfont.woff?v=4.1.0\") format(\"woff\"),url(\"../fonts/fontawesome-webfont.ttf?v=4.1.0\") format(\"truetype\"),url(\"../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular\") format(\"svg\");\n    font-weight:normal;\n    font-style:normal}\n\n.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon{\n    display:inline-block;\n    font-family:FontAwesome;\n    font-style:normal;\n    font-weight:normal;\n    line-height:1;\n    -webkit-font-smoothing:antialiased;\n    -moz-osx-font-smoothing:grayscale}\n\n.fa-lg{\n    font-size:1.33333em;\n    line-height:0.75em;\n    vertical-align:-15%}\n\n.fa-2x{\n    font-size:2em}\n\n.fa-3x{\n    font-size:3em}\n\n.fa-4x{\n    font-size:4em}\n\n.fa-5x{\n    font-size:5em}\n\n.fa-fw{\n    width:1.28571em;\n    text-align:center}\n\n.fa-ul{\n    padding-left:0;\n    margin-left:2.14286em;\n    list-style-type:none}\n\n.fa-ul>li{\n    position:relative}\n\n.fa-li{\n    position:absolute;\n    left:-2.14286em;\n    width:2.14286em;\n    top:0.14286em;\n    text-align:center}\n\n.fa-li.fa-lg{\n    left:-1.85714em}\n\n.fa-border{\n    padding:.2em .25em .15em;\n    border:solid 0.08em #eee;\n    border-radius:.1em}\n\n.pull-right{\n    float:right}\n\n.pull-left{\n    float:left}\n\n.fa.pull-left,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.pull-left.icon{\n    margin-right:.3em}\n\n.fa.pull-right,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.pull-right.icon{\n    margin-left:.3em}\n\n.fa-spin{\n    -webkit-animation:spin 2s infinite linear;\n    -moz-animation:spin 2s infinite linear;\n    -o-animation:spin 2s infinite linear;\n    animation:spin 2s infinite linear}\n\n@-moz-keyframes spin{\n    0%{\n        -moz-transform:rotate(0deg)}\n\n    100%{\n        -moz-transform:rotate(359deg)}\n\n}\n\n@-webkit-keyframes spin{\n    0%{\n        -webkit-transform:rotate(0deg)}\n\n    100%{\n        -webkit-transform:rotate(359deg)}\n\n}\n\n@-o-keyframes spin{\n    0%{\n        -o-transform:rotate(0deg)}\n\n    100%{\n        -o-transform:rotate(359deg)}\n\n}\n\n@keyframes spin{\n    0%{\n        -webkit-transform:rotate(0deg);\n        transform:rotate(0deg)}\n\n    100%{\n        -webkit-transform:rotate(359deg);\n        transform:rotate(359deg)}\n\n}\n\n.fa-rotate-90{\n    filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n    -webkit-transform:rotate(90deg);\n    -moz-transform:rotate(90deg);\n    -ms-transform:rotate(90deg);\n    -o-transform:rotate(90deg);\n    transform:rotate(90deg)}\n\n.fa-rotate-180{\n    filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n    -webkit-transform:rotate(180deg);\n    -moz-transform:rotate(180deg);\n    -ms-transform:rotate(180deg);\n    -o-transform:rotate(180deg);\n    transform:rotate(180deg)}\n\n.fa-rotate-270{\n    filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n    -webkit-transform:rotate(270deg);\n    -moz-transform:rotate(270deg);\n    -ms-transform:rotate(270deg);\n    -o-transform:rotate(270deg);\n    transform:rotate(270deg)}\n\n.fa-flip-horizontal{\n    filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);\n    -webkit-transform:scale(-1, 1);\n    -moz-transform:scale(-1, 1);\n    -ms-transform:scale(-1, 1);\n    -o-transform:scale(-1, 1);\n    transform:scale(-1, 1)}\n\n.fa-flip-vertical{\n    filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n    -webkit-transform:scale(1, -1);\n    -moz-transform:scale(1, -1);\n    -ms-transform:scale(1, -1);\n    -o-transform:scale(1, -1);\n    transform:scale(1, -1)}\n\n.fa-stack{\n    position:relative;\n    display:inline-block;\n    width:2em;\n    height:2em;\n    line-height:2em;\n    vertical-align:middle}\n\n.fa-stack-1x,.fa-stack-2x{\n    position:absolute;\n    left:0;\n    width:100%;\n    text-align:center}\n\n.fa-stack-1x{\n    line-height:inherit}\n\n.fa-stack-2x{\n    font-size:2em}\n\n.fa-inverse{\n    color:#fff}\n\n.fa-glass:before{\n    content:\"\"}\n\n.fa-music:before{\n    content:\"\"}\n\n.fa-search:before,.icon-search:before{\n    content:\"\"}\n\n.fa-envelope-o:before{\n    content:\"\"}\n\n.fa-heart:before{\n    content:\"\"}\n\n.fa-star:before{\n    content:\"\"}\n\n.fa-star-o:before{\n    content:\"\"}\n\n.fa-user:before{\n    content:\"\"}\n\n.fa-film:before{\n    content:\"\"}\n\n.fa-th-large:before{\n    content:\"\"}\n\n.fa-th:before{\n    content:\"\"}\n\n.fa-th-list:before{\n    content:\"\"}\n\n.fa-check:before{\n    content:\"\"}\n\n.fa-times:before{\n    content:\"\"}\n\n.fa-search-plus:before{\n    content:\"\"}\n\n.fa-search-minus:before{\n    content:\"\"}\n\n.fa-power-off:before{\n    content:\"\"}\n\n.fa-signal:before{\n    content:\"\"}\n\n.fa-gear:before,.fa-cog:before{\n    content:\"\"}\n\n.fa-trash-o:before{\n    content:\"\"}\n\n.fa-home:before,.icon-home:before{\n    content:\"\"}\n\n.fa-file-o:before{\n    content:\"\"}\n\n.fa-clock-o:before{\n    content:\"\"}\n\n.fa-road:before{\n    content:\"\"}\n\n.fa-download:before{\n    content:\"\"}\n\n.fa-arrow-circle-o-down:before{\n    content:\"\"}\n\n.fa-arrow-circle-o-up:before{\n    content:\"\"}\n\n.fa-inbox:before{\n    content:\"\"}\n\n.fa-play-circle-o:before{\n    content:\"\"}\n\n.fa-rotate-right:before,.fa-repeat:before{\n    content:\"\"}\n\n.fa-refresh:before{\n    content:\"\"}\n\n.fa-list-alt:before{\n    content:\"\"}\n\n.fa-lock:before{\n    content:\"\"}\n\n.fa-flag:before{\n    content:\"\"}\n\n.fa-headphones:before{\n    content:\"\"}\n\n.fa-volume-off:before{\n    content:\"\"}\n\n.fa-volume-down:before{\n    content:\"\"}\n\n.fa-volume-up:before{\n    content:\"\"}\n\n.fa-qrcode:before{\n    content:\"\"}\n\n.fa-barcode:before{\n    content:\"\"}\n\n.fa-tag:before{\n    content:\"\"}\n\n.fa-tags:before{\n    content:\"\"}\n\n.fa-book:before,.icon-book:before{\n    content:\"\"}\n\n.fa-bookmark:before{\n    content:\"\"}\n\n.fa-print:before{\n    content:\"\"}\n\n.fa-camera:before{\n    content:\"\"}\n\n.fa-font:before{\n    content:\"\"}\n\n.fa-bold:before{\n    content:\"\"}\n\n.fa-italic:before{\n    content:\"\"}\n\n.fa-text-height:before{\n    content:\"\"}\n\n.fa-text-width:before{\n    content:\"\"}\n\n.fa-align-left:before{\n    content:\"\"}\n\n.fa-align-center:before{\n    content:\"\"}\n\n.fa-align-right:before{\n    content:\"\"}\n\n.fa-align-justify:before{\n    content:\"\"}\n\n.fa-list:before{\n    content:\"\"}\n\n.fa-dedent:before,.fa-outdent:before{\n    content:\"\"}\n\n.fa-indent:before{\n    content:\"\"}\n\n.fa-video-camera:before{\n    content:\"\"}\n\n.fa-photo:before,.fa-image:before,.fa-picture-o:before{\n    content:\"\"}\n\n.fa-pencil:before{\n    content:\"\"}\n\n.fa-map-marker:before{\n    content:\"\"}\n\n.fa-adjust:before{\n    content:\"\"}\n\n.fa-tint:before{\n    content:\"\"}\n\n.fa-edit:before,.fa-pencil-square-o:before{\n    content:\"\"}\n\n.fa-share-square-o:before{\n    content:\"\"}\n\n.fa-check-square-o:before{\n    content:\"\"}\n\n.fa-arrows:before{\n    content:\"\"}\n\n.fa-step-backward:before{\n    content:\"\"}\n\n.fa-fast-backward:before{\n    content:\"\"}\n\n.fa-backward:before{\n    content:\"\"}\n\n.fa-play:before{\n    content:\"\"}\n\n.fa-pause:before{\n    content:\"\"}\n\n.fa-stop:before{\n    content:\"\"}\n\n.fa-forward:before{\n    content:\"\"}\n\n.fa-fast-forward:before{\n    content:\"\"}\n\n.fa-step-forward:before{\n    content:\"\"}\n\n.fa-eject:before{\n    content:\"\"}\n\n.fa-chevron-left:before{\n    content:\"\"}\n\n.fa-chevron-right:before{\n    content:\"\"}\n\n.fa-plus-circle:before{\n    content:\"\"}\n\n.fa-minus-circle:before{\n    content:\"\"}\n\n.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{\n    content:\"\"}\n\n.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{\n    content:\"\"}\n\n.fa-question-circle:before{\n    content:\"\"}\n\n.fa-info-circle:before{\n    content:\"\"}\n\n.fa-crosshairs:before{\n    content:\"\"}\n\n.fa-times-circle-o:before{\n    content:\"\"}\n\n.fa-check-circle-o:before{\n    content:\"\"}\n\n.fa-ban:before{\n    content:\"\"}\n\n.fa-arrow-left:before{\n    content:\"\"}\n\n.fa-arrow-right:before{\n    content:\"\"}\n\n.fa-arrow-up:before{\n    content:\"\"}\n\n.fa-arrow-down:before{\n    content:\"\"}\n\n.fa-mail-forward:before,.fa-share:before{\n    content:\"\"}\n\n.fa-expand:before{\n    content:\"\"}\n\n.fa-compress:before{\n    content:\"\"}\n\n.fa-plus:before{\n    content:\"\"}\n\n.fa-minus:before{\n    content:\"\"}\n\n.fa-asterisk:before{\n    content:\"\"}\n\n.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{\n    content:\"\"}\n\n.fa-gift:before{\n    content:\"\"}\n\n.fa-leaf:before{\n    content:\"\"}\n\n.fa-fire:before,.icon-fire:before{\n    content:\"\"}\n\n.fa-eye:before{\n    content:\"\"}\n\n.fa-eye-slash:before{\n    content:\"\"}\n\n.fa-warning:before,.fa-exclamation-triangle:before{\n    content:\"\"}\n\n.fa-plane:before{\n    content:\"\"}\n\n.fa-calendar:before{\n    content:\"\"}\n\n.fa-random:before{\n    content:\"\"}\n\n.fa-comment:before{\n    content:\"\"}\n\n.fa-magnet:before{\n    content:\"\"}\n\n.fa-chevron-up:before{\n    content:\"\"}\n\n.fa-chevron-down:before{\n    content:\"\"}\n\n.fa-retweet:before{\n    content:\"\"}\n\n.fa-shopping-cart:before{\n    content:\"\"}\n\n.fa-folder:before{\n    content:\"\"}\n\n.fa-folder-open:before{\n    content:\"\"}\n\n.fa-arrows-v:before{\n    content:\"\"}\n\n.fa-arrows-h:before{\n    content:\"\"}\n\n.fa-bar-chart-o:before{\n    content:\"\"}\n\n.fa-twitter-square:before{\n    content:\"\"}\n\n.fa-facebook-square:before{\n    content:\"\"}\n\n.fa-camera-retro:before{\n    content:\"\"}\n\n.fa-key:before{\n    content:\"\"}\n\n.fa-gears:before,.fa-cogs:before{\n    content:\"\"}\n\n.fa-comments:before{\n    content:\"\"}\n\n.fa-thumbs-o-up:before{\n    content:\"\"}\n\n.fa-thumbs-o-down:before{\n    content:\"\"}\n\n.fa-star-half:before{\n    content:\"\"}\n\n.fa-heart-o:before{\n    content:\"\"}\n\n.fa-sign-out:before{\n    content:\"\"}\n\n.fa-linkedin-square:before{\n    content:\"\"}\n\n.fa-thumb-tack:before{\n    content:\"\"}\n\n.fa-external-link:before{\n    content:\"\"}\n\n.fa-sign-in:before{\n    content:\"\"}\n\n.fa-trophy:before{\n    content:\"\"}\n\n.fa-github-square:before{\n    content:\"\"}\n\n.fa-upload:before{\n    content:\"\"}\n\n.fa-lemon-o:before{\n    content:\"\"}\n\n.fa-phone:before{\n    content:\"\"}\n\n.fa-square-o:before{\n    content:\"\"}\n\n.fa-bookmark-o:before{\n    content:\"\"}\n\n.fa-phone-square:before{\n    content:\"\"}\n\n.fa-twitter:before{\n    content:\"\"}\n\n.fa-facebook:before{\n    content:\"\"}\n\n.fa-github:before,.icon-github:before{\n    content:\"\"}\n\n.fa-unlock:before{\n    content:\"\"}\n\n.fa-credit-card:before{\n    content:\"\"}\n\n.fa-rss:before{\n    content:\"\"}\n\n.fa-hdd-o:before{\n    content:\"\"}\n\n.fa-bullhorn:before{\n    content:\"\"}\n\n.fa-bell:before{\n    content:\"\"}\n\n.fa-certificate:before{\n    content:\"\"}\n\n.fa-hand-o-right:before{\n    content:\"\"}\n\n.fa-hand-o-left:before{\n    content:\"\"}\n\n.fa-hand-o-up:before{\n    content:\"\"}\n\n.fa-hand-o-down:before{\n    content:\"\"}\n\n.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{\n    content:\"\"}\n\n.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{\n    content:\"\"}\n\n.fa-arrow-circle-up:before{\n    content:\"\"}\n\n.fa-arrow-circle-down:before{\n    content:\"\"}\n\n.fa-globe:before{\n    content:\"\"}\n\n.fa-wrench:before{\n    content:\"\"}\n\n.fa-tasks:before{\n    content:\"\"}\n\n.fa-filter:before{\n    content:\"\"}\n\n.fa-briefcase:before{\n    content:\"\"}\n\n.fa-arrows-alt:before{\n    content:\"\"}\n\n.fa-group:before,.fa-users:before{\n    content:\"\"}\n\n.fa-chain:before,.fa-link:before,.icon-link:before{\n    content:\"\"}\n\n.fa-cloud:before{\n    content:\"\"}\n\n.fa-flask:before{\n    content:\"\"}\n\n.fa-cut:before,.fa-scissors:before{\n    content:\"\"}\n\n.fa-copy:before,.fa-files-o:before{\n    content:\"\"}\n\n.fa-paperclip:before{\n    content:\"\"}\n\n.fa-save:before,.fa-floppy-o:before{\n    content:\"\"}\n\n.fa-square:before{\n    content:\"\"}\n\n.fa-navicon:before,.fa-reorder:before,.fa-bars:before{\n    content:\"\"}\n\n.fa-list-ul:before{\n    content:\"\"}\n\n.fa-list-ol:before{\n    content:\"\"}\n\n.fa-strikethrough:before{\n    content:\"\"}\n\n.fa-underline:before{\n    content:\"\"}\n\n.fa-table:before{\n    content:\"\"}\n\n.fa-magic:before{\n    content:\"\"}\n\n.fa-truck:before{\n    content:\"\"}\n\n.fa-pinterest:before{\n    content:\"\"}\n\n.fa-pinterest-square:before{\n    content:\"\"}\n\n.fa-google-plus-square:before{\n    content:\"\"}\n\n.fa-google-plus:before{\n    content:\"\"}\n\n.fa-money:before{\n    content:\"\"}\n\n.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{\n    content:\"\"}\n\n.fa-caret-up:before{\n    content:\"\"}\n\n.fa-caret-left:before{\n    content:\"\"}\n\n.fa-caret-right:before{\n    content:\"\"}\n\n.fa-columns:before{\n    content:\"\"}\n\n.fa-unsorted:before,.fa-sort:before{\n    content:\"\"}\n\n.fa-sort-down:before,.fa-sort-desc:before{\n    content:\"\"}\n\n.fa-sort-up:before,.fa-sort-asc:before{\n    content:\"\"}\n\n.fa-envelope:before{\n    content:\"\"}\n\n.fa-linkedin:before{\n    content:\"\"}\n\n.fa-rotate-left:before,.fa-undo:before{\n    content:\"\"}\n\n.fa-legal:before,.fa-gavel:before{\n    content:\"\"}\n\n.fa-dashboard:before,.fa-tachometer:before{\n    content:\"\"}\n\n.fa-comment-o:before{\n    content:\"\"}\n\n.fa-comments-o:before{\n    content:\"\"}\n\n.fa-flash:before,.fa-bolt:before{\n    content:\"\"}\n\n.fa-sitemap:before{\n    content:\"\"}\n\n.fa-umbrella:before{\n    content:\"\"}\n\n.fa-paste:before,.fa-clipboard:before{\n    content:\"\"}\n\n.fa-lightbulb-o:before{\n    content:\"\"}\n\n.fa-exchange:before{\n    content:\"\"}\n\n.fa-cloud-download:before{\n    content:\"\"}\n\n.fa-cloud-upload:before{\n    content:\"\"}\n\n.fa-user-md:before{\n    content:\"\"}\n\n.fa-stethoscope:before{\n    content:\"\"}\n\n.fa-suitcase:before{\n    content:\"\"}\n\n.fa-bell-o:before{\n    content:\"\"}\n\n.fa-coffee:before{\n    content:\"\"}\n\n.fa-cutlery:before{\n    content:\"\"}\n\n.fa-file-text-o:before{\n    content:\"\"}\n\n.fa-building-o:before{\n    content:\"\"}\n\n.fa-hospital-o:before{\n    content:\"\"}\n\n.fa-ambulance:before{\n    content:\"\"}\n\n.fa-medkit:before{\n    content:\"\"}\n\n.fa-fighter-jet:before{\n    content:\"\"}\n\n.fa-beer:before{\n    content:\"\"}\n\n.fa-h-square:before{\n    content:\"\"}\n\n.fa-plus-square:before{\n    content:\"\"}\n\n.fa-angle-double-left:before{\n    content:\"\"}\n\n.fa-angle-double-right:before{\n    content:\"\"}\n\n.fa-angle-double-up:before{\n    content:\"\"}\n\n.fa-angle-double-down:before{\n    content:\"\"}\n\n.fa-angle-left:before{\n    content:\"\"}\n\n.fa-angle-right:before{\n    content:\"\"}\n\n.fa-angle-up:before{\n    content:\"\"}\n\n.fa-angle-down:before{\n    content:\"\"}\n\n.fa-desktop:before{\n    content:\"\"}\n\n.fa-laptop:before{\n    content:\"\"}\n\n.fa-tablet:before{\n    content:\"\"}\n\n.fa-mobile-phone:before,.fa-mobile:before{\n    content:\"\"}\n\n.fa-circle-o:before{\n    content:\"\"}\n\n.fa-quote-left:before{\n    content:\"\"}\n\n.fa-quote-right:before{\n    content:\"\"}\n\n.fa-spinner:before{\n    content:\"\"}\n\n.fa-circle:before{\n    content:\"\"}\n\n.fa-mail-reply:before,.fa-reply:before{\n    content:\"\"}\n\n.fa-github-alt:before{\n    content:\"\"}\n\n.fa-folder-o:before{\n    content:\"\"}\n\n.fa-folder-open-o:before{\n    content:\"\"}\n\n.fa-smile-o:before{\n    content:\"\"}\n\n.fa-frown-o:before{\n    content:\"\"}\n\n.fa-meh-o:before{\n    content:\"\"}\n\n.fa-gamepad:before{\n    content:\"\"}\n\n.fa-keyboard-o:before{\n    content:\"\"}\n\n.fa-flag-o:before{\n    content:\"\"}\n\n.fa-flag-checkered:before{\n    content:\"\"}\n\n.fa-terminal:before{\n    content:\"\"}\n\n.fa-code:before{\n    content:\"\"}\n\n.fa-mail-reply-all:before,.fa-reply-all:before{\n    content:\"\"}\n\n.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{\n    content:\"\"}\n\n.fa-location-arrow:before{\n    content:\"\"}\n\n.fa-crop:before{\n    content:\"\"}\n\n.fa-code-fork:before{\n    content:\"\"}\n\n.fa-unlink:before,.fa-chain-broken:before{\n    content:\"\"}\n\n.fa-question:before{\n    content:\"\"}\n\n.fa-info:before{\n    content:\"\"}\n\n.fa-exclamation:before{\n    content:\"\"}\n\n.fa-superscript:before{\n    content:\"\"}\n\n.fa-subscript:before{\n    content:\"\"}\n\n.fa-eraser:before{\n    content:\"\"}\n\n.fa-puzzle-piece:before{\n    content:\"\"}\n\n.fa-microphone:before{\n    content:\"\"}\n\n.fa-microphone-slash:before{\n    content:\"\"}\n\n.fa-shield:before{\n    content:\"\"}\n\n.fa-calendar-o:before{\n    content:\"\"}\n\n.fa-fire-extinguisher:before{\n    content:\"\"}\n\n.fa-rocket:before{\n    content:\"\"}\n\n.fa-maxcdn:before{\n    content:\"\"}\n\n.fa-chevron-circle-left:before{\n    content:\"\"}\n\n.fa-chevron-circle-right:before{\n    content:\"\"}\n\n.fa-chevron-circle-up:before{\n    content:\"\"}\n\n.fa-chevron-circle-down:before{\n    content:\"\"}\n\n.fa-html5:before{\n    content:\"\"}\n\n.fa-css3:before{\n    content:\"\"}\n\n.fa-anchor:before{\n    content:\"\"}\n\n.fa-unlock-alt:before{\n    content:\"\"}\n\n.fa-bullseye:before{\n    content:\"\"}\n\n.fa-ellipsis-h:before{\n    content:\"\"}\n\n.fa-ellipsis-v:before{\n    content:\"\"}\n\n.fa-rss-square:before{\n    content:\"\"}\n\n.fa-play-circle:before{\n    content:\"\"}\n\n.fa-ticket:before{\n    content:\"\"}\n\n.fa-minus-square:before{\n    content:\"\"}\n\n.fa-minus-square-o:before{\n    content:\"\"}\n\n.fa-level-up:before{\n    content:\"\"}\n\n.fa-level-down:before{\n    content:\"\"}\n\n.fa-check-square:before{\n    content:\"\"}\n\n.fa-pencil-square:before{\n    content:\"\"}\n\n.fa-external-link-square:before{\n    content:\"\"}\n\n.fa-share-square:before{\n    content:\"\"}\n\n.fa-compass:before{\n    content:\"\"}\n\n.fa-toggle-down:before,.fa-caret-square-o-down:before{\n    content:\"\"}\n\n.fa-toggle-up:before,.fa-caret-square-o-up:before{\n    content:\"\"}\n\n.fa-toggle-right:before,.fa-caret-square-o-right:before{\n    content:\"\"}\n\n.fa-euro:before,.fa-eur:before{\n    content:\"\"}\n\n.fa-gbp:before{\n    content:\"\"}\n\n.fa-dollar:before,.fa-usd:before{\n    content:\"\"}\n\n.fa-rupee:before,.fa-inr:before{\n    content:\"\"}\n\n.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{\n    content:\"\"}\n\n.fa-ruble:before,.fa-rouble:before,.fa-rub:before{\n    content:\"\"}\n\n.fa-won:before,.fa-krw:before{\n    content:\"\"}\n\n.fa-bitcoin:before,.fa-btc:before{\n    content:\"\"}\n\n.fa-file:before{\n    content:\"\"}\n\n.fa-file-text:before{\n    content:\"\"}\n\n.fa-sort-alpha-asc:before{\n    content:\"\"}\n\n.fa-sort-alpha-desc:before{\n    content:\"\"}\n\n.fa-sort-amount-asc:before{\n    content:\"\"}\n\n.fa-sort-amount-desc:before{\n    content:\"\"}\n\n.fa-sort-numeric-asc:before{\n    content:\"\"}\n\n.fa-sort-numeric-desc:before{\n    content:\"\"}\n\n.fa-thumbs-up:before{\n    content:\"\"}\n\n.fa-thumbs-down:before{\n    content:\"\"}\n\n.fa-youtube-square:before{\n    content:\"\"}\n\n.fa-youtube:before{\n    content:\"\"}\n\n.fa-xing:before{\n    content:\"\"}\n\n.fa-xing-square:before{\n    content:\"\"}\n\n.fa-youtube-play:before{\n    content:\"\"}\n\n.fa-dropbox:before{\n    content:\"\"}\n\n.fa-stack-overflow:before{\n    content:\"\"}\n\n.fa-instagram:before{\n    content:\"\"}\n\n.fa-flickr:before{\n    content:\"\"}\n\n.fa-adn:before{\n    content:\"\"}\n\n.fa-bitbucket:before,.icon-bitbucket:before{\n    content:\"\"}\n\n.fa-bitbucket-square:before{\n    content:\"\"}\n\n.fa-tumblr:before{\n    content:\"\"}\n\n.fa-tumblr-square:before{\n    content:\"\"}\n\n.fa-long-arrow-down:before{\n    content:\"\"}\n\n.fa-long-arrow-up:before{\n    content:\"\"}\n\n.fa-long-arrow-left:before{\n    content:\"\"}\n\n.fa-long-arrow-right:before{\n    content:\"\"}\n\n.fa-apple:before{\n    content:\"\"}\n\n.fa-windows:before{\n    content:\"\"}\n\n.fa-android:before{\n    content:\"\"}\n\n.fa-linux:before{\n    content:\"\"}\n\n.fa-dribbble:before{\n    content:\"\"}\n\n.fa-skype:before{\n    content:\"\"}\n\n.fa-foursquare:before{\n    content:\"\"}\n\n.fa-trello:before{\n    content:\"\"}\n\n.fa-female:before{\n    content:\"\"}\n\n.fa-male:before{\n    content:\"\"}\n\n.fa-gittip:before{\n    content:\"\"}\n\n.fa-sun-o:before{\n    content:\"\"}\n\n.fa-moon-o:before{\n    content:\"\"}\n\n.fa-archive:before{\n    content:\"\"}\n\n.fa-bug:before{\n    content:\"\"}\n\n.fa-vk:before{\n    content:\"\"}\n\n.fa-weibo:before{\n    content:\"\"}\n\n.fa-renren:before{\n    content:\"\"}\n\n.fa-pagelines:before{\n    content:\"\"}\n\n.fa-stack-exchange:before{\n    content:\"\"}\n\n.fa-arrow-circle-o-right:before{\n    content:\"\"}\n\n.fa-arrow-circle-o-left:before{\n    content:\"\"}\n\n.fa-toggle-left:before,.fa-caret-square-o-left:before{\n    content:\"\"}\n\n.fa-dot-circle-o:before{\n    content:\"\"}\n\n.fa-wheelchair:before{\n    content:\"\"}\n\n.fa-vimeo-square:before{\n    content:\"\"}\n\n.fa-turkish-lira:before,.fa-try:before{\n    content:\"\"}\n\n.fa-plus-square-o:before{\n    content:\"\"}\n\n.fa-space-shuttle:before{\n    content:\"\"}\n\n.fa-slack:before{\n    content:\"\"}\n\n.fa-envelope-square:before{\n    content:\"\"}\n\n.fa-wordpress:before{\n    content:\"\"}\n\n.fa-openid:before{\n    content:\"\"}\n\n.fa-institution:before,.fa-bank:before,.fa-university:before{\n    content:\"\"}\n\n.fa-mortar-board:before,.fa-graduation-cap:before{\n    content:\"\"}\n\n.fa-yahoo:before{\n    content:\"\"}\n\n.fa-google:before{\n    content:\"\"}\n\n.fa-reddit:before{\n    content:\"\"}\n\n.fa-reddit-square:before{\n    content:\"\"}\n\n.fa-stumbleupon-circle:before{\n    content:\"\"}\n\n.fa-stumbleupon:before{\n    content:\"\"}\n\n.fa-delicious:before{\n    content:\"\"}\n\n.fa-digg:before{\n    content:\"\"}\n\n.fa-pied-piper-square:before,.fa-pied-piper:before{\n    content:\"\"}\n\n.fa-pied-piper-alt:before{\n    content:\"\"}\n\n.fa-drupal:before{\n    content:\"\"}\n\n.fa-joomla:before{\n    content:\"\"}\n\n.fa-language:before{\n    content:\"\"}\n\n.fa-fax:before{\n    content:\"\"}\n\n.fa-building:before{\n    content:\"\"}\n\n.fa-child:before{\n    content:\"\"}\n\n.fa-paw:before{\n    content:\"\"}\n\n.fa-spoon:before{\n    content:\"\"}\n\n.fa-cube:before{\n    content:\"\"}\n\n.fa-cubes:before{\n    content:\"\"}\n\n.fa-behance:before{\n    content:\"\"}\n\n.fa-behance-square:before{\n    content:\"\"}\n\n.fa-steam:before{\n    content:\"\"}\n\n.fa-steam-square:before{\n    content:\"\"}\n\n.fa-recycle:before{\n    content:\"\"}\n\n.fa-automobile:before,.fa-car:before{\n    content:\"\"}\n\n.fa-cab:before,.fa-taxi:before{\n    content:\"\"}\n\n.fa-tree:before{\n    content:\"\"}\n\n.fa-spotify:before{\n    content:\"\"}\n\n.fa-deviantart:before{\n    content:\"\"}\n\n.fa-soundcloud:before{\n    content:\"\"}\n\n.fa-database:before{\n    content:\"\"}\n\n.fa-file-pdf-o:before{\n    content:\"\"}\n\n.fa-file-word-o:before{\n    content:\"\"}\n\n.fa-file-excel-o:before{\n    content:\"\"}\n\n.fa-file-powerpoint-o:before{\n    content:\"\"}\n\n.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{\n    content:\"\"}\n\n.fa-file-zip-o:before,.fa-file-archive-o:before{\n    content:\"\"}\n\n.fa-file-sound-o:before,.fa-file-audio-o:before{\n    content:\"\"}\n\n.fa-file-movie-o:before,.fa-file-video-o:before{\n    content:\"\"}\n\n.fa-file-code-o:before{\n    content:\"\"}\n\n.fa-vine:before{\n    content:\"\"}\n\n.fa-codepen:before{\n    content:\"\"}\n\n.fa-jsfiddle:before{\n    content:\"\"}\n\n.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{\n    content:\"\"}\n\n.fa-circle-o-notch:before{\n    content:\"\"}\n\n.fa-ra:before,.fa-rebel:before{\n    content:\"\"}\n\n.fa-ge:before,.fa-empire:before{\n    content:\"\"}\n\n.fa-git-square:before{\n    content:\"\"}\n\n.fa-git:before{\n    content:\"\"}\n\n.fa-hacker-news:before{\n    content:\"\"}\n\n.fa-tencent-weibo:before{\n    content:\"\"}\n\n.fa-qq:before{\n    content:\"\"}\n\n.fa-wechat:before,.fa-weixin:before{\n    content:\"\"}\n\n.fa-send:before,.fa-paper-plane:before{\n    content:\"\"}\n\n.fa-send-o:before,.fa-paper-plane-o:before{\n    content:\"\"}\n\n.fa-history:before{\n    content:\"\"}\n\n.fa-circle-thin:before{\n    content:\"\"}\n\n.fa-header:before{\n    content:\"\"}\n\n.fa-paragraph:before{\n    content:\"\"}\n\n.fa-sliders:before{\n    content:\"\"}\n\n.fa-share-alt:before{\n    content:\"\"}\n\n.fa-share-alt-square:before{\n    content:\"\"}\n\n.fa-bomb:before{\n    content:\"\"}\n\n.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{\n    font-family:inherit}\n\n.fa:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{\n    font-family:\"FontAwesome\";\n    display:inline-block;\n    font-style:normal;\n    font-weight:normal;\n    line-height:1;\n    text-decoration:inherit}\n\na .fa,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .icon{\n    display:inline-block;\n    text-decoration:inherit}\n\n.btn .fa,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .icon,.nav .fa,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .icon{\n    display:inline}\n\n.btn .fa.fa-large,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .fa-large.icon{\n    line-height:0.9em}\n\n.btn .fa.fa-spin,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .fa-spin.icon{\n    display:inline-block}\n\n.btn.fa:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.btn.icon:before{\n    opacity:0.5;\n    -webkit-transition:opacity 0.05s ease-in;\n    -moz-transition:opacity 0.05s ease-in;\n    transition:opacity 0.05s ease-in}\n\n.btn.fa:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.btn.icon:hover:before{\n    opacity:1}\n\n.btn-mini .fa:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .icon:before{\n    font-size:14px;\n    vertical-align:-15%}\n\n.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo{\n    padding:12px;\n    line-height:24px;\n    margin-bottom:24px;\n    background:#e7f2fa}\n\n.wy-alert-title,.rst-content .admonition-title{\n    color:#fff;\n    font-weight:bold;\n    display:block;\n    color:#fff;\n    background:#6ab0de;\n    margin:-12px;\n    padding:6px 12px;\n    margin-bottom:12px}\n\n.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo{\n    background:#fdf3f2}\n\n.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title{\n    background:#f29f97}\n\n.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo{\n    background:#ffedcc}\n\n.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title{\n    background:#f0b37e}\n\n.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo{\n    background:#e7f2fa}\n\n.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title{\n    background:#6ab0de}\n\n.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo{\n    background:#dbfaf4}\n\n.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title{\n    background:#1abc9c}\n\n.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo{\n    background:#f3f6f6}\n\n.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title{\n    color:#404040;\n    background:#e1e4e5}\n\n.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a{\n    color:#2980B9}\n\n.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child{\n    margin-bottom:0}\n\n.wy-tray-container{\n    position:fixed;\n    bottom:0px;\n    left:0;\n    z-index:600}\n\n.wy-tray-container li{\n    display:block;\n    width:300px;\n    background:transparent;\n    color:#fff;\n    text-align:center;\n    box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);\n    padding:0 24px;\n    min-width:20%;\n    opacity:0;\n    height:0;\n    line-height:56px;\n    overflow:hidden;\n    -webkit-transition:all 0.3s ease-in;\n    -moz-transition:all 0.3s ease-in;\n    transition:all 0.3s ease-in}\n\n.wy-tray-container li.wy-tray-item-success{\n    background:#27AE60}\n\n.wy-tray-container li.wy-tray-item-info{\n    background:#2980B9}\n\n.wy-tray-container li.wy-tray-item-warning{\n    background:#E67E22}\n\n.wy-tray-container li.wy-tray-item-danger{\n    background:#E74C3C}\n\n.wy-tray-container li.on{\n    opacity:1;\n    height:56px}\n\n@media screen and (max-width: 768px){\n    .wy-tray-container{\n        bottom:auto;\n        top:0;\n        width:100%}\n\n    .wy-tray-container li{\n        width:100%}\n\n}\n\nbutton{\n    font-size:100%;\n    margin:0;\n    vertical-align:baseline;\n    *vertical-align:middle;\n    cursor:pointer;\n    line-height:normal;\n    -webkit-appearance:button;\n    *overflow:visible}\n\nbutton::-moz-focus-inner,input::-moz-focus-inner{\n                             border:0;\n                             padding:0}\n\nbutton[disabled]{\n    cursor:default}\n\n.btn{\n    display:inline-block;\n    border-radius:2px;\n    line-height:normal;\n    white-space:nowrap;\n    text-align:center;\n    cursor:pointer;\n    font-size:100%;\n    padding:6px 12px 8px 12px;\n    color:#fff;\n    border:1px solid rgba(0,0,0,0.1);\n    background-color:#27AE60;\n    text-decoration:none;\n    font-weight:normal;\n    font-family:\"Lato\",\"proxima-nova\",\"Helvetica Neue\",Arial,sans-serif;\n    box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;\n    outline-none:false;\n    vertical-align:middle;\n    *display:inline;\n    zoom:1;\n    -webkit-user-drag:none;\n    -webkit-user-select:none;\n    -moz-user-select:none;\n    -ms-user-select:none;\n    user-select:none;\n    -webkit-transition:all 0.1s linear;\n    -moz-transition:all 0.1s linear;\n    transition:all 0.1s linear}\n\n.btn-hover{\n    background:#2e8ece;\n    color:#fff}\n\n.btn:hover{\n    background:#2cc36b;\n    color:#fff}\n\n.btn:focus{\n    background:#2cc36b;\n    outline:0}\n\n.btn:active{\n    box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;\n    padding:8px 12px 6px 12px}\n\n.btn:visited{\n    color:#fff}\n\n.btn:disabled{\n    background-image:none;\n    filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);\n    filter:alpha(opacity=40);\n    opacity:0.4;\n    cursor:not-allowed;\n    box-shadow:none}\n\n.btn-disabled{\n    background-image:none;\n    filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);\n    filter:alpha(opacity=40);\n    opacity:0.4;\n    cursor:not-allowed;\n    box-shadow:none}\n\n.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{\n    background-image:none;\n    filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);\n    filter:alpha(opacity=40);\n    opacity:0.4;\n    cursor:not-allowed;\n    box-shadow:none}\n\n.btn::-moz-focus-inner{\n    padding:0;\n    border:0}\n\n.btn-small{\n    font-size:80%}\n\n.btn-info{\n    background-color:#2980B9 !important}\n\n.btn-info:hover{\n    background-color:#2e8ece !important}\n\n.btn-neutral{\n    background-color:#f3f6f6 !important;\n    color:#404040 !important}\n\n.btn-neutral:hover{\n    background-color:#e5ebeb !important;\n    color:#404040}\n\n.btn-neutral:visited{\n    color:#404040 !important}\n\n.btn-success{\n    background-color:#27AE60 !important}\n\n.btn-success:hover{\n    background-color:#295 !important}\n\n.btn-danger{\n    background-color:#E74C3C !important}\n\n.btn-danger:hover{\n    background-color:#ea6153 !important}\n\n.btn-warning{\n    background-color:#E67E22 !important}\n\n.btn-warning:hover{\n    background-color:#e98b39 !important}\n\n.btn-invert{\n    background-color:#222}\n\n.btn-invert:hover{\n    background-color:#2f2f2f !important}\n\n.btn-link{\n    background-color:transparent !important;\n    color:#2980B9;\n    box-shadow:none;\n    border-color:transparent !important}\n\n.btn-link:hover{\n    background-color:transparent !important;\n    color:#409ad5 !important;\n    box-shadow:none}\n\n.btn-link:active{\n    background-color:transparent !important;\n    color:#409ad5 !important;\n    box-shadow:none}\n\n.btn-link:visited{\n    color:#9B59B6}\n\n.wy-btn-group .btn,.wy-control .btn{\n    vertical-align:middle}\n\n.wy-btn-group{\n    margin-bottom:24px;\n    *zoom:1}\n\n.wy-btn-group:before,.wy-btn-group:after{\n    display:table;\n    content:\"\"}\n\n.wy-btn-group:after{\n    clear:both}\n\n.wy-dropdown{\n    position:relative;\n    display:inline-block}\n\n.wy-dropdown-active .wy-dropdown-menu{\n    display:block}\n\n.wy-dropdown-menu{\n    position:absolute;\n    left:0;\n    display:none;\n    float:left;\n    top:100%;\n    min-width:100%;\n    background:#fcfcfc;\n    z-index:100;\n    border:solid 1px #cfd7dd;\n    box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);\n    padding:12px}\n\n.wy-dropdown-menu>dd>a{\n    display:block;\n    clear:both;\n    color:#404040;\n    white-space:nowrap;\n    font-size:90%;\n    padding:0 12px;\n    cursor:pointer}\n\n.wy-dropdown-menu>dd>a:hover{\n    background:#2980B9;\n    color:#fff}\n\n.wy-dropdown-menu>dd.divider{\n    border-top:solid 1px #cfd7dd;\n    margin:6px 0}\n\n.wy-dropdown-menu>dd.search{\n    padding-bottom:12px}\n\n.wy-dropdown-menu>dd.search input[type=\"search\"]{\n    width:100%}\n\n.wy-dropdown-menu>dd.call-to-action{\n    background:#e3e3e3;\n    text-transform:uppercase;\n    font-weight:500;\n    font-size:80%}\n\n.wy-dropdown-menu>dd.call-to-action:hover{\n    background:#e3e3e3}\n\n.wy-dropdown-menu>dd.call-to-action .btn{\n    color:#fff}\n\n.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{\n    bottom:100%;\n    top:auto;\n    left:auto;\n    right:0}\n\n.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{\n    background:#fcfcfc;\n    margin-top:2px}\n\n.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{\n    padding:6px 12px}\n\n.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{\n    background:#2980B9;\n    color:#fff}\n\n.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{\n    right:0;\n    text-align:right}\n\n.wy-dropdown-arrow:before{\n    content:\" \";\n    border-bottom:5px solid #f5f5f5;\n    border-left:5px solid transparent;\n    border-right:5px solid transparent;\n    position:absolute;\n    display:block;\n    top:-4px;\n    left:50%;\n    margin-left:-3px}\n\n.wy-dropdown-arrow.wy-dropdown-arrow-left:before{\n    left:11px}\n\n.wy-form-stacked select{\n    display:block}\n\n.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{\n    display:inline-block;\n    *display:inline;\n    *zoom:1;\n    vertical-align:middle}\n\n.wy-form-aligned .wy-control-group>label{\n    display:inline-block;\n    vertical-align:middle;\n    width:10em;\n    margin:6px 12px 0 0;\n    float:left}\n\n.wy-form-aligned .wy-control{\n    float:left}\n\n.wy-form-aligned .wy-control label{\n    display:block}\n\n.wy-form-aligned .wy-control select{\n    margin-top:6px}\n\nfieldset{\n    border:0;\n    margin:0;\n    padding:0}\n\nlegend{\n    display:block;\n    width:100%;\n    border:0;\n    padding:0;\n    white-space:normal;\n    margin-bottom:24px;\n    font-size:150%;\n    *margin-left:-7px}\n\nlabel{\n    display:block;\n    margin:0 0 0.3125em 0;\n    color:#333;\n    font-size:90%}\n\ninput,select,textarea{\n    font-size:100%;\n    margin:0;\n    vertical-align:baseline;\n    *vertical-align:middle}\n\n.wy-control-group{\n    margin-bottom:24px;\n    *zoom:1;\n    max-width:68em;\n    margin-left:auto;\n    margin-right:auto;\n    *zoom:1}\n\n.wy-control-group:before,.wy-control-group:after{\n    display:table;\n    content:\"\"}\n\n.wy-control-group:after{\n    clear:both}\n\n.wy-control-group:before,.wy-control-group:after{\n    display:table;\n    content:\"\"}\n\n.wy-control-group:after{\n    clear:both}\n\n.wy-control-group.wy-control-group-required>label:after{\n    content:\" *\";\n    color:#E74C3C}\n\n.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{\n    padding-bottom:12px}\n\n.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{\n    width:100%}\n\n.wy-control-group .wy-form-full input[type=\"text\"],.wy-control-group .wy-form-full input[type=\"password\"],.wy-control-group .wy-form-full input[type=\"email\"],.wy-control-group .wy-form-full input[type=\"url\"],.wy-control-group .wy-form-full input[type=\"date\"],.wy-control-group .wy-form-full input[type=\"month\"],.wy-control-group .wy-form-full input[type=\"time\"],.wy-control-group .wy-form-full input[type=\"datetime\"],.wy-control-group .wy-form-full input[type=\"datetime-local\"],.wy-control-group .wy-form-full input[type=\"week\"],.wy-control-group .wy-form-full input[type=\"number\"],.wy-control-group .wy-form-full input[type=\"search\"],.wy-control-group .wy-form-full input[type=\"tel\"],.wy-control-group .wy-form-full input[type=\"color\"],.wy-control-group .wy-form-halves input[type=\"text\"],.wy-control-group .wy-form-halves input[type=\"password\"],.wy-control-group .wy-form-halves input[type=\"email\"],.wy-control-group .wy-form-halves input[type=\"url\"],.wy-control-group .wy-form-halves input[type=\"date\"],.wy-control-group .wy-form-halves input[type=\"month\"],.wy-control-group .wy-form-halves input[type=\"time\"],.wy-control-group .wy-form-halves input[type=\"datetime\"],.wy-control-group .wy-form-halves input[type=\"datetime-local\"],.wy-control-group .wy-form-halves input[type=\"week\"],.wy-control-group .wy-form-halves input[type=\"number\"],.wy-control-group .wy-form-halves input[type=\"search\"],.wy-control-group .wy-form-halves input[type=\"tel\"],.wy-control-group .wy-form-halves input[type=\"color\"],.wy-control-group .wy-form-thirds input[type=\"text\"],.wy-control-group .wy-form-thirds input[type=\"password\"],.wy-control-group .wy-form-thirds input[type=\"email\"],.wy-control-group .wy-form-thirds input[type=\"url\"],.wy-control-group .wy-form-thirds input[type=\"date\"],.wy-control-group .wy-form-thirds input[type=\"month\"],.wy-control-group .wy-form-thirds input[type=\"time\"],.wy-control-group .wy-form-thirds input[type=\"datetime\"],.wy-control-group .wy-form-thirds input[type=\"datetime-local\"],.wy-control-group .wy-form-thirds input[type=\"week\"],.wy-control-group .wy-form-thirds input[type=\"number\"],.wy-control-group .wy-form-thirds input[type=\"search\"],.wy-control-group .wy-form-thirds input[type=\"tel\"],.wy-control-group .wy-form-thirds input[type=\"color\"]{\n    width:100%}\n\n.wy-control-group .wy-form-full{\n    float:left;\n    display:block;\n    margin-right:2.35765%;\n    width:100%;\n    margin-right:0}\n\n.wy-control-group .wy-form-full:last-child{\n    margin-right:0}\n\n.wy-control-group .wy-form-halves{\n    float:left;\n    display:block;\n    margin-right:2.35765%;\n    width:48.82117%}\n\n.wy-control-group .wy-form-halves:last-child{\n    margin-right:0}\n\n.wy-control-group .wy-form-halves:nth-of-type(2n){\n    margin-right:0}\n\n.wy-control-group .wy-form-halves:nth-of-type(2n+1){\n    clear:left}\n\n.wy-control-group .wy-form-thirds{\n    float:left;\n    display:block;\n    margin-right:2.35765%;\n    width:31.76157%}\n\n.wy-control-group .wy-form-thirds:last-child{\n    margin-right:0}\n\n.wy-control-group .wy-form-thirds:nth-of-type(3n){\n    margin-right:0}\n\n.wy-control-group .wy-form-thirds:nth-of-type(3n+1){\n    clear:left}\n\n.wy-control-group.wy-control-group-no-input .wy-control{\n    margin:6px 0 0 0;\n    font-size:90%}\n\n.wy-control-no-input{\n    display:inline-block;\n    margin:6px 0 0 0;\n    font-size:90%}\n\n.wy-control-group.fluid-input input[type=\"text\"],.wy-control-group.fluid-input input[type=\"password\"],.wy-control-group.fluid-input input[type=\"email\"],.wy-control-group.fluid-input input[type=\"url\"],.wy-control-group.fluid-input input[type=\"date\"],.wy-control-group.fluid-input input[type=\"month\"],.wy-control-group.fluid-input input[type=\"time\"],.wy-control-group.fluid-input input[type=\"datetime\"],.wy-control-group.fluid-input input[type=\"datetime-local\"],.wy-control-group.fluid-input input[type=\"week\"],.wy-control-group.fluid-input input[type=\"number\"],.wy-control-group.fluid-input input[type=\"search\"],.wy-control-group.fluid-input input[type=\"tel\"],.wy-control-group.fluid-input input[type=\"color\"]{\n    width:100%}\n\n.wy-form-message-inline{\n    display:inline-block;\n    padding-left:0.3em;\n    color:#666;\n    vertical-align:middle;\n    font-size:90%}\n\n.wy-form-message{\n    display:block;\n    color:#999;\n    font-size:70%;\n    margin-top:0.3125em;\n    font-style:italic}\n\ninput{\n    line-height:normal}\n\ninput[type=\"button\"],input[type=\"reset\"],input[type=\"submit\"]{\n    -webkit-appearance:button;\n    cursor:pointer;\n    font-family:\"Lato\",\"proxima-nova\",\"Helvetica Neue\",Arial,sans-serif;\n    *overflow:visible}\n\ninput[type=\"text\"],input[type=\"password\"],input[type=\"email\"],input[type=\"url\"],input[type=\"date\"],input[type=\"month\"],input[type=\"time\"],input[type=\"datetime\"],input[type=\"datetime-local\"],input[type=\"week\"],input[type=\"number\"],input[type=\"search\"],input[type=\"tel\"],input[type=\"color\"]{\n    -webkit-appearance:none;\n    padding:6px;\n    display:inline-block;\n    border:1px solid #ccc;\n    font-size:80%;\n    font-family:\"Lato\",\"proxima-nova\",\"Helvetica Neue\",Arial,sans-serif;\n    box-shadow:inset 0 1px 3px #ddd;\n    border-radius:0;\n    -webkit-transition:border 0.3s linear;\n    -moz-transition:border 0.3s linear;\n    transition:border 0.3s linear}\n\ninput[type=\"datetime-local\"]{\n    padding:0.34375em 0.625em}\n\ninput[disabled]{\n    cursor:default}\n\ninput[type=\"checkbox\"],input[type=\"radio\"]{\n    -webkit-box-sizing:border-box;\n    -moz-box-sizing:border-box;\n    box-sizing:border-box;\n    padding:0;\n    margin-right:0.3125em;\n    *height:13px;\n    *width:13px}\n\ninput[type=\"search\"]{\n    -webkit-box-sizing:border-box;\n    -moz-box-sizing:border-box;\n    box-sizing:border-box}\n\ninput[type=\"search\"]::-webkit-search-cancel-button,input[type=\"search\"]::-webkit-search-decoration{\n                                                       -webkit-appearance:none}\n\ninput[type=\"text\"]:focus,input[type=\"password\"]:focus,input[type=\"email\"]:focus,input[type=\"url\"]:focus,input[type=\"date\"]:focus,input[type=\"month\"]:focus,input[type=\"time\"]:focus,input[type=\"datetime\"]:focus,input[type=\"datetime-local\"]:focus,input[type=\"week\"]:focus,input[type=\"number\"]:focus,input[type=\"search\"]:focus,input[type=\"tel\"]:focus,input[type=\"color\"]:focus{\n                                                                                                                                                                                                                                                                                                                                                               outline:0;\n                                                                                                                                                                                                                                                                                                                                                               outline:thin dotted \\9;\n                                                                                                                                                                                                                                                                                                                                                               border-color:#333}\n\ninput.no-focus:focus{\n    border-color:#ccc !important}\n\ninput[type=\"file\"]:focus,input[type=\"radio\"]:focus,input[type=\"checkbox\"]:focus{\n                                                       outline:thin dotted #333;\n                                                       outline:1px auto #129FEA}\n\ninput[type=\"text\"][disabled],input[type=\"password\"][disabled],input[type=\"email\"][disabled],input[type=\"url\"][disabled],input[type=\"date\"][disabled],input[type=\"month\"][disabled],input[type=\"time\"][disabled],input[type=\"datetime\"][disabled],input[type=\"datetime-local\"][disabled],input[type=\"week\"][disabled],input[type=\"number\"][disabled],input[type=\"search\"][disabled],input[type=\"tel\"][disabled],input[type=\"color\"][disabled]{\n    cursor:not-allowed;\n    background-color:#f3f6f6;\n    color:#cad2d3}\n\ninput:focus:invalid,textarea:focus:invalid,select:focus:invalid{\n                                               color:#E74C3C;\n                                               border:1px solid #E74C3C}\n\ninput:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{\n                                                           border-color:#E74C3C}\n\ninput[type=\"file\"]:focus:invalid:focus,input[type=\"radio\"]:focus:invalid:focus,input[type=\"checkbox\"]:focus:invalid:focus{\n                                                                                   outline-color:#E74C3C}\n\ninput.wy-input-large{\n    padding:12px;\n    font-size:100%}\n\ntextarea{\n    overflow:auto;\n    vertical-align:top;\n    width:100%;\n    font-family:\"Lato\",\"proxima-nova\",\"Helvetica Neue\",Arial,sans-serif}\n\nselect,textarea{\n    padding:0.5em 0.625em;\n    display:inline-block;\n    border:1px solid #ccc;\n    font-size:80%;\n    box-shadow:inset 0 1px 3px #ddd;\n    -webkit-transition:border 0.3s linear;\n    -moz-transition:border 0.3s linear;\n    transition:border 0.3s linear}\n\nselect{\n    border:1px solid #ccc;\n    background-color:#fff}\n\nselect[multiple]{\n    height:auto}\n\nselect:focus,textarea:focus{\n                 outline:0}\n\nselect[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{\n    cursor:not-allowed;\n    background-color:#fff;\n    color:#cad2d3;\n    border-color:transparent}\n\n.wy-checkbox,.wy-radio{\n    margin:6px 0;\n    color:#404040;\n    display:block}\n\n.wy-checkbox input,.wy-radio input{\n    vertical-align:baseline}\n\n.wy-form-message-inline{\n    display:inline-block;\n    *display:inline;\n    *zoom:1;\n    vertical-align:middle}\n\n.wy-input-prefix,.wy-input-suffix{\n    white-space:nowrap;\n    padding:6px}\n\n.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{\n    line-height:27px;\n    padding:0 8px;\n    display:inline-block;\n    font-size:80%;\n    background-color:#f3f6f6;\n    border:solid 1px #ccc;\n    color:#999}\n\n.wy-input-suffix .wy-input-context{\n    border-left:0}\n\n.wy-input-prefix .wy-input-context{\n    border-right:0}\n\n.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{\n    color:#E74C3C}\n\n.wy-control-group.wy-control-group-error input[type=\"text\"],.wy-control-group.wy-control-group-error input[type=\"password\"],.wy-control-group.wy-control-group-error input[type=\"email\"],.wy-control-group.wy-control-group-error input[type=\"url\"],.wy-control-group.wy-control-group-error input[type=\"date\"],.wy-control-group.wy-control-group-error input[type=\"month\"],.wy-control-group.wy-control-group-error input[type=\"time\"],.wy-control-group.wy-control-group-error input[type=\"datetime\"],.wy-control-group.wy-control-group-error input[type=\"datetime-local\"],.wy-control-group.wy-control-group-error input[type=\"week\"],.wy-control-group.wy-control-group-error input[type=\"number\"],.wy-control-group.wy-control-group-error input[type=\"search\"],.wy-control-group.wy-control-group-error input[type=\"tel\"],.wy-control-group.wy-control-group-error input[type=\"color\"]{\n    border:solid 1px #E74C3C}\n\n.wy-control-group.wy-control-group-error textarea{\n    border:solid 1px #E74C3C}\n\n.wy-inline-validate{\n    white-space:nowrap}\n\n.wy-inline-validate .wy-input-context{\n    padding:0.5em 0.625em;\n    display:inline-block;\n    font-size:80%}\n\n.wy-inline-validate.wy-inline-validate-success .wy-input-context{\n    color:#27AE60}\n\n.wy-inline-validate.wy-inline-validate-danger .wy-input-context{\n    color:#E74C3C}\n\n.wy-inline-validate.wy-inline-validate-warning .wy-input-context{\n    color:#E67E22}\n\n.wy-inline-validate.wy-inline-validate-info .wy-input-context{\n    color:#2980B9}\n\n.rotate-90{\n    -webkit-transform:rotate(90deg);\n    -moz-transform:rotate(90deg);\n    -ms-transform:rotate(90deg);\n    -o-transform:rotate(90deg);\n    transform:rotate(90deg)}\n\n.rotate-180{\n    -webkit-transform:rotate(180deg);\n    -moz-transform:rotate(180deg);\n    -ms-transform:rotate(180deg);\n    -o-transform:rotate(180deg);\n    transform:rotate(180deg)}\n\n.rotate-270{\n    -webkit-transform:rotate(270deg);\n    -moz-transform:rotate(270deg);\n    -ms-transform:rotate(270deg);\n    -o-transform:rotate(270deg);\n    transform:rotate(270deg)}\n\n.mirror{\n    -webkit-transform:scaleX(-1);\n    -moz-transform:scaleX(-1);\n    -ms-transform:scaleX(-1);\n    -o-transform:scaleX(-1);\n    transform:scaleX(-1)}\n\n.mirror.rotate-90{\n    -webkit-transform:scaleX(-1) rotate(90deg);\n    -moz-transform:scaleX(-1) rotate(90deg);\n    -ms-transform:scaleX(-1) rotate(90deg);\n    -o-transform:scaleX(-1) rotate(90deg);\n    transform:scaleX(-1) rotate(90deg)}\n\n.mirror.rotate-180{\n    -webkit-transform:scaleX(-1) rotate(180deg);\n    -moz-transform:scaleX(-1) rotate(180deg);\n    -ms-transform:scaleX(-1) rotate(180deg);\n    -o-transform:scaleX(-1) rotate(180deg);\n    transform:scaleX(-1) rotate(180deg)}\n\n.mirror.rotate-270{\n    -webkit-transform:scaleX(-1) rotate(270deg);\n    -moz-transform:scaleX(-1) rotate(270deg);\n    -ms-transform:scaleX(-1) rotate(270deg);\n    -o-transform:scaleX(-1) rotate(270deg);\n    transform:scaleX(-1) rotate(270deg)}\n\n@media only screen and (max-width: 480px){\n    .wy-form button[type=\"submit\"]{\n        margin:0.7em 0 0}\n\n    .wy-form input[type=\"text\"],.wy-form input[type=\"password\"],.wy-form input[type=\"email\"],.wy-form input[type=\"url\"],.wy-form input[type=\"date\"],.wy-form input[type=\"month\"],.wy-form input[type=\"time\"],.wy-form input[type=\"datetime\"],.wy-form input[type=\"datetime-local\"],.wy-form input[type=\"week\"],.wy-form input[type=\"number\"],.wy-form input[type=\"search\"],.wy-form input[type=\"tel\"],.wy-form input[type=\"color\"]{\n        margin-bottom:0.3em;\n        display:block}\n\n    .wy-form label{\n        margin-bottom:0.3em;\n        display:block}\n\n    .wy-form input[type=\"password\"],.wy-form input[type=\"email\"],.wy-form input[type=\"url\"],.wy-form input[type=\"date\"],.wy-form input[type=\"month\"],.wy-form input[type=\"time\"],.wy-form input[type=\"datetime\"],.wy-form input[type=\"datetime-local\"],.wy-form input[type=\"week\"],.wy-form input[type=\"number\"],.wy-form input[type=\"search\"],.wy-form input[type=\"tel\"],.wy-form input[type=\"color\"]{\n        margin-bottom:0}\n\n    .wy-form-aligned .wy-control-group label{\n        margin-bottom:0.3em;\n        text-align:left;\n        display:block;\n        width:100%}\n\n    .wy-form-aligned .wy-control{\n        margin:1.5em 0 0 0}\n\n    .wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{\n        display:block;\n        font-size:80%;\n        padding:6px 0}\n\n}\n\n@media screen and (max-width: 768px){\n    .tablet-hide{\n        display:none}\n\n}\n\n@media screen and (max-width: 480px){\n    .mobile-hide{\n        display:none}\n\n}\n\n.float-left{\n    float:left}\n\n.float-right{\n    float:right}\n\n.full-width{\n    width:100%}\n\n.wy-table,.rst-content table.docutils,.rst-content table.field-list{\n    border-collapse:collapse;\n    border-spacing:0;\n    empty-cells:show;\n    margin-bottom:24px}\n\n.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{\n    color:#000;\n    font:italic 85%/1 arial,sans-serif;\n    padding:1em 0;\n    text-align:center}\n\n.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{\n    font-size:90%;\n    margin:0;\n    overflow:visible;\n    padding:8px 16px}\n\n.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{\n    border-left-width:0}\n\n.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{\n    color:#000;\n    text-align:left;\n    vertical-align:bottom;\n    white-space:nowrap}\n\n.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{\n    font-weight:bold;\n    border-bottom:solid 2px #e1e4e5}\n\n.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{\n    background-color:transparent;\n    vertical-align:middle}\n\n.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{\n    line-height:18px}\n\n.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{\n    margin-bottom:0}\n\n.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{\n    width:1%;\n    padding-right:0}\n\n.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{\n    margin:0}\n\n.wy-table-secondary{\n    color:gray;\n    font-size:90%}\n\n.wy-table-tertiary{\n    color:gray;\n    font-size:80%}\n\n.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{\n    background-color:#f3f6f6}\n\n.wy-table-backed{\n    background-color:#f3f6f6}\n\n.wy-table-bordered-all,.rst-content table.docutils{\n    border:1px solid #e1e4e5}\n\n.wy-table-bordered-all td,.rst-content table.docutils td{\n    border-bottom:1px solid #e1e4e5;\n    border-left:1px solid #e1e4e5}\n\n.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{\n    border-bottom-width:0}\n\n.wy-table-bordered{\n    border:1px solid #e1e4e5}\n\n.wy-table-bordered-rows td{\n    border-bottom:1px solid #e1e4e5}\n\n.wy-table-bordered-rows tbody>tr:last-child td{\n    border-bottom-width:0}\n\n.wy-table-horizontal tbody>tr:last-child td{\n    border-bottom-width:0}\n\n.wy-table-horizontal td,.wy-table-horizontal th{\n    border-width:0 0 1px 0;\n    border-bottom:1px solid #e1e4e5}\n\n.wy-table-horizontal tbody>tr:last-child td{\n    border-bottom-width:0}\n\n.wy-table-responsive{\n    margin-bottom:24px;\n    max-width:100%;\n    overflow:auto}\n\n.wy-table-responsive table{\n    margin-bottom:0 !important}\n\n.wy-table-responsive table td,.wy-table-responsive table th{\n    white-space:nowrap}\n\na{\n    color:#2980B9;\n    text-decoration:none;\n    cursor:pointer}\n\na:hover{\n    color:#3091d1}\n\na:visited{\n    color:#9B59B6}\n\nhtml{\n    height:100%;\n    overflow-x:hidden}\n\nbody{\n    font-family:\"Lato\",\"proxima-nova\",\"Helvetica Neue\",Arial,sans-serif;\n    font-weight:normal;\n    color:#404040;\n    min-height:100%;\n    overflow-x:hidden;\n    background:#edf0f2}\n\n.wy-text-left{\n    text-align:left}\n\n.wy-text-center{\n    text-align:center}\n\n.wy-text-right{\n    text-align:right}\n\n.wy-text-large{\n    font-size:120%}\n\n.wy-text-normal{\n    font-size:100%}\n\n.wy-text-small,small{\n    font-size:80%}\n\n.wy-text-strike{\n    text-decoration:line-through}\n\n.wy-text-warning{\n    color:#E67E22 !important}\n\na.wy-text-warning:hover{\n    color:#eb9950 !important}\n\n.wy-text-info{\n    color:#2980B9 !important}\n\na.wy-text-info:hover{\n    color:#409ad5 !important}\n\n.wy-text-success{\n    color:#27AE60 !important}\n\na.wy-text-success:hover{\n    color:#36d278 !important}\n\n.wy-text-danger{\n    color:#E74C3C !important}\n\na.wy-text-danger:hover{\n    color:#ed7669 !important}\n\n.wy-text-neutral{\n    color:#404040 !important}\n\na.wy-text-neutral:hover{\n    color:#595959 !important}\n\nh1,h2,h3,h4,h5,h6,legend{\n    margin-top:0;\n    font-weight:700;\n    font-family:\"Roboto Slab\",\"ff-tisa-web-pro\",\"Georgia\",Arial,sans-serif}\n\np{\n    line-height:24px;\n    margin:0;\n    font-size:16px;\n    margin-bottom:24px}\n\nh1{\n    font-size:175%}\n\nh2{\n    font-size:150%}\n\nh3{\n    font-size:125%}\n\nh4{\n    font-size:115%}\n\nh5{\n    font-size:110%}\n\nh6{\n    font-size:100%}\n\nhr{\n    display:block;\n    height:1px;\n    border:0;\n    border-top:1px solid #e1e4e5;\n    margin:24px 0;\n    padding:0}\n\ncode,.rst-content tt{\n    white-space:nowrap;\n    max-width:100%;\n    background:#fff;\n    border:solid 1px #e1e4e5;\n    font-size:75%;\n    padding:0 5px;\n    font-family:Consolas,\"Andale Mono WT\",\"Andale Mono\",\"Lucida Console\",\"Lucida Sans Typewriter\",\"DejaVu Sans Mono\",\"Bitstream Vera Sans Mono\",\"Liberation Mono\",\"Nimbus Mono L\",Monaco,\"Courier New\",Courier,monospace;\n    color:#E74C3C;\n    overflow-x:auto}\n\ncode.code-large,.rst-content tt.code-large{\n    font-size:90%}\n\n.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{\n    list-style:disc;\n    line-height:24px;\n    margin-bottom:24px}\n\n.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{\n    list-style:disc;\n    margin-left:24px}\n\n.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{\n                                                                                                                                  margin-bottom:0}\n\n.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{\n    margin-bottom:0}\n\n.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{\n    list-style:circle}\n\n.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{\n    list-style:square}\n\n.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{\n    list-style:decimal}\n\n.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{\n    list-style:decimal;\n    line-height:24px;\n    margin-bottom:24px}\n\n.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{\n    list-style:decimal;\n    margin-left:24px}\n\n.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{\n                                                                                                                           margin-bottom:0}\n\n.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{\n    margin-bottom:0}\n\n.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{\n    list-style:disc}\n\n.codeblock-example{\n    border:1px solid #e1e4e5;\n    border-bottom:none;\n    padding:24px;\n    padding-top:48px;\n    font-weight:500;\n    background:#fff;\n    position:relative}\n\n.codeblock-example:after{\n    content:\"Example\";\n    position:absolute;\n    top:0px;\n    left:0px;\n    background:#9B59B6;\n    color:#fff;\n    padding:6px 12px}\n\n.codeblock-example.prettyprint-example-only{\n    border:1px solid #e1e4e5;\n    margin-bottom:24px}\n\n.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{\n    border:1px solid #e1e4e5;\n    padding:0px;\n    overflow-x:auto;\n    background:#fff;\n    margin:1px 0 24px 0}\n\n.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{\n    border:none;\n    background:none;\n    margin:0}\n\ndiv[class^='highlight'] td.code{\n    width:100%}\n\n.linenodiv pre{\n    border-right:solid 1px #e6e9ea;\n    margin:0;\n    padding:12px 12px;\n    font-family:Consolas,\"Andale Mono WT\",\"Andale Mono\",\"Lucida Console\",\"Lucida Sans Typewriter\",\"DejaVu Sans Mono\",\"Bitstream Vera Sans Mono\",\"Liberation Mono\",\"Nimbus Mono L\",Monaco,\"Courier New\",Courier,monospace;\n    font-size:12px;\n    line-height:1.5;\n    color:#d9d9d9}\n\ndiv[class^='highlight'] pre{\n    white-space:pre;\n    margin:0;\n    padding:12px 12px;\n    font-family:Consolas,\"Andale Mono WT\",\"Andale Mono\",\"Lucida Console\",\"Lucida Sans Typewriter\",\"DejaVu Sans Mono\",\"Bitstream Vera Sans Mono\",\"Liberation Mono\",\"Nimbus Mono L\",Monaco,\"Courier New\",Courier,monospace;\n    font-size:12px;\n    line-height:1.5;\n    display:block;\n    overflow:auto;\n    color:#404040}\n\n@media print{\n    .codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{\n        white-space:pre-wrap}\n\n}\n\n.hll{\n    background-color:#ffc;\n    margin:0 -12px;\n    padding:0 12px;\n    display:block}\n\n.c{\n    color:#998;\n    font-style:italic}\n\n.err{\n    color:#a61717;\n    background-color:#e3d2d2}\n\n.k{\n    font-weight:bold}\n\n.o{\n    font-weight:bold}\n\n.cm{\n    color:#998;\n    font-style:italic}\n\n.cp{\n    color:#999;\n    font-weight:bold}\n\n.c1{\n    color:#998;\n    font-style:italic}\n\n.cs{\n    color:#999;\n    font-weight:bold;\n    font-style:italic}\n\n.gd{\n    color:#000;\n    background-color:#fdd}\n\n.gd .x{\n    color:#000;\n    background-color:#faa}\n\n.ge{\n    font-style:italic}\n\n.gr{\n    color:#a00}\n\n.gh{\n    color:#999}\n\n.gi{\n    color:#000;\n    background-color:#dfd}\n\n.gi .x{\n    color:#000;\n    background-color:#afa}\n\n.go{\n    color:#888}\n\n.gp{\n    color:#555}\n\n.gs{\n    font-weight:bold}\n\n.gu{\n    color:purple;\n    font-weight:bold}\n\n.gt{\n    color:#a00}\n\n.kc{\n    font-weight:bold}\n\n.kd{\n    font-weight:bold}\n\n.kn{\n    font-weight:bold}\n\n.kp{\n    font-weight:bold}\n\n.kr{\n    font-weight:bold}\n\n.kt{\n    color:#458;\n    font-weight:bold}\n\n.m{\n    color:#099}\n\n.s{\n    color:#d14}\n\n.n{\n    color:#333}\n\n.na{\n    color:teal}\n\n.nb{\n    color:#0086b3}\n\n.nc{\n    color:#458;\n    font-weight:bold}\n\n.no{\n    color:teal}\n\n.ni{\n    color:purple}\n\n.ne{\n    color:#900;\n    font-weight:bold}\n\n.nf{\n    color:#900;\n    font-weight:bold}\n\n.nn{\n    color:#555}\n\n.nt{\n    color:navy}\n\n.nv{\n    color:teal}\n\n.ow{\n    font-weight:bold}\n\n.w{\n    color:#bbb}\n\n.mf{\n    color:#099}\n\n.mh{\n    color:#099}\n\n.mi{\n    color:#099}\n\n.mo{\n    color:#099}\n\n.sb{\n    color:#d14}\n\n.sc{\n    color:#d14}\n\n.sd{\n    color:#d14}\n\n.s2{\n    color:#d14}\n\n.se{\n    color:#d14}\n\n.sh{\n    color:#d14}\n\n.si{\n    color:#d14}\n\n.sx{\n    color:#d14}\n\n.sr{\n    color:#009926}\n\n.s1{\n    color:#d14}\n\n.ss{\n    color:#990073}\n\n.bp{\n    color:#999}\n\n.vc{\n    color:teal}\n\n.vg{\n    color:teal}\n\n.vi{\n    color:teal}\n\n.il{\n    color:#099}\n\n.gc{\n    color:#999;\n    background-color:#EAF2F5}\n\n.wy-breadcrumbs li{\n    display:inline-block}\n\n.wy-breadcrumbs li.wy-breadcrumbs-aside{\n    float:right}\n\n.wy-breadcrumbs li a{\n    display:inline-block;\n    padding:5px}\n\n.wy-breadcrumbs li a:first-child{\n    padding-left:0}\n\n.wy-breadcrumbs-extra{\n    margin-bottom:0;\n    color:#b3b3b3;\n    font-size:80%;\n    display:inline-block}\n\n@media screen and (max-width: 480px){\n    .wy-breadcrumbs-extra{\n        display:none}\n\n    .wy-breadcrumbs li.wy-breadcrumbs-aside{\n        display:none}\n\n}\n\n@media print{\n    .wy-breadcrumbs li.wy-breadcrumbs-aside{\n        display:none}\n\n}\n\n.wy-affix{\n    position:fixed;\n    top:1.618em}\n\n.wy-menu a:hover{\n    text-decoration:none}\n\n.wy-menu-horiz{\n    *zoom:1}\n\n.wy-menu-horiz:before,.wy-menu-horiz:after{\n    display:table;\n    content:\"\"}\n\n.wy-menu-horiz:after{\n    clear:both}\n\n.wy-menu-horiz ul,.wy-menu-horiz li{\n    display:inline-block}\n\n.wy-menu-horiz li:hover{\n    background:rgba(255,255,255,0.1)}\n\n.wy-menu-horiz li.divide-left{\n    border-left:solid 1px #404040}\n\n.wy-menu-horiz li.divide-right{\n    border-right:solid 1px #404040}\n\n.wy-menu-horiz a{\n    height:32px;\n    display:inline-block;\n    line-height:32px;\n    padding:0 16px}\n\n.wy-menu-vertical header{\n    height:32px;\n    display:inline-block;\n    line-height:32px;\n    padding:0 1.618em;\n    display:block;\n    font-weight:bold;\n    text-transform:uppercase;\n    font-size:80%;\n    color:#2980B9;\n    white-space:nowrap}\n\n.wy-menu-vertical ul{\n    margin-bottom:0}\n\n.wy-menu-vertical li.divide-top{\n    border-top:solid 1px #404040}\n\n.wy-menu-vertical li.divide-bottom{\n    border-bottom:solid 1px #404040}\n\n.wy-menu-vertical li.current{\n    background:#e3e3e3}\n\n.wy-menu-vertical li.current a{\n    color:gray;\n    border-right:solid 1px #c9c9c9;\n    padding:0.4045em 2.427em}\n\n.wy-menu-vertical li.current a:hover{\n    background:#d6d6d6}\n\n.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{\n    color:#404040;\n    padding:0.4045em 1.618em;\n    font-weight:bold;\n    position:relative;\n    background:#fcfcfc;\n    border:none;\n    border-bottom:solid 1px #c9c9c9;\n    border-top:solid 1px #c9c9c9;\n    padding-left:1.618em -4px}\n\n.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{\n    background:#fcfcfc}\n\n.wy-menu-vertical li.toctree-l2.current>a{\n    background:#c9c9c9;\n    padding:0.4045em 2.427em}\n\n.wy-menu-vertical li.current ul{\n    display:block}\n\n.wy-menu-vertical li ul{\n    margin-bottom:0;\n    display:none}\n\n.wy-menu-vertical .local-toc li ul{\n    display:block}\n\n.wy-menu-vertical li ul li a{\n    margin-bottom:0;\n    color:#b3b3b3;\n    font-weight:normal}\n\n.wy-menu-vertical a{\n    display:inline-block;\n    line-height:18px;\n    padding:0.4045em 1.618em;\n    display:block;\n    position:relative;\n    font-size:90%;\n    color:#b3b3b3}\n\n.wy-menu-vertical a:hover{\n    background-color:#4e4a4a;\n    cursor:pointer}\n\n.wy-menu-vertical a:active{\n    background-color:#2980B9;\n    cursor:pointer;\n    color:#fff}\n\n.wy-side-nav-search{\n    z-index:200;\n    background-color:#2980B9;\n    text-align:center;\n    padding:0.809em;\n    display:block;\n    color:#fcfcfc;\n    margin-bottom:0.809em}\n\n.wy-side-nav-search input[type=text]{\n    width:100%;\n    border-radius:50px;\n    padding:6px 12px;\n    border-color:#2472a4}\n\n.wy-side-nav-search img{\n    display:block;\n    margin:auto auto 0.809em auto;\n    height:45px;\n    width:45px;\n    background-color:#2980B9;\n    padding:5px;\n    border-radius:100%}\n\n.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{\n    color:#fcfcfc;\n    font-size:100%;\n    font-weight:bold;\n    display:inline-block;\n    padding:4px 6px;\n    margin-bottom:0.809em}\n\n.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{\n    background:rgba(255,255,255,0.1)}\n\n.wy-nav .wy-menu-vertical header{\n    color:#2980B9}\n\n.wy-nav .wy-menu-vertical a{\n    color:#b3b3b3}\n\n.wy-nav .wy-menu-vertical a:hover{\n    background-color:#2980B9;\n    color:#fff}\n\n[data-menu-wrap]{\n    -webkit-transition:all 0.2s ease-in;\n    -moz-transition:all 0.2s ease-in;\n    transition:all 0.2s ease-in;\n    position:absolute;\n    opacity:1;\n    width:100%;\n    opacity:0}\n\n[data-menu-wrap].move-center{\n    left:0;\n    right:auto;\n    opacity:1}\n\n[data-menu-wrap].move-left{\n    right:auto;\n    left:-100%;\n    opacity:0}\n\n[data-menu-wrap].move-right{\n    right:-100%;\n    left:auto;\n    opacity:0}\n\n.wy-body-for-nav{\n    background:left repeat-y #fcfcfc;\n    background-image:url(data:image/png;\n                         base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);\n    background-size:300px 1px}\n\n.wy-grid-for-nav{\n    position:absolute;\n    width:100%;\n    height:100%}\n\n.wy-nav-side{\n    position:absolute;\n    top:0;\n    left:0;\n    width:300px;\n    overflow:hidden;\n    min-height:100%;\n    background:#343131;\n    z-index:200}\n\n.wy-nav-top{\n    display:none;\n    background:#2980B9;\n    color:#fff;\n    padding:0.4045em 0.809em;\n    position:relative;\n    line-height:50px;\n    text-align:center;\n    font-size:100%;\n    *zoom:1}\n\n.wy-nav-top:before,.wy-nav-top:after{\n    display:table;\n    content:\"\"}\n\n.wy-nav-top:after{\n    clear:both}\n\n.wy-nav-top a{\n    color:#fff;\n    font-weight:bold}\n\n.wy-nav-top img{\n    margin-right:12px;\n    height:45px;\n    width:45px;\n    background-color:#2980B9;\n    padding:5px;\n    border-radius:100%}\n\n.wy-nav-top i{\n    font-size:30px;\n    float:left;\n    cursor:pointer}\n\n.wy-nav-content-wrap{\n    margin-left:300px;\n    background:#fcfcfc;\n    min-height:100%}\n\n.wy-nav-content{\n    padding:1.618em 3.236em;\n    height:100%;\n    max-width:800px;\n    margin:auto}\n\n.wy-body-mask{\n    position:fixed;\n    width:100%;\n    height:100%;\n    background:rgba(0,0,0,0.2);\n    display:none;\n    z-index:499}\n\n.wy-body-mask.on{\n    display:block}\n\nfooter{\n    color:#999}\n\nfooter p{\n    margin-bottom:12px}\n\n.rst-footer-buttons{\n    *zoom:1}\n\n.rst-footer-buttons:before,.rst-footer-buttons:after{\n    display:table;\n    content:\"\"}\n\n.rst-footer-buttons:after{\n    clear:both}\n\n#search-results .search li{\n    margin-bottom:24px;\n    border-bottom:solid 1px #e1e4e5;\n    padding-bottom:24px}\n\n#search-results .search li:first-child{\n    border-top:solid 1px #e1e4e5;\n    padding-top:24px}\n\n#search-results .search li a{\n    font-size:120%;\n    margin-bottom:12px;\n    display:inline-block}\n\n#search-results .context{\n    color:gray;\n    font-size:90%}\n\n@media screen and (max-width: 768px){\n    .wy-body-for-nav{\n        background:#fcfcfc}\n\n    .wy-nav-top{\n        display:block}\n\n    .wy-nav-side{\n        left:-300px}\n\n    .wy-nav-side.shift{\n        width:85%;\n        left:0}\n\n    .wy-nav-content-wrap{\n        margin-left:0}\n\n    .wy-nav-content-wrap .wy-nav-content{\n        padding:1.618em}\n\n    .wy-nav-content-wrap.shift{\n        position:fixed;\n        min-width:100%;\n        left:85%;\n        top:0;\n        height:100%;\n        overflow:hidden}\n\n}\n\n@media screen and (min-width: 1400px){\n    .wy-nav-content-wrap{\n        background:rgba(0,0,0,0.05)}\n\n    .wy-nav-content{\n        margin:0;\n        background:#fcfcfc}\n\n}\n\n@media print{\n    .rst-versions,footer,.wy-nav-side{\n        display:none}\n\n    .wy-nav-content-wrap{\n        margin-left:0}\n\n}\n\nnav.stickynav{\n    position:fixed;\n    top:0}\n\n.rst-versions{\n    position:fixed;\n    bottom:0;\n    left:0;\n    width:300px;\n    color:#fcfcfc;\n    background:#1f1d1d;\n    border-top:solid 10px #343131;\n    font-family:\"Lato\",\"proxima-nova\",\"Helvetica Neue\",Arial,sans-serif;\n    z-index:400}\n\n.rst-versions a{\n    color:#2980B9;\n    text-decoration:none}\n\n.rst-versions .rst-badge-small{\n    display:none}\n\n.rst-versions .rst-current-version{\n    padding:12px;\n    background-color:#272525;\n    display:block;\n    text-align:right;\n    font-size:90%;\n    cursor:pointer;\n    color:#27AE60;\n    *zoom:1}\n\n.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{\n    display:table;\n    content:\"\"}\n\n.rst-versions .rst-current-version:after{\n    clear:both}\n\n.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .icon{\n    color:#fcfcfc}\n\n.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{\n    float:left}\n\n.rst-versions .rst-current-version .icon-book{\n    float:left}\n\n.rst-versions .rst-current-version.rst-out-of-date{\n    background-color:#E74C3C;\n    color:#fff}\n\n.rst-versions .rst-current-version.rst-active-old-version{\n    background-color:#F1C40F;\n    color:#000}\n\n.rst-versions.shift-up .rst-other-versions{\n    display:block}\n\n.rst-versions .rst-other-versions{\n    font-size:90%;\n    padding:12px;\n    color:gray;\n    display:none}\n\n.rst-versions .rst-other-versions hr{\n    display:block;\n    height:1px;\n    border:0;\n    margin:20px 0;\n    padding:0;\n    border-top:solid 1px #413d3d}\n\n.rst-versions .rst-other-versions dd{\n    display:inline-block;\n    margin:0}\n\n.rst-versions .rst-other-versions dd a{\n    display:inline-block;\n    padding:6px;\n    color:#fcfcfc}\n\n.rst-versions.rst-badge{\n    width:auto;\n    bottom:20px;\n    right:20px;\n    left:auto;\n    border:none;\n    max-width:300px}\n\n.rst-versions.rst-badge .icon-book{\n    float:none}\n\n.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{\n    float:none}\n\n.rst-versions.rst-badge.shift-up .rst-current-version{\n    text-align:right}\n\n.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{\n    float:left}\n\n.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{\n    float:left}\n\n.rst-versions.rst-badge .rst-current-version{\n    width:auto;\n    height:30px;\n    line-height:30px;\n    padding:0 6px;\n    display:block;\n    text-align:center}\n\n@media screen and (max-width: 768px){\n    .rst-versions{\n        width:85%;\n        display:none}\n\n    .rst-versions.shift{\n        display:block}\n\n    img{\n        width:100%;\n        height:auto}\n\n}\n\n.rst-content img{\n    max-width:100%;\n    height:auto !important}\n\n.rst-content div.figure{\n    margin-bottom:24px}\n\n.rst-content div.figure.align-center{\n    text-align:center}\n\n.rst-content .section>img,.rst-content .section>a>img{\n    margin-bottom:24px}\n\n.rst-content blockquote{\n    margin-left:24px;\n    line-height:24px;\n    margin-bottom:24px}\n\n.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{\n    margin-bottom:0}\n\n.rst-content .admonition-title:before{\n    margin-right:4px}\n\n.rst-content .admonition table{\n    border-color:rgba(0,0,0,0.1)}\n\n.rst-content .admonition table td,.rst-content .admonition table th{\n    background:transparent !important;\n    border-color:rgba(0,0,0,0.1) !important}\n\n.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{\n    list-style:lower-alpha}\n\n.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{\n    list-style:upper-alpha}\n\n.rst-content .section ol p,.rst-content .section ul p{\n    margin-bottom:12px}\n\n.rst-content .line-block{\n    margin-left:24px}\n\n.rst-content .topic-title{\n    font-weight:bold;\n    margin-bottom:12px}\n\n.rst-content .toc-backref{\n    color:#404040}\n\n.rst-content .align-right{\n    float:right;\n    margin:0px 0px 24px 24px}\n\n.rst-content .align-left{\n    float:left;\n    margin:0px 24px 24px 0px}\n\n.rst-content .align-center{\n    margin:auto;\n    display:block}\n\n.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink{\n    display:none;\n    visibility:hidden;\n    font-size:14px}\n\n.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after{\n    visibility:visible;\n    content:\"\";\n    font-family:FontAwesome;\n    display:inline-block}\n\n.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink{\n    display:inline-block}\n\n.rst-content .sidebar{\n    float:right;\n    width:40%;\n    display:block;\n    margin:0 0 24px 24px;\n    padding:24px;\n    background:#f3f6f6;\n    border:solid 1px #e1e4e5}\n\n.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{\n    font-size:90%}\n\n.rst-content .sidebar .last{\n    margin-bottom:0}\n\n.rst-content .sidebar .sidebar-title{\n    display:block;\n    font-family:\"Roboto Slab\",\"ff-tisa-web-pro\",\"Georgia\",Arial,sans-serif;\n    font-weight:bold;\n    background:#e1e4e5;\n    padding:6px 12px;\n    margin:-24px;\n    margin-bottom:24px;\n    font-size:100%}\n\n.rst-content .highlighted{\n    background:#F1C40F;\n    display:inline-block;\n    font-weight:bold;\n    padding:0 6px}\n\n.rst-content .footnote-reference,.rst-content .citation-reference{\n    vertical-align:super;\n    font-size:90%}\n\n.rst-content table.docutils.citation,.rst-content table.docutils.footnote{\n    background:none;\n    border:none;\n    color:#999}\n\n.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{\n    border:none;\n    background-color:transparent !important;\n    white-space:normal}\n\n.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{\n    padding-left:0;\n    padding-right:0;\n    vertical-align:top}\n\n.rst-content table.field-list{\n    border:none}\n\n.rst-content table.field-list td{\n    border:none;\n    padding-top:5px}\n\n.rst-content table.field-list td>strong{\n    display:inline-block;\n    margin-top:3px}\n\n.rst-content table.field-list .field-name{\n    padding-right:10px;\n    text-align:left;\n    white-space:nowrap}\n\n.rst-content table.field-list .field-body{\n    text-align:left;\n    padding-left:0}\n\n.rst-content tt{\n    color:#000}\n\n.rst-content tt big,.rst-content tt em{\n    font-size:100% !important;\n    line-height:normal}\n\n.rst-content tt .xref,a .rst-content tt{\n    font-weight:bold}\n\n.rst-content a tt{\n    color:#2980B9}\n\n.rst-content dl{\n    margin-bottom:24px}\n\n.rst-content dl dt{\n    font-weight:bold}\n\n.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{\n    margin-bottom:12px !important}\n\n.rst-content dl dd{\n    margin:0 0 12px 24px}\n\n.rst-content dl:not(.docutils){\n    margin-bottom:24px}\n\n.rst-content dl:not(.docutils) dt{\n    display:inline-block;\n    margin:6px 0;\n    font-size:90%;\n    line-height:normal;\n    background:#e7f2fa;\n    color:#2980B9;\n    border-top:solid 3px #6ab0de;\n    padding:6px;\n    position:relative}\n\n.rst-content dl:not(.docutils) dt:before{\n    color:#6ab0de}\n\n.rst-content dl:not(.docutils) dt .headerlink{\n    color:#404040;\n    font-size:100% !important}\n\n.rst-content dl:not(.docutils) dl dt{\n    margin-bottom:6px;\n    border:none;\n    border-left:solid 3px #ccc;\n    background:#f0f0f0;\n    color:gray}\n\n.rst-content dl:not(.docutils) dl dt .headerlink{\n    color:#404040;\n    font-size:100% !important}\n\n.rst-content dl:not(.docutils) dt:first-child{\n    margin-top:0}\n\n.rst-content dl:not(.docutils) tt{\n    font-weight:bold}\n\n.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname{\n    background-color:transparent;\n    border:none;\n    padding:0;\n    font-size:100% !important}\n\n.rst-content dl:not(.docutils) tt.descname{\n    font-weight:bold}\n\n.rst-content dl:not(.docutils) .optional{\n    display:inline-block;\n    padding:0 4px;\n    color:#000;\n    font-weight:bold}\n\n.rst-content dl:not(.docutils) .property{\n    display:inline-block;\n    padding-right:8px}\n\n.rst-content .viewcode-link,.rst-content .viewcode-back{\n    display:inline-block;\n    color:#27AE60;\n    font-size:80%;\n    padding-left:24px}\n\n.rst-content .viewcode-back{\n    display:block;\n    float:right}\n\n.rst-content p.rubric{\n    margin-bottom:12px;\n    font-weight:bold}\n\n@media screen and (max-width: 480px){\n    .rst-content .sidebar{\n        width:100%}\n\n}\n\nspan[id*='MathJax-Span']{\n    color:#404040}\n\n.math{\n    text-align:center}\n\n\n/*# sourceMappingURL=theme.css.map */\n"
  },
  {
    "path": "simple_eval.py",
    "content": "\"\"\"\nSimpleEval - (C) 2013-2019 Daniel Fairhead\n-------------------------------------\nAn short, easy to use, safe and reasonably extensible expression evaluator.\nDesigned for things like in a website where you want to allow the user to\ngenerate a string, or a number from some other input, without allowing full\neval() or other unsafe or needlessly complex linguistics.\n-------------------------------------\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n-------------------------------------\nInitial idea copied from J.F. Sebastian on Stack Overflow\n( http://stackoverflow.com/a/9558001/1973500 ) with\nmodifications and many improvements.\n-------------------------------------\nContributors:\n- corro (Robin Baumgartner) (py3k)\n- dratchkov (David R) (nested dicts)\n- marky1991 (Mark Young) (slicing)\n- T045T (Nils Berg) (!=, py3kstr, obj.\n- perkinslr (Logan Perkins) (.__globals__ or .func_ breakouts)\n- impala2 (Kirill Stepanov) (massive _eval refactor)\n- gk (ugik) (Other iterables than str can DOS too, and can be made)\n- daveisfera (Dave Johansen) 'not' Boolean op, Pycharm, pep8, various other fixes\n- xaled (Khalid Grandi) method chaining correctly, double-eval bugfix.\n- EdwardBetts (Edward Betts) spelling correction.\n- charlax (Charles-Axel Dein charlax) Makefile and cleanups\n- mommothazaz123 (Andrew Zhu) f\"string\" support, Python 3.8 support\n- lubieowoce (Uryga) various potential vulnerabilities\n- JCavallo (Jean Cavallo) names dict shouldn't be modified\n- Birne94 (Daniel Birnstiel) for fixing leaking generators.\n- patricksurry (Patrick Surry) or should return last value, even if falsy.\n- shughes-uk (Samantha Hughes) python w/o 'site' should not fail to import.\n-------------------------------------\nBasic Usage:\n>>> s = SimpleEval()\n>>> s.eval(\"20 + 30\")\n50\nYou can add your own functions easily too:\nif file.txt contents is \"11\"\n>>> def get_file():\n...     with open(\"file.txt\", 'r') as f:\n...         return f.read()\n>>> s.functions[\"get_file\"] = get_file\n>>> s.eval(\"int(get_file()) + 31\")\n42\nFor more information, see the full package documentation on pypi, or the github\nrepo.\n-----------\nIf you don't need to re-use the evaluator (with it's names, functions, etc),\nthen you can use the simple_eval() function:\n>>> simple_eval(\"21 + 19\")\n40\nYou can pass names, operators and functions to the simple_eval function as\nwell:\n>>> simple_eval(\"40 + two\", names={\"two\": 2})\n42\n\"\"\"\n\nimport ast\nimport operator as op\nimport sys\nimport warnings\nfrom random import random\n\nPYTHON3 = sys.version_info[0] == 3\n\n########################################\n# Module wide 'globals'\n\nMAX_STRING_LENGTH = 100000\nMAX_COMPREHENSION_LENGTH = 10000\nMAX_POWER = 4000000  # highest exponent\nDISALLOW_PREFIXES = ['_', 'func_']\nDISALLOW_METHODS = ['format', 'format_map', 'mro']\n\n# Disallow functions:\n# This, strictly speaking, is not necessary.  These /should/ never be accessable anyway,\n# if DISALLOW_PREFIXES and DISALLOW_METHODS are all right.  This is here to try and help\n# people not be stupid.  Allowing these functions opens up all sorts of holes - if any of\n# their functionality is required, then please wrap them up in a safe container.  And think\n# very hard about it first.  And don't say I didn't warn you.\n# builtins is a dict in python >3.6 but a module before\nDISALLOW_FUNCTIONS = {\n        type, isinstance, eval, getattr, setattr, repr, compile, open\n        }\nif hasattr(__builtins__, 'help') or \\\n        (hasattr(__builtins__, '__contains__') and 'help' in __builtins__):\n    # PyInstaller environment doesn't include this module.\n    DISALLOW_FUNCTIONS.add(help)\n\n\nif PYTHON3:\n    exec('DISALLOW_FUNCTIONS.add(exec)') # exec is not a function in Python2...\n\n\n########################################\n# Exceptions:\n\n\nclass InvalidExpression(Exception):\n    \"\"\" Generic Exception \"\"\"\n\n    pass\n\n\nclass FunctionNotDefined(InvalidExpression):\n    \"\"\" sorry! That function isn't defined! \"\"\"\n\n    def __init__(self, func_name, expression):\n        self.message = \"Function '{0}' not defined,\" \\\n                       \" for expression '{1}'.\".format(func_name, expression)\n        setattr(self, 'func_name', func_name)  # bypass 2to3 confusion.\n        self.expression = expression\n\n        # pylint: disable=bad-super-call\n        super(InvalidExpression, self).__init__(self.message)\n\n\nclass NameNotDefined(InvalidExpression):\n    \"\"\" a name isn't defined. \"\"\"\n\n    def __init__(self, name, expression):\n        self.name = name\n        self.message = \"'{0}' is not defined for expression '{1}'\".format(\n            name, expression)\n        self.expression = expression\n\n        # pylint: disable=bad-super-call\n        super(InvalidExpression, self).__init__(self.message)\n\n\nclass AttributeDoesNotExist(InvalidExpression):\n    \"\"\"attribute does not exist\"\"\"\n\n    def __init__(self, attr, expression):\n        self.message = \\\n            \"Attribute '{0}' does not exist in expression '{1}'\".format(\n                attr, expression)\n        self.attr = attr\n        self.expression = expression\n\n\nclass FeatureNotAvailable(InvalidExpression):\n    \"\"\" What you're trying to do is not allowed. \"\"\"\n\n    pass\n\n\nclass NumberTooHigh(InvalidExpression):\n    \"\"\" Sorry! That number is too high. I don't want to spend the\n        next 10 years evaluating this expression! \"\"\"\n\n    pass\n\n\nclass IterableTooLong(InvalidExpression):\n    \"\"\" That iterable is **way** too long, baby. \"\"\"\n\n    pass\n\nclass AssignmentAttempted(UserWarning):\n    pass\n\n########################################\n# Default simple functions to include:\n\n\ndef random_int(top):\n    \"\"\" return a random int below <top> \"\"\"\n\n    return int(random() * top)\n\n\ndef safe_power(a, b):  # pylint: disable=invalid-name\n    \"\"\" a limited exponent/to-the-power-of function, for safety reasons \"\"\"\n\n    if abs(a) > MAX_POWER or abs(b) > MAX_POWER:\n        raise NumberTooHigh(\"Sorry! I don't want to evaluate {0} ** {1}\"\n                            .format(a, b))\n    return a ** b\n\n\ndef safe_mult(a, b):  # pylint: disable=invalid-name\n    \"\"\" limit the number of times an iterable can be repeated... \"\"\"\n\n    if hasattr(a, '__len__') and b * len(a) > MAX_STRING_LENGTH:\n        raise IterableTooLong('Sorry, I will not evalute something that long.')\n    if hasattr(b, '__len__') and a * len(b) > MAX_STRING_LENGTH:\n        raise IterableTooLong('Sorry, I will not evalute something that long.')\n\n    return a * b\n\n\ndef safe_add(a, b):  # pylint: disable=invalid-name\n    \"\"\" iterable length limit again \"\"\"\n\n    if hasattr(a, '__len__') and hasattr(b, '__len__'):\n        if len(a) + len(b) > MAX_STRING_LENGTH:\n            raise IterableTooLong(\"Sorry, adding those two together would\"\n                                  \" make something too long.\")\n    return a + b\n\n\n########################################\n# Defaults for the evaluator:\n\nDEFAULT_OPERATORS = {ast.Add: safe_add, ast.Sub: op.sub, ast.Mult: safe_mult,\n                     ast.Div: op.truediv, ast.FloorDiv: op.floordiv,\n                     ast.Pow: safe_power, ast.Mod: op.mod,\n                     ast.Eq: op.eq, ast.NotEq: op.ne,\n                     ast.Gt: op.gt, ast.Lt: op.lt,\n                     ast.GtE: op.ge, ast.LtE: op.le,\n                     ast.Not: op.not_,\n                     ast.USub: op.neg, ast.UAdd: op.pos,\n                     ast.In: lambda x, y: op.contains(y, x),\n                     ast.NotIn: lambda x, y: not op.contains(y, x),\n                     ast.Is: lambda x, y: x is y,\n                     ast.IsNot: lambda x, y: x is not y,\n                     }\n\nDEFAULT_FUNCTIONS = {\"rand\": random, \"randint\": random_int,\n                     \"int\": int, \"float\": float,\n                     \"str\": str if PYTHON3 else unicode}\n\nDEFAULT_NAMES = {\"True\": True, \"False\": False, \"None\": None}\n\nATTR_INDEX_FALLBACK = True\n\n\n########################################\n# And the actual evaluator:\n\n\nclass SimpleEval(object):  # pylint: disable=too-few-public-methods\n    \"\"\" A very simple expression parser.\n        >>> s = SimpleEval()\n        >>> s.eval(\"20 + 30 - ( 10 * 5)\")\n        0\n        \"\"\"\n    expr = \"\"\n\n    def __init__(self, operators=None, functions=None, names=None):\n        \"\"\"\n            Create the evaluator instance.  Set up valid operators (+,-, etc)\n            functions (add, random, get_val, whatever) and names. \"\"\"\n\n        if not operators:\n            operators = DEFAULT_OPERATORS.copy()\n        if not functions:\n            functions = DEFAULT_FUNCTIONS.copy()\n        if not names:\n            names = DEFAULT_NAMES.copy()\n\n        self.operators = operators\n        self.functions = functions\n        self.names = names\n\n        self.nodes = {\n            ast.Expr: self._eval_expr,\n            ast.Assign: self._eval_assign,\n            ast.AugAssign: self._eval_aug_assign,\n            ast.Import: self._eval_import,\n            ast.Num: self._eval_num,\n            ast.Str: self._eval_str,\n            ast.Name: self._eval_name,\n            ast.UnaryOp: self._eval_unaryop,\n            ast.BinOp: self._eval_binop,\n            ast.BoolOp: self._eval_boolop,\n            ast.Compare: self._eval_compare,\n            ast.IfExp: self._eval_ifexp,\n            ast.Call: self._eval_call,\n            ast.keyword: self._eval_keyword,\n            ast.Subscript: self._eval_subscript,\n            ast.Attribute: self._eval_attribute,\n            ast.Index: self._eval_index,\n            ast.Slice: self._eval_slice,\n        }\n\n        # py3k stuff:\n        if hasattr(ast, 'NameConstant'):\n            self.nodes[ast.NameConstant] = self._eval_constant\n\n        # py3.6, f-strings\n        if hasattr(ast, 'JoinedStr'):\n            self.nodes[ast.JoinedStr] = self._eval_joinedstr  # f-string\n            self.nodes[ast.FormattedValue] = self._eval_formattedvalue  # formatted value in f-string\n\n        # py3.8 uses ast.Constant instead of ast.Num, ast.Str, ast.NameConstant\n        if hasattr(ast, 'Constant'):\n            self.nodes[ast.Constant] = self._eval_constant\n\n        # Defaults:\n\n        self.ATTR_INDEX_FALLBACK = ATTR_INDEX_FALLBACK\n\n        # Check for forbidden functions:\n\n        for f in self.functions.values():\n            if f in DISALLOW_FUNCTIONS:\n                raise FeatureNotAvailable('This function {} is a really bad idea.'.format(f))\n\n\n    def eval(self, expr):\n        \"\"\" evaluate an expresssion, using the operators, functions and\n            names previously set up. \"\"\"\n\n        # set a copy of the expression aside, so we can give nice errors...\n\n        self.expr = expr\n\n        # and evaluate:\n        return self._eval(ast.parse(expr.strip()).body[0])\n\n    def _eval(self, node):\n        \"\"\" The internal evaluator used on each node in the parsed tree. \"\"\"\n\n        try:\n            handler = self.nodes[type(node)]\n        except KeyError:\n            raise FeatureNotAvailable(\"Sorry, {0} is not available in this \"\n                                      \"evaluator\".format(type(node).__name__))\n\n        return handler(node)\n\n    def _eval_expr(self, node):\n        return self._eval(node.value)\n\n    def _eval_assign(self, node):\n        warnings.warn(\"Assignment ({}) attempted, but this is ignored\".format(self.expr), AssignmentAttempted)\n        return self._eval(node.value)\n\n    def _eval_aug_assign(self, node):\n        warnings.warn(\"Assignment ({}) attempted, but this is ignored\".format(self.expr), AssignmentAttempted)\n        return self._eval(node.value)\n\n    def _eval_import(self, node):\n        raise FeatureNotAvailable(\"Sorry, 'import' is not allowed.\")\n        return self._eval(node.value)\n\n    @staticmethod\n    def _eval_num(node):\n        return node.n\n\n    @staticmethod\n    def _eval_str(node):\n        if len(node.s) > MAX_STRING_LENGTH:\n            raise IterableTooLong(\"String Literal in statement is too long!\"\n                                  \" ({0}, when {1} is max)\".format(\n                                      len(node.s), MAX_STRING_LENGTH))\n        return node.s\n\n    @staticmethod\n    def _eval_constant(node):\n        if hasattr(node.value, '__len__') and len(node.value) > MAX_STRING_LENGTH:\n            raise IterableTooLong(\"Literal in statement is too long!\"\n                                  \" ({0}, when {1} is max)\".format(len(node.value), MAX_STRING_LENGTH))\n        return node.value\n\n    def _eval_unaryop(self, node):\n        return self.operators[type(node.op)](self._eval(node.operand))\n\n    def _eval_binop(self, node):\n        return self.operators[type(node.op)](self._eval(node.left),\n                                             self._eval(node.right))\n\n    def _eval_boolop(self, node):\n        if isinstance(node.op, ast.And):\n            vout = False\n            for value in node.values:\n                vout = self._eval(value)\n                if not vout:\n                    return vout\n            return vout\n        elif isinstance(node.op, ast.Or):\n            for value in node.values:\n                vout = self._eval(value)\n                if vout:\n                    return vout\n            return vout\n\n    def _eval_compare(self, node):\n        right = self._eval(node.left)\n        to_return = True\n        for operation, comp in zip(node.ops, node.comparators):\n            if not to_return:\n                break\n            left = right\n            right = self._eval(comp)\n            to_return = self.operators[type(operation)](left, right)\n        return to_return\n\n    def _eval_ifexp(self, node):\n        return self._eval(node.body) if self._eval(node.test) \\\n                                         else self._eval(node.orelse)\n\n    def _eval_call(self, node):\n        if isinstance(node.func, ast.Attribute):\n            func = self._eval(node.func)\n        else:\n            try:\n                func = self.functions[node.func.id]\n            except KeyError:\n                raise FunctionNotDefined(node.func.id, self.expr)\n            except AttributeError as e:\n                raise FeatureNotAvailable('Lambda Functions not implemented')\n\n            if func in DISALLOW_FUNCTIONS:\n                raise FeatureNotAvailable('This function is forbidden')\n\n        return func(\n            *(self._eval(a) for a in node.args),\n            **dict(self._eval(k) for k in node.keywords)\n        )\n\n    def _eval_keyword(self, node):\n        return node.arg, self._eval(node.value)\n\n    def _eval_name(self, node):\n        try:\n            # This happens at least for slicing\n            # This is a safe thing to do because it is impossible\n            # that there is a true exression assigning to none\n            # (the compiler rejects it, so you can't even\n            # pass that to ast.parse)\n            if hasattr(self.names, '__getitem__'):\n                return self.names[node.id]\n            elif callable(self.names):\n                return self.names(node)\n            else:\n                raise InvalidExpression('Trying to use name (variable) \"{0}\"'\n                                        ' when no \"names\" defined for'\n                                        ' evaluator'.format(node.id))\n\n        except KeyError:\n            if node.id in self.functions:\n                return self.functions[node.id]\n\n            raise NameNotDefined(node.id, self.expr)\n\n    def _eval_subscript(self, node):\n        container = self._eval(node.value)\n        key = self._eval(node.slice)\n        try:\n            return container[key]\n        except KeyError:\n            raise\n\n    def _eval_attribute(self, node):\n        for prefix in DISALLOW_PREFIXES:\n            if node.attr.startswith(prefix):\n                raise FeatureNotAvailable(\n                    \"Sorry, access to __attributes \"\n                    \" or func_ attributes is not available. \"\n                    \"({0})\".format(node.attr))\n        if node.attr in DISALLOW_METHODS:\n            raise FeatureNotAvailable(\n                \"Sorry, this method is not available. \"\n                \"({0})\".format(node.attr))\n        # eval node\n        node_evaluated = self._eval(node.value)\n\n        # Maybe the base object is an actual object, not just a dict\n        try:\n            return getattr(node_evaluated, node.attr)\n        except (AttributeError, TypeError):\n            pass\n\n        # TODO: is this a good idea?  Try and look for [x] if .x doesn't work?\n        if self.ATTR_INDEX_FALLBACK:\n            try:\n                return node_evaluated[node.attr]\n            except (KeyError, TypeError):\n                pass\n\n        # If it is neither, raise an exception\n        raise AttributeDoesNotExist(node.attr, self.expr)\n\n    def _eval_index(self, node):\n        return self._eval(node.value)\n\n    def _eval_slice(self, node):\n        lower = upper = step = None\n        if node.lower is not None:\n            lower = self._eval(node.lower)\n        if node.upper is not None:\n            upper = self._eval(node.upper)\n        if node.step is not None:\n            step = self._eval(node.step)\n        return slice(lower, upper, step)\n\n    def _eval_joinedstr(self, node):\n        length = 0\n        evaluated_values = []\n        for n in node.values:\n            val = str(self._eval(n))\n            if len(val) + length > MAX_STRING_LENGTH:\n                raise IterableTooLong(\"Sorry, I will not evaluate something this long.\")\n            evaluated_values.append(val)\n        return ''.join(evaluated_values)\n\n    def _eval_formattedvalue(self, node):\n        if node.format_spec:\n            fmt = \"{:\" + self._eval(node.format_spec) + \"}\"\n            return fmt.format(self._eval(node.value))\n        return self._eval(node.value)\n\n\nclass EvalWithCompoundTypes(SimpleEval):\n    \"\"\"\n        SimpleEval with additional Compound Types, and their respective\n        function editions. (list, tuple, dict, set).\n    \"\"\"\n\n    def __init__(self, operators=None, functions=None, names=None):\n        super(EvalWithCompoundTypes, self).__init__(operators, functions, names)\n\n        self.functions.update(\n            list=list,\n            tuple=tuple,\n            dict=dict,\n            set=set)\n\n        self.nodes.update({\n            ast.Dict: self._eval_dict,\n            ast.Tuple: self._eval_tuple,\n            ast.List: self._eval_list,\n            ast.Set: self._eval_set,\n            ast.ListComp: self._eval_comprehension,\n            ast.GeneratorExp: self._eval_comprehension,\n        })\n\n    def eval(self, expr):\n        self._max_count = 0\n        return super(EvalWithCompoundTypes, self).eval(expr)\n\n    def _eval_dict(self, node):\n        return {self._eval(k): self._eval(v)\n                for (k, v) in zip(node.keys, node.values)}\n\n    def _eval_tuple(self, node):\n        return tuple(self._eval(x) for x in node.elts)\n\n    def _eval_list(self, node):\n        return list(self._eval(x) for x in node.elts)\n\n    def _eval_set(self, node):\n        return set(self._eval(x) for x in node.elts)\n\n    def _eval_comprehension(self, node):\n        to_return = []\n\n        extra_names = {}\n\n        previous_name_evaller = self.nodes[ast.Name]\n\n        def eval_names_extra(node):\n            \"\"\"\n                Here we hide our extra scope for within this comprehension\n            \"\"\"\n            if node.id in extra_names:\n                return extra_names[node.id]\n            return previous_name_evaller(node)\n\n        self.nodes.update({ast.Name: eval_names_extra})\n\n        def recurse_targets(target, value):\n            \"\"\"\n                Recursively (enter, (into, (nested, name), unpacking)) = \\\n                             and, (assign, (values, to), each\n            \"\"\"\n            if isinstance(target, ast.Name):\n                extra_names[target.id] = value\n            else:\n                for t, v in zip(target.elts, value):\n                    recurse_targets(t, v)\n\n        def do_generator(gi=0):\n            g = node.generators[gi]\n            for i in self._eval(g.iter):\n                self._max_count += 1\n\n                if self._max_count > MAX_COMPREHENSION_LENGTH:\n                    raise IterableTooLong('Comprehension generates too many elements')\n                recurse_targets(g.target, i)\n                if all(self._eval(iff) for iff in g.ifs):\n                    if len(node.generators) > gi + 1:\n                        do_generator(gi+1)\n                    else:\n                        to_return.append(self._eval(node.elt))\n\n        try:\n            do_generator()\n        finally:\n            self.nodes.update({ast.Name: previous_name_evaller})\n\n        return to_return\n\n\ndef simple_eval(expr, operators=None, functions=None, names=None):\n    \"\"\" Simply evaluate an expresssion \"\"\"\n    s = SimpleEval(operators=operators,\n                   functions=functions,\n                   names=names)\n    return s.eval(expr)\n"
  },
  {
    "path": "tests/revealjs.org",
    "content": "* Main\n** Basic Page\n\tThis is a basic page\n** TODO Table Page\n   \n   |  H1  | H2 | H3 |\n   |------+----+----|\n   | Row1 |  1 |  2 |\n   | Row2 |  3 |  4 |\n   |------+----+----|\n   | Row3 |  5 |  6 |\n   | Row4 |  7 |  8 |\n\n** Link Page\n   \n   - [[https://reg.ca][RegCa]] \n   - [[https://google.ca][Google]] \n   - List 1\n     - Sub List 1\n     - Sub List 2\n\n** Source Blocks Page\n   \n   #+BEGIN_SRC cpp\n    printf(\"Hello World\\n\");\n    int x = 5;\n   #+END_SRC\n\n   #+BEGIN_SRC python\n    if this_is_test == 5:\n      print(\"Another test\") \n   #+END_SRC"
  },
  {
    "path": "tests/revealjs_ok.html",
    "content": "<!doctype html>\n<html lang=\"en\" class>\n  <head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/dist/reset.css\">\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/dist/reveal.css\">\n    <style>None</style>\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/dist/theme/league.css\" id=\"theme\">\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/highlight/zenburn.css\" id=\"highlight-theme\">\n  </head>\n  <body style=\"transition: -webkit-transform 0.8s ease 0s; transform-origin: 0px 0px;\">\n  <div class=\"reveal slide center has-vertical-slides has-horizontal-slides ready\" role=\"application\" data-transition-speed=\"default\" data-background-transition=\"none\">\n    <div class=\"slides\">\n      <section >\n      <h2>Main</h2>\n      <section >\n      <h3>Basic Page</h3>\n\tThis is a basic page\n      </section>\n      <section >\n      <h3>Table Page</h3>\n<br/>\n  <table>\n    <tr>\n     <th>  H1  </th>\n     <th> H2 </th>\n     <th> H3 </th>\n    </tr>\n\n    <tr>\n     <th> Row1 </th>\n     <th>  1 </th>\n     <th>  2 </th>\n    </tr>\n    <tr>\n     <th> Row2 </th>\n     <th>  3 </th>\n     <th>  4 </th>\n    </tr>\n\n    <tr>\n     <th> Row3 </th>\n     <th>  5 </th>\n     <th>  6 </th>\n    </tr>\n    <tr>\n     <th> Row4 </th>\n     <th>  7 </th>\n     <th>  8 </th>\n    </tr>\n  </table>\n      </section>\n      <section >\n      <h3>Link Page</h3>\n<br/>\n    <ul>\n     <li> <a href=\"https://reg.ca\">RegCa</a>    </li>\n     <li> <a href=\"https://google.ca\">Google</a>    </li>\n     <li> List 1    </li>\n    <ul>\n     <li> Sub List 1    </li>\n     <li> Sub List 2    </li>\n     </ul>\n     </ul>\n<br/>\n      </section>\n      <section >\n      <h3>Source Blocks Page</h3>\n<br/>\n    <pre><code language=\"cpp\" >\n    printf(\"Hello World\\n\");\n    int x = 5;\n  </code></pre>\n<br/>\n    <pre><code language=\"language-python\" >\n    if this_is_test == 5:\n      print(\"Another test\")\n  </code></pre>\n      </section>\n      </section>\n    </div>\n  </div>\n  <script src=\"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/dist/reveal.min.js\"></script>\n  <script src=\"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/markdown/markdown.js\"></script>\n  <script src=\"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/highlight/highlight.js\"></script>\n  <script src=\"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/search/search.js\"></script>\n  <script src=\"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/zoom/zoom.js\"></script>\n  <script src=\"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/notes/notes.js\"></script>\n  <script src=\"https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/math/math.js\"></script>\n  <script>\n      Reveal.initialize({\n          hash: true,\n          transition: 'none',\n          transitionSpeed: 'default',\n          dependencies: [\n              { src: 'https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/markdown/markdown.js', async: true },\n              { src: 'https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/highlight/highlight.js', async: true },\n              { src: 'https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/search/search.js', async: true },\n              { src: 'https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/zoom/zoom.js', async: true },\n              { src: 'https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/notes/notes.js', async: true },\n              { src: 'https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/plugin/math/math.js', async: true }\n          ],\n          plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]\n      });\n  </script>\n  </body>\n</html>\n"
  },
  {
    "path": "tests/sourceunittests.org",
    "content": "* Introduction\n  These are unit tests for the babel or source block functionality of org extended.\n  To run these you will need:\n\n  - The Java Runtime installed (to execute ditaa and plantuml diagrams)\n  - [[https://plantuml.com/download][PlantUML]] and [[http://ditaa.sourceforge.net/][Ditaa]] jar files in your config file.\n  - [[https://graphviz.org/][Graphviz]] installed and in your settings path.\n\n  Execution of these is done by evaluating the table in the result check section below.\n  ALL results are chained off those tables.\n\n\n* Result Checks\n  :PROPERTIES:\n    :NoTableHighlight: True\n  :END:\n  |      Name      |           R1          |  Result  |   Ok   |\n  |----------------+-----------------------+----------+--------|\n  | Row Sums       |                       | [15, 40] | PASSED |\n  | List Sums      |                       | [6]      | PASSED |\n  | Many Vars Test |                       | 15       | PASSED |\n  | NumList Sums   |                       | 10       | PASSED |\n  | PlantUML       | [[file:plantuml.png]] | True     | PASSED |\n  | GraphViz       | [[file:graphviz.png]] | True     | PASSED |\n  | Dataa          | [[file:ditaa.png]]    | True     | PASSED |\n  #+TBLFM:@2$4=passed(sbe('row-sums')[0] == 15 and sbe('row-sums')[1] == 40)::@3$4=passed(sbe('list-sums')[0] == 6)::@2$3=sbe('row-sums')::@3$3=sbe('list-sums')::@6$2=sbe('plantuml-test')::@6$3=sbe('file-exists',filename=filename($-1).replace('\\\\','\\\\\\\\'))::@6$4=passed($-1)::@7$2=sbe('graphviz-test')::@7$3=sbe('file-exists',filename=filename($-1).replace('\\\\','\\\\\\\\'))::@7$4=passed($-1)::@8$2=sbe('ditaa-test')::@8$3=sbe('file-exists',filename=filename($-1).replace('\\\\','\\\\\\\\'))::@8$4=passed($-1)::@4$3=sbe('many-vars')::@4$4=passed($-1==15)::@5$3=sbe('numlist-sums')::@5$4=passed($-1==10)\n\n* Simple Table Test\n\n  #+NAME: table-data\n  | a | b | c | d | e  |\n  | 1 | 2 | 3 | 4 | 5  |\n  | 6 | 7 | 8 | 9 | 10 |\n\n\n  #+NAME: row-sums\n  #+BEGIN_SRC python :results table :var DATA=table-data\n   rowSums = []\n   for i in range(1,len(DATA)):\n      row = DATA[i]\n      rowSum = 0\n      for j in range(0,len(row)):\n          rowSum += row[j]\n      rowSums.append(rowSum)\n   print(str(rowSums))\n  #+END_SRC\n\n  #+RESULTS:\n  | 15 |\n  | 40 |\n\n* Simple List Test\n\n    #+NAME: list-data\n    - 1\n    - 2\n      - 5\n        - 10\n    - 3\n\n    #+NAME: list-sums\n    #+BEGIN_SRC python :results table :var DATA=list-data\n      sum = 0\n      for i in DATA:\n        sum += int(i)\n      print(\"[{}]\".format(sum))\n    #+END_SRC\n\n  #+RESULTS:\n  | 6 |\n\n* Simple Numbered List Test\n\n  #+NAME: numlist-data\n  1. 2\n  2. 3\n  3. 4\n     1. 5\n  4. 1\n\n  #+NAME: numlist-sums\n  #+BEGIN_SRC python :var DATA=numlist-data\n    sum = 0\n    for i in DATA:\n      sum += int(i)\n    print(\"{}\".format(sum))\n  #+END_SRC\n\n  #+RESULTS:\n  : 10\n\n* Simple PlantUML Diagram\n\n  #+NAME: plantuml-test\n  #+BEGIN_SRC plantuml :file plantuml.png\n    a -> b\n    b -> c\n    c -> d\n  #+END_SRC\n\n  #+RESULTS:\n  [[file:plantuml.png]]\n\n* Simple Ditaa Diagram\n\n  #+NAME: ditaa-test\n  #+BEGIN_SRC ditaa :file ditaa.png\n    +--------+        +----------+\n    | Ditaa  | -----> | Sublime  |\n    +--------+        +----------+\n  #+END_SRC\n\n  #+RESULTS:\n  [[file:ditaa.png]]\n\n* Simple Graphviz Diagram\n\n  #+NAME: graphviz-test\n  #+BEGIN_SRC graphviz :file graphviz.png\n   digraph G {\n    a -> b;\n    b -> c;\n    a -> c;\n   } \n  #+END_SRC\n\n  #+RESULTS:\n  [[file:graphviz.png]]\n\n* Input Tests\n  This test is all about testing the various ways variables can enter a source block\n\n  :PROPERTIES:\n    :header-args:python: :var z=3\n  :END:\n\n  #+PROPERTY: header-args: :var v=5\n\n  #+NAME: many-vars \n  #+HEADER: :var w=4\n  #+BEGIN_SRC python :var x=1 :var y=2\n   newlist = [v,w,z,y,x]\n   sum = 0\n   for i in newlist:\n       sum += i\n   print(str(sum)) \n  #+END_SRC\n\n  #+RESULTS:\n  : 15\n\n\n  #+NAME: single-var\n  #+BEGIN_SRC python :var x=5\n    print(x)\n  #+END_SRC\n\n  #+RESULTS:\n  : 5\n\n* Handlers\n  Handlers re-interpret the data in various ways. This could be a table, a list or just adding a text adornment.\n\n** Table Output\n   Table output will try to format the output as a table\n\n  #+NAME: table-output\n  #+BEGIN_SRC python :results table\n    print(['a','b','c'])\n  #+END_SRC\n\n  #+RESULTS:\n  | a |\n  | b |\n  | c |\n\n** List Output\n   List output will try to interpret the data as a list of some sort.\n\n  #+NAME: list-output\n  #+BEGIN_SRC python :results list\n    print(['a','b','c'])\n  #+END_SRC\n\n  #+RESULTS:\n  - a\n  - b\n  - c\n\n** Raw Output\n   Raw output does 0 decoration\n\n  #+NAME: raw-output\n  #+BEGIN_SRC python :results raw\n    print(['a','b','c'])\n  #+END_SRC\n\n   #+RESULTS:\n   ['a', 'b', 'c']\n\n** Text Output\n  Text output gets a : at the start of each line\n\n  #+NAME: text-output\n  #+BEGIN_SRC python\n    print(['a','b','c'])\n  #+END_SRC\n\n   #+RESULTS:\n   : ['a', 'b', 'c']\n\n* Formatters\n  Formatters wrap the output from the handler in some kind of wrapping. A drawer, a source block, etc.\n\n** Drawer\n   The drawer formatter wraps the output in a drawer\n\n  #+NAME: table-output\n  #+BEGIN_SRC python :results table drawer\n    print(['a','b','c'])\n  #+END_SRC\n\n   #+RESULTS:\n   :results:\n   | a |\n   | b |\n   | c |\n   :end:\n\n** Org\n  Source block in orgmode format\n\n  #+NAME: org-output\n  #+BEGIN_SRC python :results table org\n    print(['a','b','c'])\n  #+END_SRC\n\n   #+RESULTS:\n   #+begin_src org\n   | a |\n   | b |\n   | c |\n   #+end_src\n\n** Code\n  Source that outputs source code\n\n  #+NAME: code-output\n  #+BEGIN_SRC python :results raw code\n    print(\"print(['a','b','c'])\")\n  #+END_SRC\n\n   #+RESULTS:\n   #+begin_src python\n   print(['a','b','c'])\n   #+end_src\n\n** Html\n\n  #+NAME: html-output\n  #+BEGIN_SRC python :results html\n    print(\"<a>hello</a>\")\n  #+END_SRC\n\n   #+RESULTS:\n   #+begin_src html\n   <a>hello</a>\n   #+end_src\n\n* Call and Inline\n\n** Call Other Functions\n\n  #+call: html-output()\n\n   #+RESULTS:\n   #+begin_src html\n   <a>hello</a>\n   #+end_src\n\n  #+call: single-var(x=20)\n\n  #+RESULTS:\n  : 20\n\n** Inline Blocks\n\n  Inline block can be anywhere src_python{print(\"hello world\")} {{{results(=hello world=)}}} a good exporter should just include the resuls here\n\n* Tools\n\n  #+NAME: file-exists\n  #+BEGIN_SRC python :var filename=\"filetotest\" :results value\n    import os \n    return os.path.exists(filename)\n  #+END_SRC\n  #+RESULTS:\n  : False\n"
  },
  {
    "path": "tests/tableunittests.org",
    "content": "* Table Tests\n   These are the core unit tests for our tables.\n   When making changes to table systems you should run these.\n\n   This is also a little demonstration of some of the capabilities of the system.\n   To run, run the \"Org Execute All Tables\" command\n\n** Straight column copy test\n   Copy from A => B and check that it worked\n    |  a   |  b   |   c    |\n    |------+------+--------|\n    | 0.04 | 0.04 | PASSED |\n    | 0.62 | 0.62 | PASSED |\n    | 0.82 | 0.82 | PASSED |\n    | 0.04 | 0.04 | PASSED |\n    #+TBLFM:$1=rand();%.2f::$2=$1::$3=passed($1==$2,$3)\n\n** Relative column copy test\n   Copy from -2 => -1 and check that it worked\n\n    |  a   |  b   |   c    |\n    |------+------+--------|\n    | 0.01 | 0.01 | PASSED |\n    | 0.84 | 0.84 | PASSED |\n    | 0.40 |  0.4 | PASSED |\n    | 0.38 | 0.38 | PASSED |\n    #+TBLFM:$1=rand();%.2f::$2=$-1::$3=passed($-2 == $-1)\n\n** Simple Boolean Comparisons\n   Check greater than and less than comparisons work\n\n    | a | b |      |   c   |   d    |\n    |---+---+------+-------+--------|\n    | 1 | 2 | a>b  | False | PASSED |\n    | 1 | 2 | a<b  | True  | PASSED |\n    | 2 | 1 | a>b  | True  | PASSED |\n    | 2 | 1 | a<b  | False | PASSED |\n    | 1 | 2 | a<=b | True  | PASSED |\n    | 1 | 2 | a>=b | False | PASSED |\n    | 1 | 2 | a==b | False | PASSED |\n    | 2 | 1 | a<=b | False | PASSED |\n    | 2 | 1 | a>=b | True  | PASSED |\n    | 1 | 1 | a==b | True  | PASSED |\n    #+TBLFM:@2$4=$1>$2::@2$5=passed($4==False)::@3$4=$1<$2::@3$5=passed(bool($4)==True)::@4$4=$-3>$-2::@4$5=passed($-1==True)::@5$4=$-3<$-2::@5$5=passed($-1==False)::@6$4=$1<=$2::@6$5=passed($-1)::@7$4=$1>=$2::@8$4=$1==$2::@7$5=passed($-1==False)::@8$5=passed($-1==False)::@9$4=$1<=$2::@9$5=passed($-1==False)::@10$4=$1>=$2::@11$4=$1==$2::@10$5=passed($-1==True)::@11$5=passed($-1==True)\n\n\n** Add Sub\n   Simple addition and subtraction tests\n\n    | s1 | s2 | desc | result |   ok   |\n    |----+----+------+--------+--------|\n    |  1 |  2 | a+b  |      3 | PASSED |\n    |  2 |  1 | a-b  |      1 | PASSED |\n    | -1 |  2 | -a+b |      1 | PASSED |\n    |  2 |  3 | a-b  |     -1 | PASSED |\n    #+TBLFM:@2$4=$1+$2::@2$5=passed($-1==3)::@3$4=$1-$2::@3$5=passed($-1==1)::@4$4=$1+$2::@4$5=passed($-1==1)::@5$4=$1-$2::@5$5=passed($-1==-1)\n\n** Mult Div\n   Basic multiplication and division tests\n\n    | s1 | s2 | desc | result |   ok   |\n    |----+----+------+--------+--------|\n    | 10 |  5 | a*b  |     50 | PASSED |\n    | 10 |  5 | a/b  |    2.0 | PASSED |\n    |  2 |  5 | a**b |     32 | PASSED |\n    | 10 |  3 | a%b  |      1 | PASSED |\n    #+TBLFM:@2$4=$1*$2::@2$5=passed($-1==50)::@3$4=$1/$2::@3$5=passed(int($-1)==2)::@4$4=$1**$2::@4$5=passed($-1==32)::@5$4=$1%$2::@5$5=passed($-1==1)\n\n** Bool Ops\n   Some more boolean operations\n\n    |   s1  |   s2  |  desc  | result |   ok   |\n    |-------+-------+--------+--------+--------|\n    | True  |       | not a  | False  | PASSED |\n    | False |       | not a  | True   | PASSED |\n    | True  | False | a != b | True   | PASSED |\n    | True  | True  | a != b | False  | PASSED |\n    | True  | False | a == b | False  | PASSED |\n    | True  | True  | a == b | True   | PASSED |\n    #+TBLFM:@2$4=not $1::@2$5=passed($-1==False)::@3$4=not $1::@3$5=passed($-1==True)::@4$4=$1!=$2::@4$5=passed($-1==True)::@5$4=$1!=$2::@5$5=passed($-1==False)::@6$4=$1==$2::@6$5=passed($-1==False)::@7$4=$1==$2::@8$5=passed($-1==True)\n\n** Highlighting Cells\n   Cell highlight test\n\n    | a  | b  | c  | e  | f  |\n    |----+----+----+----+----|\n    | r  | r  | r  | r  | r  |\n    | g  | g  | g  | g  | g  |\n    | b  | b  | b  | b  | b  |\n    | y  | y  | y  | y  | y  |\n    | c  | c  | c  | c  | c  |\n    | p  | p  | p  | p  | p  |\n    | o  | o  | o  | o  | o  |\n    | pi | pi | pi | pi | pi |\n    #+TBLFM:@2=highlight(@<,\"red\",\"r\")::@3=highlight(@3,\"green\",\"g\")::@4=highlight(@4,\"blue\",\"b\")::@5=highlight(@5,\"yellow\",\"y\")::@6=highlight(@6,\"cyan\",\"c\")::@7=highlight(@7,\"purple\",\"p\")::@8=highlight(@8,\"orange\",\"o\")::@9=highlight(@9,\"pink\",\"pi\")\n\n** Basic Functions\n   Test some of the basic functions\n\n    | source 1 | source 2 |         desc        |       result      |   ok   |\n    |----------+----------+---------------------+-------------------+--------|\n    | -1       |          | abs                 | 1                 | PASSED |\n    | 1.1      |          | ceil                | 2                 | PASSED |\n    | 1.1      |          | floor               | 1                 | PASSED |\n    | 1.1      |          | int                 | 1                 | PASSED |\n    | 0        |          | bool                | False             | PASSED |\n    | 1        |          | float               | 1.0               | PASSED |\n    | 1.5      |          | round               | 2.0               | PASSED |\n    | 1.9      |          | trunc               | 1                 | PASSED |\n    | 2*pi     |          | sin(2*pi)           | -0.0              | PASSED |\n    | 0        |          | cos(0)              | 1.0               | PASSED |\n    | pi       |          | tan(pi)             | -0.0              | PASSED |\n    |          |          | exp(2)              | 7.39              | PASSED |\n    |          |          | atan(1.55740772465) | 1.0               | PASSED |\n    |          |          | acos(0.54030230586) | 1.0               | PASSED |\n    |          |          | asin()              | 1.0               | PASSED |\n    |          |          | degrees(pi)         | 180.0             | PASSED |\n    |          |          | radians()           | 3.141592653589793 | PASSED |\n    |          |          | sqrt(4)             | 2.0               | PASSED |\n    |          |          | pow(2,2)            | 4.0               | PASSED |\n    |          |          | log(exp(1))         | 1.0               | PASSED |\n    |          |          | log10(10**10)       | 10.0              | PASSED |\n    |          |          | log2(2**2)          | 2.0               | PASSED |\n    |          |          | asinh(sinh(pi))     | 3.141592653589793 | PASSED |\n    |          |          | acosh(cosh(pi))     | 3.141592653589793 | PASSED |\n    |          |          | atanh(tanh(pi))     | 3.141592653589798 | PASSED |\n    #+TBLFM:@2$4=abs($1)::@2$5=passed($-1==1)::@3$4=ceil($1)::@3$5=passed($-1==2)::@4$4=floor($1)::@4$5=passed($-1==1)::@5$4=int($1)::@5$5=passed($-1==1)::@6$4=bool($1)::@6$5=passed($-1==False)::@7$4=float($1)::@7$5=passed($-1==1.0)::@8$4=round($1)::@8$5=passed($-1==2.0)::@9$4=trunc($1)::@9$5=passed($-1==1)::@10$4=round(sin(2*pi))::@10$5=passed($-1==0)::@11$4=cos(0)::@11$5=passed($-1==1.0)::@12$4=round(tan(pi))::@12$5=passed($-1==0)::@13$4=exp(2);%.2f::@13$5=passed($-1==7.39)::@19$4=sqrt(4)::@19$5=passed($-1==2.0)::@20$4=pow(2,2)::@20$5=passed($-1==4.0)::@14$4=round(atan(1.55740772465))::@14$5=passed($-1==1)::@15$4=round(acos(0.54030230586))::@15$5=passed($-1==1)::@16$4=round(asin(0.8414709848))::@16$5=passed($-1==1)::@17$4=degrees(pi)::@17$5=passed($-1==180)::@18$4=radians(180.0)::@18$5=passed($-1==pi)::@21$4=log(exp(1))::@21$5=passed($-1==1)::@22$4=log10(10**10)::@22$5=passed($-1==10)::@23$4=log2(2**2)::@23$5=passed($-1==2)::@24$4=asinh(sinh(pi))::@24$5=passed($-1==pi)::@25$4=acosh(cosh(pi))::@25$5=passed($-1==pi)::@26$4=atanh(tanh(pi))::@26$5=passed(round($-1)==round(pi))\n\n** DateTime Functions\n   Testing some date and time methods.\n\n    #+NAME: date-time-test\n    |           s1           | s2 |   desc   |         result         |   ok   |\n    |------------------------+----+----------+------------------------+--------|\n    | <2021-03-15 Mon 17:57> |    | now      | <2021-05-19 Wed 00:28> | PASSED |\n    |                        |    | minute   | 57                     | PASSED |\n    |                        |    | hour     | 17                     | PASSED |\n    |                        |    | day      | 15                     | PASSED |\n    |                        |    | year     | 2021                   | PASSED |\n    |                        |    | month    | 3                      | PASSED |\n    |                        |    | time     | 17:57:00               | PASSED |\n    |                        |    | date     | <2021-03-15 Mon 17:57> | PASSED |\n    | <2021-03-16 Tue 17:57> |    | weekday  | 1                      | PASSED |\n    |                        |    | yearday  | 75                     | PASSED |\n    | 3d                     |    | duration | 3d                     | PASSED |\n    #+TBLFM:@2$4=now()::@2$5=passed(minute(date($-1))==minute(now()))::@3$4=minute(date(@2$1))::@3$5=passed($-1==57)::@4$4=hour(@2$1)::@4$5=passed($-1==17)::@5$4=day(@2$1)::@5$5=passed($-1==15)::@6$4    =year(@2$1)::@6$5=passed($-1==2021)::@7$4=month(@2$1)::@7$5=passed($-1==3)::@8$4=time(@2$1)::@9$4=date(@2$1)::@9$5=passed($-1==@2$1)::@10$4=weekday(date(@10$1))::@11$4=yearday(@10$1)::@11$5=passed($-1==75)::@10$5=passed($-1==1)::@8$5=passed($-1==\"17:57:00\")::@12$4=duration(@12$1)::@12$5=passed($-1==\"3d\")\n\n** Range Functions\n   Testing out some of the range methods\n\n    | a | b | c | d | e |   desc   | result |   ok   |\n    |---+---+---+---+---+----------+--------+--------|\n    | 1 | 2 | 3 | 4 | 5 | vsum row |     15 | PASSED |\n    | 2 |   |   |   |   | vsum col |     15 | PASSED |\n    | 3 |   |   |   |   | vmean    |    3.0 | PASSED |\n    | 4 |   |   |   |   | vmax     |      5 | PASSED |\n    | 5 |   |   |   |   | vmin     |      1 | PASSED |\n    |   |   |   |   |   | vmedian  |      3 | PASSED |\n    #+TBLFM:@2$7=vsum($1..$5)::@2$8=passed($-1==15)::@3$7=vsum(@2$1..@6$1)::@3$8=passed($-1==15)::@4$7=vmean(@2$1..@2$5)::@4$8=passed($-1==3.0)::@5$7=vmax(@2$1..@2$5)::@5$8=passed($-1==5)::@6$7=vmin(@2$1..@2$5)::@6$8=passed($-1==1)::@7$7=vmedian(@2$1..@2$5)::@7$8=passed($-1==3)\n\n** Remote References\n   Extract a result from somewhere else and use it in this table.\n\n    |         result         |   ok   |\n    |------------------------+--------|\n    | <2021-03-15 Mon 17:57> | PASSED |\n    #+TBLFM:@2$1=remote(\"date-time-test\",@2$1)::@2$2=passed(minute($-1)==57)\n\n\n** Side Relative References\n   Relative to the edges of the table\n\n    | a | b | c | d | result |   ok   |\n    |---+---+---+---+--------+--------|\n    | 1 | 2 | 3 | 4 |      1 | PASSED |\n    | 1 | 2 | 3 | 4 |      2 | PASSED |\n    | 1 | 2 | 3 | 4 |      3 | PASSED |\n    | 1 | 2 | 3 | 4 |      4 | PASSED |\n    #+TBLFM:@2$5=$<::@3$5=$<<::@4$5=$<<<::@2$6=passed($-1==1)::@3$6=passed($-1==2)::@4$6=passed($-1==3)::@5$5=$>>>::@5$6=passed($-1==4)\n\n    Row relative copy\n    | a  |   b    | c  |   d    | e |\n    |----+--------+----+--------+---|\n    |  1 | 2      |  3 | 4      | 5 |\n    |  1 | 2      |  3 | 4      | 5 |\n    |  5 | 4      |  3 | 2      | 1 |\n    |  5 | 4      |  3 | 2      | 1 |\n    | 15 | PASSED | 15 | PASSED |   |\n    #+TBLFM:@3=@<::@4=@>>::@6$1=vsum(@4$1..@4$5)::@6$2=passed($1==15)::@6$3=vsum(@3$1..@3$5)::@6$4=passed($-1==15)\n\n** Range Source and Targets\n   Using block ranges to specify destination\n\n    |  a   |  b   |  c   |  d   |  e   |        |\n    |------+------+------+------+------+--------|\n    | 0.67 | 0.90 | 0.67 |  0.9 | True | PASSED |\n    | 0.83 | 0.27 | 0.83 | 0.27 | True | PASSED |\n    | 0.93 | 0.29 | 0.93 | 0.29 | True | PASSED |\n    | 0.16 | 0.55 | 0.16 | 0.55 | True | PASSED |\n    #+TBLFM:@2$1..@5$2=rand();%.2f::@2$3..@5$4=$-2::$5=True if $-4==$-2 and $-3==$-1 else False::$6=passed($-1)\n\n** Advanced Table Syntax\n   Some of the advanced table bits and pieces\n\n    |   | results |    |   |   |   |        |\n    |---+---------+----+---+---+---+--------|\n    | ! | a       | b  | c | d | e |        |\n    | # | 9       |    |   | 4 | 5 | PASSED |\n    | # | 3       | 1  | 2 |   |   | PASSED |\n    | $ | max=5   |    |   |   |   |        |\n    | # | 15      | 10 |   |   |   | PASSED |\n    #+TBLFM:@4$2=$b + $c::@3$2=$e+$d::@3$7=passed($a==9)::@4$7=passed($a==3)::@6$2=$max+$b::@6$7=passed($a==15)\n\n\n** Remote Tables Of Different Dimensions\n    #+NAME: longer-table\n    | a | b | c |\n    | 1 | 2 |   |\n\n    #+NAME: should-be-b\n    | b |\n    #+TBLFM:@1$1=remote('longer-table',@1$2)\n\n    | b | PASSED |\n    #+TBLFM:@1$1=remote('should-be-b',@1$1)::@1$2=passed($-1=='b')\n\n** Long Tables and Plots\n   Lets test a long table and plot it.\n   Eventually table computation bogs down at this size.\n\n   #+PLOT: title:\"Random\" ind:1 deps:(3) with:lines file:out.png\n   |  a  |  b   |  c   |\n   |-----+------+------|\n   |   2 | 0.69 | 0.50 |\n   |   3 | 0.96 | 0.46 |\n   |   4 | 0.74 | 0.35 |\n   |   5 | 0.10 | 0.24 |\n   |   6 | 0.74 | 0.58 |\n   |   7 | 0.79 | 0.56 |\n   |   8 | 1.00 | 0.71 |\n   |   9 | 0.64 | 0.10 |\n   |  10 | 0.38 | 0.42 |\n   |  11 | 0.74 | 0.97 |\n   |  12 | 0.12 | 0.34 |\n   |  13 | 0.65 | 0.02 |\n   |  14 | 0.78 | 1.00 |\n   |  15 | 0.42 | 0.46 |\n   |  16 | 0.83 | 0.65 |\n   |  17 | 0.39 | 0.76 |\n   |  18 | 0.68 | 0.30 |\n   |  19 | 0.79 | 0.51 |\n   |  20 | 0.71 | 0.70 |\n   |  21 | 0.72 | 0.40 |\n   |  22 | 0.51 | 0.01 |\n   |  23 | 0.16 | 0.16 |\n   |  24 | 0.30 | 0.25 |\n   |  25 | 0.99 | 0.05 |\n   |  26 | 0.10 | 0.39 |\n   |  27 | 0.59 | 0.43 |\n   |  28 | 0.61 | 0.62 |\n   |  29 | 0.90 | 0.85 |\n   |  30 | 0.80 | 0.79 |\n   |  31 | 0.26 | 0.10 |\n   |  32 | 0.47 | 0.09 |\n   |  33 | 0.22 | 0.42 |\n   |  34 | 0.63 | 0.88 |\n   |  35 | 0.33 | 0.07 |\n   |  36 | 0.80 | 0.11 |\n   |  37 | 0.90 | 0.10 |\n   |  38 | 0.99 | 0.77 |\n   |  39 | 0.88 | 0.30 |\n   |  40 | 0.94 | 0.78 |\n   |  41 | 0.61 | 0.14 |\n   |  42 | 0.36 | 0.68 |\n   |  43 | 0.73 | 0.59 |\n   |  44 | 0.23 | 0.77 |\n   |  45 | 0.90 | 0.63 |\n   |  46 | 0.35 | 0.14 |\n   |  47 | 0.66 | 0.41 |\n   |  48 | 0.35 | 0.73 |\n   |  49 | 0.17 | 0.10 |\n   |  50 | 0.92 | 0.89 |\n   |  51 | 0.64 | 0.80 |\n   |  52 | 0.19 | 0.15 |\n   |  53 | 0.99 | 0.37 |\n   |  54 | 0.13 | 0.43 |\n   |  55 | 0.40 | 0.14 |\n   |  56 | 0.30 | 0.03 |\n   |  57 | 0.09 | 0.12 |\n   |  58 | 0.10 | 0.01 |\n   |  59 | 0.08 | 0.82 |\n   |  60 | 0.13 | 0.56 |\n   |  61 | 0.03 | 0.05 |\n   |  62 | 0.59 | 0.32 |\n   |  63 | 0.91 | 0.83 |\n   |  64 | 0.10 | 0.15 |\n   |  65 | 0.96 | 0.87 |\n   |  66 | 0.26 | 0.63 |\n   |  67 | 0.70 | 0.28 |\n   |  68 | 0.50 | 0.70 |\n   |  69 | 0.74 | 0.53 |\n   |  70 | 0.68 | 0.69 |\n   |  71 | 0.91 | 0.51 |\n   |  72 | 0.89 | 0.25 |\n   |  73 | 0.44 | 0.46 |\n   |  74 | 0.06 | 0.91 |\n   |  75 | 0.15 | 0.88 |\n   |  76 | 0.35 | 0.61 |\n   |  77 | 0.57 | 0.29 |\n   |  78 | 0.85 | 0.03 |\n   |  79 | 0.90 | 0.72 |\n   |  80 | 0.75 | 0.97 |\n   |  81 | 0.61 | 0.69 |\n   |  82 | 0.02 | 0.48 |\n   |  83 | 0.16 | 0.43 |\n   |  84 | 0.76 | 0.98 |\n   |  85 | 0.17 | 0.35 |\n   |  86 | 0.21 | 0.44 |\n   |  87 | 0.45 | 0.78 |\n   |  88 | 0.46 | 0.86 |\n   |  89 | 0.71 | 0.08 |\n   |  90 | 0.14 | 0.20 |\n   |  91 | 0.43 | 0.53 |\n   |  92 | 0.49 | 0.77 |\n   |  93 | 0.71 | 0.78 |\n   |  94 | 0.66 | 0.78 |\n   |  95 | 0.35 | 0.71 |\n   |  96 | 0.91 | 0.21 |\n   |  97 | 0.48 | 0.14 |\n   |  98 | 0.00 | 0.21 |\n   |  99 | 0.62 | 0.66 |\n   | 100 | 0.16 | 0.89 |\n   #+TBLFM:$1=@#::@2$2..@100$3=rand();%.2f\n\n   #+RESULTS:\n   [[file:C:/Users/ihdav/AppData/Roaming/Sublime Text/Packages/OrgExtended/out.png]]\n\n* Full Relative Test\n  This was found to be broken in 1.2.32!\n\n  | a | b | c | d |        |        |        |        |\n  | 1 | 2 | 3 | 4 |        |        |        |        |\n  | 2 | 1 | 5 | 4 | PASSED | PASSED | PASSED | PASSED |\n  |   |   | 4 | 5 |        |        |        |        |\n  #+TBLFM:@3$1=@-1$+1::@3$2=@-1$-1::@3$3=@+1$+1::@3$4=@+1$-1::@3$5=passed($-4==2)::@3$6=passed($-4==1)::@3$7=passed($-4==5)::@3$8=passed($-4==4)\n\n\n** Test Table\n   | a | b | c | d |\n   | 1 | 2 | 3 | 4 |\n   | 2 | 3 | 4 | 5 |\n   | 3 | 4 | 5 | 6 |\n\n  * Complex Relative Test\n  \n  | a     | b | c | d |\n  | 1     | 2 | 3 | 4 |\n  | <ERR> | 2 |   |   |\n  #+TBLFM:@3$1=@int($+1)$2\n"
  },
  {
    "path": "tests/testfile.org",
    "content": "// We start with some of the more well known file level comments.\n// NOTE: There are many more comments than these.\n//       this is just some of the more common ones.\n\n// The filetags comment lets you tag all headings in a file with a tag.\n#+FILETAGS: :Ian:Tagged:\n\n// The startup comment controls how the file is displayed on startup\n// Some common options are: \n// overview content  showall showeverything - These control how startup folding is handled.\n// noinlineimages inlineimages              - These let you have the system show images inline in the document by default\n// logdone                                  - This tells the system to add a log message when you close a task.\n#+STARTUP: content logdone\n\n// The TODO cycle of a task can be the default, set in your settings file or set\n// here in a comment on a per file basis.\n//#+TODO: A B C | D E\n\n\n// The ARCHIVE comment lets you control how headings are archived from this file.\n// You can do this globally from your settings file OR you can do it on a per file basis.\n//\n// While this basic heading works if you add your own extension you need\n// to add to validOrgExtensions in the sublime-settings\n// file. Otherwise the DB will not know about your file extension\n// and will reject the archive file when you go to archive your data.\n#+ARCHIVE: %s_archive::* Archive\n\n\n// Priorities are another type of tag you can add to a heading.\n// You can set your own priority list using a comment like so.\n// While these are supported they are not highlighted like A B C D E are\n// I hope some day we can support syntax extensions to make this possible.\n#+PRIORITIES: 1 2 3 4 5\n\n// This comment is for html export.\n#+HTML_STYLE: refined\n\n// These are some basic comments that can show up during export and\n// can be useful in some types of documents.\n#+AUTHOR:   Ian Davids\n#+TITLE:    Org Mode Test File\n#+LANGUAGE: en\n#+DATE:     March 20 2018\n#+EMAIL:    myemail@mydomain.com\n#+OPTIONS: \n\n#+TODO: TODO(!) WAIT(@) | DONE\n\n* Introduction\n  This is a simple test file that has a bunch of the core Org Extended features in it.\n  Org is huge and adding all of the features in org to a single file would be a very very large document.\n\n  This is however a little playground of some of the more common aspects of Org.\n\n  If all you do is look at this file you are missing out on a LOT of orgmode features.\n  You should look at:\n\n  - Keybindings - This will give you some overview of the bits we have bound for ease of use.\n  - Commands    - Typing \"Org\" in to the command panel is a quick way to browse the available commands.\n                  <hopefully we will eventually support a self documenting command to let the commands speak for themselves\" \n  - Documentation - orgextended_docs is a repo full of orgmode files to help you learn about orgmode. Its not the best, but what I have had time to write.\n  - Worklog - Sometimes it can be handy to paruse our worklog to look at what I have been working on recently. \"Org Show Worklog\" will bring that up for you.\n\n \n* Basic Headings\n\n  A heading or node in org mode is similar to a heading in markdown. Markdown uses # to denote a heading, org uses stars.\n  The more stars, the deeper the sub heading.\n\n  I am only supporting 7 levels of headings.\n  Sub headings simply nest inside the parent heading.\n\n  Org has commands to help you add and remove headings, move them around, change their indent and jump around.\n\n** Heading 2\n*** Heading 3\n**** Heading 4\n***** Heading 5\n****** Heading 6\n******* Heading 7\n******** Heading 8\n********* Heading 9\n\n\n* Tags                                                                    :TAG1:TAG2:\n  Tags are a means of filtering your headings in this file or across all your files.\n  Tags are meta data that you can attach to your headings. The tags apply to a heading and all\n  sub headings.\n\n** This heading will have TAG1 and TAG2 on it. :OTHERTAGS:\n   BUT this heading will be the only heading with the OTHERTAGS tag applied.\n\n* TODO States\n  States are a means of turning a regular heading into a task. Org has the concept that TODO lists\n  can, should and do appear all over your notes. For that reason orgmode has the ability to find those\n  todos and present them in various agenda views. TODO's flow through states. Those states are defined by you.\n\n  I have not found a good way to make syntax highlighting extensible SO as a compromise, while the active todo\n  states ARE configurable (see the comment #+TODO above) the syntax highlighting of those states is limited to the\n  states that I have setup.\n\n  I am often adding new states. I have several closed states like:\n\n  *** NOTE This marks this as a note\n  *** PHONE This marks this as notes from a telephone call.\n  *** MEETING This marks this as notes from a meeting.\n\n* Drawers\n  :MYDRAWER:\n  Anything can go in here\n  :END:\n\n  One of the features of org is the concept of a drawer. A drawer is a generic section that can contain any meta data.\n  Drawers get auto folded away to avoid clutter unless you are editing them. \n\n* Properties and the LogBook\n  :PROPERTIES:\n  :ORDERED:  t\n  :END:\n  :LOGBOOK:\n  - This is a line\n  :END:\n  \n  Properties are a special drawer. The contain key/value pairs that are often accessible by other subsystems in org mode.\n  As an example a common use of the property drawer is to store Effort which is used by column view to estimate the epected effort of tasks.\n  Another example might be variables and constants used in tables, or enabling features for checkboxes and other systems.\n\n  In addition to the property drawer, another common drawer is the LOGBOOK. The logbook is where clocking information tends to get stored\n  when you are tracking the time spent on tasks. OR It can be used to store notes related to closing out a task.\n\n  One special use of the property drawer is to add an ID or CUSTOM_ID field (IDs should be guids while CUSTOM IDs are yours to generate as long as they are unique)\n  These can be used to reference a heading in your org files.\n\n  - \"Org Create Heading Id\" - will generate an ID (guid) for you.\n  - \"Org Insert CustomId\"   - will prompt you to insert your own custom id.\n\n* orgmode (vs true orgmode compat) bits\n  These items are NOT true org mode things but come\n  from the previous ST2 orgmode package. I felt they were worth\n  supporting and have kept them. I do not think being purist is\n  super helpful when it comes to helping out the sublime community\n\n\t~ This is a break\n\t--- This is a page break ---\n\n\t-> For Follow Up\n\t=> For Follow Up\n\n* Lists\n  Orgmode has support for 5 types of lists:\n\n  + Plus unordered list\n  + More stuff\n\n  - Basic unordered list\n  - More stuff\n\n  - [ ] Checkbox lists\n  - [ ] More stuff\n\n  1. Numbered list\n  2. More stuff\n\n  - Definition1 :: This is what it means\n  - Definition2 :: This is what that means\n\n  The ctrl + enter do what I mean editing feature allows you to quickly build lists of this type.\n  We support sorting and nested lists.\n\n* Checkboxes [33%]\n  \n  Checkboxes deserve their own section.\n  The do what I mean toggle command also works on checkboxes\n\n  Summary boxes [/] and [%] are auto updated when you toggle\n  a checkbox. Summary boxes also work on the heading (see above.) \n\n  - [ ] Checkbox\n  - [x] Blocked checkbox\n  - [-] Checked checkbox [1/3]\n      - [ ] sub\n      - [ ] sub2\n      - [x] sub3\n\n* Links\n\n  Links in org mode are complex. Our link handler still needs some work but will hopefully improve over time.\n  Our link handler supports the concept of a protocol. You can write your own protocol handlers.\n\n  http: is a built in protocol, so is file: by default the system assumes that a link references a file.\n  Links can have a descript or not:\n\n  - [[testfile.org]]\n  - [[testfile.org][TestFile]]\n\n  The system aggressively tries to fold the link if a description is present. In Emacs, Emacs would hide ALL of the link bits only showing the target\n  making it look like a hyperlink on a website. We can't quite do that in sublime, but we try our best.\n  \n  NOTE: Folding is not perfect but I find folding the actual ref itself\n        is a reasonable compromise.\n\n  - [[https://reg.ca][Reg Ca]] Org link\n\n  Links can be followed simply by pressing enter on the link.\n  This makes orgmode something like a mini wiki. \n\n*** IDs and CUSTOM_IDs\n  Links can also reference an ID or CUSTOM_ID:\n\n   #+BEGIN_EXAMPLE\n    <URL>::#<ID>\n   #+END_EXAMPLE\n\n  - [[file:C:\\Users\\ihdav\\AppData\\Roaming\\Sublime Text\\Packages\\OrgExtended\\testfile.org::#33da3712-51b7-485c-b69d-f54dd266543f][ID Creation]] \n  - [[file:C:\\Users\\ihdav\\AppData\\Roaming\\Sublime Text\\Packages\\OrgExtended\\testfile.org::#My-Custom-Id][Custom Id]] \n\n*** Anchors or Internal Targets\n\n  Another form of targetting is linking to an internal anchor.\n  This is a link to a target internal to this org file.\n  A good HTML exporter should turn that target into a propper anchor in the file.\n\n  #+BEGIN_EXAMPLE\n    <URL>::<TARGET>\n  #+END_EXAMPLE\n\n  - [[Target1][Link To Target1]]\n  - [[testfile.org::Target1][Link To Target1]]\n  \n  Org has the ability to \"name\" an object like a table. Names are assigned using the name comment:\n  #+BEGIN_EXAMPLE\n    #+NAME: my-name\n  #+END_EXAMPLE\n\n  These links behave just like file anchors or targets:\n  #+BEGIN_EXAMPLE\n    <URL>::<NAME>\n  #+END_EXAMPLE\n\n  - [[MyNamedObject][Link to Named Object]]\n  - [[testfile.org::MyNamedObject][Link to Named Object]]\n\n*** Targetting Headings\n  Headings are also targettable. Here you use ::* as a means of indicating the header is your target.\n  #+BEGIN_EXAMPLE\n    <FILE>::*<HEADING>\n  #+END_EXAMPLE\n\n  - [[file:testfile.org::*Scheduling][Scheduling]]\n\n*** An Anchor for target practice.\n  Here is a target so we can link to it from the Link To Target above.\n  <<Target1>>\n\n* Scheduling\n\n  There are 4 important timestamps that can appear in any heading.\n  These first 3 should always appear right after the heading:\n\n  SCHEDULED: <2020-05-25 Thu 10:50 +1d> - This is when you want to START on a task\n  CLOSED: [2020-05-25 Mon]              - When enabled this will track when you closed the task (moved to a done state)\n  DEADLINE: <2020-05-25 Tue>            - This is when the task should be \"done by\" or closed.\n\n  Scheduled and Deadline are used by the agenda to track open tasks. There is 1 more type of timestamp used by the agenda\n  which is simply the active timestamp: <2021-03-19 Fri 13:23> \n\n  An active timestamp means it gets picked up by the agena as the datetime of an appointment (rather than a task)\n  Inactive timestamps do not get considered by the agenda: [2021-03-19 Fri 13:24] \n\n  Timestamps are complex beasts in org. They can have warnings -2d, recurrence +1w or span some time 12:00-13:45\n  For more information please see the org manual.\n\n* Navigation\n\n  Ctrl arrow key travels up and down the tree of headings\n\n  - \"Org Jump In File\" gives you a quick way to jump around in a file. (NOTE symbols work as well but sometimes the indent is helpful)\n  - \"Org Jump To Today\" and \"Org Jump To CustomId\" are quick ways of jumping to headings with CUSTOM_ID tags (today is a special CUSTOM ID)\n\n* Archive, Refile, Copy\n\n  There are commands for archiving, refiling and copying headings around.\n\n  - \"Org Archive Subtree\" - will copy the subtree to this files archive target.\n  - \"Org Refile\" - will attempt to let you refile the current heading somewhere in your orgDir.\n  - \"Org Copy Entity\" \"Org Copy Subtree\" also try to let you copy around headings as needed.\n\n* Capture\n  \n  One of the biggest features I can't do without is the quick capture keybindings and templates.\n  I have a system for this in place. \n\n  Capture templates are snippets! You have to define them!\n  You define some snippets and then add capture entries into your settings file. Once you have done this\n  You can quick capture from anywhere into the apropriate org target. \n\n* Control Comments\n\n  As seen above there are a lot of control comments. Many of them are poorly documented at this time.\n   \n   #+PRIORITIES: A B C\n   #+TITLE: Orgmode example file\n   \n* Src Block\n\n  Org Babel Mode or Org Source Blocks are one of the cornerstones of Org Mode. Org Mode WAS the original Jupyter notebooks.\n  Right now in our implementation we only have a very small number of actual source handlers for executing code. \n  (powershell, python, ditaa, plantuml, graphviz) Hopefully that will grow.\n\n  We will also document how to add your own handlers going forward.\n\n  That said we support quite a long list of language highlighting options for the moment. The list of languages we can highlight can be found\n  in languagelist.yaml. That list is used to generate the syntax. If you would like a language added to the list please let me know. (or fire me a PR)\n\n  Here are some examples:\n\n  #+ATTR_LATEX: :options commentstyle=\\bfseries\n\t#+BEGIN_SRC python\n    def func(a):\n        print(\"hello world\")\n    func('hi')\n\t#+END_SRC\n\n\t#+BEGIN_SRC cpp\n\tclass MyClass\n\t{\n\tpublic:\n\t\tMyClass(int x, int y) {}\n\t}\n\t#+END_SRC\n\n\t#+BEGIN_SRC C\n\tvoid main(int x, int y)\n\t{\n\t\tprintf(\"hello world\\n\");\n\t}\n\t#+END_SRC\n\n\t#+begin_src js\n\tfunction myfunc(x , y) {\n\t\tconsole.log(\"Hello World\")\n\t}\n\t#+end_src\n\n\t#+begin_src xml\n\t<mytag attribute=\"hello\">\n\t\tSome inner text\n\t</mytag>\n\t#+end_src\n\n  #+BEGIN_SRC plantuml\n    a -> b\n    b -> c\n  #+END_SRC\n\n  #+BEGIN_SRC graphviz\n  diagram G {\n    a -> b;\n    b -> c;\n  }\n  #+END_SRC\n\n  #+BEGIN_SRC bat\n    REM Comment line\n    @echo off\n    hi=%1\n  #+END_SRC\n\n  #+BEGIN_SRC regexp\n    \\s+(?P<name>[a-z])\\s+\n  #+END_SRC \n\n  #+BEGIN_SRC org\n  * Heading\n  :PROPERTIES:\n  :END:\n  #+END_SRC \n\n #+BEGIN_SRC md\n### Markdown\n    But rules have to be followed here so things have to be right aligned in the block.\n```cpp\n    printf(\"\");\n```\n #+END_SRC \n\n** Babel\n\n  The tower of babel or babelfish is the inspiration for the name of this feature in Emacs. This feature has its roots in:\n\n  - Literate Programming\n  - Reproducible Research\n\n  That said, babel can be used for a LOT of other things. From generating diagrams in documents and presentations to \n  development / visualizing some gathered data.\n\n  With babel a named data table, variable definition or list can act as input for a source block.\n\n   #+NAME: in-table\n   | a | b | c | d | e |\n   | 1 | 2 | 3 | 4 | 5 |\n   | 6 | 7 | 8 | 9 | 0 |\n   \n   #+BEGIN_SRC powershell :var DATA=in-table\n     $DATA | %{\"$_\"}\n   #+END_SRC\n\n   #+RESULTS:\n   | a | b | c | d | e |\n   | 1 | 2 | 3 | 4 | 5 |\n   | 6 | 7 | 8 | 9 | 0 |\n\n   #+BEGIN_SRC python :var DATA=in-table :results table\n     print(str(DATA))\n   #+END_SRC\n\n   #+RESULTS:\n   | a | b | c | d | e |\n   | 1 | 2 | 3 | 4 | 5 |\n   | 6 | 7 | 8 | 9 | 0 |\n\n*** Graphing\n\n  If you have the right tools installed and in your path, this includes things like graphs of data:\n\n    #+BEGIN_SRC graphviz :file images/graphviz.png\n     digraph G {\n       a -> b;\n       a -> c;\n       c -> d;\n     } \n    #+END_SRC\n\n    #+RESULTS:\n    [[file:images\\graphviz.png]]\n\n    Diagrams using plantuml or ditaa.\n\n    #+BEGIN_SRC plantuml :file images/plantuml.png\n      Bob -> Sally : Says Hi\n      Sally -> Bob : Says Hi\n    #+END_SRC\n\n    #+RESULTS:\n    [[file:images\\plantuml.png]]\n\n    Or Graphs using GNU Plot\n\n    #+PLOT: title:\"Lines\" ind:2 deps:(3 4)  with:lines file:images/plot.png\n    |    Sede   |  Max   | H-index |  top  |\n    |-----------+--------+---------+-------|\n    | Sao Paolo |  71.00 |   11.50 |  13.5 |\n    | Stockholm | 134.19 |   14.33 | 16.33 |\n    | Leeds     | 165.77 |   19.68 | 21.68 |\n    | Morelia   | 257.56 |   17.67 | 19.67 |\n    | Chile     | 257.72 |   21.39 | 23.39 |\n    #+TBLFM:$4=$3+2.0\n\n    #+RESULTS:\n\n* Bold Italics Underline\n\n  Being a document interchange format org mode has support for the usual formatting suspects:\n\n    *bold*\n    /italic/\n    _underline_\n    +strikethrough+\n    ~code~\n    =verbatim=\n\n* Example, Verse, Quote, Center\n\n  Org also has support for quite a few simple example quote or verse blocks\n\n    #+begin_example\n    This is an example of something\n    in a block\n    #+end_example\n\n    #+BEGIN_QUOTE\n    This is a quote from something.\n    #+END_QUOTE\n\n    #+BEGIN_VERSE\n    A verse of poetry\n    #+END_VERSE\n\n    #+BEGIN_CENTER\n    A verse of poetry\n    #+END_CENTER\n\n    Some of these have snippets to help in creating them:\n\n    #+BEGIN_EXAMPLE\n      <s \n      <e\n    #+END_EXAMPLE\n\n\n* NOTE [#TOP] Priorities\n   General user defined priority tags work\n   but a, b, c, d, e have independent\n   coloring options in the grammar.\n** TODO [#A] Top priority\n   A body for this work item\n*** NEXT [#B] Second priority\n**** TODO [#C] Third priorty item\n***** TODO [#D] Third priorty item\n****** BLOCKED [#E] Third priorty item\n\n* Inline Images\n  Links can be used to show images or open\n  up an image viewer if followed.\n\n  Run: \"Org Show Image: on this link\n  Notice that this link is an HTML link, org can download and cache images locally for display purposes.\n  This will have problems for redirects, git lfs or other complex links.\n\n  #+CAPTION:   This is a caption for this image\n  #+ATTR_HTML: :width 200\n    [[https://raw.githubusercontent.com/ihdavids/orgextended_docs/master/images/orgstart.gif]]\n\n\n\n* Table Editor\n  At the moment I am using the Table Editor plugin for my table navigation, creation and manipulation.\n  The Alt and Shift + Alt plus arrow keys in a table will move rows and columns around and add them. Also \"Alt+o t -\"\n  will insert a hline below your cursor.\n\n  #+CAPTION: This is a table caption\n  |   Heading 1    | Heading 2 | Heading 3 |\n  |----------------+-----------+-----------|\n  | Some data      |         1 |         3 |\n  | More data      |         2 |         4 |\n  |----------------+-----------+-----------|\n  | Something else |         5 |         6 |\n\n\n  However, this is just the begining. Tables can act like spreadsheets! \n\n  #+ATTR_LATEX: :environment pmatrix :mode math\n  | a | b |\n  | 1 | 5 |\n  #+TBLFM:@2$2=$1*5\n\n  Here 2,2 (b) is filled in by taking 2,1 and multiplying it by 5.\n  There are a whole gamut of features, expressions, plotting and other table machinations available\n  and that is best left for the docs.\n\n* Dynamic Blocks\n\n  Dynamic Blocks are kind of like source blocks (listed above) but for generic code snippets. Emacs\n  makes these really really powerful since you can define new code snippets and functions ANYWHERE in the editor.\n\n  Sublime cannot do that, so instead we use a sub folder with python snippets in your User folder.\n  There are also a couple of built in blocks that we will talk about later. We have a test one that is always present:\n  called insertdatetime. Execute this block by pressing <space> c c or Alt + o + c + c and it will replace the block contents\n  with the current date and time.\n  \n  #+BEGIN: insertdatetime\n  If you run this, this text will be replaced with the current datetime\n  #+END:\n\n** Clocking\n   Another built in dynamic block that can be really handy is the clock table.\n   If you are preparing invoices and want to know how long you spent on various tasks, the clock table can be pretty handy.\n \n   Clocking is a built in org function. It uses a central data file in your User folder and a timestamp in your property drawer to track\n   how long you have spent on a task.\n \n   - \"Org Clock In\"  - Starts the clock on a task.\n   - \"Org Clock Out\" - Stops the clock\n \n   Running the table below will generate a table with your clocked data:\n \n   #+BEGIN: clocktable :scope subtree :level 2\n   |Heading|Time|\n   |-\n   |A|B|\n   #+END:\n \n   NOTE Clocking and the column view mode in emacs (which we don't fully support yet) go hand in hand as effort estimate vs actual time spent.\n\n*** A task with some time invested\n    :PROPERTIES:\n     CLOCK: [2020-03-31 Tue 16:28]--[2020-03-31 Tue 16:29] => 00:01\n     CLOCK: [2020-03-31 Tue 20:39]--[2020-03-31 Tue 20:55] => 00:16\n    :END:\n \n** Column View\n\n  Column mode in Emacs lets you look at your document headings as if they were a table and visualize the\n  properties (of your choosing) in the various headings as columns in a table. We don't yet have support for this\n  mode in sublime! But we will eventually.\n\n  For now, we have a piece of this... The columnview dynamic block\n\n  This table was NOT generated from this file. Columnview uses a configuration comment that looks something like so:\n\n  #+COLUMNS: %ITEM(Task) %Effort(Effort) %TODO(Todo) %DEADLINE(Deadline) %ALLTAGS(Tags) %TIMESTAMP(Time) %TIMESTAMP_IA(Inactive) %PRIORITY(Priority)\n\n  Some of these specify the heading, some properties (Like the Effort entry) Some of them DEADLINE details etc.\n  More information can be found in our little gantt chart demo:\n\n  [[https://github.com/ihdavids/orgextended_docs/blob/master/learning_gantt_example.org][Gantt Demo]]\n\n  Or in the Org Manual:\n\n  [[https://orgmode.org/manual/Capturing-column-view.html#Capturing-column-view][Column View]] \n\n  #+BEGIN: columnview  :hlines nil :id global :indent t :maxdepth 2 :exclude-tags (ExcludeMe)\n   | Task                       | Effort | Todo | Deadline             | Tags  | Time                 | Inactive             | Priority |\n   | 1.1.26                     |        |      |                      | a     |                      |                      |          |\n   | ..Source Blocks            | 2d     | DONE |                      | a     |                      |                      |          |\n   | ..Folding                  |        |      |                      | a     |                      |                      |          |\n   | ..Properties               | 2d     |      | 2021-03-09 Tue 20:55 | a     |                      |                      |          |\n   | ..Spreadsheets Preview V11 | 4h     |      |                      | a tag | 2021-03-09 Tue 14:53 |                      |          |\n   | ..ColumnView Dynamic Block | 1d     |      |                      | a     |                      | 2021-03-09 Tue 11:00 | B        |\n  #+END:\n\n* Named Object Target\n\n  Object in orgmode can have a name. This is here so we have something to target from the links example above.\n\n  #+NAME: MyNamedObject\n  | Hello      | World |\n  | Some Table |       |\n\n\n* ID Target Example\n  :PROPERTIES:\n    :ID: 33da3712-51b7-485c-b69d-f54dd266543f\n  :END:\n\n  Headings can have a generated ID. This is here so we have something to target in the links example above.\n\n* Custom IDs\n  :PROPERTIES:\n    :CUSTOM_ID: My-Custom-Id\n  :END:\n\n  Headings can have a custom ID. This is here so we have something to target in the links example above.\n\n* Table Remote Test\n\n  One of the interesting abilities that comes along with tables is the ability to reference data in other tables.\n  Here is an example of referencing the data in the table above in Named Object Target.\n\n  | a          | b | c | d | e |\n  | Some Table |   |   |   |   |\n  #+TBLFM:@2$1=remote(\"MyNamedObject\",@2$1)\n\n* Time Data\n  :PROPERTIES:\n    :CUSTOM_ID: my-custom-id\n  :END:\n  These are some common time values used in testing the agenda.\n  The dates and times will be out of date. Replace these with your own\n  to test the agenda.\n\n  There are some todos and some non todos. Both can appear in the agenda when active.\n\n** TODO Time range\n   <2021-02-16 Thu 16:00-17:00> \n\n** TODO Scheduled Date\n   SCHEDULED: <2021-02-10 Wed 16:49> \n \n** TODO Deadline Date w Warning\n   SCHEDULED: <2021-02-10 Wed 16:49 -2d> \n \n** TODO Test Recurrence\n   <2021-02-16 Tue 14:10-15:10 +1d>\n \n** TODO Recurring Active\n    <2021-02-15 Wed 14:40 +1d> \n \n** Time range\n   <2021-02-16 Thu 16:00-17:00> \n\n** Scheduled Date\n   SCHEDULED: <2021-02-10 Wed 16:49> \n \n** Deadline Date w Warning\n   SCHEDULED: <2021-02-10 Wed 16:49 -2d> \n \n** Test Recurrence\n   <2021-02-16 Tue 14:10-15:10 +1d>\n \n** Recurring Active\n    <2021-02-15 Wed 14:40 +1d> \n\n** TODO Recurring BUT ARCHIVED                                            :ARCHIVED:\n    <2021-02-15 Wed 14:40 +1d> \n\n\n\n$e^{i\\pi}+1=0$\n\n\n\n[[http://reg.ca]] \n** DONE Done task1 \n   CLOSED: [2021-05-13 Thu 23:14]\n\n** DONE Task 2\n   CLOSED: [2010-05-13 Thu 23:14]\n\n   \n\n* TODO Hi\n\n\n* Clocker\n   #+BEGIN: clocktable :scope subtree :level 2\n  |    Heading    |  Time |       |\n  |---------------+-------+-------|\n  | Clocker       | 00:18 |       |\n  | \\_ Clocktest1 |       | 00:18 |\n   #+END:\n** Clocktest1\n  :LOGBOOK:\n    CLOCK: [2021-05-29 Sat 00:05]--[2021-05-29 Sat 00:23] => 00:17\n    CLOCK: [2021-05-29 Sat 00:23]--[2021-05-29 Sat 00:23] => 00:00\n    CLOCK: [2021-05-29 Sat 00:23]--[2021-05-29 Sat 00:23] => 00:00\n  :END:\n\n* PerlTest\n\n  #+NAME: input-table\n  | a | b | c |\n  | 1 | 2 | 3 |\n  \n  #+BEGIN_SRC perl :var DATA=input-table :results table\n    foreach(my $m = 0; $m <= $#DATA; $m++)\n    {   \n      for(my $n = 0; $n <= $#{$DATA[$m]} ; $n++)\n      {  \n        print \"$DATA[$m][$n] \";  \n      }  \n      print \"\\n\";  \n    } \n  #+END_SRC\n  #+RESULTS:\n  | a | b | c |\n  | 1 | 2 | 3 |\n\n  #+BEGIN_SRC perl :results value\n    return \"Hello world\"\n  #+END_SRC\n  #+RESULTS:\n  : Hello world\n\n* CSharpTest\n  \n  #+BEGIN_SRC csharp\n    using System;\n    Console.Writeline(\"Hello world\");\n  #+END_SRC"
  },
  {
    "path": "todo.org",
    "content": "#+TITLE: Org Extended Todo Lists\n#+STARTUP: content\n  \n* RANDOM BACKLOG  \n** TODO Misc [0/3]\n\t- [ ] TODO states are fully dynamic, even in coloring? Not sure I can make that possible.\n\t- [ ] Searching by tag (like occur style?)\n\t- [ ] Presentation mode from a file.\n\n** TODO Extensibility [2/5]\n\t- [x] Avoid reloading when files do not change\n\t- [ ] Similar folder names for all extensions in User folder\n\t- [ ] Document all extensibility in user folder (and test it)\n\t- [ ] Symbol and function table is only created once and reused. \n\t- [x] Document all items available in the settings file. (Might be best just to do this in the settings file?)\n\n** TODO Capture [71%]\n \t- [ ] Capture panel size controls?\n \t- [ ] External Capture (orgprotocol)\n \t- [ ] Capture in Orgs\n \t- [x] Basic capture buffer\n \t- [x] Templates in config file.\n \t- [x] Capture targetting\n \t- [x] *Capture manages level properly (BROKEN)*\n \t- [x] Capture using sublime snippets\n \t- [x] Capture with view vs panel (better for neovintageous users)\n \n** TODO Refiling [2/3]\n \t- [x] Basic Refile support\n \t- [x] Basic Copy support\n \t- [ ] More complex options for refiling.\n \n** TODO Archiving [5/8]\n \t- [x] Copy to org_archive an entire subtree\n \t- [ ] (Low Priority) Archive by old datetime stamps\n \t- [x] (Low Priority) Archive by adding :ARCHIVE: tag\n \t- [ ] (Low Priority) Archive projects without TODO tags.\n \t- [ ] Configuration for what gets added to the archive entries\n \t- [x] #+ARCHIVE tags\n \t- [x] Global archive option\n \t- [x] Unicode Archiving Support\n \n** TODO Dynamic Blocks [4/5]\n \t- [x] Basic dynamic blocks\n \t- [ ] Test user side blocks\n \t- [x] clocktable block\n \t- [x] Clock reports\n \t- [x] execute all dynamic blocks in file command\n \n** TODO Column View and Effort [0/2]\n \t- [ ] Column view (Is this possible in sublime?)\n \t- [ ] Effort Estimate\n \n** TODO Google Calendar Integration [0/4]\n \t- [ ] This I am going to do by publishing calsync eventually.\n \t- [ ] Also build this into orgs\n \t- [ ] Pull my calendar\n \t- [ ] Update my calendar\n \n** TODO Tables [22/25]\n \t- [x] Basic table editing (Table Edit?)\n \t- [x] Syntax highlighting of tables\n \t- [x] Formula highlighting in tables\n \t- [ ] Bold headers in tables\n \t- [x] Table formats\n \t- [x] Table parameters to execution blocks\n \t- [x] Relative offsets in tables\n \t- [x] In cell formulas\n \t- [x] From edge symbols\n \t- [x] Date time calc functions\n \t- [x] Start column for column formulas\n \t- [x] Range operator for cells\n \t- [x] Range targets for cells\n \t- [x] HLine indexes\n \t- [x] Table visualization\n \t- [x] Table resizing updates formulas\n \t- [x] Extensible functions for tables\n \t- [x] Documentation page for tables\n \t- [ ] Extensible symbols for tables\n \t- [x] Advanced table features\n \t- [x] Gnu Plot Support\n \t- [x] Table cache handles multiple files.\n \t- [x] Remote keyword handles tables in other files.\n \t- [x] Named Objects [100%]\n \t\t- [x] Works with babel\n \t\t- [x] Identifies tables and other things\n \t- [ ] Performance, 1000x1000 should be possible to work in efficiently\n \n** TODO Clocking [2/7]\n \t- [x] Basic Clocking\n \t- [ ] Todo list showing by clock history\n \t- [x] Clock report todo view (day, week, month)\n \t- [ ] Clock report to mermaid output\n \t- [ ] Auto record sublime death in clocking and stop clock\n \t- [ ] Clock has its own status panel\n \t- [ ] Manually adjust clock time once clocked in.\n \t\t  (Sometimes I forget to clock in and I don't want to have to remember to adjust it AFTER I clock out.)\n \n** TODO Logging [0/2]\n \t- [ ] Todo state controls (Markup @ symbol etc.)\n \t- [ ] Logging and notes on certain state transitions.\n \n** TODO Agenda [4/5]\n \t- [x] Agenda? Integration with existing plugin? NO\n \t- [x] Week View\n \t- [x] Week Quick Select\n \t- [x] Core Agenda [8/8]\n \t\t- [x] Todo list (dynamic)\n \t\t- [x] Extensible agenda views\n \t\t- [x] org_calendar - will it work for me? (NO) - to linked to old orgmode\n \t\t- [x] Todo summaries?\n \t\t- [x] More extensible views.\n \t\t- [x] Week View\n \t\t- [x] Calendar is selectable for day view?\n \t\t- [x] Formatting for today line in day view?\n*** TODO Notifications [3/7]\n         - [ ] Fully customizable\n         - [x] Windows Support\n         - [x] Mac Support\n         - [x] Linux popup\n         - [ ] Windows powershell prompt (ascii art)\n         - [ ] Notifications pop up properly!\n         - [ ] Notifications checks are not as expensive. (Use Orgs maybe?)\n \n \n** TODO Editing [22/24]\n \t- [x] Vintageous bindings\n \t- [x] Quotes\n \t- [x] Src blocks (more languages finish the color scheme)\n \t- [x] Symbol indexing for headers\n \t- [x] Color highlighting for #+ symbols\n \t- [x] Image display? Is that possible?\n \t- [x] csharp mode still doesn't exit properly for some reason? Something is up with that grammar\n \t- [x] Persistent folding between open and close\n \t- [x] Sublime snippets?\n \t- [-] Snippets [4/5]\n \t\t- [x] Src block snippet\n \t\t- [x] Quote block snippet\n \t\t- [x] Notes block snippet\n \t\t- [ ] Name snippet\n \t\t- [x] Example block snippet\n \t- [x] Numbered Lists\n \t- [ ] Todo cycling\n \t- [x] Todo menu\n \t- [x] Priority menu\n \t- [x] Insert heading (child and sibling)\n \t- [x] Insertion flow with dwim style insertion (new headings, new checkboxes etc)\n \t- [x] Caret when editing is propper\n \t- [x] Indent, De-Indent heading and subtree\n \t- [x] Heading movement, like you can do with lines\n \t- [x] Checkbox insert?\n \t- [x] Auto indenting of checkboxes (with tab)\n \t- [x] Property insertion\n \t- [x] Fix Tag Insertion (tooltip is broken for some reason)\n \t- [x] Fix Tab Insertion (snippets are now not expanding properly) (ST4 only issue)\n \n \n** TODO Checkboxes [3/3]\n \t- [x] Checkbox summary updating\n \t\t- [x] Recursive mode for checkbox summaries (1.1.19)\n \t- [x] Checkbox percentages\n \t- [x] BUG: Summaries on headings fall through to rest of list\n \n** TODO DatePicker [1/5]\n \t- [ ] Support +XXX versions of commands\n \t- [ ] Support Expanding dates inline in buffer from date text (like a snippet)\n \t- [ ] Support Scrolling on dates with hotkeys\n \t- [x] Support Prettier clock\n \t- [ ] Better colors for clock\n \n** TODO Links [11/19]\n \t- [x] Orgmode style links\n \t- [x] images displayed inline\n \t- [ ] #+ATTR_ORG: :width 100 supported for images\n \t- [x] Single entry links vs with description (don't auto fold)\n \t- [x] Follow links on various platforms.\n \t- [x] Link copy\n \t- [ ] Link insertion\n \t- [x] Link snippet\n \t- [x] Collapsing links/pretty formatting (not possible) or can this be done with folding?\n \t- [ ] Links in templates.\n \t- [x] Ensure file: works (currently doesn't work that well)\n \t- [x] <<TAG>> works for links\n \t- [ ] Named objects work\n \t- [ ] Ensure line number\n \t- [ ] search links\n \t- [x] regex links works for links\n \t- [x] custom_id links work\n \t- [ ] Write a page about personal wikis\n \t- [ ] Link aliases, find a way of making that work well. How about doing this like dynamic blocks? Simplify the resolver?\n \n \n** TODO Parsing [5/6]\n \t- [x] Basic file parsing\n \t- [x] Tags parsed.\n \t- [x] Comments (#+) available\n \t- [x] Positions available\n \t- [ ] Stripping to keep in memory size down.\n \t- [x] Folding on unsaved files seems to have a problem sometimes\n \n** TODO Jira\n     - [ ] Query Jira for My Stuff\n \n** DONE Folding [12/12]\n \t- [x] Fold cycling\n \t- [x] Local fold cycling\n \t- [x] Fold cycling in a modified file (currently gets confused)\n \t- [x] Global fold cycling\n \t- [x] Initial folding state control tag\n \t- [x] Fold ALL, Unfold ALL commands\n \t- [x] Folding property drawers\n \t- [x] Folding src and quote blocks\n \t- [x] Automatic property drawer folding. (I hate seeing those things!)\n \t- [x] Fixing folding over a git pull! Sublime folds don't adapt and persist across a save.\n \t- [x] Folding of all generic property drawers.\n \t- [x] Folding of checkbox trees\n \n** DONE Formatting [9/9]\n \t- [x] Basic syntax highlighting\n \t- [x] Priority blocks\n \t- [x] Smarter heading blocks\n \t- [x] Fix priority highlighting.\n \t- [x] Property drawers vs tags.\n \t- [x] Strings?\n \t- [x] Finish the babel work.\n \t- [x] Htmlify\n \t- [x] Priorities (From format block)\n*** DONE Colored Headers\n*** DONE Underlined Headers\n \n** DONE Export [6/6]\n \t- [x] Pandoc\n \t- [x] Reveal.js support\n \t- [x] Export subtree\n \t- [x] Export to html\n \t- [x] Export to latex\n \t- [x] Export to pdf\n \n** DONE Core Babel [5/5]\n \t- [x] plantuml and dot integration?\n \t- [x] latex?\n \t- [x] noweb\n \t- [x] naming src blocks\n \t- [x] parameters from tables\n\n* BIGGER FUTURE RELEASE IDEAS\n** TODO Ghost View (Webpage or overlay rendering?)\n** TODO Ghost View in Agenda (Popup of task in overlay, but rendered)\n** TODO Better Back References\n** TODO Convert to Orgs as DB rather than python DB.\n** TODO Interactive Hud for Querying TODO Lists (using orgs)\n** TODO Improved Spreadsheets (formula export / import)\n** TODO Improved integration with mermaid et al, render timeline etc.\n** TODO Estimation support (column view) \n   - not really sure if I can do this in sublime yet. REALLY hope the sublime team gives me some of the features I have been asking for\n   \tEmacs has a lovely means of editing properties on all headings in a file.\n\tThis is called column mode. It is implemented as an overlay on a buffer... which means... we can't do it in sublime.\n\n\tRight now my thought is that we might implement it with phantoms and the input panel. We might do as follows:\n\n\t- Flip to a column fold of the document\n\t- Insert phantoms at every heading that have the table elements\n\t- Support cursor navigation of the phantoms with the input panel representing the active cell.\n\t- Dynamically update the folded properties as we go.\n\n\tIt's lame, but it's the best idea I have right now.\n** TODO Quality of life\n   - Build a fully interactive unit test for the system\n   - Improve auto highlighting construction\n   - Improve todo lists to include headings\n** TODO Presentation Mode in Sublime\n   - Again I don't really have enough features for this, but I could try I suppose. \n** TODO Videos about the plugin\n** TODO Org For Writers\n\n\tThe idea of this is to use org mode to emulate some of the more common writing tools such as scrivener\n\n\tThis has been something that emacs has had for years and some writers do indeed use it.\n\n\tWe split the layout into 2 views.\n\tWe show the same document in both views\n\tThe view on the left we have a ViewEventListener for that:\n\tForces the document to stay folded in contents view mode. You can unfold for a quick look but it will refold again like links and properties do.\n\tIt listens for you to press enter and if you do it jumps to that heading in the right pane.\n\tThe right pane has a view event listener that is tracking selection. When that moves it highlights a region in the left pane on the heading you are currently in!\n\tIn this way you have a table of contents view with sections and can easily jump around.\n\tWe create helper methods to create property drawers for notes and other writers aids. These are hidden away.\n\tWe support export to PDF and other common ebook formats that writers tend to publish in.\n\n** TODO Read The Org Export\n\n\tI would like to create a default html style export that behaves a looks a lot like Read The Org, which is a very popular style for emacs. \n\n* RELEASES\n** DONE 1.1.0 - Editing, Capture, Refiling, Searching\n** DONE 1.2.0 - Full Table Alpha\n   My goal here is to remove the Preview moniker from tables. That said some of the work will be\n   outside of pure table support but rather be about building the start of our babel feature.\n \n   The \"big reveal\" of 1.2.0 is going to be this:\n \n   [[https://www.youtube.com/watch?v=5ViUBaarsbw][Gantt Charts In Org]] \n \n**** Planned Releases\n***** DONE 1.1.27 - Extending Date Formula Support\n***** DONE 1.1.28 - Core Performance and Quality of Life\n***** DONE 1.1.29 - GNU Plot Script Blocks\n***** DONE 1.1.30 - Table Babel\n***** DONE 1.2.0  - RELEASE\n  \n*** DONE 1.1.27 \n     Core Idea: Extending datetime formula support\n                you should be able to make the table the guy shows in the video\n                with some \"OrgExtended\" flair to make it easier.\n**** Ian Goals\n    I am working towards this as my ultimate goal\n    [[https://www.youtube.com/watch?v=5ViUBaarsbw][Gantt Charts In Org]] \n  \n    For 1.1.26 I am hoping to have the full creation of the table\n    functional, but with some added bells and whistles that allow\n    you to create that table dynamically directly in the columnview\n    rather than having to build the table every time you want a gantt chart.\n  \n    - [x] Support adding formulas to the generated table in the columnview description somehow\n    - [x] Support adding non existent columns in the columnview description (probably just property markers)\n    - [x] Support date() parsing cells\n    - [x] Support OrgDate converting back to a string properly\n    - [x] Support OrgDate + OrgDuration additions so you do not have to remove the d from the effort estimate.\n    - [x] Support percentage strings\n    - [x] Support if statement in tables \n  \n**** DONE 1.1.27 Documentation Goals\n    - [x] Document advanced tables\n    - [x] Audit other major features that I might have forgotten?\n  \n*** DONE 1.1.28 \n     Core Idea: Table Performance and Quality of Life\n                I should feel like the table feature is not needlessly expensive\n                and I can use it for babel.\n**** Ian Goals\n  \t- [x] Improve function table creation times. Can we cache this?\n  \t- [x] Test table cache across multiple files?\n  \t- [x] Create symbol parsing cache?\n  \t- [x] Turn off highlight durng execution view updates\n  \t- [x] Create table from node vs view (improve remote function) - *Important for babel*\n  \t- [x] Cleanup table? Move plot out of table file?\n  \t- [x] Cleanup table? Hoist any utility functions?\n  \t- [x] Cleanup table? Improve parameter parser around quotes?\n  \t- [x] Support extensible symbols as well as functions.\n    - [x] Add GnuPlot syntax\n  \n**** Documentation Goals\n    - [x] Document all available functions (using a TextCommand) (can we create docstrings for this and pull from that?)\n    - [x] Document all available symbols\n    - [x] Start column view docs\n    - [ ] Add docstrings to all functions.\n  \n*** DONE 1.1.29\n    Core Idea: Add GNU Plot Script Blocks\n \n    - [x] Add a syntax for gnu plot script blocks if one does not already exist\n    - [x] Add a src handler to execute these script blocks.\n    - [x] Any prep/improvements I feel is necessary to support setting up for table source data and babel work\n \n**** Documentation Goals\n \t- [x] Write a tool to dump out the list of supported script blocks to our docs.\n \t- [x] Add that to our script block page.\n \n*** DONE 1.1.30\n \tCore Idea: Table Babel\n \n**** Ian Goals\n \t- [x] Support tables as data sources for babel\n    - [x] Provide tool for detecting datetimes in cells\n    - [x] GNU Plot converts dates automatically\n \n \t--> More research required here as to the full list of tasks.\n \n**** Documentation Goals\n \t- [x] Table Babel Demo\n \n*** DONE 1.2.0\n**** Ian Goals\n    - [x] Full unit test suite\n    - [x] More functions for table editing.\n \t\n**** Documentation Goals\n \t- [x] Gantt chart demo page.\n \n \n** TODO 1.3.0 - Full Babel Support\n*** Babel - What this is\n    Babel has at its root 2 ideas:\n\n  \t- Literate Programming  :: The concept that programming is more about communication to programmers than communication to a machine\n  \t- Reproducible Research :: The idea that all tools, data, process and output should be part of a research document.\n\n**** Script vs Function\n\tBable supports the notion of script vs function execution.\n\tIn script mode babel will capture stdout and stderr and treat that as the output\n\tIn function mode babel will treat the code as a function and capture the output of the last statement\n\tand format it back to text.\n\n\tFunctional:\n\n\t#+BEGIN_EXAMPLE\n\t  :results value\n\t#+END_EXAMPLE\n\n\tScript:\n\n\t#+BEGIN_EXAMPLE\n\t  :results output\n\t#+END_EXAMPLE\n\n**** Simple Variables\n\tSource blocks can and should support :var key=data-source-or-value entries\n\tThese specify the available parameters to a source block.\n\n**** Sources\n\tI was thinking we could treat sources as plain old data types OR generators.\n\tGenerators represent the abstract concept of a list and can pull from almost anywhere.\n\n**** Tables as Source\n\n\tTable data should be an optional source for any source block.\n\n**** Lists as Source\n\n\tList blocks in code should be an optional source for any source block.\n\n**** Output Formats\n\n\tThe system needs to be smart enough to detect tabular data and output it as:\n\n\t- a link\n\t- a table\n\t- simple output\n\t- a list\n\t- silent\n\n\t#+BEGIN_EXAMPLE\n\t  :results silent\n\t  :results replace\n\t#+END_EXAMPLE\n\n**** Call Comment Block\n\n\tThese are a way of invoking a script block several times with different parameters.\n\n\t#+BEGIN_EXAMPLE\n\t  #+call: srcblockname(x=6)\n\t#+END_EXAMPLE\n\n**** Table Functions\n\tScript blocks need to be called from a TBLFM: block on a table. This is done through\n\ta function that takes the name and parameters. (sbe function)\n\n**** Tangle\n\tThe ability to strip code from a document and produce a fully functional\n\tpiece of source code. The tangle engine is dependent on the language snippets to help\n\tformat the code.\n\n\t- OrgTangleDocument - Should produce source files following the tangle parameters in src blocks.\n\n\tNote NoWeb macros should be respected and evaluated as part of the tangle process.\n\n \t#+BEGIN_EXAMPLE\n\t:export none\n\t:tangle\n \t#+END_EXAMPLE\n\n**** NoWeb\n\t- A macro like language inside of source blocks:\n\n\t#+BEGIN_EXAMPLE\n\t  <<pasted-source-named-x-here>>\n\n\t  # <<call-source-named-y(a=5)>>\n\t#+END_EXAMPLE\n\n**** Sessions\n\t*Probably not going to support this!*\n\n\tBabel supports the notion of working with sessions. This becomes huge when you want to use babel for execution\n\ton remote machines through ssh et al. IMHO this is a last feature to support. \n*** DONE 1.2.1 - Basic Input\n    - [x] Python supports table sources\n    - [x] Powershell supports table sources\n    - [x] Unordered lists can act as data sources\n    - [x] Ordered lists can act as data sources\n    - [x] Plain variables work embedded in block header.\n \n*** DONE 1.2.2 - Better Input, Some Output \n    - [x] Quoted strings work for properties.\n    - [x] Property and variable blocks can act as variable sources.\n    - [x] Table output works.\n \n*** DONE 1.2.3 - Execution Modes\n    - [x] List output works\n    - [x] drawer format\n    - [x] code format\n    - [x] org format\n    - [x] raw format\n    - [x] file format\n    - [x] text format\n    - [x] Parameters\n    - [x] Output to Drawer\n \n*** DONE 1.2.4\n    - [x] results value\n    - [x] results output\n    - [x] results replace\n    - [x] results prepend\n    - [x] results append\n    - [x] results silent\n    - [x] chaining execution\n \n*** DONE 1.2.5 - Calling\n    - [x] better chaining of functions\n    - [x] handle silent functions.\n    - [x] #+call\n    - [x] Table sbe functions\n \n*** DONE 1.2.6 - Inline Blocks\n    - [x] Inline blocks and execution\n    - [x] #+header blocks \n \n*** DONE 1.2.7/1.2.8 - Quality of Life\n    - [x] Build some unit tests in a table\n \n*** DONE 1.2.9 - Tangle\n    - [x] Support tangling\n    - [x] Cache - support hash value in results\n    - [x] Eval - never and query\n --- Fixed Color Scheme Export, and ST3 dependencies problem in here.\n*** DONE 1.2.15 - NoWeb\n    - [x] NoWeb for pasting\n    - [x] NoWeb for parameters\n    - [x] NoWeb function calls\n \n*** DONE 1.2.16 - Batch File\n    - [x] More testing of noweb\n    - [x] Dos CMD support\n    - [x] Params / Vars\n \n*** DONE 1.2.18 - Bash and JavaScript\n    - [x] Bash block\n    - [x] Bash module and supports table sources?\n    - [x] The community seems to use node.js a lot perhaps this one is a good one to support.\n \n*** DONE 1.2.19 - Caching Security and Exports\n    - [x] Exports - Various export controls / mechanisms\n \n*** DONE 1.2.20 - Cleanup\n    - [x] Cleanup\n \n*** DONE 1.2.21 - Latex\n    - [x] Kind of got off track and am adding latex exporter support\n \n*** DONE 1.2.22 - More Latex\n    - [x] Latex Basics are done\n \n*** DONE 1.2.23 - Full Latex?\n    - [x] Images are supported\n    - [x] Better link support (use \\url in the right places)\n    - [x] Results are handled properly during export\n    - [x] Local refs work for links\n    - [x] Table of contents can be included\n    - [ ] Export DND sample (and it works)\n    - [x] Strip todo, tags, property and other blocks\n    - [x] Options audit\n \n*** DONE 1.2.24 - 1.2.49 Off Track!\n \t- [x] Bugfixes\n \t- [x] Improving Clocking\n \t- [x] Improving Task List filtering\n \t- [x] Org Dailies (Org Roam Like Feature)\n\n*** TODO 1.2. - Html Exporter Upgrade\n    - Convert the exporter to use the new framework\n    - Improve the documentation\n \n*** TODO 1.2. - Perl\n    - [ ] Support perl in honour of graham\n \n*** TODO 1.2. - Typescript\n    - [ ] Support typescript in honour website work\n \n*** TODO 1.2. - C#\n    - [ ] .NET Core Support\n    - [ ] .NET Core Params / Vars\n \n*** TODO 1.2. - Go\n    - [ ] Basic Go Snippet Support\n \n*** TODO 1.2. - RUST\n    This one I may not do, we will see. It is becomming a really highly useful language though.\n    I find myself occasionally working in it, so I will consider it.\n \n    - [ ] Basic RUST Snippet Support\n \n \n*** TODO 1.3.0 - RELEASE\n    Full Babel Support \n    - What big target are we trying to hit?\n   \n \n\n\n* FUTURE PLUGIN IDEAS\n** TODO TRAMP\n \t- I would love to hook this in to babel as well.\n \t- I would love to see this embeded into sublime as a whole\n \t  this IS one of the powerful tools of emacs.\n \n** TODO GUD - Grand Unified Debugger\n \t- I would love to see something like GUD ported\n \n** TODO Mu4E\n \t- I love using Mu once I have org.\n \n** TODO EDiff\n \t- There are diff tools for sublime but ediff is simple and awesome\n \t  the other tools cost to much money IMHO and I find them a bit buggy.\n \n \n\n\n\n\n\n\n* Combat\n\n** Combat\n   #+NAME: Combat-Action\n   |     PC     |   Damage   |     |\n   |------------+------------+-----|\n   | John       | 2          |     |\n   | Sam        | 0          |     |\n   | Brigand    | 9          |     |\n   | Rabid Wolf | 2          |     |\n   |------------+------------+-----|\n   | I Hit      | Who        | For |\n   |------------+------------+-----|\n   | Sam        | Rabid Wolf | 2   |\n   | John       | Brigand    | 8   |\n   | Sam        | Brigand    | 1   |\n   | Rabid Wolf | John       | 2   |\n   #+TBLFM: @2$2..@5$2=vsumifeq($2,$1,@7$3..@>$3,'b_or')\n\n** Player Info\n   #+NAME: Player-Stats\n   | Player | Start Health | Temp Hits | AC | Damage | Cur Hp | Initiative |\n   |--------+--------------+-----------+----+--------+--------+------------|\n   | John   |           13 |         0 | 18 |      2 |     11 |            |\n   | Sam    |           15 |         0 | 13 |      0 |     15 |            |\n   #+TBLFM:@2$5=remote('Combat-Action',@2$2)::@3$5=remote('Combat-Action',@3$2)::$6=($2+$3)-$5::$6=gradient($6,($6/$2)*100.0,\"red\",\"orange\",\"yellow\",\"cyan\",\"green\")\n \n** Monsters\n   #+NAME: Monster-Stats\n   |    Name    | Start Health | Damage | Cur Hp | AC | Initiative |\n   |------------+--------------+--------+--------+----+------------|\n   | Brigand    |           10 |      9 |      1 |  4 |            |\n   | Rabid Wolf |           12 |      2 |     10 |  2 |            |\n   #+TBLFM:@3$3=remote(\"Combat-Action\",@5$2)::@2$3=remote(\"Combat-Action\",@4$2)::$4=$2-$3::$4=gradient($4,($4/$2)*100.0, \"red\",\"orange\",\"yellow\",\"cyan\",\"green\")\n \n"
  }
]