Scripts collection

Discuss and announce AkelPad plugins
  • Author
  • Message
KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Sorts lines according to two keys: by line length and by string, alphabetically or numerically.
Removes duplicate lines.
Reverses the order of lines.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10988#p10988
// Version: 2019-07-01
// Author: KDJ
//
// *** Sort lines ***
//
// Sort lines according to two keys: by line length and by string, alphabetically or numerically; removes duplicate lines, reverses the order of lines
//
// Usage:
//   Call("Scripts::Main", 1, "SortLines.js")
//
// Shortcut keys in dialog box:
//   Enter - Sort
//   Esc   - Close
//   Shift+Alt+Right (Left, Down, Up, End, Home, PgDn, PgUp) - move dialog box.

if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 0x0415) //Polish
{
  var sTxtCaption   = "Sortowanie wierszy";
  var sTxtRange     = "Zakres";
  var sTxtFrom      = "Od";
  var sTxtTo        = "Do";
  var sTxtLines     = "Wiersze:";
  var sTxtColumns   = "&Kolumny:";
  var sTxtKeys      = "Klucze sortowania";
  var sTxtKey1      = "Klucz &1 - Długość wiersza";
  var sTxtKey2      = "Klucz &2 - Zawartość wiersza";
  var sTxtRTL       = "Czytaj od prawej do lewej";
  var sTxtEntLine   = "Cały &wiersz";
  var sTxtDesc      = "&Malejąco";
  var sTxtIgCase    = "&Ignoruj wlk. liter";
  var sTxtString    = "&String";
  var sTxtLocale    = "&Alfabetycznie";
  var sTxtNum       = "&Numerycznie";
  var sTxtSortAnd   = "Sortuj, a następnie";
  var sTxtRemoDuKey = "&Usuń wiersze z duplikatami kluczy";
  var sTxtExtrDuKey = "&Zachowaj tylko wiersze z duplikatami kluczy";
  var sTxtExtrUnKey = "Zac&howaj tylko wiersze z unikalnymi kluczami";
  var sTxtNoSort    = "Nie sortuj, ale";
  var sTxtReverse   = "&Odwróć kolejność wierszy";
  var sTxtCopyToCB  = "Wynik kopiuj do schowka, nie zmieniaj &tekstu";
  var sTxtUsePlug   = "Użyj wtyczki &Format";
  var sTxtSort      = "Sortuj";
  var sTxtUndo      = "&Cofnij"; 
  var sTxtRedo      = "&Powtórz";
  var sTxtNoRangeL  = "Brak zakresu wierszy.";
  var sTxtNoKey2    = "Brak zakresu kolumn w drugim kluczu sortowania.";
}
else if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 0x0419) //Russian translation by AZJIO
{
  var sTxtCaption   = "Сортировка строк";
  var sTxtRange     = "Диапазон строк";
  var sTxtFrom      = "От";
  var sTxtTo        = "До";
  var sTxtLines     = "Строки:";
  var sTxtColumns   = "&Колонки:";
  var sTxtKeys      = "Сортировать по ключам";
  var sTxtKey1      = "Ключ &1 - По длине строки";
  var sTxtKey2      = "Ключ &2 - По содержимому";
  var sTxtRTL       = "Читать справа налево";
  var sTxtEntLine   = "Вычислять всю &строку";
  var sTxtDesc      = "&По убыванию";
  var sTxtIgCase    = "&Игнор регистр";
  var sTxtString    = "&Строка";
  var sTxtLocale    = "&По алфавиту";
  var sTxtNum       = "&По номерам";
  var sTxtSortAnd   = "Сортировать, и далее:";
  var sTxtRemoDuKey = "&Удалить строки с дубль-ключами";
  var sTxtExtrDuKey = "&Оставить строки только с дубль-ключами";
  var sTxtExtrUnKey = "Оставить строки с уникальными ключами";
  var sTxtNoSort    = "Не сортировать, но:";
  var sTxtReverse   = "&Обратный порядок строк";
  var sTxtCopyToCB  = "Результат в буфер обмена, не изменяя документ";
  var sTxtUsePlug   = "Использовать плагин &Format";
  var sTxtSort      = "Сортировать";
  var sTxtUndo      = "&Отменить";
  var sTxtRedo      = "&Вернуть";
  var sTxtNoRangeL  = "Нет диапазона строк.";
  var sTxtNoKey2    = "Нет диапазона колонок во 2-м ключе сортировки.";
}
else
{
  var sTxtCaption   = "Sort lines";
  var sTxtRange     = "Range";
  var sTxtFrom      = "From";
  var sTxtTo        = "To";
  var sTxtLines     = "Lines:";
  var sTxtColumns   = "&Columns:";
  var sTxtKeys      = "Keys";
  var sTxtKey1      = "Key &1 - Line length";
  var sTxtKey2      = "Key &2 - Line content";
  var sTxtRTL       = "Read from right to left";
  var sTxtEntLine   = "&Entire line";
  var sTxtDesc      = "&Descending";
  var sTxtIgCase    = "&Ignore case";
  var sTxtString    = "&String";
  var sTxtLocale    = "&Alphabetically";
  var sTxtNum       = "&Numerically";
  var sTxtSortAnd   = "Sort, and also";
  var sTxtRemoDuKey = "Re&move lines with duplicate keys";
  var sTxtExtrDuKey = "E&xtract lines with duplicate keys";
  var sTxtExtrUnKey = "Extra&ct lines with unique keys";
  var sTxtNoSort    = "Not sort, but";
  var sTxtReverse   = "Reverse &order of lines";
  var sTxtCopyToCB  = "Resul&t copy to clipboard, do not replace text";
  var sTxtUsePlug   = "Use &Format plugin";
  var sTxtSort      = "Sort";
  var sTxtUndo      = "&Undo";
  var sTxtRedo      = "&Redo";
  var sTxtNoRangeL  = "There is no range of lines.";
  var sTxtNoKey2    = "There is no range of columns in second key.";
}

var DT_DWORD    = 3;
var BM_SETCHECK = 241;

var oSys       = AkelPad.SystemFunction();
var hMainWnd   = AkelPad.GetMainWnd();
var hEditWnd   = AkelPad.GetEditWnd();
var hGuiFont   = oSys.Call("Gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
var hInstDLL   = AkelPad.GetInstanceDll();
var sClassName = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstDLL;
var bKey1      = 0;
var bDescLen   = 0;
var bKey2      = 1;
var bRTL       = 0;
var bEntLine   = 0;
var bDesc      = 0;
var bIgCase    = 1;
var nMethod    = 1;
var nSortAnd   = 0;
var nNoSort    = 0;
var bCopyToCB  = 0;
var bUsePlug   = 0;
var nUndoLimit = 0;
var nRedoLimit = 0;
var nWordWrap;
var nLastCol;
var hWndDlg;
var lpBuffer;
var bGetSel;
var bIsReturn;
var hFocus;
var nWndPosX;
var nWndPosY;

ReadWriteIni(0);

var aWnd        = [];
var IDRANGE     = 1000;
var IDFROM      = 1001;
var IDTO        = 1002;
var IDLINES     = 1003;
var IDBEGLINE   = 1004;
var IDENDLINE   = 1005;
var IDSORT1     = 1006;
var IDKEY1      = 1007;
var IDDESCLEN   = 1008;
var IDSORT2     = 1009;
var IDKEY2      = 1010;
var IDRTL       = 1011;
var IDENTLINE   = 1012;
var IDFROM2     = 1013;
var IDTO2       = 1014;
var IDCOLUMNS   = 1015;
var IDBEGCOL    = 1016;
var IDENDCOL    = 1017;
var IDDESC      = 1018;
var IDIGCASE    = 1019;
var IDSORT3     = 1020;
var IDSTRING    = 1021;
var IDLOCALE    = 1022;
var IDNUM       = 1023;
var IDSORT4     = 1024;
var IDREMODUKEY = 1025;
var IDEXTRDUKEY = 1026;
var IDEXTRUNKEY = 1027;
var IDNOSORT    = 1028;
var IDREVERSE   = 1029;
var IDREMODULIN = 1030;
var IDEXTRDULIN = 1031;
var IDEXTRUNLIN = 1032;
var IDCOPYTOCB  = 1033;
var IDUSEPLUG   = 1034;
var IDSORT      = 1035;
var IDUNDO      = 1036;
var IDREDO      = 1037;

var CLASS   = 0;
var WND     = 1;
var EXSTYLE = 2;
var STYLE   = 3;
var X       = 4;
var Y       = 5;
var W       = 6;
var H       = 7;
var TXT     = 8;

//0x50000000 - WS_VISIBLE|WS_CHILD
//0x50000007 - WS_VISIBLE|WS_CHILD|BS_GROUPBOX
//0x50000009 - WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON
//0x50010000 - WS_VISIBLE|WS_CHILD|WS_TABSTOP
//0x50010003 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
//0x50012080 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER
//Windows               CLASS, WND, EXSTYLE,      STYLE,   X,   Y,   W,   H, TXT
aWnd[IDRANGE    ] = ["BUTTON",   0,       0, 0x50000007,  10,  10, 185,  70, sTxtRange];
aWnd[IDFROM     ] = ["STATIC",   0,       0, 0x50000000,  70,  30,  55,  13, sTxtFrom];
aWnd[IDTO       ] = ["STATIC",   0,       0, 0x50000000, 130,  30,  55,  13, sTxtTo];
aWnd[IDLINES    ] = ["STATIC",   0,       0, 0x50000000,  20,  45,  50,  13, sTxtLines];
aWnd[IDBEGLINE  ] = ["STATIC",   0,   0x200, 0x50000000,  70,  45,  55,  20, ""];
aWnd[IDENDLINE  ] = ["STATIC",   0,   0x200, 0x50000000, 130,  45,  55,  20, ""];
aWnd[IDSORT1    ] = ["BUTTON",   0,       0, 0x50000007,  10,  90, 290,  52, sTxtKeys];
aWnd[IDKEY1     ] = ["BUTTON",   0,       0, 0x50010003,  20, 115, 150,  16, sTxtKey1];
aWnd[IDDESCLEN  ] = ["BUTTON",   0,       0, 0x50010003, 205, 115,  90,  16, sTxtDesc];
aWnd[IDSORT2    ] = ["BUTTON",   0,       0, 0x50000007,  10, 135, 290, 130, ""];
aWnd[IDKEY2     ] = ["BUTTON",   0,       0, 0x50010003,  20, 150, 150,  16, sTxtKey2];
aWnd[IDRTL      ] = ["BUTTON",   0,       0, 0x50010003,  40, 170, 140,  16, sTxtRTL];
aWnd[IDENTLINE  ] = ["BUTTON",   0,       0, 0x50010003,  40, 190, 140,  16, sTxtEntLine];
aWnd[IDFROM2    ] = ["STATIC",   0,       0, 0x50000000,  70, 215,  55,  13, sTxtFrom];
aWnd[IDTO2      ] = ["STATIC",   0,       0, 0x50000000, 130, 215,  55,  13, sTxtTo];
aWnd[IDCOLUMNS  ] = ["STATIC",   0,       0, 0x50000000,  20, 230,  50,  13, sTxtColumns];
aWnd[IDBEGCOL   ] = ["EDIT",     0,   0x200, 0x50012080,  70, 230,  55,  20, ""];
aWnd[IDENDCOL   ] = ["EDIT",     0,   0x200, 0x50012080, 130, 230,  55,  20, ""];
aWnd[IDDESC     ] = ["BUTTON",   0,       0, 0x50010003, 205, 150,  90,  16, sTxtDesc];
aWnd[IDIGCASE   ] = ["BUTTON",   0,       0, 0x50010003, 205, 170,  90,  16, sTxtIgCase];
aWnd[IDSORT3    ] = ["BUTTON",   0,       0, 0x50000007, 195, 185, 105,  80, ""];
aWnd[IDSTRING   ] = ["BUTTON",   0,       0, 0x50000009, 205, 200,  90,  16, sTxtString];
aWnd[IDLOCALE   ] = ["BUTTON",   0,       0, 0x50000009, 205, 220,  90,  16, sTxtLocale];
aWnd[IDNUM      ] = ["BUTTON",   0,       0, 0x50000009, 205, 240,  90,  16, sTxtNum];
aWnd[IDSORT4    ] = ["BUTTON",   0,       0, 0x50000007,  10, 275, 290,  85, sTxtSortAnd];
aWnd[IDREMODUKEY] = ["BUTTON",   0,       0, 0x50010003,  60, 295, 230,  16, sTxtRemoDuKey];
aWnd[IDEXTRDUKEY] = ["BUTTON",   0,       0, 0x50010003,  60, 315, 230,  16, sTxtExtrDuKey];
aWnd[IDEXTRUNKEY] = ["BUTTON",   0,       0, 0x50010003,  60, 335, 230,  16, sTxtExtrUnKey];
aWnd[IDNOSORT   ] = ["BUTTON",   0,       0, 0x50000007,  10, 370, 290, 105, sTxtNoSort];
aWnd[IDREVERSE  ] = ["BUTTON",   0,       0, 0x50010003,  60, 390, 230,  16, sTxtReverse];
aWnd[IDREMODULIN] = ["BUTTON",   0,       0, 0x50010003,  60, 410, 230,  16, sTxtRemoDuKey];
aWnd[IDEXTRDULIN] = ["BUTTON",   0,       0, 0x50010003,  60, 430, 230,  16, sTxtExtrDuKey];
aWnd[IDEXTRUNLIN] = ["BUTTON",   0,       0, 0x50010003,  60, 450, 230,  16, sTxtExtrUnKey];
aWnd[IDCOPYTOCB ] = ["BUTTON",   0,       0, 0x50010003,  20, 485, 270,  16, sTxtCopyToCB];
aWnd[IDUSEPLUG  ] = ["BUTTON",   0,       0, 0x50010003,  20, 505, 270,  16, sTxtUsePlug];
aWnd[IDSORT     ] = ["BUTTON",   0,       0, 0x50010000, 220,  10,  80,  23, sTxtSort];
aWnd[IDUNDO     ] = ["BUTTON",   0,       0, 0x50010000, 220,  35,  80,  23, sTxtUndo];
aWnd[IDREDO     ] = ["BUTTON",   0,       0, 0x50010000, 220,  60,  80,  23, sTxtRedo];

if (hEditWnd)
{
  nWordWrap = AkelPad.SendMessage(hEditWnd, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
  if (nWordWrap > 0) AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);

  if (AkelPad.WindowRegisterClass(sClassName))
  {
    if (lpBuffer = AkelPad.MemAlloc(256 * _TSIZE))
    {
      hWndDlg = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                  0,               //dwExStyle
                  sClassName,      //lpClassName
                  sTxtCaption,     //lpWindowName
                  0x90CA0000,      //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
                  0,               //x
                  0,               //y
                  315,             //nWidth
                  560,             //nHeight
                  hMainWnd,        //hWndParent
                  0,               //ID
                  hInstDLL,        //hInstance
                  DialogCallback); //Script function callback. To use it class must be registered by WindowRegisterClass.
      if (hWndDlg)
      {
        //Disable main window, to make dialog modal
        oSys.Call("User32::EnableWindow", hMainWnd, false);

        //Message loop
        AkelPad.WindowGetMessage();
      }
      AkelPad.MemFree(lpBuffer);
    }
    AkelPad.WindowUnregisterClass(sClassName);
  }

  if (nWordWrap > 0) AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
}

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  var i, nLowParam;

  if (uMsg == 1) //WM_CREATE
  {
    for (i = 1000; i < aWnd.length; ++i)
    {
      aWnd[i][WND] = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                       aWnd[i][EXSTYLE], //dwExStyle
                       aWnd[i][CLASS],   //lpClassName
                       0,                //lpWindowName
                       aWnd[i][STYLE],   //dwStyle
                       aWnd[i][X],       //x
                       aWnd[i][Y],       //y
                       aWnd[i][W],       //nWidth
                       aWnd[i][H],       //nHeight
                       hWnd,             //hWndParent
                       i,                //ID
                       hInstDLL,         //hInstance
                       0);               //lpParam
      SetWindowFontAndText(aWnd[i][WND], hGuiFont, aWnd[i][TXT]);
    }

    GetSelection();
    SetSelection();
    CheckButtons();
    CheckUndoRedo();

    //Set window position
    if ((nWndPosX == undefined) || (nWndPosY == undefined))
      MoveWindow(hMainWnd, hWnd, "RT");
    else
      MoveWindow(hMainWnd, hWnd, [nWndPosX, nWndPosY]);

    hFocus = aWnd[bUsePlug ? IDKEY2 : IDKEY1][WND];
  }

  else if ((uMsg == 6 /*WM_ACTIVATE*/) && (! wParam))
    hFocus = oSys.Call("User32::GetFocus");

  else if (uMsg == 7) //WM_SETFOCUS
    oSys.Call("User32::SetFocus", hFocus);

  else if (uMsg == 256) //WM_KEYDOWN
  {
    if (wParam == 27) //VK_ESCAPE
      oSys.Call("User32::PostMessage" + _TCHAR, hWndDlg, 16 /*WM_CLOSE*/, 0, 0);
    else if (wParam == 13) //VK_RETURN
    {
      if (! bIsReturn)
      {
        hFocus = oSys.Call("User32::GetFocus");
        if ((hFocus != aWnd[IDSORT][WND]) && (hFocus != aWnd[IDUNDO][WND]) && (hFocus != aWnd[IDREDO][WND]))
          oSys.Call("User32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDSORT, 0);
      }
    }
  }

  else if (uMsg == 257) //WM_KEYUP
    bIsReturn = 0;

  else if ((uMsg == 260) /*WM_SYSKEYDOWN*/ &&
           (oSys.Call("User32::GetAsyncKeyState", 0xA0 /*VK_LSHIFT*/)))
  {
    if (wParam == 0x27) //VK_RIGHT
      MoveWindow(hMainWnd, hWnd, "R");
    else if (wParam == 0x25) //VK_LEFT
      MoveWindow(hMainWnd, hWnd, "L");
    else if (wParam == 0x28) //VK_DOWN
      MoveWindow(hMainWnd, hWnd, "D");
    else if (wParam == 0x26) //VK_UP
      MoveWindow(hMainWnd, hWnd, "U");
    else if (wParam == 0x23) //VK_END
      MoveWindow(hMainWnd, hWnd, "E");
    else if (wParam == 0x24) //VK_HOME
      MoveWindow(hMainWnd, hWnd, "H");
    else if (wParam == 0x22) //VK_NEXT
      MoveWindow(hMainWnd, hWnd, "B");
    else if (wParam == 0x21) //VK_PRIOR
      MoveWindow(hMainWnd, hWnd, "T");
  }

  else if (uMsg == 273) //WM_COMMAND
  {
    nLowParam = LoWord(wParam);

    if ((nLowParam == IDBEGCOL) || (nLowParam == IDENDCOL))
    {
      CheckEditValue(nLowParam);
      if (bGetSel)
        SetSelection();
    }

    else if (((nLowParam >= IDKEY1) && (nLowParam <= IDENTLINE)) || ((nLowParam >= IDDESC) && (nLowParam <= IDUSEPLUG)))
      CheckButtons(nLowParam);

    else if (nLowParam == IDSORT)
    {
      if (SortLines())
      {
        CheckUndoRedo(nLowParam);
        GetSelection();
      }
    }

    else if (nLowParam == IDUNDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
      GetSelection();
    }

    else if (nLowParam == IDREDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
      GetSelection();
    }
  }

  else if (uMsg == 16) //WM_CLOSE
  {
    ReadWriteIni(1);

    //Enable main window
    oSys.Call("User32::EnableWindow", hMainWnd, true);
    //Destroy dialog
    oSys.Call("User32::DestroyWindow", hWnd);
  }

  else if (uMsg == 2) //WM_DESTROY
    oSys.Call("User32::PostQuitMessage", 0);

  else
    SetDefID(hWnd);

  return 0;
}

function SetWindowFontAndText(hWnd, hFont, sText)
{
  AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
  oSys.Call("User32::SetWindowText" + _TCHAR, hWnd, sText);
}

function MoveWindow(hWndParent, hWnd, vAction)
{
  var aRectParent;
  var aRect;
  var nX;
  var nY;

  if (! hWndParent)
    hWndParent=oSys.Call("User32::GetDesktopWindow");

  aRectParent = GetWindowPos(hWndParent);
  aRect       = GetWindowPos(hWnd);

  nX = aRect.left;
  nY = aRect.top;

  if (vAction == "R") //Move right
    nX = aRect.left + ((aRect.left < aRectParent.right - 50) ? 20 : 0);
  else if (vAction == "L") //Move left
    nX = aRect.left - ((aRect.right > aRectParent.left + 50) ? 20 : 0);
  else if (vAction == "D") //Move down
    nY = aRect.top + ((aRect.top < aRectParent.bottom - 50) ? 20 : 0);
  else if (vAction == "U") //Move up
    nY = aRect.top - ((aRect.bottom > aRectParent.top + 50) ? 20 : 0);
  else if (vAction == "E") //Move end (right)
    nX = aRect.left + (aRectParent.right - aRect.right);
  else if (vAction == "H") //Move home (left)
    nX = aRect.left + (aRectParent.left - aRect.left);
  else if (vAction == "B") //Move bottom
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  else if (vAction == "T") //Move top
    nY = aRect.top + (aRectParent.top - aRect.top);
  else if (vAction == "C") //Center window
  {
    nX = aRectParent.left + ((aRectParent.right  - aRectParent.left) / 2 - (aRect.right  - aRect.left) / 2);
    nY = aRectParent.top  + ((aRectParent.bottom - aRectParent.top)  / 2 - (aRect.bottom - aRect.top)  / 2);
  }
  else if (vAction == "LT") //Move left top
  {
    nX = aRectParent.left;
    nY = aRectParent.top;
  }
  else if (vAction == "RT") //Move right top
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRectParent.top;
  }
  else if (vAction == "LB") //Move left bottom
  {
    nX = aRectParent.left;
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else if (vAction == "RB") //Move right bottom
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else
  {
    nX = vAction[0];
    nY = vAction[1];
  }

  oSys.Call("User32::SetWindowPos", hWnd, 0, nX, nY, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
}

function GetWindowPos(hWnd)
{
  var lpRect = AkelPad.MemAlloc(16) //sizeof(RECT);
  var aRect  = [];

  oSys.Call("User32::GetWindowRect", hWnd, lpRect);

  aRect.left   = AkelPad.MemRead(_PtrAdd(lpRect,  0), DT_DWORD);
  aRect.top    = AkelPad.MemRead(_PtrAdd(lpRect,  4), DT_DWORD);
  aRect.right  = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD);
  aRect.bottom = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD);
  AkelPad.MemFree(lpRect);

  return aRect;
}

