1:    2:    3:    4:    5:    6:    7:    8:    9:   10:   11:   12:   13:   14:   15:   16:   17:   18:   19:   20:   21:   22:   23:   24:   25:   26:   27:   28:   29:   30:   31:   32:   33:   34:   35:   36:   37:   38:   39:   40:   41:   42:   43:   44:   45:   46:   47:   48:   49:   50:   51:   52:   53:   54:   55:   56:   57:   58:   59:   60:   61:   62:   63:   64:   65:   66:   67:   68:   69:   70:   71:   72:   73:   74:   75:   76:   77:   78:   79:   80:   81:   82:   83:   84:   85:   86:   87:   88:   89:   90:   91:   92:   93:   94:   95:   96:   97:   98:   99:  100:  101:  102:  103:  104:  105:  106:  107:  108:  109:  110:  111:  112:  113:  114:  115:  116:  117:  118:  119:  120:  121:  122:  123:  124:  125:  126:  127:  128:  129:  130:  131:  132:  133:  134:  135:  136:  137:  138:  139:  140:  141:  142:  143:  144:  145:  146:  147:  148:  149:  150:  151:  152:  153:  154:  155:  156:  157:  158:  159:  160:  161:  162:  163:  164:  165:  166:  167:  168:  169:  170:  171:  172:  173:  174:  175:  176:  177:  178:  179:  180:  181:  182:  183:  184:  185:  186:  187:  188:  189:  190:  191:  192:  193:  194:  195:  196:  197:  198:  199:  200:  201:  202:  203:  204:  205:  206:  207:  208:  209:  210:  211:  212:  213:  214:  215:  216:  217:  218:  219:  220:  221:  222:  223:  224:  225:  226:  227:  228:  229:  230:  231:  232:  233:  234:  235:  236:  237:  238:  239:  240:  241:  242:  243:  244:  245:  246:  247:  248:  249:  250:  251:  252:  253:  254:  255:  256:  257:  258:  259:  260:  261:  262:  263:  264:  265:  266:  267:  268:  269:  270:  271:  272:  273:  274:  275:  276:  277:  278:  279:  280:  281:  282:  283:  284:  285:  286:  287:  288:  289:  290:  291:  292:  293:  294:  295:  296:  297:  298:  299:  300:  301:  302:  303:  304:  305:  306:  307:  308:  309:  310:  311:  312:  313:  314:  315:  316:  317:  318:  319:  320:  321:  322:  323:  324:  325:  326:  327:  328:  329:  330:  331:  332:  333:  334:  335:  336:  337:  338:  339:  340:  341:  342:  343:  344:  345:  346:  347:  348:  349:  350:  351:  352:  353:  354:  355:  356:  357:  358:  359:  360:  361:  362:  363:  364:  365:  366:  367:  368:  369:  370:  371:  372:  373:  374:  375:  376:  377:  378:  379:  380:  381:  382:  383:  384:  385:  386:  387:  388:  389:  390:  391:  392:  393:  394:  395:  396:  397:  398:  399:  400:  401:  402:  403:  404:  405:  406:  407:  408:  409:  410:  411:  412:  413:  414:  415:  416:  417:  418:  419:  420:  421:  422:  423:  424:  425:  426:  427:  428:  429:  430:  431:  432:  433:  434:  435:  436:  437:  438:  439:  440:  441:  442:  443:  444:  445:  446:  447:  448:  449:  450:  451:  452:  453:  454:  455:  456:  457:  458:  459:  460:  461:  462:  463:  464:  465:  466:  467:  468:  469:  470:  471:  472:  473:  474:  475:  476:  477:  478:  479:  480:  481:  482:  483:  484:  485:  486:  487:  488:  489:  490:  491:  492:  493:  494:  495:  496:  497:  498:  499:  500:  501:  502:  503:  504:  505:  506:  507:  508:  509:  510:  511:  512:  513:  514:  515:  516:  517:  518:  519:  520:  521:  522:  523:  524:  525:  526:  527:  528:  529:  530:  531:  532:  533:  534:  535:  536:  537:  538:  539:  540:  541:  542:  543:  544:  545:  546:  547:  548:  549:  550:  551:  552:  553:  554:  555:  556:  557:  558:  559:  560:  561:  562:  563:  564:  565:  566:  567:  568:  569:  570:  571:  572:  573:  574:  575:  576:  577:  578:  579:  580:  581:  582:  583:  584:  585:  586:  587:  588:  589:  590:  591:  592:  593:  594:  595:  596:  597:  598:  599:  600:  601:  602:  603:  604:  605:  606:  607:  608:  609:  610:  611:  612:  613:  614:  615:  616:  617:  618:  619:  620:  621:  622:  623:  624:  625:  626:  627:  628:  629:  630:  631:  632:  633:  634:  635:  636:  637:  638:  639:  640:  641:  642:  643:  644:  645:  646:  647:  648:  649:  650:  651:  652:  653:  654:  655:  656:  657:  658:  659:  660:  661:  662:  663:  664:  665:  666:  667:  668:  669:  670:  671:  672:  673:  674:  675:  676:  677:  678:  679:  680:  681:  682:  683:  684:  685:  686:  687:  688:  689:  690:  691:  692:  693:  694:  695:  696:  697:  698:  699:  700:  701:  702:  703:  704:  705:  706:  707:  708:  709:  710:  711:  712:  713:  714:  715:  716:  717:  718:  719:  720:  721:  722:  723:  724:  725:  726:  727:  728:  729:  730:  731:  732:  733:  734:  735:  736:  737:  738:  739:  740:  741:  742:  743:  744:  745:  746:  747:  748:  749:  750:  751:  752:  753:  754:  755:  756:  757:  758:  759:  760:  761:  762:  763:  764:  765:  766:  767:  768:  769:  770:  771:  772:  773:  774:  775:  776:  777:  778:  779:  780:  781:  782:  783:  784:  785:  786:  787:  788:  789:  790:  791:  792:  793:  794:  795:  796:  797:  798:  799:  800:  801:  802:  803:  804:  805:  806:  807:  808:  809:  810:  811:  812:  813:  814:  815:  816:  817:  818:  819:  820:  821:  822:  823:  824:  825:  826:  827:  828:  829:  830:  831:  832:  833:  834:  835:  836:  837:  838:  839:  840:  841:  842:  843:  844:  845:  846:  847:  848:  849:  850:  851:  852:  853:  854:  855:  856:  857:  858:  859:  860:  861:  862:  863:  864:  865:  866:  867:  868:  869:  870:  871:  872:  873:  874:  875:  876:  877:  878:  879:  880:  881:  882:  883:  884:  885:  886:  887:  888:  889:  890:  891:  892:  893:  894:  895:  896:  897:  898:  899:  900:  901:  902:  903:  904:  905:  906:  907:  908:  909:  910:  911:  912:  913:  914:  915:  916:  917:  918:  919:  920:  921:  922:  923:  924:  925:  926:  927:  928:  929:  930:  931:  932:  933:  934:  935:  936:  937:  938:  939:  940:  941:  942:  943:  944:  945:  946:  947:  948:  949:  950:  951:  952:  953:  954:  955:  956:  957:  958:  959:  960:  961:  962:  963:  964:  965:  966:  967:  968:  969:  970:  971:  972:  973:  974:  975:  976:  977:  978:  979:  980:  981:  982:  983:  984:  985:  986:  987:  988:  989:  990:  991:  992:  993:  994:  995:  996:  997:  998:  999: 1000: 1001: 1002: 1003: 1004: 1005: 1006: 1007: 1008: 1009: 1010: 1011: 1012: 1013: 1014: 1015: 1016: 1017: 1018: 1019: 1020: 1021: 1022: 1023: 1024: 1025: 1026: 1027: 1028: 1029: 1030: 1031: 1032: 1033: 1034: 1035: 1036: 1037: 1038: 1039: 1040: 1041: 1042: 1043: 1044: 1045: 1046: 1047: 1048: 1049: 1050: 1051: 1052: 1053: 1054: 1055: 1056: 1057: 1058: 1059: 1060: 1061: 1062: 1063: 1064: 1065: 1066: 1067: 1068: 1069: 1070: 1071: 1072: 1073: 1074: 1075: 1076: 1077: 1078: 1079: 1080: 1081: 1082: 1083: 1084: 1085: 1086: 1087: 1088: 1089: 1090: 1091: 1092: 1093: 1094: 1095: 1096: 1097: 1098: 1099: 1100: 1101: 1102: 1103: 1104: 1105: 1106: 1107: 1108: 1109: 1110: 1111: 1112: 1113: 1114: 1115: 1116: 1117: 1118: 1119: 1120: 1121: 1122: 1123: 1124: 1125: 1126: 1127: 1128: 1129: 1130: 1131: 1132: 1133: 1134: 1135: 1136: 1137: 1138: 1139: 1140: 1141: 1142: 1143: 1144: 1145: 1146: 1147: 1148: 1149: 1150: 1151: 1152: 1153: 1154: 1155: 1156: 1157: 1158: 1159: 1160: 1161: 1162: 1163: 1164: 1165: 1166: 1167: 1168: 1169: 1170: 1171: 1172: 1173: 1174: 1175: 1176: 1177: 1178: 1179: 1180: 1181: 1182: 1183: 1184: 1185: 1186: 1187: 1188: 1189: 1190: 1191: 1192: 1193: 1194: 1195: 1196: 1197: 1198: 1199: 1200: 1201: 1202: 1203: 1204: 1205: 1206: 1207: 1208: 1209: 1210: 1211: 1212: 1213: 1214: 1215: 1216: 1217: 1218: 1219: 1220: 1221: 1222: 1223: 1224: 1225: 1226: 1227: 1228: 1229: 1230: 1231: 1232: 1233: 1234: 1235: 1236: 1237: 1238: 1239: 1240: 1241: 1242: 1243: 1244: 1245: 1246: 1247: 1248: 1249: 1250: 1251: 1252: 1253: 1254: 1255: 1256: 1257: 1258: 1259: 1260: 1261: 1262: 1263: 1264: 1265: 1266: 1267: 1268: 1269: 1270: 1271: 1272: 1273: 1274: 1275: 1276: 1277: 1278: 1279: 1280: 1281: 1282: 1283: 1284: 1285: 1286: 1287: 1288: 1289: 1290: 1291: 1292: 1293: 1294: 1295: 1296: 1297: 1298: 1299: 1300: 1301: 1302: 1303: 1304: 1305: 1306: 1307: 1308: 1309: 1310: 1311: 1312: 1313: 1314: 1315: 1316: 1317: 1318: 1319: 1320: 1321: 1322: 1323: 1324: 1325: 1326: 1327: 1328: 1329: 1330: 1331: 1332: 1333: 1334: 1335: 1336: 1337: 1338: 1339: 1340: 1341: 1342: 1343: 1344: 1345: 1346: 1347: 1348: 1349: 1350: 1351: 1352: 1353: 1354: 1355: 1356: 1357: 1358: 1359: 1360: 1361: 1362: 1363: 1364: 1365: 1366: 1367: 1368: 1369: 1370: 1371: 1372: 1373: 1374: 1375: 1376: 1377: 1378: 1379: 1380: 1381: 1382: 1383: 1384: 1385: 1386: 1387: 1388: 1389: 1390: 1391: 1392: 1393: 1394: 1395: 1396: 1397: 1398: 1399: 1400: 1401: 1402: 1403: 1404: 1405: 1406: 1407: 1408: 1409: 1410: 1411: 1412: 1413: 1414: 1415: 1416: 1417: 1418: 1419: 1420: 1421: 1422: 1423: 1424: 1425: 1426: 1427: 1428: 1429: 1430: 1431: 1432: 1433: 1434: 1435: 1436: 1437: 1438: 1439: 1440: 1441: 1442: 1443: 1444: 1445: 1446: 1447: 1448: 1449: 1450: 1451: 1452: 1453: 1454: 1455: 1456: 1457: 1458: 1459: 1460: 1461: 1462: 1463: 1464: 1465: 1466: 1467: 1468: 1469: 1470: 1471: 1472: 1473: 1474: 1475: 1476: 1477: 1478: 1479: 1480: 1481: 1482: 1483: 1484: 1485: 1486: 1487: 1488: 1489: 1490: 1491: 1492: 1493: 1494: 1495: 1496: 1497: 1498: 1499: 1500: 1501: 1502: 1503: 1504: 1505: 1506: 1507: 1508: 1509: 1510: 1511: 1512: 1513: 1514: 1515: 1516: 1517: 1518: 1519: 1520: 1521: 1522: 1523: 1524: 1525: 1526: 1527: 1528: 1529: 1530: 1531: 1532: 1533: 1534: 1535: 1536: 1537: 1538: 1539: 1540: 1541: 1542: 1543: 1544: 1545: 1546: 1547: 1548: 1549: 1550: 1551: 1552: 1553: 1554: 1555: 1556: 1557: 1558: 1559: 1560: 1561: 1562: 1563: 1564: 1565: 1566: 1567: 1568: 1569: 1570: 1571: 1572: 1573: 1574: 1575: 1576: 1577: 1578: 1579: 1580: 1581: 1582: 1583: 1584: 1585: 1586: 1587: 1588: 1589: 1590: 1591: 1592: 1593: 1594: 1595: 1596: 1597: 1598: 1599: 1600: 1601: 1602: 1603: 1604: 1605: 1606: 1607: 1608: 1609: 1610: 1611: 1612: 1613: 1614: 1615: 1616: 1617: 1618: 1619: 1620: 1621: 1622: 1623: 1624: 1625: 1626: 1627: 1628: 1629: 1630: 1631: 1632: 1633: 1634: 1635: 1636: 1637: 1638: 1639: 1640: 1641: 1642: 1643: 1644: 1645: 1646: 1647: 1648: 1649: 1650: 1651: 1652: 1653: 1654: 1655: 1656: 1657: 1658: 1659: 1660: 1661: 1662: 1663: 1664: 1665: 1666: 1667: 1668: 1669: 1670: 1671: 1672: 1673: 1674: 1675: 1676: 1677: 1678: 1679: 1680: 1681: 1682: 1683: 1684: 1685: 1686: 1687: 1688: 1689: 1690: 1691: 1692: 1693: 1694: 1695: 1696: 1697: 1698: 1699: 1700: 1701: 1702: 1703: 1704: 1705: 1706: 1707: 1708: 1709: 1710: 1711: 1712: 1713: 1714: 1715: 1716: 1717: 1718: 1719: 1720: 1721: 1722: 1723: 1724: 1725: 1726: 1727: 1728: 1729: 1730: 1731: 1732: 1733: 1734: 1735: 1736: 1737: 1738: 1739: 1740: 1741: 1742: 1743: 1744: 1745: 1746: 1747: 1748: 1749: 1750: 1751: 1752: 1753: 1754: 1755: 1756: 1757: 1758: 1759: 1760: 1761: 1762: 1763: 1764: 1765: 1766: 1767: 1768: 1769: 1770: 1771: 1772: 1773: 1774: 1775: 1776: 1777: 1778: 1779: 1780: 1781: 1782: 1783: 1784: 1785: 1786: 1787: 1788: 1789: 1790: 1791: 1792: 1793: 1794: 1795: 1796: 1797: 1798: 1799: 1800: 1801: 1802: 1803: 1804: 1805: 1806: 1807: 1808: 1809: 1810: 1811: 1812: 1813: 1814: 1815: 1816: 1817: 1818: 1819: 1820: 1821: 1822: 1823: 1824: 1825: 1826: 1827: 1828: 1829: 1830: 1831: 1832: 1833: 1834: 1835: 1836: 1837: 1838: 1839: 1840: 
<?php
/**
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines http://www.simplemachines.org
 * @copyright 2019 Simple Machines and individual contributors
 * @license http://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.1 RC1
 */