function LoWord(nParam)
{
  return (nParam & 0xFFFF);
}

function SetDefID(hWnd)
{
  var nID    = 1000;
  var hFocus = oSys.Call("User32::GetFocus");

  while ((nID < aWnd.length) && (hFocus != aWnd[nID][WND]))
    ++nID;

  if ((nID != IDUNDO) && (nID != IDREDO))
    nID = IDSORT;

  oSys.Call("User32::DefDlgProc" + _TCHAR, hWnd, 1025 /*DM_SETDEFID*/, nID, 0);
}

function ReadWriteIni(bWrite)
{
  var oFSO     = new ActiveXObject("Scripting.FileSystemObject");
  var sIniName = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini";
  var aRect;
  var oFile;
  var sIniTxt;

  if (bWrite)
  {
    aRect = GetWindowPos(hWndDlg);
    sIniTxt =
      'nWndPosX='  + aRect.left + ';\r\n' +
      'nWndPosY='  + aRect.top  + ';\r\n' +
      'bKey1='     + bKey1 + ';\r\n' +
      'bDescLen='  + bDescLen + ';\r\n' +
      'bKey2='     + bKey2 + ';\r\n' +
      'bRTL='      + bRTL + ';\r\n' +
      'bEntLine='  + bEntLine + ';\r\n' +
      'bDesc='     + bDesc + ';\r\n' +
      'bIgCase='   + bIgCase + ';\r\n' +
      'nMethod='   + nMethod + ';\r\n' +
      'nSortAnd='  + nSortAnd + ';\r\n' +
      'nNoSort='   + nNoSort + ';\r\n' +
      'bCopyToCB=' + bCopyToCB + ';\r\n' +
      'bUsePlug='  + bUsePlug + ';'

    oFile = oFSO.OpenTextFile(sIniName, 2, true, 0);
    oFile.Write(sIniTxt);
    oFile.Close();
  }

  else if (oFSO.FileExists(sIniName))
  {
    try
    {
      eval(AkelPad.ReadFile(sIniName));
    }
    catch (oError)
    {}
  }
}

function CheckButtons(nButton)
{
  if ((nButton == IDKEY1) && ((! bKey1) || bKey2))
    bKey1 = ! bKey1;
  else if (nButton == IDDESCLEN)
    bDescLen = ! bDescLen;
  else if ((nButton == IDKEY2) && ((! bKey2) || bKey1))
    bKey2 = ! bKey2;
  else if (nButton == IDRTL)
    bRTL = ! bRTL;
  else if (nButton == IDENTLINE)
    bEntLine = ! bEntLine;
  else if (nButton == IDDESC)
    bDesc = ! bDesc;
  else if (nButton == IDIGCASE)
    bIgCase = ! bIgCase;
  else if ((nButton == IDSTRING) || (nButton == IDLOCALE) || (nButton == IDNUM))
    nMethod = nButton - IDSTRING + 1;
  else if ((nButton == IDREMODUKEY) || (nButton == IDEXTRDUKEY) || (nButton == IDEXTRUNKEY))
  {
    if (nSortAnd == nButton - IDREMODUKEY + 1)
      nSortAnd = 0;
    else
      nSortAnd = nButton - IDREMODUKEY + 1;
  }
  else if ((nButton == IDREVERSE) || (nButton == IDREMODULIN) || (nButton == IDEXTRDULIN) || (nButton == IDEXTRUNLIN))
  {
    if (nNoSort == nButton - IDREVERSE + 1)
      nNoSort = 0;
    else
      nNoSort = nButton - IDREVERSE + 1;
  }
  else if (nButton == IDCOPYTOCB)
    bCopyToCB = ! bCopyToCB;
  else if (nButton == IDUSEPLUG)
    bUsePlug = ! bUsePlug;

  if ((bUsePlug) && ((nNoSort > 1) || (nMethod == 2)))
    nMethod = 1;

  AkelPad.SendMessage(aWnd[IDKEY1][WND],      BM_SETCHECK, bKey1,           0);
  AkelPad.SendMessage(aWnd[IDDESCLEN][WND],   BM_SETCHECK, bDescLen,        0);
  AkelPad.SendMessage(aWnd[IDKEY2][WND],      BM_SETCHECK, bKey2,           0);
  AkelPad.SendMessage(aWnd[IDRTL][WND],       BM_SETCHECK, bRTL,            0);
  AkelPad.SendMessage(aWnd[IDENTLINE][WND],   BM_SETCHECK, bEntLine,        0);
  AkelPad.SendMessage(aWnd[IDDESC][WND],      BM_SETCHECK, bDesc,           0);
  AkelPad.SendMessage(aWnd[IDIGCASE][WND],    BM_SETCHECK, bIgCase,         0);
  AkelPad.SendMessage(aWnd[IDSTRING][WND],    BM_SETCHECK, (nMethod == 1),  0);
  AkelPad.SendMessage(aWnd[IDLOCALE][WND],    BM_SETCHECK, (nMethod == 2),  0);
  AkelPad.SendMessage(aWnd[IDNUM][WND],       BM_SETCHECK, (nMethod == 3),  0);
  AkelPad.SendMessage(aWnd[IDREMODUKEY][WND], BM_SETCHECK, (nSortAnd == 1), 0);
  AkelPad.SendMessage(aWnd[IDEXTRDUKEY][WND], BM_SETCHECK, (nSortAnd == 2), 0);
  AkelPad.SendMessage(aWnd[IDEXTRUNKEY][WND], BM_SETCHECK, (nSortAnd == 3), 0);
  AkelPad.SendMessage(aWnd[IDREVERSE][WND],   BM_SETCHECK, (nNoSort == 1),  0);
  AkelPad.SendMessage(aWnd[IDREMODULIN][WND], BM_SETCHECK, (nNoSort == 2),  0);
  AkelPad.SendMessage(aWnd[IDEXTRDULIN][WND], BM_SETCHECK, (nNoSort == 3),  0);
  AkelPad.SendMessage(aWnd[IDEXTRUNLIN][WND], BM_SETCHECK, (nNoSort == 4),  0);
  AkelPad.SendMessage(aWnd[IDCOPYTOCB][WND],  BM_SETCHECK, bCopyToCB,       0);
  AkelPad.SendMessage(aWnd[IDUSEPLUG][WND],   BM_SETCHECK, bUsePlug,        0);

  oSys.Call("User32::EnableWindow", aWnd[IDKEY1][WND],      (nNoSort != 1) && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDDESCLEN][WND],   (nNoSort == 0) && bKey1 && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDKEY2][WND],      (nNoSort != 1));
  oSys.Call("User32::EnableWindow", aWnd[IDRTL][WND],       (nNoSort != 1) && bKey2 && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDENTLINE][WND],   (nNoSort != 1) && bKey2);
  oSys.Call("User32::EnableWindow", aWnd[IDFROM2][WND],     (nNoSort != 1) && bKey2 && (! bEntLine));
  oSys.Call("User32::EnableWindow", aWnd[IDTO2][WND],       (nNoSort != 1) && bKey2 && (! bEntLine));
  oSys.Call("User32::EnableWindow", aWnd[IDCOLUMNS][WND],   (nNoSort != 1) && bKey2 && (! bEntLine));
  oSys.Call("User32::EnableWindow", aWnd[IDBEGCOL][WND],    (nNoSort != 1) && bKey2 && (! bEntLine));
  oSys.Call("User32::EnableWindow", aWnd[IDENDCOL][WND],    (nNoSort != 1) && bKey2 && (! bEntLine));
  oSys.Call("User32::EnableWindow", aWnd[IDDESC][WND],      (nNoSort == 0) && bKey2);
  oSys.Call("User32::EnableWindow", aWnd[IDIGCASE][WND],    (nNoSort != 1) && bKey2 && ((nMethod != 3) || bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDSTRING][WND],    (nNoSort != 1) && bKey2);
  oSys.Call("User32::EnableWindow", aWnd[IDLOCALE][WND],    (nNoSort != 1) && bKey2 && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDNUM][WND],       (nNoSort != 1) && bKey2 && (! (bUsePlug && (nNoSort > 1))));
  oSys.Call("User32::EnableWindow", aWnd[IDREMODUKEY][WND], (nNoSort == 0) && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDEXTRDUKEY][WND], (nNoSort == 0) && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDEXTRUNKEY][WND], (nNoSort == 0) && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDCOPYTOCB][WND],  (! bUsePlug));
}

function CheckUndoRedo(nButton)
{
  var nBegSel  = AkelPad.GetSelStart();
  var sTxtUndo = aWnd[IDUNDO][TXT];
  var sTxtRedo = aWnd[IDREDO][TXT];

  if (nButton == IDSORT)
  {
    if (nUndoLimit < AkelPad.SendMessage(hEditWnd, 3084 /*AEM_GETUNDOLIMIT*/, 0, 0))
      ++nUndoLimit;
    nRedoLimit = 0;
  }
  else if ((nButton == IDUNDO) && (nUndoLimit))
  {
    --nUndoLimit;
    ++nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3077 /*AEM_UNDO*/, 0, 0);
  }
  else if ((nButton == IDREDO) && (nRedoLimit))
  {
    ++nUndoLimit;
    --nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3078 /*AEM_REDO*/, 0, 0);
    AkelPad.SetSel(nBegSel, AkelPad.GetSelEnd());
  }

  if (nUndoLimit)
    sTxtUndo += " (" + nUndoLimit + ")";
  if (nRedoLimit)
    sTxtRedo += " (" + nRedoLimit + ")";

  if (((oSys.Call("User32::GetFocus") == aWnd[IDUNDO][WND]) && (nUndoLimit == 0)) ||
      ((oSys.Call("User32::GetFocus") == aWnd[IDREDO][WND]) && (nRedoLimit == 0)))
    oSys.Call("User32::SetFocus", aWnd[IDKEY1][WND]);

  SetWindowFontAndText(aWnd[IDUNDO][WND], hGuiFont, sTxtUndo);
  SetWindowFontAndText(aWnd[IDREDO][WND], hGuiFont, sTxtRedo);

  oSys.Call("User32::EnableWindow", aWnd[IDUNDO][WND], nUndoLimit);
  oSys.Call("User32::EnableWindow", aWnd[IDREDO][WND], nRedoLimit);
}

function CheckEditValue(nID)
{
  var sEditValue;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[nID][WND], lpBuffer, 256);
  sEditValue = AkelPad.MemRead(lpBuffer, _TSTR);

  if (sEditValue == 0)
  {
    SetWindowFontAndText(aWnd[nID][WND], hGuiFont, "1");
    AkelPad.SendMessage(aWnd[nID][WND], 177 /*EM_SETSEL*/, 0, -1);
  }
  else if (sEditValue > nLastCol)
  {
    SetWindowFontAndText(aWnd[nID][WND], hGuiFont, String(nLastCol));
    AkelPad.SendMessage(aWnd[nID][WND], 177 /*EM_SETSEL*/, 0, -1);
  }
}

function GetSelection()
{
  var lpBegSel = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var lpEndSel = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var nLine1, nLine2, nCol1, nCol2;

  AkelPad.SendMessage(hEditWnd, 3123 /*AEM_EXGETSEL*/, lpBegSel, lpEndSel);

  nLine1 = AkelPad.MemRead(lpBegSel, DT_DWORD) + 1;
  nLine2 = AkelPad.MemRead(lpEndSel, DT_DWORD) + 1;

  if ((nLine1 == nLine2) && (! bGetSel))
  {
    nLine1 = 1;
    nLine2 = AkelPad.SendMessage(hEditWnd, 3129 /*AEM_GETLINENUMBER*/, 0 /*AEGL_LINECOUNT*/, 0);
  }

  nLastCol = LineMaxLength(nLine1, nLine2) + 1;
  SetWindowFontAndText(aWnd[IDBEGLINE][WND], hGuiFont, String(nLine1));
  SetWindowFontAndText(aWnd[IDENDLINE][WND], hGuiFont, String(nLine2));

  if (! bGetSel)
  {
    if (AkelPad.MemRead(_PtrAdd(lpBegSel, _X64 ? 16 : 8), DT_DWORD) < AkelPad.MemRead(_PtrAdd(lpEndSel, _X64 ? 16 : 8), DT_DWORD))
    {
      nCol1 = AkelPad.MemRead(_PtrAdd(lpBegSel, _X64 ? 16 : 8), DT_DWORD) + 1;
      nCol2 = AkelPad.MemRead(_PtrAdd(lpEndSel, _X64 ? 16 : 8), DT_DWORD) + 1;
    }
    else
    {
      nCol1 = AkelPad.MemRead(_PtrAdd(lpEndSel, _X64 ? 16 : 8), DT_DWORD) + 1;
      nCol2 = AkelPad.MemRead(_PtrAdd(lpBegSel, _X64 ? 16 : 8), DT_DWORD) + 1;
    }
  
    if (nCol1 > nLastCol)
      nCol1 = nLastCol;
    if (nCol2 > nLastCol)
      nCol2 = nLastCol;

    SetWindowFontAndText(aWnd[IDBEGCOL][WND],  hGuiFont, String(nCol1));
    SetWindowFontAndText(aWnd[IDENDCOL][WND],  hGuiFont, String(nCol2));

    //removed (2018-02-01)
    //bEntLine = ! AkelPad.SendMessage(hEditWnd, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
  }

  AkelPad.MemFree(lpBegSel);
  AkelPad.MemFree(lpEndSel);
  bGetSel = 1;
}

function LineMaxLength(nLine1, nLine2)
{
  var nMaxLenL = 0;
  var nBegLine;
  var nLenLine;
  var i;

  for (i = nLine1 - 1; i < nLine2; ++i)
  {
    nBegLine = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, i, 0);
    nLenLine = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine, 0);
    if (nLenLine > nMaxLenL)
      nMaxLenL = nLenLine;
  }

  return nMaxLenL;
}

function SetSelection()
{
  var hFocus    = oSys.Call("User32::GetFocus");
  var lpSelect  = AkelPad.MemAlloc(_X64 ? 56 : 32 /*sizeof(AESELECTION)*/);
  var lpBegSel  = lpSelect;
  var lpEndSel  = _PtrAdd(lpSelect, _X64 ? 24 : 12);
  var lpSelFlag = _PtrAdd(lpSelect, _X64 ? 48 : 24);
  var nColSel   = 1;
  var nLine1, nLine2, nCol1, nCol2;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGLINE][WND], lpBuffer, 256);
  nLine1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDLINE][WND], lpBuffer, 256);
  nLine2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;

  if ((hFocus == aWnd[IDBEGCOL][WND]) || (hFocus == aWnd[IDENDCOL][WND]))
  {
    oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGCOL][WND], lpBuffer, 256);
    nCol1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
    oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDCOL][WND], lpBuffer, 256);
    nCol2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  }
  else
  {
    nCol1   = 0;
    nCol2   = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine2, 0), 0);
    nColSel = 0;
  }

  AkelPad.MemCopy(lpBegSel, nLine1,  DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpBegSel, _X64 ? 16 : 8), nCol1, DT_DWORD);
  AkelPad.MemCopy(lpEndSel, nLine2,  DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpEndSel, _X64 ? 16 : 8), nCol2, DT_DWORD);
  AkelPad.MemCopy(lpSelFlag, nColSel, DT_DWORD);

  AkelPad.SendMessage(hEditWnd, 3132 /*AEM_INDEXUPDATE*/, 0, lpBegSel);
  AkelPad.SendMessage(hEditWnd, 3132 /*AEM_INDEXUPDATE*/, 0, lpEndSel);

  AkelPad.SendMessage(hEditWnd, 3126 /*AEM_SETSEL*/, 0, lpSelect);

  AkelPad.MemFree(lpSelect);
}

function SortLines()
{
  var aTxt  = [];
  var sText = "";
  var nLine1;
  var nLine2;
  var nCol1;
  var nCol2;
  var i;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGLINE][WND], lpBuffer, 256);
  nLine1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDLINE][WND], lpBuffer, 256);
  nLine2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGCOL][WND], lpBuffer, 256);
  nCol1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDCOL][WND], lpBuffer, 256);
  nCol2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;

  if (nLine1 == nLine2)
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoRangeL, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    return 0;
  }

  if ((nCol1 == nCol2) && bKey2 && (! bEntLine) && (nNoSort != 1))
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoKey2, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    oSys.Call("User32::SetFocus", aWnd[IDENDCOL][WND]);
    AkelPad.SendMessage(aWnd[IDENDCOL][WND], 177 /*EM_SETSEL*/, 0, -1);
    return 0;
  }

  hFocus = oSys.Call("User32::GetFocus");

  if (bUsePlug)
  {
    if (! bEntLine)
    {
      oSys.Call("User32::SetFocus", aWnd[IDENDCOL][WND]);
      SetSelection();
    }
    SortByPlugin();
    oSys.Call("User32::SetFocus", hFocus);
    return 1;
  }
  else
  {
    oSys.Call("User32::SetFocus", aWnd[IDSORT][WND]);
    SetSelection();

    if (nNoSort == 1)
    {
      aTxt  = AkelPad.GetSelText(1 /*\r*/).split("\r");
      sText = aTxt.reverse().join("\r");
    }
    else
    {
      aTxt[0] = AkelPad.GetSelText(1 /*\r*/).split("\r");

      if (bKey2)
      {
        if (bEntLine)
          aTxt[1] = AkelPad.GetSelText(1 /*\r*/).split("\r");
        else
          aTxt[1] = GetTextRangeColumn([nLine1, nCol1], [nLine2, nCol2]);

        if (bRTL)
        {
          for (i = 0; i < aTxt[1].length; ++i)
            aTxt[1][i] = aTxt[1][i].split("").reverse().join("");
        }
      }

      aTxt = ArrayTransp(aTxt);

      ArraySort(aTxt);

      for (i = 0; i < aTxt.length; ++i)
        sText += aTxt[i][0] + "\r";

      sText = sText.slice(0, -1);
    }

    if (bCopyToCB)
    {
      AkelPad.SetClipboardText(sText);
      oSys.Call("User32::SetFocus", hFocus);
      return 0;
    }
    else
    {
      AkelPad.ReplaceSel(sText, -1);
      oSys.Call("User32::SetFocus", hFocus);
      return 1;
    }
  }
}

function GetTextRangeColumn(aBeg, aEnd, bReturnText, nNewLine, bFillSpaces)
{
  var nBegLine1;
  var nBegLine2;
  var nLenLine2;
  var nLine1;
  var nLine2;
  var nCol1;
  var nCol2;
  var aLines;
  var nWidth;
  var i;

  if (aBeg[0] < aEnd[0])
  {
    nLine1 = aBeg[0];
    nLine2 = aEnd[0];
  }
  else
  {
    nLine1 = aEnd[0];
    nLine2 = aBeg[0];
  }

  if (aBeg[1] < aEnd[1])
  {
    nCol1 = aBeg[1];
    nCol2 = aEnd[1];
  }
  else
  {
    nCol1 = aEnd[1];
    nCol2 = aBeg[1];
  }

	nBegLine1 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine1, 0);
	nBegLine2 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine2, 0);
	nLenLine2 = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine2, 0);
  aLines    = AkelPad.GetTextRange(nBegLine1, nBegLine2 + nLenLine2, 1 /*"\r"*/).split("\r");
  nWidth    = nCol2 - nCol1;

  for (i = 0; i < aLines.length; ++i)
  {
    aLines[i] = aLines[i].substring(nCol1, nCol2);
    if (bFillSpaces)
      while (aLines[i].length < nWidth)
        aLines[i] += " ";
  }

  if (bReturnText)
  {
    if ((! nNewLine) || (nNewLine == 1))
      pNewLine = "\r";
    else if (nNewLine == 2)
      pNewLine = "\n";
    else
      pNewLine = "\r\n";

    return aLines.join(pNewLine);
  }
  else
    return aLines;
}

function ArrayTransp(aA)
{
  var nLen1 = aA.length;
  var nLen2 = aA[0].length;
  var aB    = new Array(nLen2);
  var i, n;

  for (n = 0; n < nLen2; ++n)
  {
    aB[n] = [];

    for (i = 0; i < nLen1; ++i)
      aB[n].push(aA[i][n]);
  }

  return aB;
}

function ArraySort(aTxt)
{
  if (nNoSort == 0)
  {
    aTxt.sort(CompareValue);
    RemoveFromArray(aTxt);
  }
  else
    NoSort(aTxt);
}

function CompareValue(aA, aB)
{
  var nResult = 0;

  if (bKey1)
  {
    if (aA[0].length > aB[0].length)
      nResult = bDescLen ? -1 : 1;
    else if (aA[0].length < aB[0].length)
      nResult = bDescLen ? 1 : -1;
  }

  if (bKey2 && (nResult == 0))
  {
    if (nMethod == 1)
    {
      if (bIgCase)
      {
        aA[1] = aA[1].toUpperCase();
        aB[1] = aB[1].toUpperCase();
      }
      if (aA[1] > aB[1])
        nResult = bDesc ? -1 : 1;
      else if (aA[1] < aB[1])
        nResult = bDesc ? 1 : -1;
    }
    else if (nMethod == 2)
    {
      nResult = oSys.Call("Kernel32::lstrcmp" + (bIgCase ? "i" : "") + _TCHAR, aA[1], aB[1]);
      if (bDesc)
        nResult = -nResult;
    }
    else
    {
      var oRegExp = /(-?\d+\.?\d*)|(-?\.\d+)/;
  
      aA[1] = oRegExp.exec(aA[1]);
      aB[1] = oRegExp.exec(aB[1]);
      aA[1] = aA[1] ? parseFloat(aA[1][0]) : 0;
      aB[1] = aB[1] ? parseFloat(aB[1][0]) : 0;
      nResult = bDesc ? (aB[1] - aA[1]) : (aA[1] - aB[1]);
    }
  }

  return nResult;
}

function RemoveFromArray(aTxt)
{
  var i;

  if (nSortAnd == 1)
  {
    for (i = aTxt.length - 1; i > 0; --i)
    {
      if (CompareValue(aTxt[i], aTxt[i - 1]) == 0)
        aTxt.splice(i, 1);
    }
  }
  else if (nSortAnd == 2)
  {
    for (i = aTxt.length - 2; i > 0; --i)
    {
      if ((CompareValue(aTxt[i], aTxt[i + 1]) != 0) && (CompareValue(aTxt[i], aTxt[i - 1]) != 0))
        aTxt.splice(i, 1);
    }
    if ((aTxt.length > 1) && (CompareValue(aTxt[aTxt.length - 1], aTxt[aTxt.length - 2]) != 0))
      aTxt.splice(aTxt.length - 1, 1);
    if ((aTxt.length > 1) && (CompareValue(aTxt[0], aTxt[1]) != 0))
      aTxt.splice(0, 1);
    if (aTxt.length == 1)
      aTxt.splice(0, 1);
  }
  else if (nSortAnd == 3)
  {
    i = aTxt.length - 1;
    while (i > 0)
    {
      if (CompareValue(aTxt[i], aTxt[i - 1]) == 0)
      {
        aTxt.splice(i - 1, 2);
        i -= 2;
      }
      else
        --i;
    }
  }
}

function NoSort(aTxt)
{
  var i, n, bIsDup;

  if (nNoSort == 2)
  {
    for (n = 0; n < aTxt.length; ++n)
    {
      i = n + 1;
      while (i < aTxt.length)
      {
        if (CompareValue(aTxt[i], aTxt[n]) == 0)
          aTxt.splice(i, 1);
        else
          ++i;
      }
    }
  }

  else if (nNoSort == 3)
  {
    n = 0;
    while (n < aTxt.length)
    {
      bIsDup = false;
      for (i = 0; i < aTxt.length; ++i)
      {
        if ((CompareValue(aTxt[i], aTxt[n]) == 0) && (i != n))
        {
          bIsDup = true;
          break;
        }
      }
      if (bIsDup)
        ++n;
      else
        aTxt.splice(n, 1);
    }
  }

  else if (nNoSort == 4)
  {
    n = 0;
    while (n < aTxt.length)
    {
      bIsDup = false;
      i = n + 1;
      while (i < aTxt.length)
      {
        if (CompareValue(aTxt[i], aTxt[n]) == 0)
        {
          bIsDup = true;
          aTxt.splice(i, 1);
        }
        else
          ++i;
      }
      if (bIsDup)
        aTxt.splice(n, 1);
      else
        ++n;
    }
  }
}

function SortByPlugin()
{
  var sAscDesc = bDesc ? "Desc" : "Asc";

  if (nNoSort == 1)
    AkelPad.Call("Format::LineReverse");
  else if (nNoSort == 2)
    AkelPad.Call("Format::LineRemoveDuplicates", ! bIgCase);
  else if (nNoSort == 3)
    AkelPad.Call("Format::LineGetDuplicates", ! bIgCase);
  else if (nNoSort == 4)
    AkelPad.Call("Format::LineGetUnique", ! bIgCase);
  else if (nMethod == 1)
    AkelPad.Call("Format::LineSortStr" + sAscDesc, ! bIgCase);
  else if (nMethod == 3)
    AkelPad.Call("Format::LineSortInt" + sAscDesc, ! bIgCase);
}

Last edited by KDJ on Mon Jul 01, 2019 5:43 pm, edited 17 times in total.

Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

Code: Select all

' SwitchSplittedWindow.vbs
'========================   Описание   =====================================
' Переключение между позициями окна в заданной очерёдностью
'========================  Параметры =====================================
'В параметрах вызова скрипта должен быть прописан один параметр:
' 1 - Переключение горизонтальное --> вертикальное --> четыре части
' 2 - Переключение вертикальное --> горизонтальное --> четыре части
' 3 - Переключение горизонтальное --> четыре части -> вертикальное
' 4 - Переключение вертикальное --> четыре части --> горизонтальное
' 5 - Переключение четыре части --> вертикальное --> горизонтальное
' 6 - Переключение четыре части -- > горизонтальное --> вертикальное
'
' Call("Scripts::Main", 1, "SwitchSplittedWindow.vbs", `"2"`)
'
' Автор:           Аверин Андрей & VladSh
' Версия:          1.4 (2011.01.06 - 18.11.2011)
' Mail:            Averin-And@yandex.ru
' Site:            http://tc-image.3dn.ru/forum/9-412-1196-16-1333816090
' Site:            http://akelpad.sourceforge.net/forum/viewtopic.php?p=11012#p11012
'========================================================================
Set WSH = CreateObject("WScript.Shell")

If WScript.Arguments.Count < 1 Then
   Param = 1 'если порядок не задан в аргументах, то по умолчанию работает 1-й вариант: гор -> верт -> 4 части
Else
   Param = CInt(WScript.Arguments(0))
End If

Select Case Param
   Case 1 Call Switch(4214, 4213, 4212)
   Case 2 Call Switch(4213, 4214, 4212)
   Case 3 Call Switch(4214, 4212, 4213)
   Case 4 Call Switch(4213, 4212, 4214)
   Case 5 Call Switch(4212, 4213, 4214)
   Case 6 Call Switch(4212, 4214, 4213)
End Select

Sub Switch(n, m, k)
   Tree = "HKCU\Software\Akelsoft\AkelPad\Plugs\Scripts\SwitchSplittedWindow\"
   Name = GetHandleCurrent()
   If Name = 0 Then
      Call SplitWindow(n) : Call RegWrite(Tree, n)
   Else
      On Error Resume Next
      l = CInt(WSH.RegRead(Tree & Name))
      Select Case l
        Case 0 l = n
        Case n l = m
        Case m l = k
        Case k Call SplitWindow(k) : Call WSH.RegDelete(Tree & Name) : Call WsEnd
      End Select
      Call SplitWindow(l) : Call RegWrite(Tree, l) : Call WsEnd
   End If
End Sub

Function GetHandleCurrent() : GetHandleCurrent = AkelPad.SendMessage(AkelPad.GetEditWnd(), 3447, 0, 0) : End Function
Sub SplitWindow(n) : Call AkelPad.SendMessage(AkelPad.GetMainWnd(), 273, n, 0) : End Sub
Sub RegWrite(Tree, n) : Call WSH.RegWrite(Tree & GetHandleCurrent(), Cstr(n)) : End Sub
Sub WsEnd : Set WSH = Nothing : WScript.Quit : End Sub


А это иконка для скрипта:

Code: Select all

MIME-Version: 1.0
Content-Type: application/octet-stream; name="SwitchWindow.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="SwitchWindow.zip"

UEsDBBQAAgAIAI2ZJj5r+EqoaQIAADYVAAAWAAAAQWtlbFBhZFRvb2xCYXJfNjMyLmljb+1YQU8T
QRR+VbCIhlQFtbWtDcEGEz0Y/wBXEyWevFStJzUxRgViJBpZCm1tJZj4D4BENCZeQI3BHrxw8KBW
arQV2Y3B7smLF4+fb3dbusXdSrfFEt3XfJk37823XyY7+zozRA7aRIEAcRughy6iIBG5XFr/YhPR
G/a7OcZDqIe0uGKCi2yzbUPZ5AlCI6DXt2qTvda4RvpE1UGvT1X8zPSrsdX6a+bZ+rb+f6xf6fu3
qm8J/9D8FRNIWDMa+f5tfVu/HvpW9x9m+otiGp8zKWQzL5GriFTJ/5BS9Y3GKc/JLsyVIacgM4cl
8e1v+tMnCVPFvZmuRpX1e3X9P+3vjhMmjmko+lPcPmI8Mah/L8KEp6ESZk8XWgVnClBiBcyGSijj
nCXM8NgZ9udvdOFVnwfPOPb61kE8P0cYDIcROx+CONy+oj9/yYFcxI/8+CHIST/ku53Ijx2AnPBB
HgsyujgW4FhQzcnJ/cgneDzn8wkv8nEPw43lWAfk+B4sRxkjHfj5+JT6vuVkQP3X+3bviLpu70Qm
8ON+54r+xwHCp+F9kMYPQ4r7IUXZj3ogRnZDGnVD5GeJwk7296pxacQNKeZjeLnv02KjPF7YxZx2
iEM7sHS7DYuDzfhyc1vB34KvQhvkSAu+R1uQue6EffLZGGZc32jzekKvpdxTuAp3FcV7ip6m+s8z
fbUZtcLMHlw+WrHu6vlG57gi3+y8Zqa/mm+2320U32j+ZvxK+Bv6ZvvIWua/3vxq11+teNe/He/7
tiJ9jWv4QCsW+lvZd3LOqeWvODjvRHbIq64cZX7TF7pRnzplkejQuL8AUEsBAhQAFAACAAgAjZkm
Pmv4SqhpAgAANhUAABYAAAAAAAAAAAAgAAAAAAAAAEFrZWxQYWRUb29sQmFyXzYzMi5pY29QSwUG
AAAAAAEAAQBEAAAAnQIAAAAA
Last edited by Andrey_A_A on Thu Sep 13, 2012 2:49 am, edited 5 times in total.

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11092#p11092
// Description(1033): Opens the selected branch in the registry editor
// Description(1049): Открывает выделенную ветвь в редакторе реестра
// если выделения искомой ветви не произошло, значит её не существует
// Version: 1.10 (2015.08.31)
// 	from 1.4 (2011.01.21)
// Author: VladSh
// Initial version: 1.3 by mozers™ (SciTE)
//
// Понимает записи вида:
//		HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
//		[HKLM\SYSTEM\CurrentControlSet\Control]	/символы [] обрезаются/
//		HKLM\\SYSTEM\\CurrentControlSet\\Control
// 
//	Предлагаемая комбинация клавиш:	Ctrl+Alt+J

var key = AkelPad.GetSelText();
if (!key) {		//Если текст не выделен, то будем пытаться получить "ссылку" из текущей строки
	var hWndEdit = AkelPad.GetEditWnd();
	var nPosCurrent = AkelPad.GetSelStart();		//позиция курсора в файле
	
	var oLine = getLine(nPosCurrent);
	var nIndexCurrent = nPosCurrent - oLine.start + 1;		//позиция курсора в строке
	
	key = getKey(oLine.text, nIndexCurrent)		//предварительный поиск ключа, отталкиваясь от позиции курсора
	if (!key)
		key = getKey(oLine.text, -1);		//предварительный поиск ключа - во всей строке
}
else {
	key = getKey(key, -1);		//предварительный поиск ключа - по выделенному тексту
	if (!key) WScript.Quit();
}
//Проверяем, есть ли что-то похожее на ветку реестра
var posStart = key.indexOf("HK");
if (posStart == -1) WScript.Quit();
key = key.substr(posStart);

var pSlash = "\\";
var procRegEdit = "regedit.exe";
var WshShell = new ActiveXObject("WScript.Shell");

var LastKeyPath = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\";
var LastKeyName = LastKeyPath + "Lastkey";		//параметр отдельно от пути, т.к. с помощью Run выделение осуществляется только для каталога
key = key.replace(/^HKLM\\/, "HKEY_LOCAL_MACHINE\\");
key = key.replace(/^HKCR\\/, "HKEY_CLASSES_ROOT\\");
key = key.replace(/^HKCU\\/, "HKEY_CURRENT_USER\\");
key = key.replace(/\\\\/g, pSlash);
key = key.replace(/\[/g, "");		//обрезаем [] (для строки из *.reg-файла)
key = key.replace(/\]/g, "");
key = WshShell.RegRead(LastKeyName).match(/^[^\\]+/) + pSlash + key;

if (key.lastIndexOf(pSlash) == key.length - pSlash.length)
	key = key.substr(0, key.length - pSlash.length);		//обрезаем финальный слэш, если он есть, т.к. с ним не происходит выделения ветки

TaskKill(procRegEdit);		//для "обновления", т.к. иначе перехода на нужную ветку не производится

WshShell.RegWrite(LastKeyName, key, "REG_SZ");
WshShell.Run(WshShell.ExpandEnvironmentStrings("%WinDir%") + "\\" + procRegEdit, 1, false);


function getLine(nPos) {
	var line = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nPos);
	var index = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/, line, 0);
	var len = AkelPad.SendMessage(hWndEdit, 193 /*EM_LINELENGTH*/, index, 0);
	var text = AkelPad.GetTextRange(index, index + len);
	
	return {
		text: text,
		start: index,
		len: len
	};
}

///Поиск ключа по границам, иначе берём всю переданную строку, т.к. возможно текст выделен правильно, без ограничителей
function getKey(pText, nIndex) {
	var key = getBlock(pText, nIndex, '[', ']');		//ищём внутри []
	if (!key) {
		key = getBlock(pText, nIndex, '"', '"');		//иначе ищём внутри ""
		if (!key) {
			key = getBlock(pText, nIndex, "'", "'");		//иначе ищём внутри ''
			if (!key) {
				key = pText;		//берём всю переданную строку
			}
		}
	}
	return key;
}

function getBlock(pText, nPos, pTextStart, pTextEnd) {		//если в nPos передано -1, то искать во всей строке
	var pBlock = "";
	var nLbound;
	var nUbound;
	if (nPos != -1) {
		nLbound = nPos;
		nUbound = nPos;
	}
	else {
		nLbound = pTextStart.length + 1;
		nUbound = pText.length - pTextEnd.length - 1;
	}
	
	var posTextStart = pText.lastIndexOf(pTextStart, nUbound);					//Ищем вверх
	if (posTextStart != -1) {
		var posTextEnd = pText.indexOf(pTextEnd, nLbound);							//Ищем вниз
		if (posTextEnd != -1) {
			posTextStart += 1;
			if (posTextStart < posTextEnd)
				pBlock = pText.substring(posTextStart, posTextEnd);
			else
				pBlock = pText.substring(posTextEnd + pTextStart.length, posTextStart - pTextEnd.length);
		}
	}
	return pBlock;
}

function TaskKill(process_name) {
	var objWMIService = GetObject("winmgmts:\\\\.\\root\\CIMV2");
	var colProcessList = objWMIService.ExecQuery ('SELECT * FROM Win32_Process WHERE NAME = "' + process_name + '"');
	var enumItems = new Enumerator(colProcessList);
	for (; !enumItems.atEnd(); enumItems.moveNext())
		enumItems.item().Terminate();
}
Алгоритм:
1. Если есть выделение, то берётся чисто выделение; пробелы в конце не обрезаются, т.к. кроме пробелов там может быть любые символы...;
2. Если нет выделения, тогда:
- отталкиваемся от позиции курсора (считаем, что он установлен внутри [] или "");
- если ничего не найдено, то берём всю строку и берём текст внутри крайних [] или "";
3. Если в строке нет символов, в которые может быть заключён путь. то предполагаем, что это просто текстовый файл, поэтому берём строку с символов "HK" и пытаемся открыть; если этих символов - выходим, т.к. это не ветка реестра.

Из этого следует несколько вариантов работы скрипта (для пользователя):
- по выделению (путь должен быть чётко выделен);
- по позиции курсора внутри пути (самый частый и простой способ);
- из всей строки, в которой установлен курсор (в этом случае пользователь соглашается с тем, что текст между крайними [] или "" считается путём, т.е. корректно скрипт будет работать, если в текущей строке пара вышеуказанных символов встречается 1 раз); этот способ подходит для больших строк (трудно такое придумать чтобы курсором тяжело было попасть, но... пусть будет).

Благодарности: mozers™, KDJ, Skif_off.
Last edited by VladSh on Tue Sep 01, 2015 9:09 am, edited 13 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

converter.js <download | mirror | development version>
  • Encode/decode HTML entities
  • Convert JavaScript escape sequences like "\u00a9" or "\xa9" («©» symbol)
  • Escape/unescape special RegExp symbols
  • Escape/unescape special strings symbols
  • Encode/decode Uniform Resource Identifiers (URIs)
  • Hexadecimal escape/unescape
  • Base64 encode/decode
  • Convert charset

Image Image


Post size limit, here is packed file:

Code: Select all

begin 644 converter.7z
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
A`'(`+@!J`',````4"@$``!#KHUUISP$5!@$`(```````
`
end
sum -r/size 26769/18078

Save as text file with .uue extension, unpack with Total Commander or WinRAR. And unpack .7z with WinRAR or 7-Zip. :)
Last edited by Infocatcher on Wed May 07, 2014 11:26 am, edited 16 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

getHash.js <download | mirror | development version>
Calculates hash sum of text.
It can be very slow, be careful.


Image Image


Post size limit, here is packed file:

Code: Select all