/**
 * The main template
 */
function template_main()
{
}

/**
 * View package details when installing/uninstalling
 */
function template_view_package()
{
    global $context, $settings, $txt, $scripturl;

    echo '
        <div class="cat_bar">
            <h3 class="catbg">', $txt[($context['uninstalling'] ? 'un' : '') . 'install_mod'], '</h3>
        </div>
        <div class="information">';

    if ($context['is_installed'])
        echo '
            <strong>', $txt['package_installed_warning1'], '</strong><br>
            <br>
            ', $txt['package_installed_warning2'], '<br>
            <br>';

    echo $txt['package_installed_warning3'], '
        </div>
        <br>';

    // Do errors exist in the install? If so light them up like a christmas tree.
    if ($context['has_failure'])
        echo '
        <div class="errorbox">
            ', sprintf($txt['package_will_fail_title'], $txt['package_' . ($context['uninstalling'] ? 'uninstall' : 'install')]), '<br>
            ', sprintf($txt['package_will_fail_warning'], $txt['package_' . ($context['uninstalling'] ? 'uninstall' : 'install')]),
            !empty($context['failure_details']) ? '<br><br><strong>' . $context['failure_details'] . '</strong>' : '', '
        </div>';

    // Display the package readme if one exists
    if (isset($context['package_readme']))
    {
        echo '
        <div class="cat_bar">
            <h3 class="catbg">', $txt['package_' . ($context['uninstalling'] ? 'un' : '') . 'install_readme'], '</h3>
        </div>
        <div class="windowbg">
            ', $context['package_readme'], '
            <span class="floatright">', $txt['package_available_readme_language'], '
                <select name="readme_language" id="readme_language" onchange="if (this.options[this.selectedIndex].value) window.location.href = smf_prepareScriptUrl(smf_scripturl + \'', '?action=admin;area=packages;sa=', $context['uninstalling'] ? 'uninstall' : 'install', ';package=', $context['filename'], ';readme=\' + this.options[this.selectedIndex].value + \';license=\' + get_selected(\'license_language\'));">';

        foreach ($context['readmes'] as $a => $b)
            echo '
                    <option value="', $b, '"', $a === 'selected' ? ' selected' : '', '>', $b == 'default' ? $txt['package_readme_default'] : ucfirst($b), '</option>';

        echo '
                </select>
            </span>
        </div>
        <br>';
    }

    // Did they specify a license to display?
    if (isset($context['package_license']))
    {
        echo '
        <div class="cat_bar">
            <h3 class="catbg">', $txt['package_install_license'], '</h3>
        </div>
        <div class="windowbg">
            ', $context['package_license'], '
            <span class="floatright">', $txt['package_available_license_language'], '
                <select name="license_language" id="license_language" onchange="if (this.options[this.selectedIndex].value) window.location.href = smf_prepareScriptUrl(smf_scripturl + \'', '?action=admin;area=packages;sa=install', ';package=', $context['filename'], ';license=\' + this.options[this.selectedIndex].value + \';readme=\' + get_selected(\'readme_language\'));">';

        foreach ($context['licenses'] as $a => $b)
            echo '
                    <option value="', $b, '"', $a === 'selected' ? ' selected' : '', '>', $b == 'default' ? $txt['package_license_default'] : ucfirst($b), '</option>';
        echo '
                </select>
            </span>
        </div>
        <br>';
    }

    echo '
        <form action="', !empty($context['post_url']) ? $context['post_url'] : '#', '" onsubmit="submitonce(this);" method="post" accept-charset="', $context['character_set'], '" id="view_package">
            <div class="cat_bar">
                <h3 class="catbg">
                    ', $context['uninstalling'] ? $txt['package_uninstall_actions'] : $txt['package_install_actions'], ' &quot;', $context['package_name'], '&quot;
                </h3>
            </div>';

    // Are there data changes to be removed?
    if ($context['uninstalling'] && !empty($context['database_changes']))
    {
        // This is really a special case so we're adding style inline
        echo '
            <div class="windowbg" style="margin: 0; border-radius: 0;">
                <label><input type="checkbox" name="do_db_changes">', $txt['package_db_uninstall'], '</label>
                <div id="db_changes_div">
                    ', $txt['package_db_uninstall_actions'], ':
                    <ul class="normallist smalltext">';

        foreach ($context['database_changes'] as $change)
            echo '
                        <li>', $change, '</li>';

        echo '
                    </ul>
                </div>
            </div>';
    }

    echo '
            <div class="information">';

    if (empty($context['actions']) && empty($context['database_changes']))
        echo '
                <br>
                <div class="errorbox">
                    ', $txt['corrupt_compatible'], '
                </div>
            </div><!-- .information -->';
    else
    {
        echo '
                ', $txt['perform_actions'], '
            </div><!-- .information -->
            <br>
            <table class="table_grid">
                <thead>
                    <tr class="title_bar">
                        <th scope="col"></th>
                        <th scope="col" width="30"></th>
                        <th scope="col" class="lefttext">', $txt['package_install_type'], '</th>
                        <th scope="col" class="lefttext" width="50%">', $txt['package_install_action'], '</th>
                        <th class="lefttext" scope="col" width="20%">', $txt['package_install_desc'], '</th>
                    </tr>
                </thead>
                <tbody>';

        $i = 1;
        $j = 1;
        $action_num = 1;
        $js_operations = array();
        foreach ($context['actions'] as $packageaction)
        {
            // Did we pass or fail?  Need to now for later on.
            $js_operations[$action_num] = isset($packageaction['failed']) ? $packageaction['failed'] : 0;

            echo '
                    <tr class="bg ', $i % 2 == 0 ? 'even' : 'odd', '">
                        <td>', isset($packageaction['operations']) ? '<img id="operation_img_' . $action_num . '" src="' . $settings['images_url'] . '/selected_open.png" alt="*" style="display: none;">' : '', '</td>
                        <td style="width: 30px;">', $i++, '.</td>
                        <td style="width: 23%;">', $packageaction['type'], '</td>
                        <td style="width: 50%;">', $packageaction['action'], '</td>
                        <td style="width: 20%;">', $packageaction['description'], '</td>
                    </tr>';

            // Is there water on the knee? Operation!
            if (isset($packageaction['operations']))
            {
                echo '
                    <tr id="operation_', $action_num, '">
                        <td colspan="5">
                            <table class="full_width">';

                // Show the operations.
                $operation_num = 1;
                foreach ($packageaction['operations'] as $operation)
                {
                    // Determine the position text.
                    $operation_text = $operation['position'] == 'replace' ? 'operation_replace' : ($operation['position'] == 'before' ? 'operation_after' : 'operation_before');

                    echo '
                                <tr class="bg ', $operation_num % 2 == 0 ? 'even' : 'odd', '">
                                    <td class="righttext">
                                        <a href="', $scripturl, '?action=admin;area=packages;sa=showoperations;operation_key=', $operation['operation_key'], !empty($context['install_id']) ? ';install_id=' . $context['install_id'] : '', ';package=', $_REQUEST['package'], ';filename=', $operation['filename'], ($operation['is_boardmod'] ? ';boardmod' : ''), (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'uninstall' ? ';reverse' : ''), '" onclick="return reqWin(this.href, 600, 400, false);">
                                            <span class="main_icons package_ops"></span>
                                        </a>
                                    </td>
                                    <td width="30">', $operation_num++, '.</td>
                                    <td width="23%">', $txt[$operation_text], '</td>
                                    <td width="50%">', $operation['action'], '</td>
                                    <td width="20%">', $operation['description'], !empty($operation['ignore_failure']) ? ' (' . $txt['operation_ignore'] . ')' : '', '</td>
                                </tr>';
                }

                echo '
                            </table>
                        </td>
                    </tr>';

                // Increase it.
                $action_num++;
            }
        }
        echo '
                </tbody>
            </table>';

        // What if we have custom themes we can install into? List them too!
        if (!empty($context['theme_actions']))
        {
            echo '
            <br>
            <div class="cat_bar">
                <h3 class="catbg">
                    ', $context['uninstalling'] ? $txt['package_other_themes_uninstall'] : $txt['package_other_themes'], '
                </h3>
            </div>
            <div id="custom_changes">
                <div class="information">
                    ', $txt['package_other_themes_desc'], '
                </div>
                <table class="table_grid">';

            // Loop through each theme and display it's name, and then it's details.
            foreach ($context['theme_actions'] as $id => $theme)
            {
                // Pass?
                $js_operations[$action_num] = !empty($theme['has_failure']);

                echo '
                    <tr class="title_bar">
                        <td class="righttext" colspan="2">';

                if (!empty($context['themes_locked']))
                    echo '
                            <input type="hidden" name="custom_theme[]" value="', $id, '">';
                echo '
                            <input type="checkbox" name="custom_theme[]" id="custom_theme_', $id, '" value="', $id, '" onclick="', (!empty($theme['has_failure']) ? 'if (this.form.custom_theme_' . $id . '.checked && !confirm(\'' . $txt['package_theme_failure_warning'] . '\')) return false;' : ''), 'invertAll(this, this.form, \'dummy_theme_', $id, '\', true);"', !empty($context['themes_locked']) ? ' disabled checked' : '', '>
                        </td>
                        <td colspan="3">
                            ', $theme['name'], '
                        </td>
                    </tr>';

                foreach ($theme['actions'] as $action)
                {
                    echo '
                    <tr class="bg ', $j++ % 2 == 0 ? 'even' : 'odd', '">
                        <td colspan="2">', isset($packageaction['operations']) ?
                            '<img id="operation_img_' . $action_num . '" src="' . $settings['images_url'] . '/selected_open.png" alt="*" style="display: none;">' : '', '
                            <input type="checkbox" name="theme_changes[]" value="', !empty($action['value']) ? $action['value'] : '', '" id="dummy_theme_', $id, '"', (!empty($action['not_mod']) ? '' : ' disabled'), !empty($context['themes_locked']) ? ' checked' : '', ' class="floatright">
                        </td>
                        <td width="23%">', $action['type'], '</td>
                        <td width="50%">', $action['action'], '</td>
                        <td width="20%"><strong>', $action['description'], '</strong></td>
                    </tr>';

                    // Is there water on the knee? Operation!
                    if (isset($action['operations']))
                    {
                        echo '
                    <tr id="operation_', $action_num, '">
                        <td colspan="5">
                            <table class="full_width">';

                        $operation_num = 1;
                        foreach ($action['operations'] as $operation)
                        {
                            // Determine the position text.
                            $operation_text = $operation['position'] == 'replace' ? 'operation_replace' : ($operation['position'] == 'before' ? 'operation_after' : 'operation_before');

                            echo '
                                <tr class="bg ', $operation_num % 2 == 0 ? 'even' : 'odd', '">
                                    <td class="righttext">
                                        <a href="', $scripturl, '?action=admin;area=packages;sa=showoperations;operation_key=', $operation['operation_key'], !empty($context['install_id']) ? ';install_id=' . $context['install_id'] : '', ';package=', $_REQUEST['package'], ';filename=', $operation['filename'], ($operation['is_boardmod'] ? ';boardmod' : ''), (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'uninstall' ? ';reverse' : ''), '" onclick="return reqWin(this.href, 600, 400, false);">
                                            <span class="main_icons package_ops"></span>
                                        </a>
                                    </td>
                                    <td width="30">', $operation_num++, '.</td>
                                    <td width="23%">', $txt[$operation_text], '</td>
                                    <td width="50%">', $operation['action'], '</td>
                                    <td width="20%">', $operation['description'], !empty($operation['ignore_failure']) ? ' (' . $txt['operation_ignore'] . ')' : '', '</td>
                                </tr>';
                        }

                        echo '
                            </table>
                        </td>
                    </tr>';

                        // Increase it.
                        $action_num++;
                    }
                }
            }

            echo '
                </table>
            </div><!-- #custom_changes -->';
        }
    }

    // Are we effectively ready to install?
    if (!$context['ftp_needed'] && (!empty($context['actions']) || !empty($context['database_changes'])))
        echo '
            <div class="righttext padding">
                <input type="submit" value="', $context['uninstalling'] ? $txt['package_uninstall_now'] : $txt['package_install_now'], '" onclick="return ', !empty($context['has_failure']) ? '(submitThisOnce(this) &amp;&amp; confirm(\'' . ($context['uninstalling'] ? $txt['package_will_fail_popup_uninstall'] : $txt['package_will_fail_popup']) . '\'))' : 'submitThisOnce(this)', ';" class="button">
            </div>';

    // If we need ftp information then demand it!
    elseif ($context['ftp_needed'])
        echo '
            <div class="cat_bar">
                <h3 class="catbg">', $txt['package_ftp_necessary'], '</h3>
            </div>
            <div>
                ', template_control_chmod(), '
            </div>';

    echo '

            <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">', (isset($context['form_sequence_number']) && !$context['ftp_needed']) ? '
            <input type="hidden" name="seqnum" value="' . $context['form_sequence_number'] . '">' : '', '
        </form>';

    // Toggle options.
    echo '
    <script>';

    // Operations.
    if (!empty($js_operations))
        foreach ($js_operations as $key => $operation)
            echo '
        new smc_Toggle({
            bToggleEnabled: true,
            bNoAnimate: true,
            bCurrentlyCollapsed: ', $operation ? 'false' : 'true', ',
            aSwappableContainers: [
                \'operation_', $key, '\'
            ],
            aSwapImages: [
                {
                    sId: \'operation_img_', $key, '\',
                    srcExpanded: smf_images_url + \'/selected_open.png\',
                    altExpanded: \'*\',
                    srcCollapsed: smf_images_url + \'/selected.png\',
                    altCollapsed: \'*\'
                }
            ]
        });';

    // Get the currently selected item from a select list
    echo '
        function get_selected(id)
        {
            var aSelected = document.getElementById(id);
            for (var i = 0; i < aSelected.options.length; i++)
            {
                if (aSelected.options[i].selected == true)
                    return aSelected.options[i].value;
            }
            return aSelected.options[0];
        }';

    // And a bit more for database changes.
    if ($context['uninstalling'] && !empty($context['database_changes']))
        echo '
        makeToggle(document.getElementById(\'db_changes_div\'), ', JavaScriptEscape($txt['package_db_uninstall_details']) , ');';

    echo '
    </script>';
}

/**
 * Extract package contents
 */
function template_extract_package()
{
    global $context, $txt, $scripturl;

    echo '
        <div class="cat_bar">
            <h3 class="catbg">';

    if (empty($context['redirect_url']))
        echo $context['uninstalling'] ? $txt['uninstall'] : $txt['extracting'];
    else
        echo $txt['package_installed_redirecting'];

    echo '</h3>
        </div>
        <div class="windowbg">';

    // If we are going to redirect we have a slightly different agenda.
    if (!empty($context['redirect_url']))
        echo '
            ', $context['redirect_text'], '<br><br>
            <a href="', $context['redirect_url'], '">', $txt['package_installed_redirect_go_now'], '</a><span id="countdown" class="hidden"> (5) </span> | <a href="', $scripturl, '?action=admin;area=packages;sa=browse">', $txt['package_installed_redirect_cancel'], '</a>
            <script>
                var countdown = ', $context['redirect_timeout'], ';
                var el = document.getElementById(\'countdown\');
                var loop = setInterval(doCountdown, 1000);

                function doCountdown()
                {
                    countdown--;
                    el.textContent = " (" + countdown + ") ";

                    if (countdown == 0)
                    {
                        clearInterval(loop);
                        window.location = "', $context['redirect_url'], '";
                    }
                }
                el.classList.remove(\'hidden\');
                el.value = " (" + countdown + ") ";
            </script>';

    elseif ($context['uninstalling'])
        echo '
            ', $txt['package_uninstall_done'];

    elseif ($context['install_finished'])
    {
        if ($context['extract_type'] == 'avatar')
            echo '
            ', $txt['avatars_extracted'];

        elseif ($context['extract_type'] == 'language')
            echo '
            ', $txt['language_extracted'];

        else
            echo '
            ', $txt['package_installed_done'];
    }
    else
        echo '
            ', $txt['corrupt_compatible'];

    echo '
        </div><!-- .windowbg -->';

    // Show the "restore permissions" screen?
    if (function_exists('template_show_list') && !empty($context['restore_file_permissions']['rows']))
    {
        echo '<br>';
        template_show_list('restore_file_permissions');
    }
}

/**
 * List files in a package
 */
function template_list()
{
    global $context, $txt, $scripturl;

    echo '
        <div class="cat_bar">
            <h3 class="catbg">', $txt['list_file'], '</h3>
        </div>
        <div class="cat_bar">
            <h3 class="catbg">', $txt['files_archive'], ' ', $context['filename'], ':</h3>
        </div>
        <div class="windowbg">
            <ol>';

    foreach ($context['files'] as $fileinfo)
        echo '
                <li><a href="', $scripturl, '?action=admin;area=packages;sa=examine;package=', $context['filename'], ';file=', $fileinfo['filename'], '" title="', $txt['view'], '">', $fileinfo['filename'], '</a> (', $fileinfo['size'], ' ', $txt['package_bytes'], ')</li>';

    echo '
            </ol>
            <br>
            <a href="', $scripturl, '?action=admin;area=packages">[ ', $txt['back'], ' ]</a>
        </div>';
}

/**
 * Examine a single file within a package
 */
function template_examine()
{
    global $context, $txt, $scripturl;

    echo '
        <div class="cat_bar">
            <h3 class="catbg">', $txt['package_examine_file'], '</h3>
        </div>
        <div class="cat_bar">
            <h3 class="catbg">', $txt['package_file_contents'], ' ', $context['filename'], ':</h3>
        </div>
        <div class="windowbg">
            <pre class="file_content">', $context['filedata'], '</pre>
            <a href="', $scripturl, '?action=admin;area=packages;sa=list;package=', $context['package'], '">[ ', $txt['list_files'], ' ]</a>
        </div>';
}

/**
 * List all packages
 */
function template_browse()
{
    global $context, $txt, $scripturl, $modSettings;

    echo '
        <div id="update_section"></div>
        <div id="admin_form_wrapper">
            <div class="cat_bar">
                <h3 class="catbg">
                    ', $txt['packages_adding_title'], '
                </h3>
            </div>
            <div class="information">
                ', $txt['packages_adding'], '
            </div>

            <script>
                window.smfForum_scripturl = smf_scripturl;
                window.smfForum_sessionid = smf_session_id;
                window.smfForum_sessionvar = smf_session_var;';

    // Make a list of already installed mods so nothing is listed twice ;).
    echo '
                window.smfInstalledPackages = ["', implode('", "', $context['installed_mods']), '"];
                window.smfVersion = "', $context['forum_version'], '";
            </script>
            <div id="yourVersion" style="display:none">', $context['forum_version'], '</div>';

    if (empty($modSettings['disable_smf_js']))
        echo '
            <script src="', $scripturl, '?action=viewsmfile;filename=latest-news.js"></script>';

    // This sets the announcements and current versions themselves ;).
    echo '
            <script>
                var oAdminIndex = new smf_AdminIndex({
                    sSelf: \'oAdminCenter\',
                    bLoadAnnouncements: false,
                    bLoadVersions: false,
                    bLoadUpdateNotification: true,
                    sUpdateNotificationContainerId: \'update_section\',
                    sUpdateNotificationDefaultTitle: ', JavaScriptEscape($txt['update_available']), ',
                    sUpdateNotificationDefaultMessage: ', JavaScriptEscape($txt['update_message']), ',
                    sUpdateNotificationTemplate: ', JavaScriptEscape('
                        <h3 id="update_title">
                            %title%
                        </h3>
                        <div id="update_message" class="smalltext">
                            %message%
                        </div>
                    '), ',
                    sUpdateNotificationLink: smf_scripturl + ', JavaScriptEscape('?action=admin;area=packages;pgdownload;auto;package=%package%;' . $context['session_var'] . '=' . $context['session_id']), '
                });
            </script>';

    echo '
        </div><!-- #admin_form_wrapper -->';

    $mods_available = false;
    foreach ($context['modification_types'] as $type)
    {
        if (!empty($context['available_' . $type]))
        {
            template_show_list('packages_lists_' . $type);
            $mods_available = true;
        }
    }

    if (!$mods_available)
        echo '
        <div class="noticebox">', $txt['no_packages'], '</div>';
    else
        echo '
        <br>';

    // The advanced (emulation) box, collapsed by default
    echo '
        <form action="', $scripturl, '?action=admin;area=packages;sa=browse" method="get">
            <div id="advanced_box">
                <div class="cat_bar">
                    <h3 class="catbg">
                        <span id="advanced_panel_toggle" class="floatright" style="display: none;"></span>
                        <a href="#" id="advanced_panel_link">', $txt['package_advanced_button'], '</a>
                    </h3>
                </div>
                <div id="advanced_panel_div" class="windowbg">
                    <p>
                        ', $txt['package_emulate_desc'], '
                    </p>
                    <dl class="settings">
                        <dt>
                            <strong>', $txt['package_emulate'], ':</strong><br>
                            <span class="smalltext">
                                <a href="#" onclick="return revert();">', $txt['package_emulate_revert'], '</a>
                            </span>
                        </dt>
                        <dd>
                            <a id="revert" name="revert"></a>
                            <select name="version_emulate" id="ve">';

    foreach ($context['emulation_versions'] as $version)
        echo '
                                <option value="', $version, '"', ($version == $context['selected_version'] ? ' selected="selected"' : ''), '>', $version, '</option>';

    echo '
                            </select>
                        </dd>
                    </dl>
                    <div class="righttext padding">
                        <input type="submit" value="', $txt['package_apply'], '" class="button">
                    </div>
                </div><!-- #advanced_panel_div -->
            </div><!-- #advanced_box -->
            <input type="hidden" name="action" value="admin">
            <input type="hidden" name="area" value="packages">
            <input type="hidden" name="sa" value="browse">
        </form>
    <script>
        var oAdvancedPanelToggle = new smc_Toggle({
            bToggleEnabled: true,
            bCurrentlyCollapsed: true,
            aSwappableContainers: [
                \'advanced_panel_div\'
            ],
            aSwapImages: [
                {
                    sId: \'advanced_panel_toggle\',
                    altExpanded: ', JavaScriptEscape($txt['hide']), ',
                    altCollapsed: ', JavaScriptEscape($txt['show']), '
                }
            ],
            aSwapLinks: [
                {
                    sId: \'advanced_panel_link\',
                    msgExpanded: ', JavaScriptEscape($txt['package_advanced_button']), ',
                    msgCollapsed: ', JavaScriptEscape($txt['package_advanced_button']), '
                }
            ]
        });
        function revert()
        {
            var default_version = "', $context['default_version'], '";
            $("#ve").find("option").filter(function(index) {
                return default_version === $(this).text();
            }).attr("selected", "selected");
            return false;
        }
    </script>';
}

/**
 * List package servers
 */
function template_servers()
{
    global $context, $txt, $scripturl;

    if (!empty($context['package_ftp']['error']))
        echo '
    <div class="errorbox">
        <pre>', $context['package_ftp']['error'], '</pre>
    </div>';

    echo '
    <div id="admin_form_wrapper">
        <div class="cat_bar">
            <h3 class="catbg">', $txt['package_upload_title'], '</h3>
        </div>
        <div class="windowbg">
            <form action="', $scripturl, '?action=admin;area=packages;get;sa=upload" method="post" accept-charset="', $context['character_set'], '" enctype="multipart/form-data">
                <dl class="settings">
                    <dt>
                        <strong>', $txt['package_upload_select'], ':</strong>
                    </dt>
                    <dd>
                        <input type="file" name="package" size="38">
                    </dd>
                </dl>
                <input type="submit" value="', $txt['upload'], '" class="button">
                <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
            </form>
        </div>
        <div class="cat_bar">
            <h3 class="catbg">
                <a class="download_new_package">
                    <span class="toggle_down floatright" alt="*" title="', $txt['show'], '"></span>
                    ', $txt['download_new_package'], '
                </a>
            </h3>
        </div>
        <div class="new_package_content">';

    if ($context['package_download_broken'])
    {
        echo '
            <div class="cat_bar">
                <h3 class="catbg">', $txt['package_ftp_necessary'], '</h3>
            </div>
            <div class="windowbg">
                <p>
                    ', $txt['package_ftp_why_download'], '
                </p>
                <form action="', $scripturl, '?action=admin;area=packages;get" method="post" accept-charset="', $context['character_set'], '">
                    <dl class="settings">
                        <dt>
                            <label for="ftp_server">', $txt['package_ftp_server'], ':</label>
                        </dt>
                        <dd>
                            <input type="text" size="30" name="ftp_server" id="ftp_server" value="', $context['package_ftp']['server'], '">
                            <label for="ftp_port">', $txt['package_ftp_port'], ':</label>
                            <input type="text" size="3" name="ftp_port" id="ftp_port" value="', $context['package_ftp']['port'], '">
                        </dd>
                        <dt>
                            <label for="ftp_username">', $txt['package_ftp_username'], ':</label>
                        </dt>
                        <dd>
                            <input type="text" size="50" name="ftp_username" id="ftp_username" value="', $context['package_ftp']['username'], '">
                        </dd>
                        <dt>
                            <label for="ftp_password">', $txt['package_ftp_password'], ':</label>
                        </dt>
                        <dd>
                            <input type="password" size="50" name="ftp_password" id="ftp_password">
                        </dd>
                        <dt>
                            <label for="ftp_path">', $txt['package_ftp_path'], ':</label>
                        </dt>
                        <dd>
                            <input type="text" size="50" name="ftp_path" id="ftp_path" value="', $context['package_ftp']['path'], '">
                        </dd>
                    </dl>
                    <div class="righttext">
                        <input type="submit" value="', $txt['package_proceed'], '" class="button">
                    </div>
                </form>
            </div><!-- .windowbg -->';
    }

    echo '
            <div class="windowbg">
                <fieldset>
                    <legend>' . $txt['package_servers'] . '</legend>
                    <ul class="package_servers">';

    foreach ($context['servers'] as $server)
        echo '
                        <li class="flow_auto">
                            <span class="floatleft">' . $server['name'] . '</span>
                            <span class="package_server floatright"><a href="' . $scripturl . '?action=admin;area=packages;get;sa=remove;server=' . $server['id'] . ';', $context['session_var'], '=', $context['session_id'], '">[ ' . $txt['delete'] . ' ]</a></span>
                            <span class="package_server floatright"><a href="' . $scripturl . '?action=admin;area=packages;get;sa=browse;server=' . $server['id'] . '">[ ' . $txt['package_browse'] . ' ]</a></span>
                        </li>';
    echo '
                    </ul>
                </fieldset>
                <fieldset>
                    <legend>' . $txt['add_server'] . '</legend>
                    <form action="' . $scripturl . '?action=admin;area=packages;get;sa=add" method="post" accept-charset="', $context['character_set'], '">
                        <dl class="settings">
                            <dt>
                                <strong>' . $txt['server_name'] . ':</strong>
                            </dt>
                            <dd>
                                <input type="text" name="servername" size="44" value="SMF">
                            </dd>
                            <dt>
                                <strong>' . $txt['serverurl'] . ':</strong>
                            </dt>
                            <dd>
                                <input type="text" name="serverurl" size="44" value="https://">
                            </dd>
                        </dl>
                        <div class="righttext">
                            <input type="submit" value="' . $txt['add_server'] . '" class="button">
                            <input type="hidden" name="' . $context['session_var'] . '" value="' . $context['session_id'] . '">
                        </div>
                    </form>
                </fieldset>
                <fieldset>
                    <legend>', $txt['package_download_by_url'], '</legend>
                    <form action="', $scripturl, '?action=admin;area=packages;get;sa=download;byurl;', $context['session_var'], '=', $context['session_id'], '" method="post" accept-charset="', $context['character_set'], '">
                        <dl class="settings">
                            <dt>
                                <strong>' . $txt['serverurl'] . ':</strong>
                            </dt>
                            <dd>
                                <input type="text" name="package" size="44" value="https://">
                            </dd>
                            <dt>
                                <strong>', $txt['package_download_filename'], ':</strong>
                            </dt>
                            <dd>
                                <input type="text" name="filename" size="44"><br>
                                <span class="smalltext">', $txt['package_download_filename_info'], '</span>
                            </dd>
                        </dl>
                        <input type="submit" value="', $txt['download'], '" class="button">
                    </form>
                </fieldset>
            </div><!-- .windowbg -->
        </div><!-- .new_package_content -->
    </div><!-- #admin_form_wrapper -->';
}

/**
 * Confirm package operation
 */
function template_package_confirm()
{
    global $context, $txt;

    echo '
        <div class="cat_bar">
            <h3 class="catbg">', $context['page_title'], '</h3>
        </div>
        <div class="windowbg">
            <p>', $context['confirm_message'], '</p>
            <a href="', $context['proceed_href'], '">[ ', $txt['package_confirm_proceed'], ' ]</a> <a href="JavaScript:history.go(-1);">[ ', $txt['package_confirm_go_back'], ' ]</a>
        </div>';
}

/**
 * List packages.
 */
function template_package_list()
{
    global $context, $txt, $smcFunc;

    echo '
        <div class="cat_bar">
            <h3 class="catbg">', $context['page_title'], '</h3>
        </div>
        <div class="windowbg">';

    // No packages, as yet.
    if (empty($context['package_list']))
        echo '
            <ul>
                <li>', $txt['no_packages'], '</li>
            </ul>';

    // List out the packages...
    else
    {
        echo '
            <ul id="package_list">';

        foreach ($context['package_list'] as $i => $packageSection)
        {
            echo '
                <li>
                    <strong><span id="ps_img_', $i, '" class="toggle_up" alt="*" style="display: none;"></span> ', $packageSection['title'], '</strong>';

            if (!empty($packageSection['text']))
                echo '
                    <div class="sub_bar">
                        <h3 class="subbg">', $packageSection['text'], '</h3>
                    </div>';

            echo '
                    <', $context['list_type'], ' id="package_section_', $i, '" class="packages">';

            foreach ($packageSection['items'] as $id => $package)
            {
                echo '
                        <li>';

                // Textual message. Could be empty just for a blank line...
                if ($package['is_text'])
                    echo '
                            ', empty($package['name']) ? '&nbsp;' : $package['name'];

                // This is supposed to be a rule..
                elseif ($package['is_line'])
                    echo '
                            <hr>';

                // A remote link.
                elseif ($package['is_remote'])
                    echo '
                            <strong>', $package['link'], '</strong>';

                // A title?
                elseif ($package['is_heading'] || $package['is_title'])
                    echo '
                            <strong>', $package['name'], '</strong>';

                // Otherwise, it's a package.
                else
                {
                    // 1. Some mod [ Download ].
                    echo '
                        <strong><span id="ps_img_', $i, '_pkg_', $id, '" class="toggle_up" alt="*" style="display: none;"></span> ', $package['can_install'] || !empty($package['can_emulate_install']) ? '<strong>' . $package['name'] . '</strong> <a href="' . $package['download']['href'] . '">[ ' . $txt['download'] . ' ]</a>' : $package['name'], '</strong>
                        <ul id="package_section_', $i, '_pkg_', $id, '" class="package_section">';

                    // Show the mod type?
                    if ($package['type'] != '')
                        echo '
                            <li class="package_section">
                                ', $txt['package_type'], ':&nbsp; ', $smcFunc['ucwords']($smcFunc['strtolower']($package['type'])), '
                            </li>';

                    // Show the version number?
                    if ($package['version'] != '')
                        echo '
                            <li class="package_section">
                                ', $txt['mod_version'], ':&nbsp; ', $package['version'], '
                            </li>';

                    // How 'bout the author?
                    if (!empty($package['author']) && $package['author']['name'] != '' && isset($package['author']['link']))
                        echo '
                            <li class="package_section">
                                ', $txt['mod_author'], ':&nbsp; ', $package['author']['link'], '
                            </li>';

                    // The homepage...
                    if ($package['author']['website']['link'] != '')
                        echo '
                            <li class="package_section">
                                ', $txt['author_website'], ':&nbsp; ', $package['author']['website']['link'], '
                            </li>';

                    // Description: bleh bleh!
                    // Location of file: http://someplace/.
                    echo '
                            <li class="package_section">
                                ', $txt['file_location'], ':&nbsp; <a href="', $package['href'], '">', $package['href'], '</a>
                            </li>
                            <li class="package_section">
                                <div class="information">
                                    ', $txt['package_description'], ':&nbsp; ', $package['description'], '
                                </div>
                            </li>
                        </ul>';
                }

                echo '
                    </li>';
            }
            echo '
                </', $context['list_type'], '>
                </li>';
        }
        echo '
            </ul>';
    }

    echo '
        </div><!-- .windowbg -->';

    // Now go through and turn off all the sections.
    if (!empty($context['package_list']))
    {
        $section_count = count($context['package_list']);

        echo '
    <script>';

        foreach ($context['package_list'] as $section => $ps)
        {
            echo '
        var oPackageServerToggle_', $section, ' = new smc_Toggle({
            bToggleEnabled: true,
            bCurrentlyCollapsed: ', count($ps['items']) == 1 || $section_count == 1 ? 'false' : 'true', ',
            aSwappableContainers: [
                \'package_section_', $section, '\'
            ],
            aSwapImages: [
                {
                    sId: \'ps_img_', $section, '\',
                    altExpanded: \'*\',
                    altCollapsed: \'*\'
                }
            ]
        });';

            foreach ($ps['items'] as $id => $package)
            {
                if (!$package['is_text'] && !$package['is_line'] && !$package['is_remote'])
                    echo '
        var oPackageToggle_', $section, '_pkg_', $id, ' = new smc_Toggle({
            bToggleEnabled: true,
            bCurrentlyCollapsed: true,
            aSwappableContainers: [
                \'package_section_', $section, '_pkg_', $id, '\'
            ],
            aSwapImages: [
                {
                    sId: \'ps_img_', $section, '_pkg_', $id, '\',
                    altExpanded: \'*\',
                    altCollapsed: \'*\'
                }
            ]
        });';
            }
        }

        echo '
    </script>';
    }
}

/**
 * Confirmation page showing a package was uploaded/downloaded successfully.
 */
function template_downloaded()
{
    global $context, $txt, $scripturl;

    echo '
        <div class="cat_bar">
            <h3 class="catbg">', $context['page_title'], '</h3>
        </div>
        <div class="windowbg">
            <p>
                ', (empty($context['package_server']) ? $txt['package_uploaded_successfully'] : $txt['package_downloaded_successfully']), '
            </p>
            <ul>
                <li>
                    <span class="floatleft"><strong>', $context['package']['name'], '</strong></span>
                    <span class="package_server floatright">', $context['package']['list_files']['link'], '</span>
                    <span class="package_server floatright">', $context['package']['install']['link'], '</span>
                </li>
            </ul>
            <br><br>
            <p><a href="', $scripturl, '?action=admin;area=packages;get', (isset($context['package_server']) ? ';sa=browse;server=' . $context['package_server'] : ''), '">[ ', $txt['back'], ' ]</a></p>
        </div>';
}

/**
 * Installation options - FTP info and backup settings
 */
function template_install_options()
{
    global $context, $txt, $scripturl;

    if (!empty($context['saved_successful']))
        echo '
    <div class="infobox">', $txt['settings_saved'], '</div>';

    echo '
        <div class="cat_bar">
            <h3 class="catbg">', $txt['package_install_options'], '</h3>
        </div>
        <div class="information noup">
            ', $txt['package_install_options_ftp_why'], '
        </div>
        <div class="windowbg noup">
            <form action="', $scripturl, '?action=admin;area=packages;sa=options" method="post" accept-charset="', $context['character_set'], '">
                <dl class="settings">
                    <dt>
                        <label for="pack_server"><strong>', $txt['package_install_options_ftp_server'], ':</strong></label>
                    </dt>
                    <dd>
                        <input type="text" name="pack_server" id="pack_server" value="', $context['package_ftp_server'], '" size="30">
                    </dd>
                    <dt>
                        <label for="pack_port"><strong>', $txt['package_install_options_ftp_port'], ':</strong></label>
                    </dt>
                    <dd>
                        <input type="text" name="pack_port" id="pack_port" size="3" value="', $context['package_ftp_port'], '">
                    </dd>
                    <dt>
                        <label for="pack_user"><strong>', $txt['package_install_options_ftp_user'], ':</strong></label>
                    </dt>
                    <dd>
                        <input type="text" name="pack_user" id="pack_user" value="', $context['package_ftp_username'], '" size="30">
                    </dd>
                    <dt>
                        <label for="package_make_backups">', $txt['package_install_options_make_backups'], '</label>
                    </dt>
                    <dd>
                        <input type="checkbox" name="package_make_backups" id="package_make_backups" value="1"', $context['package_make_backups'] ? ' checked' : '', '>
                    </dd>
                    <dt>
                        <label for="package_make_full_backups">', $txt['package_install_options_make_full_backups'], '</label>
                    </dt>
                    <dd>
                        <input type="checkbox" name="package_make_full_backups" id="package_make_full_backups" value="1"', $context['package_make_full_backups'] ? ' checked' : '', '>
                    </dd>
                </dl>

                <input type="submit" name="save" value="', $txt['save'], '" class="button">
                <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
            </form>
        </div><!-- .windowbg -->';
}

/**
 * CHMOD control form
 *
 * @return bool False if nothing to do.
 */
function template_control_chmod()
{
    global $context, $txt;

    // Nothing to do? Brilliant!
    if (empty($context['package_ftp']))
        return false;

    if (empty($context['package_ftp']['form_elements_only']))
    {
        echo '
                ', sprintf($txt['package_ftp_why'], 'document.getElementById(\'need_writable_list\').style.display = \'\'; return false;'), '<br>
                <div id="need_writable_list" class="smalltext">
                    ', $txt['package_ftp_why_file_list'], '
                    <ul style="display: inline;">';

        if (!empty($context['notwritable_files']))
            foreach ($context['notwritable_files'] as $file)
                echo '
                        <li>', $file, '</li>';

        echo '
                    </ul>';

        if (!$context['server']['is_windows'])
            echo '
                    <hr>
                    ', $txt['package_chmod_linux'], '<br>
                    <samp># chmod a+w ', implode(' ', $context['notwritable_files']), '</samp>';

        echo '
                </div><!-- #need_writable_list -->';
    }

    echo '
                <div class="bordercolor" id="ftp_error_div" style="', (!empty($context['package_ftp']['error']) ? '' : 'display:none;'), 'padding: 1px; margin: 1ex;">
                    <div class="windowbg" id="ftp_error_innerdiv" style="padding: 1ex;">
                        <samp id="ftp_error_message">', !empty($context['package_ftp']['error']) ? $context['package_ftp']['error'] : '', '</samp>
                    </div>
                </div>';

    if (!empty($context['package_ftp']['destination']))
        echo '
                <form action="', $context['package_ftp']['destination'], '" method="post" accept-charset="', $context['character_set'], '">';

    echo '
                    <fieldset>
                    <dl class="settings">
                        <dt>
                            <label for="ftp_server">', $txt['package_ftp_server'], ':</label>
                        </dt>
                        <dd>
                            <input type="text" size="30" name="ftp_server" id="ftp_server" value="', $context['package_ftp']['server'], '">
                            <label for="ftp_port">', $txt['package_ftp_port'], ':</label>
                            <input type="text" size="3" name="ftp_port" id="ftp_port" value="', $context['package_ftp']['port'], '">
                        </dd>
                        <dt>
                            <label for="ftp_username">', $txt['package_ftp_username'], ':</label>
                        </dt>
                        <dd>
                            <input type="text" size="50" name="ftp_username" id="ftp_username" value="', $context['package_ftp']['username'], '">
                        </dd>
                        <dt>
                            <label for="ftp_password">', $txt['package_ftp_password'], ':</label>
                        </dt>
                        <dd>
                            <input type="password" size="50" name="ftp_password" id="ftp_password">
                        </dd>
                        <dt>
                            <label for="ftp_path">', $txt['package_ftp_path'], ':</label>
                        </dt>
                        <dd>
                            <input type="text" size="50" name="ftp_path" id="ftp_path" value="', $context['package_ftp']['path'], '">
                        </dd>
                    </dl>
                    </fieldset>';

    if (empty($context['package_ftp']['form_elements_only']))
        echo '
                    <div class="righttext" style="margin: 1ex;">
                        <span id="test_ftp_placeholder_full"></span>
                        <input type="submit" value="', $txt['package_proceed'], '" class="button">
                    </div>';

    if (!empty($context['package_ftp']['destination']))
        echo '
                    <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
                </form>';

    // Hide the details of the list.
    if (empty($context['package_ftp']['form_elements_only']))
        echo '
                <script>
                    document.getElementById(\'need_writable_list\').style.display = \'none\';
                </script>';

    // Quick generate the test button.
    echo '
                <script>
                    // Generate a "test ftp" button.
                    var generatedButton = false;
                    function generateFTPTest()
                    {
                        // Don\'t ever call this twice!
                        if (generatedButton)
                            return false;
                        generatedButton = true;

                        // No XML?
                        if (!window.XMLHttpRequest || (!document.getElementById("test_ftp_placeholder") && !document.getElementById("test_ftp_placeholder_full")))
                            return false;

                        var ftpTest = document.createElement("input");
                        ftpTest.type = "button";
                        ftpTest.onclick = testFTP;

                        if (document.getElementById("test_ftp_placeholder"))
                        {
                            ftpTest.value = "', $txt['package_ftp_test'], '";
                            document.getElementById("test_ftp_placeholder").appendChild(ftpTest);
                        }
                        else
                        {
                            ftpTest.value = "', $txt['package_ftp_test_connection'], '";
                            document.getElementById("test_ftp_placeholder_full").appendChild(ftpTest);
                        }
                    }
                    function testFTPResults(oXMLDoc)
                    {
                        ajax_indicator(false);

                        // This assumes it went wrong!
                        var wasSuccess = false;
                        var message = "', addcslashes($txt['package_ftp_test_failed'], "'"), '";

                        var results = oXMLDoc.getElementsByTagName(\'results\')[0].getElementsByTagName(\'result\');
                        if (results.length > 0)
                        {
                            if (results[0].getAttribute(\'success\') == 1)
                                wasSuccess = true;
                            message = results[0].firstChild.nodeValue;
                        }

                        document.getElementById("ftp_error_div").style.display = "";
                        document.getElementById("ftp_error_div").style.backgroundColor = wasSuccess ? "green" : "red";
                        document.getElementById("ftp_error_innerdiv").style.backgroundColor = wasSuccess ? "#DBFDC7" : "#FDBDBD";

                        setInnerHTML(document.getElementById("ftp_error_message"), message);
                    }
                    generateFTPTest();
                </script>';

    // Make sure the button gets generated last.
    $context['insert_after_template'] .= '
                <script>
                    generateFTPTest();
                </script>';
}

/**
 * Wrapper for the above template function showing that FTP is required
 */
function template_ftp_required()
{
    global $txt;

    echo '
        <fieldset>
            <legend>
                ', $txt['package_ftp_necessary'], '
            </legend>
            <div class="ftp_details">
                ', template_control_chmod(), '
            </div>
        </fieldset>';
}

/**
 * View operation details.
 */
function template_view_operations()
{
    global $context, $txt, $settings, $modSettings;

    echo '<!DOCTYPE html>
<html', $context['right_to_left'] ? ' dir="rtl"' : '', '>
    <head>
        <meta charset="', $context['character_set'], '">
        <title>', $txt['operation_title'], '</title>
        <link rel="stylesheet" href="', $settings['theme_url'], '/css/index', $context['theme_variant'], '.css', $context['browser_cache'], '">
        <link rel="stylesheet" href="', $settings['theme_url'], '/css/admin.css', $context['browser_cache'], '">
        <script src="', $settings['default_theme_url'], '/scripts/script.js', $context['browser_cache'], '"></script>
        <script src="', $settings['default_theme_url'], '/scripts/theme.js', $context['browser_cache'], '"></script>
    </head>
    <body>
        <div class="padding windowbg">
            <div class="padding">
                ', $context['operations']['search'], '
            </div>
            <div class="padding">
                ', $context['operations']['replace'], '
            </div>
        </div>
    </body>
</html>';
}

/**
 * The file permissions page.
 */
function template_file_permissions()
{
    global $txt, $scripturl, $context;

    // This will handle expanding the selection.
    echo '
    <script>
        var oRadioValues = {
            0: "read",
            1: "writable",
            2: "execute",
            3: "custom",
            4: "no_change"
        }
        function dynamicAddMore()
        {
            ajax_indicator(true);

            getXMLDocument(smf_prepareScriptUrl(smf_scripturl) + \'action=admin;area=packages;fileoffset=\' + (parseInt(this.offset) + ', $context['file_limit'], ') + \';onlyfind=\' + escape(this.path) + \';sa=perms;xml;', $context['session_var'], '=', $context['session_id'], '\', onNewFolderReceived);
        }

        // Getting something back?
        function onNewFolderReceived(oXMLDoc)
        {
            ajax_indicator(false);

            var fileItems = oXMLDoc.getElementsByTagName(\'folders\')[0].getElementsByTagName(\'folder\');

            // No folders, no longer worth going further.
            if (fileItems.length < 1)
            {
                if (oXMLDoc.getElementsByTagName(\'roots\')[0].getElementsByTagName(\'root\')[0])
                {
                    var rootName = oXMLDoc.getElementsByTagName(\'roots\')[0].getElementsByTagName(\'root\')[0].firstChild.nodeValue;
                    var itemLink = document.getElementById(\'link_\' + rootName);

                    // Move the children up.
                    for (i = 0; i <= itemLink.childNodes.length; i++)
                        itemLink.parentNode.insertBefore(itemLink.childNodes[0], itemLink);

                    // And remove the link.
                    itemLink.parentNode.removeChild(itemLink);
                }
                return false;
            }
            var tableHandle = false;
            var isMore = false;
            var ident = "";
            var my_ident = "";
            var curLevel = 0;

            for (var i = 0; i < fileItems.length; i++)
            {
                if (fileItems[i].getAttribute(\'more\') == 1)
                {
                    isMore = true;
                    var curOffset = fileItems[i].getAttribute(\'offset\');
                }

                if (fileItems[i].getAttribute(\'more\') != 1 && document.getElementById("insert_div_loc_" + fileItems[i].getAttribute(\'ident\')))
                {
                    ident = fileItems[i].getAttribute(\'ident\');
                    my_ident = fileItems[i].getAttribute(\'my_ident\');
                    curLevel = fileItems[i].getAttribute(\'level\') * 5;
                    curPath = fileItems[i].getAttribute(\'path\');

                    // Get where we\'re putting it next to.
                    tableHandle = document.getElementById("insert_div_loc_" + fileItems[i].getAttribute(\'ident\'));

                    var curRow = document.createElement("tr");
                    curRow.className = "windowbg";
                    curRow.id = "content_" + my_ident;
                    curRow.style.display = "";
                    var curCol = document.createElement("td");
                    curCol.className = "smalltext";
                    curCol.width = "40%";

                    // This is the name.
                    var fileName = document.createTextNode(fileItems[i].firstChild.nodeValue);

                    // Start by wacking in the spaces.
                    setInnerHTML(curCol, repeatString("&nbsp;", curLevel));

                    // Create the actual text.
                    if (fileItems[i].getAttribute(\'folder\') == 1)
                    {
                        var linkData = document.createElement("a");
                        linkData.name = "fol_" + my_ident;
                        linkData.id = "link_" + my_ident;
                        linkData.href = \'#\';
                        linkData.path = curPath + "/" + fileItems[i].firstChild.nodeValue;
                        linkData.ident = my_ident;
                        linkData.onclick = dynamicExpandFolder;

                        var folderImage = document.createElement("span");
                        folderImage.className = "main_icons folder";
                        linkData.appendChild(folderImage);

                        linkData.appendChild(fileName);
                        curCol.appendChild(linkData);
                    }
                    else
                        curCol.appendChild(fileName);

                    curRow.appendChild(curCol);

                    // Right, the permissions.
                    curCol = document.createElement("td");
                    curCol.className = "smalltext";

                    var writeSpan = document.createElement("span");
                    writeSpan.className = fileItems[i].getAttribute(\'writable\') ? "green" : "red";
                    setInnerHTML(writeSpan, fileItems[i].getAttribute(\'writable\') ? \'', $txt['package_file_perms_writable'], '\' : \'', $txt['package_file_perms_not_writable'], '\');
                    curCol.appendChild(writeSpan);

                    if (fileItems[i].getAttribute(\'permissions\'))
                    {
                        var permData = document.createTextNode("\u00a0(', $txt['package_file_perms_chmod'], ': " + fileItems[i].getAttribute(\'permissions\') + ")");
                        curCol.appendChild(permData);
                    }

                    curRow.appendChild(curCol);

                    // Now add the five radio buttons.
                    for (j = 0; j < 5; j++)
                    {
                        curCol = document.createElement("td");
                        curCol.className = "centertext perm_" + oRadioValues[j];
                        curCol.align = "center";

                        var curInput = createNamedElement("input", "permStatus[" + curPath + "/" + fileItems[i].firstChild.nodeValue + "]", j == 4 ? "checked" : "");
                        curInput.type = "radio";
                        curInput.checked = "checked";
                        curInput.value = oRadioValues[j];

                        curCol.appendChild(curInput);
                        curRow.appendChild(curCol);
                    }

                    // Put the row in.
                    tableHandle.parentNode.insertBefore(curRow, tableHandle);

                    // Put in a new dummy section?
                    if (fileItems[i].getAttribute(\'folder\') == 1)
                    {
                        var newRow = document.createElement("tr");
                        newRow.id = "insert_div_loc_" + my_ident;
                        newRow.style.display = "none";
                        tableHandle.parentNode.insertBefore(newRow, tableHandle);
                        var newCol = document.createElement("td");
                        newCol.colspan = 2;
                        newRow.appendChild(newCol);
                    }
                }
            }

            // Is there some more to remove?
            if (document.getElementById("content_" + ident + "_more"))
            {
                document.getElementById("content_" + ident + "_more").parentNode.removeChild(document.getElementById("content_" + ident + "_more"));
            }

            // Add more?
            if (isMore && tableHandle)
            {
                // Create the actual link.
                var linkData = document.createElement("a");
                linkData.href = \'#fol_\' + my_ident;
                linkData.path = curPath;
                linkData.offset = curOffset;
                linkData.onclick = dynamicAddMore;

                linkData.appendChild(document.createTextNode(\'', $txt['package_file_perms_more_files'], '\'));

                curRow = document.createElement("tr");
                curRow.className = "windowbg";
                curRow.id = "content_" + ident + "_more";
                tableHandle.parentNode.insertBefore(curRow, tableHandle);
                curCol = document.createElement("td");
                curCol.className = "smalltext";
                curCol.width = "40%";

                setInnerHTML(curCol, repeatString("&nbsp;", curLevel));
                curCol.appendChild(document.createTextNode(\'\\u00ab \'));
                curCol.appendChild(linkData);
                curCol.appendChild(document.createTextNode(\' \\u00bb\'));

                curRow.appendChild(curCol);
                curCol = document.createElement("td");
                curCol.className = "smalltext";
                curRow.appendChild(curCol);
            }

            // Keep track of it.
            var curInput = createNamedElement("input", "back_look[]");
            curInput.type = "hidden";
            curInput.value = curPath;

            curCol.appendChild(curInput);
        }
    </script>';

    echo '
    <div class="noticebox">
        <div>
            <strong>', $txt['package_file_perms_warning'], ':</strong>
            <div class="smalltext">
                <ol style="margin-top: 2px; margin-bottom: 2px">
                    ', $txt['package_file_perms_warning_desc'], '
                </ol>
            </div>
        </div>
    </div>

    <form action="', $scripturl, '?action=admin;area=packages;sa=perms;', $context['session_var'], '=', $context['session_id'], '" method="post" accept-charset="', $context['character_set'], '">
        <div class="cat_bar">
            <h3 class="catbg">
                <span class="floatleft">', $txt['package_file_perms'], '</span><span class="perms_status floatright">', $txt['package_file_perms_new_status'], '</span>
            </h3>
        </div>
        <table class="table_grid">
            <thead>
                <tr class="title_bar">
                    <th class="lefttext" width="30%">', $txt['package_file_perms_name'], '</th>
                    <th width="30%" class="lefttext">', $txt['package_file_perms_status'], '</th>
                    <th width="8%"><span class="file_permissions">', $txt['package_file_perms_status_read'], '</span></th>
                    <th width="8%"><span class="file_permissions">', $txt['package_file_perms_status_write'], '</span></th>
                    <th width="8%"><span class="file_permissions">', $txt['package_file_perms_status_execute'], '</span></th>
                    <th width="8%"><span class="file_permissions">', $txt['package_file_perms_status_custom'], '</span></th>
                    <th width="8%"><span class="file_permissions">', $txt['package_file_perms_status_no_change'], '</span></th>
                </tr>
            </thead>
            <tbody>';

    foreach ($context['file_tree'] as $name => $dir)
    {
        echo '
                <tr class="windowbg">
                    <td width="30%">
                        <strong>';

        if (!empty($dir['type']) && ($dir['type'] == 'dir' || $dir['type'] == 'dir_recursive'))
            echo '
                            <span class="main_icons folder"></span>';

        echo '
                            ', $name, '
                        </strong>
                    </td>
                    <td width="30%">
                        <span style="color: ', ($dir['perms']['chmod'] ? 'green' : 'red'), '">', ($dir['perms']['chmod'] ? $txt['package_file_perms_writable'] : $txt['package_file_perms_not_writable']), '</span>
                        ', ($dir['perms']['perms'] ? ' (' . $txt['package_file_perms_chmod'] . ': ' . substr(sprintf('%o', $dir['perms']['perms']), -4) . ')' : ''), '
                    </td>
                    <td class="centertext perm_read">
                        <input type="radio" name="permStatus[', $name, ']" value="read" class="centertext">
                    </td>
                    <td class="centertext perm_writable">
                        <input type="radio" name="permStatus[', $name, ']" value="writable" class="centertext">
                    </td>
                    <td class="centertext perm_execute">
                        <input type="radio" name="permStatus[', $name, ']" value="execute" class="centertext">
                    </td>
                    <td class="centertext perm_custom">
                        <input type="radio" name="permStatus[', $name, ']" value="custom" class="centertext">
                    </td>
                    <td class="centertext perm_no_change">
                        <input type="radio" name="permStatus[', $name, ']" value="no_change" checked class="centertext">
                    </td>
                </tr>';

        if (!empty($dir['contents']))
            template_permission_show_contents($name, $dir['contents'], 1);
    }

    echo '
            </tbody>
        </table>
        <br>
        <div class="cat_bar">
            <h3 class="catbg">', $txt['package_file_perms_change'], '</h3>
        </div>
        <div class="windowbg">
            <fieldset>
                <dl>
                    <dt>
                        <input type="radio" name="method" value="individual" checked id="method_individual">
                        <label for="method_individual"><strong>', $txt['package_file_perms_apply'], '</strong></label>
                    </dt>
                    <dd>
                        <em class="smalltext">', $txt['package_file_perms_custom'], ': <input type="text" name="custom_value" value="0755" maxlength="4" size="5"> <a href="', $scripturl, '?action=helpadmin;help=chmod_flags" onclick="return reqOverlayDiv(this.href);" class="help">(?)</a></em>
                    </dd>
                    <dt>
                        <input type="radio" name="method" value="predefined" id="method_predefined">
                        <label for="method_predefined"><strong>', $txt['package_file_perms_predefined'], ':</strong></label>
                        <select name="predefined" onchange="document.getElementById(\'method_predefined\').checked = \'checked\';">
                            <option value="restricted" selected>', $txt['package_file_perms_pre_restricted'], '</option>
                            <option value="standard">', $txt['package_file_perms_pre_standard'], '</option>
                            <option value="free">', $txt['package_file_perms_pre_free'], '</option>
                        </select>
                    </dt>
                    <dd>
                        <em class="smalltext">', $txt['package_file_perms_predefined_note'], '</em>
                    </dd>
                </dl>
            </fieldset>';

    // Likely to need FTP?
    if (empty($context['ftp_connected']))
        echo '
            <p>
                ', $txt['package_file_perms_ftp_details'], ':
            </p>
            ', template_control_chmod(), '
            <div class="noticebox">', $txt['package_file_perms_ftp_retain'], '</div>';

    echo '
            <span id="test_ftp_placeholder_full"></span>
            <input type="hidden" name="action_changes" value="1">
            <input type="submit" value="', $txt['package_file_perms_go'], '" name="go" class="button">
        </div><!-- .windowbg -->';

    // Any looks fors we've already done?
    foreach ($context['look_for'] as $path)
        echo '
        <input type="hidden" name="back_look[]" value="', $path, '">';

    echo '
    </form>
    <br>';
}

/**
 * Shows permissions for items within a directory (called from template_file_permissions)
 *
 * @param string $ident A unique ID - typically the directory name
 * @param array $contents An array of items within the directory
 * @param int $level How far to go inside the directory
 * @param bool $has_more Whether there are more files to display besides what's in $contents
 */
function template_permission_show_contents($ident, $contents, $level, $has_more = false)
{
    global $txt, $scripturl, $context;
    $js_ident = preg_replace('~[^A-Za-z0-9_\-=:]~', ':-:', $ident);

    // Have we actually done something?
    $drawn_div = false;

    foreach ($contents as $name => $dir)
    {
        if (isset($dir['perms']))
        {
            if (!$drawn_div)
            {
                $drawn_div = true;
                echo '
            </tbody>
            <tbody class="table_grid" id="', $js_ident, '">';
            }

            $cur_ident = preg_replace('~[^A-Za-z0-9_\-=:]~', ':-:', $ident . '/' . $name);

            echo '
                <tr class="windowbg" id="content_', $cur_ident, '">
                    <td class="smalltext" width="30%">' . str_repeat('&nbsp;', $level * 5), '
                    ', (!empty($dir['type']) && $dir['type'] == 'dir_recursive') || !empty($dir['list_contents']) ? '<a id="link_' . $cur_ident . '" href="' . $scripturl . '?action=admin;area=packages;sa=perms;find=' . base64_encode($ident . '/' . $name) . ';back_look=' . $context['back_look_data'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '#fol_' . $cur_ident . '" onclick="return expandFolder(\'' . $cur_ident . '\', \'' . addcslashes($ident . '/' . $name, "'\\") . '\');">' : '';

            if (!empty($dir['type']) && ($dir['type'] == 'dir' || $dir['type'] == 'dir_recursive'))
                echo '
                        <span class="main_icons folder"></span>';

            echo '
                        ', $name, '
                        ', (!empty($dir['type']) && $dir['type'] == 'dir_recursive') || !empty($dir['list_contents']) ? '</a>' : '', '
                    </td>
                    <td class="smalltext">
                        <span class="', ($dir['perms']['chmod'] ? 'success' : 'error'), '">', ($dir['perms']['chmod'] ? $txt['package_file_perms_writable'] : $txt['package_file_perms_not_writable']), '</span>
                        ', ($dir['perms']['perms'] ? ' (' . $txt['package_file_perms_chmod'] . ': ' . substr(sprintf('%o', $dir['perms']['perms']), -4) . ')' : ''), '
                    </td>
                    <td class="centertext perm_read"><input type="radio" name="permStatus[', $ident . '/' . $name, ']" value="read"></td>
                    <td class="centertext perm_writable"><input type="radio" name="permStatus[', $ident . '/' . $name, ']" value="writable"></td>
                    <td class="centertext perm_execute"><input type="radio" name="permStatus[', $ident . '/' . $name, ']" value="execute"></td>
                    <td class="centertext perm_custom"><input type="radio" name="permStatus[', $ident . '/' . $name, ']" value="custom"></td>
                    <td class="centertext perm_no_change"><input type="radio" name="permStatus[', $ident . '/' . $name, ']" value="no_change" checked></td>
                </tr>
                <tr id="insert_div_loc_' . $cur_ident . '" style="display: none;"><td></td></tr>';

            if (!empty($dir['contents']))
                template_permission_show_contents($ident . '/' . $name, $dir['contents'], $level + 1, !empty($dir['more_files']));
        }
    }

    // We have more files to show?
    if ($has_more)
        echo '
                <tr class="windowbg" id="content_', $js_ident, '_more">
                    <td class="smalltext" width="40%">' . str_repeat('&nbsp;', $level * 5), '
                        &#171; <a href="' . $scripturl . '?action=admin;area=packages;sa=perms;find=' . base64_encode($ident) . ';fileoffset=', ($context['file_offset'] + $context['file_limit']), ';' . $context['session_var'] . '=' . $context['session_id'] . '#fol_' . preg_replace('~[^A-Za-z0-9_\-=:]~', ':-:', $ident) . '">', $txt['package_file_perms_more_files'], '</a> &#187;
                    </td>
                    <td colspan="6"></td>
                </tr>';

    if ($drawn_div)
    {
        // Hide anything too far down the tree.
        $isFound = false;
        foreach ($context['look_for'] as $tree)
            if (substr($tree, 0, strlen($ident)) == $ident)
                $isFound = true;

        if ($level > 1 && !$isFound)
            echo '
        <script>
            expandFolder(\'', $js_ident, '\', \'\');
        </script>';
    }
}

/**
 * A progress page showing what permissions changes are being applied
 */
function template_action_permissions()
{
    global $txt, $scripturl, $context;

    $countDown = 3;

    echo '
        <form action="', $scripturl, '?action=admin;area=packages;sa=perms;', $context['session_var'], '=', $context['session_id'], '" id="perm_submit" method="post" accept-charset="', $context['character_set'], '">
            <div class="cat_bar">
                <h3 class="catbg">', $txt['package_file_perms_applying'], '</h3>
            </div>';

    if (!empty($context['skip_ftp']))
        echo '
            <div class="errorbox">
                ', $txt['package_file_perms_skipping_ftp'], '
            </div>';

    // How many have we done?
    $remaining_items = count($context['method'] == 'individual' ? $context['to_process'] : $context['directory_list']);
    $progress_message = sprintf($context['method'] == 'individual' ? $txt['package_file_perms_items_done'] : $txt['package_file_perms_dirs_done'], $context['total_items'] - $remaining_items, $context['total_items']);
    $progress_percent = round(($context['total_items'] - $remaining_items) / $context['total_items'] * 100, 1);

    echo '
            <div class="windowbg">
                <div>
                    <strong>', $progress_message, '</strong><br>
                    <div class="progress_bar progress_blue">
                        <span>', $progress_percent, '%</span>
                        <div class="bar" style="width: ', $progress_percent, '%;"></div>
                    </div>
                </div>';

    // Second progress bar for a specific directory?
    if ($context['method'] != 'individual' && !empty($context['total_files']))
    {
        $file_progress_message = sprintf($txt['package_file_perms_files_done'], $context['file_offset'], $context['total_files']);
        $file_progress_percent = round($context['file_offset'] / $context['total_files'] * 100, 1);

        echo '
                <br>
                <div>
                    <strong>', $file_progress_message, '</strong><br>
                    <div class="progress_bar">
                        <span>', $file_progress_percent, '%</span>
                        <div class="bar" style="width: ', $file_progress_percent, '%;"></div>
                    </div>
                </div>';
    }

    echo '
                <br>';

    // Put out the right hidden data.
    if ($context['method'] == 'individual')
        echo '
                <input type="hidden" name="custom_value" value="', $context['custom_value'], '">
                <input type="hidden" name="totalItems" value="', $context['total_items'], '">
                <input type="hidden" name="toProcess" value="', $context['to_process_encode'], '">';
    else
        echo '
                <input type="hidden" name="predefined" value="', $context['predefined_type'], '">
                <input type="hidden" name="fileOffset" value="', $context['file_offset'], '">
                <input type="hidden" name="totalItems" value="', $context['total_items'], '">
                <input type="hidden" name="dirList" value="', $context['directory_list_encode'], '">
                <input type="hidden" name="specialFiles" value="', $context['special_files_encode'], '">';

    // Are we not using FTP for whatever reason.
    if (!empty($context['skip_ftp']))
        echo '
                <input type="hidden" name="skip_ftp" value="1">';

    // Retain state.
    foreach ($context['back_look_data'] as $path)
        echo '
                <input type="hidden" name="back_look[]" value="', $path, '">';

    echo '
                <input type="hidden" name="method" value="', $context['method'], '">
                <input type="hidden" name="action_changes" value="1">
                <div class="righttext padding">
                    <input type="submit" name="go" id="cont" value="', $txt['not_done_continue'], '" class="button">
                </div>
            </div><!-- .windowbg -->
        </form>';

    // Just the countdown stuff
    echo '
    <script>
        var countdown = ', $countDown, ';
        doAutoSubmit();

        function doAutoSubmit()
        {
            if (countdown == 0)
                document.forms.perm_submit.submit();
            else if (countdown == -1)
                return;

            document.getElementById(\'cont\').value = "', $txt['not_done_continue'], ' (" + countdown + ")";
            countdown--;

            setTimeout("doAutoSubmit();", 1000);
        }
    </script>';
}

?>