begin 644 getHash.7z
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
,SP$5!@$`(```````
`
end
sum -r/size 45042/18462

Save as text file with .uue extension, unpack with Total Commander or WinRAR. And unpack .7z with WinRAR or 7-Zip. :)
Last edited by Infocatcher on Wed May 07, 2014 11:29 am, edited 13 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Sorts lists in lines by using Format plugin.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11121#p11121
// Version: 2015-09-19
// Author: KDJ
//
// *** Sort list by using Format plugin ***
//
// Usage:
//   Call("Scripts::Main", 1, "SortList.js")
//
// Shortcut keys in dialog box:
//   Enter - Sort
//   Esc   - Close
//   Shift+Alt+Right (Left, Down, Up, End, Home, PgDn, PgUp) - move dialog box.
//
// Remarks:
//   In each line, sorts separately.
//   If you do not specify a separator, it will be sorted single characters.

if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 0x0415) //Polish
{
  var sTxtCaption  = "Sortowanie list w wierszach";
  var sTxtSep      = "Separator:";
  var sTxtTab      = "\\t = Tabulacja";
  var sTxtSortMet  = "Metoda sortowania";
  var sTxtDesc     = "&Malejąco";
  var sTxtIgCase   = "&Ignoruj wlk. liter";
  var sTxtString   = "&String";
  var sTxtNum      = "&Numerycznie";
  var sTxtNoSort   = "Nie sortuj, ale";
  var sTxtReverse  = "&Odwróć kolejność elementów";
  var sTxtRemoDup  = "&Usuń duplikaty elementów";
  var sTxtExtrDup  = "&Zachowaj tylko powielone elementy";
  var sTxtExtrUni  = "Zac&howaj tylko unikalne elementy";
  var sTxtCopyToCB = "Wynik kopiuj do schowka, nie zmieniaj &tekstu";
  var sTxtSort     = "Sortuj";
  var sTxtUndo     = "&Cofnij";
  var sTxtRedo     = "&Powtórz";
  var sTxtNoSep    = "Zaznaczony tekst nie zawiera separatora.";
}
else
{
  var sTxtCaption  = "Sort lists in lines";
  var sTxtSep      = "Separator:";
  var sTxtTab      = "\\t = Tabulation";
  var sTxtSortMet  = "Sort method";
  var sTxtDesc     = "&Descending";
  var sTxtIgCase   = "&Ignore case";
  var sTxtString   = "&String";
  var sTxtNum      = "&Numerically";
  var sTxtNoSort   = "No sort, but";
  var sTxtReverse  = "Reverse &order of elements";
  var sTxtRemoDup  = "Re&move duplicate elements";
  var sTxtExtrDup  = "E&xtract duplicate elements";
  var sTxtExtrUni  = "Extra&ct unique elements";
  var sTxtCopyToCB = "Resul&t copy to clipboard, do not replace text";
  var sTxtSort     = "Sort";
  var sTxtUndo     = "&Undo";
  var sTxtRedo     = "&Redo";
  var sTxtNoSep    = "Selected text not contain separator.";
}

var DT_DWORD    = 3;
var BM_SETCHECK = 241;

var oSys       = AkelPad.SystemFunction();
var hMainWnd   = AkelPad.GetMainWnd();
var hEditWnd   = AkelPad.GetEditWnd();
var hGuiFont   = oSys.Call("Gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
var hInstDLL   = AkelPad.GetInstanceDll();
var sClassName = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstDLL;
var sSep       = ";";
var bTab       = 1;
var bDesc      = 0;
var bIgCase    = 1;
var nMethod    = 1;
var nNoSort    = 0;
var bCopyToCB  = 0;
var nUndoLimit = 0;
var nRedoLimit = 0;
var hWndDlg;
var lpBuffer;
var bIsReturn;
var hFocus;
var nWndPosX;
var nWndPosY;

ReadWriteIni(0);

var aWnd       = [];
var IDGROUP1   = 1000;
var IDSTATSEP  = 1001;
var IDSEP      = 1002;
var IDTAB      = 1003;
var IDGROUP2   = 1004;
var IDDESC     = 1005;
var IDIGCASE   = 1006;
var IDGROUP3   = 1007;
var IDSTRING   = 1008;
var IDNUM      = 1009;
var IDGROUP4   = 1010;
var IDREVERSE  = 1011;
var IDREMODUP  = 1012;
var IDEXTRDUP  = 1013;
var IDEXTRUNI  = 1014;
var IDCOPYTOCB = 1015;
var IDSORT     = 1016;
var IDUNDO     = 1017;
var IDREDO     = 1018;

var CLASS   = 0;
var WND     = 1;
var EXSTYLE = 2;
var STYLE   = 3;
var X       = 4;
var Y       = 5;
var W       = 6;
var H       = 7;
var TXT     = 8;

//0x50000000 - WS_VISIBLE|WS_CHILD
//0x50000007 - WS_VISIBLE|WS_CHILD|BS_GROUPBOX
//0x50000009 - WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON
//0x50010000 - WS_VISIBLE|WS_CHILD|WS_TABSTOP
//0x50010003 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
//0x50010080 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL
//Windows              CLASS, WND, EXSTYLE,      STYLE,   X,   Y,   W,   H, TXT
aWnd[IDGROUP1  ] = ["BUTTON",   0,       0, 0x50000007,  10,  10, 170,  75, ""];
aWnd[IDSTATSEP ] = ["STATIC",   0,       0, 0x50000000,  20,  30,  60,  13, sTxtSep];
aWnd[IDSEP     ] = ["EDIT",     0,   0x200, 0x50010080,  80,  30,  90,  20, sSep];
aWnd[IDTAB     ] = ["BUTTON",   0,       0, 0x50010003,  80,  60,  90,  16, sTxtTab];
aWnd[IDGROUP2  ] = ["BUTTON",   0,       0, 0x50000007,  10,  95, 260,  65, sTxtSortMet];
aWnd[IDDESC    ] = ["BUTTON",   0,       0, 0x50010003,  40, 115,  90,  16, sTxtDesc];
aWnd[IDIGCASE  ] = ["BUTTON",   0,       0, 0x50010003,  40, 135,  90,  16, sTxtIgCase];
aWnd[IDGROUP3  ] = ["BUTTON",   0,       0, 0x50000007, 150,  95, 120,  65, ""];
aWnd[IDSTRING  ] = ["BUTTON",   0,       0, 0x50000009, 175, 115,  90,  16, sTxtString];
aWnd[IDNUM     ] = ["BUTTON",   0,       0, 0x50000009, 175, 135,  90,  16, sTxtNum];
aWnd[IDGROUP4  ] = ["BUTTON",   0,       0, 0x50000007,  10, 170, 260, 105, sTxtNoSort];
aWnd[IDREVERSE ] = ["BUTTON",   0,       0, 0x50010003,  60, 190, 200,  16, sTxtReverse];
aWnd[IDREMODUP ] = ["BUTTON",   0,       0, 0x50010003,  60, 210, 200,  16, sTxtRemoDup];
aWnd[IDEXTRDUP ] = ["BUTTON",   0,       0, 0x50010003,  60, 230, 200,  16, sTxtExtrDup];
aWnd[IDEXTRUNI ] = ["BUTTON",   0,       0, 0x50010003,  60, 250, 200,  16, sTxtExtrUni];
aWnd[IDCOPYTOCB] = ["BUTTON",   0,       0, 0x50010003,  20, 285, 240,  16, sTxtCopyToCB];
aWnd[IDSORT    ] = ["BUTTON",   0,       0, 0x50010000, 190,  14,  80,  23, sTxtSort];
aWnd[IDUNDO    ] = ["BUTTON",   0,       0, 0x50010000, 190,  39,  80,  23, sTxtUndo];
aWnd[IDREDO    ] = ["BUTTON",   0,       0, 0x50010000, 190,  64,  80,  23, sTxtRedo];

if (hEditWnd)
{
  AkelPad.SendMessage(hEditWnd, 3128 /*AEM_UPDATESEL*/, 0 /*AESELT_COLUMNOFF*/, 0);
  if (AkelPad.GetSelStart() == AkelPad.GetSelEnd())
    AkelPad.SetSel(0, -1);

  if (AkelPad.WindowRegisterClass(sClassName))
  {
    if (lpBuffer = AkelPad.MemAlloc(256 * _TSIZE))
    {
      hWndDlg = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                  0,               //dwExStyle
                  sClassName,      //lpClassName
                  sTxtCaption,     //lpWindowName
                  0x90CA0000,      //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
                  0,               //x
                  0,               //y
                  285,             //nWidth
                  340,             //nHeight
                  hMainWnd,        //hWndParent
                  0,               //ID
                  hInstDLL,        //hInstance
                  DialogCallback); //Script function callback. To use it class must be registered by WindowRegisterClass.
      if (hWndDlg)
      {
        //Disable main window, to make dialog modal
        oSys.Call("User32::EnableWindow", hMainWnd, false);

        //Message loop
        AkelPad.WindowGetMessage();
      }
      AkelPad.MemFree(lpBuffer);
    }
    AkelPad.WindowUnregisterClass(sClassName);
  }
}

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  var i, nLowParam;

  if (uMsg == 1) //WM_CREATE
  {
    for (i = 1000; i < aWnd.length; ++i)
    {
      aWnd[i][WND] = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                       aWnd[i][EXSTYLE], //dwExStyle
                       aWnd[i][CLASS],   //lpClassName
                       0,                //lpWindowName
                       aWnd[i][STYLE],   //dwStyle
                       aWnd[i][X],       //x
                       aWnd[i][Y],       //y
                       aWnd[i][W],       //nWidth
                       aWnd[i][H],       //nHeight
                       hWnd,             //hWndParent
                       i,                //ID
                       hInstDLL,         //hInstance
                       0);               //lpParam
      SetWindowFontAndText(aWnd[i][WND], hGuiFont, aWnd[i][TXT]);
    }

    //Set limit edit text
    AkelPad.SendMessage(aWnd[IDSEP][WND], 197 /*EM_LIMITTEXT*/, 20, 0);

    CheckButtons();
    CheckUndoRedo();

    //Set window position
    if ((nWndPosX == undefined) || (nWndPosY == undefined))
      MoveWindow(hMainWnd, hWnd, "RT");
    else
      MoveWindow(hMainWnd, hWnd, [nWndPosX, nWndPosY]);
  }

  else if (uMsg == 7) //WM_SETFOCUS
  {
    oSys.Call("User32::SetFocus", aWnd[IDSEP][WND]);
    AkelPad.SendMessage(aWnd[IDSEP][WND], 177 /*EM_SETSEL*/, 0, -1);
  }

  else if (uMsg == 256) //WM_KEYDOWN
  {
    if (wParam == 27) //VK_ESCAPE
      oSys.Call("User32::PostMessage" + _TCHAR, hWndDlg, 16 /*WM_CLOSE*/, 0, 0);
    else if (wParam == 13) //VK_RETURN
    {
      if (! bIsReturn)
      {
        hFocus = oSys.Call("User32::GetFocus");
        if ((hFocus != aWnd[IDSORT][WND]) && (hFocus != aWnd[IDUNDO][WND]) && (hFocus != aWnd[IDREDO][WND]))
          oSys.Call("User32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDSORT, 0);
      }
    }
  }

  else if (uMsg == 257) //WM_KEYUP
    bIsReturn = 0;

  else if ((uMsg == 260) /*WM_SYSKEYDOWN*/ &&
           (oSys.Call("User32::GetAsyncKeyState", 0xA0 /*VK_LSHIFT*/)))
  {
    if (wParam == 0x27) //VK_RIGHT
      MoveWindow(hMainWnd, hWnd, "R");
    else if (wParam == 0x25) //VK_LEFT
      MoveWindow(hMainWnd, hWnd, "L");
    else if (wParam == 0x28) //VK_DOWN
      MoveWindow(hMainWnd, hWnd, "D");
    else if (wParam == 0x26) //VK_UP
      MoveWindow(hMainWnd, hWnd, "U");
    else if (wParam == 0x23) //VK_END
      MoveWindow(hMainWnd, hWnd, "E");
    else if (wParam == 0x24) //VK_HOME
      MoveWindow(hMainWnd, hWnd, "H");
    else if (wParam == 0x22) //VK_NEXT
      MoveWindow(hMainWnd, hWnd, "B");
    else if (wParam == 0x21) //VK_PRIOR
      MoveWindow(hMainWnd, hWnd, "T");
  }

  else if (uMsg == 273) //WM_COMMAND
  {
    nLowParam = LoWord(wParam);

    if ((nLowParam >= IDTAB) && (nLowParam <= IDCOPYTOCB))
    {
      CheckButtons(nLowParam);
    }

    else if (nLowParam == IDSORT)
    {
      if (SortList())
        CheckUndoRedo(nLowParam);
    }

    else if (nLowParam == IDUNDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
    }

    else if (nLowParam == IDREDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
    }
  }

  else if (uMsg == 16) //WM_CLOSE
  {
    ReadWriteIni(1);

    //Enable main window
    oSys.Call("User32::EnableWindow", hMainWnd, true);
    //Destroy dialog
    oSys.Call("User32::DestroyWindow", hWnd);
  }

  else if (uMsg == 2) //WM_DESTROY
  {
    //Exit message loop
    oSys.Call("User32::PostQuitMessage", 0);
  }

  else
    SetDefID(hWnd);

  return 0;
}

function SetWindowFontAndText(hWnd, hFont, sText)
{
  AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
  oSys.Call("User32::SetWindowText" + _TCHAR, hWnd, sText);
}

function MoveWindow(hWndParent, hWnd, vAction)
{
  var aRectParent;
  var aRect;
  var nX;
  var nY;

  if (! hWndParent)
    hWndParent=oSys.Call("User32::GetDesktopWindow");

  aRectParent = GetWindowPos(hWndParent);
  aRect       = GetWindowPos(hWnd);

  nX = aRect.left;
  nY = aRect.top;

  if (vAction == "R") //Move right
    nX = aRect.left + ((aRect.left < aRectParent.right - 50) ? 20 : 0);
  else if (vAction == "L") //Move left
    nX = aRect.left - ((aRect.right > aRectParent.left + 50) ? 20 : 0);
  else if (vAction == "D") //Move down
    nY = aRect.top + ((aRect.top < aRectParent.bottom - 50) ? 20 : 0);
  else if (vAction == "U") //Move up
    nY = aRect.top - ((aRect.bottom > aRectParent.top + 50) ? 20 : 0);
  else if (vAction == "E") //Move end (right)
    nX = aRect.left + (aRectParent.right - aRect.right);
  else if (vAction == "H") //Move home (left)
    nX = aRect.left + (aRectParent.left - aRect.left);
  else if (vAction == "B") //Move bottom
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  else if (vAction == "T") //Move top
    nY = aRect.top + (aRectParent.top - aRect.top);
  else if (vAction == "C") //Center window
  {
    nX = aRectParent.left + ((aRectParent.right  - aRectParent.left) / 2 - (aRect.right  - aRect.left) / 2);
    nY = aRectParent.top  + ((aRectParent.bottom - aRectParent.top)  / 2 - (aRect.bottom - aRect.top)  / 2);
  }
  else if (vAction == "LT") //Move left top
  {
    nX = aRectParent.left;
    nY = aRectParent.top;
  }
  else if (vAction == "RT") //Move right top
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRectParent.top;
  }
  else if (vAction == "LB") //Move left bottom
  {
    nX = aRectParent.left;
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else if (vAction == "RB") //Move right bottom
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else
  {
    nX = vAction[0];
    nY = vAction[1];
  }

  oSys.Call("User32::SetWindowPos", hWnd, 0, nX, nY, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
}

function GetWindowPos(hWnd)
{
  var lpRect = AkelPad.MemAlloc(16) //sizeof(RECT);
  var aRect  = [];

  oSys.Call("User32::GetWindowRect", hWnd, lpRect);

  aRect.left   = AkelPad.MemRead(_PtrAdd(lpRect,  0), DT_DWORD);
  aRect.top    = AkelPad.MemRead(_PtrAdd(lpRect,  4), DT_DWORD);
  aRect.right  = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD);
  aRect.bottom = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD);
  AkelPad.MemFree(lpRect);

  return aRect;
}

function LoWord(nParam)
{
  return (nParam & 0xFFFF);
}

function SetDefID(hWnd)
{
  var nID    = 1000;
  var hFocus = oSys.Call("User32::GetFocus");

  while ((nID < aWnd.length) && (hFocus != aWnd[nID][WND]))
    ++nID;

  if ((nID != IDUNDO) && (nID != IDREDO))
    nID = IDSORT;

  oSys.Call("User32::DefDlgProc" + _TCHAR, hWnd, 1025 /*DM_SETDEFID*/, nID, 0);
}

function ReadWriteIni(bWrite)
{
  var oFSO     = new ActiveXObject("Scripting.FileSystemObject");
  var sIniName = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini";
  var aRect;
  var oFile;
  var sIniTxt;

  if (bWrite)
  {
    aRect = GetWindowPos(hWndDlg);

    oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDSEP][WND], lpBuffer, 256);
    sSep = AkelPad.MemRead(lpBuffer, _TSTR);

    sIniTxt = 'nWndPosX='  + aRect.left + ';\r\n' +
              'nWndPosY='  + aRect.top  + ';\r\n' +
              'sSep="'     + sSep.replace(/[\\"]/g, "\\$&") + '";\r\n' +
              'bTab='      + bTab + ';\r\n' +
              'bDesc='     + bDesc + ';\r\n' +
              'bIgCase='   + bIgCase + ';\r\n' +
              'nMethod='   + nMethod + ';\r\n' +
              'nNoSort='   + nNoSort + ';\r\n' +
              'bCopyToCB=' + bCopyToCB + ';'

    oFile = oFSO.OpenTextFile(sIniName, 2, true, 0);
    oFile.Write(sIniTxt);
    oFile.Close();
  }

  else if (oFSO.FileExists(sIniName))
  {
    try
    {
      eval(AkelPad.ReadFile(sIniName));
    }
    catch (oError)
    {
    }
  }
}

function CheckButtons(nButton)
{
  if (nButton == IDTAB)
    bTab = ! bTab;
  else if (nButton == IDDESC)
    bDesc = ! bDesc;
  else if (nButton == IDIGCASE)
    bIgCase = ! bIgCase;
  else if ((nButton == IDSTRING) || (nButton == IDNUM))
    nMethod = nButton - IDSTRING + 1;
  else if ((nButton == IDREVERSE) || (nButton == IDREMODUP) ||
           (nButton == IDEXTRDUP) || (nButton == IDEXTRUNI))
  {
    if (nNoSort == nButton - IDREVERSE + 1)
      nNoSort = 0;
    else
      nNoSort = nButton - IDREVERSE + 1;
  }
  else if (nButton == IDCOPYTOCB)
    bCopyToCB = ! bCopyToCB;

  if (nNoSort > 1)
    nMethod = 1;

  AkelPad.SendMessage(aWnd[IDTAB][WND],      BM_SETCHECK, bTab,           0);
  AkelPad.SendMessage(aWnd[IDDESC][WND],     BM_SETCHECK, bDesc,          0);
  AkelPad.SendMessage(aWnd[IDIGCASE][WND],   BM_SETCHECK, bIgCase,        0);
  AkelPad.SendMessage(aWnd[IDSTRING][WND],   BM_SETCHECK, (nMethod == 1), 0);
  AkelPad.SendMessage(aWnd[IDNUM][WND],      BM_SETCHECK, (nMethod == 2), 0);
  AkelPad.SendMessage(aWnd[IDREVERSE][WND],  BM_SETCHECK, (nNoSort == 1), 0);
  AkelPad.SendMessage(aWnd[IDREMODUP][WND],  BM_SETCHECK, (nNoSort == 2), 0);
  AkelPad.SendMessage(aWnd[IDEXTRDUP][WND],  BM_SETCHECK, (nNoSort == 3), 0);
  AkelPad.SendMessage(aWnd[IDEXTRUNI][WND],  BM_SETCHECK, (nNoSort == 4), 0);
  AkelPad.SendMessage(aWnd[IDCOPYTOCB][WND], BM_SETCHECK, bCopyToCB,      0);

  oSys.Call("User32::EnableWindow", aWnd[IDDESC][WND],   (nNoSort == 0));
  oSys.Call("User32::EnableWindow", aWnd[IDIGCASE][WND], (nNoSort != 1));
  oSys.Call("User32::EnableWindow", aWnd[IDSTRING][WND], (nNoSort != 1));
  oSys.Call("User32::EnableWindow", aWnd[IDNUM][WND],    (nNoSort == 0));
}

function CheckUndoRedo(nButton)
{
  var nBegSel  = AkelPad.GetSelStart();
  var sTxtUndo = aWnd[IDUNDO][TXT];
  var sTxtRedo = aWnd[IDREDO][TXT];

  if (nButton == IDSORT)
  {
    if (nUndoLimit < AkelPad.SendMessage(hEditWnd, 3084 /*AEM_GETUNDOLIMIT*/, 0, 0))
      ++nUndoLimit;
    nRedoLimit = 0;
  }
  else if ((nButton == IDUNDO) && (nUndoLimit))
  {
    --nUndoLimit;
    ++nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3077 /*AEM_UNDO*/, 0, 0);
  }
  else if ((nButton == IDREDO) && (nRedoLimit))
  {
    ++nUndoLimit;
    --nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3078 /*AEM_REDO*/, 0, 0);
    AkelPad.SetSel(nBegSel, AkelPad.GetSelEnd());
  }

  if (nUndoLimit)
    sTxtUndo += " (" + nUndoLimit + ")";
  if (nRedoLimit)
    sTxtRedo += " (" + nRedoLimit + ")";

  if (((oSys.Call("User32::GetFocus") == aWnd[IDUNDO][WND]) && (nUndoLimit == 0)) ||
      ((oSys.Call("User32::GetFocus") == aWnd[IDREDO][WND]) && (nRedoLimit == 0)))
    oSys.Call("User32::SetFocus", aWnd[IDSEP][WND]);

  SetWindowFontAndText(aWnd[IDUNDO][WND], hGuiFont, sTxtUndo);
  SetWindowFontAndText(aWnd[IDREDO][WND], hGuiFont, sTxtRedo);

  oSys.Call("User32::EnableWindow", aWnd[IDUNDO][WND], nUndoLimit);
  oSys.Call("User32::EnableWindow", aWnd[IDREDO][WND], nRedoLimit);
}

function SortList()
{
  var nBegSel  = AkelPad.GetSelStart();
  var nEndSel  = AkelPad.GetSelEnd();
  var sText    = AkelPad.GetSelText();
  var nLine1   = AkelPad.SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nBegSel);
  var nLine2   = AkelPad.SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nEndSel);
  var nBegLen  = TextLen();
  var nBegLine;
  var nEndLine;
  var bSepEnd;
  var rSep;
  var rSep_g;
  var rSepEnd;
  var i;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDSEP][WND], lpBuffer, 256);
  sSep = AkelPad.MemRead(lpBuffer, _TSTR);

  if (bTab) sSep = sSep.replace(/\\t/g, "\t");

  rSep    = new RegExp(escapeRegExp(sSep));
  rSep_g  = new RegExp(escapeRegExp(sSep), "g");
  rSepEnd = new RegExp(escapeRegExp(sSep) + "$");

  if (! rSep.test(sText))
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoSep, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    return 0;
  }

  SetRedraw(hEditWnd, false);
  AkelPad.SendMessage(hEditWnd, 3080 /*AEM_STOPGROUPTYPING*/, 0, 0);
  AkelPad.SendMessage(hEditWnd, 3081 /*AEM_BEGINUNDOACTION*/, 0, 0);
  AkelPad.ReplaceSel(sText, -1);

  for (i = nLine1; i <= nLine2; ++i)
  {
    if (nLine1 < nLine2)
    {
       nBegLine = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, i, 0);
       nEndLine = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, i, 0) +
                    AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine, 0);
      if (i == nLine1)
        AkelPad.SetSel(nBegSel, nEndLine);
      else if (i == nLine2)
        AkelPad.SetSel(nBegLine, nEndSel - nBegLen + TextLen());
      else
        AkelPad.SetSel(nBegLine, nEndLine);

      sText = AkelPad.GetSelText();
    }

    if (rSep.test(sText))
    {
      bSepEnd = rSepEnd.test(sText);
      sText   = sText.replace(rSep_g, "\r");
      AkelPad.ReplaceSel("\r" + sText + "\r", -1);
      AkelPad.SetSel(AkelPad.GetSelStart() + 1, AkelPad.GetSelEnd() - 1);
      SortByPlugin();
      sText = AkelPad.GetTextRange(AkelPad.GetSelStart(), AkelPad.GetSelEnd() - 1 + bSepEnd).replace(/\r/g, sSep);
      AkelPad.SetSel(AkelPad.GetSelStart() - 1, AkelPad.GetSelEnd() + bSepEnd);
      AkelPad.ReplaceSel(sText, -1);
    }
  }

  AkelPad.SetSel(nBegSel, AkelPad.GetSelEnd());
  AkelPad.SendMessage(hEditWnd, 3082 /*AEM_ENDUNDOACTION*/, 0, 0);
  AkelPad.SendMessage(hEditWnd, 3080 /*AEM_STOPGROUPTYPING*/, 0, 0);

  if (bCopyToCB)
  {
    AkelPad.SetClipboardText(AkelPad.GetSelText());
    AkelPad.SendMessage(hEditWnd, 3077 /*AEM_UNDO*/, 0, 0);
  }

  SetRedraw(hEditWnd, true);
  return ! bCopyToCB;
}

function SortByPlugin()
{
  var sAscDesc = bDesc ? "Desc" : "Asc";

  if (nNoSort == 1)
    AkelPad.Call("Format::LineReverse");
  else if (nNoSort == 2)
    AkelPad.Call("Format::LineRemoveDuplicates", ! bIgCase);
  else if (nNoSort == 3)
    AkelPad.Call("Format::LineGetDuplicates", ! bIgCase);
  else if (nNoSort == 4)
    AkelPad.Call("Format::LineGetUnique", ! bIgCase);
  else if (nMethod == 1)
    AkelPad.Call("Format::LineSortStr" + sAscDesc, ! bIgCase);
  else if (nMethod == 2)
    AkelPad.Call("Format::LineSortInt" + sAscDesc, ! bIgCase);
}

function escapeRegExp(sStr)
{
  return sStr.replace(/[\\\/.^$+*?|()\[\]{}]/g, "\\$&");
}

function SetRedraw(hWnd, bRedraw)
{
  var oSys = AkelPad.SystemFunction();
  AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
  bRedraw && oSys.Call("User32::InvalidateRect", hWnd, 0, true);
}

function TextLen()
{
  var nOffset = -1;
  var lpIndex;

  if (lpIndex = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/))
  {
    AkelPad.SendMessage(hEditWnd, 3130 /*AEM_GETINDEX*/, 2 /*AEGI_LASTCHAR*/, lpIndex);
    nOffset = AkelPad.SendMessage(hEditWnd, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, lpIndex);
    AkelPad.MemFree(lpIndex);
  }
  return nOffset;
}

Last edited by KDJ on Sat Sep 19, 2015 3:48 pm, edited 7 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11212#p11212
// http://infocatcher.ucoz.net/js/akelpad_scripts/AESCrypt.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/AESCrypt.js

// (c) Infocatcher 2010-2011, 2014
// version 0.2.7.1 - 2014-05-06

//===================
// AES-256 encrypt/decrypt
// Based on script from http://www.movable-type.co.uk/scripts/aes.html

// Arguments:
//   -mode=0             - (default) ask user about direction (encrypt or decrypt)
//        =1             - encrypt
//        =2             - decrypt
//   -maxLineWidth=75    - allow split output to lines with fixed width
//   -showPassword=true  - force show or hide password
//   -saveOptions=true   - allow store last used password state

// Usage:
//   Call("Scripts::Main", 1, "AESCrypt.js", "-mode=1")     - encrypt
//   Call("Scripts::Main", 1, "AESCrypt.js", "-mode=2")     - decrypt
//   Call("Scripts::Main", 1, "AESCrypt.js", "-mode=0 -maxLineWidth=0 -showPassword=true -saveOptions=false")
//===================

function _localize(s) {
	var strings = {
		"Nothing to encrypt!": {
			ru: "Нечего зашифровывать!"
		},
		"Nothing to decrypt!": {
			ru: "Нечего расшифровывать!"
		},
		"Direction": {
			ru: "Направление"
		},
		"Encrypt": {
			ru: "Зашифровать"
		},
		"Decrypt": {
			ru: "Расшифровать"
		},
		"Password": {
			ru: "Пароль"
		},
		"&Encrypt": {
			ru: "&Зашифровать"
		},
		"&Decrypt": {
			ru: "&Расшифровать"
		},
		"Impossible to decrypt: invalid format!": {
			ru: "Невозможно расшифровать: некорректный формат!"
		},
		"Enter &password:": {
			ru: "Введите &пароль:"
		},
		"Reenter p&assword:": {
			ru: "Повторите п&ароль:"
		},
		"&Show password": {
			ru: "По&казывать пароль"
		},
		"OK": {
			ru: "ОК"
		},
		"Cancel": {
			ru: "Отмена"
		},
		"Passwords do not match!": {
			ru: "Пароли не совпадают!"
		}
	};
	var lng;
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru"; break;
		default:   lng = "en";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

var MODE_USER_SELECT = 0;
var MODE_ENCRYPT     = 1;
var MODE_DECRYPT     = 2;

// Read arguments:
// getArg(argName, defaultValue)
var mode         = getArg("mode", 0);
var maxLineWidth = getArg("maxLineWidth", 75);
var showPassword = getArg("showPassword");
var saveOptions  = getArg("saveOptions", true);

var decrypt = mode == MODE_DECRYPT;


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  AES implementation in JavaScript (c) Chris Veness 2005-2010                                   */
/*   - see http://csrc.nist.gov/publications/PubsFIPS.html#197                                    */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

var Aes = {};  // Aes namespace

/**
 * AES Cipher function: encrypt 'input' state with Rijndael algorithm
 *   applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage
 *
 * @param {Number[]} input 16-byte (128-bit) input state array
 * @param {Number[][]} w   Key schedule as 2D byte-array (Nr+1 x Nb bytes)
 * @returns {Number[]}     Encrypted output state array
 */
Aes.cipher = function(input, w) {    // main Cipher function [§5.1]
  var Nb = 4;               // block size (in words): no of columns in state (fixed at 4 for AES)
  var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys

  var state = [[],[],[],[]];  // initialise 4xNb byte-array 'state' with input [§3.4]
  for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];

  state = Aes.addRoundKey(state, w, 0, Nb);

  for (var round=1; round<Nr; round++) {
    state = Aes.subBytes(state, Nb);
    state = Aes.shiftRows(state, Nb);
    state = Aes.mixColumns(state, Nb);
    state = Aes.addRoundKey(state, w, round, Nb);
  }

  state = Aes.subBytes(state, Nb);
  state = Aes.shiftRows(state, Nb);
  state = Aes.addRoundKey(state, w, Nr, Nb);

  var output = new Array(4*Nb);  // convert state to 1-d array before returning [§3.4]
  for (var i=0; i<4*Nb; i++) output[i] = state[i%4][Math.floor(i/4)];
  return output;
}

/**
 * Perform Key Expansion to generate a Key Schedule
 *
 * @param {Number[]} key Key as 16/24/32-byte array
 * @returns {Number[][]} Expanded key schedule as 2D byte-array (Nr+1 x Nb bytes)
 */
Aes.keyExpansion = function(key) {  // generate Key Schedule (byte-array Nr+1 x Nb) from Key [§5.2]
  var Nb = 4;            // block size (in words): no of columns in state (fixed at 4 for AES)
  var Nk = key.length/4  // key length (in words): 4/6/8 for 128/192/256-bit keys
  var Nr = Nk + 6;       // no of rounds: 10/12/14 for 128/192/256-bit keys

  var w = new Array(Nb*(Nr+1));
  var temp = new Array(4);

  for (var i=0; i<Nk; i++) {
    var r = [key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]];
    w[i] = r;
  }

  for (var i=Nk; i<(Nb*(Nr+1)); i++) {
    w[i] = new Array(4);
    for (var t=0; t<4; t++) temp[t] = w[i-1][t];
    if (i % Nk == 0) {
      temp = Aes.subWord(Aes.rotWord(temp));
      for (var t=0; t<4; t++) temp[t] ^= Aes.rCon[i/Nk][t];
    } else if (Nk > 6 && i%Nk == 4) {
      temp = Aes.subWord(temp);
    }
    for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t];
  }

  return w;
}

/*
 * ---- remaining routines are private, not called externally ----
 */

Aes.subBytes = function(s, Nb) {    // apply SBox to state S [§5.1.1]
  for (var r=0; r<4; r++) {
    for (var c=0; c<Nb; c++) s[r][c] = Aes.sBox[s[r][c]];
  }
  return s;
}

Aes.shiftRows = function(s, Nb) {    // shift row r of state S left by r bytes [§5.1.2]
  var t = new Array(4);
  for (var r=1; r<4; r++) {
    for (var c=0; c<4; c++) t[c] = s[r][(c+r)%Nb];  // shift into temp copy
    for (var c=0; c<4; c++) s[r][c] = t[c];         // and copy back
  }          // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
  return s;  // see asmaes.sourceforge.net/rijndael/rijndaelImplementation.pdf
}

Aes.mixColumns = function(s, Nb) {   // combine bytes of each col of state S [§5.1.3]
  for (var c=0; c<4; c++) {
    var a = new Array(4);  // 'a' is a copy of the current column from 's'
    var b = new Array(4);  // 'b' is a•{02} in GF(2^8)
    for (var i=0; i<4; i++) {
      a[i] = s[i][c];
      b[i] = s[i][c]&0x80 ? s[i][c]<<1 ^ 0x011b : s[i][c]<<1;

    }
    // a[n] ^ b[n] is a•{03} in GF(2^8)
    s[0][c] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; // 2*a0 + 3*a1 + a2 + a3
    s[1][c] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; // a0 * 2*a1 + 3*a2 + a3
    s[2][c] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; // a0 + a1 + 2*a2 + 3*a3
    s[3][c] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; // 3*a0 + a1 + a2 + 2*a3
  }
  return s;
}

Aes.addRoundKey = function(state, w, rnd, Nb) {  // xor Round Key into state S [§5.1.4]
  for (var r=0; r<4; r++) {
    for (var c=0; c<Nb; c++) state[r][c] ^= w[rnd*4+c][r];
  }
  return state;
}

Aes.subWord = function(w) {    // apply SBox to 4-byte word w
  for (var i=0; i<4; i++) w[i] = Aes.sBox[w[i]];
  return w;
}

Aes.rotWord = function(w) {    // rotate 4-byte word w left by one byte
  var tmp = w[0];
  for (var i=0; i<3; i++) w[i] = w[i+1];
  w[3] = tmp;
  return w;
}

// sBox is pre-computed multiplicative inverse in GF(2^8) used in subBytes and keyExpansion [§5.1.1]
Aes.sBox =  [0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
             0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
             0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
             0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
             0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
             0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
             0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
             0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
             0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
             0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
             0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
             0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
             0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
             0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
             0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
             0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16];

// rCon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]
Aes.rCon = [ [0x00, 0x00, 0x00, 0x00],
             [0x01, 0x00, 0x00, 0x00],
             [0x02, 0x00, 0x00, 0x00],
             [0x04, 0x00, 0x00, 0x00],
             [0x08, 0x00, 0x00, 0x00],
             [0x10, 0x00, 0x00, 0x00],
             [0x20, 0x00, 0x00, 0x00],
             [0x40, 0x00, 0x00, 0x00],
             [0x80, 0x00, 0x00, 0x00],
             [0x1b, 0x00, 0x00, 0x00],
             [0x36, 0x00, 0x00, 0x00] ];


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  AES Counter-mode implementation in JavaScript (c) Chris Veness 2005-2009                      */
/*   - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf                       */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

Aes.Ctr = {};  // Aes.Ctr namespace: a subclass or extension of Aes

/**
 * Encrypt a text using AES encryption in Counter mode of operation
 *
 * Unicode multi-byte character safe
 *
 * @param {String} plaintext Source text to be encrypted
 * @param {String} password  The password to use to generate a key
 * @param {Number} nBits     Number of bits to be used in the key (128, 192, or 256)
 * @returns {string}         Encrypted text
 */
Aes.Ctr.encrypt = function(plaintext, password, nBits) {
  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
  if (!(nBits==128 || nBits==192 || nBits==256)) return '';  // standard allows 128/192/256 bit keys
  plaintext = Utf8.encode(plaintext);
  password = Utf8.encode(password);
  //var t = new Date();  // timer

  // use AES itself to encrypt password to get cipher key (using plain password as source for key
  // expansion) - gives us well encrypted key
  var nBytes = nBits/8;  // no bytes in key
  var pwBytes = new Array(nBytes);
  for (var i=0; i<nBytes; i++) {
    pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
  }
  var key = Aes.cipher(pwBytes, Aes.keyExpansion(pwBytes));  // gives us 16-byte key
  key = key.concat(key.slice(0, nBytes-16));  // expand key to 16/24/32 bytes long

  // initialise counter block (NIST SP800-38A §B.2): millisecond time-stamp for nonce in 1st 8 bytes,
  // block counter in 2nd 8 bytes
  var counterBlock = new Array(blockSize);
  var nonce = (new Date()).getTime();  // timestamp: milliseconds since 1-Jan-1970
  var nonceSec = Math.floor(nonce/1000);
  var nonceMs = nonce%1000;
  // encode nonce with seconds in 1st 4 bytes, and (repeated) ms part filling 2nd 4 bytes
  for (var i=0; i<4; i++) counterBlock[i] = (nonceSec >>> i*8) & 0xff;
  for (var i=0; i<4; i++) counterBlock[i+4] = nonceMs & 0xff;
  // and convert it to a string to go on the front of the ciphertext
  var ctrTxt = '';
  for (var i=0; i<8; i++) ctrTxt += String.fromCharCode(counterBlock[i]);

  // generate key schedule - an expansion of the key into distinct Key Rounds for each round
  var keySchedule = Aes.keyExpansion(key);

  var blockCount = Math.ceil(plaintext.length/blockSize);
  var ciphertxt = new Array(blockCount);  // ciphertext as array of strings

  for (var b=0; b<blockCount; b++) {
    // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
    // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB)
    for (var c=0; c<4; c++) counterBlock[15-c] = (b >>> c*8) & 0xff;
    for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8)

    var cipherCntr = Aes.cipher(counterBlock, keySchedule);  // -- encrypt counter block --

    // block size is reduced on final block
    var blockLength = b<blockCount-1 ? blockSize : (plaintext.length-1)%blockSize+1;
    var cipherChar = new Array(blockLength);

    for (var i=0; i<blockLength; i++) {  // -- xor plaintext with ciphered counter char-by-char --
      cipherChar[i] = cipherCntr[i] ^ plaintext.charCodeAt(b*blockSize+i);
      cipherChar[i] = String.fromCharCode(cipherChar[i]);
    }
    ciphertxt[b] = cipherChar.join('');
  }

  // Array.join is more efficient than repeated string concatenation in IE
  var ciphertext = ctrTxt + ciphertxt.join('');
  ciphertext = Base64.encode(ciphertext);  // encode in base64

  //alert((new Date()) - t);
  return ciphertext;
}

/**
 * Decrypt a text encrypted by AES in counter mode of operation
 *
 * @param {String} ciphertext Source text to be encrypted
 * @param {String} password   The password to use to generate a key
 * @param {Number} nBits      Number of bits to be used in the key (128, 192, or 256)
 * @returns {String}          Decrypted text
 */
Aes.Ctr.decrypt = function(ciphertext, password, nBits) {
  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
  if (!(nBits==128 || nBits==192 || nBits==256)) return '';  // standard allows 128/192/256 bit keys
  ciphertext = Base64.decode(ciphertext);
  password = Utf8.encode(password);
  //var t = new Date();  // timer

  // use AES to encrypt password (mirroring encrypt routine)
  var nBytes = nBits/8;  // no bytes in key
  var pwBytes = new Array(nBytes);
  for (var i=0; i<nBytes; i++) {
    pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
  }
  var key = Aes.cipher(pwBytes, Aes.keyExpansion(pwBytes));
  key = key.concat(key.slice(0, nBytes-16));  // expand key to 16/24/32 bytes long

  // recover nonce from 1st 8 bytes of ciphertext
  var counterBlock = new Array(8);
  ctrTxt = ciphertext.slice(0, 8);
  for (var i=0; i<8; i++) counterBlock[i] = ctrTxt.charCodeAt(i);

  // generate key schedule
  var keySchedule = Aes.keyExpansion(key);

  // separate ciphertext into blocks (skipping past initial 8 bytes)
  var nBlocks = Math.ceil((ciphertext.length-8) / blockSize);
  var ct = new Array(nBlocks);
  for (var b=0; b<nBlocks; b++) ct[b] = ciphertext.slice(8+b*blockSize, 8+b*blockSize+blockSize);
  ciphertext = ct;  // ciphertext is now array of block-length strings

  // plaintext will get generated block-by-block into array of block-length strings
  var plaintxt = new Array(ciphertext.length);

  for (var b=0; b<nBlocks; b++) {
    // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
    for (var c=0; c<4; c++) counterBlock[15-c] = ((b) >>> c*8) & 0xff;
    for (var c=0; c<4; c++) counterBlock[15-c-4] = (((b+1)/0x100000000-1) >>> c*8) & 0xff;

    var cipherCntr = Aes.cipher(counterBlock, keySchedule);  // encrypt counter block

    var plaintxtByte = new Array(ciphertext[b].length);
    for (var i=0; i<ciphertext[b].length; i++) {
      // -- xor plaintxt with ciphered counter byte-by-byte --
      plaintxtByte[i] = cipherCntr[i] ^ ciphertext[b].charCodeAt(i);
      plaintxtByte[i] = String.fromCharCode(plaintxtByte[i]);
    }
    plaintxt[b] = plaintxtByte.join('');
  }

  // join array of blocks into single plaintext string
  var plaintext = plaintxt.join('');
  plaintext = Utf8.decode(plaintext);  // decode from UTF8 back to Unicode multi-byte chars

  //alert((new Date()) - t);
  return plaintext;
}


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  Base64 class: Base 64 encoding / decoding (c) Chris Veness 2002-2010                          */
/*    note: depends on Utf8 class                                                                 */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

var Base64 = {};  // Base64 namespace

Base64.code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

/**
 * Encode string into Base64, as defined by RFC 4648 [http://tools.ietf.org/html/rfc4648]
 * (instance method extending String object). As per RFC 4648, no newlines are added.
 *
 * @param {String} str The string to be encoded as base-64
 * @param {Boolean} [utf8encode=false] Flag to indicate whether str is Unicode string to be encoded
 *   to UTF8 before conversion to base64; otherwise string is assumed to be 8-bit characters
 * @returns {String} Base64-encoded string
 */
Base64.encode = function(str, utf8encode) {  // http://tools.ietf.org/html/rfc4648
  utf8encode =  (typeof utf8encode == 'undefined') ? false : utf8encode;
  var o1, o2, o3, bits, h1, h2, h3, h4, e=[], pad = '', c, plain, coded;
  var b64 = Base64.code;

  plain = utf8encode ? str.encodeUTF8() : str;

  c = plain.length % 3;  // pad string to length of multiple of 3
  if (c > 0) { while (c++ < 3) { pad += '='; plain += '\0'; } }
  // note: doing padding here saves us doing special-case packing for trailing 1 or 2 chars

  for (c=0; c<plain.length; c+=3) {  // pack three octets into four hexets
    o1 = plain.charCodeAt(c);
    o2 = plain.charCodeAt(c+1);
    o3 = plain.charCodeAt(c+2);

    bits = o1<<16 | o2<<8 | o3;

    h1 = bits>>18 & 0x3f;
    h2 = bits>>12 & 0x3f;
    h3 = bits>>6 & 0x3f;
    h4 = bits & 0x3f;

    // use hextets to index into code string
    e[c/3] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
  }
  coded = e.join('');  // join() is far faster than repeated string concatenation in IE

  // replace 'A's from padded nulls with '='s
  coded = coded.slice(0, coded.length-pad.length) + pad;

  return coded;
}

/**
 * Decode string from Base64, as defined by RFC 4648 [http://tools.ietf.org/html/rfc4648]
 * (instance method extending String object). As per RFC 4648, newlines are not catered for.
 *
 * @param {String} str The string to be decoded from base-64
 * @param {Boolean} [utf8decode=false] Flag to indicate whether str is Unicode string to be decoded
 *   from UTF8 after conversion from base64
 * @returns {String} decoded string
 */
Base64.decode = function(str, utf8decode) {
  utf8decode =  (typeof utf8decode == 'undefined') ? false : utf8decode;
  var o1, o2, o3, h1, h2, h3, h4, bits, d=[], plain, coded;
  var b64 = Base64.code;

  coded = utf8decode ? str.decodeUTF8() : str;


  for (var c=0; c<coded.length; c+=4) {  // unpack four hexets into three octets
    h1 = b64.indexOf(coded.charAt(c));
    h2 = b64.indexOf(coded.charAt(c+1));
    h3 = b64.indexOf(coded.charAt(c+2));
    h4 = b64.indexOf(coded.charAt(c+3));

    bits = h1<<18 | h2<<12 | h3<<6 | h4;

    o1 = bits>>>16 & 0xff;
    o2 = bits>>>8 & 0xff;
    o3 = bits & 0xff;

    d[c/4] = String.fromCharCode(o1, o2, o3);
    // check for padding
    if (h4 == 0x40) d[c/4] = String.fromCharCode(o1, o2);
    if (h3 == 0x40) d[c/4] = String.fromCharCode(o1);
  }
  plain = d.join('');  // join() is far faster than repeated string concatenation in IE

  return utf8decode ? plain.decodeUTF8() : plain;
}


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  Utf8 class: encode / decode between multi-byte Unicode characters and UTF-8 multiple          */
/*              single-byte character encoding (c) Chris Veness 2002-2010                         */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

var Utf8 = {};  // Utf8 namespace

/**
 * Encode multi-byte Unicode string into utf-8 multiple single-byte characters
 * (BMP / basic multilingual plane only)
 *
 * Chars in range U+0080 - U+07FF are encoded in 2 chars, U+0800 - U+FFFF in 3 chars
 *
 * @param {String} strUni Unicode string to be encoded as UTF-8
 * @returns {String} encoded string
 */
Utf8.encode = function(strUni) {
  // use regular expressions & String.replace callback function for better efficiency
  // than procedural approaches
  var strUtf = strUni.replace(
      /[\u0080-\u07ff]/g,  // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz
      function(c) {
        var cc = c.charCodeAt(0);
        return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); }
    );
  strUtf = strUtf.replace(
      /[\u0800-\uffff]/g,  // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz
      function(c) {
        var cc = c.charCodeAt(0);
        return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); }
    );
  return strUtf;
}

/**
 * Decode utf-8 encoded string back into multi-byte Unicode characters
 *
 * @param {String} strUtf UTF-8 string to be decoded back to Unicode
 * @returns {String} decoded string
 */
Utf8.decode = function(strUtf) {
  // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char!
  var strUni = strUtf.replace(
      /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g,  // 3-byte chars
      function(c) {  // (note parentheses for precence)
        var cc = ((c.charCodeAt(0)&0x0f)<<12) | ((c.charCodeAt(1)&0x3f)<<6) | ( c.charCodeAt(2)&0x3f);
        return String.fromCharCode(cc); }
    );
  strUni = strUni.replace(
      /[\u00c0-\u00df][\u0080-\u00bf]/g,                 // 2-byte chars
      function(c) {  // (note parentheses for precence)
        var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f;
        return String.fromCharCode(cc); }
    );
  return strUni;
}

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */


var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();
var hWndEdit = AkelPad.GetEditWnd();

if(hMainWnd && !AkelPad.GetEditReadOnly(hWndEdit))
	encryptOrDecrypt();

function encryptOrDecrypt(pass) {
	var text = AkelPad.GetSelText();
	var selectAll = false;
	if(!text) {
		text = getAllText();
		if(!text) {
			var msg = _localize("Nothing to " + (decrypt ? "decrypt" : "encrypt") + "!");
			AkelPad.MessageBox(hMainWnd, msg, WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);
			return;
		}
		selectAll = true;
	}

	if(mode == MODE_USER_SELECT) {
		var dirObj = { value: isBase64(text) };
		var pass = passwordPrompt(WScript.ScriptName, _localize("Password"), true, dirObj);
		if(!pass) // Cancel
			return;
		decrypt = dirObj.value;
	}

	if(decrypt) {
		//if(maxLineWidth > 0)
		text = text.replace(/[\n\r]+/g, "");
		if(!isBase64(text)) {
			AkelPad.MessageBox(
				hMainWnd,
				_localize("Impossible to decrypt: invalid format!"),
				WScript.ScriptName,
				16 /*MB_ICONERROR*/
			);
			return;
		}
	}

	if(!pass)
		pass = passwordPrompt(WScript.ScriptName, _localize(decrypt ? "Decrypt" : "Encrypt"), true);
	if(!pass) // Cancel
		return;

	var res = Aes.Ctr[decrypt ? "decrypt" : "encrypt"](text, pass, 256);
	if(!decrypt && maxLineWidth > 0)
		res = res.replace(new RegExp(".{" + maxLineWidth + "}", "g"), "$&\n");

	insertNoScroll(res, selectAll);
}
function isBase64(str) {
	str = str.replace(/[\n\r]+/g, "");
	return str.length % 4 == 0 && !/[^a-zA-Z0-9+\/]/.test(str.replace(/=+$/, ""));
}

function passwordPrompt(caption, label, modal, direction) {
	var hInstanceDLL = AkelPad.GetInstanceDll();
	var dialogClass = "AkelPad::Scripts::" + WScript.ScriptName + "::" + oSys.Call("kernel32::GetCurrentProcessId");

	// Note: "modal" argument is always true now and following should not happens
	var hWndDialog = oSys.Call("user32::FindWindowEx" + _TCHAR, 0, 0, dialogClass, 0);
	if(hWndDialog) {
		if(oSys.Call("user32::IsIconic", hWndDialog))
			oSys.Call("user32::ShowWindow", hWndDialog, 9 /*SW_RESTORE*/);
		AkelPad.SendMessage(hWndDialog, 7 /*WM_SETFOCUS*/, 0, 0);
		return null;
	}

	if(
		!AkelPad.WindowRegisterClass(dialogClass)
		&& ( // Previous script instance crashed
			!AkelPad.WindowUnregisterClass(dialogClass)
			|| !AkelPad.WindowRegisterClass(dialogClass)
		)
	)
		return null;

	var pass;
	var lpBuffer = AkelPad.MemAlloc(256 * _TSIZE);
	if(!lpBuffer)
		return null;

	var IDC_STATIC      = -1;
	var IDC_ENCRYPT     = 1001;
	var IDC_DECRYPT     = 1002;
	var IDC_PASS        = 1003;
	var IDC_PASS2       = 1004;
	var IDC_PASS2_LABEL = 1005;
	var IDC_SHOWPASS    = 1006;
	var IDC_OK          = 1007;
	var IDC_CANCEL      = 1008;

	var hWndGroupMode, hWndEncrypt, hWndDecrypt;
	var hWndGroup, hWndPassLabel, hWndPass, hWndPass2Label, hWndPass2, hWndShowPass;
	var hWndOK, hWndCancel;

	var addY = direction ? 54 : 0;
	var p2h = direction || !decrypt ? 0 : 52;

	var scale = new Scale(0, hMainWnd);
	var sizeNonClientX = oSys.Call("user32::GetSystemMetrics", 7 /*SM_CXFIXEDFRAME*/)*2;
	var sizeNonClientY = oSys.Call("user32::GetSystemMetrics", 8 /*SM_CYFIXEDFRAME*/)*2
		+ oSys.Call("user32::GetSystemMetrics", 4 /*SM_CYCAPTION*/);

	// Create dialog
	hWndDialog = oSys.Call(
		"user32::CreateWindowEx" + _TCHAR,
		0,                                          //dwExStyle
		dialogClass,                                //lpClassName
		0,                                          //lpWindowName
		0x90CA0000,                                 //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
		scale.x(0),                                 //x
		scale.y(0),                                 //y
		scale.x(252) + sizeNonClientX,              //nWidth
		scale.y(214 + addY - p2h) + sizeNonClientY, //nHeight
		hMainWnd,                                   //hWndParent
		0,                                          //ID
		hInstanceDLL,                               //hInstance
		dialogCallback                              //Script function callback. To use it class must be registered by WindowRegisterClass.
	);
	if(!hWndDialog)
		return null;

	function dialogCallback(hWnd, uMsg, wParam, lParam) {
		switch(uMsg) {
			case 1: //WM_CREATE
				function setWindowFontAndText(hWnd, hFont, pText) {
					AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
					oSys.Call("user32::SetWindowText" + _TCHAR, hWnd, pText.substr(0, 255));
				}

				var hGuiFont = oSys.Call("gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);

				// Dialog caption
				oSys.Call("user32::SetWindowText" + _TCHAR, hWnd, caption);

				if(direction) {
					// GroupBox mode
					hWndGroupMode = createWindowEx(
						0,            //dwExStyle
						"BUTTON",     //lpClassName
						0,            //lpWindowName
						0x50000007,   //WS_VISIBLE|WS_CHILD|BS_GROUPBOX
						14,           //x
						13,           //y
						224,          //nWidth
						44,           //nHeight
						hWnd,         //hWndParent
						IDC_STATIC,   //ID
						hInstanceDLL, //hInstance
						0             //lpParam
					);
					setWindowFontAndText(hWndGroupMode, hGuiFont, _localize("Direction"));

					// Radiobutton encrypt
					hWndEncrypt = createWindowEx(
						0,            //dwExStyle
						"BUTTON",     //lpClassName
						0,            //lpWindowName
						0x50000009,   //WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON
						26,           //x
						33,           //y
						96,           //nWidth
						16,           //nHeight
						hWnd,         //hWndParent
						IDC_ENCRYPT,  //ID
						hInstanceDLL, //hInstance
						0             //lpParam
					);
					setWindowFontAndText(hWndEncrypt, hGuiFont, _localize("&Encrypt"));
					checked(hWndEncrypt, !direction.value);

					// Radiobutton decrypt
					hWndDecrypt = createWindowEx(
						0,            //dwExStyle
						"BUTTON",     //lpClassName
						0,            //lpWindowName
						0x50000009,   //WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON
						128,          //x
						33,           //y
						96,           //nWidth
						16,           //nHeight
						hWnd,         //hWndParent
						IDC_DECRYPT,  //ID
						hInstanceDLL, //hInstance
						0             //lpParam
					);
					setWindowFontAndText(hWndDecrypt, hGuiFont, _localize("&Decrypt"));
					//checked(hWndDecrypt, mode == MODE_DECRYPT);
					checked(hWndDecrypt, direction.value);
				}

				// GroupBox
				hWndGroup = createWindowEx(
					0,            //dwExStyle
					"BUTTON",     //lpClassName
					0,            //lpWindowName
					0x50000007,   //WS_VISIBLE|WS_CHILD|BS_GROUPBOX
					14,           //x
					13 + addY,    //y
					224,          //nWidth
					152 - p2h,    //nHeight
					hWnd,         //hWndParent
					IDC_STATIC,   //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndGroup, hGuiFont, label);

				// Static window: password label
				hWndPassLabel = createWindowEx(
					0,            //dwExStyle
					"STATIC",     //lpClassName
					0,            //lpWindowName
					0x50000000,   //WS_VISIBLE|WS_CHILD
					32,           //x
					35 + addY,    //y
					177,          //nWidth
					13,           //nHeight
					hWnd,         //hWndParent
					IDC_STATIC,   //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndPassLabel, hGuiFont, _localize("Enter &password:"));

				// Edit window: password
				hWndPass = createWindowEx(
					0x200,        //WS_EX_CLIENTEDGE
					"EDIT",       //lpClassName
					0,            //lpWindowName
					0x500100A0,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_PASSWORD
					29,           //x
					53 + addY,    //y
					195,          //nWidth
					23,           //nHeight
					hWnd,         //hWndParent
					IDC_PASS,     //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndPass, hGuiFont, "");

				if(direction || !decrypt) {
					// Static window: password 2 label
					hWndPass2Label = createWindowEx(
						0,               //dwExStyle
						"STATIC",        //lpClassName
						0,               //lpWindowName
						0x50000000,      //WS_VISIBLE|WS_CHILD
						32,              //x
						86 + addY,       //y
						177,             //nWidth
						13,              //nHeight
						hWnd,            //hWndParent
						IDC_PASS2_LABEL, //ID
						hInstanceDLL,    //hInstance
						0                //lpParam
					);
					setWindowFontAndText(hWndPass2Label, hGuiFont, _localize("Reenter p&assword:"));

					// Edit window: password 2
					hWndPass2 = createWindowEx(
						0x200,        //WS_EX_CLIENTEDGE
						"EDIT",       //lpClassName
						0,            //lpWindowName
						0x500100A0,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_PASSWORD
						29,           //x
						104 + addY,   //y
						195,          //nWidth
						23,           //nHeight
						hWnd,         //hWndParent
						IDC_PASS2,    //ID
						hInstanceDLL, //hInstance
						0             //lpParam
					);
					setWindowFontAndText(hWndPass2, hGuiFont, "");
				}

				// Checkbox: show password
				hWndShowPass = createWindowEx(
					0,                //dwExStyle
					"BUTTON",         //lpClassName
					0,                //lpWindowName
					0x50010003,       //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
					32,               //x
					138 + addY - p2h, //y
					177,              //nWidth
					16,               //nHeight
					hWnd,             //hWndParent
					IDC_SHOWPASS,     //ID
					hInstanceDLL,     //hInstance
					0                 //lpParam
				);
				setWindowFontAndText(hWndShowPass, hGuiFont, _localize("&Show password"));
				var sp = showPassword === undefined
					? saveOptions
						? pref("showPassword", 1 /*PO_DWORD*/) == 1
						: false
					: showPassword;
				checked(hWndShowPass, sp);
				setShowPass(sp, direction ? !direction.value : !decrypt);

				// OK button window
				hWndOK = createWindowEx(
					0,                //dwExStyle
					"BUTTON",         //lpClassName
					0,                //lpWindowName
					0x50010001,       //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_DEFPUSHBUTTON
					13,               //x
					178 + addY - p2h, //y
					107,              //nWidth
					23,               //nHeight
					hWnd,             //hWndParent
					IDC_OK,           //ID
					hInstanceDLL,     //hInstance
					0                 //lpParam
				);
				setWindowFontAndText(hWndOK, hGuiFont, _localize("OK"));

				// Cancel button window
				hWndCancel = createWindowEx(
					0,                //dwExStyle
					"BUTTON",         //lpClassName
					0,                //lpWindowName
					0x50010000,       //WS_VISIBLE|WS_CHILD|WS_TABSTOP
					132,              //x
					178 + addY - p2h, //y
					107,              //nWidth
					23,               //nHeight
					hWnd,             //hWndParent
					IDC_CANCEL,       //ID
					hInstanceDLL,     //hInstance
					0                 //lpParam
				);
				setWindowFontAndText(hWndCancel, hGuiFont, _localize("Cancel"));

				oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_PASS, 0);

				//centerWindow(hMainWnd, hWnd);
				centerWindow(null, hWnd);
			break;
			case 7: //WM_SETFOCUS
				var hWndFocus = hWndPass;
				if(direction) {
					if(checked(hWndEncrypt))      hWndFocus = hWndEncrypt;
					else if(checked(hWndDecrypt)) hWndFocus = hWndDecrypt;
				}
				oSys.Call("user32::SetFocus", hWndFocus);
			break;
			case 256: //WM_KEYDOWN
				if(wParam == 27) //VK_ESCAPE
					oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_CANCEL, 0);
				else if(wParam == 13) //VK_RETURN
					oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_OK, 0);
			break;
			case 273: //WM_COMMAND
				switch(wParam & 0xffff) {
					case IDC_OK:
						oSys.Call("user32::GetWindowText" + _TCHAR, hWndPass, lpBuffer, 256);
						var pass1 = AkelPad.MemRead(lpBuffer, _TSTR);
						if(!pass1)
							break;
						var showPass = checked(hWndShowPass);
						var enc = direction ? checked(hWndEncrypt) : !decrypt;
						if(!showPass && enc) {
							oSys.Call("user32::GetWindowText" + _TCHAR, hWndPass2, lpBuffer, 256);
							var pass2 = AkelPad.MemRead(lpBuffer, _TSTR);
							if(pass1 != pass2) {
								AkelPad.MessageBox(
									hWnd,
									_localize("Passwords do not match!"),
									WScript.ScriptName,
									16 /*MB_ICONERROR*/
								);
								break;
							}
						}
						if(direction && !readRadiosState())
							break;
						saveOptions && pref("showPassword", 1 /*PO_DWORD*/, Number(showPass));
						pass = pass1;
						closeDialog();
					break;
					case IDC_CANCEL:
						closeDialog();
					break;
					case IDC_SHOWPASS:
					case IDC_ENCRYPT:
					case IDC_DECRYPT:
						setShowPass(checked(hWndShowPass), direction ? checked(hWndEncrypt) : !decrypt);
					break;
					case IDC_PASS:
					case IDC_PASS2:
						var hasPass = oSys.Call("user32::GetWindowTextLength" + _TCHAR, hWndPass) > 0;
						enabled(hWndOK,    hasPass);
						enabled(hWndPass2, hasPass);
				}
			break;
			case 16: //WM_CLOSE
				modal && enabled(hMainWnd, true); // Enable main window
				oSys.Call("user32::DestroyWindow", hWnd); // Destroy dialog
			break;
			case 2: //WM_DESTROY
				oSys.Call("user32::PostQuitMessage", 0); // Exit message loop
		}
		return 0;
	}
	function centerWindow(hWndParent, hWnd) {
		var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
		if(!lpRect)
			return;
		if(!hWndParent)
			hWndParent = oSys.Call("user32::GetDesktopWindow");
		oSys.Call("user32::GetWindowRect", hWndParent, lpRect);
		var rcWndParent = parseRect(lpRect);
		oSys.Call("user32::GetWindowRect", hWnd, lpRect);
		var rcWnd = parseRect(lpRect);
		var x = rcWndParent.left + ((rcWndParent.right  - rcWndParent.left) / 2 - (rcWnd.right  - rcWnd.left) / 2);
		var y = rcWndParent.top  + ((rcWndParent.bottom - rcWndParent.top)  / 2 - (rcWnd.bottom - rcWnd.top)  / 2);
		oSys.Call("user32::SetWindowPos", hWnd, 0, x, y, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
		AkelPad.MemFree(lpRect);
	}
	function parseRect(lpRect) {
		return {
			left:   AkelPad.MemRead(lpRect,      3 /*DT_DWORD*/),
			top:    AkelPad.MemRead(lpRect +  4, 3 /*DT_DWORD*/),
			right:  AkelPad.MemRead(lpRect +  8, 3 /*DT_DWORD*/),
			bottom: AkelPad.MemRead(lpRect + 12, 3 /*DT_DWORD*/)
		};
	}
	function readRadiosState() {
		if(checked(hWndEncrypt))
			direction.value = false;
		else if(checked(hWndDecrypt))
			direction.value = true;
		else
			return false;
		return true;
	}
	function checked(hWnd, val) {
		return arguments.length == 1
			? AkelPad.SendMessage(hWnd, 240 /*BM_GETCHECK*/, 0, 0)
			: AkelPad.SendMessage(hWnd, 241 /*BM_SETCHECK*/, val ? 1 /*BST_CHECKED*/ : 0, 0);
	}
	function enabled(hWnd, val) {
		oSys.Call("user32::EnableWindow", hWnd, val);
	}
	function showWindow(hWnd, val) {
		oSys.Call("user32::ShowWindow", hWnd, val);
	}
	function closeDialog() {
		oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 16 /*WM_CLOSE*/, 0, 0);
	}
	function setShowPass(showPass, showSecondField) {
		showSecondField = !showPass && showSecondField;
		hWndPass2Label && showWindow(hWndPass2Label, showSecondField);
		hWndPass2      && showWindow(hWndPass2,      showSecondField);
		if(!setShowPass.passChar)
			setShowPass.passChar = AkelPad.SendMessage(hWndPass, 0x00D2/*EM_GETPASSWORDCHAR*/, 0, 0) || 0x002A;
		var passChar = showPass ? 0 : setShowPass.passChar;
		AkelPad.SendMessage(hWndPass, 0x00CC/*EM_SETPASSWORDCHAR*/, passChar, 0);
		oSys.Call("user32::InvalidateRect", hWndPass, 0, 1/*TRUE*/);
	}

	function Scale(hDC, hWnd) {
		var hNewDC = hDC || oSys.Call("user32::GetDC", hWnd);
		if(hNewDC) {
			this._x = oSys.Call("gdi32::GetDeviceCaps", hNewDC, 88 /*LOGPIXELSX*/);
			this._y = oSys.Call("gdi32::GetDeviceCaps", hNewDC, 90 /*LOGPIXELSY*/);

			//Align to 16 pixel
			this._x += (16 - this._x % 16) % 16;
			this._y += (16 - this._y % 16) % 16;

			!hDC && oSys.Call("user32::ReleaseDC", hWnd, hNewDC);

			this.x = function(x) {
				return oSys.Call("kernel32::MulDiv", x, this._x, 96);
			};
			this.y = function(y) {
				return oSys.Call("kernel32::MulDiv", y, this._y, 96);
			};
		}
		else {
			this.x = this.y = function(n) {
				return n;
			};
		}
	}
	function createWindowEx(
		dwExStyle, lpClassName, lpWindowName, dwStyle,
		x, y, w, h,
		hWndParent, id, hInstance, callback
	) {
		return oSys.Call(
			"user32::CreateWindowEx" + _TCHAR,
			dwExStyle,
			lpClassName,
			lpWindowName,
			dwStyle,
			scale.x(x),
			scale.y(y),
			scale.x(w),
			scale.y(h),
			hWndParent,
			id,
			hInstance,
			callback || 0
		);
	}

	modal && enabled(hMainWnd, false); // Disable main window, to make dialog modal

	AkelPad.ScriptNoMutex(); // Allow other scripts running
	AkelPad.WindowGetMessage(); // Message loop

	AkelPad.MemFree(lpBuffer);
	AkelPad.WindowUnregisterClass(dialogClass);
	return pass;
}

function getAllText() {
	if(typeof AkelPad.GetTextRange != "undefined")
		return AkelPad.GetTextRange(0, -1);
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return "";
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	var columnSel = AkelPad.SendMessage(hWndEdit, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
	var ss = AkelPad.GetSelStart();
	var se = AkelPad.GetSelEnd();

	AkelPad.SetSel(0, -1);
	var str = AkelPad.GetSelText();

	AkelPad.SetSel(ss, se);
	columnSel && AkelPad.SendMessage(hWndEdit, 3128 /*AEM_UPDATESEL*/, 0x1 /*AESELT_COLUMNON*/, 0);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	AkelPad.MemFree(lpPoint);
	setRedraw(hWndEdit, true);
	return str;
}
function insertNoScroll(str, selectAll) {
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return;
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	selectAll && AkelPad.SetSel(0, -1);
	//var ss = AkelPad.GetSelStart();
	AkelPad.ReplaceSel(str, true);
	//if(ss != AkelPad.GetSelStart())
	//	AkelPad.SetSel(ss, ss + str.length);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	setRedraw(hWndEdit, true);
	AkelPad.MemFree(lpPoint);
}
function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function pref(name, type, val) {
	var oSet = AkelPad.ScriptSettings();
	if(arguments.length == 3) {
		if(!oSet.Begin(WScript.ScriptBaseName, 0x2 /*POB_SAVE*/))
			return false;
		var ok = oSet.Write(name, type, val);
		oSet.End();
		return ok;
	}
	if(!oSet.Begin(WScript.ScriptBaseName, 0x1 /*POB_READ*/))
		return undefined;
	var ret = oSet.Read(name, type || 1 /*PO_DWORD*/);
	oSet.End();
	return ret;
}
function getArg(argName, defaultVal) {
	var args = {};
	for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
		if(/^[-\/](\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
			args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
	getArg = function(argName, defaultVal) {
		argName = argName.toLowerCase();
		return typeof args[argName] == "undefined" // argName in args
			? defaultVal
			: args[argName];
	};
	return getArg(argName, defaultVal);
}
<download | mirror | development version> (see crypt.js)
Encrypt/decrypt text using AES-256.
It can be very slow, be careful.
Last edited by Infocatcher on Wed May 07, 2014 11:25 am, edited 6 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11213#p11213
// http://infocatcher.ucoz.net/js/akelpad_scripts/insertTag.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/insertTag.js

// (c) Infocatcher 2009-2012, 2014
// version 0.2.6 - 2014-07-28

//===================
// Simplify tags insertion.
// By default ask user for tag and insert
// <tag>{selected_text}</tag>

// Arguments:
//   -bbcode=0                            - Use <tag>
//          =1                            - Use [tag]
//          =-1                           - Autodetection
//   -xmlExts="[sx]html?|mht(ml)?|xml"    - Detect <html>, mask for Coder plugin alias or file extension (for -bbcode=-1)
//   -tagExts='{"": "i", "fb2": "em"}'    - Detect tag by Coder plugin alias or file extension, for %T variable
//                                          "": "i"            - default tag
//                                          "fb2|xhtml?": "em" - regular expression for special files
//                                          "ext": ""          - tag not supported in *.ext files
//   -clip=true                           - Use text from clipboard instead of selected text
//   -selectMode=0                        - Select all inserted text: [<tag>text</tag>]
//              =1                        - Select text inside tags:  <tag>[text]</tag>
//   -tag="div"                           - Don't ask tag, you also can use %T with -tagExts
//   -template='<a href="%%|">%%S</a>'    - Use template (and ignore all other arguments)
//   -saveLastTag=0                       - don't save last used tag
//               =1                       - save only typed (default)
//               =2                       - always save

// Special variables in templates:
//   %|  - selection start or end
//   %S  - selected text
//   %C  - clipboard text
//   %SC - selected text or clipboard text
//   %CS - clipboard text or selected text
//   %T  - tag (detected using -tagExts)

// Usage:
//   Call("Scripts::Main", 1, "insertTag.js")
//   Call("Scripts::Main", 1, "insertTag.js", `-bbcode=1 -tag="quote"`)
//   Call("Scripts::Main", 1, "insertTag.js", `-template='<a href="%%C">%%|%%S%%|</a>'`)
//   Call("Scripts::Main", 1, "insertTag.js", `-bbcode=-1 -tag="%%T" -tagExts='{"": "i", "fb2|xhtml?": "em"}'`)
//===================

function _localize(s) {
	var strings = {
		"Tag or template:": {
			ru: "Тэг или шаблон:"
		},
		"Tag %T not supported!": {
			ru: "Тэг %T не поддерживается!"
		},
		"Tags %T not supported!": {
			ru: "Тэги %T не поддерживаются!"
		}
	};
	var lng = "en";
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

// Read arguments:
// getArg(argName, defaultValue)
var useBBCode    = getArg("bbcode", -1);
var xmlExts      = getArg("xmlExts", "[xs]?html?|mht(ml)?|hta|asp|jsm?|css|xml|axl|dxl|fb2|kml|manifest|msc|ndl|rdf|rss|svg|user|wsdl|xaml|xmp|xsd|xslt?|xul|xbl|resx|v[cbd]proj|csproj|wx[ils]|wixobj|wixout|wixlib|wixpdb|wixmsp|wixmst");
var tagExts      = getArg("tagExts", "");
var useClipboard = getArg("clip", false);
var selectMode   = getArg("selectMode", 0);
var tag          = getArg("tag"); // Override tag prompt
var template     = getArg("template"); // Use template and ignore all arguments except -bbcode=-1 (and -xmlExts)
var saveLastTag  = getArg("saveLastTag", 1);


var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd && !AkelPad.GetEditReadOnly(hWndEdit))
	insertTag();

function insertTag() {
	var txt, ss, se;
	if(template) {
		// Example: <a href="%C">%|%S%|</a>
		if(useBBCode == -1) {
			template = detectBBCode()
				? template.replace(/</g, "[").replace(/>/g, "]")
				: template.replace(/\[/g, "<").replace(/\]/g, ">");
		}

		var rnd = function() {
			return Math.random().toString(36).substr(2) + Math.random().toString(36).substr(2);
		};
		var posMarker = rnd();
		var percent   = rnd();

		var sel  = /%C?S/.test(template) && AkelPad.GetSelText();
		var clip = /%S?C/.test(template) && AkelPad.GetClipboardText();
		if(/%T/.test(template)) {
			var autoTag = detectTag();
			if(tagNotSupported(autoTag))
				return;
		}

		txt = template
			.replace(/%%/g, percent)
			.replace(/%\|/g, posMarker)
			.replace(/%SC/g, sel || clip)
			.replace(/%CS/g, clip || sel)
			.replace(/%S/g, sel)
			.replace(/%C/g, clip)
			.replace(/%T/g, autoTag)
			.replace(new RegExp(percent, "g"), "%");

		var posMarkerRe = new RegExp(posMarker);
		if(posMarkerRe.test(txt)) {
			ss = se = AkelPad.GetSelStart() + RegExp.leftContext.length;
			txt = RegExp.leftContext + RegExp.rightContext;
		}
		if(posMarkerRe.test(txt)) {
			se = AkelPad.GetSelStart() + RegExp.leftContext.length;
			txt = RegExp.leftContext + RegExp.rightContext;
		}
	}
	else {
		txt = useClipboard
			? AkelPad.GetClipboardText()
			: AkelPad.GetSelText();
		var hasTxt = !!txt;

		if(!tag) {
			var tagTyped = true;
			tag = AkelPad.InputBox(
				hMainWnd,
				WScript.ScriptName,
				_localize("Tag or template:"),
				saveLastTag && pref("lastTag", 3 /*PO_STRING*/) || ""
			);
		}
		if(!tag)
			return;
		if(saveLastTag && (tagTyped || saveLastTag == 2))
			pref("lastTag", 3 /*PO_STRING*/, tag);

		if(tagTyped && /%[%|SC]/.test(tag)) {
			template = tag;
			useBBCode = tag.charAt(0) == "[";
			insertTag();
			return;
		}

		if(tagTyped) {
			var first = tag.charAt(0);
			if(first == "<" || first == "[") { // [tag -> tag
				useBBCode = first == "[";
				tag = tag.substr(1);
				if(tag.charAt(tag.length - 1) == (useBBCode ? "]" : ">")) // tag] -> tag
					tag = tag.slice(0, -1);
			}
		}

		if(useBBCode == -1)
			useBBCode = detectBBCode();

		var attrs = /^([^\s=]+)([\s=].*)$/.test(tag) ? RegExp.$2 : "";
		if(attrs)
			tag = RegExp.$1;

		if(/%T/.test(tag)) {
			var autoTag = detectTag();
			if(tagNotSupported(autoTag))
				return;
			tag = tag.replace(/%T/g, autoTag);
		}

		var sTag = (useBBCode ? "["  : "<")  + tag + attrs + (useBBCode ? "]" : ">");
		var eTag = (useBBCode ? "[/" : "</") + tag         + (useBBCode ? "]" : ">");
		txt = sTag + txt + eTag;

		if(!hasTxt || selectMode == 1) {
			var _ss = AkelPad.GetSelStart();
			ss = _ss + sTag.length;
			se = _ss + txt.length - eTag.length;
		}
	}
	insertNoScroll(txt, ss, se);
}
function detectBBCode() {
	return !extPattern(xmlExts).test(getFileType());
}
function detectTag() {
	var patterns = getTagData();
	if(!patterns)
		return undefined;
	var fileType = getFileType();
	for(var exts in patterns)
		if(extPattern(exts).test(fileType))
			return patterns[exts];
	return patterns[""] || undefined;
}
function getTagData() {
	var patterns = tagExts && eval("(" + tagExts + ")");
	getTagData = function() {
		return patterns;
	};
	return patterns;
}
function tagNotSupported(tag) {
	if(!tag) {
		var tags = [];
		var patterns = getTagData();
		if(patterns) for(var exts in patterns)
			if(patterns[exts])
				tags.push(patterns[exts]);
		AkelPad.MessageBox(
			hMainWnd,
			_localize(tags.length > 1 ? "Tags %T not supported!" : "Tag %T not supported!")
				.replace("%T", tags.join(", ")),
			WScript.ScriptName,
			48 /*MB_ICONEXCLAMATION*/
		);
	}
	return !tag;
}
function extPattern(exts) {
	return new RegExp("\\.(" + exts + ")$", "i");
}
function getFileType() {
	var fileType = getCoderAlias() || AkelPad.GetEditFile(0);
	getFileType = function() {
		return fileType;
	};
	return fileType;
}
function getCoderAlias() {
	if(
		!AkelPad.IsPluginRunning("Coder::HighLight")
		&& !AkelPad.IsPluginRunning("Coder::CodeFold")
		&& !AkelPad.IsPluginRunning("Coder::AutoComplete")
	)
		return "";
	// http://akelpad.sourceforge.net/forum/viewtopic.php?p=19363#p19363
	var hWndEdit = AkelPad.GetEditWnd();
	var hDocEdit = AkelPad.GetEditDoc();
	var pAlias = "";
	if(hWndEdit && hDocEdit) {
		var lpAlias = AkelPad.MemAlloc(256 * 2 /*sizeof(wchar_t)*/);
		if(lpAlias) {
			AkelPad.CallW("Coder::Settings", 18 /*DLLA_CODER_GETALIAS*/, hWndEdit, hDocEdit, lpAlias, 0);
			pAlias = AkelPad.MemRead(lpAlias, 1 /*DT_UNICODE*/);
			AkelPad.MemFree(lpAlias);
		}
	}
	return pAlias;
}

function insertNoScroll(str, ss, se) {
	var nFirstLine = saveLineScroll(hWndEdit);

	//var ss = AkelPad.GetSelStart();
	AkelPad.ReplaceSel(str, true);
	//if(ss != AkelPad.GetSelStart())
	//	AkelPad.SetSel(ss, ss + str.length);

	if(ss != undefined || se != undefined) {
		if(ss == undefined) ss = AkelPad.GetSelStart();
		if(se == undefined) se = AkelPad.GetSelEnd();
		AkelPad.SetSel(ss, se);
	}

	restoreLineScroll(hWndEdit, nFirstLine);
}
// From Instructor's SearchReplace.js
function saveLineScroll(hWnd)
{
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, false, 0);
	return AkelPad.SendMessage(hWnd, 3129 /*AEM_GETLINENUMBER*/, 4 /*AEGL_FIRSTVISIBLELINE*/, 0);
}
function restoreLineScroll(hWnd, nBeforeLine)
{
	if (AkelPad.SendMessage(hWnd, 3129 /*AEM_GETLINENUMBER*/, 4 /*AEGL_FIRSTVISIBLELINE*/, 0) != nBeforeLine)
	{
		var lpScrollPos;
		var nPosY=AkelPad.SendMessage(hWnd, 3198 /*AEM_VPOSFROMLINE*/, 0 /*AECT_GLOBAL*/, nBeforeLine);

		if (lpScrollPos=AkelPad.MemAlloc(_X64?16:8 /*sizeof(POINT64)*/))
		{
			AkelPad.MemCopy(lpScrollPos + 0 /*offsetof(POINT64, x)*/, -1, 2 /*DT_QWORD*/);
			AkelPad.MemCopy(lpScrollPos + (_X64?8:4) /*offsetof(POINT64, y)*/, nPosY, 2 /*DT_QWORD*/);
			AkelPad.SendMessage(hWnd, 3180 /*AEM_SETSCROLLPOS*/, 0, lpScrollPos);
			AkelPad.MemFree(lpScrollPos);
		}
	}
	AkelPad.SendMessage(hWnd, 3377 /*AEM_UPDATECARET*/, 0, 0);
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, true, 0);
	oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}

function getArg(argName, defaultVal) {
	var args = {};
	for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
		if(/^[-\/](\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
			args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
	getArg = function(argName, defaultVal) {
		argName = argName.toLowerCase();
		return typeof args[argName] == "undefined" // argName in args
			? defaultVal
			: args[argName];
	};
	return getArg(argName, defaultVal);
}
function pref(name, type, val) {
	var oSet = AkelPad.ScriptSettings();
	if(arguments.length == 3) {
		if(!oSet.Begin(WScript.ScriptBaseName, 0x2 /*POB_SAVE*/))
			return false;
		var ok = oSet.Write(name, type, val);
		oSet.End();
		return ok;
	}
	if(!oSet.Begin(WScript.ScriptBaseName, 0x1 /*POB_READ*/))
		return undefined;
	var ret = oSet.Read(name, type || 1 /*PO_DWORD*/);
	oSet.End();
	return ret;
}
<download | mirror | development version>
Simplify tags insertion.
By default ask user for tag and insert
<tag>{selected_text}</tag>
Last edited by Infocatcher on Mon Jul 28, 2014 1:51 pm, edited 6 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11240#p11240

// (c) Infocatcher 2008, 2011-2012
// version 0.1.2 - 2012-12-11

var map = {
	"à": "a",
	"À": "A",
	"á": "a",
	"Á": "A",
	"â": "a",
	"Â": "A",
	"ã": "a",
	"Ã": "A",
	"ä": "a",
	"Ä": "A",
	"å": "a",
	"Å": "A",
	"æ": "ae",
	"Æ": "AE",
	"ç": "c",
	"Ç": "C",
	"È": "E",
	"è": "e",
	"é": "e",
	"É": "E",
	"ê": "e",
	"Ê": "E",
	"ë": "e",
	"Ë": "E",
	"Ì": "I",
	"ì": "i",
	"í": "i",
	"Í": "I",
	"î": "i",
	"Î": "I",
	"Ï": "I",
	"ï": "i",
	"Ð": "D",
	"ð": "d",
	"ñ": "n",
	"Ñ": "N",
	"Ò": "O",
	"ò": "o",
	"Ó": "O",
	"Ó": "O",
	"ó": "o",
	"ó": "o",
	"ô": "o",
	"Ô": "O",
	"Õ": "O",
	"õ": "o",
	"ö": "o",
	"Ö": "O",
	"ù": "u",
	"Ù": "U",
	"Ú": "U",
	"ú": "u",
	"û": "u",
	"Û": "U",
	"ü": "u",
	"Ü": "U",
	"ý": "y",
	"Ý": "Y",
	"ÿ": "y",
	"Ÿ": "Y",
	"ā": "a",
	"Ā": "A",
	"ă": "a",
	"Ă": "A",
	"Ą": "A",
	"Ą": "A",
	"ą": "a",
	"ą": "a",
	"Ć": "C",
	"ć": "c",
	"Ć": "C",
	"ć": "c",
	"ĉ": "c",
	"Ĉ": "C",
	"Ċ": "C",
	"ċ": "c",
	"č": "c",
	"Č": "C",
	"ď": "d",
	"Ď": "D",
	"Đ": "D",
	"đ": "d",
	"Ē": "E",
	"ē": "e",
	"ĕ": "e",
	"Ĕ": "E",
	"ė": "e",
	"Ė": "E",
	"ę": "e",
	"Ę": "E",
	"Ę": "E",
	"ę": "e",
	"Ě": "E",
	"ě": "e",
	"ĝ": "g",
	"Ĝ": "G",
	"ğ": "g",
	"Ğ": "G",
	"ġ": "g",
	"Ġ": "G",
	"ģ": "g",
	"Ģ": "G",
	"Ĥ": "H",
	"ĥ": "h",
	"ħ": "h",
	"Ħ": "H",
	"ĩ": "i",
	"Ĩ": "I",
	"ī": "i",
	"Ī": "I",
	"Ĭ": "I",
	"ĭ": "i",
	"Į": "I",
	"į": "i",
	"İ": "I",
	"ı": "i",
	"ij": "ij",
	"IJ": "IJ",
	"ĵ": "j",
	"Ĵ": "J",
	"ķ": "k",
	"Ķ": "K",
	"ĸ": "k",
	"ĺ": "l",
	"Ĺ": "L",
	"Ļ": "L",
	"ļ": "l",
	"Ľ": "L",
	"ľ": "l",
	"Ŀ": "L",
	"ŀ": "l",
	"Ł": "L",
	"ł": "l",
	"Ł": "L",
	"ł": "l",
	"ń": "n",
	"Ń": "N",
	"ń": "n",
	"Ń": "N",
	"ņ": "n",
	"Ņ": "N",
	"ň": "n",
	"Ň": "N",
	"ʼn": "n",
	"Ō": "O",
	"ō": "o",
	"Ŏ": "O",
	"ŏ": "o",
	"ő": "o",
	"Ő": "O",
	"œ": "oe",
	"Œ": "OE",
	"Ŕ": "R",
	"ŕ": "r",
	"ŗ": "r",
	"Ŗ": "R",
	"ř": "r",
	"Ř": "R",
	"Ś": "S",
	"ś": "s",
	"ś": "s",
	"Ś": "S",
	"ŝ": "s",
	"Ŝ": "S",
	"ş": "s",
	"Ş": "S",
	"š": "s",
	"Š": "S",
	"Ţ": "T",
	"ţ": "t",
	"ť": "t",
	"Ť": "T",
	"ŧ": "t",
	"Ŧ": "T",
	"ũ": "u",
	"Ũ": "U",
	"Ū": "U",
	"ū": "u",
	"ŭ": "u",
	"Ŭ": "U",
	"ů": "u",
	"Ů": "U",
	"Ű": "U",
	"ű": "u",
	"Ų": "U",
	"ų": "u",
	"ŵ": "w",
	"Ŵ": "W",
	"ŷ": "Y",
	"Ŷ": "Y",
	"Ź": "Z",
	"Ź": "Z",
	"ź": "z",
	"ź": "z",
	"ż": "z",
	"Ż": "Z",
	"Ż": "Z",
	"ż": "z",
	"ž": "z",
	"Ž": "Z",
	"ƀ": "b",
	"ƈ": "c",
	"Ƈ": "C",
	"ƒ": "f",
	"Ƒ": "F",
	"Ƙ": "K",
	"ƙ": "k",
	"ơ": "o",
	"Ơ": "O",
	"ƥ": "p",
	"Ƥ": "P",
	"ƫ": "t",
	"ƭ": "t",
	"Ƭ": "T",
	"Ư": "U",
	"ư": "u",
	"Ƶ": "Z",
	"ƶ": "z",
	"DŽ": "DZ",
	"Dž": "Dz",
	"dž": "dz",
	"Lj": "Lj",
	"LJ": "LJ",
	"lj": "lj",
	"Nj": "Nj",
	"nj": "nj",
	"NJ": "NJ",
	"ǎ": "a",
	"Ǎ": "A",
	"ǐ": "i",
	"Ǐ": "I",
	"Ǒ": "O",
	"ǒ": "o",
	"Ǔ": "U",
	"ǔ": "u",
	"ǖ": "u",
	"Ǖ": "U",
	"ǘ": "u",
	"Ǘ": "U",
	"Ǚ": "U",
	"ǚ": "u",
	"Ǜ": "U",
	"ǜ": "u",
	"ǝ": "e",
	"ǟ": "a",
	"Ǟ": "A",
	"ǡ": "a",
	"Ǡ": "A",
	"ǣ": "ae",
	"Ǣ": "AE",
	"ǥ": "g",
	"Ǥ": "G",
	"ǧ": "g",
	"Ǧ": "G",
	"ǩ": "k",
	"Ǩ": "K",
	"ǫ": "o",
	"Ǫ": "O",
	"ǭ": "o",
	"Ǭ": "O",
	"Ǯ": "Z",
	"ǰ": "J",
	"ǯ": "z",
	"DZ": "DZ",
	"Dz": "Dz",
	"dz": "dz",
	"Ǵ": "G",
	"ǵ": "g",
	"Ǻ": "A",
	"ǻ": "a",
	"Ǽ": "AE",
	"ǽ": "ae",
	"Ǿ": "O",
	"ǿ": "o",
	"Ȁ": "A",
	"ȁ": "a",
	"Ȃ": "A",
	"ȃ": "a",
	"Ȅ": "E",
	"ȅ": "e",
	"Ȇ": "E",
	"ȇ": "e",
	"ȉ": "i",
	"Ȉ": "I",
	"Ȋ": "I",
	"ȋ": "i",
	"Ȍ": "O",
	"ȍ": "o",
	"ȏ": "o",
	"Ȏ": "O",
	"Ȑ": "R",
	"ȑ": "r",
	"Ȓ": "R",
	"ȓ": "r",
	"ȕ": "u",
	"Ȕ": "U",
	"ȗ": "u",
	"Ȗ": "U",
	"ɐ": "a",
	"ɑ": "a",
	"ɒ": "a",
	"Ɓ": "B",
	"Ɖ": "D",
	"ɖ": "d",
	"Ɗ": "D",
	"ɗ": "d",
	"ɛ": "e",
	"Ɠ": "G",
	"Ʀ": "R",
	"Ʈ": "T",
	"ʤ": "dz",
	"ʣ": "dz",
	"ʥ": "dz",
	"ʦ": "ts",
	"ʧ": "tf",
	"ΐ": "i",
	"Ά": "A",
	"Έ": "E",
	"Ή": "H",
	"Ί": "I",
	"ϊ": "i",
	"ϋ": "u",
	"Ό": "O",
	"ό": "o",
	"ύ": "u",
	"Ύ": "Y",
	"і": "i",
	"ї": "i",
	"ј": "j",
	"ќ": "k",
	"ў": "y",
	"ӑ": "a",
	"Ӑ": "A",
	"Ӓ": "A",
	"ӓ": "a",
	"ӕ": "ae",
	"Ӕ": "AE",
	"Ӗ": "E",
	"ӗ": "e"
};

function replaceLetters(str) {
	for(var s in map)
		str = str.replace(new RegExp(s, "g"), map[s]);
	return str;
}

var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd && !AkelPad.GetEditReadOnly(hWndEdit)) {
	var text = AkelPad.GetSelText();
	if(!text) {
		var selectAll = true;
		text = AkelPad.GetTextRange(0, -1);
	}
	var res = replaceLetters(text);
	if(res != text)
		insertNoScroll(res, selectAll);
}

function insertNoScroll(str, selectAll) {
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return;
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	selectAll && AkelPad.SetSel(0, -1);
	//var ss = AkelPad.GetSelStart();
	AkelPad.ReplaceSel(str, true);
	//if(ss != AkelPad.GetSelStart())
	//	AkelPad.SetSel(ss, ss + str.length);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	setRedraw(hWndEdit, true);
	AkelPad.MemFree(lpPoint);
}
function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download>
Updated version of old script.
Last edited by Infocatcher on Tue Dec 11, 2012 5:14 pm, edited 1 time in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

jsBeautifier.js <download | development version>
JavaScript unpacker and beautifier, based on code from https://beautifier.io/.
Additionally can unpack HTML with scripts and styles inside.

File is too big and can't be placed here.
Alternative download: Infocatcher.zip (all in one).
Last edited by Infocatcher on Sat Sep 21, 2019 7:02 pm, edited 49 times in total.

Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

Code: Select all

' OpenFileNameFromBuffer.vbs
'========================   Описание   =====================================
' Открыть файл, имя/путь которого, находится в выделении или в буфере обмена
' - можно скопировать/выделить кнопку/пункт меню AkelPad, Total Commander ...
' - можно скопировать/выделить пути с абсолютными именами
' - можно скопировать/выделить строку со всяким "лишним мусором" в котором есть имя/путь для открытия
' (если ни в выделении, ни в буфере ничего нет ничего подходящего - поиск имени производится во всей строке...)
'====================  Как работает скрипт  ================================
' из выделенной/отправленной в буфер строки извлекается имя/путь скрипта/файла
' и далее имя проверяется в указанных папках и открывается в AkelPad
' (если такого нет в папках - выдаётся сообщение
'=======================  Дополнение =======================================
' Вы можете удалить/внести свои условия/адреса поиска в скрипте
' используется Functions.vbs, который следует положить ...AkelFiles\Plugs\Scripts\Include\
'=========================    Пример    ====================================
' -"Открыть выделенное имя/путь файла или из буфера" Call("Scripts::Main", 1, "OpenFileNameFromBuffer.vbs")

' используется Functions.vbs, который следует положить в ...AkelFiles\Plugs\Scripts\Include\

' Автор:           Аверин Андрей
' Версия:          1.8 (10.10.2010 - 19.08.2012)
' Mail:            Averin-And@yandex.ru
' Site:            http://tc-image.3dn.ru/forum/9-391-1166-16-1333732766
' Site:            http://akelpad.sourceforge.net/forum/viewtopic.php?p=11255#p11255
'===========================================================================
Count = 1 : Call TestingPath

Sub TestingPath
  With AkelPad Text = .GetSelText()
    If Count = 0 Then : Text = ClearNameOrPath(GetLine) : Count = 2 : End If
    If Len(Text) = 0 And Count = 1 Then : Text = .GetClipboardText() : Count = 0 : End If
    If Len(Text) = 0 Then MsBoxErr
    nSelStart = .GetSelStart()
    If InStr(Text, vbNewLine) > 0 Then : sText = Split(Text, vbNewLine) : pText = sText(0) : Else : pText = Text : End If
    Call .Include("Functions.vbs")
  End With
  If CreateObject("Scripting.FileSystemObject").FileExists(pText) Then OpenFF(pText)
  If pText = "TOTALCMD#BAR#DATA" Then pText = sText(1) ' если выделена в буфер кнопка Total Commander
  pText = ClearNameOrPath(pText)
  If Len(pText) = 0 Then Call MsBoxErr
  If InStr(UCase(pText), "AU3") = 0 Then pText = ClearEndLine(pText, "0123456789")
  pText = ReplaceSymPath(pText)

  If Instr(pText, "\") > 0 And Instr(pText, ".") > 0 Then
    If Left(pText, 1) = "%" Then pText = GetPath(pText) ' если путь содержит переменные окружения
    If CreateObject("Scripting.FileSystemObject").FileExists(pText) Then
      OpenFF(pText)
    Else
      If Instr(pText, ".") = InstrRev(pText, ".") Then OpenFF(RunPath(pText)) : Call MsBoxErr
    End If
  Else
    If Instr(pText, ".") = InstrRev(pText, ".") Then OpenFF(RunPath(pText)) : Call MsBoxErr
  End If
End Sub

Sub OpenFF(Name) : Call AkelPad.OpenFile(Name) : Wscript.Quit : End Sub

' функция проверки нахождения имени файла в указанных папках
' удалите ненужные и вставьте свои папки
Function RunPath(FName)
  With AkelPad
    P0 = .GetAkelDir(0) & "\" : P1 = .GetAkelDir(1) & "\" : P2 = .GetAkelDir(2) & "\"
    P4 = .GetAkelDir(4) & "\" : P5 = .GetAkelDir(5) & "\" : P6 = .GetAkelDir(6) & "\" 
  End With
  TC =  GetPath("%COMMANDER_PATH%") & "\" : TCF = TC & "Files\" : TU =  TC & "Utilities\"
  TCFL = TCF & "Lists\" : TCC = TC & "Scripts\" : TCB = TC & "Bar\"
  PT = P4 & "Templates\" : TM = TC & "0\" : TS = TM & "Script_Site\"
  WD = GetPath("%WINDIR%") & "\"
  APath = Array(P0, P0 & "Help", P1 & "List", P2, P4, P4 & "AkelMenu", P4 & "AutoComplete",_
          P4 & "AkelMenu", P4 & "Coder", P4 & "Sessions", P4 & "SpellCheck", P4 & "Templates",_
          PT & "AkelPad", PT & "Asp", PT & "Asp.net", PT & "Assemblers", PT & "Batch",_
          PT & "C-Language", PT & "Css", PT & "Html", PT & "Pascal", PT & "Xml", P5,_
          P5 & "Include", P5 & "Include\win32", P5 & "Params", P5 & "Params\ShowMenuEx",_
          P5 & "Params\ShowMenuAlt", P5 & "ShowMenu", P5 & "win32lib", P6, TC, TC & "Language",_
          TC & "Keys", TCB, TCB & "Bars", TCB & "Bars_Plus", TCB & "Filter", TCF & "ExtProgram", _
          TCB & "Font", TCB & "Rename", TCB & "Search", TCB & "Select", TCB & "Start_Menu", _
          TCF, TCF & "Bat", TCF & "Comands", TCF & "Ncl", TCF & "Tab", TCF & "HTML",_
          TCF & "Help\TCInfo",  TCFL & "Collection", TCFL & "CreateMenu", TCFL & "Lst", _
          TCFL & "MarkerList", TCFL & "MusicList", TCFL & "PathList", TCFL & "Play", _
          TCFL & "ProgramList", TCFL & "ReportList", TCFL & "StatisticFile", _
          TCC & "AddIcons", TCC & "Attributes", TCC & "Buffer", TCC & "Copy", TCC & "CreateBar", _
          TCC & "CreateLists", TCC & "CreateRegistration", TCC & "FileEditing", TCC & "Filters", _
          TCC & "Folders", TCC & "ImageWSH", TCC & "Include", TCC & "Keyboard", TCC & "Link", _
          TCC & "Marker", TCC & "Miscellanea", TCC & "Move", TCC & "Panel", TCC & "Plus", _
          TCC & "ReNames", TCC & "Run", TCC & "Searches", TCC & "SysScript", TCC & "NetWork", _
          TCC & "TextWork", TCC & "Un-Packing", WD, WD & "system32", "c:\MyFiles",_
          TS & "N_V", TS & "S", TS & "V", TU & "Inet\WGet", P1 & "Regs")
  p = 0
  For ii = 0 To Ubound(APath)
    PF = Trim(APath(ii) & "\" & FName)
    If CreateObject("Scripting.FileSystemObject").FileExists(PF) Then : RunPath = PF : p = 1 : Exit For : End If
  Next
  If p = 0 Then MsBoxErr
End Function

Sub MsBoxErr
  If Count = 1 Then
    Call AkelPad.SetSel(nSelStart, nSelStart) : Call TestingPath
  Else
    If Count = 0 Then
      Call TestingPath
    Else
      MsgBox "Ни в выделении ни в буфере обмена" & vbNewLine &_
      "Нет корректного ИМЕНИ / ПУТИ файла для открытия" & vbNewLine &_
      "или такого файла нет в папках, указанных в скрипте" & vbNewLine &_
      "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" & vbNewLine &_
      "Выделите или скопируйте чего-нибудь подходящее" & vbNewLine &_
      "И повторите попытку " , vbApplicationModal & vbExclamation,_
      "Открытие файла, путь/имя которого скопирован или выделен" : Wscript.Quit
    End If
  End If
End Sub



используется: Functions.vbs
Last edited by Andrey_A_A on Thu Sep 13, 2012 2:43 am, edited 2 times in total.

Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

Code: Select all

' DublicateFile.vbs
'========================   Описание   =====================================
' Создание дубликата файла в той же папке и его открытие с добавлением счетчика _N
'
' Call("Scripts::Main", 1, "DublicateFile.vbs")
' предлагаемая горячая клавиша Alt + F5

' Автор:           Аверин Андрей
' Версия:          1.3 (22.11.2010 - 01.05.2012)
' Mail:            Averin-And@yandex.ru
' Site:            http://tc-image.3dn.ru/forum/9-354-1087-16-1333507842
' Site:            http://akelpad.sourceforge.net/forum/viewtopic.php?p=11259#p11259
'===========================================================================
File = AkelPad.GetEditFile(0)
If AkelPad.GetEditWnd() = 0 Or Len(File) = 0 Then WScript.Quit
With CreateObject("Scripting.FileSystemObject")
  Path  = .GetParentFolderName(File) & "\"
  Name = .GetBaseName(File)
  Ext = "." & .GetExtensionName(File)
  FPath = Path  & Name & Ext
  Do While .FileExists(FPath)
      i = i + 1 : FPath = Path & Name & "_" & (i Mod 10) & Ext
  Loop
  If .FileExists(File) Then .CopyFile File, FPath
  AkelPad.OpenFile(FPath)
End With


Иконка к скрипту:

Code: Select all

MIME-Version: 1.0
Content-Type: application/octet-stream; name="DublicateFile.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="DublicateFile.zip"

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
BgAAAAABAAEAPwAAABgJAAAAAA==
Last edited by Andrey_A_A on Thu Sep 13, 2012 2:45 am, edited 2 times in total.

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

Code: Select all

// Description(1033): Deleting block of whitespaces; for other characters - a usual deleting (1 symbol)
// Description(1049): Удаляет пробелы блоками (количество пробелов в блоке берётся из настроек программы)
// 	для других символов - обычное удаление (посимвольно)
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11267#p11267
// Version: 2.2 (2011.01.26)
// 	from 2.0 (2011.01.21)
// Author: VladSh
// Initial version: 1.0 by lexa
// 
// Предлагаемая комбинация клавиш:	Shift+Alt+Backspace

var nPosCurrent = AkelPad.GetSelStart();
if (!nPosCurrent) WScript.Quit();

if (nPosCurrent == AkelPad.GetSelEnd()) {
	var hWndEdit = AkelPad.GetEditWnd();
	var oLine = getBlockLeft(nPosCurrent);
	
	var nTabStop = AkelPad.SendMessage(AkelPad.GetEditWnd(), 3239 /*AEM_GETTABSTOP*/, 0, 0);		//количество пробелов (из настроек)
	var pSpaces = repeat(" ", nTabStop);
	
	var posCursorNew = oLine.len - nTabStop;
	var pPartDel = oLine.text.substr(posCursorNew);		//предполагаемая удаляемая часть
	if (pPartDel != pSpaces)
		posCursorNew = oLine.len - 1;
	var pPartRemain = oLine.text.substr(0, posCursorNew);
	
	var bNoSelEOL = false;
	if (!oLine.start) {
		var fNoSelEOL = "SmartSel::NoSelEOL";
		var bNoSelEOL = AkelPad.IsPluginRunning(fNoSelEOL);
		if (bNoSelEOL) AkelPad.Call(fNoSelEOL);		//Turn OFF
	}
	
	setRedraw(hWndEdit, false);
	AkelPad.SetSel(nPosCurrent - oLine.text.length, nPosCurrent);
	AkelPad.ReplaceSel(pPartRemain);
	setRedraw(hWndEdit, true);
	
	if (bNoSelEOL) AkelPad.Call(fNoSelEOL);		//Turn ON
}
else
	AkelPad.ReplaceSel("");


function repeat(pText, nCount) {
	return (new Array(nCount + 1)).join(pText);
}

function getBlockLeft(nPos) {
	var line = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nPos);
	var index = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/, line, 0);
	if (index == nPos && index != 0) {
		var line = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nPos - 1);
		var index = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/, line, 0);
	}
	var text = AkelPad.GetTextRange(index, nPos);
	
	return {
		text: text,
		start: index,
		len: text.length
	};
}

function setRedraw(hWnd, bRedraw) {
   var oSys = AkelPad.SystemFunction();
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}


Code: Select all

// Description(1033): Removal of the current paragraph by Ctrl+Alt+Y
// Description(1049): Удаление текущего параграфа по Ctrl+Alt+Y
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11267#p11267
// Version: 1.2 (2011.12.12)
// Author: VladSh

if (! AkelPad.Include("selCompleteLine.js")) WScript.Quit();
selCompleteLine(AkelPad.GetSelStart(), AkelPad.GetSelEnd());

AkelPad.Command(4197);
N.B. Скрипт использует selCompleteLine.js.
Last edited by VladSh on Wed Jan 14, 2015 10:02 pm, edited 11 times in total.

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11340#p11340
// Description(1033): Receiving appointed attributes of each line of XML-file
// Description(1049): Вытягивание определённых атрибутов из каждой строки файла с XML-структурой
// Version: 1.8 (2015.04.17)
// Author: VladSh
// 
// Arguments:
// 	см. скрипт ShowMenuEx.js

if (! AkelPad.Include("ShowMenuEx.js")) WScript.Quit();
if (! AkelPad.Include("selCompleteLine.js")) WScript.Quit();

var arrAttr = getSelectedMenuItem(POS_CURSOR, false).split(", ");

//создаём структуру искомых тэгов, перечень которых берём из файла параметров
var structAttr = {};
for (var i = 0, l = arrAttr.length; i < l; i++)
	structAttr[arrAttr[i]] = 1;

var pContent = AkelPad.GetTextRange(0, -1);

//вызываем основную функцию обработчика всего файла
var pContent = processRowText(pContent, /\r\n|\n|\r/);

AkelPad.Call("Log::Output", 4, pContent, -1, 2);


//функция обработки отдельной строки
function processString(rowXML) {
	var pResult = "";
	var aRES = getAttributesValues(rowXML);
	if (aRES != null)
      pResult = aRES.join(", ");
	return pResult
}

function getAttributesValues(sXML) {
	var aXML = sXML.split('"');
	
	var sATTR = "";
	var aRES = [];
	var r = 0;
	
	for (var n = 0; n <= aXML.length; n++) {
		sATTR = aXML[n].replace(/ /g, "");
		sATTR = sATTR.replace(/=/g, "");
		sATTR = sATTR.replace(/</g, "");
		
		if (structAttr[sATTR] == 1) {
			aRES[r] = aXML[n + 1];
			r += 1;
		}
		n += 1;
	}
	
	if (r > 0) return aRES
}

function addToResult(arrOutput, vResult) {
	if (vResult) arrOutput[arrOutput.length] = vResult;
}
NB: Скрипт использует:
- ShowMenuEx.js (для вывода меню наименований атрибутов);
- selCompleteLine.js (для обработки всех строк файла в цикле).

Атрибуты для отбора в файле параметров указываются через ", ", например строка:

Code: Select all

model, posX, posY
Пример XML можно взять здесь.

Благодарности: Infocatcher
Last edited by VladSh on Fri Jun 19, 2015 9:42 pm, edited 10 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11346#p11346
// http://infocatcher.ucoz.net/js/akelpad_scripts/openRelativeFile.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/openRelativeFile.js

// (c) Infocatcher 2011, 2014
// version 0.1.7 - 2014-08-01

//===================
// Tries to open file with relative path
// (will be used system association to open binary files)
// Supports Mozilla's chrome.manifest files (https://developer.mozilla.org/en/chrome_registration)
// Priorities: selected path (if any) or autodetected path (you can just place caret anywhere inside path)

// Usage:
//   Call("Scripts::Main", 1, "openRelativeFile.js")
// Also you can use -showPath argument for debug purposes:
//   Call("Scripts::Main", 1, "openRelativeFile.js", "-showPath=true")
//===================

//== Settings begin
// You can use openRelativeFile-options.js file to override settings

//var paths = ["%ProgramFiles%\\Something"];
var paths = [];

var delimitersStart = {
	'"': true,
	"'": true,
	"<": true,
	"[": true,
	"(": true,
	">": true,
	"=": true,
	"\n": true,
	"\r": true,
	"": true
};
var delimitersEnd = {
	'"': true,
	"'": true,
	">": true,
	"]": true,
	")": true,
	"<": true,
	"\n": true,
	"\r": true,
	"": true
};
var delimitersSpaces = {
	" ": true,
	"\t": true,
	"\n": true,
	"\r": true,
	"\0": true,
	"\u00a0": true, //  
	"\u2002": true, //  
	"\u2003": true, //  
	"\u2009": true //  
};
var delimitersStop = {
	"\n": true,
	"\r": true,
	"\0": true,
	"" : true
};

var maxLength = 2000;
//== Settings end

var optionsPath = WScript.ScriptFullName.replace(/(\.[^.]+)?$/, "-options$&");
if(new ActiveXObject("Scripting.FileSystemObject").FileExists(optionsPath))
	eval(AkelPad.ReadFile(optionsPath));

var showPath = AkelPad.GetArgValue("showPath", false);

var hMainWnd = AkelPad.GetMainWnd();
var fso = new ActiveXObject("Scripting.FileSystemObject");
var wsh = new ActiveXObject("WScript.Shell");

if(hMainWnd)
	openRelative();

function openRelative() {
	var pathStarts = [];
	var pathEnds = [];

	var ss = AkelPad.GetSelStart();
	var se = AkelPad.GetSelEnd();

	if(ss != se) {
		checkPrefix(ss);
		var relPath = decodePathURI(AkelPad.GetSelText());
		if(openRelativePath(relPath))
			return true;
		++ss, --se;
	}

	var cnt = 0;
	for(;;) {
		var chr = --ss < 0 ? "" : AkelPad.GetTextRange(ss, ss + 1);
		if(chr in delimitersSpaces && !pathStarts.length)
			pathStarts.push(ss + 1);
		else if(chr in delimitersStart) {
			pathStarts.push(ss + 1);
			break;
		}
		if(chr in delimitersStop)
			break;
		if(++cnt > maxLength)
			break;
	}
	if(!pathStarts.length)
		return false;

	for(var i = 0, l = pathStarts.length; i < l; ++i)
		if(checkPrefix(pathStarts[i]))
			break;

	cnt = 0;
	for(;;) {
		var chr = AkelPad.GetTextRange(se, ++se);
		if(chr in delimitersSpaces && !pathEnds.length)
			pathEnds.push(se - 1);
		else if(chr in delimitersEnd) {
			pathEnds.push(se - 1);
			break;
		}
		if(chr in delimitersStop)
			break;
		if(++cnt > maxLength)
			break;
	}
	if(!pathEnds.length)
		return false;

	for(var i = Math.max(pathStarts.length, pathEnds.length) - 1; i >= 0; --i) {
		// Use corresponding points: 1 - delimitersStart/End, 0 - delimitersSpaces
		var pathStart = pathStarts[i] || pathStarts[pathStarts.length - 1];
		var pathEnd = pathEnds[i] || pathEnds[pathEnds.length - 1];
		var relPathRaw = AkelPad.GetTextRange(pathStart, pathEnd);
		var relPath = decodePathURI(relPathRaw);
		if(openRelativePath(relPath, pathStart, pathEnd))
			return true;
	}
	return false;
}
function checkPrefix(pathStart) {
	if(pathStart > 0) { // Detect AkelPad.Include()
		var before = AkelPad.GetTextRange(Math.max(0, pathStart - 40), pathStart);
		if(/\bAkelPad\s*\.\s*Include\s*\(\s*["']$/.test(before)) {
			var includeDir = AkelPad.GetAkelDir(6 /*ADTYPE_INCLUDE*/);
			if(arrayIndexOf(paths, includeDir) == -1)
				paths.push(includeDir);
			return true;
		}
	}
	return false;
}
function arrayIndexOf(arr, item) {
	for(var i = 0, l = arr.length; i < l; ++i)
		if(arr[i] === item)
			return i;
	return -1;
}
function openRelativePath(relPath, pathStart, pathEnd) {
	var path;

	var curPath = AkelPad.GetEditFile(0);
	var curDir = fso.GetParentFolderName(curPath);
	var tmp = curDir + "\\" + relPath;
	if(fso.FileExists(tmp))
		path = tmp;
	else {
		tmp = wsh.ExpandEnvironmentStrings(relPath);
		if(fso.FileExists(tmp))
			path = tmp;
		if(!path && /^(chrome|resource):\/\//.test(relPath)) {
			tmp = parseChromePath(curDir, relPath);
			if(tmp)
				path = tmp;
		}
		if(!path && /^\w+:\//.test(relPath)) {
			var tokens = relPath.replace(/^\w+:/, "").split(/[\\\/]+/);
			for(;;) {
				tmp = getFile(curDir, tokens.concat());
				if(tmp) {
					path = tmp;
					break;
				}
				var newDir = getParentDir(curDir);
				if(!newDir || newDir == curDir)
					break;
				curDir = newDir;
			}
		}
		if(!path) {
			for(var i = 0, l = paths.length; i < l; ++i) {
				tmp = wsh.ExpandEnvironmentStrings(paths[i]) + "\\" + relPath;
				if(fso.FileExists(tmp)) {
					path = tmp;
					break;
				}
			}
		}
	}
	if(!path)
		return false;

	if(showPath) {
		var msg = "Relative path:\n" + relPath
			+ "\nDetected path:";
		path = AkelPad.InputBox(hMainWnd, WScript.ScriptName, msg, path);
		if(!path)
			return false;
	}

	if(pathStart && pathEnd)
		AkelPad.SetSel(pathStart, pathEnd);
	if(isFileBinary(path)) // Use system association for binary files
		wsh.Exec('rundll32.exe shell32.dll,ShellExec_RunDLL "' + path + '"');
	else
		AkelPad.OpenFile(path);

	return true;
}
function decodePathURI(path) {
	path = path
		.replace(/^file:\/+/i, "")
		.replace(/[?#].*$/, "");
	try {
		path = decodeURIComponent(path);
	}
	catch(e) {
	}
	return path;
}
function parseChromePath(curDir, chromePath) {
	if(/^(resource):\/+([^\/]+)(\/.*)?/.test(chromePath)) {
		var protocol = RegExp.$1;
		var domain   = RegExp.$2;
		var path     = RegExp.$3;
	}
	else if(/^(\w+):\/+([^\/]+)\/([^\/]+)(\/.*)?/.test(chromePath)) {
		var protocol = RegExp.$1;
		var domain   = RegExp.$2;
		var type     = RegExp.$3;
		var path     = RegExp.$4;
	}
	else
		return false;

	for(;;) { // See https://developer.mozilla.org/en/chrome_registration
		var tmp = curDir + "\\chrome.manifest";
		if(fso.FileExists(tmp)) {
			var manifest = AkelPad.ReadFile(tmp);
			break;
		}
		var newDir = getParentDir(curDir);
		if(!newDir || newDir == curDir)
			return false;
		curDir = newDir;
	}
	if(!manifest)
		return false;

	var pattern;
	switch(protocol) {
		case "chrome":
			switch(type) {
				case "content":
					// content extensionname chrome/content/
					pattern = new RegExp("(^|[\\n\\r])content[ \\t]+" + escapeRegExp(domain) + "[ \\t]+(\\S+)");
				break;
				case "skin":
					// skin extensionname classic/1.0 chrome/skin/
					pattern = new RegExp("(^|[\\n\\r])skin[ \\t]+" + escapeRegExp(domain) + "[ \\t]+\\S+[ \\t]+(\\S+)");
				break;
				case "locale":
					// locale extensionname en-US chrome/locale/en-US/
					pattern = new RegExp("(^|[\\n\\r])locale[ \\t]+" + escapeRegExp(domain) + "[ \\t]+\\S+[ \\t]+(\\S+)");
			}
		break;
		case "resource":
			// resource extensionname resource/
			pattern = new RegExp("(^|[\\n\\r])resource[ \\t]+" + escapeRegExp(domain) + "[ \\t]+(\\S+)");
	}

	if(!pattern)
		return false;

	tmp = getManifestInfo(pattern, manifest, curDir, path);
	if(tmp)
		return tmp;

	// https://developer.mozilla.org/en/chrome_registration#manifest
	var lines = manifest.split(/[\n\r]+/);
	for(var i = 0, l = lines.length; i < l; ++i) {
		var line = lines[i];
		if(!/^manifest[ \t]+(\S+)/.test(line))
			continue;
		var manifestPath = curDir + "\\" + RegExp.$1;
		if(!fso.FileExists(manifestPath))
			continue;
		manifest = AkelPad.ReadFile(manifestPath);
		tmp = getManifestInfo(pattern, manifest, fso.GetParentFolderName(manifestPath), path);
		if(tmp)
			return tmp;
	}

	return false;
}
function getManifestInfo(pattern, manifest, curDir, path) {
	if(!pattern.test(manifest))
		return false;
	var fullPath = curDir + "\\" + unwrapChromePath(RegExp.$2) + path;
	if(fso.FileExists(fullPath))
		return fullPath;
	return false;
}
function unwrapChromePath(path) {
	if(/^jar:/.test(path))
		path = path.substr(4).replace(/[^\/]+!\//, "");
	return path;
}
function escapeRegExp(str) {
	return str.replace(/[\\\/.^$+*?|()\[\]{}]/g, "\\$&");
}
function getFile(curDir, tokens) {
	var parts = [];
	for(;;) {
		parts.unshift(tokens.pop());
		var tmp = curDir + "\\" + parts.join("\\");
		if(fso.FileExists(tmp))
			return tmp;
		if(!tokens.length)
			break;
	}
	return null;
}
function getParentDir(dir) {
	return dir.replace(/[\\\/]+[^\\\/]+$/, "");
}
function isFileBinary(pFile) {
	// Thanks to Instructor
	// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11344#p11344
	var lpDetectCodepage;
	var bResult=false;

	if (lpDetectCodepage=AkelPad.MemAlloc(_X64?24:20 /*sizeof(DETECTCODEPAGEW)*/))
	{
		AkelPad.MemCopy(lpDetectCodepage /*offsetof(DETECTCODEPAGEW, pFile)*/, AkelPad.MemStrPtr(pFile), 2 /*DT_QWORD*/);
		AkelPad.MemCopy(lpDetectCodepage + (_X64?8:4) /*offsetof(DETECTCODEPAGEW, dwBytesToCheck)*/, 1024, 3 /*DT_DWORD*/);
		AkelPad.MemCopy(lpDetectCodepage + (_X64?12:8) /*offsetof(DETECTCODEPAGEW, dwFlags)*/, 0x11 /*ADT_BINARY_ERROR|ADT_NOMESSAGES*/, 3 /*DT_DWORD*/);
		if (AkelPad.SendMessage(hMainWnd, 1177 /*AKD_DETECTCODEPAGEW*/, 0, lpDetectCodepage) == -4 /*EDT_BINARY*/)
			bResult=true;

		AkelPad.MemFree(lpDetectCodepage);
	}
	return bResult;
}
<download | mirror | development version>
Tries to open file with relative path (will be used system association to open binary files).
Supports Mozilla's chrome.manifest files.
Priorities: selected path (if any) or autodetected path (you can just place caret anywhere inside path)

Thanks to Instructor for IsFileBinary() example.
Last edited by Infocatcher on Fri Aug 01, 2014 12:18 pm, edited 2 times in total.
Post Reply