summaryrefslogtreecommitdiffstats
path: root/usr
diff options
context:
space:
mode:
Diffstat (limited to 'usr')
-rwxr-xr-xusr/local/captiveportal/index.php73
-rw-r--r--usr/local/captiveportal/radius_accounting.inc4
-rw-r--r--usr/local/pkg/miniupnpd.inc21
-rw-r--r--usr/local/pkg/miniupnpd.xml6
-rw-r--r--usr/local/pkg/openntpd.xml1
-rwxr-xr-xusr/local/www/bandwidth_by_ip.php77
-rwxr-xr-xusr/local/www/carp_status.php50
-rwxr-xr-xusr/local/www/diag_arp.php3
-rwxr-xr-xusr/local/www/diag_backup.php168
-rwxr-xr-xusr/local/www/diag_dhcp_leases.php8
-rw-r--r--usr/local/www/diag_dns.php112
-rwxr-xr-xusr/local/www/diag_dump_states.php4
-rw-r--r--usr/local/www/diag_ipsec.php26
-rwxr-xr-xusr/local/www/diag_ipsec_sad.php22
-rwxr-xr-xusr/local/www/diag_ipsec_spd.php21
-rwxr-xr-xusr/local/www/diag_logs_filter.php81
-rwxr-xr-xusr/local/www/diag_logs_filter_dynamic.php5
-rw-r--r--usr/local/www/diag_logs_filter_summary.php218
-rwxr-xr-xusr/local/www/diag_logs_settings.php7
-rwxr-xr-xusr/local/www/diag_nanobsd.php290
-rw-r--r--usr/local/www/diag_showbogons.php100
-rw-r--r--usr/local/www/diag_system_pftop.php4
-rw-r--r--usr/local/www/easyrule.inc251
-rw-r--r--usr/local/www/easyrule.php132
-rw-r--r--[-rwxr-xr-x]usr/local/www/edit.php7
-rwxr-xr-xusr/local/www/exec.php8
-rwxr-xr-xusr/local/www/fbegin.inc11
-rw-r--r--usr/local/www/filter_log.inc82
-rw-r--r--usr/local/www/filterparser.php4
-rwxr-xr-xusr/local/www/firewall_aliases.php10
-rwxr-xr-xusr/local/www/firewall_aliases_edit.php161
-rwxr-xr-xusr/local/www/firewall_nat.php24
-rwxr-xr-xusr/local/www/firewall_nat_1to1.php11
-rwxr-xr-xusr/local/www/firewall_nat_1to1_edit.php16
-rwxr-xr-xusr/local/www/firewall_nat_edit.php77
-rwxr-xr-xusr/local/www/firewall_nat_out.php12
-rwxr-xr-xusr/local/www/firewall_nat_out_edit.php6
-rwxr-xr-xusr/local/www/firewall_nat_server.php161
-rwxr-xr-xusr/local/www/firewall_nat_server_edit.php159
-rwxr-xr-xusr/local/www/firewall_rules.php69
-rwxr-xr-xusr/local/www/firewall_rules_edit.php58
-rw-r--r--usr/local/www/firewall_schedule.php3
-rw-r--r--usr/local/www/firewall_schedule_edit.php13
-rwxr-xr-xusr/local/www/firewall_shaper.php16
-rwxr-xr-xusr/local/www/firewall_shaper_layer7.php12
-rwxr-xr-xusr/local/www/firewall_shaper_queues.php8
-rw-r--r--usr/local/www/firewall_shaper_vinterface.php18
-rwxr-xr-xusr/local/www/firewall_shaper_wizards.php6
-rwxr-xr-xusr/local/www/firewall_virtual_ip.php6
-rwxr-xr-xusr/local/www/firewall_virtual_ip_edit.php2
-rwxr-xr-xusr/local/www/guiconfig.inc576
-rwxr-xr-xusr/local/www/interfaces.php33
-rwxr-xr-xusr/local/www/interfaces_assign.php10
-rw-r--r--usr/local/www/interfaces_bridge.php7
-rw-r--r--usr/local/www/interfaces_bridge_edit.php9
-rw-r--r--usr/local/www/interfaces_lagg_edit.php1
-rw-r--r--usr/local/www/interfaces_ppp_edit.php11
-rwxr-xr-xusr/local/www/interfaces_qinq.php2
-rwxr-xr-xusr/local/www/interfaces_vlan_edit.php2
-rwxr-xr-xusr/local/www/javascript/row_helper.js2
-rw-r--r--usr/local/www/javascript/suggestions.js4
-rwxr-xr-xusr/local/www/javascript/ticker.js42
-rwxr-xr-xusr/local/www/load_balancer_monitor.php6
-rwxr-xr-xusr/local/www/load_balancer_monitor_edit.php3
-rwxr-xr-xusr/local/www/load_balancer_pool.php6
-rwxr-xr-xusr/local/www/load_balancer_pool_edit.php3
-rwxr-xr-xusr/local/www/load_balancer_relay_action.php6
-rwxr-xr-xusr/local/www/load_balancer_relay_action_edit.php3
-rwxr-xr-xusr/local/www/load_balancer_relay_protocol.php6
-rwxr-xr-xusr/local/www/load_balancer_relay_protocol_edit.php3
-rwxr-xr-xusr/local/www/load_balancer_virtual_server.php6
-rwxr-xr-xusr/local/www/load_balancer_virtual_server_edit.php2
-rwxr-xr-xusr/local/www/pkg_edit.php50
-rwxr-xr-xusr/local/www/pkg_mgr.php11
-rwxr-xr-xusr/local/www/pkg_mgr_install.php14
-rwxr-xr-xusr/local/www/pkg_mgr_installed.php4
-rw-r--r--usr/local/www/protochart/ProtoChart.js2653
-rw-r--r--usr/local/www/protochart/excanvas-compressed.js19
-rw-r--r--usr/local/www/protochart/excanvas.js785
-rwxr-xr-xusr/local/www/restart_httpd.php11
-rwxr-xr-xusr/local/www/services_captiveportal.php4
-rwxr-xr-xusr/local/www/services_captiveportal_filemanager.php10
-rwxr-xr-xusr/local/www/services_captiveportal_ip.php30
-rwxr-xr-xusr/local/www/services_captiveportal_ip_edit.php17
-rwxr-xr-xusr/local/www/services_captiveportal_mac.php13
-rwxr-xr-xusr/local/www/services_captiveportal_mac_edit.php12
-rw-r--r--usr/local/www/services_captiveportal_vouchers.php395
-rw-r--r--usr/local/www/services_captiveportal_vouchers_edit.php181
-rwxr-xr-xusr/local/www/services_dhcp.php483
-rwxr-xr-xusr/local/www/services_dhcp_edit.php15
-rwxr-xr-xusr/local/www/services_dnsmasq.php15
-rwxr-xr-xusr/local/www/services_dnsmasq_domainoverride_edit.php2
-rwxr-xr-xusr/local/www/services_dnsmasq_edit.php15
-rwxr-xr-xusr/local/www/services_igmpproxy.php2
-rwxr-xr-xusr/local/www/services_proxyarp.php11
-rwxr-xr-xusr/local/www/services_proxyarp_edit.php27
-rwxr-xr-xusr/local/www/services_wol.php1
-rwxr-xr-xusr/local/www/services_wol_edit.php10
-rwxr-xr-xusr/local/www/status_captiveportal.php40
-rw-r--r--usr/local/www/status_captiveportal_test.php95
-rw-r--r--usr/local/www/status_captiveportal_voucher_rolls.php109
-rw-r--r--usr/local/www/status_captiveportal_vouchers.php117
-rwxr-xr-xusr/local/www/status_gateways.php2
-rwxr-xr-xusr/local/www/status_graph.php203
-rw-r--r--usr/local/www/status_openvpn.php74
-rwxr-xr-xusr/local/www/status_queues.php2
-rwxr-xr-xusr/local/www/status_services.php3
-rwxr-xr-xusr/local/www/status_slbd_pool.php5
-rwxr-xr-xusr/local/www/status_slbd_vs.php4
-rw-r--r--usr/local/www/status_upnp.php6
-rwxr-xr-xusr/local/www/system.php9
-rw-r--r--usr/local/www/system_advanced_admin.php1
-rw-r--r--usr/local/www/system_advanced_firewall.php1
-rw-r--r--usr/local/www/system_advanced_misc.php62
-rw-r--r--usr/local/www/system_advanced_network.php36
-rw-r--r--usr/local/www/system_advanced_notifications.php147
-rw-r--r--usr/local/www/system_advanced_sysctl.php9
-rw-r--r--usr/local/www/system_camanager.php1
-rw-r--r--usr/local/www/system_certmanager.php1
-rwxr-xr-xusr/local/www/system_firmware.php57
-rwxr-xr-xusr/local/www/system_firmware_auto.php38
-rwxr-xr-xusr/local/www/system_gateway_groups.php11
-rwxr-xr-xusr/local/www/system_gateway_groups_edit.php2
-rwxr-xr-xusr/local/www/system_gateways.php11
-rwxr-xr-xusr/local/www/system_gateways_edit.php10
-rw-r--r--usr/local/www/system_groupmanager.php7
-rw-r--r--usr/local/www/system_groupmanager_addprivs.php14
-rwxr-xr-xusr/local/www/system_routes.php12
-rwxr-xr-xusr/local/www/system_routes_edit.php15
-rw-r--r--usr/local/www/system_usermanager.php1
-rw-r--r--usr/local/www/system_usermanager_addcert.php1
-rw-r--r--usr/local/www/system_usermanager_addprivs.php13
-rw-r--r--usr/local/www/themes/metallic/all.css8
-rw-r--r--usr/local/www/themes/metallic/images/button_left.gifbin534 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/button_mid.gifbin149 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/button_right.gifbin333 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/icons/icon_advanced.gifbin0 -> 306 bytes
-rw-r--r--usr/local/www/themes/metallic/images/icons/icon_advanced_s.gifbin0 -> 314 bytes
-rw-r--r--usr/local/www/themes/metallic/images/misc/plogo_0.gifbin2195 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/misc/plogo_1.gifbin3851 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/misc/plogo_10.gifbin10624 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/misc/plogo_2.gifbin4611 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/misc/plogo_3.gifbin5572 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/misc/plogo_4.gifbin7103 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/misc/plogo_5.gifbin8717 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/misc/plogo_6.gifbin9422 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/misc/plogo_7.gifbin9443 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/misc/plogo_8.gifbin10240 -> 0 bytes
-rw-r--r--usr/local/www/themes/metallic/images/misc/plogo_9.gifbin10823 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/all.css21
-rw-r--r--usr/local/www/themes/nervecenter/images/background.gifbin44097 -> 44574 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/button_left.gifbin534 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/button_mid.gifbin149 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/button_right.gifbin333 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/icons/icon_advanced.gifbin0 -> 306 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/icons/icon_advanced_s.gifbin0 -> 314 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/icons/icon_block_add.gifbin0 -> 192 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/icons/icon_pass_add.gifbin0 -> 183 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/misc/plogo_0.gifbin2195 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/misc/plogo_1.gifbin3851 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/misc/plogo_10.gifbin10624 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/misc/plogo_2.gifbin4611 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/misc/plogo_3.gifbin5572 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/misc/plogo_4.gifbin7103 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/misc/plogo_5.gifbin8717 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/misc/plogo_6.gifbin9422 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/misc/plogo_7.gifbin9443 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/misc/plogo_8.gifbin10240 -> 0 bytes
-rw-r--r--usr/local/www/themes/nervecenter/images/misc/plogo_9.gifbin10823 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/all.css8
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/icons/icon_advanced.gifbin0 -> 306 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/icons/icon_advanced_s.gifbin0 -> 314 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/misc/plogo_0.gifbin2195 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/misc/plogo_1.gifbin3851 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/misc/plogo_10.gifbin10624 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/misc/plogo_2.gifbin4611 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/misc/plogo_3.gifbin5572 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/misc/plogo_4.gifbin7103 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/misc/plogo_5.gifbin8717 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/misc/plogo_6.gifbin9422 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/misc/plogo_7.gifbin9443 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/misc/plogo_8.gifbin10240 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense-dropdown/images/misc/plogo_9.gifbin10823 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense/all.css8
-rw-r--r--usr/local/www/themes/pfsense/images/icons/icon_advanced.gifbin0 -> 306 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/icons/icon_advanced_s.gifbin0 -> 314 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/misc/plogo_0.gifbin2195 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/misc/plogo_1.gifbin3851 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/misc/plogo_10.gifbin10624 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/misc/plogo_2.gifbin4611 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/misc/plogo_3.gifbin5572 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/misc/plogo_4.gifbin7103 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/misc/plogo_5.gifbin8717 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/misc/plogo_6.gifbin9422 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/misc/plogo_7.gifbin9443 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/misc/plogo_8.gifbin10240 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense/images/misc/plogo_9.gifbin10823 -> 0 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/all.css1349
-rw-r--r--usr/local/www/themes/pfsense_ng/bottom-loader.js10
-rw-r--r--usr/local/www/themes/pfsense_ng/favicon.icobin0 -> 1406 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/graphlink.css43
-rw-r--r--usr/local/www/themes/pfsense_ng/images/alert_bgr.pngbin0 -> 2344 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/alerter.pngbin0 -> 2627 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/background.jpgbin0 -> 247709 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/footer.pngbin0 -> 1822 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/header.pngbin0 -> 4994 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/horizontal.pngbin0 -> 236 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/hostname.pngbin0 -> 1899 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/favicon.icobin0 -> 1406 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_advanced.gifbin0 -> 306 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_advanced_s.gifbin0 -> 314 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_alert.gifbin0 -> 2055 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_alias_host.gifbin0 -> 348 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_alias_net.gifbin0 -> 331 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_alias_port.gifbin0 -> 346 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_alias_url.gifbin0 -> 314 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_alias_url_reload.gifbin0 -> 1111 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_block.gifbin0 -> 193 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_block_d.gifbin0 -> 193 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_cablenic.gifbin0 -> 91 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_cal.gifbin0 -> 646 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_cal_mo.gifbin0 -> 1060 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_carp.gifbin0 -> 352 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_carp_d.gifbin0 -> 357 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_chain.pngbin0 -> 281 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_check.gifbin0 -> 1291 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_clock_green.gifbin0 -> 308 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_clock_grey.gifbin0 -> 308 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_clock_red.gifbin0 -> 308 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_close.gifbin0 -> 64 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_configure.gifbin0 -> 64 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_down.gifbin0 -> 1114 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_down_d.gifbin0 -> 689 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_down_mo.gifbin0 -> 1117 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_e.gifbin0 -> 1106 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_e_mo.gifbin0 -> 1120 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_error.gifbin0 -> 1312 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_exclam.gifbin0 -> 1274 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_flag_de.pngbin0 -> 134 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_flag_en.pngbin0 -> 736 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_flag_es.pngbin0 -> 308 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_flag_pt_BR.pngbin0 -> 653 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_cert.pngbin0 -> 1526 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_file.pngbin0 -> 694 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_group.pngbin0 -> 739 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_host.pngbin0 -> 508 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_imp.pngbin0 -> 683 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_mail.pngbin0 -> 498 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_pwd.pngbin0 -> 674 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_search.pngbin0 -> 666 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_time.pngbin0 -> 711 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_unknown.pngbin0 -> 595 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_url.pngbin0 -> 731 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_user.pngbin0 -> 641 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_fw-update.gifbin0 -> 43785 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_ifalias.gifbin0 -> 315 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_ifalias_d.gifbin0 -> 315 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_import_alias.gifbin0 -> 1109 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_in.gifbin0 -> 177 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_in_d.gifbin0 -> 190 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_info_pkg.gifbin0 -> 1131 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_interface_down.gifbin0 -> 88 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_interface_up.gifbin0 -> 87 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_left.gifbin0 -> 1120 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_left_d.gifbin0 -> 691 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_left_mo.gifbin0 -> 1129 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_log.gifbin0 -> 297 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_log_d.gifbin0 -> 297 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_log_s.gifbin0 -> 305 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_log_s_d.gifbin0 -> 305 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_minus.gifbin0 -> 61 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_open.gifbin0 -> 62 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_other.gifbin0 -> 125 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_other_d.gifbin0 -> 125 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_out.gifbin0 -> 179 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_out_d.gifbin0 -> 189 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_parp.gifbin0 -> 303 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_parp_d.gifbin0 -> 303 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_pass.gifbin0 -> 182 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_pass_d.gifbin0 -> 182 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_plus.gifbin0 -> 1100 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_plus_bl.gifbin0 -> 1096 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_plus_bl_p.gifbin0 -> 1079 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_plus_d.gifbin0 -> 682 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_plus_mo.gifbin0 -> 1120 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_plus_p.gifbin0 -> 1087 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall.gifbin0 -> 1119 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_d.gifbin0 -> 701 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_mo.gifbin0 -> 1130 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg.gifbin0 -> 1109 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg_d.gifbin0 -> 694 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg_mo.gifbin0 -> 1135 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml.gifbin0 -> 1105 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml_d.gifbin0 -> 686 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml_mo.gifbin0 -> 1131 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_reject.gifbin0 -> 193 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_reject_d.gifbin0 -> 193 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_right.gifbin0 -> 1117 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_service_restart.gifbin0 -> 1120 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_service_restart_d.gifbin0 -> 1115 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_service_start.gifbin0 -> 1119 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_service_start_d.gifbin0 -> 1115 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_service_stop.gifbin0 -> 1106 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_service_stop_d.gifbin0 -> 1100 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_services_restart_mo.gifbin0 -> 1129 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_services_start_mo.gifbin0 -> 1130 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_services_stop_mo.gifbin0 -> 1126 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_system-group-grey.pngbin0 -> 1459 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_system-group.pngbin0 -> 2788 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_system-user-grey.pngbin0 -> 1052 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_system-user.pngbin0 -> 1912 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_system_lock_screen.pngbin0 -> 1653 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_system_logout.pngbin0 -> 2030 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_trapped.gifbin0 -> 1101 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_trapped_p.gifbin0 -> 1079 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_ts_rule.gifbin0 -> 194 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_ts_rule_d.gifbin0 -> 193 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_up.gifbin0 -> 1116 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_up_d.gifbin0 -> 691 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_up_mo.gifbin0 -> 1129 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_wlan.gifbin0 -> 66 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_wlan_d.gifbin0 -> 100 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_wol_all.gifbin0 -> 1126 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_wzd_nsaved.pngbin0 -> 502 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_wzd_saved.pngbin0 -> 444 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_x.gifbin0 -> 1111 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_x_d.gifbin0 -> 680 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_x_mo.gifbin0 -> 1126 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_x_p.gifbin0 -> 1090 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/in.gifbin0 -> 177 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/in_d.gifbin0 -> 190 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/out.gifbin0 -> 179 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/out_d.gifbin0 -> 189 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/logo.gifbin0 -> 2471 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/logobig.jpgbin0 -> 13482 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/mainmenu-down.gifbin0 -> 55 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/mainmenu-right.gifbin0 -> 56 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/mainmenuitem.gifbin0 -> 54 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/menu-dot.gifbin0 -> 54 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/menu_footer.gifbin0 -> 234 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/menu_right.gifbin0 -> 61 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/menubgr.pngbin0 -> 176 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/menubgr_footer.pngbin0 -> 499 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/menubgr_highlight.pngbin0 -> 207 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/bar_blue.gifbin0 -> 94 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/bar_gray.gifbin0 -> 94 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/bar_left.gifbin0 -> 289 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/bar_right.gifbin0 -> 288 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/bullet_toggle_minus.pngbin0 -> 207 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/bullet_toggle_plus.pngbin0 -> 209 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/button.gifbin0 -> 805 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/graph.pngbin0 -> 2617 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/key_128.gifbin0 -> 2766 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/key_152.gifbin0 -> 2772 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/key_256.gifbin0 -> 2808 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/key_64.gifbin0 -> 2723 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/left_background.gif (renamed from usr/local/www/themes/the_wall/images/misc/left_background.gif)bin38943 -> 38943 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/loader.gifbin0 -> 5971 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/loader_all.gifbin0 -> 2612 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/loader_filter.gifbin0 -> 2647 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/loader_tab.gif (renamed from usr/local/www/themes/_orange-flow/images/misc/loader_tab.gif)bin5852 -> 5852 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/logon.pngbin0 -> 59374 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/progress_bar.gifbin0 -> 44791 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/rrd_error.png (renamed from usr/local/www/themes/_orange-flow/images/misc/rrd_error.png)bin43427 -> 43427 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/status_alerter.gifbin0 -> 2203 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/status_carpmaster.gifbin0 -> 1558 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/status_left.gifbin0 -> 600 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/status_page_loading.gifbin0 -> 3318 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/status_reload_all.gifbin0 -> 3286 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/status_reload_filter.gifbin0 -> 3288 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/status_right.gifbin0 -> 599 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/tri_c.gifbin0 -> 61 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/tri_c_black.gifbin0 -> 69 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/tri_o.gifbin0 -> 58 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/tri_o_black.gifbin0 -> 67 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/misc/widget_loader.gifbin0 -> 2545 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/transparent.gifbin0 -> 146 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/transparent_pixel.gifbin0 -> 43 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/wizards/initial/joincluster.gifbin0 -> 10076 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/wizards/initial/joincluster_mo.gifbin0 -> 10153 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/wizards/initial/restore.gifbin0 -> 9199 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/wizards/initial/restore_mo.gifbin0 -> 9099 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/wizards/initial/standalone.gifbin0 -> 7265 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/wizards/initial/standalone_mo.gifbin0 -> 7382 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/wizards/initial/startnewcluster.gifbin0 -> 10175 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/images/wizards/initial/startnewcluster_mo.gifbin0 -> 10030 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/blank.gifbin0 -> 48 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-box-model.js2
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-core.js2
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css-strict.js2
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css2.js2
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css3.js2
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-fixed.js2
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-html4.js2
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-ie5.js2
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-lite-p.js3
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-lite.js2
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-png.js2
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-server.css43
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-standard-p.js3
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-standard.js2
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/ie7/test-trans.pngbin0 -> 106 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/img/grey-40.pngbin0 -> 849 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/img/submenu-off.gifbin0 -> 65 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/img/submenu-on.gifbin0 -> 65 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/img/white-90.pngbin0 -> 849 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/img/x.gifbin0 -> 43 bytes
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/niftyjsCode.js174
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/transmenu-body.php51
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/transmenu-head.php85
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/transmenu.org785
-rw-r--r--usr/local/www/themes/pfsense_ng/javascript/transmenuC.js86
-rw-r--r--usr/local/www/themes/pfsense_ng/jsevents/body.def7
-rw-r--r--usr/local/www/themes/pfsense_ng/loader.js29
-rw-r--r--usr/local/www/themes/pfsense_ng/login.css1099
-rw-r--r--usr/local/www/themes/pfsense_ng/menu.inc178
-rw-r--r--usr/local/www/themes/pfsense_ng/no_big_logo1
-rw-r--r--usr/local/www/themes/pfsense_ng/rrdcolors.inc.php (renamed from usr/local/www/themes/_orange-flow/rrdcolors.inc.php)9
-rw-r--r--usr/local/www/themes/pfsense_ng/styles/menustyles.css44
-rw-r--r--usr/local/www/themes/pfsense_ng/styles/transmenu.css75
-rw-r--r--usr/local/www/themes/pfsense_ng/wizard.css1065
-rw-r--r--usr/local/www/themes/the_wall/all.css8
-rw-r--r--usr/local/www/themes/the_wall/images/button_left.gifbin534 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/button_mid.gifbin149 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/button_right.gifbin333 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/icons/icon_advanced.gifbin0 -> 306 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/icons/icon_advanced_s.gifbin0 -> 314 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/misc/plogo_0.gifbin2195 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/misc/plogo_1.gifbin3851 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/misc/plogo_10.gifbin10624 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/misc/plogo_2.gifbin4611 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/misc/plogo_3.gifbin5572 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/misc/plogo_4.gifbin7103 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/misc/plogo_5.gifbin8717 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/misc/plogo_6.gifbin9422 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/misc/plogo_7.gifbin9443 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/misc/plogo_8.gifbin10240 -> 0 bytes
-rw-r--r--usr/local/www/themes/the_wall/images/misc/plogo_9.gifbin10823 -> 0 bytes
-rwxr-xr-xusr/local/www/vpn_ipsec.php12
-rwxr-xr-xusr/local/www/vpn_ipsec_mobile.php10
-rw-r--r--usr/local/www/vpn_ipsec_phase1.php14
-rw-r--r--usr/local/www/vpn_ipsec_phase2.php7
-rw-r--r--usr/local/www/vpn_l2tp.php7
-rw-r--r--usr/local/www/vpn_l2tp_users.php10
-rw-r--r--usr/local/www/vpn_l2tp_users_edit.php22
-rw-r--r--usr/local/www/vpn_openvpn_client.php1
-rw-r--r--usr/local/www/vpn_openvpn_csc.php1
-rw-r--r--usr/local/www/vpn_openvpn_server.php48
-rwxr-xr-xusr/local/www/vpn_pppoe.php15
-rwxr-xr-xusr/local/www/vpn_pppoe_users.php9
-rwxr-xr-xusr/local/www/vpn_pppoe_users_edit.php13
-rwxr-xr-xusr/local/www/vpn_pptp.php11
-rwxr-xr-xusr/local/www/vpn_pptp_users.php9
-rwxr-xr-xusr/local/www/vpn_pptp_users_edit.php15
-rw-r--r--usr/local/www/widgets/widgets/captive_portal_status.widget.php35
-rw-r--r--usr/local/www/widgets/widgets/services_status.widget.php3
-rwxr-xr-xusr/local/www/wizard.php51
-rw-r--r--usr/local/www/wizards/setup_wizard.xml1
-rw-r--r--usr/local/www/wizards/traffic_shaper_wizard.inc165
-rw-r--r--usr/local/www/wizards/traffic_shaper_wizard.xml2
-rwxr-xr-xusr/local/www/wizards/traffic_shaper_wizard_dedicated.inc4
-rwxr-xr-xusr/local/www/wizards/traffic_shaper_wizard_multi_all.inc4
-rw-r--r--usr/local/www/wizards/traffic_shaper_wizard_multi_lan.inc4
-rwxr-xr-xusr/local/www/wlan_strong_key_generator/generator.php376
464 files changed, 13309 insertions, 2050 deletions
diff --git a/usr/local/captiveportal/index.php b/usr/local/captiveportal/index.php
index 3771bf9..aef677d 100755
--- a/usr/local/captiveportal/index.php
+++ b/usr/local/captiveportal/index.php
@@ -3,6 +3,7 @@
$Id$
part of m0n0wall (http://m0n0.ch/wall)
+ Copyrigth (C) 2009 Ermal Luçi
Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
All rights reserved.
@@ -121,6 +122,33 @@ EOD;
/* radius functions handle everything so we exit here since we're done */
exit;
+} else if ($_POST['accept'] && $_POST['auth_voucher']) {
+
+ $voucher = trim($_POST['auth_voucher']);
+ $timecredit = voucher_auth($voucher);
+ // $timecredit contains either a credit in minutes or an error message
+ if ($timecredit > 0) { // voucher is valid. Remaining minutes returned
+ // if multiple vouchers given, use the first as username
+ $a_vouchers = split("[\t\n\r ]+",$voucher);
+ $voucher = $a_vouchers[0];
+ $attr = array( 'voucher' => 1,
+ 'session_timeout' => $timecredit*60,
+ 'session_terminate_time' => 0);
+ if (portal_allow($clientip, $clientmac,$voucher,null,$attr)) {
+
+ // YES: user is good for $timecredit minutes.
+ captiveportal_logportalauth($voucher,$clientmac,$clientip,"VOUCHER LOGIN good for $timecredit min.");
+ } else {
+ portal_reply_page($redirurl, "error", $config['voucher']['msgexpired']);
+ }
+ } else if (-1 == $timecredit) { // valid but expired
+ captiveportal_logportalauth($voucher,$clientmac,$clientip,"FAILURE","voucher expired");
+ portal_reply_page($redirurl, "error", $config['voucher']['msgexpired']);
+ } else {
+ captiveportal_logportalauth($voucher,$clientmac,$clientip,"FAILURE");
+ portal_reply_page($redirurl, "error", $config['voucher']['msgnoaccess']);
+ }
+
} else if ($_POST['accept'] && $radius_enable) {
if ($_POST['auth_user'] && $_POST['auth_pass']) {
@@ -233,6 +261,9 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut
$radiusservers = captiveportal_get_radius_servers();
+ if ($attributes['voucher'])
+ $remaining_time = $attributes['session_timeout'];
+
/* Find an existing session */
for ($i = 0; $i < count($cpdb); $i++) {
/* on the same ip */
@@ -241,6 +272,19 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut
$sessionid = $cpdb[$i][5];
break;
}
+ elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpdb[$i][4] == $username)) {
+ // user logged in with an active voucher. Check for how long and calculate
+ // how much time we can give him (voucher credit - used time)
+ $remaining_time = $cpdb[$i][0] + $cpdb[$i][7] - time();
+ if ($remaining_time < 0) // just in case.
+ $remaining_time = 0;
+
+ /* This user was already logged in so we disconnect the old one */
+ captiveportal_disconnect($cpdb[$i],$radiusservers,13);
+ captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],"CONCURRENT LOGIN - TERMINATING OLD SESSION");
+ unset($cpdb[$i]);
+ break;
+ }
elseif ((isset($config['captiveportal']['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
/* on the same username */
if ($cpdb[$i][4] == $username) {
@@ -253,6 +297,11 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut
}
}
+ if ($attributes['voucher'] && $remaining_time <= 0) {
+ unlock($cplock);
+ return 0; // voucher already used and no time left
+ }
+
if (!isset($sessionid)) {
/* generate unique session ID */
@@ -269,27 +318,29 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut
$bw_down = isset($attributes['bw_down']) ? trim($attributes['bw_down']) : $config['captiveportal']['bwdefaultdn'];
if ($peruserbw && !empty($bw_up) && is_numeric($bw_up)) {
- $bw_up_pipeno = $ruleno + 40500;
- exec("/sbin/ipfw add $ruleno set 2 pipe $bw_up_pipeno ip from $clientip to any in");
- exec("/sbin/ipfw pipe $bw_up_pipeno config bw {$bw_up}Kbit/s queue 100");
+ $bw_up_pipeno = $ruleno + 20000;
+ mwexec("/sbin/ipfw pipe $bw_up_pipeno config bw {$bw_up}Kbit/s queue 100");
+ mwexec("/sbin/ipfw table 3 add {$clientip} {$bw_up_pipeno}");
} else {
- exec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from $clientip to any in");
+ mwexec("/sbin/ipfw table 3 add {$clientip}");
}
if ($peruserbw && !empty($bw_down) && is_numeric($bw_down)) {
- $bw_down_pipeno = $ruleno + 45500;
- exec("/sbin/ipfw add $ruleno set 2 pipe $bw_down_pipeno ip from any to $clientip out");
- exec("/sbin/ipfw pipe $bw_down_pipeno config bw {$bw_down}Kbit/s queue 100");
+ $bw_down_pipeno = $ruleno + 20001;
+ mwexec("/sbin/ipfw pipe $bw_down_pipeno config bw {$bw_down}Kbit/s queue 100");
+ mwexec("/sbin/ipfw table 4 add {$clientip} {$bw_down_pipeno}");
} else {
- exec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to $clientip out");
+ mwexec("/sbin/ipfw table 4 add {$clientip}");
}
/* add ipfw rules for layer 2 */
if (!isset($config['captiveportal']['nomacfilter'])) {
- $l2ruleno = $ruleno + 10000;
- exec("/sbin/ipfw add $l2ruleno set 3 deny all from $clientip to any not MAC any $clientmac layer2 in");
- exec("/sbin/ipfw add $l2ruleno set 3 deny all from any to $clientip not MAC $clientmac any layer2 out");
+ exec("/sbin/ipfw add $ruleno set 3 deny all from $clientip to any not MAC any $clientmac layer2 in");
+ exec("/sbin/ipfw add $ruleno set 3 deny all from any to $clientip not MAC $clientmac any layer2 out");
}
+ if ($attributes['voucher'])
+ $attributes['session_timeout'] = $remaining_time;
+
/* encode password in Base64 just in case it contains commas */
$bpassword = base64_encode($password);
$cpdb[] = array(time(), $ruleno, $clientip, $clientmac, $username, $sessionid, $bpassword,
diff --git a/usr/local/captiveportal/radius_accounting.inc b/usr/local/captiveportal/radius_accounting.inc
index fb8ece3..bfd0247 100644
--- a/usr/local/captiveportal/radius_accounting.inc
+++ b/usr/local/captiveportal/radius_accounting.inc
@@ -157,7 +157,7 @@ function RADIUS_ACCOUNTING_STOP($ruleno,$username,$sessionid,$start_time,$radius
$radiusvendor = $config['captiveportal']['radiusvendor'] ? $config['captiveportal']['radiusvendor'] : null;
$stop_time = (empty($stop_time)) ? time() : $stop_time;
$session_time = $stop_time - $start_time;
- $volume = getVolume($ruleno);
+ $volume = getVolume($clientip);
$volume['input_bytes_radius'] = remainder($volume['input_bytes']);
$volume['input_gigawords'] = gigawords($volume['input_bytes']);
$volume['output_bytes_radius'] = remainder($volume['output_bytes']);
@@ -306,4 +306,4 @@ function remainder($bytes) {
}
-?> \ No newline at end of file
+?>
diff --git a/usr/local/pkg/miniupnpd.inc b/usr/local/pkg/miniupnpd.inc
index 57a5ec4..8d45bad 100644
--- a/usr/local/pkg/miniupnpd.inc
+++ b/usr/local/pkg/miniupnpd.inc
@@ -1,6 +1,7 @@
<?php
require_once("config.inc");
require_once("functions.inc");
+ require_once("shaper.inc");
/* MiniUPnPd */
@@ -30,6 +31,16 @@
return substr($uuid,0,8).'-'.substr($uuid,9,4).'-'.substr($uuid,13,4).'-'.substr($uuid,17,4).'-'.substr($uuid,21,12);
}
+ function upnp_validate_queue($qname) {
+ read_altq_config();
+ $qlist = get_altq_name_list();
+ if (is_array($qlist)) {
+ return in_array($qname, $qlist);
+ } else {
+ return false;
+ }
+ }
+
function upnp_validate_ip($ip, $check_cdir) {
/* validate cdir */
if($check_cdir) {
@@ -86,6 +97,8 @@
$input_errors[] = 'You must specify a value greater than 0 in the \'Maximum Download Speed\' field';
if($post['upload'] && $post['upload'] <= 0)
$input_errors[] = 'You must specify a value greater than 0 in the \'Maximum Upload Speed\' field';
+ if($post['upnpqueue'] && !upnp_validate_queue($post['upnpqueue']))
+ $input_errors[] = 'You must specify a valid traffic shaping queue.';
/* user permissions validation */
for($i=1; $i<=4; $i++) {
@@ -202,6 +215,14 @@
if($upnp_config['permdefault'])
$config_text .= "deny 0-65535 0.0.0.0/0 0-65535\n";
+ /* Recheck if queue is valid */
+ if (!upnp_validate_queue($upnp_config['upnpqueue']))
+ unset($upnp_config['upnpqueue']);
+
+ /* Add shaper queue */
+ if($upnp_config['upnpqueue'])
+ $config_text .= "queue={$upnp_config['upnpqueue']}\n";
+
/* write out the configuration */
upnp_write_config($config_file, $config_text);
diff --git a/usr/local/pkg/miniupnpd.xml b/usr/local/pkg/miniupnpd.xml
index dc3b057..e7a39c1 100644
--- a/usr/local/pkg/miniupnpd.xml
+++ b/usr/local/pkg/miniupnpd.xml
@@ -43,6 +43,7 @@
<fielddescr>Enable UPnP</fielddescr>
<fieldname>enable</fieldname>
<type>checkbox</type>
+ <enablefields>iface_array,overridewanip,upnpqueue,logpackets,sysuptime,permdefault,permuser1,permuser2,permuser3,permuser4</enablefields>
</field>
<field>
<fielddescr>Interfaces (generally LAN)</fielddescr>
@@ -70,6 +71,11 @@
<type>input</type>
</field>
<field>
+ <fielddescr>Traffic Shaping Queue</fielddescr>
+ <fieldname>upnpqueue</fieldname>
+ <type>input</type>
+ </field>
+ <field>
<fielddescr>Log packets handled by UPnP rules?</fielddescr>
<fieldname>logpackets</fieldname>
<type>checkbox</type>
diff --git a/usr/local/pkg/openntpd.xml b/usr/local/pkg/openntpd.xml
index c503e62..907c6fb 100644
--- a/usr/local/pkg/openntpd.xml
+++ b/usr/local/pkg/openntpd.xml
@@ -9,7 +9,6 @@
<fielddescr>Enable</fielddescr>
<description>Check this to enable the NTP server.</description>
<type>checkbox</type>
- <enablefields>interface</enablefields>
</field>
<field>
<fieldname>interface</fieldname>
diff --git a/usr/local/www/bandwidth_by_ip.php b/usr/local/www/bandwidth_by_ip.php
new file mode 100755
index 0000000..3fd01a6
--- /dev/null
+++ b/usr/local/www/bandwidth_by_ip.php
@@ -0,0 +1,77 @@
+<?php
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ *
+ *
+ *
+ *
+ *
+ */
+
+require_once('guiconfig.inc');
+require_once('interfaces.inc');
+require_once('pfsense-utils.inc');
+require_once('util.inc');
+
+$listedIPs = "";
+
+//get interface IP and break up into an array
+$interface = $_GET['if'];
+$real_interface = convert_friendly_interface_to_real_interface_name($interface);
+$intip = find_interface_ip($real_interface);
+$intip = explode (".", $intip);
+
+//use class A subnet to make sure we capture all traffic on specified interface
+$intsubnet = $intip[0] . ".0.0.0/8";
+
+exec("rate -i {$real_interface} -nlq 1 -A -c {$intsubnet}", $listedIPs);
+
+unset($bandwidthinfo);
+unset($receivebytesarray);
+unset($transmitbytesarray);
+
+$someinfo = false;
+for ($x=2; $x<12; $x++){
+
+ $bandwidthinfo = $listedIPs[$x];
+
+ // echo $bandwidthinfo;
+ $emptyinfocounter = 1;
+ if ($bandwidthinfo != "") {
+ $splitinfo = explode ("|",$bandwidthinfo);
+ $receivebytesarray = explode(" ",$splitinfo[0]);
+ //print IP of host;
+ echo $receivebytesarray[0] . ";";
+
+ //skip empty array elements until first element found with data
+ while ($receivebytesarray[$emptyinfocounter] == "")
+ {
+ $emptyinfocounter++;
+ }
+ //print received bytes for host
+ echo $receivebytesarray[$emptyinfocounter] . ";";
+
+ $transmitbytesarray = explode(" ",$splitinfo[1]);
+
+ $emptyinfocounter = 1;
+
+ //skip empty array elements until first element found with data
+ while ($transmitbytesarray[$emptyinfocounter] == "")
+ {
+ $emptyinfocounter++;
+ }
+ //print transmitted bytes for host
+ echo $transmitbytesarray[$emptyinfocounter] . "|";
+
+ //mark that we collected information
+ $someinfo = true;
+ }
+}
+
+
+//no bandwidth usage found
+if ($someinfo == false)
+ echo "no info";
+
+?>
diff --git a/usr/local/www/carp_status.php b/usr/local/www/carp_status.php
index 5d4875b..c4d9477 100755
--- a/usr/local/www/carp_status.php
+++ b/usr/local/www/carp_status.php
@@ -79,7 +79,7 @@ include("head.inc");
<div id="mainlevel">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
- <td class="tabcont">
+ <td>
<?php
if(is_array($config['virtualip']['vip'])) {
foreach($config['virtualip']['vip'] as $carp) {
@@ -99,7 +99,7 @@ include("head.inc");
?>
<p>
- <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <table class="tabcont sortable" width="100%" border="0" cellpadding="6" cellspacing="0">
<tr>
<td class="listhdrr"><b><center>Carp Interface</center></b></td>
<td class="listhdrr"><b><center>Virtual IP</center></b></td>
@@ -149,42 +149,30 @@ include("head.inc");
}
}
?>
- <tr>
- <td>
- <center>
-<?php
- echo "<br>pfSync nodes:<br>";
- echo "<pre>";
- system("/sbin/pfctl -vvss | /usr/bin/grep creator | /usr/bin/cut -d\" \" -f7 | /usr/bin/sort -u");
- echo "</pre>";
-?>
- </center>
- </td>
- </tr>
- <tr>
- <td colspan="4">
- <p>
- <span class="vexpl">
- <span class="red">
- <strong>
- Note:
- </strong>
- </span>
- <br />
- You can configure CARP settings <a href="pkg_edit.php?xml=carp_settings.xml&id=0">here</a>.
- </span>
- </p>
- </td>
- </tr>
</table>
-
</td>
</tr>
</table>
</div>
-<?php include("fend.inc"); ?>
+<p/>
+
+<span class="vexpl">
+<span class="red"><strong>Note:</strong></span>
+<br />
+You can configure CARP settings <a href="pkg_edit.php?xml=carp_settings.xml&id=0">here</a>.
+</span>
+<p/>
+
+<?php
+ echo "<br>pfSync nodes:<br>";
+ echo "<pre>";
+ system("/sbin/pfctl -vvss | /usr/bin/grep creator | /usr/bin/cut -d\" \" -f7 | /usr/bin/sort -u");
+ echo "</pre>";
+?>
+
+<?php include("fend.inc"); ?>
</body>
</html>
diff --git a/usr/local/www/diag_arp.php b/usr/local/www/diag_arp.php
index 00f9b60..4b07f8b 100755
--- a/usr/local/www/diag_arp.php
+++ b/usr/local/www/diag_arp.php
@@ -240,12 +240,11 @@ $pgtitle = array("Diagnostics","ARP Table");
include("head.inc");
?>
<body link="#000000" vlink="#000000" alink="#000000">
-<script src="/javascript/sorttable.js"></script>
<? include("fbegin.inc"); ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
-<table class="sortable" name="sortabletable" id="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
+<table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="listhdrr">IP address</td>
<td class="listhdrr">MAC address</td>
diff --git a/usr/local/www/diag_backup.php b/usr/local/www/diag_backup.php
index 9b6c484..86100fc 100755
--- a/usr/local/www/diag_backup.php
+++ b/usr/local/www/diag_backup.php
@@ -40,13 +40,44 @@
/* Allow additional execution time 0 = no limit. */
-ini_set('max_execution_time', '3600');
-ini_set('max_input_time', '3600');
+ini_set('max_execution_time', '0');
+ini_set('max_input_time', '0');
/* omit no-cache headers because it confuses IE with file downloads */
$omit_nocacheheaders = true;
require("guiconfig.inc");
+function add_base_packages_menu_items() {
+ global $g, $config;
+ $base_packages = split($g['base_packages'], ",");
+ $modified_config = false;
+ foreach($base_packages as $bp) {
+ $basepkg_path = "/usr/local/pkg/{$bp}";
+ $tmpinfo = pathinfo($basepkg_path, PATHINFO_EXTENSION);
+ if($tmpinfo['extension'] == "xml" && file_exists($basepkg_path)) {
+ $pkg_config = parse_xml_config_pkg($basepkg_path, "packagegui");
+ if($pkg_config['menu'] != "") {
+ if(is_array($pkg_config['menu'])) {
+ foreach($pkg_config['menu'] as $menu) {
+ if(is_array($config['installedpackages']['menu']))
+ foreach($config['installedpackages']['menu'] as $amenu)
+ if($amenu['name'] == $menu['name'])
+ continue;
+ $config['installedpackages']['menu'][] = $menu;
+ $modified_config = true;
+ }
+ }
+ $static_output .= "done.\n";
+ update_output_window($static_output);
+ }
+ }
+ }
+ if($modified_config) {
+ write_confg("Restored base_package menus after configuration restore.");
+ $config = parse_config(true);
+ }
+}
+
function remove_bad_chars($string) {
return preg_replace('/[^a-z|_|0-9]/i','',$string);
}
@@ -100,6 +131,17 @@ function spit_out_select_items($area, $showall) {
}
+if ($_POST['apply']) {
+ ob_flush();
+ flush();
+ sleep(5);
+ conf_mount_rw();
+ clear_subsystem_dirty("restore");
+ conf_mount_ro();
+ mwexec("/sbin/shutdown -r now");
+ exit;
+}
+
if ($_POST) {
unset($input_errors);
if (stristr($_POST['Submit'], "Restore configuration"))
@@ -137,7 +179,7 @@ if ($_POST) {
$data = "";
if($options == "nopackages") {
- $sfn = "/tmp/config.xml.nopkg";
+ $sfn = "{$g['tmp_path']}/config.xml.nopkg";
exec("sed '/<installedpackages>/,/<\/installedpackages>/d' /conf/config.xml > {$sfn}");
$data = file_get_contents($sfn);
} else {
@@ -151,6 +193,8 @@ if ($_POST) {
}
}
+ unlock($lockbckp);
+
if ($_POST['encrypt']) {
$data = encrypt_data($data, $_POST['encrypt_password']);
tagfile_reformat($data, $data, "config.xml");
@@ -183,7 +227,6 @@ if ($_POST) {
header("Content-Length: $size");
echo $data;
- unlock($lockbckp);
exit;
}
}
@@ -222,7 +265,6 @@ if ($_POST) {
$data = str_replace("m0n0wall", "pfsense", $data);
$m0n0wall_upgrade = true;
}
-
if($_POST['restorearea']) {
/* restore a specific area of the configuration */
if(!stristr($data, $_POST['restorearea'])) {
@@ -233,21 +275,20 @@ if ($_POST) {
$savemsg = "The configuration area has been restored. You may need to reboot the firewall.";
}
} else {
- if(!stristr($data, "<pfsense>")) {
- $input_errors[] = "You have selected to restore the full configuration but we could not locate a pfsense tag.";
+ if(!stristr($data, "<" . $g['xml_rootobj'] . ">")) {
+ $input_errors[] = "You have selected to restore the full configuration but we could not locate a " . $g['xml_rootobj'] . " tag.";
} else {
/* restore the entire configuration */
file_put_contents($_FILES['conffile']['tmp_name'], $data);
if (config_install($_FILES['conffile']['tmp_name']) == 0) {
/* this will be picked up by /index.php */
conf_mount_rw();
- if($g['platform'] <> "cdrom")
- touch("/needs_package_sync");
- $reboot_needed = true;
- $savemsg = "The configuration has been restored. The firewall is now rebooting.";
+ mark_subsystem_dirty("restore");
+ $savemsg = "The configuration has been restored. You need to reboot your firewall.";
+ touch("/conf/needs_package_sync");
/* remove cache, we will force a config reboot */
- if(file_exists("/tmp/config.cache"))
- unlink("/tmp/config.cache");
+ if(file_exists("{$g['tmp_path']}/config.cache"))
+ unlink("{$g['tmp_path']}/config.cache");
$config = parse_config(true);
/* extract out rrd items, unset from $confgi when done */
if($config['rrddata']) {
@@ -257,8 +298,10 @@ if ($_POST) {
fclose($rrd_fd);
}
unset($config['rrddata']);
- unlink_if_exists("/tmp/config.cache");
+ unlink_if_exists("{$g['tmp_path']}/config.cache");
write_config();
+ add_base_packages_menu_items();
+ convert_config();
conf_mount_ro();
}
if($m0n0wall_upgrade == true) {
@@ -271,21 +314,85 @@ if ($_POST) {
if(is_array($ifdescrs))
foreach($ifdescrs as $iface)
$config['interfaces'][$iface]['descr'] = remove_bad_chars($config['interfaces'][$iface]['descr']);
- unlink_if_exists("/tmp/config.cache");
+ unlink_if_exists("{$g['tmp_path']}/config.cache");
+ // Reset configuration version to something low
+ // in order to force the config upgrade code to
+ // run through with all steps that are required.
+ $config['system']['version'] = "1.0";
+ // Deal with descriptions longer than 63 characters
+ for ($i = 0; isset($config["filter"]["rule"][$i]); $i++) {
+ if(count($config['filter']['rule'][$i]['descr']) > 63)
+ $config['filter']['rule'][$i]['descr'] = substr($config['filter']['rule'][$i]['descr'], 0, 63);
+ }
+ // Move interface from ipsec to enc0
+ for ($i = 0; isset($config["filter"]["rule"][$i]); $i++) {
+ if($config['filter']['rule'][$i]['interface'] == "ipsec")
+ $config['filter']['rule'][$i]['interface'] = "enc0";
+ }
+ // Convert icmp types
+ // http://www.openbsd.org/cgi-bin/man.cgi?query=icmp&sektion=4&arch=i386&apropos=0&manpath=OpenBSD+Current
+ for ($i = 0; isset($config["filter"]["rule"][$i]); $i++) {
+ if($config["filter"]["rule"][$i]['icmptype']) {
+ switch($config["filter"]["rule"][$i]['icmptype']) {
+ case "echo":
+ $config["filter"]["rule"][$i]['icmptype'] = "echoreq";
+ break;
+ case "unreach":
+ $config["filter"]["rule"][$i]['icmptype'] = "unreach";
+ break;
+ case "echorep":
+ $config["filter"]["rule"][$i]['icmptype'] = "echorep";
+ break;
+ case "squench":
+ $config["filter"]["rule"][$i]['icmptype'] = "squench";
+ break;
+ case "redir":
+ $config["filter"]["rule"][$i]['icmptype'] = "redir";
+ break;
+ case "timex":
+ $config["filter"]["rule"][$i]['icmptype'] = "timex";
+ break;
+ case "paramprob":
+ $config["filter"]["rule"][$i]['icmptype'] = "paramprob";
+ break;
+ case "timest":
+ $config["filter"]["rule"][$i]['icmptype'] = "timereq";
+ break;
+ case "timestrep":
+ $config["filter"]["rule"][$i]['icmptype'] = "timerep";
+ break;
+ case "inforeq":
+ $config["filter"]["rule"][$i]['icmptype'] = "inforeq";
+ break;
+ case "inforep":
+ $config["filter"]["rule"][$i]['icmptype'] = "inforep";
+ break;
+ case "maskreq":
+ $config["filter"]["rule"][$i]['icmptype'] = "maskreq";
+ break;
+ case "maskrep":
+ $config["filter"]["rule"][$i]['icmptype'] = "maskrep";
+ break;
+ }
+ }
+ }
write_config();
+ add_base_packages_menu_items();
+ convert_config();
conf_mount_ro();
- $savemsg = "The m0n0wall configuration has been restored and upgraded to pfSense.<p>The firewall is now rebooting.";
- $reboot_needed = true;
+ $savemsg = "The m0n0wall configuration has been restored and upgraded to pfSense. You need to reboot your firewall.";
+ mark_subsystem_dirty("restore");
}
if(isset($config['captiveportal']['enable'])) {
/* for some reason ipfw doesn't init correctly except on bootup sequence */
- $savemsg = "The configuration has been restored.<p>The firewall is now rebooting.";
- $reboot_needed = true;
+ $savemsg = "The configuration has been restored. You need to reboot your firewall.";
+ mark_subsystem_dirty("restore");
}
setup_serial_port();
if(is_interface_mismatch() == true) {
touch("/var/run/interface_mismatch_reboot_needed");
- $reboot_needed = false;
+ clear_subsystem_dirty("restore");
+ convert_config();
header("Location: interfaces_assign.php");
exit;
}
@@ -309,8 +416,8 @@ if ($_POST) {
if ($ver2restore <> "") {
$conf_file = "{$g['cf_conf_path']}/bak/config-" . strtotime($ver2restore) . ".xml";
if (config_install($conf_file) == 0) {
- $reboot_needed = true;
- $savemsg = "The configuration has been restored. The firewall is now rebooting.";
+ mark_subsystem_dirty("restore");
+ $savemsg = "The configuration has been restored. You need to reboot your firewall.";
} else {
$input_errors[] = "The configuration could not be restored.";
}
@@ -357,6 +464,9 @@ function decrypt_change() {
<form action="diag_backup.php" method="post" name="iform" enctype="multipart/form-data">
<?php if ($input_errors) print_input_errors($input_errors); ?>
<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (is_subsystem_dirty('restore')): ?><p>
+<?php print_info_box_np("The firewall configuration has been changed.<br>You must apply the new config by restarting the firewall in order for changes to take effect.", "apply", "Reboot firewall");?><br>
+<?php endif; ?>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
@@ -503,17 +613,3 @@ decrypt_change();
<?php include("fend.inc"); ?>
</body>
</html>
-
-<?php
-
-if($reboot_needed == true) {
- ob_flush();
- flush();
- sleep(5);
- while(file_exists("{$g['varrun_path']}/config.lock"))
- sleep(3);
- mwexec("/sbin/shutdown -r now");
- exit;
-}
-
-?>
diff --git a/usr/local/www/diag_dhcp_leases.php b/usr/local/www/diag_dhcp_leases.php
index 21a4f70..c79f309 100755
--- a/usr/local/www/diag_dhcp_leases.php
+++ b/usr/local/www/diag_dhcp_leases.php
@@ -74,7 +74,7 @@ if (($_GET['deleteip']) && (is_ipaddr($_GET['deleteip']))) {
/* Restart DHCP Service */
services_dhcpd_configure();
- header("Location: diag_dhcp_leases.php");
+ header("Location: diag_dhcp_leases.php?all={$_GET['all']}");
}
include("head.inc");
@@ -278,7 +278,7 @@ if ($_GET['order'])
/* only print pool status when we have one */
if(count($pools) > 0) {
?>
-<table class="sortable" id="sortabletable" name="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
+<table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="listhdrr">Failover Group</a></td>
<td class="listhdrr">My State</a></td>
@@ -309,7 +309,7 @@ foreach ($pools as $data) {
<p>
-<table class="sortable" id="sortabletable" name="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
+<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="listhdrr"><a href="#">IP address</a></td>
<td class="listhdrr"><a href="#">MAC address</a></td>
@@ -382,7 +382,7 @@ foreach ($leases as $data) {
/* Only show the button for offline dynamic leases */
if (($data['type'] == "dynamic") && ($data['online'] != "online")) {
- echo "<td class=\"list\" valign=\"middle\"><a href=\"diag_dhcp_leases.php?deleteip={$data['ip']}\">";
+ echo "<td class=\"list\" valign=\"middle\"><a href=\"diag_dhcp_leases.php?deleteip={$data['ip']}&all={$_GET['all']}\">";
echo "<img src=\"/themes/{$g['theme']}/images/icons/icon_x.gif\" width=\"17\" height=\"17\" border=\"0\" title=\"delete this dhcp lease\"></a></td>\n";
}
echo "</tr>\n";
diff --git a/usr/local/www/diag_dns.php b/usr/local/www/diag_dns.php
new file mode 100644
index 0000000..d1be628
--- /dev/null
+++ b/usr/local/www/diag_dns.php
@@ -0,0 +1,112 @@
+<?php
+/*
+ diag_dns.php
+
+ Copyright (C) 2009 Jim Pingle (jpingle@gmail.com)
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+$pgtitle = "Diagnostics: DNS";
+require("guiconfig.inc");
+
+/* Cheap hack to support both $_GET and $_POST */
+if ($_GET['host'])
+ $_POST = $_GET;
+
+if ($_POST) {
+ unset($input_errors);
+
+ $reqdfields = explode(" ", "host");
+ $reqdfieldsn = explode(",", "Host");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ $host = trim($_POST['host']);
+
+ if (!(is_hostname($host) || is_ipaddr($host))) {
+ $input_errors[] = "Host must be a valid hostname or IP address.";
+ }
+
+ $type = "unknown";
+ $resolved = "";
+ $ipaddr = "";
+ $hostname = "";
+ if (!$input_errors) {
+ if (is_ipaddr($host)) {
+ $type = "ip";
+ $resolved = gethostbyaddr($host);
+ $ipaddr = $host;
+ if ($host != $resolved)
+ $hostname = $resolved;
+ } elseif (is_hostname($host)) {
+ $type = "hostname";
+ $resolved = gethostbyname($host);
+ $hostname = $host;
+ if ($host != $resolved)
+ $ipaddr = $resolved;
+ }
+
+ if ($host == $resolved) {
+ $resolved = "No record found";
+ }
+ }
+}
+
+include("head.inc"); ?>
+<body link="#000000" vlink="#000000" alink="#000000">
+<? include("fbegin.inc"); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="diag_dns.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Hostname or IP</td>
+ <td width="78%" class="vtable">
+ <?=$mandfldhtml;?><input name="host" type="text" class="formfld" id="host" size="20" value="<?=htmlspecialchars($host);?>">
+ <? if ($resolved && $type) { ?>
+ = <?php echo $resolved; ?>
+ <? } ?>
+ </td>
+ </tr>
+ <?php if (!$input_errors && $ipaddr) { ?>
+ <tr>
+ <td width="22%" valign="top">More Information:</td>
+ <td width="78%" class="vtable">
+ NOTE: These links are to external services, so their reliability cannot be guaranteed.<br/><br/>
+ <a href="http://private.dnsstuff.com/tools/whois.ch?ip=<?php echo $ipaddr; ?>">IP WHOIS @ DNS Stuff</a><br />
+ <a href="http://private.dnsstuff.com/tools/ipall.ch?ip=<?php echo $ipaddr; ?>">IP Info @ DNS Stuff</a>
+ </td>
+ </tr>
+ <?php } ?>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="DNS Lookup">
+ </td>
+ </tr>
+ </table>
+</form>
+</td></tr></table>
+<?php include("fend.inc"); ?>
diff --git a/usr/local/www/diag_dump_states.php b/usr/local/www/diag_dump_states.php
index fce3d19..6c56b2f 100755
--- a/usr/local/www/diag_dump_states.php
+++ b/usr/local/www/diag_dump_states.php
@@ -122,7 +122,7 @@ include("head.inc");
$current_statecount=`pfctl -si | grep "current entries" | awk '{ print $3 }'`;
?>
-<table class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="0">
+<table class="tabcont sortable" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<form action="<?=$_SERVER['SCRIPT_NAME'];?>" method="get">
@@ -141,7 +141,7 @@ include("head.inc");
</tr>
<tr>
<td>
- <table class="tabcont sortable" width="100%" border="0" cellspacing="0" cellpadding="0">
+ <table class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="listhdrr" width="10%"><?=gettext("Proto");?></td>
<td class="listhdrr" width="65"><?=gettext("Source -> Router -> Destination");?></td>
diff --git a/usr/local/www/diag_ipsec.php b/usr/local/www/diag_ipsec.php
index a080a5b..7422503 100644
--- a/usr/local/www/diag_ipsec.php
+++ b/usr/local/www/diag_ipsec.php
@@ -74,7 +74,7 @@ $sad = ipsec_dump_sad();
<tr>
<td>
<div id="mainarea">
- <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0" class="tabcont sortable">
<tr>
<td nowrap class="listhdrr">Local IP</td>
<td nowrap class="listhdrr">Remote IP</a></td>
@@ -116,25 +116,23 @@ $sad = ipsec_dump_sad();
}
}
?>
- <tr>
- <td colspan="4">
- <p>
- <span class="vexpl">
- <span class="red">
- <strong>Note:<br /></strong>
- </span>
- You can configure your IPsec
- <a href="vpn_ipsec.php">here</a>.
- </span>
- </p>
- </td>
- </tr>
</table>
</div>
</td>
</tr>
</table>
+<p/>
+
+<span class="vexpl">
+ <span class="red">
+ <strong>Note:<br /></strong>
+ </span>
+ You can configure your IPsec
+ <a href="vpn_ipsec.php">here</a>.
+</span>
+
+
<?php include("fend.inc"); ?>
</body>
</html>
diff --git a/usr/local/www/diag_ipsec_sad.php b/usr/local/www/diag_ipsec_sad.php
index 1162289..4d67869 100755
--- a/usr/local/www/diag_ipsec_sad.php
+++ b/usr/local/www/diag_ipsec_sad.php
@@ -75,7 +75,7 @@ if ($_GET['act'] == "del") {
<tr>
<td>
<div id="mainarea">
- <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <table class="tabcont sortable" width="100%" border="0" cellpadding="6" cellspacing="0">
<?php if (count($sad)): ?>
<tr>
<td nowrap class="listhdrr">Source</td>
@@ -114,21 +114,19 @@ if ($_GET['act'] == "del") {
</td>
</tr>
<?php endif; ?>
- <td colspan="4">
- <p>
- <span class="vexpl">
- <span class="red">
- <strong>Note:<br></strong>
- </span>
- You can configure your IPsec <a href="vpn_ipsec.php">here</a>.
- </span>
- </p>
- </td>
</table>
</div>
</td>
</tr>
</table>
- <?php include("fend.inc"); ?>
+
+<p/>
+
+<span class="vexpl">
+<span class="red"><strong>Note:<br></strong></span>
+You can configure your IPsec <a href="vpn_ipsec.php">here</a>.
+</span>
+
+<?php include("fend.inc"); ?>
</body>
</html>
diff --git a/usr/local/www/diag_ipsec_spd.php b/usr/local/www/diag_ipsec_spd.php
index cb4008f..a910cae 100755
--- a/usr/local/www/diag_ipsec_spd.php
+++ b/usr/local/www/diag_ipsec_spd.php
@@ -74,7 +74,7 @@ $spd = ipsec_dump_spd();
<tr>
<td>
<div id="mainarea" style="background:#eeeeee">
- <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <table class="tabcont sortable" width="100%" border="0" cellpadding="6" cellspacing="0">
<?php if (count($spd)): ?>
<tr>
<td nowrap class="listhdrr">Source</td>
@@ -126,22 +126,19 @@ $spd = ipsec_dump_spd();
</td>
</tr>
<?php endif; ?>
- <td colspan="4">
- <p>
- <span class="vexpl">
- <span class="red">
- <strong>Note:<br></strong>
- </span>
- You can configure your IPsec <a href="vpn_ipsec.php">here</a>.
- </span>
- </p>
- </td>
</table>
</div>
</td>
</tr>
</table>
- <?php include("fend.inc"); ?>
+
+<p>
+<span class="vexpl">
+<span class="red"><strong>Note:<br></strong></span>
+You can configure your IPsec <a href="vpn_ipsec.php">here</a>.
+</span>
+
+<?php include("fend.inc"); ?>
</body>
</html>
diff --git a/usr/local/www/diag_logs_filter.php b/usr/local/www/diag_logs_filter.php
index 960956f..fa25c95 100755
--- a/usr/local/www/diag_logs_filter.php
+++ b/usr/local/www/diag_logs_filter.php
@@ -5,7 +5,8 @@
part of pfSesne by Scott Ullrich
originally based on m0n0wall (http://m0n0.ch/wall)
- Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ Copyright (C) 2003-2009 Manuel Kasper <mk@neon1.net>,
+ Jim Pingle <myfirstname>@<mylastname>.org
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -51,13 +52,34 @@ if($_GET['getrulenum'] or $_POST['getrulenum']) {
exit;
}
+if($_GET['dnsip'] or $_POST['dnsip']) {
+ if($_GET['dnsip'])
+ $dnsip = $_GET['dnsip'];
+ if($_POST['dnsip'])
+ $dnsip = $_POST['dnsip'];
+ $host = get_reverse_dns($dnsip);
+ if ($host == $ip) {
+ $host = "No PTR Record";
+ }
+ echo "IP: {$dnsip}\nHost: {$host}";
+ exit;
+}
+
+$filtertext = "";
+if($_GET['filtertext'] or $_POST['filtertext']) {
+ if($_GET['filtertext'])
+ $filtertext = $_GET['filtertext'];
+ if($_POST['filtertext'])
+ $filtertext = $_POST['filtertext'];
+}
+
$filter_logfile = "{$g['varlog_path']}/filter.log";
$nentries = $config['syslog']['nentries'];
if (!$nentries)
$nentries = 50;
-if ($_POST['clear'])
+if ($_POST['clear'])
clear_log_file($filter_logfile);
$pgtitle = array("Status","System logs","Firewall");
@@ -88,12 +110,20 @@ include("head.inc");
<td>
<div id="mainarea">
<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td colspan="6" align="left">
+ Normal View | <a href="diag_logs_filter_dynamic.php">Dynamic View</a> | <a href="diag_logs_filter_summary.php">Summary View</a><br/><br/>
+ </td></tr>
<?php if (!isset($config['syslog']['rawfilter'])):
- $filterlog = conv_log_filter($filter_logfile, $nentries, $nentries + 100);
+ $filterlog = conv_log_filter($filter_logfile, $nentries, $nentries + 100, $filtertext);
?>
<tr>
<td colspan="6" class="listtopic">
- Last <?php echo $nentries;?> firewall log entries &nbsp;&nbsp;&nbsp;(<a href='/diag_logs_filter_dynamic.php'>switch</a> to dynamic view)</td>
+ <?php if (!$filtertext) { ?>
+ Last <?php echo count($filterlog);?> firewall log entries.
+ <?php } else { ?>
+ <?php echo count($filterlog);?> matched log entries.
+ <?php } ?>
+ (Max <?php echo $nentries;?>)
</tr>
<tr>
<td width="10%" class="listhdrr">Act</td>
@@ -111,8 +141,23 @@ include("head.inc");
<?php if ($filterent['count']) echo $filterent['count'];?></td>
<td class="listr" nowrap><?php echo htmlspecialchars($filterent['time']);?></td>
<td class="listr" nowrap><?php echo htmlspecialchars($filterent['interface']);?></td>
- <td class="listr" nowrap><?php echo htmlspecialchars($filterent['src']);?></td>
- <td class="listr" nowrap><?php echo htmlspecialchars($filterent['dst']);?></td>
+ <?php
+ $int = strtolower($filterent['interface']);
+ $proto = strtolower($filterent['proto']);
+
+ $srcstr = $filterent['srcip'] . get_port_with_service($filterent['srcport'], $proto);
+ $dststr = $filterent['dstip'] . get_port_with_service($filterent['dstport'], $proto);
+ ?>
+ <td class="listr" nowrap>
+ <a href="diag_dns.php?host=<?php echo $filterent['srcip']; ?>" title="Reverse Resolve with DNS"><img border="0" src="/themes/nervecenter/images/icons/icon_log.gif"></a>
+ <a href="easyrule.php?<?php echo "action=block&int={$int}&src={$filterent['srcip']}"; ?>" title="Easy Rule: Add to Block List" onclick="return confirm('Do you really want to add this BLOCK rule?\n\nEasy Rule is still experimental.\nContinue at risk of your own peril.\nBackups are also nice.')"><img border="0" src="/themes/nervecenter/images/icons/icon_block_add.gif"></a>
+ <?php echo $srcstr;?>
+ </td>
+ <td class="listr" nowrap>
+ <a href="diag_dns.php?host=<?php echo $filterent['dstip']; ?>" title="Reverse Resolve with DNS"><img border="0" src="/themes/nervecenter/images/icons/icon_log.gif"></a>
+ <a href="easyrule.php?<?php echo "action=pass&int={$int}&proto={$proto}&src={$filterent['srcip']}&dst={$filterent['dstip']}&dstport={$filterent['dstport']}"; ?>" title="Easy Rule: Pass this traffic" onclick="return confirm('Do you really want to add this PASS rule?\n\nEasy Rule is still experimental.\nContinue at risk of your own peril.\nBackups are also nice.')"><img border="0" src="/themes/nervecenter/images/icons/icon_pass_add.gif"></a>
+ <?php echo $dststr;?>
+ </td>
<?php
if ($filterent['proto'] == "TCP")
$filterent['proto'] .= ":{$filterent['tcpflags']}";
@@ -124,11 +169,27 @@ include("head.inc");
<td colspan="2" class="listtopic">
Last <?php echo $nentries;?> firewall log entries</td>
</tr>
- <?php dump_clog($filter_logfile, $nentries); ?>
+ <?php
+ if($filtertext)
+ dump_clog($filter_logfile, $nentries, true, array("$filtertext"));
+ else
+ dump_clog($filter_logfile, $nentries);
+ ?>
<?php endif; ?>
- <tr><td><br /><form action="diag_logs_filter.php" method="post">
-<input name="clear" type="submit" class="formbtn" value="Clear log" /></td></tr>
-</form>
+ <tr>
+ <td align="left" valign="top" colspan="3">
+ <form id="clearform" name="clearform" action="diag_logs_filter.php" method="post" style="margin-top: 14px;">
+ <input id="submit" name="clear" type="submit" class="formbtn" value="<?=gettext("Clear log");?>" />
+ </form>
+ </td>
+ <td align="right" valign="top" colspan="3">
+ <form id="filterform" name="filterform" action="diag_logs_filter.php" method="post" style="margin-top: 14px;">
+ <input id="filtertext" name="filtertext" value="<?=gettext($filtertext);?>" />
+ <input id="filtersubmit" name="filtersubmit" type="submit" class="formbtn" value="<?=gettext("Filter");?>" />
+ </form>
+ </td>
+
+ </tr>
</table>
</div>
</td>
diff --git a/usr/local/www/diag_logs_filter_dynamic.php b/usr/local/www/diag_logs_filter_dynamic.php
index 3e4cae3..3bcd9b0 100755
--- a/usr/local/www/diag_logs_filter_dynamic.php
+++ b/usr/local/www/diag_logs_filter_dynamic.php
@@ -108,8 +108,11 @@ include("head.inc");
<tr>
<td>
<div id="mainarea">
+ <div class="tabcont">
+ <a href="diag_logs_filter.php">Normal View</a> | Dynamic View | <a href="diag_logs_filter_summary.php">Summary View</a>
+ </div>
<div class="listtopic">
- Last <?php echo $nentries; ?> records; (Switch to <a href="diag_logs_filter.php">regular</a> view) Pause:<input valign="middle" type="checkbox" onClick="javascript:toggle_pause();">
+ Last <?php echo $nentries; ?> records; Pause:<input valign="middle" type="checkbox" onClick="javascript:toggle_pause();">
</div>
<div id="log">
<div class="log-header">
diff --git a/usr/local/www/diag_logs_filter_summary.php b/usr/local/www/diag_logs_filter_summary.php
new file mode 100644
index 0000000..e0e5877
--- /dev/null
+++ b/usr/local/www/diag_logs_filter_summary.php
@@ -0,0 +1,218 @@
+<?php
+/*
+ diag_logs_filter_summary.php
+
+ Copyright (C) 2009 Jim Pingle (jpingle@gmail.com)
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+$pgtitle = "Diagnostics: System logs: Firewall Log Summary";
+require_once("guiconfig.inc");
+include_once("filter_log.inc");
+
+$filter_logfile = "{$g['varlog_path']}/filter.log";
+$lines = 5000;
+$entriesperblock = 5;
+
+$filterlog = conv_log_filter($filter_logfile, $lines, $lines);
+$gotlines = count($filterlog);
+$fields = array(
+ 'act' => "Actions",
+ 'interface' => "Interfaces",
+ 'proto' => "Protocols",
+ 'srcip' => "Source IPs",
+ 'dstip' => "Destination IPs",
+ 'srcport' => "Source Ports",
+ 'dstport' => "Destination Ports");
+
+$summary = array();
+foreach (array_keys($fields) as $f) {
+ $summary[$f] = array();
+}
+
+$totals = array();
+
+function cmp($a, $b) {
+ if ($a == $b) {
+ return 0;
+ }
+ return ($a < $b) ? 1 : -1;
+}
+
+function stat_block($summary, $stat, $num) {
+ global $gotlines, $fields;
+ uasort($summary[$stat] , 'cmp');
+ print '<table width="200px" cellpadding="3" cellspacing="0" border="1">';
+ print "<tr><th colspan='2'>{$fields[$stat]} data</th></tr>";
+ $k = array_keys($summary[$stat]);
+ $total = 0;
+ $numentries = 0;
+ for ($i=0; $i < $num; $i++) {
+ if ($k[$i]) {
+ $total += $summary[$stat][$k[$i]];
+ $numentries++;
+ $outstr = $k[$i];
+ if (is_ipaddr($outstr)) {
+ $outstr = "<a href=\"diag_dns.php?host={$outstr}\" title=\"Reverse Resolve with DNS\"><img border=\"0\" src=\"/themes/nervecenter/images/icons/icon_log.gif\"></a> {$outstr}";
+ } elseif (substr_count($outstr, '/') == 1) {
+ list($proto, $port) = explode('/', $outstr);
+ $service = getservbyport($port, strtolower($proto));
+ if ($service)
+ $outstr .= ": {$service}";
+ }
+ print "<tr><td>{$outstr}</td><td width='50px' align='right'>{$summary[$stat][$k[$i]]}</td></tr>\n";
+ }
+ }
+ $leftover = $gotlines - $total;
+ if ($leftover > 0) {
+ print "<tr><td>Other</td><td width='50px' align='right'>{$leftover}</td></tr>\n";
+ }
+ print '</table>';
+}
+
+function pie_block($summary, $stat, $num) {
+ global $gotlines, $fields;
+ uasort($summary[$stat] , 'cmp');
+ $k = array_keys($summary[$stat]);
+ $total = 0;
+ $numentries = 0;
+ print "\n<script language=\"javascript\" type=\"text/javascript\">\n";
+ for ($i=0; $i < $num; $i++) {
+ if ($k[$i]) {
+ $total += $summary[$stat][$k[$i]];
+ $numentries++;
+ print "var d{$stat}{$i} = [];\n";
+ print "d{$stat}{$i}.push([1, {$summary[$stat][$k[$i]]}]);\n";
+ }
+ }
+ $leftover = $gotlines - $total;
+ if ($leftover > 0) {
+ print "var d{$stat}{$num} = [];\n";
+ print "d{$stat}{$num}.push([1, {$leftover}]);\n";
+ }
+
+ print "Event.observe(window, 'load', function() {\n";
+ print " new Proto.Chart($('piechart{$stat}'), \n";
+ print " [\n";
+ for ($i=0; $i < $num; $i++) {
+ if ($k[$i]) {
+ print " { data: d{$stat}{$i}, label: \"{$k[$i]}\"}";
+ if (!(($i == ($numentries - 1)) && ($leftover <= 0)))
+ print ",\n";
+ else
+ print "\n";
+ }
+ }
+ if ($leftover > 0)
+ print " { data: d{$stat}{$i}, label: \"Other\"}\n";
+ print " ],\n";
+ print " {\n";
+ print " pies: {show: true, autoScale: true},\n";
+ print " legend: {show: true, labelFormatter: lblfmt}\n";
+ print " });\n";
+ print "});\n";
+
+ print "</script>";
+ print "<table cellpadding=\"3\" cellspacing=\"0\" border=\"0\">";
+ print "<tr><th><font size=\"+1\">{$fields[$stat]}</font></th></tr>";
+ print "<tr><td><div id=\"piechart{$stat}\" style=\"width:450px;height:300px\"></div>\n";
+ print "</table>";
+}
+
+foreach ($filterlog as $fe) {
+ $specialfields = array('srcport', 'dstport');
+ foreach (array_keys($fields) as $field) {
+ if (!in_array($field, $specialfields))
+ $summary[$field][$fe[$field]]++;
+ }
+ /* Handle some special cases */
+ if ($fe['srcport'])
+ $summary['srcport'][$fe['proto'].'/'.$fe['srcport']]++;
+ else
+ $summary['srcport'][$fe['srcport']]++;
+ if ($fe['dstport'])
+ $summary['dstport'][$fe['proto'].'/'.$fe['dstport']]++;
+ else
+ $summary['dstport'][$fe['dstport']]++;
+}
+
+include("head.inc"); ?>
+<body link="#000000" vlink="#000000" alink="#000000">
+<script src="/javascript/filter_log.js" type="text/javascript"></script>
+<script language="javascript" type="text/javascript" src="/protochart/prototype.js"></script>
+<script language="javascript" type="text/javascript" src="/protochart/ProtoChart.js"></script>
+<!--[if IE]>
+<script language="javascript" type="text/javascript" src="/protochart/excanvas.js">
+</script>
+<![endif]-->
+<script language="javascript" type="text/javascript">
+ function lblfmt(lbl) {
+ return '<font size=\"-2\">' + lbl + '</font>'
+ }
+</script>
+
+<? include("fbegin.inc"); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+<?php
+ $tab_array = array();
+ $tab_array[] = array("System", false, "diag_logs.php");
+ $tab_array[] = array("Firewall", true, "diag_logs_filter.php");
+ $tab_array[] = array("DHCP", false, "diag_logs_dhcp.php");
+ $tab_array[] = array("Portal Auth", false, "diag_logs_auth.php");
+ $tab_array[] = array("IPSEC VPN", false, "diag_logs_ipsec.php");
+ $tab_array[] = array("PPTP VPN", false, "diag_logs_vpn.php");
+ $tab_array[] = array("Load Balancer", false, "diag_logs_slbd.php");
+ $tab_array[] = array("OpenVPN", false, "diag_logs_openvpn.php");
+ $tab_array[] = array("OpenNTPD", false, "diag_logs_ntpd.php");
+ $tab_array[] = array("Settings", false, "diag_logs_settings.php");
+ display_top_tabs($tab_array);
+?>
+ </td></tr>
+ <tr>
+ <td>
+ <div id="mainarea">
+ <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0" align="center">
+ <tr><td colspan="6" align="left">
+ <a href="diag_logs_filter.php">Normal View</a> | <a href="diag_logs_filter_dynamic.php">Dynamic View</a> | Summary View<br/><br/>
+ </td></tr>
+ <tr><td align="center">
+
+This is a firewall log summary, of the last <?php echo $gotlines; ?> lines of the firewall log (Max <?php echo $lines; ?>).<br />
+NOTE: IE8 users must enable compatibility view.
+
+<?php
+foreach(array_keys($fields) as $field) {
+ pie_block($summary, $field , $entriesperblock);
+ echo "<br /><br />";
+ stat_block($summary, $field , $entriesperblock);
+ echo "<br /><br />";
+}
+?>
+ </td></tr></table>
+ </div>
+ </td>
+ </tr>
+</table>
+<?php include("fend.inc"); ?>
diff --git a/usr/local/www/diag_logs_settings.php b/usr/local/www/diag_logs_settings.php
index d98bd6f..b744258 100755
--- a/usr/local/www/diag_logs_settings.php
+++ b/usr/local/www/diag_logs_settings.php
@@ -47,6 +47,7 @@ $pconfig['filter'] = isset($config['syslog']['filter']);
$pconfig['dhcp'] = isset($config['syslog']['dhcp']);
$pconfig['portalauth'] = isset($config['syslog']['portalauth']);
$pconfig['vpn'] = isset($config['syslog']['vpn']);
+$pconfig['logall'] = isset($config['syslog']['logall']);
$pconfig['system'] = isset($config['syslog']['system']);
$pconfig['enable'] = isset($config['syslog']['enable']);
$pconfig['logdefaultblock'] = !isset($config['syslog']['nologdefaultblock']);
@@ -77,6 +78,7 @@ if ($_POST) {
$config['syslog']['dhcp'] = $_POST['dhcp'] ? true : false;
$config['syslog']['portalauth'] = $_POST['portalauth'] ? true : false;
$config['syslog']['vpn'] = $_POST['vpn'] ? true : false;
+ $config['syslog']['logall'] = $_POST['logall'] ? true : false;
$config['syslog']['system'] = $_POST['system'] ? true : false;
$config['syslog']['disablelocallogging'] = $_POST['disablelocallogging'] ? true : false;
$config['syslog']['enable'] = $_POST['enable'] ? true : false;
@@ -197,7 +199,10 @@ function enable_change(enable_over) {
firewall events<br> <input name="dhcp" id="dhcp" type="checkbox" value="yes" <?php if ($pconfig['dhcp']) echo "checked"; ?>>
DHCP service events<br> <input name="portalauth" id="portalauth" type="checkbox" value="yes" <?php if ($pconfig['portalauth']) echo "checked"; ?>>
Portal Auth<br> <input name="vpn" id="vpn" type="checkbox" value="yes" <?php if ($pconfig['vpn']) echo "checked"; ?>>
- PPTP VPN events</td>
+ PPTP VPN events
+ <br> <input name="logall" id="logall" type="checkbox" value="yes" <?php if ($pconfig['logall']) echo "checked"; ?>>
+ Everything
+ </td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
diff --git a/usr/local/www/diag_nanobsd.php b/usr/local/www/diag_nanobsd.php
new file mode 100755
index 0000000..06f4c3e
--- /dev/null
+++ b/usr/local/www/diag_nanobsd.php
@@ -0,0 +1,290 @@
+<?php
+/*
+ diag_nanobsd.php
+ Copyright (C) 2009 Scott Ullrich <sullrich@gmail.com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+##|+PRIV
+##|*IDENT=page-diagnostics-nanobsd
+##|*NAME=Diagnostics: NanoBSD
+##|*DESCR=Allow access to the 'Diagnostics: NanoBSD' page.
+##|*MATCH=diag_nanobsd.php*
+##|-PRIV
+
+ini_set('zlib.output_compression', 0);
+ini_set('implicit_flush', 1);
+ini_set('max_input_time', '9999');
+
+require_once("guiconfig.inc");
+require_once("config.inc");
+
+$pgtitle = array("Diagnostics","NanoBSD");
+include("head.inc");
+
+function detect_slice_info() {
+ global $SLICE, $OLDSLICE, $TOFLASH, $COMPLETE_PATH, $COMPLETE_BOOT_PATH;
+ global $GLABEL_SLIZE, $UFS_ID, $OLD_UFS_ID, $BOOTFLASH;
+ global $BOOT_DEVICE, $REAL_BOOT_DEVICE, $BOOT_DRIVE;
+
+ $BOOT_DEVICE=trim(`/sbin/mount | /usr/bin/grep pfsense | /usr/bin/cut -d'/' -f4 | /usr/bin/cut -d' ' -f1`);
+ $REAL_BOOT_DEVICE=trim(`/sbin/glabel list | /usr/bin/grep -B2 ufs/{$BOOT_DEVICE} | /usr/bin/head -n 1 | /usr/bin/cut -f3 -d' '`);
+ $BOOT_DRIVE=trim(`/sbin/glabel list | /usr/bin/grep -B2 ufs/pfsense | /usr/bin/head -n 1 | /usr/bin/cut -f3 -d' ' | /usr/bin/cut -d's' -f1`);
+
+ // Detect which slice is active and set information.
+ if(strstr($REAL_BOOT_DEVICE, "s1")) {
+ $SLICE="2";
+ $OLDSLICE="1";
+ $TOFLASH="{$BOOT_DRIVE}s{$SLICE}";
+ $COMPLETE_PATH="{$BOOT_DRIVE}s{$SLICE}a";
+ $COMPLETE_BOOT_PATH="{$BOOT_DRIVE}s{$OLDSLICE}";
+ $GLABEL_SLICE="pfsense1";
+ $UFS_ID="1";
+ $OLD_UFS_ID="0";
+ $BOOTFLASH="{$BOOT_DRIVE}s{$OLDSLICE}";
+
+ } else {
+ $SLICE="1";
+ $OLDSLICE="2";
+ $TOFLASH="{$BOOT_DRIVE}s{$SLICE}";
+ $COMPLETE_PATH="{$BOOT_DRIVE}s{$SLICE}a";
+ $COMPLETE_BOOT_PATH="{$BOOT_DRIVE}s{$OLDSLICE}";
+ $GLABEL_SLICE="pfsense0";
+ $UFS_ID="0";
+ $OLD_UFS_ID="1";
+ $BOOTFLASH="{$BOOT_DRIVE}s{$OLDSLICE}";
+ }
+}
+
+// Survey slice info
+detect_slice_info();
+
+?>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC" onload="<?=$jsevents["body"]["onload"];?>">
+<script src="/javascript/scriptaculous/prototype.js" type="text/javascript"></script>
+
+<?php include("fbegin.inc"); ?>
+
+<?php
+
+if($_POST['bootslice']) {
+ echo <<<EOF
+ <div id="loading">
+ <img src="/themes/metallic/images/misc/loader.gif">
+ Setting slice information, please wait...
+ <p/>&nbsp;
+ </div>
+EOF;
+ for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
+ ob_implicit_flush(1);
+ if(strstr($_POST['bootslice'], "s2")) {
+ $ASLICE="2";
+ $AOLDSLICE="1";
+ $ATOFLASH="{$BOOT_DRIVE}s{$ASLICE}";
+ $ACOMPLETE_PATH="{$BOOT_DRIVE}s{$ASLICE}a";
+ $AGLABEL_SLICE="pfsense1";
+ $AUFS_ID="1";
+ $AOLD_UFS_ID="0";
+ $ABOOTFLASH="{$BOOT_DRIVE}s{$AOLDSLICE}";
+ } else {
+ $ASLICE="1";
+ $AOLDSLICE="2";
+ $ATOFLASH="{$BOOT_DRIVE}s{$ASLICE}";
+ $ACOMPLETE_PATH="{$BOOT_DRIVE}s{$ASLICE}a";
+ $AGLABEL_SLICE="pfsense0";
+ $AUFS_ID="0";
+ $AOLD_UFS_ID="1";
+ $ABOOTFLASH="{$BOOT_DRIVE}s{$AOLDSLICE}";
+ }
+ conf_mount_rw();
+ exec("sysctl kern.geom.debugflags=16");
+ exec("gpart set -a active -i {$ASLICE} {$BOOT_DRIVE}");
+ exec("/usr/sbin/boot0cfg -s {$ASLICE} -v /dev/{$BOOT_DRIVE}");
+ exec("/bin/mkdir /tmp/{$AGLABEL_SLICE}");
+ exec("/sbin/fsck_ufs -y /dev/{$ACOMPLETE_PATH}");
+ exec("/sbin/mount /dev/ufs/{$AGLABEL_SLICE} /tmp/{$AGLABEL_SLICE}");
+ $fstab = <<<EOF
+/dev/ufs/{$AGLABEL_SLICE} / ufs ro 1 1
+/dev/ufs/cf /cf ufs ro 1 1
+EOF;
+ file_put_contents("/tmp/{$AGLABEL_SLICE}/etc/fstab", $fstab);
+ exec("/sbin/umount /tmp/{$AGLABEL_SLICE}");
+ exec("sysctl kern.geom.debugflags=0");
+ conf_mount_ro();
+ $savemsg = "The boot slice has been set to {$BOOT_DRIVE} {$AGLABEL_SLICE}";
+ // Survey slice info
+ detect_slice_info();
+
+}
+
+if($_POST['destslice']) {
+
+echo <<<EOF
+ <div id="loading">
+ <img src="/themes/metallic/images/misc/loader.gif">
+ Duplicating slice. Please wait, this will take a moment...
+ <p/>&nbsp;
+ </div>
+EOF;
+ for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
+ ob_implicit_flush(1);
+ exec("sysctl kern.geom.debugflags=16");
+ exec("dd if=/dev/zero of=/dev/{$TOFLASH} bs=1m count=1");
+ exec("/bin/dd if=/dev/{$BOOTFLASH} of=/dev/{$TOFLASH} bs=64k");
+ exec("/sbin/tunefs -L {$GLABEL_SLICE} /dev/{$COMPLETE_PATH}");
+ exec("/bin/mkdir /tmp/{$GLABEL_SLICE}");
+ exec("/sbin/fsck_ufs -y /dev/{$COMPLETE_PATH}");
+ exec("/sbin/mount /dev/ufs/{$GLABEL_SLICE} /tmp/{$GLABEL_SLICE}");
+ exec("/bin/cp /etc/fstab /tmp/{$GLABEL_SLICE}/etc/fstab");
+ $status = exec("sed -i \"\" \"s/pfsense{$OLD_UFS_ID}/pfsense{$UFS_ID}/g\" /tmp/{$GLABEL_SLICE}/etc/fstab");
+ if($status) {
+ exec("/sbin/umount /tmp/{$GLABEL_SLICE}");
+ $savemsg = "There was an error while duplicating the slice. Operation aborted.";
+ } else {
+ $savemsg = "The slice has been duplicated.<p/>If you would like to boot from this newly duplicated slice please set it using the bootup information area.";
+ exec("/sbin/umount /tmp/{$GLABEL_SLICE}");
+ }
+ exec("sysctl kern.geom.debugflags=0");
+ // Re-Survey slice info
+ detect_slice_info();
+}
+
+if ($savemsg)
+ print_info_box($savemsg)
+
+?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+ <!-- tabs here if you want them -->
+ </td>
+ </tr>
+ <tr>
+ <td id="mainarea">
+ <div class="tabcont">
+ <span class="vexpl">
+ <span class="red">
+ <strong>NOTE:&nbsp</strong>
+ </span>
+ The options on this page are intended for use by advanced users only.
+ <br/>&nbsp;
+ </span>
+ <p/>
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Bootup information</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Bootup</td>
+ <td width="78%" class="vtable">
+ <form action="diag_nanobsd.php" method="post" name="iform">
+ Bootup slice:
+ <select name='bootslice'>
+ <option value='<?php echo $BOOTFLASH; ?>'>
+ <?php echo $BOOTFLASH; ?>
+ </option>
+ <option value='<?php echo $TOFLASH; ?>'>
+ <?php echo "{$TOFLASH}"; ?>
+ </option>
+ </select>
+ <br/>
+ This will set the bootup slice.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="">&nbsp;</td><td><br/><input type='submit' value='Set bootup'></form></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="">&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Duplicate bootup slice to alternate</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Duplicate bootup slice</td>
+ <td width="78%" class="vtable">
+ <form action="diag_nanobsd.php" method="post" name="iform">
+ Destination slice:
+ <select name='destslice'>
+ <option value='<?php echo $COMPLETE_PATH; ?>'>
+ <?php echo "{$COMPLETE_BOOT_PATH} -> {$TOFLASH}"; ?>
+ </option>
+ </select>
+ <br/>
+ This will duplicate the bootup slice to the alternate slice. Use this if you would like to duplicate the known good working boot partition to the alternate.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="">&nbsp;</td><td><br/><input type='submit' value='Duplicate slice'></form></td>
+ </tr>
+<?php if(file_exists("/conf/upgrade_log.txt")): ?>
+ <tr>
+ <td colspan="2" valign="top" class="">&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">View upgrade log</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">View previous upgrade log</td>
+ <td width="78%" class="vtable">
+ <?php
+ if($_POST['viewupgradelog']) {
+ echo "<textarea name='log' cols='80' rows='40'>";
+ echo file_get_contents("/conf/upgrade_log.txt");
+ echo "\nFile list:\n";
+ echo file_get_contents("/conf/file_upgrade_log.txt");
+ echo "\nMisc log:\n";
+ echo file_get_contents("/conf/firmware_update_misc.log");
+ echo "\nfdisk/bsdlabel log:\n";
+ echo file_get_contents("/conf/fdisk_upgrade_log.txt");
+ echo "</textarea>";
+ } else {
+ echo "<form action='diag_nanobsd.php' method='post' name='iform'>";
+ echo "<input type='submit' name='viewupgradelog' value='View upgrade log'>";
+ }
+ ?>
+ </td>
+ </tr>
+<?php endif; ?>
+ <tr>
+ <td colspan="2" valign="top" class="">&nbsp;</td>
+ </tr>
+ </table>
+ </div>
+ </td>
+ </tr>
+</table>
+<?php require("fend.inc"); ?>
+</body>
+</html>
+
+<?php
+
+// Clear the loading indicator
+echo "<script type=\"text/javascript\">";
+echo "$('loading').innerHTML = '';";
+echo "</script>";
+
+?>
diff --git a/usr/local/www/diag_showbogons.php b/usr/local/www/diag_showbogons.php
new file mode 100644
index 0000000..690e4de
--- /dev/null
+++ b/usr/local/www/diag_showbogons.php
@@ -0,0 +1,100 @@
+<?php
+/* $Id$ */
+/*
+ diag_showbogons.php
+ Copyright (C) 2009 Scott Ullrich
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+##|+PRIV
+##|*IDENT=page-diag-showbogons
+##|*NAME=Diagnostics: System Activity
+##|*DESCR=Allows access to the 'Diagnostics: Show Bogons' page
+##|*MATCH=diag_showbogons.php
+##|-PRIV
+
+require("guiconfig.inc");
+
+if($_POST['Download']) {
+ mwexec_bg("/etc/rc.update_bogons.sh now");
+ $maxtimetowait = 0;
+ $loading = true;
+ while($loading == true) {
+ $isrunning = `ps awwwux | grep -v grep | grep bogons`;
+ if($isrunning == "")
+ $loading = false;
+ $maxtimetowait++;
+ if($maxtimetowait > 89)
+ $loading = false;
+ sleep(1);
+ }
+ if($maxtimetowait < 90)
+ $savemsg = "The bogons database has been updated.";
+}
+
+$bogons = `cat /etc/bogons`;
+$pgtitle = "Diagnostics: Show Bogons";
+
+include("head.inc");
+include("fbegin.inc");
+
+?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<style type="text/css">
+body { font-family: Verdana; font-size: 100%; }
+pre { font-size: 1.15em; }
+</style>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<form method="post" action="diag_showbogons.php">
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+ <table id="backuptable" class="tabcont" align="left" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td>
+ <table>
+ <tr>
+ <td>
+<b>Currently loaded bogons table:</b><p/>
+<pre>
+
+<?php echo $bogons; ?>
+</pre>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </td>
+ </tr>
+</table>
+<p/>
+<input type="submit" name="Download" value="Download"> latest bogon data.
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/diag_system_pftop.php b/usr/local/www/diag_system_pftop.php
index 78fdbe5..abdd7e3 100644
--- a/usr/local/www/diag_system_pftop.php
+++ b/usr/local/www/diag_system_pftop.php
@@ -1,7 +1,7 @@
<?php
/* $Id$ */
/*
- diag_cpu_pftop.php
+ diag_system_pftop.php
Copyright (C) 2008 Scott Ullrich
All rights reserved.
@@ -31,7 +31,7 @@
##|*IDENT=page-diag-system-activity
##|*NAME=Diagnostics: System Activity
##|*DESCR=Allows access to the 'Diagnostics: System Activity' page
-##|*MATCH=diag_system_activity*
+##|*MATCH=diag_system_pftop*
##|-PRIV
require("guiconfig.inc");
diff --git a/usr/local/www/easyrule.inc b/usr/local/www/easyrule.inc
new file mode 100644
index 0000000..4c7d26d
--- /dev/null
+++ b/usr/local/www/easyrule.inc
@@ -0,0 +1,251 @@
+<?php
+/*
+ easyrule.inc.php
+
+ Copyright (C) 2009 Jim Pingle (jpingle@gmail.com)
+ Sponsored By Anathematic @ pfSense Forums
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+$blockaliasname = 'EasyRuleBlockHosts';
+
+
+function easyrule_find_rule_interface($int) {
+ global $config;
+ /* Borrowed from firewall_rules.php */
+ $iflist = get_configured_interface_with_descr(false, true);
+
+ if ($config['pptpd']['mode'] == "server")
+ $iflist['pptp'] = "PPTP VPN";
+
+ if ($config['pppoe']['mode'] == "server")
+ $iflist['pppoe'] = "PPPoE VPN";
+
+ if ($config['l2tp']['mode'] == "server")
+ $iflist['l2tp'] = "L2TP VPN";
+
+ /* add ipsec interfaces */
+ if (isset($config['ipsec']['enable']) || isset($config['ipsec']['mobileclients']['enable'])){
+ $iflist["enc0"] = "IPSEC";
+ }
+
+ if (isset($iflist[$int]))
+ return $int;
+
+ foreach ($iflist as $if => $ifd) {
+ if (strtolower($int) == strtolower($ifd))
+ return $if;
+ }
+
+ return false;
+}
+
+function easyrule_block_rule_exists($int = 'wan') {
+ global $blockaliasname, $config;
+ /* No rules, we we know it doesn't exist */
+ if (!is_array($config['filter']['rule'])) {
+ return false;
+ }
+
+ /* Search through the rules for one referencing our alias */
+ foreach ($config['filter']['rule'] as $rule)
+ if ($rule['source']['address'] == $blockaliasname . strtoupper($int) && ($rule['interface'] == $int))
+ return true;
+ return false;
+}
+
+function easyrule_block_rule_create($int = 'wan') {
+ global $blockaliasname, $config;
+ /* If the alias doesn't exist, exit.
+ * Can't create an empty alias, and we don't know a host */
+ if (easyrule_block_alias_getid($int) === false)
+ return false;
+
+ /* If the rule already exists, no need to do it again */
+ if (easyrule_block_rule_exists($int))
+ return true;
+
+ /* No rules, start a new array */
+ if (!is_array($config['filter']['rule'])) {
+ $config['filter']['rule'] = array();
+ }
+
+ filter_rules_sort();
+ $a_filter = &$config['filter']['rule'];
+
+ /* Make up a new rule */
+ $filterent = array();
+ $filterent['type'] = 'block';
+ $filterent['interface'] = $int;
+ $filterent['source']['address'] = $blockaliasname . strtoupper($int);
+ $filterent['destination']['any'] = '';
+ $filterent['descr'] = "Easy Rule: Blocked from Firewall Log View";
+
+ $a_filter[] = $filterent;
+
+ return true;
+}
+
+function easyrule_block_alias_getid($int = 'wan') {
+ global $blockaliasname, $config;
+ if (!is_array($config['aliases']))
+ return false;
+
+ /* Hunt down an alias with the name we want, return its id */
+ foreach ($config['aliases']['alias'] as $aliasid => $alias)
+ if ($alias['name'] == $blockaliasname . strtoupper($int))
+ return $aliasid;
+
+ return false;
+}
+
+function easyrule_block_alias_add($host, $int = 'wan') {
+ global $blockaliasname, $config;
+ /* If the host isn't a valid IP address, bail */
+ if (!is_ipaddr($host))
+ return false;
+
+ /* If there are no aliases, start an array */
+ if (!is_array($config['aliases']['alias']))
+ $config['aliases']['alias'] = array();
+
+ aliases_sort();
+ $a_aliases = &$config['aliases']['alias'];
+
+ /* Try to get the ID if the alias already exists */
+ $id = easyrule_block_alias_getid($int);
+ if ($id === false)
+ unset($id);
+
+ $alias = array();
+
+ if (isset($id) && $a_aliases[$id]) {
+ /* Make sure this IP isn't already in the list. */
+ if (in_array($host.'/32', explode(" ", $a_aliases[$id]['address'])))
+ return true;
+ /* Since the alias already exists, just add to it. */
+ $alias['name'] = $a_aliases[$id]['name'];
+ $alias['type'] = $a_aliases[$id]['type'];
+ $alias['descr'] = $a_aliases[$id]['descr'];
+
+ $alias['address'] = $a_aliases[$id]['address'] . ' ' . $host . '/32';
+ $alias['detail'] = $a_aliases[$id]['detail'] . 'Entry added ' . date('r') . '||';
+ } else {
+ /* Create a new alias with all the proper information */
+ $alias['name'] = $blockaliasname . strtoupper($int);
+ $alias['type'] = 'network';
+ $alias['descr'] = mb_convert_encoding("Hosts blocked from Firewall Log view","HTML-ENTITIES","auto");
+
+ $alias['address'] = $host . '/32';
+ $alias['detail'] = 'Entry added ' . date('r') . '||';
+ }
+
+ /* Replace the old alias if needed, otherwise tack it on the end */
+ if (isset($id) && $a_aliases[$id])
+ $a_aliases[$id] = $alias;
+ else
+ $a_aliases[] = $alias;
+
+ return true;
+}
+
+function easyrule_block_host_add($host, $int = 'wan') {
+ global $retval;
+ /* Bail if the supplied host is not a valid IP address */
+ if (!is_ipaddr($host))
+ return false;
+
+ /* Flag whether or not we need to reload the filter */
+ $dirty = false;
+
+ /* Attempt to add this host to the alias */
+ if (easyrule_block_alias_add($host, $int)) {
+ $dirty = true;
+ } else {
+ /* Couldn't add the alias, or adding the host failed. */
+ return false;
+ }
+
+ /* Attempt to add the firewall rule if it doesn't exist.
+ * Failing to add the rule isn't necessarily an error, it may
+ * have been modified by the user in some way. Adding to the
+ * Alias is what's important.
+ */
+ if (!easyrule_block_rule_exists($int)) {
+ if (easyrule_block_rule_create($int)) {
+ $dirty = true;
+ } else {
+ return false;
+ }
+ }
+
+ /* If needed, write the config and reload the filter */
+ if ($dirty) {
+ write_config();
+ $retval = filter_configure();
+ header("Location: firewall_aliases.php");
+ exit;
+ } else {
+ return false;
+ }
+}
+
+function easyrule_pass_rule_add($int, $proto, $srchost, $dsthost, $dstport) {
+ global $config;
+
+ /* No rules, start a new array */
+ if (!is_array($config['filter']['rule'])) {
+ $config['filter']['rule'] = array();
+ }
+
+ filter_rules_sort();
+ $a_filter = &$config['filter']['rule'];
+
+ /* Make up a new rule */
+ $filterent = array();
+ $filterent['type'] = 'pass';
+ $filterent['interface'] = $int;
+ $filterent['descr'] = "Easy Rule: Passed from Firewall Log View";
+
+ if ($proto != "any")
+ $filterent['protocol'] = $proto;
+ else
+ unset($filterent['protocol']);
+
+ /* Default to only allow echo requests, since that's what most people want and
+ * it should be a safe choice. */
+ if ($proto == "icmp")
+ $filterent['icmptype'] = 'echoreq';
+
+ pconfig_to_address($filterent['source'], $srchost, 32);
+ pconfig_to_address($filterent['destination'], $dsthost, 32, '', $dstport, $dstport);
+
+ $a_filter[] = $filterent;
+
+ write_config();
+ $retval = filter_configure();
+ header("Location: firewall_rules.php?if={$int}");
+ exit;
+}
+?>
diff --git a/usr/local/www/easyrule.php b/usr/local/www/easyrule.php
new file mode 100644
index 0000000..090056b
--- /dev/null
+++ b/usr/local/www/easyrule.php
@@ -0,0 +1,132 @@
+<?php
+/*
+ easyrule.php
+
+ Copyright (C) 2009 Jim Pingle (jpingle@gmail.com)
+ Sponsored By Anathematic @ pfSense Forums
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+$pgtitle = "Status : EasyRule";
+require_once("guiconfig.inc");
+require_once("easyrule.inc");
+$retval = 0;
+$message = "";
+
+if ($_GET && isset($_GET['action'])) {
+ switch ($_GET['action']) {
+ case 'block':
+ /* Check that we have a valid host */
+ if (isset($_GET['src']) && isset($_GET['int'])) {
+ if (!is_ipaddr($_GET['src'])) {
+ $message .= "Tried to block invalid IP: " . htmlspecialchars($_GET['src']) . "<br/>";
+ break;
+ }
+ $_GET['int'] = easyrule_find_rule_interface($_GET['int']);
+ if ($_GET['int'] === false) {
+ $message .= "Invalid interface for block rule: " . htmlspecialchars($_GET['int']) . "<br/>";
+ break;
+ }
+ if (easyrule_block_host_add($_GET['src'], $_GET['int'])) {
+ /* shouldn't get here, the function will redirect */
+ $message .= "Host added successfully" . "<br/>";
+ } else {
+ $message .= "Failed to create block rule, alias, or add host." . "<br/>";
+ }
+ } else {
+ $message .= "Tried to block but had no host IP or interface<br/>";
+ }
+ break;
+ case 'pass':
+ /* Check for valid int, srchost, dsthost, dstport, and proto */
+ if (isset($_GET['int']) && isset($_GET['proto']) && isset($_GET['src']) && isset($_GET['dst'])) {
+ $_GET['int'] = easyrule_find_rule_interface($_GET['int']);
+ if ($_GET['int'] === false) {
+ $message .= "Invalid interface for pass rule: " . htmlspecialchars($_GET['int']) . "<br/>";
+ break;
+ }
+ if (getprotobyname($_GET['proto']) == -1) {
+ $message .= "Invalid protocol for pass rule: " . htmlspecialchars($_GET['proto']) . "<br/>";
+ break;
+ }
+ if (!is_ipaddr($_GET['src'])) {
+ $message .= "Tried to pass invalid source IP: " . htmlspecialchars($_GET['src']) . "<br/>";
+ break;
+ }
+ if (!is_ipaddr($_GET['dst'])) {
+ $message .= "Tried to pass invalid destination IP: " . htmlspecialchars($_GET['dst']) . "<br/>";
+ break;
+ }
+ if (($_GET['proto'] != 'icmp') && !isset($_GET['dstport'])) {
+ $message .= "Missing destination port: " . htmlspecialchars($_GET['dstport']) . "<br/>";
+ break;
+ }
+ if ($_GET['proto'] == 'icmp') {
+ $_GET['dstport'] = 0;
+ }
+ if (!is_numeric($_GET['dstport']) || ($_GET['dstport'] < 0) || ($_GET['dstport'] > 65536)) {
+ $message .= "Tried to pass invalid destination port: " . htmlspecialchars($_GET['dstport']) . "<br/>";
+ break;
+ }
+ /* Should have valid input... */
+ if (easyrule_pass_rule_add($_GET['int'], $_GET['proto'], $_GET['src'], $_GET['dst'], $_GET['dstport'])) {
+ /* Shouldn't get here, the function should redirect. */
+ $message .= "Successfully added pass rule!" . "<br/>";
+ } else {
+ $message .= "Failed to add pass rule." . "<br/>";
+ }
+ } else {
+ $message = "Missing parameters for pass rule";
+ break;
+ }
+ break;
+ }
+}
+
+if(stristr($retval, "error") == true)
+ $message = $retval;
+
+include("head.inc"); ?>
+<body link="#000000" vlink="#000000" alink="#000000">
+<? include("fbegin.inc"); ?>
+<p class="pgtitle"><?=$pgtitle?></p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+
+<?php if ($message) { ?>
+<br/>
+Message: <?php echo $message; ?>
+<br/>
+<? } else { ?>
+This is the Easy Rule status page, mainly used to display errors when adding rules.
+If you are seeing this, there apparently was not an error, and you navigated to the
+page directly without telling it what to do.<br/><br/>
+This page is meant to be called from the block/pass buttons on the Firewall Logs page, <a href="diag_logs_filter.php">Status &gt; System Logs,
+Firewall Tab</a>.
+<br />
+<? } ?>
+</td></tr></table>
+<?php include("fend.inc"); ?>
diff --git a/usr/local/www/edit.php b/usr/local/www/edit.php
index 32d2b2f..e820dac 100755..100644
--- a/usr/local/www/edit.php
+++ b/usr/local/www/edit.php
@@ -124,12 +124,15 @@ outputJavaScriptFileInline("filebrowser/browser.js");
function saveFile(file) {
$("fileStatus").innerHTML = "Saving file ...";
Effect.Appear("fileStatusBox", { duration: 0.5 });
-
+
+ var fileContent = escape($("fileContent").value);
+ fileContent = fileContent.replace(/\+/g,"%2B");
+
new Ajax.Request(
"<?=$_SERVER['SCRIPT_NAME'];?>", {
method: "post",
postBody: "action=save&file=" + $("fbTarget").value +
- "&data=" + $("fileContent").value,
+ "&data=" + fileContent,
onComplete: function(req) {
var values = req.responseText.split("|");
$("fileStatus").innerHTML = values[1];
diff --git a/usr/local/www/exec.php b/usr/local/www/exec.php
index 1ce8657..c6f8788 100755
--- a/usr/local/www/exec.php
+++ b/usr/local/www/exec.php
@@ -54,7 +54,8 @@ if (($_POST['submit'] == "Download") && file_exists($_POST['dlPath'])) {
unset($_POST['txtCommand']);
}
-conf_mount_rw();
+if($_POST)
+ conf_mount_rw();
// Function: is Blank
// Returns true or false depending on blankness of argument.
@@ -321,6 +322,7 @@ document.forms[0].txtCommand.focus();
<?php
-conf_mount_ro();
+if($_POST)
+ conf_mount_ro();
-?>
+?> \ No newline at end of file
diff --git a/usr/local/www/fbegin.inc b/usr/local/www/fbegin.inc
index c755a76..6a5b0cb 100755
--- a/usr/local/www/fbegin.inc
+++ b/usr/local/www/fbegin.inc
@@ -1,3 +1,6 @@
+
+<script src="/javascript/sorttable.js"></script>
+
<?php
require_once("globals.inc");
@@ -123,7 +126,7 @@ if ($_REQUEST['noticeaction'] == 'acknowledge') {
output_menu_item("/system_advanced_admin.php", "Advanced");
output_menu_item("/system_firmware.php", "Firmware");
output_menu_item("/system.php", "General Setup");
- if ($g['platform'] == "pfSense")
+ if ($g['platform'] == "pfSense" or $g['platform'] == "nanobsd")
output_menu_item("/pkg_mgr.php", "Packages");
output_menu_item("/wizard.php?xml=setup_wizard.xml", "Setup Wizard");
output_menu_item("/system_gateways.php", "Routing");
@@ -259,13 +262,17 @@ if ($_REQUEST['noticeaction'] == 'acknowledge') {
output_menu_item("/diag_arp.php", "ARP Tables");
output_menu_item("/diag_backup.php", "Backup/Restore");
output_menu_item("/exec.php", "Command Prompt");
+ output_menu_item("/diag_dns.php", "DNS Lookup");
output_menu_item("/edit.php", "Edit File");
output_menu_item("/diag_defaults.php", "Factory Defaults");
- output_menu_item("/halt.php", "Halt System");
+ output_menu_item("/halt.php", "Halt System");
+ if($g['platform'] == "nanobsd")
+ output_menu_item("/diag_nanobsd.php", "NanoBSD");
output_menu_item("/diag_ping.php", "Ping");
output_menu_item("/diag_system_pftop.php", "pfTOP");
output_menu_item("/reboot.php", "Reboot");
output_menu_item("/diag_routes.php", "Routes");
+ output_menu_item("/diag_showbogons.php", "Show Bogons");
output_menu_item("/diag_dump_states.php", "States");
output_menu_item("/diag_system_activity.php", "System Activity");
output_menu_item("/diag_traceroute.php", "Traceroute");
diff --git a/usr/local/www/filter_log.inc b/usr/local/www/filter_log.inc
index f7b6c32..5c54dbd 100644
--- a/usr/local/www/filter_log.inc
+++ b/usr/local/www/filter_log.inc
@@ -1,7 +1,7 @@
<?php
/* $Id$ */
/*
- log.inc.php
+ filter_log.inc
part of pfSesne by Scott Ullrich
originally based on m0n0wall (http://m0n0.ch/wall)
@@ -31,13 +31,16 @@
*/
/* format filter logs */
-function conv_log_filter($logfile, $nentries, $tail = 50) {
+function conv_log_filter($logfile, $nentries, $tail = 50, $filtertext = "") {
global $config, $g;
/* Make sure this is a number before using it in a system call */
if (!(is_numeric($tail)))
return;
+ if ($filtertext)
+ $tail = 5000;
+
/* FreeBSD 8 splits pf log lines into two lines, so we need to at least
* tail twice as many, plus some extra to account for unparseable lines */
$tail = $tail * 2 + 50;
@@ -45,7 +48,7 @@ function conv_log_filter($logfile, $nentries, $tail = 50) {
/* Always do a reverse tail, to be sure we're grabbing the 'end' of the log. */
$logarr = "";
- if(isset($config['system']['usefifolog']))
+ if(isset($config['system']['usefifolog']))
exec("/usr/sbin/fifolog_reader {$logfile} | /usr/bin/tail -r -n {$tail}", $logarr);
else
exec("/usr/sbin/clog {$logfile} | grep -v \"CLOG\" | grep -v \"\033\" | /usr/bin/tail -r -n {$tail}", $logarr);
@@ -60,7 +63,7 @@ function conv_log_filter($logfile, $nentries, $tail = 50) {
break;
$flent = parse_filter_line($logent);
- if ($flent != "") {
+ if (($flent != "") && (match_filter_line($flent, $filtertext))) {
$counter++;
$filterlog[] = $flent;
}
@@ -69,6 +72,13 @@ function conv_log_filter($logfile, $nentries, $tail = 50) {
return isset($config['syslog']['reverse']) ? $filterlog : array_reverse($filterlog);
}
+function match_filter_line($flent, $filtertext = "") {
+ if (!$filtertext)
+ return true;
+ $filtertext = str_replace(' ', '\s+', $filtertext);
+ return preg_match("/{$filtertext}/i", implode(" ", array_values($flent)));
+}
+
function collapse_filter_lines($logarr) {
$lastline = "";
$collapsed = array();
@@ -95,8 +105,17 @@ function parse_filter_line($line) {
list($all, $flent['time'], $host, $rule, $flent['act'], $flent['realint'], $details, $src, $dst, $leftovers) = $log_split;
- $flent['src'] = convert_port_period_to_colon($src);
- $flent['dst'] = convert_port_period_to_colon($dst);
+ list($flent['srcip'], $flent['srcport']) = parse_ipport($src);
+ list($flent['dstip'], $flent['dstport']) = parse_ipport($dst);
+
+ $flent['src'] = $flent['srcip'];
+ $flent['dst'] = $flent['dstip'];
+
+ if ($flent['srcport'])
+ $flent['src'] .= ':' . $flent['srcport'];
+ if ($flent['dstport'])
+ $flent['dst'] .= ':' . $flent['dstport'];
+
$flent['interface'] = convert_log_interface_to_friendly_interface_name($flent['realint']);
$tmp = split("/", $rule);
@@ -104,7 +123,7 @@ function parse_filter_line($line) {
$proto = array(" ", "(?)");
/* Attempt to determine the protocol, based on several possible patterns.
- * The value returned by strpos() must be strictly checkeded against the
+ * The value returned by strpos() must be strictly checkeded against the
* boolean FALSE because it could return a valid answer of 0 upon success. */
if (!(strpos($details, 'proto ') === FALSE)) {
preg_match("/.*\sproto\s(.*)\s\(/", $details, $proto);
@@ -152,26 +171,49 @@ function convert_log_interface_to_friendly_interface_name($int) {
return $int;
}
-function convert_port_period_to_colon($addr) {
+function parse_ipport($addr) {
+ $addr = rtrim($addr, ":");
+ $port = '';
if (substr_count($addr, '.') > 1) {
- /* IPv4 - Change the port delimiter to : */
+ /* IPv4 */
$addr_split = split("\.", $addr);
- if($addr_split[4] == "") {
- $newvar = "{$addr_split[0]}.{$addr_split[1]}.{$addr_split[2]}.{$addr_split[3]}";
- $newvar = rtrim($newvar, ":");
- } else {
+ $ip = "{$addr_split[0]}.{$addr_split[1]}.{$addr_split[2]}.{$addr_split[3]}";
+
+ if ($ip == "...")
+ return array($addr, '');
+
+ if($addr_split[4] != "") {
$port_split = split("\:", $addr_split[4]);
- $newvar = "{$addr_split[0]}.{$addr_split[1]}.{$addr_split[2]}.{$addr_split[3]}:{$port_split[0]}";
- $newvar = rtrim($newvar, ":");
+ $port = $port_split[0];
}
- if($newvar == "...")
- return $addr;
- return $newvar;
} else {
- /* IPv6 - Leave it alone */
+ /* IPv6 */
$addr = split(" ", $addr);
- return rtrim($addr[0], ":");
+ $addr = rtrim($addr[0], ":");
+ $addr_split = split("\.", $addr);
+ if (count($addr_split) > 1) {
+ $ip = $addr_split[0];
+ $port = $addr_split[1];
+ } else {
+ $ip = $addr;
+ }
+ }
+
+ return array($ip, $port);
+}
+
+function get_port_with_service($port, $proto) {
+ if (!$port)
+ return '';
+
+ $service = getservbyport($port, $proto);
+ $portstr = "";
+ if ($service) {
+ $portstr = "<span title=\"Service {$port}/{$proto}: {$service}\">" . htmlspecialchars($port) . "</span>";
+ } else {
+ $portstr = htmlspecialchars($port);
}
+ return ':' . $portstr;
}
function find_rule_by_number($rulenum, $type="rules") {
diff --git a/usr/local/www/filterparser.php b/usr/local/www/filterparser.php
index 79e927d..2ca79fe 100644
--- a/usr/local/www/filterparser.php
+++ b/usr/local/www/filterparser.php
@@ -63,7 +63,11 @@ while(!feof($log)) {
proto - Protocol (e.g. TCP, UDP, ICMP, etc)
tcpflags - TCP flags/control bits
src - Source address with port
+ srcip - Source IP
+ srcport - Source Port
dst - Destination address with port
+ dstip - Destination IP
+ dstport - Destination Port
*/
if ($flent != "")
echo "{$flent['time']} {$flent['act']} {$flent['realint']} {$flent['proto']} {$flent['src']} {$flent['dst']}\n";
diff --git a/usr/local/www/firewall_aliases.php b/usr/local/www/firewall_aliases.php
index c0701f6..76c473e 100755
--- a/usr/local/www/firewall_aliases.php
+++ b/usr/local/www/firewall_aliases.php
@@ -61,10 +61,8 @@ if ($_POST) {
$savemsg = get_std_save_message($retval);
else
$savemsg = $retval;
- if ($retval == 0) {
- if (file_exists($d_aliasesdirty_path))
- unlink($d_aliasesdirty_path);
- }
+ if ($retval == 0)
+ clear_subsystem_dirty('aliases');
}
}
@@ -141,7 +139,7 @@ if ($_GET['act'] == "del") {
unset($a_aliases[$_GET['id']]);
write_config();
filter_configure();
- touch($d_aliasesdirty_path);
+ mark_subsystem_dirty('aliases');
header("Location: firewall_aliases.php");
exit;
}
@@ -157,7 +155,7 @@ include("head.inc");
<?php include("fbegin.inc"); ?>
<form action="firewall_aliases.php" method="post">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_aliasesdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('aliases')): ?><p>
<?php print_info_box_np("The alias list has been changed.<br>You must apply the changes in order for them to take effect.");?>
<?php endif; ?>
diff --git a/usr/local/www/firewall_aliases_edit.php b/usr/local/www/firewall_aliases_edit.php
index 5971283..d99ae71 100755
--- a/usr/local/www/firewall_aliases_edit.php
+++ b/usr/local/www/firewall_aliases_edit.php
@@ -3,6 +3,7 @@
/*
firewall_aliases_edit.php
Copyright (C) 2004 Scott Ullrich
+ Copyright (C) 2009 Ermal Luçi
All rights reserved.
originially part of m0n0wall (http://m0n0.ch/wall)
@@ -48,12 +49,68 @@ if (!is_array($config['aliases']['alias']))
aliases_sort();
$a_aliases = &$config['aliases']['alias'];
+
+if($_POST)
+ $origname = $_POST['origname'];
+
+// Debugging
+if($debug)
+ exec("rm -f {$g['tmp_path']}/alias_rename_log.txt");
+
+function update_alias_names_upon_change($section, $subsection, $fielda, $fieldb, $new_alias_name) {
+ global $g, $config, $pconfig, $origname, $debug;
+ if(!$origname)
+ return;
+
+ if($debug) $fd = fopen("{$g['tmp_path']}/print_r", "a");
+ if($debug) fwrite($fd, print_r($pconfig, true));
+
+ if($fieldb) {
+ if($debug) fwrite($fd, "fieldb exists\n");
+ for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) {
+ if($debug) fwrite($fd, "$i\n");
+ if($config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] == $origname) {
+ if($debug) fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
+ $config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] = $new_alias_name;
+ }
+ }
+ } else {
+ if($debug) fwrite($fd, "fieldb does not exist\n");
+ for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) {
+ if($config["$section"]["$subsection"][$i]["$fielda"] == $origname) {
+ $config["$section"]["$subsection"][$i]["$fielda"] = $new_alias_name;
+ if($debug) fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
+ }
+ }
+ }
+
+ if($debug) fclose($fd);
+
+}
+
+function alias_same_type($name, $type) {
+ global $config;
+
+ foreach ($config['aliases']['alias'] as $alias) {
+ if ($name == $alias['name']) {
+ if (in_array($type, array("host", "network")) &&
+ in_array($alias['type'], array("host", "network")))
+ return true;
+ if ($type == $alias['type'])
+ return true;
+ else
+ return false;
+ }
+ }
+ return true;
+}
$id = $_GET['id'];
if (isset($_POST['id']))
$id = $_POST['id'];
if (isset($id) && $a_aliases[$id]) {
+ $original_alias_name = $a_aliases[$id]['name'];
$pconfig['name'] = $a_aliases[$id]['name'];
$pconfig['detail'] = $a_aliases[$id]['detail'];
$pconfig['address'] = $a_aliases[$id]['address'];
@@ -144,9 +201,9 @@ if ($_POST) {
if($_POST['address' . $x]) {
/* fetch down and add in */
$isfirst = 0;
- $temp_filename = tempnam("/tmp/", "alias_import");
+ $temp_filename = tempnam("{$g['tmp_path']}/", "alias_import");
unlink($temp_filename);
- $fda = fopen("/tmp/tmpfetch","w");
+ $fda = fopen("{$g['tmp_path']}/tmpfetch","w");
fwrite($fda, "/usr/bin/fetch -q -o \"{$temp_filename}/aliases\" \"" . $_POST['address' . $x] . "\"");
fclose($fda);
mwexec("mkdir -p {$temp_filename}");
@@ -190,12 +247,13 @@ if ($_POST) {
$address = "";
$isfirst = 0;
/* item is a normal alias type */
+ $wrongaliases = "";
for($x=0; $x<4999; $x++) {
if($_POST["address{$x}"] <> "") {
if ($isfirst > 0)
$address .= " ";
$address .= $_POST["address{$x}"];
- if($_POST["address_subnet{$x}"] <> "")
+ if(is_ipaddr($_POST["address{$x}"]) && $_POST["address_subnet{$x}"] <> "")
$address .= "/" . $_POST["address_subnet{$x}"];
if($_POST["detail{$x}"] <> "") {
@@ -207,7 +265,13 @@ if ($_POST) {
$final_address_details .= "||";
$isfirst++;
}
+ if (is_alias($_POST["address{$x}"])) {
+ if (!alias_same_type($_POST["address{$x}"], $_POST['type']))
+ $wrongaliases .= " " . $_POST["address{$x}"];
+ }
}
+ if ($wrongaliases <> "")
+ $input_errors[] = "The following aliases: {$wrongaliases} \ncannot be nested cause they are not of the same type.";
}
if (!$input_errors) {
@@ -216,12 +280,43 @@ if ($_POST) {
$alias['type'] = $_POST['type'];
$alias['detail'] = $final_address_details;
- if (isset($id) && $a_aliases[$id])
+ /* Check to see if alias name needs to be
+ * renamed on referenced rules and such
+ */
+ if ($_POST['name'] <> $_POST['origname']) {
+ // Firewall rules
+ update_alias_names_upon_change('filter', 'rule', 'source', 'address', $_POST['name']);
+ update_alias_names_upon_change('filter', 'rule', 'destination', 'address', $_POST['name']);
+ // NAT Rules
+ update_alias_names_upon_change('nat', 'rule', 'target', '', $_POST['name']);
+ update_alias_names_upon_change('nat', 'rule', 'external-port', '', $_POST['name']);
+ update_alias_names_upon_change('nat', 'rule', 'local-port', '' , $_POST['name']);
+ // Alias in an alias
+ update_alias_names_upon_change('aliases', 'alias', 'address', '' , $_POST['name']);
+ }
+
+ if (isset($id) && $a_aliases[$id]) {
+ if ($a_aliases[$id]['name'] <> $alias['name']) {
+ foreach ($a_aliases as $aliasid => $aliasd) {
+ if ($aliasd['address'] <> "") {
+ $tmpdirty = false;
+ $tmpaddr = explode(" ", $aliasd['address']);
+ foreach ($tmpaddr as $tmpidx => $tmpalias) {
+ if ($tmpalias == $a_aliases[$id]['name']) {
+ $tmpaddr[$tmpidx] = $alias['name'];
+ $tmpdirty = true;
+ }
+ }
+ if ($tmpdirty == true)
+ $a_aliases[$aliasid]['address'] = implode(" ", $tmpaddr);
+ }
+ }
+ }
$a_aliases[$id] = $alias;
- else
+ } else
$a_aliases[] = $alias;
- touch($d_aliasesdirty_path);
+ mark_subsystem_dirty('aliases');
write_config();
filter_configure();
@@ -244,6 +339,8 @@ include("head.inc");
$jscriptstr = <<<EOD
<script type="text/javascript">
+
+var objAlias = new Array(4999);
function typesel_change() {
switch (document.iform.type.selectedIndex) {
case 0: /* host */
@@ -300,6 +397,13 @@ function typesel_change() {
}
}
+function add_alias_control() {
+ var name = "address" + (totalrows - 1);
+ obj = document.getElementById(name);
+ obj.setAttribute('class', 'formfldalias');
+ obj.setAttribute('autocomplete', 'off');
+ objAlias[totalrows - 1] = new AutoSuggestControl(obj, new StateSuggestions(addressarray));
+}
EOD;
$network_str = gettext("Network");
@@ -374,6 +478,10 @@ EOD;
<script type="text/javascript" src="/javascript/row_helper.js">
</script>
+<script type="text/javascript" src="/javascript/autosuggest.js">
+</script>
+<script type="text/javascript" src="/javascript/suggestions.js">
+</script>
<input type='hidden' name='address_type' value='textbox' />
<input type='hidden' name='address_subnet_type' value='select' />
@@ -400,20 +508,10 @@ EOD;
<tr>
<td colspan="2" valign="top" class="listtopic">Alias Edit</td>
</tr>
-<?php if(is_alias_inuse($pconfig['name']) == true): ?>
- <tr>
- <td valign="top" class="vncellreq">Name</td>
- <td class="vtable"> <input name="name" type="hidden" id="name" size="40" value="<?=htmlspecialchars($pconfig['name']);?>" />
- <?php echo $pconfig['name']; ?>
- <p>
- <span class="vexpl">NOTE: This alias is in use so the name may not be modified!</span>
- </p>
- </td>
- </tr>
-<?php else: ?>
<tr>
<td valign="top" class="vncellreq">Name</td>
<td class="vtable">
+ <input name="origname" type="hidden" id="origname" class="formfld unknown" size="40" value="<?=htmlspecialchars($pconfig['name']);?>" />
<input name="name" type="text" id="name" class="formfld unknown" size="40" value="<?=htmlspecialchars($pconfig['name']);?>" />
<br />
<span class="vexpl">
@@ -421,7 +519,6 @@ EOD;
</span>
</td>
</tr>
-<?php endif; ?>
<tr>
<td width="22%" valign="top" class="vncell">Description</td>
<td width="78%" class="vtable">
@@ -480,7 +577,7 @@ EOD;
?>
<tr>
<td>
- <input name="address<?php echo $tracker; ?>" type="text" class="formfld unknown" id="address<?php echo $tracker; ?>" size="30" value="<?=htmlspecialchars($address);?>" />
+ <input autocomplete="off" name="address<?php echo $tracker; ?>" type="text" class="formfldalias" id="address<?php echo $tracker; ?>" size="30" value="<?=htmlspecialchars($address);?>" />
</td>
<td>
<select name="address_subnet<?php echo $tracker; ?>" class="formselect" id="address_subnet<?php echo $tracker; ?>">
@@ -508,7 +605,7 @@ EOD;
</tfoot>
</table>
- <a onclick="javascript:addRowTo('maintable'); typesel_change(); return false;" href="#">
+ <a onclick="javascript:addRowTo('maintable', 'formfldalias'); typesel_change(); add_alias_control(this); return false;" href="#">
<img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="add another entry" />
</a>
</td>
@@ -533,6 +630,30 @@ EOD;
loaded = <?php echo $counter; ?>;
typesel_change();
update_box_type();
+
+<?php
+ $isfirst = 0;
+ $aliases = "";
+ $addrisfirst = 0;
+ $aliasesaddr = "";
+ if(isset($config['aliases']['alias']) && is_array($config['aliases']['alias']))
+ foreach($config['aliases']['alias'] as $alias_name) {
+ if ($pconfig['name'] <> "" && $pconfig['name'] == $alias_name['name'])
+ continue;
+ if($addrisfirst == 1) $aliasesaddr .= ",";
+ $aliasesaddr .= "'" . $alias_name['name'] . "'";
+ $addrisfirst = 1;
+ }
+?>
+
+ var addressarray=new Array(<?php echo $aliasesaddr; ?>);
+
+<?php
+ for ($jv = 0; $jv < $counter; $jv++)
+ echo "objAlias[{$jv}] = new AutoSuggestControl(document.getElementById(\"address{$jv}\"), new StateSuggestions(addressarray));\n";
+?>
+
+
</script>
<?php include("fend.inc"); ?>
diff --git a/usr/local/www/firewall_nat.php b/usr/local/www/firewall_nat.php
index 9bcc2e6..274a3f2 100755
--- a/usr/local/www/firewall_nat.php
+++ b/usr/local/www/firewall_nat.php
@@ -69,10 +69,8 @@ if ($_POST) {
$retval |= filter_configure();
if ($retval == 0) {
- if (file_exists($d_natconfdirty_path))
- unlink($d_natconfdirty_path);
- if (file_exists($d_filterconfdirty_path))
- unlink($d_filterconfdirty_path);
+ clear_subsystem_dirty('natconf');
+ clear_subsystem_dirty('filter');
}
}
@@ -83,10 +81,16 @@ if (isset($_POST['del_x'])) {
if (is_array($_POST['rule']) && count($_POST['rule'])) {
foreach ($_POST['rule'] as $rulei) {
$target = $rule['target'];
+ // Check for filter rule associations
+ if (isset($a_nat[$rulei]['associated-filter-rule-id'])){
+ delete_id($a_nat[$rulei]['associated-filter-rule-id'], $config['filter']['rule']);
+
+ mark_subsystem_dirty('filter');
+ }
unset($a_nat[$rulei]);
}
write_config();
- touch($d_natconfdirty_path);
+ mark_subsystem_dirty('natconf');
header("Location: firewall_nat.php");
exit;
}
@@ -129,7 +133,7 @@ if (isset($_POST['del_x'])) {
}
$a_nat = $a_nat_new;
write_config();
- touch($d_natconfdirty_path);
+ mark_subsystem_dirty('natconf');
header("Location: firewall_nat.php");
exit;
}
@@ -148,7 +152,7 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
<?php include("fbegin.inc"); ?>
<form action="firewall_nat.php" method="post" name="iform">
<script type="text/javascript" language="javascript" src="/javascript/row_toggle.js"></script>
-<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('natconf')): ?><p>
<?php
if($savemsg)
print_info_box_np("{$savemsg}<br>The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");
@@ -219,7 +223,11 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
?>
<tr valign="top" id="fr<?=$nnats;?>">
<td class="listt"><input type="checkbox" id="frc<?=$nnats;?>" name="rule[]" value="<?=$i;?>" onClick="fr_bgcolor('<?=$nnats;?>')" style="margin: 0; padding: 0; width: 15px; height: 15px;"></td>
- <td class="listt" align="center"></td>
+ <td class="listt" align="center">
+ <?php if(isset($natent['associated-filter-rule-id']) && $natent['associated-filter-rule-id']>0): ?>
+ <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_chain.png" width="17" height="17" title="Firewall rule ID <?=htmlspecialchars($natent['associated-filter-rule-id']); ?> is managed with this rule" border="0">
+ <?php endif; ?>
+ </td>
<td class="listlr" onClick="fr_toggle(<?=$nnats;?>)" id="frd<?=$nnats;?>" ondblclick="document.location='firewall_nat_edit.php?id=<?=$nnats;?>';">
<?php
if (!$natent['interface'] || ($natent['interface'] == "wan"))
diff --git a/usr/local/www/firewall_nat_1to1.php b/usr/local/www/firewall_nat_1to1.php
index 009106a..29f7585 100755
--- a/usr/local/www/firewall_nat_1to1.php
+++ b/usr/local/www/firewall_nat_1to1.php
@@ -43,7 +43,6 @@ if (!is_array($config['nat']['onetoone'])) {
$config['nat']['onetoone'] = array();
}
$a_1to1 = &$config['nat']['onetoone'];
-nat_1to1_rules_sort();
if ($_POST) {
@@ -55,10 +54,8 @@ if ($_POST) {
$savemsg = get_std_save_message($retval);
if ($retval == 0) {
- if (file_exists($d_natconfdirty_path))
- unlink($d_natconfdirty_path);
- if (file_exists($d_filterconfdirty_path))
- unlink($d_filterconfdirty_path);
+ clear_subsystem_dirty('natconf');
+ clear_subsystem_dirty('filter');
}
}
}
@@ -67,7 +64,7 @@ if ($_GET['act'] == "del") {
if ($a_1to1[$_GET['id']]) {
unset($a_1to1[$_GET['id']]);
write_config();
- touch($d_natconfdirty_path);
+ mark_subsystem_dirty('natconf');
header("Location: firewall_nat_1to1.php");
exit;
}
@@ -81,7 +78,7 @@ include("head.inc");
<?php include("fbegin.inc"); ?>
<form action="firewall_nat_1to1.php" method="post">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('natconf')): ?><p>
<?php print_info_box_np("The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td>
diff --git a/usr/local/www/firewall_nat_1to1_edit.php b/usr/local/www/firewall_nat_1to1_edit.php
index 7ef2fab..eaa14a9 100755
--- a/usr/local/www/firewall_nat_1to1_edit.php
+++ b/usr/local/www/firewall_nat_1to1_edit.php
@@ -36,6 +36,19 @@
##|*MATCH=firewall_nat_1to1_edit.php*
##|-PRIV
+function nat1to1cmp($a, $b) {
+ return ipcmp($a['external'], $b['external']);
+}
+
+function nat_1to1_rules_sort() {
+ global $g, $config;
+
+ if (!is_array($config['nat']['onetoone']))
+ return;
+
+
+ usort($config['nat']['onetoone'], "nat1to1cmp");
+}
require("guiconfig.inc");
@@ -123,12 +136,13 @@ if ($_POST) {
$natent['descr'] = $_POST['descr'];
$natent['interface'] = $_POST['interface'];
+ nat_1to1_rules_sort();
if (isset($id) && $a_1to1[$id])
$a_1to1[$id] = $natent;
else
$a_1to1[] = $natent;
- touch($d_natconfdirty_path);
+ mark_subsystem_dirty('natconf');
write_config();
diff --git a/usr/local/www/firewall_nat_edit.php b/usr/local/www/firewall_nat_edit.php
index b7a65e4..d8a9fb6 100755
--- a/usr/local/www/firewall_nat_edit.php
+++ b/usr/local/www/firewall_nat_edit.php
@@ -42,7 +42,6 @@ require("guiconfig.inc");
if (!is_array($config['nat']['rule'])) {
$config['nat']['rule'] = array();
}
-//nat_rules_sort();
$a_nat = &$config['nat']['rule'];
$id = $_GET['id'];
@@ -62,6 +61,7 @@ if (isset($id) && $a_nat[$id]) {
$pconfig['localbeginport'] = $a_nat[$id]['local-port'];
$pconfig['descr'] = $a_nat[$id]['descr'];
$pconfig['interface'] = $a_nat[$id]['interface'];
+ $pconfig['associated-filter-rule-id'] = $a_nat[$id]['associated-filter-rule-id'];
$pconfig['nosync'] = isset($a_nat[$id]['nosync']);
if (!$pconfig['interface'])
$pconfig['interface'] = "wan";
@@ -182,24 +182,29 @@ if ($_POST) {
$natent['local-port'] = $_POST['localbeginport'];
$natent['interface'] = $_POST['interface'];
$natent['descr'] = $_POST['descr'];
+ $natent['associated-filter-rule-id'] = $_POST['associated-filter-rule-id'];
if($_POST['nosync'] == "yes")
$natent['nosync'] = true;
else
unset($natent['nosync']);
- if (isset($id) && $a_nat[$id])
- $a_nat[$id] = $natent;
- else {
- if (is_numeric($after))
- array_splice($a_nat, $after+1, 0, array($natent));
- else
- $a_nat[] = $natent;
- }
+ $need_filter_rule = false;
+ // Updating a rule with a filter rule associated
+ if( $natent['associated-filter-rule-id']>0 )
+ $need_filter_rule = true;
+ // If creating a new rule, where we want to add the filter rule, associated or not
+ else if( isset($_POST['filter-rule-association']) &&
+ ($_POST['filter-rule-association']=='add-associated' ||
+ $_POST['filter-rule-association']=='add-unassociated') )
+ $need_filter_rule = true;
+
+ if ($need_filter_rule) {
- touch($d_natconfdirty_path);
+ // If we had a previous rule associated with this NAT rule, delete that
+ if( $natent['associated-filter-rule-id'] > 0 )
+ delete_id($natent['associated-filter-rule-id'], $config['filter']['rule']);
- if ($_POST['autoadd']) {
/* auto-generate a matching firewall rule */
$filterent = array();
$filterent['interface'] = $_POST['interface'];
@@ -222,11 +227,30 @@ if ($_POST) {
*/
$filterent['descr'] = substr("NAT " . $_POST['descr'], 0, 59);
+ // If we had a previous rule association, update this rule with that ID so we don't lose association
+ if ($natent['associated-filter-rule-id'] > 0)
+ $filterent['id'] = $natent['associated-filter-rule-id'];
+ // If we wanted this rule to be associated, make sure the NAT entry is updated with the same ID
+ else if($_POST['filter-rule-association']=='add-associated')
+ $natent['associated-filter-rule-id'] = $filterent['id'] = get_next_id($config['filter']['rule']);
+
$config['filter']['rule'][] = $filterent;
- touch($d_filterconfdirty_path);
+ mark_subsystem_dirty('filter');
}
+ // Update NAT entry after creating/updating the firewall rule, so we have it's rule ID if one was created
+ if (isset($id) && $a_nat[$id])
+ $a_nat[$id] = $natent;
+ else {
+ if (is_numeric($after))
+ array_splice($a_nat, $after+1, 0, array($natent));
+ else
+ $a_nat[] = $natent;
+ }
+
+ mark_subsystem_dirty('natconf');
+
write_config();
header("Location: firewall_nat.php");
@@ -391,13 +415,34 @@ include("fbegin.inc"); ?>
HINT: This prevents the rule from automatically syncing to other CARP members.
</td>
</tr>
+ <?php if (isset($id) && $a_nat[$id] && !isset($_GET['dup'])): ?>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Filter rule association</td>
+ <td width="78%" class="vtable">
+ <select name="associated-filter-rule-id">
+ <option value="">None</option>
+ <?php foreach ($config['filter']['rule'] as $filter_rule): ?>
+ <?php if (isset($filter_rule['id']) && $filter_rule['id']>0): ?>
+ <option value="<?php echo $filter_rule['id']; ?>"<?php if($filter_rule['id']==$pconfig['associated-filter-rule-id']) echo " SELECTED"; ?>>
+ <?php echo htmlspecialchars('Rule ' . $filter_rule['id'] . ' - ' . $filter_rule['descr']); ?>
+ </option>
+ <?php endif; ?>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ </tr>
+ <?php endif; ?>
<?php if ((!(isset($id) && $a_nat[$id])) || (isset($_GET['dup']))): ?>
<tr>
- <td width="22%" valign="top">&nbsp;</td>
+ <td width="22%" valign="top">Filter rule association</td>
<td width="78%">
- <input name="autoadd" type="checkbox" id="autoadd" value="yes" CHECKED>
- <strong>Auto-add a firewall rule to permit traffic through
- this NAT rule</strong></td>
+ <select name="filter-rule-association" id="filter-rule-association">
+ <option value="">None</option>
+ <option value="add-associated" selected="selected">Add associated rule</option>
+ <option value="add-unassociated">Add unassociated rule</option>
+ <option value="pass">Pass</option>
+ </select>
+ </td>
</tr><?php endif; ?>
<tr>
<td width="22%" valign="top">&nbsp;</td>
diff --git a/usr/local/www/firewall_nat_out.php b/usr/local/www/firewall_nat_out.php
index 1a1192c..fc7d14b 100755
--- a/usr/local/www/firewall_nat_out.php
+++ b/usr/local/www/firewall_nat_out.php
@@ -59,8 +59,8 @@ if ($_POST['apply']) {
$savemsg = $retval;
if ($retval == 0) {
- unlink_if_exists($d_natconfdirty_path);
- unlink_if_exists($d_filterconfdirty_path);
+ clear_subsystem_dirty('natconf');
+ clear_subsystem_dirty('filter');
}
}
@@ -112,7 +112,7 @@ if (isset($_POST['save']) && $_POST['save'] == "Save") {
break;
}
write_config();
- touch($d_natconfdirty_path);
+ mark_subsystem_dirty('natconf');
header("Location: firewall_nat_out.php");
exit;
}
@@ -124,7 +124,7 @@ if (isset($_POST['del_x'])) {
unset($a_out[$rulei]);
}
write_config();
- touch($d_natconfdirty_path);
+ mark_subsystem_dirty('natconf');
header("Location: firewall_nat_out.php");
exit;
}
@@ -171,7 +171,7 @@ if (isset($_POST['del_x'])) {
unset($config['nat']['advancedoutbound']);
write_config();
- touch($d_natconfdirty_path);
+ mark_subsystem_dirty('natconf');
header("Location: firewall_nat_out.php");
exit;
}
@@ -188,7 +188,7 @@ include("head.inc");
<script type="text/javascript" language="javascript" src="/javascript/row_toggle.js">
</script>
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('natconf')): ?><p>
<?php print_info_box_np("The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td>
diff --git a/usr/local/www/firewall_nat_out_edit.php b/usr/local/www/firewall_nat_out_edit.php
index 6589fa9..abab75c 100755
--- a/usr/local/www/firewall_nat_out_edit.php
+++ b/usr/local/www/firewall_nat_out_edit.php
@@ -45,7 +45,6 @@ if (!is_array($config['nat']['advancedoutbound']['rule']))
$config['nat']['advancedoutbound']['rule'] = array();
$a_out = &$config['nat']['advancedoutbound']['rule'];
-//nat_out_rules_sort();
$id = $_GET['id'];
if (isset($_POST['id']))
@@ -134,6 +133,9 @@ if ($_POST) {
if ($_POST['destination_not'])
$input_errors[] = "Negating destination address of \"any\" is invalid.";
}
+ if ($_POST['nonat'] && $_POST['staticnatport']) {
+ $input_errors[] = "Static port cannot be used with No NAT.";
+ }
if ($_POST['dstport'] && !is_numericint($_POST['dstport'])) {
$input_errors[] = "A valid destination port must be specified.";
}
@@ -234,7 +236,7 @@ if ($_POST) {
$a_out[] = $natent;
}
- touch($d_natconfdirty_path);
+ mark_subsystem_dirty('natconf');
write_config();
diff --git a/usr/local/www/firewall_nat_server.php b/usr/local/www/firewall_nat_server.php
deleted file mode 100755
index c7f07a7..0000000
--- a/usr/local/www/firewall_nat_server.php
+++ /dev/null
@@ -1,161 +0,0 @@
-<?php
-/* $Id$ */
-/*
- firewall_nat_server.php
- part of m0n0wall (http://m0n0.ch/wall)
-
- Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-*/
-
-##|+PRIV
-##|*IDENT=page-firewall-nat-nataddresses
-##|*NAME=Firewall: NAT: NAT Addresses page
-##|*DESCR=Allow access to the 'Firewall: NAT: NAT Addresses' page.
-##|*MATCH=firewall_nat_server.php*
-##|-PRIV
-
-
-require("guiconfig.inc");
-
-if (!is_array($config['nat']['servernat'])) {
- $config['nat']['servernat'] = array();
-}
-$a_snat = &$config['nat']['servernat'];
-nat_server_rules_sort();
-
-if ($_POST) {
-
- $pconfig = $_POST;
-
- if ($_POST['apply']) {
- $retval = 0;
- $retval |= filter_configure();
-
- $savemsg = get_std_save_message($retval);
-
- if ($retval == 0) {
- if (file_exists($d_natconfdirty_path))
- unlink($d_natconfdirty_path);
- if (file_exists($d_filterconfdirty_path))
- unlink($d_filterconfdirty_path);
- }
- }
-}
-
-if ($_GET['act'] == "del") {
- if ($a_snat[$_GET['id']]) {
- /* make sure no inbound NAT mappings reference this entry */
- if (is_array($config['nat']['rule'])) {
- foreach ($config['nat']['rule'] as $rule) {
- if ($rule['external-address'] == $a_snat[$_GET['id']]['ipaddr']) {
- $input_errors[] = "This entry cannot be deleted because it is still referenced by at least one inbound NAT mapping.";
- break;
- }
- }
- }
-
- if (!$input_errors) {
- unset($a_snat[$_GET['id']]);
- write_config();
- touch($d_natconfdirty_path);
- header("Location: firewall_nat_server.php");
- exit;
- }
- }
-}
-
-$pgtitle = array("Firewall","NAT","NAT Addresses");
-include("head.inc");
-
-?>
-<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
-<?php include("fbegin.inc"); ?>
-<form action="firewall_nat_server.php" method="post">
-<?php if ($input_errors) print_input_errors($input_errors); ?>
-<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_natconfdirty_path)): ?><p>
-<?php print_info_box_np("The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
-<?php endif; ?>
-<table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td>
-<?php
- $tab_array = array();
- $tab_array[0] = array("Port Forward", false, "firewall_nat.php");
- $tab_array[1] = array("NAT Addresses", true, "firewall_nat_server.php");
- $tab_array[2] = array("1:1", false, "firewall_nat_1to1.php");
- $tab_array[3] = array("Outbound", false, "firewall_nat_out.php");
- $tab_array[4] = array("Outbound Load Balancing", false, "firewall_nat_out_load_balancing.php");
- display_top_tabs($tab_array);
-?>
- </td></tr>
- <tr>
- <td>
- <div id="mainarea">
- <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
- <tr>
- <td width="40%" class="listhdrr">External IP address</td>
- <td width="50%" class="listhdr">Description</td>
- <td width="10%" class="list"></td>
- </tr>
- <?php $i = 0; foreach ($a_snat as $natent): ?>
- <tr>
- <td class="listlr" ondblclick="document.location='firewall_nat_server_edit.php?id=<?=$i;?>';">
- <?=$natent['ipaddr'];?>
- </td>
- <td class="listbg" ondblclick="document.location='firewall_nat_server_edit.php?id=<?=$i;?>';">
- <?=htmlspecialchars($natent['descr']);?>&nbsp;
- </td>
- <td class="list" nowrap>
- <table border="0" cellspacing="0" cellpadding="1">
- <tr>
- <td valign="middle"><a href="firewall_nat_server_edit.php?id=<?=$i;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td>
- <td valign="middle"><a href="firewall_nat_server.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td>
- </tr>
- </table>
- </td>
- </tr>
- <?php $i++; endforeach; ?>
- <tr>
- <td class="list" colspan="2"></td>
- <td class="list">
- <table border="0" cellspacing="0" cellpadding="1">
- <tr>
- <td valign="middle"><a href="firewall_nat_server_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td>
- </tr>
- </table>
- </td>
- </tr>
- <tr>
- <td colspan="2">
- <p><span class="vexpl"><span class="red"><strong>Note:<br>
- </strong></span>The external IP addresses defined on this page may be used in <a href="firewall_nat.php">inbound NAT</a> mappings. Depending on the way your WAN connection is setup, you may also need a <a href="services_virtual_ip.php">Virtual IP</a>.</span></p>
- </td>
- </tr>
- </table>
- </div>
- </table>
- </form>
-<?php include("fend.inc"); ?>
-</body>
-</html>
diff --git a/usr/local/www/firewall_nat_server_edit.php b/usr/local/www/firewall_nat_server_edit.php
deleted file mode 100755
index 7cee424..0000000
--- a/usr/local/www/firewall_nat_server_edit.php
+++ /dev/null
@@ -1,159 +0,0 @@
-<?php
-/* $Id$ */
-/*
- firewall_nat_server_edit.php
- Copyright (C) 2004, 2005 Scott Ullrich
- All rights reserved.
-
- Originally part of m0n0wall (http://m0n0.ch/wall)
- Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-*/
-
-##|+PRIV
-##|*IDENT=page-firewall-nat-nataddresses-edit
-##|*NAME=Firewall: NAT: NAT Addresses: Edit page
-##|*DESCR=Allow access to the 'Firewall: NAT: NAT Addresses: Edit' page.
-##|*MATCH=firewall_nat_server_edit.php*
-##|-PRIV
-
-
-require("guiconfig.inc");
-
-if (!is_array($config['nat']['servernat'])) {
- $config['nat']['servernat'] = array();
-}
-nat_server_rules_sort();
-$a_snat = &$config['nat']['servernat'];
-
-$id = $_GET['id'];
-if (isset($_POST['id']))
- $id = $_POST['id'];
-
-if (isset($id) && $a_snat[$id]) {
- $pconfig['ipaddr'] = $a_snat[$id]['ipaddr'];
- $pconfig['descr'] = $a_snat[$id]['descr'];
-}
-
-if ($_POST) {
-
- unset($input_errors);
- $pconfig = $_POST;
-
- /* input validation */
- $reqdfields = explode(" ", "ipaddr");
- $reqdfieldsn = explode(",", "External IP address");
-
- do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
-
- if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
- $input_errors[] = "A valid external IP address must be specified.";
- }
-
- if ($_POST['ipaddr'] == get_interface_ip("wan"))
- $input_errors[] = "The WAN IP address may not be used in a NAT Address entry.";
-
- /* check for overlaps with other server NAT */
- foreach ($a_snat as $natent) {
- if (isset($id) && ($a_snat[$id]) && ($a_snat[$id] === $natent))
- continue;
-
- if ($_POST['ipaddr'] == $natent['ipaddr']) {
- $input_errors[] = "There is already a server NAT entry for the specified external IP address.";
- break;
- }
- }
-
- /* check for overlaps with 1:1 NAT */
- if (is_array($config['nat']['onetoone'])) {
- foreach ($config['nat']['onetoone'] as $natent) {
- if (check_subnets_overlap($_POST['ipaddr'], 32, $natent['external'], $natent['subnet'])) {
- $input_errors[] = "A 1:1 NAT mapping overlaps with the specified external IP address.";
- break;
- }
- }
- }
-
- if (!$input_errors) {
- $natent = array();
- $natent['ipaddr'] = $_POST['ipaddr'];
- $natent['descr'] = $_POST['descr'];
-
- if (isset($id) && $a_snat[$id]) {
- /* modify all inbound NAT rules with this address */
- for ($i = 0; isset($config['nat']['rule'][$i]); $i++) {
- if ($config['nat']['rule'][$i]['external-address'] == $a_snat[$id]['ipaddr'])
- $config['nat']['rule'][$i]['external-address'] = $natent['ipaddr'];
- }
- $a_snat[$id] = $natent;
- } else
- $a_snat[] = $natent;
-
- touch($d_natconfdirty_path);
-
- write_config();
-
- header("Location: firewall_nat_server.php");
- exit;
- }
-}
-
-$pgtitle = array("Firewall","NAT","NAT Addresses","Edit");
-include("head.inc");
-
-?>
-
-<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
-<?php include("fbegin.inc"); ?>
-<?php if ($input_errors) print_input_errors($input_errors); ?>
- <form action="firewall_nat_server_edit.php" method="post" name="iform" id="iform">
- <table width="100%" border="0" cellpadding="6" cellspacing="0">
- <tr>
- <td width="22%" valign="top" class="vncellreq">External IP address</td>
- <td width="78%" class="vtable">
- <input name="ipaddr" type="text" class="formfld unknown" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>">
-
- </td>
- </tr>
- <tr>
- <td width="22%" valign="top" class="vncell">Description</td>
- <td width="78%" class="vtable">
- <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
- <br> <span class="vexpl">You may enter a description here
- for your reference (not parsed).</span></td>
- </tr>
- <tr>
- <td width="22%" valign="top">&nbsp;</td>
- <td width="78%">
- <input name="Submit" type="submit" class="formbtn" value="Save"> <input type="button" class="formbtn" value="Cancel" onclick="history.back()">
- <?php if (isset($id) && $a_snat[$id]): ?>
- <input name="id" type="hidden" value="<?=$id;?>">
- <?php endif; ?>
- </td>
- </tr>
- </table>
-</form>
-<?php include("fend.inc"); ?>
-</body>
-</html>
diff --git a/usr/local/www/firewall_rules.php b/usr/local/www/firewall_rules.php
index d4b7312..a6f5b38 100755
--- a/usr/local/www/firewall_rules.php
+++ b/usr/local/www/firewall_rules.php
@@ -42,6 +42,25 @@
$pgtitle = array("Firewall", "Rules");
require("guiconfig.inc");
+function check_for_advaned_options(&$item) {
+ $item_set = "";
+ if($item['max-src-nodes'])
+ $item_set .= "max-src-nodes {$item['max-src-nodes']} ";
+ if($item['max-src-states'])
+ $item_set .= "max-src-states {$item['max-src-states']} ";
+ if($item['statetype'] != "keep state" && $item['statetype'] != "")
+ $item_set .= "statetype {$item['statetype']} {$item['statetype']}";
+ if($item['statetimeout'])
+ $item_set .= "statetimeout {$item['statetimeout']}";
+ if($item['nosync'])
+ $item_set .= "nosync ";
+ if($item['max-src-conn-rate'])
+ $item_set .= "max-src-conn-rate {$item['max-src-conn-rate']} ";
+ if($item['max-src-conn-rates'])
+ $item_set .= "max-src-conn-rates {$item['max-src-conn-rates']} ";
+ return $item_set;
+}
+
if (!is_array($config['filter']['rule'])) {
$config['filter']['rule'] = array();
}
@@ -100,8 +119,7 @@ if ($_POST) {
$retval = 0;
$retval = filter_configure();
- if (file_exists($d_filterconfdirty_path))
- unlink($d_filterconfdirty_path);
+ clear_subsystem_dirty('filter');
$savemsg = "The settings have been applied. The firewall rules are now reloading in the background. You can also <a href='status_filter_reload.php'>monitor</a> the reload progress.";
}
@@ -111,7 +129,7 @@ if ($_GET['act'] == "del") {
if ($a_filter[$_GET['id']]) {
unset($a_filter[$_GET['id']]);
write_config();
- touch($d_filterconfdirty_path);
+ mark_subsystem_dirty('filter');
header("Location: firewall_rules.php?if={$if}");
exit;
}
@@ -124,7 +142,7 @@ if (isset($_POST['del_x'])) {
unset($a_filter[$rulei]);
}
write_config();
- touch($d_filterconfdirty_path);
+ mark_subsystem_dirty('filter');
header("Location: firewall_rules.php?if={$if}");
exit;
}
@@ -135,7 +153,7 @@ if (isset($_POST['del_x'])) {
else
$a_filter[$_GET['id']]['disabled'] = true;
write_config();
- touch($d_filterconfdirty_path);
+ mark_subsystem_dirty('filter');
header("Location: firewall_rules.php?if={$if}");
exit;
}
@@ -179,7 +197,7 @@ if (isset($_POST['del_x'])) {
$a_filter = $a_filter_new;
write_config();
- touch($d_filterconfdirty_path);
+ mark_subsystem_dirty('filter');
header("Location: firewall_rules.php?if={$if}");
exit;
}
@@ -201,7 +219,7 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
<script type="text/javascript" language="javascript" src="/javascript/row_toggle.js">
</script>
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_filterconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('filter')): ?><p>
<?php print_info_box_np("The firewall rule configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
@@ -231,15 +249,16 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
<tr id="frheader">
<td width="3%" class="list">&nbsp;</td>
<td width="5%" class="list">&nbsp;</td>
+ <td width="3%" class="listhdrr">ID</td>
<td width="6%" class="listhdrr">Proto</td>
- <td width="15%" class="listhdrr">Source</td>
+ <td width="14%" class="listhdrr">Source</td>
<td width="7%" class="listhdrr">Port</td>
- <td width="15%" class="listhdrr">Destination</td>
+ <td width="14%" class="listhdrr">Destination</td>
<td width="7%" class="listhdrr">Port</td>
<td width="5%" class="listhdrr">Gateway</td>
<td width="10%" class="listhdrr">Queue</td>
<td width="5%" class="listhdrr">Schedule</td>
- <td width="22%" class="listhdr">Description</td>
+ <td width="21%" class="listhdr">Description</td>
<td width="10%" class="list">
<table border="0" cellspacing="0" cellpadding="1">
<tr>
@@ -248,8 +267,8 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
for ($i = 0; isset($a_filter[$i]); $i++) {
$filterent = $a_filter[$i];
if ($filterent['interface'] != $if && !isset($filterent['floating']))
- continue;
- if (isset($filterent['floating']) && "FloatingRules" != $if)
+ continue;
+ if (isset($filterent['floating']) && "FloatingRules" != $if)
continue;
$nrules++;
}
@@ -268,7 +287,8 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
<tr valign="top" id="frrfc1918">
<td width="3%" class="list">&nbsp;</td>
<td class="listt" align="center"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_block.gif" width="11" height="11" border="0"></td>
- <td class="listlr" style="background-color: #e0e0e0">*</td>
+ <td class="listlr" style="background-color: #e0e0e0"></td>
+ <td class="listr" style="background-color: #e0e0e0">*</td>
<td class="listr" style="background-color: #e0e0e0">RFC 1918 networks</td>
<td class="listr" style="background-color: #e0e0e0">*</td>
<td class="listr" style="background-color: #e0e0e0">*</td>
@@ -295,7 +315,8 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
<tr valign="top" id="frrfc1918">
<td width="3%" class="list">&nbsp;</td>
<td class="listt" align="center"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_block.gif" width="11" height="11" border="0"></td>
- <td class="listlr" style="background-color: #e0e0e0">*</td>
+ <td class="listlr" style="background-color: #e0e0e0"></td>
+ <td class="listr" style="background-color: #e0e0e0">*</td>
<td class="listr" style="background-color: #e0e0e0">Reserved/not assigned by IANA</td>
<td class="listr" style="background-color: #e0e0e0">*</td>
<td class="listr" style="background-color: #e0e0e0">*</td>
@@ -321,12 +342,20 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
<?php $nrules = 0; for ($i = 0; isset($a_filter[$i]); $i++):
$filterent = $a_filter[$i];
if ($filterent['interface'] != $if && !isset($filterent['floating']))
- continue;
- if (isset($filterent['floating']) && "FloatingRules" != $if)
- continue;
+ continue;
+ if (isset($filterent['floating']) && "FloatingRules" != $if)
+ continue;
+ $isadvset = check_for_advaned_options($filterent);
+ if($isadvset)
+ $advanced_set = "<img src=\"./themes/{$g['theme']}/images/icons/icon_advanced.gif\" title=\"advanced settings set: $isadvset\" border=\"0\">";
+ else
+ $advanced_set = ""
?>
<tr valign="top" id="fr<?=$nrules;?>">
- <td class="listt"><input type="checkbox" id="frc<?=$nrules;?>" name="rule[]" value="<?=$i;?>" onClick="fr_bgcolor('<?=$nrules;?>')" style="margin: 0; padding: 0; width: 15px; height: 15px;"></td>
+ <td class="listt">
+ <input type="checkbox" id="frc<?=$nrules;?>" name="rule[]" value="<?=$i;?>" onClick="fr_bgcolor('<?=$nrules;?>')" style="margin: 0; padding: 0; width: 15px; height: 15px;">
+ <?php echo $advanced_set; ?>
+ </td>
<td class="listt" align="center">
<?php if ($filterent['type'] == "block")
$iconfn = "block";
@@ -519,6 +548,9 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
}
?>
<td class="listlr" onClick="fr_toggle(<?=$nrules;?>)" id="frd<?=$nrules;?>" ondblclick="document.location='firewall_rules_edit.php?id=<?=$i;?>';">
+ <?=$textss;?><?php if (isset($filterent['id'])) echo $filterent['id']; else echo ""; ?><?=$textse;?>
+ </td>
+ <td class="listr" onClick="fr_toggle(<?=$nrules;?>)" id="frd<?=$nrules;?>" ondblclick="document.location='firewall_rules_edit.php?id=<?=$i;?>';">
<?=$textss;?><?php if (isset($filterent['protocol'])) echo strtoupper($filterent['protocol']); else echo "*"; ?><?=$textse;?>
</td>
<td class="listr" onClick="fr_toggle(<?=$nrules;?>)" id="frd<?=$nrules;?>" ondblclick="document.location='firewall_rules_edit.php?id=<?=$i;?>';">
@@ -585,6 +617,7 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
<td class="list">&nbsp;</td>
<td class="list">&nbsp;</td>
<td class="list">&nbsp;</td>
+ <td class="list">&nbsp;</td>
<td class="list">&nbsp;</td>
<td class="list">&nbsp;</td>
<td class="list">&nbsp;</td>
diff --git a/usr/local/www/firewall_rules_edit.php b/usr/local/www/firewall_rules_edit.php
index 5e3f20e..d9bc01b 100755
--- a/usr/local/www/firewall_rules_edit.php
+++ b/usr/local/www/firewall_rules_edit.php
@@ -41,7 +41,12 @@
require("guiconfig.inc");
-$specialsrcdst = explode(" ", "any wanip lanip lan pptp pppoe");
+$specialsrcdst = explode(" ", "any pptp pppoe l2tp");
+$ifdisp = get_configured_interface_with_descr();
+foreach ($ifdisp as $kif => $kdescr) {
+ $specialsrcdst[] = "{$kif}";
+ $specialsrcdst[] = "{$kif}ip";
+}
if (!is_array($config['filter']['rule'])) {
$config['filter']['rule'] = array();
@@ -66,6 +71,9 @@ if (isset($_GET['dup'])) {
if (isset($id) && $a_filter[$id]) {
$pconfig['interface'] = $a_filter[$id]['interface'];
+ if (isset($a_filter[$id]['id']))
+ $pconfig['ruleid'] = $a_filter[$id]['id'];
+
if (!isset($a_filter[$id]['type']))
$pconfig['type'] = "pass";
else
@@ -111,7 +119,7 @@ if (isset($id) && $a_filter[$id]) {
if (isset($a_filter[$id]['tag']) && $a_filter[$id]['tag'] <> "")
$pconfig['tag'] = $a_filter[$id]['tag'];
- if (isset($a_filter[$id]['tagged']) && $a_filter[$id]['tag'] <> "")
+ if (isset($a_filter[$id]['tagged']) && $a_filter[$id]['tagged'] <> "")
$pconfig['tagged'] = $a_filter[$id]['tagged'];
if (isset($a_filter[$id]['quick']) && $a_filter[$id]['quick'])
$pconfig['quick'] = $a_filter[$id]['quick'];
@@ -119,11 +127,12 @@ if (isset($id) && $a_filter[$id]) {
$pconfig['allowopts'] = true;
/* advanced */
- $pconfig['max-src-nodes'] = $a_filter[$id]['max-src-nodes'];
- $pconfig['max-src-states'] = $a_filter[$id]['max-src-states'];
- $pconfig['statetype'] = $a_filter[$id]['statetype'];
+ $pconfig['max-src-nodes'] = $a_filter[$id]['max-src-nodes'];
+ $pconfig['max-src-states'] = $a_filter[$id]['max-src-states'];
+ $pconfig['statetype'] = $a_filter[$id]['statetype'];
$pconfig['statetimeout'] = $a_filter[$id]['statetimeout'];
+ /* advanced - nosync */
$pconfig['nosync'] = isset($a_filter[$id]['nosync']);
/* advanced - new connection per second banning*/
@@ -331,13 +340,18 @@ if ($_POST) {
else if ($dnpipe[0] == "?" && $pdnpipe[0] <> "?")
$input_errors[] = "You cannot select one queue and one virtual interface for IN and Out. both must be from the same type.";
}
+ if( !empty($_POST['ruleid']) && !ctype_digit($_POST['ruleid']))
+ $input_errors[] = 'ID must be an integer';
if($_POST['l7container'] && $_POST['l7container'] != "none") {
if(!($_POST['proto'] == "tcp" || $_POST['proto'] == "udp" || $_POST['proto'] == "tcp/udp"))
$input_errors[] = "You can only select a layer7 container for tcp and/or udp protocols";
+ if ($_POST['type'] <> "pass")
+ $input_errors[] = "You can only select a layer7 container for Pass type rules.";
}
if (!$input_errors) {
$filterent = array();
+ $filterent['id'] = $_POST['ruleid']>0?$_POST['ruleid']:'';
$filterent['type'] = $_POST['type'];
if (isset($_POST['interface'] ))
$filterent['interface'] = $_POST['interface'];
@@ -448,7 +462,7 @@ if ($_POST) {
}
write_config();
- touch($d_filterconfdirty_path);
+ mark_subsystem_dirty('filter');
if (isset($_POST['floating']))
header("Location: firewall_rules.php?if=FloatingRules");
@@ -485,6 +499,12 @@ include("head.inc");
<td colspan="2" valign="top" class="listtopic">Edit Firewall rule</td>
</tr>
<tr>
+ <td width="22%" valign="top" class="vncell">ID</td>
+ <td width="78%" class="vtable">
+ <input name="ruleid" value="<?=(isset($pconfig['ruleid'])&&$pconfig['ruleid']>0)?htmlspecialchars($pconfig['ruleid']):''?>">
+ </td>
+ </tr>
+ <tr>
<td width="22%" valign="top" class="vncellreq">Action</td>
<td width="78%" class="vtable">
<select name="type" class="formselect">
@@ -653,23 +673,16 @@ include("head.inc");
<option value="any" <?php if ($pconfig['src'] == "any") { echo "selected"; } ?>>any</option>
<option value="single" <?php if (($pconfig['srcmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>>Single host or alias</option>
<option value="network" <?php if (!$sel) echo "selected"; ?>>Network</option>
- <?php if(have_ruleint_access("wan")): ?>
- <option value="wanip" <?php if ($pconfig['src'] == "wanip") { echo "selected"; } ?>>WAN address</option>
- <?php endif; ?>
- <?php if(have_ruleint_access("lan")): ?>
- <option value="lanip" <?php if ($pconfig['src'] == "lanip") { echo "selected"; } ?>>LAN address</option>
- <?php endif; ?>
- <?php if(have_ruleint_access("lan")): ?>
- <option value="lan" <?php if ($pconfig['src'] == "lan") { echo "selected"; } ?>>LAN subnet</option>
- <?php endif; ?>
<?php if(have_ruleint_access("pptp")): ?>
<option value="pptp" <?php if ($pconfig['src'] == "pptp") { echo "selected"; } ?>>PPTP clients</option>
<?php endif; ?>
<?php if(have_ruleint_access("pppoe")): ?>
<option value="pppoe" <?php if ($pconfig['src'] == "pppoe") { echo "selected"; } ?>>PPPoE clients</option>
<?php endif; ?>
+ <?php if(have_ruleint_access("l2tp")): ?>
+ <option value="l2tp" <?php if ($pconfig['src'] == "l2tp") { echo "selected"; } ?>>L2TP clients</option>
+ <?php endif; ?>
<?php
- $ifdisp = get_configured_interface_with_descr();
foreach ($ifdisp as $ifent => $ifdesc): ?>
<?php if(have_ruleint_access($ifent)): ?>
<option value="<?=$ifent;?>" <?php if ($pconfig['src'] == $ifent) { echo "selected"; } ?>><?=htmlspecialchars($ifdesc);?> subnet</option>
@@ -781,22 +794,15 @@ include("head.inc");
<option value="any" <?php if ($pconfig['dst'] == "any") { echo "selected"; } ?>>any</option>
<option value="single" <?php if (($pconfig['dstmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>>Single host or alias</option>
<option value="network" <?php if (!$sel) echo "selected"; ?>>Network</option>
- <?php if(have_ruleint_access("wan")): ?>
- <option value="wanip" <?php if ($pconfig['dst'] == "wanip") { echo "selected"; } ?>>WAN address</option>
- <?php endif; ?>
- <?php if(have_ruleint_access("lan")): ?>
- <option value="lanip" <?php if ($pconfig['dst'] == "lanip") { echo "selected"; } ?>>LAN address</option>
- <?php endif; ?>
- <?php if(have_ruleint_access("lan")): ?>
- <option value="lan" <?php if ($pconfig['dst'] == "lan") { echo "selected"; } ?>>LAN subnet</option>
- <?php endif; ?>
<?php if(have_ruleint_access("pptp")): ?>
<option value="pptp" <?php if ($pconfig['dst'] == "pptp") { echo "selected"; } ?>>PPTP clients</option>
<?php endif; ?>
<?php if(have_ruleint_access("pppoe")): ?>
<option value="pppoe" <?php if ($pconfig['dst'] == "pppoe") { echo "selected"; } ?>>PPPoE clients</option>
<?php endif; ?>
-
+ <?php if(have_ruleint_access("l2tp")): ?>
+ <option value="l2tp" <?php if ($pconfig['dst'] == "l2tp") { echo "selected"; } ?>>L2TP clients</option>
+ <?php endif; ?>
<?php foreach ($ifdisp as $if => $ifdesc): ?>
<?php if(have_ruleint_access($if)): ?>
diff --git a/usr/local/www/firewall_schedule.php b/usr/local/www/firewall_schedule.php
index a5eaf23..46bef20 100644
--- a/usr/local/www/firewall_schedule.php
+++ b/usr/local/www/firewall_schedule.php
@@ -49,7 +49,6 @@ require("guiconfig.inc");
if (!is_array($config['schedules']['schedule']))
$config['schedules']['schedule'] = array();
-schedule_sort();
$a_schedules = &$config['schedules']['schedule'];
@@ -89,7 +88,7 @@ include("head.inc");
<?php include("fbegin.inc"); ?>
<?php if ($savemsg) print_info_box($savemsg); ?>
<form action="firewall_schedule.php" method="post">
- <table class="sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="25%" class="listhdrr">Name</td>
<td width="35%" class="listhdrr">Time Range(s)</td>
diff --git a/usr/local/www/firewall_schedule_edit.php b/usr/local/www/firewall_schedule_edit.php
index fc30c18..6e628ec 100644
--- a/usr/local/www/firewall_schedule_edit.php
+++ b/usr/local/www/firewall_schedule_edit.php
@@ -37,6 +37,18 @@
##|*MATCH=firewall_schedule_edit.php*
##|-PRIV
+function schedulecmp($a, $b) {
+ return strcmp($a['name'], $b['name']);
+}
+
+function schedule_sort(){
+ global $g, $config;
+
+ if (!is_array($config['schedules']['schedule']))
+ return;
+
+ usort($config['schedules']['schedule'], "schedulecmp");
+}
$pgtitle = array("Firewall","Schedules","Edit");
require("guiconfig.inc");
@@ -158,6 +170,7 @@ if ($_POST) {
else
$schedule['schedlabel'] = uniqid();
+ schedule_sort();
if (isset($id) && $a_schedules[$id]){
$a_schedules[$id] = $schedule;
}
diff --git a/usr/local/www/firewall_shaper.php b/usr/local/www/firewall_shaper.php
index 55ec0f9..ded8724 100755
--- a/usr/local/www/firewall_shaper.php
+++ b/usr/local/www/firewall_shaper.php
@@ -86,7 +86,7 @@ if ($_GET) {
if ($queue) {
$queue->delete_queue();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
}
header("Location: firewall_shaper.php");
exit;
@@ -170,7 +170,7 @@ if ($_GET) {
$queue->SetEnabled("on");
$output_form .= $queue->build_form();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
} else
$input_errors[] = "Queue not found!";
break;
@@ -179,7 +179,7 @@ if ($_GET) {
$queue->SetEnabled("");
$output_form .= $queue->build_form();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
} else
$input_errors[] = "Queue not found!";
break;
@@ -222,7 +222,7 @@ if ($_GET) {
$altq->SetLink(&$tmppath);
$altq->wconfig();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
$can_enable = true;
$can_add = true;
}
@@ -247,7 +247,7 @@ if ($_GET) {
} else
$can_add = false;
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
$can_enable = true;
if ($altq->GetScheduler() != "PRIQ") /* XXX */
if ($tmp->GetDefault() <> "")
@@ -276,7 +276,7 @@ if ($_GET) {
system("rm -f /var/db/rrd/*queues.rrd");
enable_rrd_graphing();
- unlink($d_shaperconfdirty_path);
+ clear_subsystem_dirty('shaper');
if ($queue) {
$output_form .= $queue->build_form();
@@ -293,7 +293,7 @@ if ($_GET) {
$queue->update_altq_queue_data($_POST);
$queue->wconfig();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
$dontshow = false;
}
read_altq_config();
@@ -408,7 +408,7 @@ include("fbegin.inc");
<form action="firewall_shaper.php" method="post" id="iform" name="iform">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_shaperconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('shaper')): ?><p>
<?php print_info_box_np("The traffic shaper configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/firewall_shaper_layer7.php b/usr/local/www/firewall_shaper_layer7.php
index 2dd5acc..773458c 100755
--- a/usr/local/www/firewall_shaper_layer7.php
+++ b/usr/local/www/firewall_shaper_layer7.php
@@ -141,8 +141,8 @@ else if ($_POST) {
if(sizeof($dupes) == 0 && !$input_errors) {
$l7r->wconfig();
write_config();
- touch($d_shaperconfdirty_path);
-
+ mark_subsystem_dirty('shaper');
+
read_layer7_config();
}
else {
@@ -174,8 +174,8 @@ else if ($_POST) {
else
$savemsg = $retval;
- unlink($d_shaperconfdirty_path);
-
+ clear_subsystem_dirty('shaper');
+
if($container) {
$output_form .= $container->build_form();
} else {
@@ -185,7 +185,7 @@ else if ($_POST) {
} else if ($_POST['delete']) {
$container->delete_l7c();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
unset($container);
header("Location: firewall_shaper_layer7.php");
@@ -386,7 +386,7 @@ include("fbegin.inc");
<form action="firewall_shaper_layer7.php" method="post" id="iform" name="iform">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_shaperconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('shaper')): ?><p>
<?php print_info_box_np("The traffic shaper configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/firewall_shaper_queues.php b/usr/local/www/firewall_shaper_queues.php
index 3495fdf..dc62a29 100755
--- a/usr/local/www/firewall_shaper_queues.php
+++ b/usr/local/www/firewall_shaper_queues.php
@@ -75,7 +75,7 @@ if ($_GET) {
if ($qtmp) {
$qtmp->delete_queue();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
}
header("Location: firewall_shaper_queues.php");
exit;
@@ -113,7 +113,7 @@ if ($_GET) {
$config['shaper']['queue'][] = $newroot;
}
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
break;
}
}
@@ -159,7 +159,7 @@ if ($_POST['apply']) {
system("rm -f /var/db/rrd/*queues.rrd");
enable_rrd_graphing();
- unlink($d_shaperconfdirty_path);
+ clear_subsystem_dirty('shaper');
}
$pgtitle = "Firewall: Shaper: By Queues View";
@@ -175,7 +175,7 @@ include("head.inc");
<?php if ($input_errors) print_input_errors($input_errors); ?>
<form action="firewall_shaper_queues.php" method="post" name="iform" id="iform">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_shaperconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('shaper')): ?><p>
<?php print_info_box_np("The traffic shaper configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/firewall_shaper_vinterface.php b/usr/local/www/firewall_shaper_vinterface.php
index 7415447..e1370d8 100644
--- a/usr/local/www/firewall_shaper_vinterface.php
+++ b/usr/local/www/firewall_shaper_vinterface.php
@@ -1,7 +1,7 @@
<?php
/* $Id$ */
/*
- firewall_shaper.php
+ firewall_shaper_vinterface.php
Copyright (C) 2004, 2005 Scott Ullrich
Copyright (C) 2008 Ermal Luçi
All rights reserved.
@@ -87,7 +87,7 @@ if ($_GET) {
if ($queue) {
$queue->delete_queue();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
}
header("Location: firewall_shaper_vinterface.php");
exit;
@@ -152,7 +152,7 @@ if ($_GET) {
$queue->SetEnabled("on");
$output_form .= $queue->build_form();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
} else
$input_errors[] = "Queue not found!";
break;
@@ -161,7 +161,7 @@ if ($_GET) {
$queue->SetEnabled("");
$output_form .= $queue->build_form();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
} else
$input_errors[] = "Queue not found!";
break;
@@ -184,7 +184,7 @@ if ($_GET) {
$dnpipe->SetLink(&$tmppath);
$dnpipe->wconfig();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
$can_enable = true;
$can_add = true;
}
@@ -202,7 +202,7 @@ if ($_GET) {
write_config();
$can_enable = true;
$can_add = false;
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
$can_enable = true;
}
read_dummynet_config();
@@ -224,7 +224,7 @@ if ($_GET) {
/* XXX: TODO Make dummynet pretty graphs */
// enable_rrd_graphing();
- unlink($d_shaperconfdirty_path);
+ clear_subsystem_dirty('shaper');
if ($queue) {
$output_form .= $queue->build_form();
@@ -241,7 +241,7 @@ if ($_GET) {
$queue->update_dn_data($_POST);
$queue->wconfig();
write_config();
- touch($d_shaperconfdirty_path);
+ mark_subsystem_dirty('shaper');
$dontshow = false;
}
read_dummynet_config();
@@ -351,7 +351,7 @@ include("fbegin.inc");
<form action="firewall_shaper_vinterface.php" method="post" id="iform" name="iform">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_shaperconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('shaper')): ?><p>
<?php print_info_box_np("The traffic shaper configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/firewall_shaper_wizards.php b/usr/local/www/firewall_shaper_wizards.php
index fb8e9af..e1a5532 100755
--- a/usr/local/www/firewall_shaper_wizards.php
+++ b/usr/local/www/firewall_shaper_wizards.php
@@ -1,7 +1,7 @@
<?php
/* $Id$ */
/*
- firewall_shaper.php
+ firewall_shaper_wizards.php
Copyright (C) 2004, 2005 Scott Ullrich
Copyright (C) 2008 Ermal Luçi
All rights reserved.
@@ -60,7 +60,7 @@ if ($_POST['apply']) {
system("rm -f /var/db/rrd/*queues.rrd");
enable_rrd_graphing();
- unlink($d_shaperconfdirty_path);
+ clear_subsystem_dirty('shaper');
}
$pgtitle = array("Firewall", "Traffic Shaper", "Wizards");
@@ -84,7 +84,7 @@ include("fbegin.inc");
<form action="firewall_shaper_wizards.php" method="post" id="iform" name="iform">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_shaperconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('shaper')): ?><p>
<?php print_info_box_np("The traffic shaper configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/firewall_virtual_ip.php b/usr/local/www/firewall_virtual_ip.php
index d24f234..2f51a7d 100755
--- a/usr/local/www/firewall_virtual_ip.php
+++ b/usr/local/www/firewall_virtual_ip.php
@@ -67,7 +67,7 @@ if ($_POST) {
interfaces_carp_configure();
$savemsg = get_std_save_message($retval);
- unlink_if_exists($d_vipconfdirty_path);
+ clear_subsystem_dirty('vip');
}
}
@@ -90,7 +90,7 @@ if ($_GET['act'] == "del") {
mwexec("/sbin/ifconfig " . get_real_interface($a_vip[$_GET['id']]['interface']) . " delete {$a_vip[$_GET['id']]['subnet']}");
unset($a_vip[$_GET['id']]);
write_config();
- touch($d_vipconfdirty_path);
+ mark_subsystem_dirty('vip');
header("Location: firewall_virtual_ip.php");
exit;
}
@@ -111,7 +111,7 @@ include("head.inc");
if ($savemsg)
print_info_box($savemsg);
else
- if (file_exists($d_vipconfdirty_path))
+ if (is_subsystem_dirty('vip'))
print_info_box_np("The VIP configuration has been changed.<br>You must apply the changes in order for them to take effect.");
?>
<br>
diff --git a/usr/local/www/firewall_virtual_ip_edit.php b/usr/local/www/firewall_virtual_ip_edit.php
index 2aca9be..1b83863 100755
--- a/usr/local/www/firewall_virtual_ip_edit.php
+++ b/usr/local/www/firewall_virtual_ip_edit.php
@@ -205,7 +205,7 @@ if ($_POST) {
} else
$a_vip[] = $vipent;
- touch($d_vipconfdirty_path);
+ mark_subsystem_dirty('vip');
write_config();
diff --git a/usr/local/www/guiconfig.inc b/usr/local/www/guiconfig.inc
index 7cafe2f..ebb1e35 100755
--- a/usr/local/www/guiconfig.inc
+++ b/usr/local/www/guiconfig.inc
@@ -44,7 +44,6 @@ if (!$omit_nocacheheaders) {
}
/* parse the configuration and include all configuration functions */
-require_once("config.inc");
require_once("functions.inc");
/* Pull in all the gui related display classes) */
@@ -55,7 +54,7 @@ foreach (scandir("/usr/local/www/classes/") as $file) {
}
/*
* if user has selected a custom template, use it.
- * otherwise default to pfsense tempalte
+ * otherwise default to pfsense template
*/
if($config['theme'] <> "")
$g['theme'] = $config['theme'];
@@ -71,34 +70,6 @@ foreach($apple_ua as $useragent)
if(strstr($_SERVER['HTTP_USER_AGENT'], $useragent))
$g['theme'] = "pfsense";
-$d_landirty_path = $g['varrun_path'] . "/lan.conf.dirty";
-$d_pppoeuserdirty_path = $g['varrun_path'] . "/vpn-pppoe-users-edit.dirty";
-$d_hostsdirty_path = $g['varrun_path'] . "/hosts.dirty";
-$d_natconfdirty_path = $g['varrun_path'] . "/nat.conf.dirty";
-$d_filterconfdirty_path = $g['varrun_path'] . "/filter.conf.dirty";
-$d_ipsecconfdirty_path = $g['varrun_path'] . "/ipsec.conf.dirty";
-$d_shaperconfdirty_path = $g['varrun_path'] . "/shaper.conf.dirty";
-$d_pptpuserdirty_path = $g['varrun_path'] . "/pptpd.user.dirty";
-$d_dnsmasqdirty_path = $g['varrun_path'] . "/dnsmasq.dirty";
-$d_staticmapsdirty_path = $g['varrun_path'] . "/staticmaps.dirty";
-$d_staticroutesdirty_path = $g['varrun_path'] . "/staticroutes.dirty";
-$d_aliasesdirty_path = $g['varrun_path'] . "/aliases.dirty";
-$d_proxyarpdirty_path = $g['varrun_path'] . "/proxyarp.dirty";
-$d_fwupenabled_path = $g['varrun_path'] . "/fwup.enabled";
-$d_firmwarelock_path = $g['varrun_path'] . "/firmware.lock";
-$d_sysrebootreqd_path = $g['varrun_path'] . "/sysreboot.reqd";
-$d_passthrumacsdirty_path = $g['varrun_path'] . "/passthrumacs.dirty";
-$d_allowedipsdirty_path = $g['varrun_path'] . "/allowedips.dirty";
-$d_ovpnclidirty_path = $g['varrun_path'] . "/ovpnclient.dirty";
-$d_vipconfdirty_path = $g['varrun_path'] . "/vip.conf.dirty";
-$d_sysctldirty_path = $g['varrun_path'] . "/sysctl.conf.dirty";
-$d_vsconfdirty_path = $g['varrun_path'] . "/vs.conf.dirty";
-$d_shaperconfdirty_path = $g['varrun_path'] . "/shaper.conf.dirty";
-
-/* OpenVPN Directories */
-$d_ovpnsrvdirty_path = "/tmp/ovpn-srv.dirty";
-$d_ovpncrldirty_path = "/tmp/ovpn-crl.dirty";
-$d_ovpnclidirty_path = "/tmp/ovpn-cli.dirty";
/* used by progress bar */
$lastseen = "-1";
@@ -106,7 +77,7 @@ $navlevelsep = ": "; /* navigation level separator string */
$mandfldhtml = ""; /* display this before mandatory input fields */
$mandfldhtmlspc = ""; /* same as above, but with spacing */
-if (file_exists($d_firmwarelock_path)) {
+if (is_subsystem_dirty('firmwarelock')) {
if (!$d_isfwfile) {
header("Location: system_firmware.php");
exit;
@@ -208,7 +179,7 @@ $wkports = array(
69 => "TFTP",
5900 => "VNC");
-$specialnets = array("wanip" => "WAN address", "lanip" => "LAN address", "lan" => "LAN net", "pptp" => "PPTP clients");
+$specialnets = array("wanip" => "WAN address", "lanip" => "LAN address", "lan" => "LAN net", "pptp" => "PPTP clients", "pppoe" => "PPPoE client", "l2tp" => "L2TP clients");
$spiflist = get_configured_interface_with_descr(true, true);
foreach ($spiflist as $ifgui => $ifdesc) {
@@ -220,7 +191,7 @@ $medias = array("auto" => "autoselect", "100full" => "100BASE-TX full-duplex",
"10half" => "10BASE-T half-duplex");
/* platforms that support firmware updating */
-$fwupplatforms = array('pfSense', 'net45xx', 'net48xx', 'generic-pc', 'embedded', 'wrap');
+$fwupplatforms = array('pfSense', 'net45xx', 'net48xx', 'generic-pc', 'embedded', 'wrap', 'nanobsd');
function do_input_validation($postdata, $reqdfields, $reqdfieldsn, $input_errors) {
@@ -267,26 +238,6 @@ EOF2;
}
-function exec_rc_script($scriptname) {
-
- global $d_sysrebootreqd_path;
-
- $execoutput = "";
- $retval = "";
- exec($scriptname . " >/dev/null 2>&1", $execoutput, $retval);
- return $retval;
-}
-
-function exec_rc_script_async($scriptname) {
-
- global $d_sysrebootreqd_path;
- $execoutput = "";
- $retval = "";
-
- exec("nohup " . $scriptname . " >/dev/null 2>&1 &", $execoutput, $retval);
- return $retval;
-}
-
function verify_gzip_file($fname) {
$returnvar = mwexec("/usr/bin/gzip -t " . escapeshellarg($fname));
@@ -299,7 +250,7 @@ function verify_gzip_file($fname) {
function print_info_box_np($msg, $name="apply",$value="Apply changes") {
global $g;
- if(stristr($msg, "apply") == true || stristr($msg, "save") || stristr($msg, "create")) {
+ if(stristr($msg, "apply") != false || stristr($msg, "save") != false || stristr($msg, "create") != false) {
$savebutton = "<td class='infoboxsave'>";
$savebutton .= "<input name=\"{$name}\" type=\"submit\" class=\"formbtn\" id=\"${name}\" value=\"{$value}\">";
if($_POST['if'])
@@ -405,45 +356,6 @@ function pprint_port($port) {
return $pport;
}
-function captiveportal_users_sort() {
- global $g, $config;
-
- if (!is_array($config['captiveportal']['user']))
- return;
-
- function cpusercmp($a, $b) {
- return strcasecmp($a['name'], $b['name']);
- }
-
- usort($config['captiveportal']['user'], "cpusercmp");
-}
-
-function admin_groups_sort() {
- global $g, $config;
-
- if (!is_array($config['system']['group']))
- return;
-
- function cpusercmp($a, $b) {
- return strcasecmp($a['name'], $b['name']);
- }
-
- usort($config['system']['group'], "cpusercmp");
-}
-
-function admin_users_sort() {
- global $g, $config;
-
- if (!is_array($config['system']['user']))
- return;
-
- function cpusercmp($a, $b) {
- return strcasecmp($a['name'], $b['name']);
- }
-
- usort($config['system']['user'], "cpusercmp");
-}
-
/* sort by interface only, retain the original order of rules that apply to
the same interface */
function filter_rules_sort() {
@@ -467,158 +379,6 @@ function filter_rules_sort() {
unset($config['filter']['rule'][$i]['seq']);
}
-function nat_rules_sort() {
- global $config;
-
- if (!is_array($config['nat']['rule']))
- return;
-
- function natcmp($a, $b) {
- if ($a['external-address'] == $b['external-address']) {
- if ($a['protocol'] == $b['protocol']) {
- if ($a['external-port'] == $b['external-port']) {
- return 0;
- } else {
- return ($a['external-port'] - $b['external-port']);
- }
- } else {
- return strcmp($a['protocol'], $b['protocol']);
- }
- } else if (!$a['external-address'])
- return 1;
- else if (!$b['external-address'])
- return -1;
- else
- return ipcmp($a['external-address'], $b['external-address']);
- }
-
- usort($config['nat']['rule'], "natcmp");
-}
-
-function nat_1to1_rules_sort() {
- global $g, $config;
-
- if (!is_array($config['nat']['onetoone']))
- return;
-
- function nat1to1cmp($a, $b) {
- return ipcmp($a['external'], $b['external']);
- }
-
- usort($config['nat']['onetoone'], "nat1to1cmp");
-}
-
-function nat_server_rules_sort() {
- global $g, $config;
-
- if (!is_array($config['nat']['servernat']))
- return;
-
- function natservercmp($a, $b) {
- return ipcmp($a['ipaddr'], $b['ipaddr']);
- }
-
- usort($config['nat']['servernat'], "natservercmp");
-}
-
-function nat_out_rules_sort() {
- global $g, $config;
-
- function natoutcmp($a, $b) {
- return strcmp($a['source']['network'], $b['source']['network']);
- }
-
- usort($config['nat']['advancedoutbound']['rule'], "natoutcmp");
-}
-
-function pptpd_users_sort() {
- global $g, $config;
-
- if (!is_array($config['ppptpd']['user']))
- return;
-
- function usercmp($a, $b) {
- return strcasecmp($a['name'], $b['name']);
- }
-
- usort($config['pptpd']['user'], "usercmp");
-}
-
-function l2tp_users_sort() {
- global $g, $config;
-
- if (!is_array($config['l2tp']['user']))
- return;
-
- function usercmp($a, $b) {
- return strcasecmp($a['name'], $b['name']);
- }
-
- usort($config['l2tp']['user'], "usercmp");
-}
-
-function openvpn_users_sort() {
- global $g, $config;
-
- if (!is_array($config['openvpn']['user']))
- return;
-
- function usercmp($a, $b) {
- return strcasecmp($a['name'], $b['name']);
- }
-
- usort($config['openvpn']['user'], "usercmp");
-}
-
-function pppoe_users_sort() {
- global $g, $config;
-
- if (!is_array($config['pppoe']['user']))
- return;
-
- function usercmp($a, $b) {
- return strcasecmp($a['name'], $b['name']);
- }
-
- usort($config['pppoe']['user'], "usercmp");
-}
-
-function staticroutes_sort() {
- global $g, $config;
-
- if (!is_array($config['staticroutes']['route']))
- return;
-
- function staticroutecmp($a, $b) {
- return strcmp($a['network'], $b['network']);
- }
-
- usort($config['staticroutes']['route'], "staticroutecmp");
-}
-
-function hosts_sort() {
- global $g, $config;
-
- if (!is_array($config['dnsmasq']['hosts']))
- return;
-
- function hostcmp($a, $b) {
- return strcasecmp($a['host'], $b['host']);
- }
-
- usort($config['dnsmasq']['hosts'], "hostcmp");
-}
-
-function staticmaps_sort($ifgui) {
- global $g, $config;
-
- function staticmapcmp($a, $b) {
- return ipcmp($a['ipaddr'], $b['ipaddr']);
- }
-
- usort($config['dhcpd'][$ifgui]['staticmap'], "staticmapcmp");
-}
-
function aliases_sort() {
global $g, $config;
@@ -630,95 +390,6 @@ function aliases_sort() {
usort($config['aliases']['alias'], "aliascmp");
}
-function schedule_sort(){
- global $g, $config;
-
- if (!is_array($config['schedules']['schedule']))
- return;
-
- function schedulecmp($a, $b) {
- return strcmp($a['name'], $b['name']);
- }
-
- usort($config['schedules']['schedule'], "schedulecmp");
-
-}
-
-function ipsec_mobilekey_sort() {
- global $g, $config;
-
- function mobilekeycmp($a, $b) {
- return strcmp($a['ident'][0], $b['ident'][0]);
- }
-
- usort($config['ipsec']['mobilekey'], "mobilekeycmp");
-}
-
-function proxyarp_sort() {
- global $g, $config;
-
- function proxyarpcmp($a, $b) {
- if (isset($a['network']))
- list($ast,$asn) = explode("/", $a['network']);
- else if (isset($a['range'])) {
- $ast = $a['range']['from'];
- $asn = 32;
- }
- if (isset($b['network']))
- list($bst,$bsn) = explode("/", $b['network']);
- else if (isset($b['range'])) {
- $bst = $b['range']['from'];
- $bsn = 32;
- }
- if (ipcmp($ast, $bst) == 0)
- return ($asn - $bsn);
- else
- return ipcmp($ast, $bst);
- }
-
- usort($config['proxyarp']['proxyarpnet'], "proxyarpcmp");
-}
-
-function passthrumacs_sort() {
- global $g, $config;
-
- function passthrumacscmp($a, $b) {
- return strcmp($a['mac'], $b['mac']);
- }
-
- usort($config['captiveportal']['passthrumac'],"passthrumacscmp");
-}
-
-function cpelements_sort() {
- global $g, $config;
-
- function cpelementscmp($a, $b) {
- return strcasecmp($a['name'], $b['name']);
- }
-
- usort($config['captiveportal']['element'],"cpelementscmp");
-}
-
-function allowedips_sort() {
- global $g, $config;
-
- function allowedipscmp($a, $b) {
- return strcmp($a['ip'], $b['ip']);
- }
-
- usort($config['captiveportal']['allowedip'],"allowedipscmp");
-}
-
-function wol_sort() {
- global $g, $config;
-
- function wolcmp($a, $b) {
- return strcmp($a['descr'], $b['descr']);
- }
-
- usort($config['wol']['wolentry'], "wolcmp");
-}
-
function gentitle($title) {
global $navlevelsep;
if(!is_array($title))
@@ -916,24 +587,15 @@ function pconfig_to_address(&$adr, $padr, $pmask, $pnot=false, $pbeginport=0, $p
function is_specialnet($net) {
global $specialsrcdst;
- if(!$net)
- return false;
- if (in_array($net, $specialsrcdst) || strstr($net, "opt"))
+
+ if(!$net)
+ return false;
+ if (in_array($net, $specialsrcdst))
return true;
else
return false;
}
-function ipsec_ca_sort() {
- global $g, $config;
-
- function ipseccacmp($a, $b) {
- return strcmp($a['ident'], $b['ident']);
- }
-
- usort($config['ipsec']['cacert'], "ipseccacmp");
-}
-
//function to create widget tabs when called
function display_widget_tabs(& $tab_array) {
echo "<div id='tabs'>";
@@ -1103,25 +765,211 @@ function echo_array($array,$return_me=false){
}
}
+/****f* pfsense-utils/display_top_tabs
+ * NAME
+ * display_top_tabs - display tabs with rounded edges
+ * INPUTS
+ * $text - array of tabs
+ * RESULT
+ * null
+ ******/
+function display_top_tabs(& $tab_array) {
+ global $HTTP_SERVER_VARS;
+ global $config;
+ global $g;
+
+ /* does the user have access to this tab?
+ * master user has access to everything.
+ * if the user does not have access, simply
+ * unset the tab item.
+ */
+
+ $tab_temp = array ();
+ foreach ($tab_array as $ta)
+ if(isAllowedPage($ta[2]))
+ $tab_temp[] = $ta;
+ /*
+ // FIXME : if the checks are not good enough
+ // in isAllowedPage, it needs to be
+ // fixed instead of kludging here
+
+ // TODO: humm what shall we do with pkg_edit.php and pkg.php?
+ if ((strpos($link, "pkg.php")) !== false || (strpos($link, "pkg_edit.php")) !== false) {
+ $pos_equal = strpos($link, "=");
+ $pos_xmlsuffix = strpos($link, ".xml");
+ // do we match an absolute url including ?xml= foo
+ if(!isAllowedPage($link, $allowed))
+ $link = substr($link, $pos_equal +1, ($pos_xmlsuffix - $pos_equal +3));
+ }
+ // next check - what if the basename contains a query string?
+ if ((strpos($link, "?")) !== false) {
+ $pos_qmark = strpos($link, "?");
+ $link = substr($link, 0, $pos_qmark);
+ }
+ $authorized_text = print_r($allowed, true);
+ if(is_array($authorized))
+ if (in_array(basename($link), $authorized))
+ */
+
+ unset ($tab_array);
+ $tab_array = & $tab_temp;
+
+ $tab_active_bg = "#EEEEEE";
+ $tab_inactive_bg = "#777777";
+ $nifty_tabs_corners = "#FFF";
+ $font_color = "white";
+
+ /* if tabcontrols.php exist for a theme, allow it to be overriden */
+ $themename = $config['theme'];
+ $filename = "/usr/local/www/themes/{$themename}/tabcontrols.php";
+ if(file_exists($filename)) {
+ $eval_code = file_get_contents($filename);
+ eval($eval_code);
+ }
+
+ $tabcharcount = 0;
+ foreach ($tab_array as $ta)
+ $tabcharcount = $tabcharcount + strlen($ta[0]);
+
+ // If the character count of the tab names is > 670
+ // then show a select item dropdown menubox.
+ if($tabcharcount > 82) {
+ echo "Currently viewing: ";
+ echo "<select name='TabSelect'>\n";
+ foreach ($tab_array as $ta) {
+ if($ta[1]=="true")
+ $selected = " SELECTED";
+ else
+ $selected = "";
+ echo "<option onClick=\"document.location='{$ta[2]}';\"{$selected}>{$ta['0']}</option>\n";
+ }
+ echo "</select>\n<p/>";
+ } else {
+ echo "<table cellpadding='0' cellspacing='0'>\n";
+ echo " <tr>\n";
+ $tabscounter = 0;
+ foreach ($tab_array as $ta) {
+ if ($ta[1] == true) {
+ echo " <td bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabactive'></div></td>\n";
+ } else {
+ echo " <td bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabdeactive{$tabscounter}'></div></td>\n";
+ }
+ $tabscounter++;
+ }
+ echo "</tr>\n<tr>\n";
+ foreach ($tab_array as $ta) {
+ if ($ta[1] == true) {
+ echo " <td height=\"15\" valign=\"middle\" bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;{$ta[0]}";
+ echo "&nbsp;&nbsp;&nbsp;";
+ echo "<font size='-12'>&nbsp;</font></B></td>\n";
+ } else {
+ echo " <td height=\"15\" valign=\"middle\" bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;<a href='{$ta[
+2]}'>";
+ echo "<font color='{$font_color}'>{$ta[0]}</font></a>&nbsp;&nbsp;&nbsp;";
+ echo "<font size='-12'>&nbsp;</font></B></td>\n";
+ }
+ }
+ echo "</tr>\n<tr>\n";
+ foreach ($tab_array as $ta) {
+ if ($ta[1] == true) {
+ echo " <td bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
+ } else {
+ echo " <td bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
+ }
+ $tabscounter++;
+ }
+ echo " </tr>\n";
+ echo "</table>\n";
+ echo "<script type=\"text/javascript\">";
+ echo "NiftyCheck();\n";
+ echo "Rounded(\"div#tabactive\",\"top\",\"{$nifty_tabs_corners}\",\"{$tab_active_bg}\",\"smooth\");\n";
+ for ($x = 0; $x < $tabscounter; $x++)
+ echo "Rounded(\"div#tabdeactive{$x}\",\"top\",\"{$nifty_tabs_corners}\",\"{$tab_inactive_bg}\",\"smooth\");\n";
+ echo "</script>";
+ }
+}
+
function add_package_tabs($tabgroup, & $tab_array) {
- global $config, $g;
+ global $config, $g;
- if(!is_array($config['installedpackages']))
- return;
- if(!is_array($config['installedpackages']['tab']))
- return;
+ if(!is_array($config['installedpackages']))
+ return;
+ if(!is_array($config['installedpackages']['tab']))
+ return;
- foreach($config['installedpackages']['tab'] as $tab) {
- if ($tab['group'] !== $group)
- continue;
- $tab_entry = array();
- if($tab['name']) {
- $tab_entry[] = $tab['name'];
- $tab_entry[] = false;
- $tab_entry[] = $tab['url'];
- $tab_array[] = $tab_entry;
- }
- }
+ foreach($config['installedpackages']['tab'] as $tab) {
+ if ($tab['group'] !== $group)
+ continue;
+ $tab_entry = array();
+ if($tab['name']) {
+ $tab_entry[] = $tab['name'];
+ $tab_entry[] = false;
+ $tab_entry[] = $tab['url'];
+ $tab_array[] = $tab_entry;
+ }
+ }
}
-?> \ No newline at end of file
+function rule_popup($src,$srcport,$dst,$dstport){
+ global $config;
+ $aliases_array = array();
+ if($config['aliases']['alias'] <> "" and is_array($config['aliases']['alias']))
+ {
+ $span_begin = "";
+ $alias_src_span_begin = "";
+ $alias_src_span_end = "";
+ $alias_src_port_span_begin = "";
+ $alias_src_port_span_end = "";
+ $alias_dst_span_begin = "";
+ $alias_dst_span_end = "";
+ $alias_dst_port_span_begin = "";
+ $alias_dst_port_span_end = "";
+ $alias_content_text = "";
+ foreach($config['aliases']['alias'] as $alias_name)
+ {
+ $alias_addresses = explode (" ", $alias_name['address']);
+ $alias_details = explode ("||", $alias_name['detail']);
+ $alias_objects_with_details = "";
+ $counter = 0;
+ foreach($alias_addresses as $alias_ports_address)
+ {
+ $alias_objects_with_details .= $alias_addresses[$counter];
+ $alias_detail_default = strpos ($alias_details[$counter],"Entry added");
+ if ($alias_details[$counter] != "" && $alias_detail_default === False){
+ $alias_objects_with_details .=" - " . $alias_details[$counter];
+ }
+ $alias_objects_with_details .= "<br>";
+ $counter++;
+ }
+ //max character length for caption field
+ $maxlength = 60;
+
+ $alias_descr_substr = $alias_name['descr'];
+ $alias_content_text = htmlspecialchars($alias_objects_with_details);
+ $alias_caption = htmlspecialchars($alias_descr_substr . ":");
+ $strlength = strlen ($alias_caption);
+ if ($strlength >= $maxlength)
+ $alias_caption = substr($alias_caption, 0, $maxlength) . "...";
+
+ $span_begin = "<span style=\"cursor: help;\" onmouseover=\"domTT_activate(this, event, 'content', '<h1>$alias_caption</h1><p>$alias_content_text</p>', 'trail', true, 'delay', 0, 'fade', 'both', 'fadeMax', 93, 'styleClass', 'niceTitle');\" onmouseout=\"this.style.color = ''; domTT_mouseout(this, event);\"><U>";
+
+ if ($alias_name['name'] == $src)
+ $alias_src_span_begin = $span_begin;
+ if ($alias_name['name'] == $srcport)
+ $alias_src_port_span_begin = $span_begin;
+ if ($alias_name['name'] == $dst)
+ $alias_dst_span_begin = $span_begin;
+ if ($alias_name['name'] == $dstport)
+ $alias_dst_port_span_begin = $span_begin;
+ }
+ $descriptions = array ();
+ $descriptions['src'] = $alias_src_span_begin;
+ $descriptions['srcport'] = $alias_src_port_span_begin;
+ $descriptions['dst'] = $alias_dst_span_begin;
+ $descriptions['dstport'] = $alias_dst_port_span_begin;
+
+ return $descriptions;
+ }
+}
+
+?>
diff --git a/usr/local/www/interfaces.php b/usr/local/www/interfaces.php
index 8a8fb8f..64d9662 100755
--- a/usr/local/www/interfaces.php
+++ b/usr/local/www/interfaces.php
@@ -229,39 +229,35 @@ if (isset($wancfg['wireless'])) {
if ($_POST['apply']) {
unset($input_errors);
- if (!file_exists($d_landirty_path))
+ if (!is_subsystem_dirty('interfaces'))
$intput_errors[] = "You have already applied your settings!";
else {
unlink_if_exists("{$g['tmp_path']}/config.cache");
- unlink_if_exists("{$d_landirty_path}");
+ clear_subsystem_dirty('interfaces');
interface_configure($if);
reset_carp();
/* restart snmp so that it binds to correct address */
services_snmpd_configure();
if ($if == "lan")
$savemsg = "The changes have been applied. You may need to correct your web browser's IP address.";
+
/* sync filter configuration */
setup_gateways_monitor();
- if (file_exists($d_staticroutesdirty_path))
- unlink($d_staticroutesdirty_path);
- filter_configure();
- /* set up static routes */
- system_routing_configure();
- /* start IPsec tunnels */
- vpn_ipsec_configure();
+
+ clear_subsystem_dirty('staticroutes');
}
header("Location: interfaces.php?if={$if}");
exit;
-}
+} else
if ($_POST && $_POST['enable'] == "no") {
unset($wancfg['enable']);
interface_bring_down($if);
write_config("Interface {$_POST['descr']}({$if}) is now disabled.");
- touch($d_landirty_path);
+ mark_subsystem_dirty('interfaces');
header("Location: interfaces.php?if={$if}");
exit;
-}
+} else
if ($_POST) {
unset($input_errors);
@@ -478,7 +474,7 @@ if ($_POST) {
if (isset($wancfg['wireless']))
handle_wireless_post();
write_config();
- touch($d_landirty_path);
+ mark_subsystem_dirty('interfaces');
/* regenerate cron settings/crontab file */
configure_cron();
conf_mount_ro();
@@ -729,12 +725,16 @@ $types = array("none" => "None", "static" => "Static", "dhcp" => "DHCP", "pppoe"
<?php include("fbegin.inc"); ?>
<form action="interfaces.php" method="post" name="iform" id="iform">
<?php if ($input_errors) print_input_errors($input_errors); ?>
- <?php if (file_exists($d_landirty_path)): ?><p>
+ <?php if (is_subsystem_dirty('interfaces')): ?><p>
<?php print_info_box_np(gettext("The {$wancfg['descr']} configuration has been changed.<p>You must apply the changes in order for them to take effect.<p>Don't forget to adjust the DHCP Server range if needed before applying."));?><br />
<?php endif; ?>
<?php if ($savemsg) print_info_box($savemsg); ?>
<table width="100%" border="0" cellpadding="6" cellspacing="0">
<tr>
+ <td id="mainarea">
+ <div class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
<td colspan="2" valign="top" class="listtopic">General configuration</td>
</tr>
<?php if ($if != "wan" && $if != "lan"): ?>
@@ -884,7 +884,7 @@ $types = array("none" => "None", "static" => "Static", "dhcp" => "DHCP", "pppoe"
<td width="45%" align="right"><font color="white">Default gateway:</td><td><input type="checkbox" id="defaultgw" name="defaultgw"<?=$checked?>></td>
</tr>
<tr>
- <td align="right"><font color="white">Gateway Name:</td><td><input id="name" name="name" value="<?=$wancfg['descr'] . "-GW"?>"></td>
+ <td align="right"><font color="white">Gateway Name:</td><td><input id="name" name="name" value="<?=$wancfg['descr'] . "GW"?>"></td>
</tr>
<tr>
<td align="right"><font color="white">Gateway IP:</td><td><input id="gatewayip" name="gatewayip"></td>
@@ -1432,6 +1432,9 @@ $types = array("none" => "None", "static" => "Static", "dhcp" => "DHCP", "pppoe"
</table>
</td>
</table>
+ </div>
+ </td></tr>
+ </table>
</form>
<script type="text/javascript">
var gatewayip;
diff --git a/usr/local/www/interfaces_assign.php b/usr/local/www/interfaces_assign.php
index 3b84802..e8cfc08 100755
--- a/usr/local/www/interfaces_assign.php
+++ b/usr/local/www/interfaces_assign.php
@@ -312,15 +312,17 @@ if(file_exists("/var/run/interface_mismatch_reboot_needed"))
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
<?php include("fbegin.inc"); ?>
-<?php if ($input_errors) print_input_errors($input_errors); ?>
-<?php if ($savemsg) print_info_box($savemsg); ?>
<form action="interfaces_assign.php" method="post" name="iform" id="iform">
+
<?php if (file_exists("/tmp/reload_interfaces")): ?><p>
-<?php print_info_box_np("The interface configuration has been changed.<br>You must apply
- the changes in order for them to take effect.");?><br>
+ <?php print_info_box_np("The interface configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<?php elseif; ?>
+ <?php if ($savemsg) print_info_box($savemsg); ?>
<?php endif; ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td class="tabnavtbl">
<?php
diff --git a/usr/local/www/interfaces_bridge.php b/usr/local/www/interfaces_bridge.php
index c7e4753..8f5406e 100644
--- a/usr/local/www/interfaces_bridge.php
+++ b/usr/local/www/interfaces_bridge.php
@@ -28,6 +28,13 @@
POSSIBILITY OF SUCH DAMAGE.
*/
+##|+PRIV
+##|*IDENT=page-interfaces-bridge
+##|*NAME=Interfaces: Bridge page
+##|*DESCR=Allow access to the 'Interfaces: Bridge' page.
+##|*MATCH=interfaces_bridge.php*
+##|-PRIV
+
require("guiconfig.inc");
if (!is_array($config['bridges']['bridged']))
diff --git a/usr/local/www/interfaces_bridge_edit.php b/usr/local/www/interfaces_bridge_edit.php
index 12bbb88..8eef909 100644
--- a/usr/local/www/interfaces_bridge_edit.php
+++ b/usr/local/www/interfaces_bridge_edit.php
@@ -28,6 +28,13 @@
POSSIBILITY OF SUCH DAMAGE.
*/
+##|+PRIV
+##|*IDENT=page-interfaces-bridge-edit
+##|*NAME=Interfaces: Bridge edit page
+##|*DESCR=Allow access to the 'Interfaces: Bridge : Edit' page.
+##|*MATCH=interfaces_bridge_edit.php*
+##|-PRIV
+
require("guiconfig.inc");
if (!is_array($config['bridges']['bridged']))
@@ -244,6 +251,8 @@ function show_source_port_range() {
<select name="members[]" multiple="true" class="formselect" size="3">
<?php
foreach ($ifacelist as $ifn => $ifinfo) {
+ if (strstr(get_real_interface($ifn), "gif") != FALSE)
+ continue; /* gif(4) cannot be part of bridge since it does not know about layer2 */
echo "<option value=\"{$ifn}\"";
if (stristr($pconfig['members'], $ifn))
echo "selected";
diff --git a/usr/local/www/interfaces_lagg_edit.php b/usr/local/www/interfaces_lagg_edit.php
index c73676e..f3a5567 100644
--- a/usr/local/www/interfaces_lagg_edit.php
+++ b/usr/local/www/interfaces_lagg_edit.php
@@ -75,6 +75,7 @@ if ($_POST) {
$lagg['members'] = implode(',', $_POST['members']);
$lagg['descr'] = $_POST['descr'];
$lagg['laggif'] = $_POST['laggif'];
+ $lagg['proto'] = $_POST['proto'];
$lagg['laggif'] = interface_lagg_configure($lagg);
if ($lagg['laggif'] == "" || !stristr($lagg['laggif'], "lagg"))
diff --git a/usr/local/www/interfaces_ppp_edit.php b/usr/local/www/interfaces_ppp_edit.php
index 3d06f73..7731e26 100644
--- a/usr/local/www/interfaces_ppp_edit.php
+++ b/usr/local/www/interfaces_ppp_edit.php
@@ -103,7 +103,7 @@ if ($_POST) {
$ppp['pppif'] = $_POST['pppif'];
$ppp['pppif'] = interface_ppp_configure($ppp);
if ($ppp['pppif'] == "" || !stristr($ppp['pppif'], "ppp"))
- $input_errors[] = "Error occured creating interface, please retry.";
+ $input_errors[] = "Error occurred creating PPP interface. Check System log for details";
else {
if (isset($id) && $a_ppps[$id])
$a_ppps[$id] = $ppp;
@@ -181,15 +181,16 @@ include("head.inc");
<tr>
<td width="22%" valign="top" class="vncell">Local IP</td>
<td width="78%" class="vtable">
- <input name="gateway" type="text" class="formfld unknown" id="gateway" size="40" value="<?=htmlspecialchars($pconfig['gateway']);?>">
- <span><p>Note: This is needed if you connect to a private system and are given a static ip.</span>
+ <input name="localip" type="text" class="formfld unknown" id="localip" size="40" value="<?=htmlspecialchars($pconfig['localip']);?>">
+ <span><p>Note: Enter your IP address here if it is not automatically assigned.</span>
</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell">Remote IP</td>
<td width="78%" class="vtable">
- <input name="localip" type="text" class="formfld unknown" id="localip" size="40" value="<?=htmlspecialchars($pconfig['localip']);?>">
- <span><p>Note: This is where the packets will be routed, aka gateway on normal ip routing.</span>
+ <input name="gateway" type="text" class="formfld unknown" id="gateway" size="40" value="<?=htmlspecialchars($pconfig['gateway']);?>">
+ <span><p>Note: Enter the remote IP here if not automatically assigned. This
+ is where the packets will be routed, equivalent to the gateway.</span>
</td>
</tr>
<tr>
diff --git a/usr/local/www/interfaces_qinq.php b/usr/local/www/interfaces_qinq.php
index 72010e8..7d134da 100755
--- a/usr/local/www/interfaces_qinq.php
+++ b/usr/local/www/interfaces_qinq.php
@@ -93,7 +93,7 @@ include("head.inc");
$tab_array = array();
$tab_array[0] = array("Interface assignments", false, "interfaces_assign.php");
$tab_array[1] = array("Interface Groups", false, "interfaces_groups.php");
- $tab_array[2] = array("VLANs", false, "interfaces_qinq.php");
+ $tab_array[2] = array("VLANs", false, "interfaces_vlan.php");
$tab_array[3] = array("QinQs", true, "interfaces_qinq.php");
$tab_array[4] = array("PPP", false, "interfaces_ppp.php");
$tab_array[5] = array("GRE", false, "interfaces_gre.php");
diff --git a/usr/local/www/interfaces_vlan_edit.php b/usr/local/www/interfaces_vlan_edit.php
index 04f7f4b..b656293 100755
--- a/usr/local/www/interfaces_vlan_edit.php
+++ b/usr/local/www/interfaces_vlan_edit.php
@@ -98,7 +98,7 @@ if ($_POST) {
$vlan['if'] = $_POST['if'];
$vlan['tag'] = $_POST['tag'];
$vlan['descr'] = $_POST['descr'];
- $vlan['vlanif'] = "vlan{$_POST['tag']}";
+ $vlan['vlanif'] = "{$_POST['if']}_vlan{$_POST['tag']}";
$vlan['vlanif'] = interface_vlan_configure($vlan);
if ($vlan['vlanif'] == "" || !stristr($vlan['vlanif'], "vlan"))
diff --git a/usr/local/www/javascript/row_helper.js b/usr/local/www/javascript/row_helper.js
index 15d23f1..8193043 100755
--- a/usr/local/www/javascript/row_helper.js
+++ b/usr/local/www/javascript/row_helper.js
@@ -25,7 +25,7 @@ var addRowTo = (function() {
for (i = 0; i < field_counter_js; i++) {
td = d.createElement("td");
if(rowtype[i] == 'textbox') {
- td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><input size='" + rowsize[i] + "' class='formfld unknown' name='" + rowname[i] + totalrows + "'></input> ";
+ td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><input size='" + rowsize[i] + "' class='formfld unknown' name='" + rowname[i] + totalrows + "' id='" + rowname[i] + totalrows + "'></input> ";
} else if(rowtype[i] == 'select') {
td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + "'></input><select size='1' name='" + rowname[i] + totalrows + "'><option value=\"32\" selected>32</option><option value=\"31\" >31</option><option value=\"30\" >30</option><option value=\"29\" >29</option><option value=\"28\" >28</option><option value=\"27\" >27</option><option value=\"26\" >26</option><option value=\"25\" >25</option><option value=\"24\" >24</option><option value=\"23\" >23</option><option value=\"22\" >22</option><option value=\"21\" >21</option><option value=\"20\" >20</option><option value=\"19\" >19</option><option value=\"18\" >18</option><option value=\"17\" >17</option><option value=\"16\" >16</option><option value=\"15\" >15</option><option value=\"14\" >14</option><option value=\"13\" >13</option><option value=\"12\" >12</option><option value=\"11\" >11</option><option value=\"10\" >10</option><option value=\"9\" >9</option><option value=\"8\" >8</option><option value=\"7\" >7</option><option value=\"6\" >6</option><option value=\"5\" >5</option><option value=\"4\" >4</option><option value=\"3\" >3</option><option value=\"2\" >2</option><option value=\"1\" >1</option></select> ";
} else {
diff --git a/usr/local/www/javascript/suggestions.js b/usr/local/www/javascript/suggestions.js
index 1b30fff..682a352 100644
--- a/usr/local/www/javascript/suggestions.js
+++ b/usr/local/www/javascript/suggestions.js
@@ -22,7 +22,7 @@ StateSuggestions.prototype.requestSuggestions = function (oAutoSuggestControl /*
//search for matching states
for (var i=0; i < this.states.length; i++) {
- if (this.states[i].indexOf(sTextboxValue) == 0) {
+ if (this.states[i].toLowerCase().indexOf(sTextboxValue.toLowerCase()) == 0) {
aSuggestions.push(this.states[i]);
}
}
@@ -30,4 +30,4 @@ StateSuggestions.prototype.requestSuggestions = function (oAutoSuggestControl /*
//provide suggestions to the control
oAutoSuggestControl.autosuggest(aSuggestions, bTypeAhead);
-}; \ No newline at end of file
+};
diff --git a/usr/local/www/javascript/ticker.js b/usr/local/www/javascript/ticker.js
index 77d3c63..8297c10 100755
--- a/usr/local/www/javascript/ticker.js
+++ b/usr/local/www/javascript/ticker.js
@@ -10,33 +10,39 @@ var copyspeed=speed;
var pausespeed=(pauseit==0)? copyspeed: 0;
var iedom=document.all||document.getElementById;
-if (iedom)
+if (iedom&&content)
document.write('<span id="marquee-container">'+content+'</span>');
var actualwidth='';
var scroller;
-if (window.addEventListener)
- window.addEventListener("load", populatescroller, false);
-else if (window.attachEvent)
- window.attachEvent("onload", populatescroller);
-else if (document.all || document.getElementById)
- window.onload=populatescroller;
+try {
+ if (window.addEventListener)
+ window.addEventListener("load", populatescroller, false);
+ else if (window.attachEvent)
+ window.attachEvent("onload", populatescroller);
+ else if (document.all || document.getElementById)
+ window.onload=populatescroller;
+}catch(e){}
function populatescroller(){
- scroller=document.getElementById? document.getElementById("scroller") : document.all.scroller;
- scroller.style.left=parseInt(width)+8+"px";
- scroller.innerHTML=content;
- document.getElementById("marquee-text");
- actualwidth=document.all? document.getElementById("marquee-text").offsetWidth : document.getElementById("marquee-text").offsetWidth;
- lefttime=setInterval("scrollmarquee()",20);
+ try {
+ scroller=document.getElementById? document.getElementById("scroller") : document.all.scroller;
+ scroller.style.left=parseInt(width)+8+"px";
+ scroller.innerHTML=content;
+ document.getElementById("marquee-text");
+ actualwidth=document.all? document.getElementById("marquee-text").offsetWidth : document.getElementById("marquee-text").offsetWidth;
+ lefttime=setInterval("scrollmarquee()",20);
+ }catch(e){}
}
function scrollmarquee(){
- if (parseInt(scroller.style.left)>(actualwidth*(-1)+8))
- scroller.style.left=parseInt(scroller.style.left)-copyspeed+"px";
- else
- scroller.style.left=parseInt(width)+8+"px";
+ try {
+ if (parseInt(scroller.style.left)>(actualwidth*(-1)+8))
+ scroller.style.left=parseInt(scroller.style.left)-copyspeed+"px";
+ else
+ scroller.style.left=parseInt(width)+8+"px";
+ }catch(e){}
}
if (iedom){
@@ -47,4 +53,4 @@ if (iedom){
document.write('</td></table>');
}
-//--> \ No newline at end of file
+//-->
diff --git a/usr/local/www/load_balancer_monitor.php b/usr/local/www/load_balancer_monitor.php
index 96406a9..c133d0f 100755
--- a/usr/local/www/load_balancer_monitor.php
+++ b/usr/local/www/load_balancer_monitor.php
@@ -52,7 +52,7 @@ if ($_POST) {
$retval |= relayd_configure();
$savemsg = get_std_save_message($retval);
- unlink_if_exists($d_vsconfdirty_path);
+ clear_subsystem_dirty('loadbalancer');
}
}
@@ -71,7 +71,7 @@ if ($_GET['act'] == "del") {
if (!$input_errors) {
unset($a_monitor[$_GET['id']]);
write_config();
- touch($d_vsconfdirty_path);
+ mark_subsystem_dirty('loadbalancer');
header("Location: load_balancer_monitor.php");
exit;
}
@@ -87,7 +87,7 @@ include("head.inc");
<form action="load_balancer_monitor.php" method="post">
<?php if ($input_errors) print_input_errors($input_errors); ?>
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_vsconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('loadbalancer')): ?><p>
<?php print_info_box_np("The load balancer configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/load_balancer_monitor_edit.php b/usr/local/www/load_balancer_monitor_edit.php
index 82ef06d..4cea8d3 100755
--- a/usr/local/www/load_balancer_monitor_edit.php
+++ b/usr/local/www/load_balancer_monitor_edit.php
@@ -174,8 +174,7 @@ if ($_POST) {
if ($changecount > 0) {
/* Mark config dirty */
- conf_mount_rw();
- touch($d_vsconfdirty_path);
+ mark_subsystem_dirty('loadbalancer');
write_config($changedesc);
}
diff --git a/usr/local/www/load_balancer_pool.php b/usr/local/www/load_balancer_pool.php
index 80b6941..2890bd8 100755
--- a/usr/local/www/load_balancer_pool.php
+++ b/usr/local/www/load_balancer_pool.php
@@ -54,7 +54,7 @@ if ($_POST) {
$retval |= relayd_configure();
$savemsg = get_std_save_message($retval);
- unlink_if_exists($d_vsconfdirty_path);
+ clear_subsystem_dirty('loadbalancer');
}
}
@@ -73,7 +73,7 @@ if ($_GET['act'] == "del") {
if (!$input_errors) {
unset($a_pool[$_GET['id']]);
write_config();
- touch($d_vsconfdirty_path);
+ mark_subsystem_dirty('loadbalancer');
header("Location: load_balancer_pool.php");
exit;
}
@@ -98,7 +98,7 @@ include("head.inc");
<form action="load_balancer_pool.php" method="post">
<?php if ($input_errors) print_input_errors($input_errors); ?>
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_vsconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('loadbalancer')): ?><p>
<?php print_info_box_np("The load balancer configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/load_balancer_pool_edit.php b/usr/local/www/load_balancer_pool_edit.php
index 4bf71f8..0cb24ad 100755
--- a/usr/local/www/load_balancer_pool_edit.php
+++ b/usr/local/www/load_balancer_pool_edit.php
@@ -125,8 +125,7 @@ if ($_POST) {
if ($changecount > 0) {
/* Mark pool dirty */
- conf_mount_rw();
- touch($d_vsconfdirty_path);
+ mark_subsystem_dirty('loadbalancer');
write_config($changedesc);
}
diff --git a/usr/local/www/load_balancer_relay_action.php b/usr/local/www/load_balancer_relay_action.php
index 6653f93..cd25365 100755
--- a/usr/local/www/load_balancer_relay_action.php
+++ b/usr/local/www/load_balancer_relay_action.php
@@ -54,7 +54,7 @@ if ($_POST) {
$retval |= relayd_configure();
$savemsg = get_std_save_message($retval);
- unlink_if_exists($d_vsconfdirty_path);
+ clear_subsystem_dirty('loadbalancer');
}
}
@@ -75,7 +75,7 @@ if ($_GET['act'] == "del") {
if (!$input_errors) {
unset($a_action[$_GET['id']]);
write_config();
- touch($d_vsconfdirty_path);
+ mark_subsystem_dirty('loadbalancer');
header("Location: load_balancer_relay_action.php");
exit;
}
@@ -104,7 +104,7 @@ include("head.inc");
<form action="load_balancer_relay_action.php" method="post">
<?php if ($input_errors) print_input_errors($input_errors); ?>
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_vsconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('loadbalancer')): ?><p>
<?php print_info_box_np("The load balancer configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/load_balancer_relay_action_edit.php b/usr/local/www/load_balancer_relay_action_edit.php
index 36c640c..e8a3785 100755
--- a/usr/local/www/load_balancer_relay_action_edit.php
+++ b/usr/local/www/load_balancer_relay_action_edit.php
@@ -163,8 +163,7 @@ if ($_POST) {
}
if ($changecount > 0) {
/* Mark config dirty */
- conf_mount_rw();
- touch($d_vsconfdirty_path);
+ mark_subsystem_dirty('loadbalancer');
write_config($changedesc);
}
diff --git a/usr/local/www/load_balancer_relay_protocol.php b/usr/local/www/load_balancer_relay_protocol.php
index e0007b5..2207542 100755
--- a/usr/local/www/load_balancer_relay_protocol.php
+++ b/usr/local/www/load_balancer_relay_protocol.php
@@ -52,7 +52,7 @@ if ($_POST) {
$retval |= relayd_configure();
$savemsg = get_std_save_message($retval);
- unlink_if_exists($d_vsconfdirty_path);
+ clear_subsystem_dirty('loadbalancer');
}
}
@@ -71,7 +71,7 @@ if ($_GET['act'] == "del") {
if (!$input_errors) {
unset($a_protocol[$_GET['id']]);
write_config();
- touch($d_vsconfdirty_path);
+ mark_subsystem_dirty('loadbalancer');
header("Location: load_balancer_relay_protocol.php");
exit;
}
@@ -100,7 +100,7 @@ include("head.inc");
<form action="load_balancer_relay_protocol.php" method="post">
<?php if ($input_errors) print_input_errors($input_errors); ?>
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_vsconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('loadbalancer')): ?><p>
<?php print_info_box_np("The load balancer configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/load_balancer_relay_protocol_edit.php b/usr/local/www/load_balancer_relay_protocol_edit.php
index dcdb9b9..6637715 100755
--- a/usr/local/www/load_balancer_relay_protocol_edit.php
+++ b/usr/local/www/load_balancer_relay_protocol_edit.php
@@ -118,8 +118,7 @@ if ($_POST) {
if ($changecount > 0) {
/* Mark config dirty */
- conf_mount_rw();
- touch($d_vsconfdirty_path);
+ mark_subsystem_dirty('loadbalancer');
write_config($changedesc);
}
diff --git a/usr/local/www/load_balancer_virtual_server.php b/usr/local/www/load_balancer_virtual_server.php
index ba62613..f087c90 100755
--- a/usr/local/www/load_balancer_virtual_server.php
+++ b/usr/local/www/load_balancer_virtual_server.php
@@ -53,7 +53,7 @@ if ($_POST) {
$retval |= filter_configure();
$retval |= relayd_configure();
$savemsg = get_std_save_message($retval);
- unlink_if_exists($d_vsconfdirty_path);
+ clear_subsystem_dirty('loadbalancer');
}
}
@@ -63,7 +63,7 @@ if ($_GET['act'] == "del") {
if (!$input_errors) {
unset($a_vs[$_GET['id']]);
write_config();
- touch($d_vsconfdirty_path);
+ mark_subsystem_dirty('loadbalancer');
header("Location: load_balancer_virtual_server.php");
exit;
}
@@ -94,7 +94,7 @@ include("head.inc");
<form action="load_balancer_virtual_server.php" method="post">
<?php if ($input_errors) print_input_errors($input_errors); ?>
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_vsconfdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('loadbalancer')): ?><p>
<?php print_info_box_np("The virtual server configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/load_balancer_virtual_server_edit.php b/usr/local/www/load_balancer_virtual_server_edit.php
index d62b765..8523286 100755
--- a/usr/local/www/load_balancer_virtual_server_edit.php
+++ b/usr/local/www/load_balancer_virtual_server_edit.php
@@ -114,7 +114,7 @@ if ($_POST) {
if ($changecount > 0) {
/* Mark virtual server dirty */
- touch($d_vsconfdirty_path);
+ mark_subsystem_dirty('loadbalancer');
write_config($changedesc);
}
diff --git a/usr/local/www/pkg_edit.php b/usr/local/www/pkg_edit.php
index 8005120..6bc4429 100755
--- a/usr/local/www/pkg_edit.php
+++ b/usr/local/www/pkg_edit.php
@@ -165,7 +165,7 @@ if ($_POST) {
if($firstfield == $rowhelperfield['fieldname']) $rows++;
}
$fieldname = str_replace("\\", "", $rowhelperfield['fieldname']);
- $fieldname = "\$value = \$_POST['" . $fieldname . $x . "'];";
+ $comd = "\$value = \$_POST['" . $fieldname . $x . "'];";
eval($comd);
if($value <> "") {
$comd = "\$pkgarr['row'][" . $x . "]['" . $fieldname . "'] = \"" . $value . "\";";
@@ -195,12 +195,16 @@ if ($_POST) {
$a_pkg[] = $pkgarr;
write_config($pkg['addedit_string']);
-
// late running code
if($pkg['custom_add_php_command_late'] <> "") {
eval($pkg['custom_add_php_command_late']);
}
+ if (isset($pkg['filter_rules_needed'])) {
+ pkg_build_filter_rules();
+ filter_configure();
+ }
+
// resync the configuration file code if defined.
if($pkg['custom_php_resync_config_command'] <> "") {
eval($pkg['custom_php_resync_config_command']);
@@ -255,25 +259,45 @@ foreach ($pkg['fields']['field'] as $field) {
print("\tif (document.iform.elements[\"{$field['fieldname']}\"].checked == false) {\n");
if (isset($field['enablefields'])) {
- foreach (explode(',', $field['enablefields']) as $enablefield)
- print("\t\tdocument.iform.elements[\"$enablefield\"].disabled = 1;\n");
+ foreach (explode(',', $field['enablefields']) as $enablefield) {
+ print("\t\tif(document.iform.elements[\"$enablefield\"]){\n");
+ print("\t\t\tdocument.iform.elements[\"$enablefield\"].disabled = 1;\n");
+ print("\t\t}else{\n");
+ print("\t\t\tdocument.iform.elements[\"$enablefield".'[]'."\"].disabled = 1;\n");
+ print("\t\t}\n");
+ }
}
if (isset($field['checkenablefields'])) {
- foreach (explode(',', $field['checkenablefields']) as $checkenablefield)
- print("\t\tdocument.iform.elements[\"$checkenablefield\"].checked = 0;\n");
+ foreach (explode(',', $field['checkenablefields']) as $checkenablefield) {
+ print("\t\tif(document.iform.elements[\"$checkenablefield\"]){\n");
+ print("\t\t\tdocument.iform.elements[\"$checkenablefield\"].checked = 0;\n");
+ print("\t\t}else{\n");
+ print("\t\t\tdocument.iform.elements[\"$checkenablefield".'[]'."\"].checked = 0;\n");
+ print("\t\t}\n");
+ }
}
print("\t}\n\telse {\n");
if (isset($field['enablefields'])) {
- foreach (explode(',', $field['enablefields']) as $enablefield)
- print("\t\tdocument.iform.elements[\"$enablefield\"].disabled = 0;\n");
+ foreach (explode(',', $field['enablefields']) as $enablefield) {
+ print("\t\tif(document.iform.elements[\"$enablefield\"]){\n");
+ print("\t\t\tdocument.iform.elements[\"$enablefield\"].disabled = 0;\n");
+ print("\t\t}else{\n");
+ print("\t\t\tdocument.iform.elements[\"$enablefield".'[]'."\"].disabled = 0;\n");
+ print("\t\t}\n");
+ }
}
if (isset($field['checkenablefields'])) {
- foreach(explode(',', $field['checkenablefields']) as $checkenablefield)
- print("\t\tdocument.iform.elements[\"$checkenablefield\"].checked = 1;\n");
+ foreach(explode(',', $field['checkenablefields']) as $checkenablefield) {
+ print("\t\tif(document.iform.elements[\"$checkenablefield\"]){\n");
+ print("\t\t\tdocument.iform.elements[\"$checkenablefield\"].checked = 1;\n");
+ print("\t\t}else{\n");
+ print("\t\t\tdocument.iform.elements[\"$checkenablefield".'[]'."\"].checked = 1;\n");
+ print("\t\t}\n");
+ }
}
print("\t}\n");
@@ -505,8 +529,10 @@ if ($pkg['tabs'] <> "") {
$type = $rowhelper['type'];
$fieldname = $rowhelper['fieldname'];
if($type == "option") $options = &$rowhelper['options']['option'];
- $size = "8";
- if($rowhelper['size'] <> "") $size = $rowhelper['size'];
+ if($rowhelper['size'])
+ $size = $rowhelper['size'];
+ else
+ $size = "8";
display_row($rowcounter, $value, $fieldname, $type, $rowhelper, $size);
// javascript helpers for row_helper_dynamic.js
echo "</td>\n";
diff --git a/usr/local/www/pkg_mgr.php b/usr/local/www/pkg_mgr.php
index 89a3634..a1bfb5d 100755
--- a/usr/local/www/pkg_mgr.php
+++ b/usr/local/www/pkg_mgr.php
@@ -34,11 +34,11 @@
##|*MATCH=pkg_mgr.php*
##|-PRIV
-
+require_once("globals.inc");
require_once("guiconfig.inc");
require_once("pkg-utils.inc");
-$pkg_info = get_pkg_info('all', array('name', 'category', 'website', 'version', 'status', 'descr', 'maintainer', 'required_version', 'maximum_version', 'pkginfolink'));
+$pkg_info = get_pkg_info('all', array('noembedded', 'name', 'category', 'website', 'version', 'status', 'descr', 'maintainer', 'required_version', 'maximum_version', 'pkginfolink'));
if($pkg_info) {
$fout = fopen("{$g['tmp_path']}/pkg_info.cache", "w");
fwrite($fout, serialize($pkg_info));
@@ -81,8 +81,8 @@ include("head.inc");
$testing_version = substr($version, $hyphen + 1, strlen($version) - $hyphen);
$tab_array = array();
- $tab_array[] = array("Available {$version} packages", $requested_version <> "" ? false : true, "pkg_mgr.php");
- $tab_array[] = array("Packages for any platform", $requested_version == "none" ? true : false, "pkg_mgr.php?ver=none");
+ $tab_array[] = array("{$version} packages", $requested_version <> "" ? false : true, "pkg_mgr.php");
+// $tab_array[] = array("Packages for any platform", $requested_version == "none" ? true : false, "pkg_mgr.php?ver=none");
// $tab_array[] = array("Packages with a different version", $requested_version == "other" ? true : false, "pkg_mgr.php?ver=other");
$tab_array[] = array("Installed Packages", false, "pkg_mgr_installed.php");
display_top_tabs($tab_array);
@@ -122,6 +122,9 @@ include("head.inc");
$index = &$pkg_info[$key];
if(in_array($index['name'], $instpkgs))
continue;
+ if($g['platform'] == "nanobsd")
+ if($index['noembedded'])
+ continue;
$dash = strpos($index['required_version'], "-");
$index['major_version'] = substr($index['required_version'], 0, $dash);
if ($version <> "HEAD" &&
diff --git a/usr/local/www/pkg_mgr_install.php b/usr/local/www/pkg_mgr_install.php
index b6fb197..390839f 100755
--- a/usr/local/www/pkg_mgr_install.php
+++ b/usr/local/www/pkg_mgr_install.php
@@ -60,8 +60,8 @@ include("head.inc");
<?php
$version = file_get_contents("/etc/version");
$tab_array = array();
- $tab_array[] = array("Available {$version} packages", false, "pkg_mgr.php");
- $tab_array[] = array("Packages for any platform", false, "pkg_mgr.php?ver=none");
+ $tab_array[] = array("{$version} packages", false, "pkg_mgr.php");
+// $tab_array[] = array("Packages for any platform", false, "pkg_mgr.php?ver=none");
// $tab_array[] = array("Packages for a different platform", $requested_version == "other" ? true : false, "pkg_mgr.php?ver=other");
$tab_array[] = array("Installed packages", false, "pkg_mgr_installed.php");
$tab_array[] = array("Package Installer", true, "");
@@ -124,6 +124,7 @@ switch($_GET['mode']) {
update_status("Package deleted.");
$static_output .= "\nPackage deleted.";
update_output_window($static_output);
+ filter_configure();
break;
case "showlog":
$id = htmlspecialchars($_GET['pkg']);
@@ -139,6 +140,7 @@ switch($_GET['mode']) {
$static_output .= "\n\nPackage reinstalled.";
start_service(htmlspecialchars($_GET['pkg']));
update_output_window($static_output);
+ filter_configure();
break;
case "reinstallxml":
delete_package_xml(htmlspecialchars($_GET['pkg']));
@@ -146,6 +148,7 @@ switch($_GET['mode']) {
$static_output .= "\n\nPackage reinstalled.";
start_service(htmlspecialchars($_GET['pkg']));
update_output_window($static_output);
+ filter_configure();
break;
case "installedinfo":
$id = get_pkg_id(htmlspecialchars($_GET['pkg']));
@@ -179,6 +182,7 @@ switch($_GET['mode']) {
$static_output .= "\n\nAll packages reinstalled.";
start_service(htmlspecialchars($_GET['pkg']));
update_output_window($static_output);
+ filter_configure();
break;
default:
$status = install_package(htmlspecialchars($_GET['id']));
@@ -187,7 +191,7 @@ switch($_GET['mode']) {
$static_output .= "\n\nInstallation halted.";
update_output_window($static_output);
} else {
- $filename = escapeshellcmd("/tmp/" . $_GET['pkg'] . ".info");
+ $filename = escapeshellcmd("/tmp/" . $_GET['id'] . ".info");
$fd = fopen($filename, "w");
$status_a = "Installation of " . htmlspecialchars($_GET['id']) . " completed.";
update_status($status_a);
@@ -200,6 +204,8 @@ switch($_GET['mode']) {
fclose($fd);
echo "<script type='text/javascript'>document.location=\"pkg_mgr_install.php?mode=installedinfo&pkg={$_GET['id']}\";</script>";
}
+ filter_configure();
+ break;
}
// Delete all temporary package tarballs and staging areas.
@@ -213,4 +219,4 @@ conf_mount_ro();
if($fd_log)
fclose($fd_log);
-?> \ No newline at end of file
+?>
diff --git a/usr/local/www/pkg_mgr_installed.php b/usr/local/www/pkg_mgr_installed.php
index fb872ef..0d40d01 100755
--- a/usr/local/www/pkg_mgr_installed.php
+++ b/usr/local/www/pkg_mgr_installed.php
@@ -58,8 +58,8 @@ include("head.inc");
<?php
$version = file_get_contents("/etc/version");
$tab_array = array();
- $tab_array[] = array("Available {$version} packages", false, "pkg_mgr.php");
- $tab_array[] = array("Packages for any platform", false, "pkg_mgr.php?ver=none");
+ $tab_array[] = array("{$version} packages", false, "pkg_mgr.php");
+// $tab_array[] = array("Packages for any platform", false, "pkg_mgr.php?ver=none");
// $tab_array[] = array("Packages for a different platform", $requested_version == "other" ? true : false, "pkg_mgr.php?ver=other");
$tab_array[] = array("Installed packages", true, "pkg_mgr_installed.php");
display_top_tabs($tab_array);
diff --git a/usr/local/www/protochart/ProtoChart.js b/usr/local/www/protochart/ProtoChart.js
new file mode 100644
index 0000000..4e60f18
--- /dev/null
+++ b/usr/local/www/protochart/ProtoChart.js
@@ -0,0 +1,2653 @@
+/**
+ * Class: ProtoChart
+ * Version: v0.5 beta
+ *
+ * ProtoChart is a charting lib on top of Prototype.
+ * This library is heavily motivated by excellent work done by:
+ * * Flot <http://code.google.com/p/flot/>
+ * * Flotr <http://solutoire.com/flotr/>
+ *
+ * Complete examples can be found at: <http://www.deensoft.com/lab/protochart>
+ */
+
+/**
+ * Events:
+ * ProtoChart:mousemove - Fired when mouse is moved over the chart
+ * ProtoChart:plotclick - Fired when graph is clicked
+ * ProtoChart:dataclick - Fired when graph is clicked AND the click is on a data point
+ * ProtoChart:selected - Fired when certain region on the graph is selected
+ * ProtoChart:hit - Fired when mouse is moved near or over certain data point on the graph
+ */
+
+
+if(!Proto) var Proto = {};
+
+Proto.Chart = Class.create({
+ /**
+ * Function:
+ * {Object} elem
+ * {Object} data
+ * {Object} options
+ */
+ initialize: function(elem, data, options)
+ {
+ options = options || {};
+ this.graphData = [];
+ /**
+ * Property: options
+ *
+ * Description: Various options can be set. More details in description.
+ *
+ * colors:
+ * {Array} - pass in a array which contains strings of colors you want to use. Default has 6 color set.
+ *
+ * legend:
+ * {BOOL} - show - if you want to show the legend. Default is false
+ * {integer} - noColumns - Number of columns for the legend. Default is 1
+ * {function} - labelFormatter - A function that returns a string. The function is called with a string and is expected to return a string. Default = null
+ * {string} - labelBoxBorderColor - border color for the little label boxes. Default #CCC
+ * {HTMLElem} - container - an HTML id or HTML element where the legend should be rendered. If left null means to put the legend on top of the Chart
+ * {string} - position - position for the legend on the Chart. Default value 'ne'
+ * {integer} - margin - default valud of 5
+ * {string} - backgroundColor - default to null (which means auto-detect)
+ * {float} - backgroundOpacity - leave it 0 to avoid background
+ *
+ * xaxis (yaxis) options:
+ * {string} - mode - default is null but you can pass a string "time" to indicate time series
+ * {integer} - min
+ * {integer} - max
+ * {float} - autoscaleMargin - in % to add if auto-setting min/max
+ * {mixed} - ticks - either [1, 3] or [[1, "a"], 3] or a function which gets axis info and returns ticks
+ * {function} - tickFormatter - A function that returns a string as a tick label. Default is null
+ * {float} - tickDecimals
+ * {integer} - tickSize
+ * {integer} - minTickSize
+ * {array} - monthNames
+ * {string} - timeformat
+ *
+ * Points / Lines / Bars options:
+ * {bool} - show, default is false
+ * {integer} - radius: default is 3
+ * {integer} - lineWidth : default is 2
+ * {bool} - fill : default is true
+ * {string} - fillColor: default is #ffffff
+ *
+ * Grid options:
+ * {string} - color
+ * {string} - backgroundColor - defualt is *null*
+ * {string} - tickColor - default is *#dddddd*
+ * {integer} - labelMargin - should be in pixels default is 3
+ * {integer} - borderWidth - default *1*
+ * {bool} - clickable - default *null* - pass in TRUE if you wish to monitor click events
+ * {mixed} - coloredAreas - default *null* - pass in mixed object eg. {x1, x2}
+ * {string} - coloredAreasColor - default *#f4f4f4*
+ * {bool} - drawXAxis - default *true*
+ * {bool} - drawYAxis - default *true*
+ *
+ * selection options:
+ * {string} - mode : either "x", "y" or "xy"
+ * {string} - color : string
+ */
+ this.options = this.merge(options,{
+ colors: ["#edc240", "#00A8F0", "#C0D800", "#cb4b4b", "#4da74d", "#9440ed"],
+ legend: {
+ show: false,
+ noColumns: 1,
+ labelFormatter: null,
+ labelBoxBorderColor: "#ccc",
+ container: null,
+ position: "ne",
+ margin: 5,
+ backgroundColor: null,
+ backgroundOpacity: 0.85
+ },
+ xaxis: {
+ mode: null,
+ min: null,
+ max: null,
+ autoscaleMargin: null,
+ ticks: null,
+ tickFormatter: null,
+ tickDecimals: null,
+ tickSize: null,
+ minTickSize: null,
+ monthNames: null,
+ timeformat: null
+ },
+ yaxis: {
+ mode: null,
+ min: null,
+ max: null,
+ ticks: null,
+ tickFormatter: null,
+ tickDecimals: null,
+ tickSize: null,
+ minTickSize: null,
+ monthNames: null,
+ timeformat: null,
+ autoscaleMargin: 0.02
+ },
+
+ points: {
+ show: false,
+ radius: 3,
+ lineWidth: 2,
+ fill: true,
+ fillColor: "#ffffff"
+ },
+ lines: {
+ show: false,
+ lineWidth: 2,
+ fill: false,
+ fillColor: null
+ },
+ bars: {
+ show: false,
+ lineWidth: 2,
+ barWidth: 1,
+ fill: true,
+ fillColor: null,
+ showShadow: false,
+ fillOpacity: 0.4,
+ autoScale: true
+ },
+ pies: {
+ show: false,
+ radius: 50,
+ borderWidth: 1,
+ fill: true,
+ fillColor: null,
+ fillOpacity: 0.90,
+ labelWidth: 30,
+ fontSize: 11,
+ autoScale: true
+ },
+ grid: {
+ color: "#545454",
+ backgroundColor: null,
+ tickColor: "#dddddd",
+ labelMargin: 3,
+ borderWidth: 1,
+ clickable: null,
+ coloredAreas: null,
+ coloredAreasColor: "#f4f4f4",
+ drawXAxis: true,
+ drawYAxis: true
+ },
+ mouse: {
+ track: false,
+ position: 'se',
+ fixedPosition: true,
+ clsName: 'mouseValHolder',
+ trackFormatter: this.defaultTrackFormatter,
+ margin: 3,
+ color: '#ff3f19',
+ trackDecimals: 1,
+ sensibility: 2,
+ radius: 5,
+ lineColor: '#cb4b4b'
+ },
+ selection: {
+ mode: null,
+ color: "#97CBFF"
+ },
+ allowDataClick: true,
+ makeRandomColor: false,
+ shadowSize: 4
+ });
+
+ /*
+ * Local variables.
+ */
+ this.canvas = null;
+ this.overlay = null;
+ this.eventHolder = null;
+ this.context = null;
+ this.overlayContext = null;
+
+ this.domObj = $(elem);
+
+ this.xaxis = {};
+ this.yaxis = {};
+ this.chartOffset = {left: 0, right: 0, top: 0, bottom: 0};
+ this.yLabelMaxWidth = 0;
+ this.yLabelMaxHeight = 0;
+ this.xLabelBoxWidth = 0;
+ this.canvasWidth = 0;
+ this.canvasHeight = 0;
+ this.chartWidth = 0;
+ this.chartHeight = 0;
+ this.hozScale = 0;
+ this.vertScale = 0;
+ this.workarounds = {};
+
+ this.domObj = $(elem);
+
+ this.barDataRange = [];
+
+ this.lastMousePos = { pageX: null, pageY: null };
+ this.selection = { first: { x: -1, y: -1}, second: { x: -1, y: -1} };
+ this.prevSelection = null;
+ this.selectionInterval = null;
+ this.ignoreClick = false;
+ this.prevHit = null;
+
+ if(this.options.makeRandomColor)
+ this.options.color = this.makeRandomColor(this.options.colors);
+
+ this.setData(data);
+ this.constructCanvas();
+ this.setupGrid();
+ this.draw();
+ },
+ /**
+ * Private function internally used.
+ */
+ merge: function(src, dest)
+ {
+ var result = dest || {};
+ for(var i in src){
+ result[i] = (typeof(src[i]) == 'object' && !(src[i].constructor == Array || src[i].constructor == RegExp)) ? this.merge(src[i], dest[i]) : result[i] = src[i];
+ }
+ return result;
+ },
+ /**
+ * Function: setData
+ * {Object} data
+ *
+ * Description:
+ * Sets datasoruces properly then sets the Bar Width accordingly, then copies the default data options and then processes the graph data
+ *
+ * Returns: none
+ *
+ */
+ setData: function(data)
+ {
+ this.graphData = this.parseData(data);
+ this.setBarWidth();
+ this.copyGraphDataOptions();
+ this.processGraphData();
+ },
+ /**
+ * Function: parseData
+ * {Object} data
+ *
+ * Return:
+ * {Object} result
+ *
+ * Description:
+ * Takes the provided data object and converts it into generic data that we can understand. User can pass in data in 3 different ways:
+ * - [d1, d2]
+ * - [{data: d1, label: "data1"}, {data: d2, label: "data2"}]
+ * - [d1, {data: d1, label: "data1"}]
+ *
+ * This function parses these senarios and makes it readable
+ */
+ parseData: function(data)
+ {
+ var res = [];
+ data.each(function(d){
+ var s;
+ if(d.data) {
+ s = {};
+ for(var v in d) {
+ s[v] = d[v];
+ }
+ }
+ else {
+ s = {data: d};
+ }
+ res.push(s);
+ }.bind(this));
+ return res;
+ },
+ /**
+ * function: makeRandomColor
+ * {Object} colorSet
+ *
+ * Return:
+ * {Array} result - array containing random colors
+ */
+ makeRandomColor: function(colorSet)
+ {
+ var randNum = Math.floor(Math.random() * colorSet.length);
+ var randArr = [];
+ var newArr = [];
+ randArr.push(randNum);
+
+ while(randArr.length < colorSet.length)
+ {
+ var tempNum = Math.floor(Math.random() * colorSet.length);
+
+ while(checkExisted(tempNum, randArr))
+ tempNum = Math.floor(Math.random() * colorSet.length);
+
+ randArr.push(tempNum);
+ }
+
+ randArr.each(function(ra){
+ newArr.push(colorSet[ra]);
+
+ }.bind(this));
+ return newArr;
+ },
+ /**
+ * function: checkExisted
+ * {Object} needle
+ * {Object} haystack
+ *
+ * return:
+ * {bool} existed - true if it finds needle in the haystack
+ */
+ checkExisted: function(needle, haystack)
+ {
+ var existed = false;
+ haystack.each(function(aNeedle){
+ if(aNeedle == needle) {
+ existed = true;
+ throw $break;
+ }
+ }.bind(this));
+ return existed;
+ },
+ /**
+ * function: setBarWidth
+ *
+ * Description: sets the bar width for Bar Graph, you should enable *autoScale* property for bar graph
+ */
+ setBarWidth: function()
+ {
+ if(this.options.bars.show && this.options.bars.autoScale)
+ {
+ this.options.bars.barWidth = 1 / this.graphData.length / 1.2;
+ }
+ },
+ /**
+ * Function: copyGraphDataOptions
+ *
+ * Description: Private function that goes through each graph data (series) and assigned the graph
+ * properties to it.
+ */
+ copyGraphDataOptions: function()
+ {
+ var i, neededColors = this.graphData.length, usedColors = [], assignedColors = [];
+
+ this.graphData.each(function(gd){
+ var sc = gd.color;
+ if(sc) {
+ --neededColors;
+ if(Object.isNumber(sc)) {
+ assignedColors.push(sc);
+ }
+ else {
+ usedColors.push(this.parseColor(sc));
+ }
+ }
+ }.bind(this));
+
+
+ assignedColors.each(function(ac){
+ neededColors = Math.max(neededColors, ac + 1);
+ });
+
+ var colors = [];
+ var variation = 0;
+ i = 0;
+ while (colors.length < neededColors) {
+ var c;
+ if (this.options.colors.length == i) {
+ c = new Proto.Color(100, 100, 100);
+ }
+ else {
+ c = this.parseColor(this.options.colors[i]);
+ }
+
+ var sign = variation % 2 == 1 ? -1 : 1;
+ var factor = 1 + sign * Math.ceil(variation / 2) * 0.2;
+ c.scale(factor, factor, factor);
+
+ colors.push(c);
+
+ ++i;
+ if (i >= this.options.colors.length) {
+ i = 0;
+ ++variation;
+ }
+ }
+
+ var colorIndex = 0, s;
+
+ this.graphData.each(function(gd){
+ if(gd.color == null)
+ {
+ gd.color = colors[colorIndex].toString();
+ ++colorIndex;
+ }
+ else if(Object.isNumber(gd.color)) {
+ gd.color = colors[gd.color].toString();
+ }
+
+ gd.lines = Object.extend(Object.clone(this.options.lines), gd.lines);
+ gd.points = Object.extend(Object.clone(this.options.points), gd.points);
+ gd.bars = Object.extend(Object.clone(this.options.bars), gd.bars);
+ gd.mouse = Object.extend(Object.clone(this.options.mouse), gd.mouse);
+ if (gd.shadowSize == null) {
+ gd.shadowSize = this.options.shadowSize;
+ }
+ }.bind(this));
+
+ },
+ /**
+ * Function: processGraphData
+ *
+ * Description: processes graph data, setup xaxis and yaxis min and max points.
+ */
+ processGraphData: function() {
+
+ this.xaxis.datamin = this.yaxis.datamin = Number.MAX_VALUE;
+ this.xaxis.datamax = this.yaxis.datamax = Number.MIN_VALUE;
+
+ this.graphData.each(function(gd) {
+ var data = gd.data;
+ data.each(function(d){
+ if(d == null) {
+ return;
+ }
+
+ var x = d[0], y = d[1];
+ if(!x || !y || isNaN(x = +x) || isNaN(y = +y)) {
+ d = null;
+ return;
+ }
+
+ if (x < this.xaxis.datamin)
+ this.xaxis.datamin = x;
+ if (x > this.xaxis.datamax)
+ this.xaxis.datamax = x;
+ if (y < this.yaxis.datamin)
+ this.yaxis.datamin = y;
+ if (y > this.yaxis.datamax)
+ this.yaxis.datamax = y;
+ }.bind(this));
+ }.bind(this));
+
+
+ if (this.xaxis.datamin == Number.MAX_VALUE)
+ this.xaxis.datamin = 0;
+ if (this.yaxis.datamin == Number.MAX_VALUE)
+ this.yaxis.datamin = 0;
+ if (this.xaxis.datamax == Number.MIN_VALUE)
+ this.xaxis.datamax = 1;
+ if (this.yaxis.datamax == Number.MIN_VALUE)
+ this.yaxis.datamax = 1;
+ },
+ /**
+ * Function: constructCanvas
+ *
+ * Description: constructs the main canvas for drawing. It replicates the HTML elem (usually DIV) passed
+ * in via constructor. If there is no height/width assigned to the HTML elem then we take a default size
+ * of 400px (width) and 300px (height)
+ */
+ constructCanvas: function() {
+
+ this.canvasWidth = this.domObj.getWidth();
+ this.canvasHeight = this.domObj.getHeight();
+ this.domObj.update(""); // clear target
+ this.domObj.setStyle({
+ "position": "relative"
+ });
+
+ if (this.canvasWidth <= 0) {
+ this.canvasWdith = 400;
+ }
+ if(this.canvasHeight <= 0) {
+ this.canvasHeight = 300;
+ }
+
+ this.canvas = (Prototype.Browser.IE) ? document.createElement("canvas") : new Element("CANVAS", {'width': this.canvasWidth, 'height': this.canvasHeight});
+ Element.extend(this.canvas);
+ this.canvas.style.width = this.canvasWidth + "px";
+ this.canvas.style.height = this.canvasHeight + "px";
+
+ this.domObj.appendChild(this.canvas);
+
+ if (Prototype.Browser.IE) // excanvas hack
+ {
+ this.canvas = $(window.G_vmlCanvasManager.initElement(this.canvas));
+ }
+ this.canvas = $(this.canvas);
+
+ this.context = this.canvas.getContext("2d");
+
+ this.overlay = (Prototype.Browser.IE) ? document.createElement("canvas") : new Element("CANVAS", {'width': this.canvasWidth, 'height': this.canvasHeight});
+ Element.extend(this.overlay);
+ this.overlay.style.width = this.canvasWidth + "px";
+ this.overlay.style.height = this.canvasHeight + "px";
+ this.overlay.style.position = "absolute";
+ this.overlay.style.left = "0px";
+ this.overlay.style.right = "0px";
+
+ this.overlay.setStyle({
+ 'position': 'absolute',
+ 'left': '0px',
+ 'right': '0px'
+ });
+ this.domObj.appendChild(this.overlay);
+
+ if (Prototype.Browser.IE) {
+ this.overlay = $(window.G_vmlCanvasManager.initElement(this.overlay));
+ }
+
+ this.overlay = $(this.overlay);
+ this.overlayContext = this.overlay.getContext("2d");
+
+ if(this.options.selection.mode)
+ {
+ this.overlay.observe('mousedown', this.onMouseDown.bind(this));
+ this.overlay.observe('mousemove', this.onMouseMove.bind(this));
+ }
+ if(this.options.grid.clickable) {
+ this.overlay.observe('click', this.onClick.bind(this));
+ }
+ if(this.options.mouse.track)
+ {
+ this.overlay.observe('mousemove', this.onMouseMove.bind(this));
+ }
+ },
+ /**
+ * function: setupGrid
+ *
+ * Description: a container function that does a few interesting things.
+ *
+ * 1. calls <extendXRangeIfNeededByBar> function which makes sure that our axis are expanded if needed
+ *
+ * 2. calls <setRange> function providing xaxis options which fixes the ranges according to data points
+ *
+ * 3. calls <prepareTickGeneration> function for xaxis which generates ticks according to options provided by user
+ *
+ * 4. calls <setTicks> function for xaxis that sets the ticks
+ *
+ * similar sequence is called for y-axis.
+ *
+ * At the end if this is a pie chart than we insert Labels (around the pie chart) via <insertLabels> and we also call <insertLegend>
+ */
+ setupGrid: function()
+ {
+ if(this.options.bars.show)
+ {
+ this.xaxis.max += 0.5;
+ this.xaxis.min -= 0.5;
+ }
+ //x-axis
+ this.extendXRangeIfNeededByBar();
+ this.setRange(this.xaxis, this.options.xaxis);
+ this.prepareTickGeneration(this.xaxis, this.options.xaxis);
+ this.setTicks(this.xaxis, this.options.xaxis);
+
+
+ //y-axis
+ this.setRange(this.yaxis, this.options.yaxis);
+ this.prepareTickGeneration(this.yaxis, this.options.yaxis);
+ this.setTicks(this.yaxis, this.options.yaxis);
+ this.setSpacing();
+
+ if(!this.options.pies.show)
+ {
+ this.insertLabels();
+ }
+ this.insertLegend();
+ },
+ /**
+ * function: setRange
+ *
+ * parameters:
+ * {Object} axis
+ * {Object} axisOptions
+ */
+ setRange: function(axis, axisOptions) {
+ var min = axisOptions.min != null ? axisOptions.min : axis.datamin;
+ var max = axisOptions.max != null ? axisOptions.max : axis.datamax;
+
+ if (max - min == 0.0) {
+ // degenerate case
+ var widen;
+ if (max == 0.0)
+ widen = 1.0;
+ else
+ widen = 0.01;
+
+ min -= widen;
+ max += widen;
+ }
+ else {
+ // consider autoscaling
+ var margin = axisOptions.autoscaleMargin;
+ if (margin != null) {
+ if (axisOptions.min == null) {
+ min -= (max - min) * margin;
+ // make sure we don't go below zero if all values
+ // are positive
+ if (min < 0 && axis.datamin >= 0)
+ min = 0;
+ }
+ if (axisOptions.max == null) {
+ max += (max - min) * margin;
+ if (max > 0 && axis.datamax <= 0)
+ max = 0;
+ }
+ }
+ }
+ axis.min = min;
+ axis.max = max;
+ },
+ /**
+ * function: prepareTickGeneration
+ *
+ * Parameters:
+ * {Object} axis
+ * {Object} axisOptions
+ */
+ prepareTickGeneration: function(axis, axisOptions) {
+ // estimate number of ticks
+ var noTicks;
+ if (Object.isNumber(axisOptions.ticks) && axisOptions.ticks > 0)
+ noTicks = axisOptions.ticks;
+ else if (axis == this.xaxis)
+ noTicks = this.canvasWidth / 100;
+ else
+ noTicks = this.canvasHeight / 60;
+
+ var delta = (axis.max - axis.min) / noTicks;
+ var size, generator, unit, formatter, i, magn, norm;
+
+ if (axisOptions.mode == "time") {
+ function formatDate(d, fmt, monthNames) {
+ var leftPad = function(n) {
+ n = "" + n;
+ return n.length == 1 ? "0" + n : n;
+ };
+
+ var r = [];
+ var escape = false;
+ if (monthNames == null)
+ monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+ for (var i = 0; i < fmt.length; ++i) {
+ var c = fmt.charAt(i);
+
+ if (escape) {
+ switch (c) {
+ case 'h': c = "" + d.getHours(); break;
+ case 'H': c = leftPad(d.getHours()); break;
+ case 'M': c = leftPad(d.getMinutes()); break;
+ case 'S': c = leftPad(d.getSeconds()); break;
+ case 'd': c = "" + d.getDate(); break;
+ case 'm': c = "" + (d.getMonth() + 1); break;
+ case 'y': c = "" + d.getFullYear(); break;
+ case 'b': c = "" + monthNames[d.getMonth()]; break;
+ }
+ r.push(c);
+ escape = false;
+ }
+ else {
+ if (c == "%")
+ escape = true;
+ else
+ r.push(c);
+ }
+ }
+ return r.join("");
+ }
+
+
+ // map of app. size of time units in milliseconds
+ var timeUnitSize = {
+ "second": 1000,
+ "minute": 60 * 1000,
+ "hour": 60 * 60 * 1000,
+ "day": 24 * 60 * 60 * 1000,
+ "month": 30 * 24 * 60 * 60 * 1000,
+ "year": 365.2425 * 24 * 60 * 60 * 1000
+ };
+
+
+ // the allowed tick sizes, after 1 year we use
+ // an integer algorithm
+ var spec = [
+ [1, "second"], [2, "second"], [5, "second"], [10, "second"],
+ [30, "second"],
+ [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
+ [30, "minute"],
+ [1, "hour"], [2, "hour"], [4, "hour"],
+ [8, "hour"], [12, "hour"],
+ [1, "day"], [2, "day"], [3, "day"],
+ [0.25, "month"], [0.5, "month"], [1, "month"],
+ [2, "month"], [3, "month"], [6, "month"],
+ [1, "year"]
+ ];
+
+ var minSize = 0;
+ if (axisOptions.minTickSize != null) {
+ if (typeof axisOptions.tickSize == "number")
+ minSize = axisOptions.tickSize;
+ else
+ minSize = axisOptions.minTickSize[0] * timeUnitSize[axisOptions.minTickSize[1]];
+ }
+
+ for (i = 0; i < spec.length - 1; ++i) {
+ if (delta < (spec[i][0] * timeUnitSize[spec[i][1]] + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {
+ break;
+ }
+ }
+
+ size = spec[i][0];
+ unit = spec[i][1];
+
+ // special-case the possibility of several years
+ if (unit == "year") {
+ magn = Math.pow(10, Math.floor(Math.log(delta / timeUnitSize.year) / Math.LN10));
+ norm = (delta / timeUnitSize.year) / magn;
+ if (norm < 1.5)
+ size = 1;
+ else if (norm < 3)
+ size = 2;
+ else if (norm < 7.5)
+ size = 5;
+ else
+ size = 10;
+
+ size *= magn;
+ }
+
+ if (axisOptions.tickSize) {
+ size = axisOptions.tickSize[0];
+ unit = axisOptions.tickSize[1];
+ }
+
+ var floorInBase = this.floorInBase; //gives us a reference to a global function..
+
+ generator = function(axis) {
+ var ticks = [],
+ tickSize = axis.tickSize[0], unit = axis.tickSize[1],
+ d = new Date(axis.min);
+
+ var step = tickSize * timeUnitSize[unit];
+
+
+
+ if (unit == "second")
+ d.setSeconds(floorInBase(d.getSeconds(), tickSize));
+ if (unit == "minute")
+ d.setMinutes(floorInBase(d.getMinutes(), tickSize));
+ if (unit == "hour")
+ d.setHours(floorInBase(d.getHours(), tickSize));
+ if (unit == "month")
+ d.setMonth(floorInBase(d.getMonth(), tickSize));
+ if (unit == "year")
+ d.setFullYear(floorInBase(d.getFullYear(), tickSize));
+
+ // reset smaller components
+ d.setMilliseconds(0);
+ if (step >= timeUnitSize.minute)
+ d.setSeconds(0);
+ if (step >= timeUnitSize.hour)
+ d.setMinutes(0);
+ if (step >= timeUnitSize.day)
+ d.setHours(0);
+ if (step >= timeUnitSize.day * 4)
+ d.setDate(1);
+ if (step >= timeUnitSize.year)
+ d.setMonth(0);
+
+
+ var carry = 0, v;
+ do {
+ v = d.getTime();
+ ticks.push({ v: v, label: axis.tickFormatter(v, axis) });
+ if (unit == "month") {
+ if (tickSize < 1) {
+ d.setDate(1);
+ var start = d.getTime();
+ d.setMonth(d.getMonth() + 1);
+ var end = d.getTime();
+ d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
+ carry = d.getHours();
+ d.setHours(0);
+ }
+ else
+ d.setMonth(d.getMonth() + tickSize);
+ }
+ else if (unit == "year") {
+ d.setFullYear(d.getFullYear() + tickSize);
+ }
+ else
+ d.setTime(v + step);
+ } while (v < axis.max);
+
+ return ticks;
+ };
+
+ formatter = function (v, axis) {
+ var d = new Date(v);
+
+ // first check global format
+ if (axisOptions.timeformat != null)
+ return formatDate(d, axisOptions.timeformat, axisOptions.monthNames);
+
+ var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
+ var span = axis.max - axis.min;
+
+ if (t < timeUnitSize.minute)
+ fmt = "%h:%M:%S";
+ else if (t < timeUnitSize.day) {
+ if (span < 2 * timeUnitSize.day)
+ fmt = "%h:%M";
+ else
+ fmt = "%b %d %h:%M";
+ }
+ else if (t < timeUnitSize.month)
+ fmt = "%b %d";
+ else if (t < timeUnitSize.year) {
+ if (span < timeUnitSize.year)
+ fmt = "%b";
+ else
+ fmt = "%b %y";
+ }
+ else
+ fmt = "%y";
+
+ return formatDate(d, fmt, axisOptions.monthNames);
+ };
+ }
+ else {
+ // pretty rounding of base-10 numbers
+ var maxDec = axisOptions.tickDecimals;
+ var dec = -Math.floor(Math.log(delta) / Math.LN10);
+ if (maxDec != null && dec > maxDec)
+ dec = maxDec;
+
+ magn = Math.pow(10, -dec);
+ norm = delta / magn; // norm is between 1.0 and 10.0
+
+ if (norm < 1.5)
+ size = 1;
+ else if (norm < 3) {
+ size = 2;
+ // special case for 2.5, requires an extra decimal
+ if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
+ size = 2.5;
+ ++dec;
+ }
+ }
+ else if (norm < 7.5)
+ size = 5;
+ else
+ size = 10;
+
+ size *= magn;
+
+ if (axisOptions.minTickSize != null && size < axisOptions.minTickSize)
+ size = axisOptions.minTickSize;
+
+ if (axisOptions.tickSize != null)
+ size = axisOptions.tickSize;
+
+ axis.tickDecimals = Math.max(0, (maxDec != null) ? maxDec : dec);
+
+ var floorInBase = this.floorInBase;
+
+ generator = function (axis) {
+ var ticks = [];
+ var start = floorInBase(axis.min, axis.tickSize);
+ // then spew out all possible ticks
+ var i = 0, v;
+ do {
+ v = start + i * axis.tickSize;
+ ticks.push({ v: v, label: axis.tickFormatter(v, axis) });
+ ++i;
+ } while (v < axis.max);
+ return ticks;
+ };
+
+ formatter = function (v, axis) {
+ if(v) {
+ return v.toFixed(axis.tickDecimals);
+ }
+ return 0;
+ };
+ }
+
+ axis.tickSize = unit ? [size, unit] : size;
+ axis.tickGenerator = generator;
+ if (Object.isFunction(axisOptions.tickFormatter))
+ axis.tickFormatter = function (v, axis) { return "" + axisOptions.tickFormatter(v, axis); };
+ else
+ axis.tickFormatter = formatter;
+ },
+ /**
+ * function: extendXRangeIfNeededByBar
+ */
+ extendXRangeIfNeededByBar: function() {
+
+ if (this.options.xaxis.max == null) {
+ // great, we're autoscaling, check if we might need a bump
+ var newmax = this.xaxis.max;
+ this.graphData.each(function(gd){
+ if(gd.bars.show && gd.bars.barWidth + this.xaxis.datamax > newmax)
+ {
+ newmax = this.xaxis.datamax + gd.bars.barWidth;
+ }
+ }.bind(this));
+ this.xaxis.nax = newmax;
+
+ }
+ },
+ /**
+ * function: setTicks
+ *
+ * parameters:
+ * {Object} axis
+ * {Object} axisOptions
+ */
+ setTicks: function(axis, axisOptions) {
+ axis.ticks = [];
+
+ if (axisOptions.ticks == null)
+ axis.ticks = axis.tickGenerator(axis);
+ else if (typeof axisOptions.ticks == "number") {
+ if (axisOptions.ticks > 0)
+ axis.ticks = axis.tickGenerator(axis);
+ }
+ else if (axisOptions.ticks) {
+ var ticks = axisOptions.ticks;
+
+ if (Object.isFunction(ticks))
+ // generate the ticks
+ ticks = ticks({ min: axis.min, max: axis.max });
+
+ // clean up the user-supplied ticks, copy them over
+ //var i, v;
+ ticks.each(function(t, i){
+ var v = null;
+ var label = null;
+ if(typeof t == 'object') {
+ v = t[0];
+ if(t.length > 1) { label = t[1]; }
+ }
+ else {
+ v = t;
+ }
+ if(!label) {
+ label = axis.tickFormatter(v, axis);
+ }
+ axis.ticks[i] = {v: v, label: label}
+ }.bind(this));
+
+ }
+
+ if (axisOptions.autoscaleMargin != null && axis.ticks.length > 0) {
+ if (axisOptions.min == null)
+ axis.min = Math.min(axis.min, axis.ticks[0].v);
+ if (axisOptions.max == null && axis.ticks.length > 1)
+ axis.max = Math.min(axis.max, axis.ticks[axis.ticks.length - 1].v);
+ }
+ },
+ /**
+ * Function: setSpacing
+ *
+ * Parameters: none
+ */
+ setSpacing: function() {
+ // calculate y label dimensions
+ var i, labels = [], l;
+ for (i = 0; i < this.yaxis.ticks.length; ++i) {
+ l = this.yaxis.ticks[i].label;
+
+ if (l)
+ labels.push('<div class="tickLabel">' + l + '</div>');
+ }
+
+ if (labels.length > 0) {
+ var dummyDiv = new Element('div', {'style': 'position:absolute;top:-10000px;font-size:smaller'});
+ dummyDiv.update(labels.join(""));
+ this.domObj.insert(dummyDiv);
+ this.yLabelMaxWidth = dummyDiv.getWidth();
+ this.yLabelMaxHeight = dummyDiv.select('div')[0].getHeight();
+ dummyDiv.remove();
+ }
+
+ var maxOutset = this.options.grid.borderWidth;
+ if (this.options.points.show)
+ maxOutset = Math.max(maxOutset, this.options.points.radius + this.options.points.lineWidth/2);
+ for (i = 0; i < this.graphData.length; ++i) {
+ if (this.graphData[i].points.show)
+ maxOutset = Math.max(maxOutset, this.graphData[i].points.radius + this.graphData[i].points.lineWidth/2);
+ }
+
+ this.chartOffset.left = this.chartOffset.right = this.chartOffset.top = this.chartOffset.bottom = maxOutset;
+
+ this.chartOffset.left += this.yLabelMaxWidth + this.options.grid.labelMargin;
+ this.chartWidth = this.canvasWidth - this.chartOffset.left - this.chartOffset.right;
+
+ this.xLabelBoxWidth = this.chartWidth / 6;
+ labels = [];
+
+ for (i = 0; i < this.xaxis.ticks.length; ++i) {
+ l = this.xaxis.ticks[i].label;
+ if (l) {
+ labels.push('<span class="tickLabel" width="' + this.xLabelBoxWidth + '">' + l + '</span>');
+ }
+ }
+
+ var xLabelMaxHeight = 0;
+ if (labels.length > 0) {
+ var dummyDiv = new Element('div', {'style': 'position:absolute;top:-10000px;font-size:smaller'});
+ dummyDiv.update(labels.join(""));
+ this.domObj.appendChild(dummyDiv);
+ xLabelMaxHeight = dummyDiv.getHeight();
+ dummyDiv.remove();
+ }
+
+ this.chartOffset.bottom += xLabelMaxHeight + this.options.grid.labelMargin;
+ this.chartHeight = this.canvasHeight - this.chartOffset.bottom - this.chartOffset.top;
+ this.hozScale = this.chartWidth / (this.xaxis.max - this.xaxis.min);
+ this.vertScale = this.chartHeight / (this.yaxis.max - this.yaxis.min);
+ },
+ /**
+ * function: draw
+ */
+ draw: function() {
+ if(this.options.bars.show)
+ {
+ this.extendXRangeIfNeededByBar();
+ this.setSpacing();
+ this.drawGrid();
+ this.drawBarGraph(this.graphData, this.barDataRange);
+ }
+ else if(this.options.pies.show)
+ {
+ this.preparePieData(this.graphData);
+ this.drawPieGraph(this.graphData);
+ }
+ else
+ {
+ this.drawGrid();
+ for (var i = 0; i < this.graphData.length; i++) {
+ this.drawGraph(this.graphData[i]);
+ }
+ }
+ },
+ /**
+ * function: translateHoz
+ *
+ * Paramters:
+ * {Object} x
+ *
+ * Description: Given a value this function translate it to relative x coord on canvas
+ */
+ translateHoz: function(x) {
+ return (x - this.xaxis.min) * this.hozScale;
+ },
+ /**
+ * function: translateVert
+ *
+ * parameters:
+ * {Object} y
+ *
+ * Description: Given a value this function translate it to relative y coord on canvas
+ */
+ translateVert: function(y) {
+ return this.chartHeight - (y - this.yaxis.min) * this.vertScale;
+ },
+ /**
+ * function: drawGrid
+ *
+ * parameters: none
+ *
+ * description: draws the actual grid on the canvas
+ */
+ drawGrid: function() {
+ var i;
+
+ this.context.save();
+ this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+ this.context.translate(this.chartOffset.left, this.chartOffset.top);
+
+ // draw background, if any
+ if (this.options.grid.backgroundColor != null) {
+ this.context.fillStyle = this.options.grid.backgroundColor;
+ this.context.fillRect(0, 0, this.chartWidth, this.chartHeight);
+ }
+
+ // draw colored areas
+ if (this.options.grid.coloredAreas) {
+ var areas = this.options.grid.coloredAreas;
+ if (Object.isFunction(areas)) {
+ areas = areas({ xmin: this.xaxis.min, xmax: this.xaxis.max, ymin: this.yaxis.min, ymax: this.yaxis.max });
+ }
+
+ areas.each(function(a){
+ // clip
+ if (a.x1 == null || a.x1 < this.xaxis.min)
+ a.x1 = this.xaxis.min;
+ if (a.x2 == null || a.x2 > this.xaxis.max)
+ a.x2 = this.xaxis.max;
+ if (a.y1 == null || a.y1 < this.yaxis.min)
+ a.y1 = this.yaxis.min;
+ if (a.y2 == null || a.y2 > this.yaxis.max)
+ a.y2 = this.yaxis.max;
+
+ var tmp;
+ if (a.x1 > a.x2) {
+ tmp = a.x1;
+ a.x1 = a.x2;
+ a.x2 = tmp;
+ }
+ if (a.y1 > a.y2) {
+ tmp = a.y1;
+ a.y1 = a.y2;
+ a.y2 = tmp;
+ }
+
+ if (a.x1 >= this.xaxis.max || a.x2 <= this.xaxis.min || a.x1 == a.x2
+ || a.y1 >= this.yaxis.max || a.y2 <= this.yaxis.min || a.y1 == a.y2)
+ return;
+
+ this.context.fillStyle = a.color || this.options.grid.coloredAreasColor;
+ this.context.fillRect(Math.floor(this.translateHoz(a.x1)), Math.floor(this.translateVert(a.y2)),
+ Math.floor(this.translateHoz(a.x2) - this.translateHoz(a.x1)), Math.floor(this.translateVert(a.y1) - this.translateVert(a.y2)));
+ }.bind(this));
+
+
+ }
+
+ // draw the inner grid
+ this.context.lineWidth = 1;
+ this.context.strokeStyle = this.options.grid.tickColor;
+ this.context.beginPath();
+ var v;
+ if (this.options.grid.drawXAxis) {
+ this.xaxis.ticks.each(function(aTick){
+ v = aTick.v;
+ if(v <= this.xaxis.min || v >= this.xaxis.max) {
+ return;
+ }
+ this.context.moveTo(Math.floor(this.translateHoz(v)) + this.context.lineWidth / 2, 0);
+ this.context.lineTo(Math.floor(this.translateHoz(v)) + this.context.lineWidth / 2, this.chartHeight);
+ }.bind(this));
+
+ }
+
+ if (this.options.grid.drawYAxis) {
+ this.yaxis.ticks.each(function(aTick){
+ v = aTick.v;
+ if(v <= this.yaxis.min || v >= this.yaxis.max) {
+ return;
+ }
+ this.context.moveTo(0, Math.floor(this.translateVert(v)) + this.context.lineWidth / 2);
+ this.context.lineTo(this.chartWidth, Math.floor(this.translateVert(v)) + this.context.lineWidth / 2);
+ }.bind(this));
+
+ }
+ this.context.stroke();
+
+ if (this.options.grid.borderWidth) {
+ // draw border
+ this.context.lineWidth = this.options.grid.borderWidth;
+ this.context.strokeStyle = this.options.grid.color;
+ this.context.lineJoin = "round";
+ this.context.strokeRect(0, 0, this.chartWidth, this.chartHeight);
+ this.context.restore();
+ }
+ },
+ /**
+ * function: insertLabels
+ *
+ * parameters: none
+ *
+ * description: inserts the label with proper spacing. Both on X and Y axis
+ */
+ insertLabels: function() {
+ this.domObj.select(".tickLabels").invoke('remove');
+
+ var i, tick;
+ var html = '<div class="tickLabels" style="font-size:smaller;color:' + this.options.grid.color + '">';
+
+ // do the x-axis
+ this.xaxis.ticks.each(function(tick){
+ if (!tick.label || tick.v < this.xaxis.min || tick.v > this.xaxis.max)
+ return;
+ html += '<div style="position:absolute;top:' + (this.chartOffset.top + this.chartHeight + this.options.grid.labelMargin) + 'px;left:' + (this.chartOffset.left + this.translateHoz(tick.v) - this.xLabelBoxWidth/2) + 'px;width:' + this.xLabelBoxWidth + 'px;text-align:center" class="tickLabel">' + tick.label + "</div>";
+
+ }.bind(this));
+
+ // do the y-axis
+ this.yaxis.ticks.each(function(tick){
+ if (!tick.label || tick.v < this.yaxis.min || tick.v > this.yaxis.max)
+ return;
+ html += '<div id="ylabels" style="position:absolute;top:' + (this.chartOffset.top + this.translateVert(tick.v) - this.yLabelMaxHeight/2) + 'px;left:0;width:' + this.yLabelMaxWidth + 'px;text-align:right" class="tickLabel">' + tick.label + "</div>";
+ }.bind(this));
+
+ html += '</div>';
+
+ this.domObj.insert(html);
+ },
+ /**
+ * function: drawGraph
+ *
+ * Paramters:
+ * {Object} graphData
+ *
+ * Description: given a graphData (series) this function calls a proper lower level method to draw it.
+ */
+ drawGraph: function(graphData) {
+ if (graphData.lines.show || (!graphData.bars.show && !graphData.points.show))
+ this.drawGraphLines(graphData);
+ if (graphData.bars.show)
+ this.drawGraphBar(graphData);
+ if (graphData.points.show)
+ this.drawGraphPoints(graphData);
+ },
+ /**
+ * function: plotLine
+ *
+ * parameters:
+ * {Object} data
+ * {Object} offset
+ *
+ * description:
+ * Helper function that plots a line based on the data provided
+ */
+ plotLine: function(data, offset) {
+ var prev, cur = null, drawx = null, drawy = null;
+
+ this.context.beginPath();
+ for (var i = 0; i < data.length; ++i) {
+ prev = cur;
+ cur = data[i];
+
+ if (prev == null || cur == null)
+ continue;
+
+ var x1 = prev[0], y1 = prev[1],
+ x2 = cur[0], y2 = cur[1];
+
+ // clip with ymin
+ if (y1 <= y2 && y1 < this.yaxis.min) {
+ if (y2 < this.yaxis.min)
+ continue; // line segment is outside
+ // compute new intersection point
+ x1 = (this.yaxis.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = this.yaxis.min;
+ }
+ else if (y2 <= y1 && y2 < this.yaxis.min) {
+ if (y1 < this.yaxis.min)
+ continue;
+ x2 = (this.yaxis.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = this.yaxis.min;
+ }
+
+ // clip with ymax
+ if (y1 >= y2 && y1 > this.yaxis.max) {
+ if (y2 > this.yaxis.max)
+ continue;
+ x1 = (this.yaxis.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = this.yaxis.max;
+ }
+ else if (y2 >= y1 && y2 > this.yaxis.max) {
+ if (y1 > this.yaxis.max)
+ continue;
+ x2 = (this.yaxis.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = this.yaxis.max;
+ }
+
+ // clip with xmin
+ if (x1 <= x2 && x1 < this.xaxis.min) {
+ if (x2 < this.xaxis.min)
+ continue;
+ y1 = (this.xaxis.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = this.xaxis.min;
+ }
+ else if (x2 <= x1 && x2 < this.xaxis.min) {
+ if (x1 < this.xaxis.min)
+ continue;
+ y2 = (this.xaxis.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = this.xaxis.min;
+ }
+
+ // clip with xmax
+ if (x1 >= x2 && x1 > this.xaxis.max) {
+ if (x2 > this.xaxis.max)
+ continue;
+ y1 = (this.xaxis.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = this.xaxis.max;
+ }
+ else if (x2 >= x1 && x2 > this.xaxis.max) {
+ if (x1 > this.xaxis.max)
+ continue;
+ y2 = (this.xaxis.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = this.xaxis.max;
+ }
+
+ if (drawx != this.translateHoz(x1) || drawy != this.translateVert(y1) + offset)
+ this.context.moveTo(this.translateHoz(x1), this.translateVert(y1) + offset);
+
+ drawx = this.translateHoz(x2);
+ drawy = this.translateVert(y2) + offset;
+ this.context.lineTo(drawx, drawy);
+ }
+ this.context.stroke();
+ },
+ /**
+ * function: plotLineArea
+ *
+ * parameters:
+ * {Object} data
+ *
+ * description:
+ * Helper functoin that plots a colored line graph. This function
+ * takes the data nad then fill in the area on the graph properly
+ */
+ plotLineArea: function(data) {
+ var prev, cur = null;
+
+ var bottom = Math.min(Math.max(0, this.yaxis.min), this.yaxis.max);
+ var top, lastX = 0;
+
+ var areaOpen = false;
+
+ for (var i = 0; i < data.length; ++i) {
+ prev = cur;
+ cur = data[i];
+
+ if (areaOpen && prev != null && cur == null) {
+ // close area
+ this.context.lineTo(this.translateHoz(lastX), this.translateVert(bottom));
+ this.context.fill();
+ areaOpen = false;
+ continue;
+ }
+
+ if (prev == null || cur == null)
+ continue;
+
+ var x1 = prev[0], y1 = prev[1],
+ x2 = cur[0], y2 = cur[1];
+
+ // clip x values
+
+ // clip with xmin
+ if (x1 <= x2 && x1 < this.xaxis.min) {
+ if (x2 < this.xaxis.min)
+ continue;
+ y1 = (this.xaxis.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = this.xaxis.min;
+ }
+ else if (x2 <= x1 && x2 < this.xaxis.min) {
+ if (x1 < this.xaxis.min)
+ continue;
+ y2 = (this.xaxis.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = this.xaxis.min;
+ }
+
+ // clip with xmax
+ if (x1 >= x2 && x1 > this.xaxis.max) {
+ if (x2 > this.xaxis.max)
+ continue;
+ y1 = (this.xaxis.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = this.xaxis.max;
+ }
+ else if (x2 >= x1 && x2 > this.xaxis.max) {
+ if (x1 > this.xaxis.max)
+ continue;
+ y2 = (this.xaxis.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = this.xaxis.max;
+ }
+
+ if (!areaOpen) {
+ // open area
+ this.context.beginPath();
+ this.context.moveTo(this.translateHoz(x1), this.translateVert(bottom));
+ areaOpen = true;
+ }
+
+ // now first check the case where both is outside
+ if (y1 >= this.yaxis.max && y2 >= this.yaxis.max) {
+ this.context.lineTo(this.translateHoz(x1), this.translateVert(this.yaxis.max));
+ this.context.lineTo(this.translateHoz(x2), this.translateVert(this.yaxis.max));
+ continue;
+ }
+ else if (y1 <= this.yaxis.min && y2 <= this.yaxis.min) {
+ this.context.lineTo(this.translateHoz(x1), this.translateVert(this.yaxis.min));
+ this.context.lineTo(this.translateHoz(x2), this.translateVert(this.yaxis.min));
+ continue;
+ }
+
+ var x1old = x1, x2old = x2;
+
+ // clip with ymin
+ if (y1 <= y2 && y1 < this.yaxis.min && y2 >= this.yaxis.min) {
+ x1 = (this.yaxis.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = this.yaxis.min;
+ }
+ else if (y2 <= y1 && y2 < this.yaxis.min && y1 >= this.yaxis.min) {
+ x2 = (this.yaxis.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = this.yaxis.min;
+ }
+
+ // clip with ymax
+ if (y1 >= y2 && y1 > this.yaxis.max && y2 <= this.yaxis.max) {
+ x1 = (this.yaxis.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = this.yaxis.max;
+ }
+ else if (y2 >= y1 && y2 > this.yaxis.max && y1 <= this.yaxis.max) {
+ x2 = (this.yaxis.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = this.yaxis.max;
+ }
+
+
+ // if the x value was changed we got a rectangle
+ // to fill
+ if (x1 != x1old) {
+ if (y1 <= this.yaxis.min)
+ top = this.yaxis.min;
+ else
+ top = this.yaxis.max;
+
+ this.context.lineTo(this.translateHoz(x1old), this.translateVert(top));
+ this.context.lineTo(this.translateHoz(x1), this.translateVert(top));
+ }
+
+ // fill the triangles
+ this.context.lineTo(this.translateHoz(x1), this.translateVert(y1));
+ this.context.lineTo(this.translateHoz(x2), this.translateVert(y2));
+
+ // fill the other rectangle if it's there
+ if (x2 != x2old) {
+ if (y2 <= this.yaxis.min)
+ top = this.yaxis.min;
+ else
+ top = this.yaxis.max;
+
+ this.context.lineTo(this.translateHoz(x2old), this.translateVert(top));
+ this.context.lineTo(this.translateHoz(x2), this.translateVert(top));
+ }
+
+ lastX = Math.max(x2, x2old);
+ }
+
+ if (areaOpen) {
+ this.context.lineTo(this.translateHoz(lastX), this.translateVert(bottom));
+ this.context.fill();
+ }
+ },
+ /**
+ * function: drawGraphLines
+ *
+ * parameters:
+ * {Object} graphData
+ *
+ * description:
+ * Main function that daws the line graph. This function is called
+ * if <options> lines property is set to show or no other type of
+ * graph is specified. This function depends on <plotLineArea> and
+ * <plotLine> functions.
+ */
+ drawGraphLines: function(graphData) {
+ this.context.save();
+ this.context.translate(this.chartOffset.left, this.chartOffset.top);
+ this.context.lineJoin = "round";
+
+ var lw = graphData.lines.lineWidth;
+ var sw = graphData.shadowSize;
+ // FIXME: consider another form of shadow when filling is turned on
+ if (sw > 0) {
+ // draw shadow in two steps
+ this.context.lineWidth = sw / 2;
+ this.context.strokeStyle = "rgba(0,0,0,0.1)";
+ this.plotLine(graphData.data, lw/2 + sw/2 + this.context.lineWidth/2);
+
+ this.context.lineWidth = sw / 2;
+ this.context.strokeStyle = "rgba(0,0,0,0.2)";
+ this.plotLine(graphData.data, lw/2 + this.context.lineWidth/2);
+ }
+
+ this.context.lineWidth = lw;
+ this.context.strokeStyle = graphData.color;
+ if (graphData.lines.fill) {
+ this.context.fillStyle = graphData.lines.fillColor != null ? graphData.lines.fillColor : this.parseColor(graphData.color).scale(null, null, null, 0.4).toString();
+ this.plotLineArea(graphData.data, 0);
+ }
+
+ this.plotLine(graphData.data, 0);
+ this.context.restore();
+ },
+ /**
+ * function: plotPoints
+ *
+ * parameters:
+ * {Object} data
+ * {Object} radius
+ * {Object} fill
+ *
+ * description:
+ * Helper function that draws the point graph according to the data provided. Size of each
+ * point is provided by radius variable and fill specifies if points
+ * are filled
+ */
+ plotPoints: function(data, radius, fill) {
+ for (var i = 0; i < data.length; ++i) {
+ if (data[i] == null)
+ continue;
+
+ var x = data[i][0], y = data[i][1];
+ if (x < this.xaxis.min || x > this.xaxis.max || y < this.yaxis.min || y > this.yaxis.max)
+ continue;
+
+ this.context.beginPath();
+ this.context.arc(this.translateHoz(x), this.translateVert(y), radius, 0, 2 * Math.PI, true);
+ if (fill)
+ this.context.fill();
+ this.context.stroke();
+ }
+ },
+ /**
+ * function: plotPointShadows
+ *
+ * parameters:
+ * {Object} data
+ * {Object} offset
+ * {Object} radius
+ *
+ * description:
+ * Helper function that draws the shadows for the points.
+ */
+ plotPointShadows: function(data, offset, radius) {
+ for (var i = 0; i < data.length; ++i) {
+ if (data[i] == null)
+ continue;
+
+ var x = data[i][0], y = data[i][1];
+ if (x < this.xaxis.min || x > this.xaxis.max || y < this.yaxis.min || y > this.yaxis.max)
+ continue;
+ this.context.beginPath();
+ this.context.arc(this.translateHoz(x), this.translateVert(y) + offset, radius, 0, Math.PI, false);
+ this.context.stroke();
+ }
+ },
+ /**
+ * function: drawGraphPoints
+ *
+ * paramters:
+ * {Object} graphData
+ *
+ * description:
+ * Draws the point graph onto the canvas. This function depends on helper
+ * functions <plotPointShadows> and <plotPoints>
+ */
+ drawGraphPoints: function(graphData) {
+ this.context.save();
+ this.context.translate(this.chartOffset.left, this.chartOffset.top);
+
+ var lw = graphData.lines.lineWidth;
+ var sw = graphData.shadowSize;
+ if (sw > 0) {
+ // draw shadow in two steps
+ this.context.lineWidth = sw / 2;
+ this.context.strokeStyle = "rgba(0,0,0,0.1)";
+ this.plotPointShadows(graphData.data, sw/2 + this.context.lineWidth/2, graphData.points.radius);
+
+ this.context.lineWidth = sw / 2;
+ this.context.strokeStyle = "rgba(0,0,0,0.2)";
+ this.plotPointShadows(graphData.data, this.context.lineWidth/2, graphData.points.radius);
+ }
+
+ this.context.lineWidth = graphData.points.lineWidth;
+ this.context.strokeStyle = graphData.color;
+ this.context.fillStyle = graphData.points.fillColor != null ? graphData.points.fillColor : graphData.color;
+ this.plotPoints(graphData.data, graphData.points.radius, graphData.points.fill);
+ this.context.restore();
+ },
+ /**
+ * function: preparePieData
+ *
+ * parameters:
+ * {Object} graphData
+ *
+ * Description:
+ * Helper function that manipulates the given data stream so that it can
+ * be plotted as a Pie Chart
+ */
+ preparePieData: function(graphData)
+ {
+ for(i = 0; i < graphData.length; i++)
+ {
+ var data = 0;
+ for(j = 0; j < graphData[i].data.length; j++){
+ data += parseInt(graphData[i].data[j][1]);
+ }
+ graphData[i].data = data;
+ }
+ },
+ /**
+ * function: drawPieShadow
+ *
+ * {Object} anchorX
+ * {Object} anchorY
+ * {Object} radius
+ *
+ * description:
+ * Helper function that draws a shadow for the Pie Chart. This just draws
+ * a circle with offset that simulates shadow. We do not give each piece
+ * of the pie an individual shadow.
+ */
+ drawPieShadow: function(anchorX, anchorY, radius)
+ {
+ this.context.beginPath();
+ this.context.moveTo(anchorX, anchorY);
+ this.context.fillStyle = 'rgba(0,0,0,' + 0.1 + ')';
+ startAngle = 0;
+ endAngle = (Math.PI/180)*360;
+ this.context.arc(anchorX + 2, anchorY +2, radius + (this.options.shadowSize/2), startAngle, endAngle, false);
+ this.context.fill();
+ this.context.closePath();
+ },
+ /**
+ * function: drawPieGraph
+ *
+ * parameters:
+ * {Object} graphData
+ *
+ * description:
+ * Draws the actual pie chart. This function depends on helper function
+ * <drawPieShadow> to draw the actual shadow
+ */
+ drawPieGraph: function(graphData)
+ {
+ var sumData = 0;
+ var radius = 0;
+ var centerX = this.chartWidth/2;
+ var centerY = this.chartHeight/2;
+ var startAngle = 0;
+ var endAngle = 0;
+ var fontSize = this.options.pies.fontSize;
+ var labelWidth = this.options.pies.labelWidth;
+
+ //determine Pie Radius
+ if(!this.options.pies.autoScale)
+ radius = this.options.pies.radius;
+ else
+ radius = (this.chartHeight * 0.85)/2;
+
+ var labelRadius = radius * 1.05;
+
+ for(i = 0; i < graphData.length; i++)
+ sumData += graphData[i].data;
+
+ // used to adjust labels so that everything adds up to 100%
+ totalPct = 0;
+
+ //lets draw the shadow first.. we don't need an individual shadow to every pie rather we just
+ //draw a circle underneath to simulate the shadow...
+ this.drawPieShadow(centerX, centerY, radius, 0, 0);
+
+ //lets draw the actual pie chart now.
+ graphData.each(function(gd, j){
+ var pct = gd.data / sumData;
+ startAngle = endAngle;
+ endAngle += pct * (2 * Math.PI);
+ var sliceMiddle = (endAngle - startAngle) / 2 + startAngle;
+ var labelX = centerX + Math.cos(sliceMiddle) * labelRadius;
+ var labelY = centerY + Math.sin(sliceMiddle) * labelRadius;
+ var anchorX = centerX;
+ var anchorY = centerY;
+ var textAlign = null;
+ var verticalAlign = null;
+ var left = 0;
+ var top = 0;
+
+ //draw pie:
+ //drawing pie
+ this.context.beginPath();
+ this.context.moveTo(anchorX, anchorY);
+ this.context.arc(anchorX, anchorY, radius, startAngle, endAngle, false);
+ this.context.closePath();
+ this.context.fillStyle = this.parseColor(gd.color).scale(null, null, null, this.options.pies.fillOpacity).toString();
+
+ if(this.options.pies.fill) { this.context.fill(); }
+
+ // drawing labels
+ if (sliceMiddle <= 0.25 * (2 * Math.PI))
+ {
+ // text on top and align left
+ textAlign = "left";
+ verticalAlign = "top";
+ left = labelX;
+ top = labelY + fontSize;
+ }
+ else if (sliceMiddle > 0.25 * (2 * Math.PI) && sliceMiddle <= 0.5 * (2 * Math.PI))
+ {
+ // text on bottom and align left
+ textAlign = "left";
+ verticalAlign = "bottom";
+ left = labelX - labelWidth;
+ top = labelY;
+ }
+ else if (sliceMiddle > 0.5 * (2 * Math.PI) && sliceMiddle <= 0.75 * (2 * Math.PI))
+ {
+ // text on bottom and align right
+ textAlign = "right";
+ verticalAlign = "bottom";
+ left = labelX - labelWidth;
+ top = labelY - fontSize;
+ }
+ else
+ {
+ // text on top and align right
+ textAlign = "right";
+ verticalAlign = "bottom";
+ left = labelX;
+ top = labelY - fontSize;
+ }
+
+ left = left + "px";
+ top = top + "px";
+ var textVal = Math.round(pct * 100);
+
+ if (j == graphData.length - 1) {
+ if (textVal + totalPct < 100) {
+ textVal = textVal + 1;
+ } else if (textVal + totalPct > 100) {
+ textVal = textVal - 1;
+ };
+ }
+
+ var html = "<div style=\"position: absolute;zindex:11; width:" + labelWidth + "px;fontSize:" + fontSize + "px;overflow:hidden;top:"+ top + ";left:"+ left + ";textAlign:" + textAlign + ";verticalAlign:" + verticalAlign +"\">" + textVal + "%</div>";
+ //$(html).appendTo(target);
+ this.domObj.insert(html);
+
+ totalPct = totalPct + textVal;
+ }.bind(this));
+
+ },
+ /**
+ * function: drawBarGraph
+ *
+ * parameters:
+ * {Object} graphData
+ * {Object} barDataRange
+ *
+ * description:
+ * Goes through each series in graphdata and passes it onto <drawBarGraphs> function
+ */
+ drawBarGraph: function(graphData, barDataRange)
+ {
+ graphData.each(function(gd, i){
+ this.drawGraphBars(gd, i, graphData.size(), barDataRange);
+ }.bind(this));
+ },
+ /**
+ * function: drawGraphBar
+ *
+ * parameters:
+ * {Object} graphData
+ *
+ * description:
+ * This function is called when an individual series in GraphData is bar graph and plots it
+ */
+ drawGraphBar: function(graphData)
+ {
+ this.drawGraphBars(graphData, 0, this.graphData.length, this.barDataRange);
+ },
+ /**
+ * function: plotBars
+ *
+ * parameters:
+ * {Object} graphData
+ * {Object} data
+ * {Object} barWidth
+ * {Object} offset
+ * {Object} fill
+ * {Object} counter
+ * {Object} total
+ * {Object} barDataRange
+ *
+ * description:
+ * Helper function that draws the bar graph based on data.
+ */
+ plotBars: function(graphData, data, barWidth, offset, fill,counter, total, barDataRange) {
+ var shift = 0;
+
+ if(total % 2 == 0)
+ {
+ shift = (1 + ((counter - total /2 ) - 1)) * barWidth;
+ }
+ else
+ {
+ var interval = 0.5;
+ if(counter == (total/2 - interval )) {
+ shift = - barWidth * interval;
+ }
+ else {
+ shift = (interval + (counter - Math.round(total/2))) * barWidth;
+ }
+ }
+
+ var rangeData = [];
+ data.each(function(d){
+ if(!d) return;
+
+ var x = d[0], y = d[1];
+ var drawLeft = true, drawTop = true, drawRight = true;
+ var left = x + shift, right = x + barWidth + shift, bottom = 0, top = y;
+ var rangeDataPoint = {};
+ rangeDataPoint.left = left;
+ rangeDataPoint.right = right;
+ rangeDataPoint.value = top;
+ rangeData.push(rangeDataPoint);
+
+ if (right < this.xaxis.min || left > this.xaxis.max || top < this.yaxis.min || bottom > this.yaxis.max)
+ return;
+
+ // clip
+ if (left < this.xaxis.min) {
+ left = this.xaxis.min;
+ drawLeft = false;
+ }
+
+ if (right > this.xaxis.max) {
+ right = this.xaxis.max;
+ drawRight = false;
+ }
+
+ if (bottom < this.yaxis.min)
+ bottom = this.yaxis.min;
+
+ if (top > this.yaxis.max) {
+ top = this.yaxis.max;
+ drawTop = false;
+ }
+
+ if(graphData.bars.showShadow && graphData.shadowSize > 0)
+ this.plotShadowOutline(graphData, this.context.strokeStyle, left, bottom, top, right, drawLeft, drawRight, drawTop);
+
+ // fill the bar
+ if (fill) {
+ this.context.beginPath();
+ this.context.moveTo(this.translateHoz(left), this.translateVert(bottom) + offset);
+ this.context.lineTo(this.translateHoz(left), this.translateVert(top) + offset);
+ this.context.lineTo(this.translateHoz(right), this.translateVert(top) + offset);
+ this.context.lineTo(this.translateHoz(right), this.translateVert(bottom) + offset);
+ this.context.fill();
+ }
+
+ // draw outline
+ if (drawLeft || drawRight || drawTop) {
+ this.context.beginPath();
+ this.context.moveTo(this.translateHoz(left), this.translateVert(bottom) + offset);
+ if (drawLeft)
+ this.context.lineTo(this.translateHoz(left), this.translateVert(top) + offset);
+ else
+ this.context.moveTo(this.translateHoz(left), this.translateVert(top) + offset);
+
+ if (drawTop)
+ this.context.lineTo(this.translateHoz(right), this.translateVert(top) + offset);
+ else
+ this.context.moveTo(this.translateHoz(right), this.translateVert(top) + offset);
+ if (drawRight)
+ this.context.lineTo(this.translateHoz(right), this.translateVert(bottom) + offset);
+ else
+ this.context.moveTo(this.translateHoz(right), this.translateVert(bottom) + offset);
+ this.context.stroke();
+ }
+ }.bind(this));
+
+ barDataRange.push(rangeData);
+ },
+ /**
+ * function: plotShadowOutline
+ *
+ * parameters:
+ * {Object} graphData
+ * {Object} orgStrokeStyle
+ * {Object} left
+ * {Object} bottom
+ * {Object} top
+ * {Object} right
+ * {Object} drawLeft
+ * {Object} drawRight
+ * {Object} drawTop
+ *
+ * description:
+ * Helper function that draws a outline simulating shadow for bar chart
+ */
+ plotShadowOutline: function(graphData, orgStrokeStyle, left, bottom, top, right, drawLeft, drawRight, drawTop)
+ {
+ var orgOpac = 0.3;
+
+ for(var n = 1; n <= this.options.shadowSize/2; n++)
+ {
+ var opac = orgOpac * n;
+ this.context.beginPath();
+ this.context.strokeStyle = "rgba(0,0,0," + opac + ")";
+
+ this.context.moveTo(this.translateHoz(left) + n, this.translateVert(bottom));
+
+ if(drawLeft)
+ this.context.lineTo(this.translateHoz(left) + n, this.translateVert(top) - n);
+ else
+ this.context.moveTo(this.translateHoz(left) + n, this.translateVert(top) - n);
+
+ if(drawTop)
+ this.context.lineTo(this.translateHoz(right) + n, this.translateVert(top) - n);
+ else
+ this.context.moveTo(this.translateHoz(right) + n, this.translateVert(top) - n);
+
+ if(drawRight)
+ this.context.lineTo(this.translateHoz(right) + n, this.translateVert(bottom));
+ else
+ this.context.lineTo(this.translateHoz(right) + n, this.translateVert(bottom));
+
+ this.context.stroke();
+ this.context.closePath();
+ }
+
+ this.context.strokeStyle = orgStrokeStyle;
+ },
+ /**
+ * function: drawGraphBars
+ *
+ * parameters:
+ * {Object} graphData
+ * {Object} counter
+ * {Object} total
+ * {Object} barDataRange
+ *
+ * description:
+ * Draws the actual bar graphs. Calls <plotBars> to draw the individual bar
+ */
+ drawGraphBars: function(graphData, counter, total, barDataRange){
+ this.context.save();
+ this.context.translate(this.chartOffset.left, this.chartOffset.top);
+ this.context.lineJoin = "round";
+
+ var bw = graphData.bars.barWidth;
+ var lw = Math.min(graphData.bars.lineWidth, bw);
+
+
+ this.context.lineWidth = lw;
+ this.context.strokeStyle = graphData.color;
+ if (graphData.bars.fill) {
+ this.context.fillStyle = graphData.bars.fillColor != null ? graphData.bars.fillColor : this.parseColor(graphData.color).scale(null, null, null, this.options.bars.fillOpacity).toString();
+ }
+ this.plotBars(graphData, graphData.data, bw, 0, graphData.bars.fill, counter, total, barDataRange);
+ this.context.restore();
+ },
+ /**
+ * function: insertLegend
+ *
+ * description:
+ * inserts legend onto the graph. *legend: {show: true}* must be set in <options>
+ * for for this to work.
+ */
+ insertLegend: function() {
+ this.domObj.select(".legend").invoke('remove');
+
+ if (!this.options.legend.show)
+ return;
+
+ var fragments = [];
+ var rowStarted = false;
+ this.graphData.each(function(gd, index){
+ if(!gd.label) {
+ return;
+ }
+ if(index % this.options.legend.noColumns == 0) {
+ if(rowStarted) {
+ fragments.push('</tr>');
+ }
+ fragments.push('<tr>');
+ rowStarted = true;
+ }
+ var label = gd.label;
+ if(this.options.legend.labelFormatter != null) {
+ label = this.options.legend.labelFormatter(label);
+ }
+
+ fragments.push(
+ '<td class="legendColorBox"><div style="border:1px solid ' + this.options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:14px;height:10px;background-color:' + gd.color + ';overflow:hidden"></div></div></td>' +
+ '<td class="legendLabel">' + label + '</td>');
+
+ }.bind(this));
+
+ if (rowStarted)
+ fragments.push('</tr>');
+
+ if(fragments.length > 0){
+ var table = '<table style="font-size:smaller;color:' + this.options.grid.color + '">' + fragments.join("") + '</table>';
+ if($(this.options.legend.container) != null){
+ $(this.options.legend.container).insert(table);
+ }else{
+ var pos = '';
+ var p = this.options.legend.position, m = this.options.legend.margin;
+
+ if(p.charAt(0) == 'n') pos += 'top:' + (m + this.chartOffset.top) + 'px;';
+ else if(p.charAt(0) == 's') pos += 'bottom:' + (m + this.chartOffset.bottom) + 'px;';
+ if(p.charAt(1) == 'e') pos += 'right:' + (m + this.chartOffset.right) + 'px;';
+ else if(p.charAt(1) == 'w') pos += 'left:' + (m + this.chartOffset.bottom) + 'px;';
+ var div = this.domObj.insert('<div class="ProtoChart-legend" style="border: 1px solid '+this.options.legend.borderColor+'; position:absolute;z-index:2;' + pos +'">' + table + '</div>').getElementsBySelector('div.ProtoChart-legend').first();
+
+ if(this.options.legend.backgroundOpacity != 0.0){
+ var c = this.options.legend.backgroundColor;
+ if(c == null){
+ var tmp = (this.options.grid.backgroundColor != null) ? this.options.grid.backgroundColor : this.extractColor(div);
+ c = this.parseColor(tmp).adjust(null, null, null, 1).toString();
+ }
+ this.domObj.insert('<div class="ProtoChart-legend-bg" style="position:absolute;width:' + div.getWidth() + 'px;height:' + div.getHeight() + 'px;' + pos +'background-color:' + c + ';"> </div>').select('div.ProtoChart-legend-bg').first().setStyle({
+ 'opacity': this.options.legend.backgroundOpacity
+ });
+ }
+ }
+ }
+ },
+ /**
+ * Function: onMouseMove
+ *
+ * parameters:
+ * event: {Object} ev
+ *
+ * Description:
+ * Called whenever the mouse is moved on the graph. This takes care of the mousetracking.
+ * This event also fires <ProtoChart:mousemove> event, which gets current position of the
+ * mouse as a parameters.
+ */
+ onMouseMove: function(ev) {
+ var e = ev || window.event;
+ if (e.pageX == null && e.clientX != null) {
+ var de = document.documentElement, b = $(document.body);
+ this.lastMousePos.pageX = e.clientX + (de && de.scrollLeft || b.scrollLeft || 0);
+ this.lastMousePos.pageY = e.clientY + (de && de.scrollTop || b.scrollTop || 0);
+ }
+ else {
+ this.lastMousePos.pageX = e.pageX;
+ this.lastMousePos.pageY = e.pageY;
+ }
+
+ var offset = this.overlay.cumulativeOffset();
+ var pos = {
+ x: this.xaxis.min + (e.pageX - offset.left - this.chartOffset.left) / this.hozScale,
+ y: this.yaxis.max - (e.pageY - offset.top - this.chartOffset.top) / this.vertScale
+ };
+
+ if(this.options.mouse.track && this.selectionInterval == null) {
+ this.hit(ev, pos);
+ }
+ this.domObj.fire("ProtoChart:mousemove", [ pos ]);
+ },
+ /**
+ * Function: onMouseDown
+ *
+ * Parameters:
+ * Event - {Object} e
+ *
+ * Description:
+ * Called whenever the mouse is clicked.
+ */
+ onMouseDown: function(e) {
+ if (e.which != 1) // only accept left-click
+ return;
+
+ document.body.focus();
+
+ if (document.onselectstart !== undefined && this.workarounds.onselectstart == null) {
+ this.workarounds.onselectstart = document.onselectstart;
+ document.onselectstart = function () { return false; };
+ }
+ if (document.ondrag !== undefined && this.workarounds.ondrag == null) {
+ this.workarounds.ondrag = document.ondrag;
+ document.ondrag = function () { return false; };
+ }
+
+ this.setSelectionPos(this.selection.first, e);
+
+ if (this.selectionInterval != null)
+ clearInterval(this.selectionInterval);
+ this.lastMousePos.pageX = null;
+ this.selectionInterval = setInterval(this.updateSelectionOnMouseMove.bind(this), 200);
+
+ this.overlay.observe("mouseup", this.onSelectionMouseUp.bind(this));
+ },
+ /**
+ * Function: onClick
+ * parameters:
+ * Event - {Object} e
+ * Description:
+ * Handles the "click" event on the chart. This function fires <ProtoChart:plotclick> event. If
+ * <options.allowDataClick> is enabled then it also fires <ProtoChart:dataclick> event which gives
+ * you access to exact data point where user clicked.
+ */
+ onClick: function(e) {
+ if (this.ignoreClick) {
+ this.ignoreClick = false;
+ return;
+ }
+ var offset = this.overlay.cumulativeOffset();
+ var pos ={
+ x: this.xaxis.min + (e.pageX - offset.left - this.chartOffset.left) / this.hozScale,
+ y: this.yaxis.max - (e.pageY - offset.top - this.chartOffset.top) / this.vertScale
+ };
+ this.domObj.fire("ProtoChart:plotclick", [ pos ]);
+
+ if(this.options.allowDataClick)
+ {
+ var dataPoint = {};
+ if(this.options.points.show)
+ {
+ dataPoint = this.getDataClickPoint(pos, this.options);
+ this.domObj.fire("ProtoChart:dataclick", [dataPoint]);
+ }
+ else if(this.options.lines.show && this.options.points.show)
+ {
+ dataPoint = this.getDataClickPoint(pos, this.options);
+ this.domObj.fire("ProtoChart:dataclick", [dataPoint]);
+ }
+ else if(this.options.bars.show)
+ {
+ if(this.barDataRange.length > 0)
+ {
+ dataPoint = this.getDataClickPoint(pos, this.options, this.barDataRange);
+ this.domObj.fire("ProtoChart:dataclick", [dataPoint]);
+ }
+ }
+ }
+ },
+ /**
+ * Internal function used by onClick method.
+ */
+ getDataClickPoint: function(pos, options, barDataRange)
+ {
+ pos.x = parseInt(pos.x);
+ pos.y = parseInt(pos.y);
+ var yClick = pos.y.toFixed(0);
+ var dataVal = {};
+
+ dataVal.position = pos;
+ dataVal.value = '';
+
+ if(options.points.show)
+ {
+ this.graphData.each(function(gd){
+ var temp = gd.data;
+ var xClick = parseInt(pos.x.toFixed(0));
+ if(xClick < 0) { xClick = 0; }
+ if(temp[xClick] && yClick >= temp[xClick][1] - (this.options.points.radius * 10) && yClick <= temp[xClick][1] + (this.options.points.radius * 10)) {
+ dataVal.value = temp[xClick][1];
+ throw $break;
+ }
+
+ }.bind(this));
+ }
+ else if(options.bars.show)
+ {
+ xClick = pos.x;
+ this.barDataRange.each(function(barData){
+ barData.each(function(data){
+ var temp = data;
+ if(xClick > temp.left && xClick < temp.right) {
+ dataVal.value = temp.value;
+ throw $break;
+ }
+ }.bind(this));
+ }.bind(this));
+
+ }
+
+ return dataVal;
+ },
+ /**
+ * Function: triggerSelectedEvent
+ *
+ * Description:
+ * Internal function called when a selection on the graph is made. This function
+ * fires <ProtoChart:selected> event which has a parameter representing the selection
+ * {
+ * x1: {int}, y1: {int},
+ * x2: {int}, y2: {int}
+ * }
+ */
+ triggerSelectedEvent: function() {
+ var x1, x2, y1, y2;
+ if (this.selection.first.x <= this.selection.second.x) {
+ x1 = this.selection.first.x;
+ x2 = this.selection.second.x;
+ }
+ else {
+ x1 = this.selection.second.x;
+ x2 = this.selection.first.x;
+ }
+
+ if (this.selection.first.y >= this.selection.second.y) {
+ y1 = this.selection.first.y;
+ y2 = this.selection.second.y;
+ }
+ else {
+ y1 = this.selection.second.y;
+ y2 = this.selection.first.y;
+ }
+
+ x1 = this.xaxis.min + x1 / this.hozScale;
+ x2 = this.xaxis.min + x2 / this.hozScale;
+
+ y1 = this.yaxis.max - y1 / this.vertScale;
+ y2 = this.yaxis.max - y2 / this.vertScale;
+
+ this.domObj.fire("ProtoChart:selected", [ { x1: x1, y1: y1, x2: x2, y2: y2 } ]);
+ },
+ /**
+ * Internal function
+ */
+ onSelectionMouseUp: function(e) {
+ if (document.onselectstart !== undefined)
+ document.onselectstart = this.workarounds.onselectstart;
+ if (document.ondrag !== undefined)
+ document.ondrag = this.workarounds.ondrag;
+
+ if (this.selectionInterval != null) {
+ clearInterval(this.selectionInterval);
+ this.selectionInterval = null;
+ }
+
+ this.setSelectionPos(this.selection.second, e);
+ this.clearSelection();
+ if (!this.selectionIsSane() || e.which != 1)
+ return false;
+
+ this.drawSelection();
+ this.triggerSelectedEvent();
+ this.ignoreClick = true;
+
+ return false;
+ },
+ setSelectionPos: function(pos, e) {
+ var offset = $(this.overlay).cumulativeOffset();
+ if (this.options.selection.mode == "y") {
+ if (pos == this.selection.first)
+ pos.x = 0;
+ else
+ pos.x = this.chartWidth;
+ }
+ else {
+ pos.x = e.pageX - offset.left - this.chartOffset.left;
+ pos.x = Math.min(Math.max(0, pos.x), this.chartWidth);
+ }
+
+ if (this.options.selection.mode == "x") {
+ if (pos == this.selection.first)
+ pos.y = 0;
+ else
+ pos.y = this.chartHeight;
+ }
+ else {
+ pos.y = e.pageY - offset.top - this.chartOffset.top;
+ pos.y = Math.min(Math.max(0, pos.y), this.chartHeight);
+ }
+ },
+ updateSelectionOnMouseMove: function() {
+ if (this.lastMousePos.pageX == null)
+ return;
+
+ this.setSelectionPos(this.selection.second, this.lastMousePos);
+ this.clearSelection();
+ if (this.selectionIsSane())
+ this.drawSelection();
+ },
+ clearSelection: function() {
+ if (this.prevSelection == null)
+ return;
+
+ var x = Math.min(this.prevSelection.first.x, this.prevSelection.second.x),
+ y = Math.min(this.prevSelection.first.y, this.prevSelection.second.y),
+ w = Math.abs(this.prevSelection.second.x - this.prevSelection.first.x),
+ h = Math.abs(this.prevSelection.second.y - this.prevSelection.first.y);
+
+ this.overlayContext.clearRect(x + this.chartOffset.left - this.overlayContext.lineWidth,
+ y + this.chartOffset.top - this.overlayContext.lineWidth,
+ w + this.overlayContext.lineWidth*2,
+ h + this.overlayContext.lineWidth*2);
+
+ this.prevSelection = null;
+ },
+ /**
+ * Function: setSelection
+ *
+ * Parameters:
+ * Area - {Object} area represented as a range like: {x1: 3, y1: 3, x2: 4, y2: 8}
+ *
+ * Description:
+ * Sets the current graph selection to the provided range. Calls <drawSelection> and
+ * <triggerSelectedEvent> functions internally.
+ */
+ setSelection: function(area) {
+ this.clearSelection();
+
+ if (this.options.selection.mode == "x") {
+ this.selection.first.y = 0;
+ this.selection.second.y = this.chartHeight;
+ }
+ else {
+ this.selection.first.y = (this.yaxis.max - area.y1) * this.vertScale;
+ this.selection.second.y = (this.yaxis.max - area.y2) * this.vertScale;
+ }
+ if (this.options.selection.mode == "y") {
+ this.selection.first.x = 0;
+ this.selection.second.x = this.chartWidth;
+ }
+ else {
+ this.selection.first.x = (area.x1 - this.xaxis.min) * this.hozScale;
+ this.selection.second.x = (area.x2 - this.xaxis.min) * this.hozScale;
+ }
+
+ this.drawSelection();
+ this.triggerSelectedEvent();
+ },
+ /**
+ * Function: drawSelection
+ * Description: Internal function called to draw the selection made on the graph.
+ */
+ drawSelection: function() {
+ if (this.prevSelection != null &&
+ this.selection.first.x == this.prevSelection.first.x &&
+ this.selection.first.y == this.prevSelection.first.y &&
+ this.selection.second.x == this.prevSelection.second.x &&
+ this.selection.second.y == this.prevSelection.second.y)
+ {
+ return;
+ }
+
+ this.overlayContext.strokeStyle = this.parseColor(this.options.selection.color).scale(null, null, null, 0.8).toString();
+ this.overlayContext.lineWidth = 1;
+ this.context.lineJoin = "round";
+ this.overlayContext.fillStyle = this.parseColor(this.options.selection.color).scale(null, null, null, 0.4).toString();
+
+ this.prevSelection = { first: { x: this.selection.first.x,
+ y: this.selection.first.y },
+ second: { x: this.selection.second.x,
+ y: this.selection.second.y } };
+
+ var x = Math.min(this.selection.first.x, this.selection.second.x),
+ y = Math.min(this.selection.first.y, this.selection.second.y),
+ w = Math.abs(this.selection.second.x - this.selection.first.x),
+ h = Math.abs(this.selection.second.y - this.selection.first.y);
+
+ this.overlayContext.fillRect(x + this.chartOffset.left, y + this.chartOffset.top, w, h);
+ this.overlayContext.strokeRect(x + this.chartOffset.left, y + this.chartOffset.top, w, h);
+ },
+ /**
+ * Internal function
+ */
+ selectionIsSane: function() {
+ var minSize = 5;
+ return Math.abs(this.selection.second.x - this.selection.first.x) >= minSize &&
+ Math.abs(this.selection.second.y - this.selection.first.y) >= minSize;
+ },
+ /**
+ * Internal function that formats the track. This is the format the text is shown when mouse
+ * tracking is enabled.
+ */
+ defaultTrackFormatter: function(val)
+ {
+ return '['+val.x+', '+val.y+']';
+ },
+ /**
+ * Function: clearHit
+ */
+ clearHit: function(){
+ if(this.prevHit){
+ this.overlayContext.clearRect(
+ this.translateHoz(this.prevHit.x) + this.chartOffset.left - this.options.mouse.radius*2,
+ this.translateVert(this.prevHit.y) + this.chartOffset.top - this.options.mouse.radius*2,
+ this.options.mouse.radius*3 + this.options.points.lineWidth*3,
+ this.options.mouse.radius*3 + this.options.points.lineWidth*3
+ );
+ this.prevHit = null;
+ }
+ },
+ /**
+ * Function: hit
+ *
+ * Parameters:
+ * event - {Object} event object
+ * mouse - {Object} mouse object that is used to keep track of mouse movement
+ *
+ * Description:
+ * If hit occurs this function will fire a ProtoChart:hit event.
+ */
+ hit: function(event, mouse){
+ /**
+ * Nearest data element.
+ */
+ var n = {
+ dist:Number.MAX_VALUE,
+ x:null,
+ y:null,
+ mouse:null
+ };
+
+
+ for(var i = 0, data, xsens, ysens; i < this.graphData.length; i++){
+ if(!this.graphData[i].mouse.track) continue;
+ data = this.graphData[i].data;
+ xsens = (this.hozScale*this.graphData[i].mouse.sensibility);
+ ysens = (this.vertScale*this.graphData[i].mouse.sensibility);
+ for(var j = 0, xabs, yabs; j < data.length; j++){
+ xabs = this.hozScale*Math.abs(data[j][0] - mouse.x);
+ yabs = this.vertScale*Math.abs(data[j][1] - mouse.y);
+
+ if(xabs < xsens && yabs < ysens && (xabs+yabs) < n.dist){
+ n.dist = (xabs+yabs);
+ n.x = data[j][0];
+ n.y = data[j][1];
+ n.mouse = this.graphData[i].mouse;
+ }
+ }
+ }
+
+ if(n.mouse && n.mouse.track && !this.prevHit || (this.prevHit && n.x != this.prevHit.x && n.y != this.prevHit.y)){
+ var el = this.domObj.select('.'+this.options.mouse.clsName).first();
+ if(!el){
+ var pos = '', p = this.options.mouse.position, m = this.options.mouse.margin;
+ if(p.charAt(0) == 'n') pos += 'top:' + (m + this.chartOffset.top) + 'px;';
+ else if(p.charAt(0) == 's') pos += 'bottom:' + (m + this.chartOffset.bottom) + 'px;';
+ if(p.charAt(1) == 'e') pos += 'right:' + (m + this.chartOffset.right) + 'px;';
+ else if(p.charAt(1) == 'w') pos += 'left:' + (m + this.chartOffset.bottom) + 'px;';
+
+ this.domObj.insert('<div class="'+this.options.mouse.clsName+'" style="display:none;position:absolute;'+pos+'"></div>');
+ return;
+ }
+ if(n.x !== null && n.y !== null){
+ el.setStyle({display:'block'});
+
+ this.clearHit();
+ if(n.mouse.lineColor != null){
+ this.overlayContext.save();
+ this.overlayContext.translate(this.chartOffset.left, this.chartOffset.top);
+ this.overlayContext.lineWidth = this.options.points.lineWidth;
+ this.overlayContext.strokeStyle = n.mouse.lineColor;
+ this.overlayContext.fillStyle = '#ffffff';
+ this.overlayContext.beginPath();
+
+
+ this.overlayContext.arc(this.translateHoz(n.x), this.translateVert(n.y), this.options.mouse.radius, 0, 2 * Math.PI, true);
+ this.overlayContext.fill();
+ this.overlayContext.stroke();
+ this.overlayContext.restore();
+ }
+ this.prevHit = n;
+
+ var decimals = n.mouse.trackDecimals;
+ if(decimals == null || decimals < 0) decimals = 0;
+ if(!this.options.mouse.fixedPosition)
+ {
+ el.setStyle({
+ left: (this.translateHoz(n.x) + this.options.mouse.radius + 10) + "px",
+ top: (this.translateVert(n.y) + this.options.mouse.radius + 10) + "px"
+ });
+ }
+ el.innerHTML = n.mouse.trackFormatter({x: n.x.toFixed(decimals), y: n.y.toFixed(decimals)});
+ this.domObj.fire( 'ProtoChart:hit', [n] )
+ }else if(this.options.prevHit){
+ el.setStyle({display:'none'});
+ this.clearHit();
+ }
+ }
+ },
+ /**
+ * Internal function
+ */
+ floorInBase: function(n, base) {
+ return base * Math.floor(n / base);
+ },
+ /**
+ * Function: extractColor
+ *
+ * Parameters:
+ * element - HTML element or ID of an HTML element
+ *
+ * Returns:
+ * color in string format
+ */
+ extractColor: function(element)
+ {
+ var color;
+ do
+ {
+ color = $(element).getStyle('background-color').toLowerCase();
+ if(color != '' && color != 'transparent')
+ {
+ break;
+ }
+ element = element.up(0); //or else just get the parent ....
+ } while(element.nodeName.toLowerCase() != 'body');
+
+ //safari fix
+ if(color == 'rgba(0, 0, 0, 0)')
+ return 'transparent';
+ return color;
+ },
+ /**
+ * Function: parseColor
+ *
+ * Parameters:
+ * str - color string in different formats
+ *
+ * Returns:
+ * a Proto.Color Object - use toString() function to retreive the color in rgba/rgb format
+ */
+ parseColor: function(str)
+ {
+ var result;
+
+ /**
+ * rgb(num,num,num)
+ */
+ if((result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str)))
+ return new Proto.Color(parseInt(result[1]), parseInt(result[2]), parseInt(result[3]));
+
+ /**
+ * rgba(num,num,num,num)
+ */
+ if((result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)))
+ return new Proto.Color(parseInt(result[1]), parseInt(result[2]), parseInt(result[3]), parseFloat(result[4]));
+
+ /**
+ * rgb(num%,num%,num%)
+ */
+ if((result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str)))
+ return new Proto.Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55);
+
+ /**
+ * rgba(num%,num%,num%,num)
+ */
+ if((result = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)))
+ return new Proto.Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55, parseFloat(result[4]));
+
+ /**
+ * #a0b1c2
+ */
+ if((result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str)))
+ return new Proto.Color(parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16));
+
+ /**
+ * #fff
+ */
+ if((result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str)))
+ return new Proto.Color(parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16));
+
+ /**
+ * Otherwise, check if user wants transparent .. or we just return a standard color;
+ */
+ var name = str.strip().toLowerCase();
+ if(name == 'transparent'){
+ return new Proto.Color(255, 255, 255, 0);
+ }
+
+ return new Proto.Color(100,100,100, 1);
+
+ }
+});
+
+if(!Proto) var Proto = {};
+
+/**
+ * Class: Proto.Color
+ *
+ * Helper class that manipulates colors using RGBA values.
+ *
+ */
+
+Proto.Color = Class.create({
+ initialize: function(r, g, b, a) {
+ this.rgba = ['r', 'g', 'b', 'a'];
+ var x = 4;
+ while(-1<--x) {
+ this[this.rgba[x]] = arguments[x] || ((x==3) ? 1.0 : 0);
+ }
+ },
+ toString: function() {
+ if(this.a >= 1.0) {
+ return "rgb(" + [this.r, this.g, this.b].join(",") +")";
+ }
+ else {
+ return "rgba("+[this.r, this.g, this.b, this.a].join(",")+")";
+ }
+ },
+ scale: function(rf, gf, bf, af) {
+ x = 4;
+ while(-1<--x) {
+ if(arguments[x] != null) {
+ this[this.rgba[x]] *= arguments[x];
+ }
+ }
+ return this.normalize();
+ },
+ adjust: function(rd, gd, bd, ad) {
+ x = 4; //rgba.length
+ while (-1<--x) {
+ if (arguments[x] != null)
+ this[this.rgba[x]] += arguments[x];
+ }
+ return this.normalize();
+ },
+ clone: function() {
+ return new Proto.Color(this.r, this.b, this.g, this.a);
+ },
+ limit: function(val,minVal,maxVal) {
+ return Math.max(Math.min(val, maxVal), minVal);
+ },
+ normalize: function() {
+ this.r = this.limit(parseInt(this.r), 0, 255);
+ this.g = this.limit(parseInt(this.g), 0, 255);
+ this.b = this.limit(parseInt(this.b), 0, 255);
+ this.a = this.limit(this.a, 0, 1);
+ return this;
+ }
+}); \ No newline at end of file
diff --git a/usr/local/www/protochart/excanvas-compressed.js b/usr/local/www/protochart/excanvas-compressed.js
new file mode 100644
index 0000000..9d71658
--- /dev/null
+++ b/usr/local/www/protochart/excanvas-compressed.js
@@ -0,0 +1,19 @@
+if(!window.CanvasRenderingContext2D){(function(){var I=Math,i=I.round,L=I.sin,M=I.cos,m=10,A=m/2,Q={init:function(a){var b=a||document;if(/MSIE/.test(navigator.userAgent)&&!window.opera){var c=this;b.attachEvent("onreadystatechange",function(){c.r(b)})}},r:function(a){if(a.readyState=="complete"){if(!a.namespaces["s"]){a.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml")}var b=a.createStyleSheet();b.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}";
+var c=a.getElementsByTagName("canvas");for(var d=0;d<c.length;d++){if(!c[d].getContext){this.initElement(c[d])}}}},q:function(a){var b=a.outerHTML,c=a.ownerDocument.createElement(b);if(b.slice(-2)!="/>"){var d="/"+a.tagName,e;while((e=a.nextSibling)&&e.tagName!=d){e.removeNode()}if(e){e.removeNode()}}a.parentNode.replaceChild(c,a);return c},initElement:function(a){a=this.q(a);a.getContext=function(){if(this.l){return this.l}return this.l=new K(this)};a.attachEvent("onpropertychange",V);a.attachEvent("onresize",
+W);var b=a.attributes;if(b.width&&b.width.specified){a.style.width=b.width.nodeValue+"px"}else{a.width=a.clientWidth}if(b.height&&b.height.specified){a.style.height=b.height.nodeValue+"px"}else{a.height=a.clientHeight}return a}};function V(a){var b=a.srcElement;switch(a.propertyName){case "width":b.style.width=b.attributes.width.nodeValue+"px";b.getContext().clearRect();break;case "height":b.style.height=b.attributes.height.nodeValue+"px";b.getContext().clearRect();break}}function W(a){var b=a.srcElement;
+if(b.firstChild){b.firstChild.style.width=b.clientWidth+"px";b.firstChild.style.height=b.clientHeight+"px"}}Q.init();var R=[];for(var E=0;E<16;E++){for(var F=0;F<16;F++){R[E*16+F]=E.toString(16)+F.toString(16)}}function J(){return[[1,0,0],[0,1,0],[0,0,1]]}function G(a,b){var c=J();for(var d=0;d<3;d++){for(var e=0;e<3;e++){var g=0;for(var h=0;h<3;h++){g+=a[d][h]*b[h][e]}c[d][e]=g}}return c}function N(a,b){b.fillStyle=a.fillStyle;b.lineCap=a.lineCap;b.lineJoin=a.lineJoin;b.lineWidth=a.lineWidth;b.miterLimit=
+a.miterLimit;b.shadowBlur=a.shadowBlur;b.shadowColor=a.shadowColor;b.shadowOffsetX=a.shadowOffsetX;b.shadowOffsetY=a.shadowOffsetY;b.strokeStyle=a.strokeStyle;b.d=a.d;b.e=a.e}function O(a){var b,c=1;a=String(a);if(a.substring(0,3)=="rgb"){var d=a.indexOf("(",3),e=a.indexOf(")",d+1),g=a.substring(d+1,e).split(",");b="#";for(var h=0;h<3;h++){b+=R[Number(g[h])]}if(g.length==4&&a.substr(3,1)=="a"){c=g[3]}}else{b=a}return[b,c]}function S(a){switch(a){case "butt":return"flat";case "round":return"round";
+case "square":default:return"square"}}function K(a){this.a=J();this.m=[];this.k=[];this.c=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=m*1;this.globalAlpha=1;this.canvas=a;var b=a.ownerDocument.createElement("div");b.style.width=a.clientWidth+"px";b.style.height=a.clientHeight+"px";b.style.overflow="hidden";b.style.position="absolute";a.appendChild(b);this.j=b;this.d=1;this.e=1}var j=K.prototype;j.clearRect=function(){this.j.innerHTML=
+"";this.c=[]};j.beginPath=function(){this.c=[]};j.moveTo=function(a,b){this.c.push({type:"moveTo",x:a,y:b});this.f=a;this.g=b};j.lineTo=function(a,b){this.c.push({type:"lineTo",x:a,y:b});this.f=a;this.g=b};j.bezierCurveTo=function(a,b,c,d,e,g){this.c.push({type:"bezierCurveTo",cp1x:a,cp1y:b,cp2x:c,cp2y:d,x:e,y:g});this.f=e;this.g=g};j.quadraticCurveTo=function(a,b,c,d){var e=this.f+0.6666666666666666*(a-this.f),g=this.g+0.6666666666666666*(b-this.g),h=e+(c-this.f)/3,l=g+(d-this.g)/3;this.bezierCurveTo(e,
+g,h,l,c,d)};j.arc=function(a,b,c,d,e,g){c*=m;var h=g?"at":"wa",l=a+M(d)*c-A,n=b+L(d)*c-A,o=a+M(e)*c-A,f=b+L(e)*c-A;if(l==o&&!g){l+=0.125}this.c.push({type:h,x:a,y:b,radius:c,xStart:l,yStart:n,xEnd:o,yEnd:f})};j.rect=function(a,b,c,d){this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath()};j.strokeRect=function(a,b,c,d){this.beginPath();this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath();this.stroke()};j.fillRect=function(a,
+b,c,d){this.beginPath();this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath();this.fill()};j.createLinearGradient=function(a,b,c,d){var e=new H("gradient");return e};j.createRadialGradient=function(a,b,c,d,e,g){var h=new H("gradientradial");h.n=c;h.o=g;h.i.x=a;h.i.y=b;return h};j.drawImage=function(a,b){var c,d,e,g,h,l,n,o,f=a.runtimeStyle.width,k=a.runtimeStyle.height;a.runtimeStyle.width="auto";a.runtimeStyle.height="auto";var q=a.width,r=a.height;a.runtimeStyle.width=
+f;a.runtimeStyle.height=k;if(arguments.length==3){c=arguments[1];d=arguments[2];h=(l=0);n=(e=q);o=(g=r)}else if(arguments.length==5){c=arguments[1];d=arguments[2];e=arguments[3];g=arguments[4];h=(l=0);n=q;o=r}else if(arguments.length==9){h=arguments[1];l=arguments[2];n=arguments[3];o=arguments[4];c=arguments[5];d=arguments[6];e=arguments[7];g=arguments[8]}else{throw"Invalid number of arguments";}var s=this.b(c,d),t=[],v=10,w=10;t.push(" <g_vml_:group",' coordsize="',m*v,",",m*w,'"',' coordorigin="0,0"',
+' style="width:',v,";height:",w,";position:absolute;");if(this.a[0][0]!=1||this.a[0][1]){var x=[];x.push("M11='",this.a[0][0],"',","M12='",this.a[1][0],"',","M21='",this.a[0][1],"',","M22='",this.a[1][1],"',","Dx='",i(s.x/m),"',","Dy='",i(s.y/m),"'");var p=s,y=this.b(c+e,d),z=this.b(c,d+g),B=this.b(c+e,d+g);p.x=Math.max(p.x,y.x,z.x,B.x);p.y=Math.max(p.y,y.y,z.y,B.y);t.push("padding:0 ",i(p.x/m),"px ",i(p.y/m),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",x.join(""),", sizingmethod='clip');")}else{t.push("top:",
+i(s.y/m),"px;left:",i(s.x/m),"px;")}t.push(' ">','<g_vml_:image src="',a.src,'"',' style="width:',m*e,";"," height:",m*g,';"',' cropleft="',h/q,'"',' croptop="',l/r,'"',' cropright="',(q-h-n)/q,'"',' cropbottom="',(r-l-o)/r,'"'," />","</g_vml_:group>");this.j.insertAdjacentHTML("BeforeEnd",t.join(""))};j.stroke=function(a){var b=[],c=O(a?this.fillStyle:this.strokeStyle),d=c[0],e=c[1]*this.globalAlpha,g=10,h=10;b.push("<g_vml_:shape",' fillcolor="',d,'"',' filled="',Boolean(a),'"',' style="position:absolute;width:',
+g,";height:",h,';"',' coordorigin="0 0" coordsize="',m*g," ",m*h,'"',' stroked="',!a,'"',' strokeweight="',this.lineWidth,'"',' strokecolor="',d,'"',' path="');var l={x:null,y:null},n={x:null,y:null};for(var o=0;o<this.c.length;o++){var f=this.c[o];if(f.type=="moveTo"){b.push(" m ");var k=this.b(f.x,f.y);b.push(i(k.x),",",i(k.y))}else if(f.type=="lineTo"){b.push(" l ");var k=this.b(f.x,f.y);b.push(i(k.x),",",i(k.y))}else if(f.type=="close"){b.push(" x ")}else if(f.type=="bezierCurveTo"){b.push(" c ");
+var k=this.b(f.x,f.y),q=this.b(f.cp1x,f.cp1y),r=this.b(f.cp2x,f.cp2y);b.push(i(q.x),",",i(q.y),",",i(r.x),",",i(r.y),",",i(k.x),",",i(k.y))}else if(f.type=="at"||f.type=="wa"){b.push(" ",f.type," ");var k=this.b(f.x,f.y),s=this.b(f.xStart,f.yStart),t=this.b(f.xEnd,f.yEnd);b.push(i(k.x-this.d*f.radius),",",i(k.y-this.e*f.radius)," ",i(k.x+this.d*f.radius),",",i(k.y+this.e*f.radius)," ",i(s.x),",",i(s.y)," ",i(t.x),",",i(t.y))}if(k){if(l.x==null||k.x<l.x){l.x=k.x}if(n.x==null||k.x>n.x){n.x=k.x}if(l.y==
+null||k.y<l.y){l.y=k.y}if(n.y==null||k.y>n.y){n.y=k.y}}}b.push(' ">');if(typeof this.fillStyle=="object"){var v={x:"50%",y:"50%"},w=n.x-l.x,x=n.y-l.y,p=w>x?w:x;v.x=i(this.fillStyle.i.x/w*100+50)+"%";v.y=i(this.fillStyle.i.y/x*100+50)+"%";var y=[];if(this.fillStyle.p=="gradientradial"){var z=this.fillStyle.n/p*100,B=this.fillStyle.o/p*100-z}else{var z=0,B=100}var C={offset:null,color:null},D={offset:null,color:null};this.fillStyle.h.sort(function(T,U){return T.offset-U.offset});for(var o=0;o<this.fillStyle.h.length;o++){var u=
+this.fillStyle.h[o];y.push(u.offset*B+z,"% ",u.color,",");if(u.offset>C.offset||C.offset==null){C.offset=u.offset;C.color=u.color}if(u.offset<D.offset||D.offset==null){D.offset=u.offset;D.color=u.color}}y.pop();b.push("<g_vml_:fill",' color="',D.color,'"',' color2="',C.color,'"',' type="',this.fillStyle.p,'"',' focusposition="',v.x,", ",v.y,'"',' colors="',y.join(""),'"',' opacity="',e,'" />')}else if(a){b.push('<g_vml_:fill color="',d,'" opacity="',e,'" />')}else{b.push("<g_vml_:stroke",' opacity="',
+e,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',S(this.lineCap),'"',' weight="',this.lineWidth,'px"',' color="',d,'" />')}b.push("</g_vml_:shape>");this.j.insertAdjacentHTML("beforeEnd",b.join(""));this.c=[]};j.fill=function(){this.stroke(true)};j.closePath=function(){this.c.push({type:"close"})};j.b=function(a,b){return{x:m*(a*this.a[0][0]+b*this.a[1][0]+this.a[2][0])-A,y:m*(a*this.a[0][1]+b*this.a[1][1]+this.a[2][1])-A}};j.save=function(){var a={};N(this,a);
+this.k.push(a);this.m.push(this.a);this.a=G(J(),this.a)};j.restore=function(){N(this.k.pop(),this);this.a=this.m.pop()};j.translate=function(a,b){var c=[[1,0,0],[0,1,0],[a,b,1]];this.a=G(c,this.a)};j.rotate=function(a){var b=M(a),c=L(a),d=[[b,c,0],[-c,b,0],[0,0,1]];this.a=G(d,this.a)};j.scale=function(a,b){this.d*=a;this.e*=b;var c=[[a,0,0],[0,b,0],[0,0,1]];this.a=G(c,this.a)};j.clip=function(){};j.arcTo=function(){};j.createPattern=function(){return new P};function H(a){this.p=a;this.n=0;this.o=
+0;this.h=[];this.i={x:0,y:0}}H.prototype.addColorStop=function(a,b){b=O(b);this.h.push({offset:1-a,color:b})};function P(){}G_vmlCanvasManager=Q;CanvasRenderingContext2D=K;CanvasGradient=H;CanvasPattern=P})()};
diff --git a/usr/local/www/protochart/excanvas.js b/usr/local/www/protochart/excanvas.js
new file mode 100644
index 0000000..7914cb9
--- /dev/null
+++ b/usr/local/www/protochart/excanvas.js
@@ -0,0 +1,785 @@
+// Copyright 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+// Known Issues:
+//
+// * Patterns are not implemented.
+// * Radial gradient are not implemented. The VML version of these look very
+// different from the canvas one.
+// * Clipping paths are not implemented.
+// * Coordsize. The width and height attribute have higher priority than the
+// width and height style values which isn't correct.
+// * Painting mode isn't implemented.
+// * Canvas width/height should is using content-box by default. IE in
+// Quirks mode will draw the canvas using border-box. Either change your
+// doctype to HTML5
+// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
+// or use Box Sizing Behavior from WebFX
+// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
+// * Optimize. There is always room for speed improvements.
+
+// only add this code if we do not already have a canvas implementation
+if (!window.CanvasRenderingContext2D) {
+
+(function () {
+
+ // alias some functions to make (compiled) code shorter
+ var m = Math;
+ var mr = m.round;
+ var ms = m.sin;
+ var mc = m.cos;
+
+ // this is used for sub pixel precision
+ var Z = 10;
+ var Z2 = Z / 2;
+
+ var G_vmlCanvasManager_ = {
+ init: function (opt_doc) {
+ var doc = opt_doc || document;
+ if (/MSIE/.test(navigator.userAgent) && !window.opera) {
+ var self = this;
+ doc.attachEvent("onreadystatechange", function () {
+ self.init_(doc);
+ });
+ }
+ },
+
+ init_: function (doc) {
+ if (doc.readyState == "complete") {
+ // create xmlns
+ if (!doc.namespaces["g_vml_"]) {
+ doc.namespaces.add("g_vml_", "urn:schemas-microsoft-com:vml");
+ }
+
+ // setup default css
+ var ss = doc.createStyleSheet();
+ ss.cssText = "canvas{display:inline-block;overflow:hidden;" +
+ // default size is 300x150 in Gecko and Opera
+ "text-align:left;width:300px;height:150px}" +
+ "g_vml_\\:*{behavior:url(#default#VML)}";
+
+ // find all canvas elements
+ var els = doc.getElementsByTagName("canvas");
+ for (var i = 0; i < els.length; i++) {
+ if (!els[i].getContext) {
+ this.initElement(els[i]);
+ }
+ }
+ }
+ },
+
+ fixElement_: function (el) {
+ // in IE before version 5.5 we would need to add HTML: to the tag name
+ // but we do not care about IE before version 6
+ var outerHTML = el.outerHTML;
+
+ var newEl = el.ownerDocument.createElement(outerHTML);
+ // if the tag is still open IE has created the children as siblings and
+ // it has also created a tag with the name "/FOO"
+ if (outerHTML.slice(-2) != "/>") {
+ var tagName = "/" + el.tagName;
+ var ns;
+ // remove content
+ while ((ns = el.nextSibling) && ns.tagName != tagName) {
+ ns.removeNode();
+ }
+ // remove the incorrect closing tag
+ if (ns) {
+ ns.removeNode();
+ }
+ }
+ el.parentNode.replaceChild(newEl, el);
+ return newEl;
+ },
+
+ /**
+ * Public initializes a canvas element so that it can be used as canvas
+ * element from now on. This is called automatically before the page is
+ * loaded but if you are creating elements using createElement you need to
+ * make sure this is called on the element.
+ * @param {HTMLElement} el The canvas element to initialize.
+ * @return {HTMLElement} the element that was created.
+ */
+ initElement: function (el) {
+ el = this.fixElement_(el);
+ el.getContext = function () {
+ if (this.context_) {
+ return this.context_;
+ }
+ return this.context_ = new CanvasRenderingContext2D_(this);
+ };
+
+ // do not use inline function because that will leak memory
+ el.attachEvent('onpropertychange', onPropertyChange);
+ el.attachEvent('onresize', onResize);
+
+ var attrs = el.attributes;
+ if (attrs.width && attrs.width.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setWidth_(attrs.width.nodeValue);
+ el.style.width = attrs.width.nodeValue + "px";
+ } else {
+ el.width = el.clientWidth;
+ }
+ if (attrs.height && attrs.height.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setHeight_(attrs.height.nodeValue);
+ el.style.height = attrs.height.nodeValue + "px";
+ } else {
+ el.height = el.clientHeight;
+ }
+ //el.getContext().setCoordsize_()
+ return el;
+ }
+ };
+
+ function onPropertyChange(e) {
+ var el = e.srcElement;
+
+ switch (e.propertyName) {
+ case 'width':
+ el.style.width = el.attributes.width.nodeValue + "px";
+ el.getContext().clearRect();
+ break;
+ case 'height':
+ el.style.height = el.attributes.height.nodeValue + "px";
+ el.getContext().clearRect();
+ break;
+ }
+ }
+
+ function onResize(e) {
+ var el = e.srcElement;
+ if (el.firstChild) {
+ el.firstChild.style.width = el.clientWidth + 'px';
+ el.firstChild.style.height = el.clientHeight + 'px';
+ }
+ }
+
+ G_vmlCanvasManager_.init();
+
+ // precompute "00" to "FF"
+ var dec2hex = [];
+ for (var i = 0; i < 16; i++) {
+ for (var j = 0; j < 16; j++) {
+ dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
+ }
+ }
+
+ function createMatrixIdentity() {
+ return [
+ [1, 0, 0],
+ [0, 1, 0],
+ [0, 0, 1]
+ ];
+ }
+
+ function matrixMultiply(m1, m2) {
+ var result = createMatrixIdentity();
+
+ for (var x = 0; x < 3; x++) {
+ for (var y = 0; y < 3; y++) {
+ var sum = 0;
+
+ for (var z = 0; z < 3; z++) {
+ sum += m1[x][z] * m2[z][y];
+ }
+
+ result[x][y] = sum;
+ }
+ }
+ return result;
+ }
+
+ function copyState(o1, o2) {
+ o2.fillStyle = o1.fillStyle;
+ o2.lineCap = o1.lineCap;
+ o2.lineJoin = o1.lineJoin;
+ o2.lineWidth = o1.lineWidth;
+ o2.miterLimit = o1.miterLimit;
+ o2.shadowBlur = o1.shadowBlur;
+ o2.shadowColor = o1.shadowColor;
+ o2.shadowOffsetX = o1.shadowOffsetX;
+ o2.shadowOffsetY = o1.shadowOffsetY;
+ o2.strokeStyle = o1.strokeStyle;
+ o2.arcScaleX_ = o1.arcScaleX_;
+ o2.arcScaleY_ = o1.arcScaleY_;
+ }
+
+ function processStyle(styleString) {
+ var str, alpha = 1;
+
+ styleString = String(styleString);
+ if (styleString.substring(0, 3) == "rgb") {
+ var start = styleString.indexOf("(", 3);
+ var end = styleString.indexOf(")", start + 1);
+ var guts = styleString.substring(start + 1, end).split(",");
+
+ str = "#";
+ for (var i = 0; i < 3; i++) {
+ str += dec2hex[Number(guts[i])];
+ }
+
+ if ((guts.length == 4) && (styleString.substr(3, 1) == "a")) {
+ alpha = guts[3];
+ }
+ } else {
+ str = styleString;
+ }
+
+ return [str, alpha];
+ }
+
+ function processLineCap(lineCap) {
+ switch (lineCap) {
+ case "butt":
+ return "flat";
+ case "round":
+ return "round";
+ case "square":
+ default:
+ return "square";
+ }
+ }
+
+ /**
+ * This class implements CanvasRenderingContext2D interface as described by
+ * the WHATWG.
+ * @param {HTMLElement} surfaceElement The element that the 2D context should
+ * be associated with
+ */
+ function CanvasRenderingContext2D_(surfaceElement) {
+ this.m_ = createMatrixIdentity();
+
+ this.mStack_ = [];
+ this.aStack_ = [];
+ this.currentPath_ = [];
+
+ // Canvas context properties
+ this.strokeStyle = "#000";
+ this.fillStyle = "#000";
+
+ this.lineWidth = 1;
+ this.lineJoin = "miter";
+ this.lineCap = "butt";
+ this.miterLimit = Z * 1;
+ this.globalAlpha = 1;
+ this.canvas = surfaceElement;
+
+ var el = surfaceElement.ownerDocument.createElement('div');
+ el.style.width = surfaceElement.clientWidth + 'px';
+ el.style.height = surfaceElement.clientHeight + 'px';
+ el.style.overflow = 'hidden';
+ el.style.position = 'absolute';
+ surfaceElement.appendChild(el);
+
+ this.element_ = el;
+ this.arcScaleX_ = 1;
+ this.arcScaleY_ = 1;
+ }
+
+ var contextPrototype = CanvasRenderingContext2D_.prototype;
+ contextPrototype.clearRect = function() {
+ this.element_.innerHTML = "";
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.beginPath = function() {
+ // TODO: Branch current matrix so that save/restore has no effect
+ // as per safari docs.
+
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.moveTo = function(aX, aY) {
+ this.currentPath_.push({type: "moveTo", x: aX, y: aY});
+ this.currentX_ = aX;
+ this.currentY_ = aY;
+ };
+
+ contextPrototype.lineTo = function(aX, aY) {
+ this.currentPath_.push({type: "lineTo", x: aX, y: aY});
+ this.currentX_ = aX;
+ this.currentY_ = aY;
+ };
+
+ contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
+ aCP2x, aCP2y,
+ aX, aY) {
+ this.currentPath_.push({type: "bezierCurveTo",
+ cp1x: aCP1x,
+ cp1y: aCP1y,
+ cp2x: aCP2x,
+ cp2y: aCP2y,
+ x: aX,
+ y: aY});
+ this.currentX_ = aX;
+ this.currentY_ = aY;
+ };
+
+ contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
+ // the following is lifted almost directly from
+ // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
+ var cp1x = this.currentX_ + 2.0 / 3.0 * (aCPx - this.currentX_);
+ var cp1y = this.currentY_ + 2.0 / 3.0 * (aCPy - this.currentY_);
+ var cp2x = cp1x + (aX - this.currentX_) / 3.0;
+ var cp2y = cp1y + (aY - this.currentY_) / 3.0;
+ this.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, aX, aY);
+ };
+
+ contextPrototype.arc = function(aX, aY, aRadius,
+ aStartAngle, aEndAngle, aClockwise) {
+ aRadius *= Z;
+ var arcType = aClockwise ? "at" : "wa";
+
+ var xStart = aX + (mc(aStartAngle) * aRadius) - Z2;
+ var yStart = aY + (ms(aStartAngle) * aRadius) - Z2;
+
+ var xEnd = aX + (mc(aEndAngle) * aRadius) - Z2;
+ var yEnd = aY + (ms(aEndAngle) * aRadius) - Z2;
+
+ // IE won't render arches drawn counter clockwise if xStart == xEnd.
+ if (xStart == xEnd && !aClockwise) {
+ xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
+ // that can be represented in binary
+ }
+
+ this.currentPath_.push({type: arcType,
+ x: aX,
+ y: aY,
+ radius: aRadius,
+ xStart: xStart,
+ yStart: yStart,
+ xEnd: xEnd,
+ yEnd: yEnd});
+
+ };
+
+ contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ };
+
+ contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
+ // Will destroy any existing path (same as FF behaviour)
+ this.beginPath();
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ this.stroke();
+ };
+
+ contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
+ // Will destroy any existing path (same as FF behaviour)
+ this.beginPath();
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ this.fill();
+ };
+
+ contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
+ var gradient = new CanvasGradient_("gradient");
+ return gradient;
+ };
+
+ contextPrototype.createRadialGradient = function(aX0, aY0,
+ aR0, aX1,
+ aY1, aR1) {
+ var gradient = new CanvasGradient_("gradientradial");
+ gradient.radius1_ = aR0;
+ gradient.radius2_ = aR1;
+ gradient.focus_.x = aX0;
+ gradient.focus_.y = aY0;
+ return gradient;
+ };
+
+ contextPrototype.drawImage = function (image, var_args) {
+ var dx, dy, dw, dh, sx, sy, sw, sh;
+
+ // to find the original width we overide the width and height
+ var oldRuntimeWidth = image.runtimeStyle.width;
+ var oldRuntimeHeight = image.runtimeStyle.height;
+ image.runtimeStyle.width = 'auto';
+ image.runtimeStyle.height = 'auto';
+
+ // get the original size
+ var w = image.width;
+ var h = image.height;
+
+ // and remove overides
+ image.runtimeStyle.width = oldRuntimeWidth;
+ image.runtimeStyle.height = oldRuntimeHeight;
+
+ if (arguments.length == 3) {
+ dx = arguments[1];
+ dy = arguments[2];
+ sx = sy = 0;
+ sw = dw = w;
+ sh = dh = h;
+ } else if (arguments.length == 5) {
+ dx = arguments[1];
+ dy = arguments[2];
+ dw = arguments[3];
+ dh = arguments[4];
+ sx = sy = 0;
+ sw = w;
+ sh = h;
+ } else if (arguments.length == 9) {
+ sx = arguments[1];
+ sy = arguments[2];
+ sw = arguments[3];
+ sh = arguments[4];
+ dx = arguments[5];
+ dy = arguments[6];
+ dw = arguments[7];
+ dh = arguments[8];
+ } else {
+ throw "Invalid number of arguments";
+ }
+
+ var d = this.getCoords_(dx, dy);
+
+ var w2 = sw / 2;
+ var h2 = sh / 2;
+
+ var vmlStr = [];
+
+ var W = 10;
+ var H = 10;
+
+ // For some reason that I've now forgotten, using divs didn't work
+ vmlStr.push(' <g_vml_:group',
+ ' coordsize="', Z * W, ',', Z * H, '"',
+ ' coordorigin="0,0"' ,
+ ' style="width:', W, ';height:', H, ';position:absolute;');
+
+ // If filters are necessary (rotation exists), create them
+ // filters are bog-slow, so only create them if abbsolutely necessary
+ // The following check doesn't account for skews (which don't exist
+ // in the canvas spec (yet) anyway.
+
+ if (this.m_[0][0] != 1 || this.m_[0][1]) {
+ var filter = [];
+
+ // Note the 12/21 reversal
+ filter.push("M11='", this.m_[0][0], "',",
+ "M12='", this.m_[1][0], "',",
+ "M21='", this.m_[0][1], "',",
+ "M22='", this.m_[1][1], "',",
+ "Dx='", mr(d.x / Z), "',",
+ "Dy='", mr(d.y / Z), "'");
+
+ // Bounding box calculation (need to minimize displayed area so that
+ // filters don't waste time on unused pixels.
+ var max = d;
+ var c2 = this.getCoords_(dx + dw, dy);
+ var c3 = this.getCoords_(dx, dy + dh);
+ var c4 = this.getCoords_(dx + dw, dy + dh);
+
+ max.x = Math.max(max.x, c2.x, c3.x, c4.x);
+ max.y = Math.max(max.y, c2.y, c3.y, c4.y);
+
+ vmlStr.push("padding:0 ", mr(max.x / Z), "px ", mr(max.y / Z),
+ "px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",
+ filter.join(""), ", sizingmethod='clip');");
+ } else {
+ vmlStr.push("top:", mr(d.y / Z), "px;left:", mr(d.x / Z), "px;");
+ }
+
+ vmlStr.push(' ">' ,
+ '<g_vml_:image src="', image.src, '"',
+ ' style="width:', Z * dw, ';',
+ ' height:', Z * dh, ';"',
+ ' cropleft="', sx / w, '"',
+ ' croptop="', sy / h, '"',
+ ' cropright="', (w - sx - sw) / w, '"',
+ ' cropbottom="', (h - sy - sh) / h, '"',
+ ' />',
+ '</g_vml_:group>');
+
+ this.element_.insertAdjacentHTML("BeforeEnd",
+ vmlStr.join(""));
+ };
+
+ contextPrototype.stroke = function(aFill) {
+ var lineStr = [];
+ var lineOpen = false;
+ var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
+ var color = a[0];
+ var opacity = a[1] * this.globalAlpha;
+
+ var W = 10;
+ var H = 10;
+
+ lineStr.push('<g_vml_:shape',
+ ' fillcolor="', color, '"',
+ ' filled="', Boolean(aFill), '"',
+ ' style="position:absolute;width:', W, ';height:', H, ';"',
+ ' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
+ ' stroked="', !aFill, '"',
+ ' strokeweight="', this.lineWidth, '"',
+ ' strokecolor="', color, '"',
+ ' path="');
+
+ var newSeq = false;
+ var min = {x: null, y: null};
+ var max = {x: null, y: null};
+
+ for (var i = 0; i < this.currentPath_.length; i++) {
+ var p = this.currentPath_[i];
+
+ if (p.type == "moveTo") {
+ lineStr.push(" m ");
+ var c = this.getCoords_(p.x, p.y);
+ lineStr.push(mr(c.x), ",", mr(c.y));
+ } else if (p.type == "lineTo") {
+ lineStr.push(" l ");
+ var c = this.getCoords_(p.x, p.y);
+ lineStr.push(mr(c.x), ",", mr(c.y));
+ } else if (p.type == "close") {
+ lineStr.push(" x ");
+ } else if (p.type == "bezierCurveTo") {
+ lineStr.push(" c ");
+ var c = this.getCoords_(p.x, p.y);
+ var c1 = this.getCoords_(p.cp1x, p.cp1y);
+ var c2 = this.getCoords_(p.cp2x, p.cp2y);
+ lineStr.push(mr(c1.x), ",", mr(c1.y), ",",
+ mr(c2.x), ",", mr(c2.y), ",",
+ mr(c.x), ",", mr(c.y));
+ } else if (p.type == "at" || p.type == "wa") {
+ lineStr.push(" ", p.type, " ");
+ var c = this.getCoords_(p.x, p.y);
+ var cStart = this.getCoords_(p.xStart, p.yStart);
+ var cEnd = this.getCoords_(p.xEnd, p.yEnd);
+
+ lineStr.push(mr(c.x - this.arcScaleX_ * p.radius), ",",
+ mr(c.y - this.arcScaleY_ * p.radius), " ",
+ mr(c.x + this.arcScaleX_ * p.radius), ",",
+ mr(c.y + this.arcScaleY_ * p.radius), " ",
+ mr(cStart.x), ",", mr(cStart.y), " ",
+ mr(cEnd.x), ",", mr(cEnd.y));
+ }
+
+
+ // TODO: Following is broken for curves due to
+ // move to proper paths.
+
+ // Figure out dimensions so we can do gradient fills
+ // properly
+ if(c) {
+ if (min.x == null || c.x < min.x) {
+ min.x = c.x;
+ }
+ if (max.x == null || c.x > max.x) {
+ max.x = c.x;
+ }
+ if (min.y == null || c.y < min.y) {
+ min.y = c.y;
+ }
+ if (max.y == null || c.y > max.y) {
+ max.y = c.y;
+ }
+ }
+ }
+ lineStr.push(' ">');
+
+ if (typeof this.fillStyle == "object") {
+ var focus = {x: "50%", y: "50%"};
+ var width = (max.x - min.x);
+ var height = (max.y - min.y);
+ var dimension = (width > height) ? width : height;
+
+ focus.x = mr((this.fillStyle.focus_.x / width) * 100 + 50) + "%";
+ focus.y = mr((this.fillStyle.focus_.y / height) * 100 + 50) + "%";
+
+ var colors = [];
+
+ // inside radius (%)
+ if (this.fillStyle.type_ == "gradientradial") {
+ var inside = (this.fillStyle.radius1_ / dimension * 100);
+
+ // percentage that outside radius exceeds inside radius
+ var expansion = (this.fillStyle.radius2_ / dimension * 100) - inside;
+ } else {
+ var inside = 0;
+ var expansion = 100;
+ }
+
+ var insidecolor = {offset: null, color: null};
+ var outsidecolor = {offset: null, color: null};
+
+ // We need to sort 'colors' by percentage, from 0 > 100 otherwise ie
+ // won't interpret it correctly
+ this.fillStyle.colors_.sort(function (cs1, cs2) {
+ return cs1.offset - cs2.offset;
+ });
+
+ for (var i = 0; i < this.fillStyle.colors_.length; i++) {
+ var fs = this.fillStyle.colors_[i];
+
+ colors.push( (fs.offset * expansion) + inside, "% ", fs.color, ",");
+
+ if (fs.offset > insidecolor.offset || insidecolor.offset == null) {
+ insidecolor.offset = fs.offset;
+ insidecolor.color = fs.color;
+ }
+
+ if (fs.offset < outsidecolor.offset || outsidecolor.offset == null) {
+ outsidecolor.offset = fs.offset;
+ outsidecolor.color = fs.color;
+ }
+ }
+ colors.pop();
+
+ lineStr.push('<g_vml_:fill',
+ ' color="', outsidecolor.color, '"',
+ ' color2="', insidecolor.color, '"',
+ ' type="', this.fillStyle.type_, '"',
+ ' focusposition="', focus.x, ', ', focus.y, '"',
+ ' colors="', colors.join(""), '"',
+ ' opacity="', opacity, '" />');
+ } else if (aFill) {
+ lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity, '" />');
+ } else {
+ lineStr.push(
+ '<g_vml_:stroke',
+ ' opacity="', opacity,'"',
+ ' joinstyle="', this.lineJoin, '"',
+ ' miterlimit="', this.miterLimit, '"',
+ ' endcap="', processLineCap(this.lineCap) ,'"',
+ ' weight="', this.lineWidth, 'px"',
+ ' color="', color,'" />'
+ );
+ }
+
+ lineStr.push("</g_vml_:shape>");
+
+ this.element_.insertAdjacentHTML("beforeEnd", lineStr.join(""));
+
+ //this.currentPath_ = [];
+ };
+
+ contextPrototype.fill = function() {
+ this.stroke(true);
+ };
+
+ contextPrototype.closePath = function() {
+ this.currentPath_.push({type: "close"});
+ };
+
+ /**
+ * @private
+ */
+ contextPrototype.getCoords_ = function(aX, aY) {
+ return {
+ x: Z * (aX * this.m_[0][0] + aY * this.m_[1][0] + this.m_[2][0]) - Z2,
+ y: Z * (aX * this.m_[0][1] + aY * this.m_[1][1] + this.m_[2][1]) - Z2
+ }
+ };
+
+ contextPrototype.save = function() {
+ var o = {};
+ copyState(this, o);
+ this.aStack_.push(o);
+ this.mStack_.push(this.m_);
+ this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
+ };
+
+ contextPrototype.restore = function() {
+ copyState(this.aStack_.pop(), this);
+ this.m_ = this.mStack_.pop();
+ };
+
+ contextPrototype.translate = function(aX, aY) {
+ var m1 = [
+ [1, 0, 0],
+ [0, 1, 0],
+ [aX, aY, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ contextPrototype.rotate = function(aRot) {
+ var c = mc(aRot);
+ var s = ms(aRot);
+
+ var m1 = [
+ [c, s, 0],
+ [-s, c, 0],
+ [0, 0, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ contextPrototype.scale = function(aX, aY) {
+ this.arcScaleX_ *= aX;
+ this.arcScaleY_ *= aY;
+ var m1 = [
+ [aX, 0, 0],
+ [0, aY, 0],
+ [0, 0, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ /******** STUBS ********/
+ contextPrototype.clip = function() {
+ // TODO: Implement
+ };
+
+ contextPrototype.arcTo = function() {
+ // TODO: Implement
+ };
+
+ contextPrototype.createPattern = function() {
+ return new CanvasPattern_;
+ };
+
+ // Gradient / Pattern Stubs
+ function CanvasGradient_(aType) {
+ this.type_ = aType;
+ this.radius1_ = 0;
+ this.radius2_ = 0;
+ this.colors_ = [];
+ this.focus_ = {x: 0, y: 0};
+ }
+
+ CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
+ aColor = processStyle(aColor);
+ this.colors_.push({offset: 1-aOffset, color: aColor});
+ };
+
+ function CanvasPattern_() {}
+
+ // set up externs
+ G_vmlCanvasManager = G_vmlCanvasManager_;
+ CanvasRenderingContext2D = CanvasRenderingContext2D_;
+ CanvasGradient = CanvasGradient_;
+ CanvasPattern = CanvasPattern_;
+
+})();
+
+} // if
diff --git a/usr/local/www/restart_httpd.php b/usr/local/www/restart_httpd.php
index 3aea0a7..27227e4 100755
--- a/usr/local/www/restart_httpd.php
+++ b/usr/local/www/restart_httpd.php
@@ -26,9 +26,16 @@
POSSIBILITY OF SUCH DAMAGE.
*/
+##|+PRIV
+##|*IDENT=page-diagnostics-restart-httpd
+##|*NAME=Diagnostics: Restart HTTPD : System page
+##|*DESCR=Allow access to the 'Diagnostics: Restart HTTPD: System' page.
+##|*MATCH=restart_httpd.php*
+##|-PRIV
+
require_once("guiconfig.inc");
-require_once("system.inc");
-$pgtitle = array("Restarting mini_httpd");
+
+$pgtitle = array("Restarting httpd");
include("head.inc");
?>
diff --git a/usr/local/www/services_captiveportal.php b/usr/local/www/services_captiveportal.php
index f0d8b24..93961a5 100755
--- a/usr/local/www/services_captiveportal.php
+++ b/usr/local/www/services_captiveportal.php
@@ -264,6 +264,7 @@ function enable_change(enable_change) {
$tab_array[] = array("Captive portal", true, "services_captiveportal.php");
$tab_array[] = array("Pass-through MAC", false, "services_captiveportal_mac.php");
$tab_array[] = array("Allowed IP addresses", false, "services_captiveportal_ip.php");
+ $tab_array[] = array("Vouchers", false, "services_captiveportal_vouchers.php");
$tab_array[] = array("File Manager", false, "services_captiveportal_filemanager.php");
display_top_tabs($tab_array);
?> </td></tr>
@@ -558,12 +559,13 @@ value="<?=htmlspecialchars($pconfig['radiuskey2']);?>"></td>
<?php endif; ?>
Upload an HTML file for the portal page here (leave blank to keep the current one). Make sure to include a form (POST to &quot;$PORTAL_ACTION$&quot;)
with a submit button (name=&quot;accept&quot;) and a hidden field with name=&quot;redirurl&quot; and value=&quot;$PORTAL_REDIRURL$&quot;.
-Include the &quot;auth_user&quot; and &quot;auth_pass&quot; input fields if authentication is enabled, otherwise it will always fail.
+Include the &quot;auth_user&quot; and &quot;auth_pass&quot; and/or &quot;auth_voucher&quot; input fields if authentication is enabled, otherwise it will always fail.
Example code for the form:<br>
<br>
<tt>&lt;form method=&quot;post&quot; action=&quot;$PORTAL_ACTION$&quot;&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;input name=&quot;auth_user&quot; type=&quot;text&quot;&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;input name=&quot;auth_pass&quot; type=&quot;password&quot;&gt;<br>
+ &nbsp;&nbsp;&nbsp;&lt;input name=&quot;auth_voucher&quot; type=&quot;text&quot;&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;input name=&quot;redirurl&quot; type=&quot;hidden&quot; value=&quot;$PORTAL_REDIRURL$&quot;&gt;<br>
&nbsp;&nbsp;&nbsp;&lt;input name=&quot;accept&quot; type=&quot;submit&quot; value=&quot;Continue&quot;&gt;<br>
&lt;/form&gt;</tt></td>
diff --git a/usr/local/www/services_captiveportal_filemanager.php b/usr/local/www/services_captiveportal_filemanager.php
index 0c1a12c..93bdb9b 100755
--- a/usr/local/www/services_captiveportal_filemanager.php
+++ b/usr/local/www/services_captiveportal_filemanager.php
@@ -36,6 +36,15 @@
##|*MATCH=services_captiveportal_filemanager.php*
##|-PRIV
+function cpelementscmp($a, $b) {
+ return strcasecmp($a['name'], $b['name']);
+}
+
+function cpelements_sort() {
+ global $config;
+
+ usort($config['captiveportal']['element'],"cpelementscmp");
+}
$pgtitle = array("Services","Captive portal");
@@ -119,6 +128,7 @@ include("head.inc");
$tab_array[] = array("Captive portal", false, "services_captiveportal.php");
$tab_array[] = array("Pass-through MAC", false, "services_captiveportal_mac.php");
$tab_array[] = array("Allowed IP addresses", false, "services_captiveportal_ip.php");
+ $tab_array[] = array("Vouchers", false, "services_captiveportal_vouchers.php");
$tab_array[] = array("File Manager", true, "services_captiveportal_filemanager.php");
display_top_tabs($tab_array);
?> </td></tr>
diff --git a/usr/local/www/services_captiveportal_ip.php b/usr/local/www/services_captiveportal_ip.php
index 70908c7..0c8983c 100755
--- a/usr/local/www/services_captiveportal_ip.php
+++ b/usr/local/www/services_captiveportal_ip.php
@@ -42,32 +42,18 @@ require("guiconfig.inc");
if (!is_array($config['captiveportal']['allowedip']))
$config['captiveportal']['allowedip'] = array();
-allowedips_sort();
$a_allowedips = &$config['captiveportal']['allowedip'] ;
-if ($_POST) {
-
- $pconfig = $_POST;
-
- if ($_POST['apply']) {
- $retval = 0;
-
- $retval = captiveportal_allowedip_configure();
-
- $savemsg = get_std_save_message($retval);
- if ($retval == 0) {
- if (file_exists($d_allowedipsdirty_path)) {
- unlink($d_allowedipsdirty_path);
- }
- }
- }
-}
-
if ($_GET['act'] == "del") {
if ($a_allowedips[$_GET['id']]) {
+ $ipent = $a_allowedips[$_GET['id']];
+ if ($ipent['dir'] == "from")
+ mwexec("/sbin/ipfw table 1 delete " . $ipent['ip']);
+ else
+ mwexec("/sbin/ipfw table 2 delete " . $ipent['ip']);
+
unset($a_allowedips[$_GET['id']]);
write_config();
- touch($d_allowedipsdirty_path);
header("Location: services_captiveportal_ip.php");
exit;
}
@@ -80,9 +66,6 @@ include("head.inc");
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
<form action="services_captiveportal_ip.php" method="post">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_allowedipsdirty_path)): ?>
-<?php print_info_box_np("The captive portal IP address configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
-<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td class="tabnavtbl">
<?php
@@ -90,6 +73,7 @@ include("head.inc");
$tab_array[] = array("Captive portal", false, "services_captiveportal.php");
$tab_array[] = array("Pass-through MAC", false, "services_captiveportal_mac.php");
$tab_array[] = array("Allowed IP addresses", true, "services_captiveportal_ip.php");
+ $tab_array[] = array("Vouchers", false, "services_captiveportal_vouchers.php");
$tab_array[] = array("File Manager", false, "services_captiveportal_filemanager.php");
display_top_tabs($tab_array);
?>
diff --git a/usr/local/www/services_captiveportal_ip_edit.php b/usr/local/www/services_captiveportal_ip_edit.php
index bc0f29e..1ae6f36 100755
--- a/usr/local/www/services_captiveportal_ip_edit.php
+++ b/usr/local/www/services_captiveportal_ip_edit.php
@@ -35,6 +35,15 @@
##|*MATCH=services_captiveportal_ip_edit.php*
##|-PRIV
+function allowedipscmp($a, $b) {
+ return strcmp($a['ip'], $b['ip']);
+}
+
+function allowedips_sort() {
+ global $g, $config;
+
+ usort($config['captiveportal']['allowedip'],"allowedipscmp");
+}
$pgtitle = array("Services","Captive portal","Edit allowed IP address");
require("guiconfig.inc");
@@ -86,6 +95,7 @@ if ($_POST) {
$ip['descr'] = $_POST['descr'];
$ip['dir'] = $_POST['dir'];
+ allowedips_sort();
if (isset($id) && $a_allowedips[$id])
$a_allowedips[$id] = $ip;
else
@@ -93,7 +103,12 @@ if ($_POST) {
write_config();
- touch($d_allowedipsdirty_path) ;
+ if (isset($config['captiveportal']['enable'])) {
+ if ($ip['dir'] == "from")
+ mwexec("/sbin/ipfw table 1 add " . $ip['ip']);
+ else
+ mwexec("/sbin/ipfw table 2 add " . $ip['ip']);
+ }
header("Location: services_captiveportal_ip.php");
exit;
diff --git a/usr/local/www/services_captiveportal_mac.php b/usr/local/www/services_captiveportal_mac.php
index 01ef052..5282b29 100755
--- a/usr/local/www/services_captiveportal_mac.php
+++ b/usr/local/www/services_captiveportal_mac.php
@@ -42,7 +42,6 @@ require("guiconfig.inc");
if (!is_array($config['captiveportal']['passthrumac']))
$config['captiveportal']['passthrumac'] = array();
-passthrumacs_sort();
$a_passthrumacs = &$config['captiveportal']['passthrumac'] ;
if ($_POST) {
@@ -55,11 +54,8 @@ if ($_POST) {
$retval = captiveportal_passthrumac_configure();
$savemsg = get_std_save_message($retval);
- if ($retval == 0) {
- if (file_exists($d_passthrumacsdirty_path)) {
- unlink($d_passthrumacsdirty_path);
- }
- }
+ if ($retval == 0)
+ clear_subsystem_dirty('passthrumac');
}
}
@@ -67,7 +63,7 @@ if ($_GET['act'] == "del") {
if ($a_passthrumacs[$_GET['id']]) {
unset($a_passthrumacs[$_GET['id']]);
write_config();
- touch($d_passthrumacsdirty_path);
+ mark_subsystem_dirty('passthrumac');
header("Location: services_captiveportal_mac.php");
exit;
}
@@ -80,7 +76,7 @@ include("head.inc");
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
<form action="services_captiveportal_mac.php" method="post">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_passthrumacsdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('passthrumac')): ?><p>
<?php print_info_box_np("The captive portal MAC address configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
@@ -90,6 +86,7 @@ include("head.inc");
$tab_array[] = array("Captive portal", false, "services_captiveportal.php");
$tab_array[] = array("Pass-through MAC", true, "services_captiveportal_mac.php");
$tab_array[] = array("Allowed IP addresses", false, "services_captiveportal_ip.php");
+ $tab_array[] = array("Vouchers", false, "services_captiveportal_vouchers.php");
$tab_array[] = array("File Manager", false, "services_captiveportal_filemanager.php");
display_top_tabs($tab_array);
?>
diff --git a/usr/local/www/services_captiveportal_mac_edit.php b/usr/local/www/services_captiveportal_mac_edit.php
index 7161a20..da6e6b3 100755
--- a/usr/local/www/services_captiveportal_mac_edit.php
+++ b/usr/local/www/services_captiveportal_mac_edit.php
@@ -35,6 +35,15 @@
##|*MATCH=services_captiveportal_mac_edit.php*
##|-PRIV
+function passthrumacscmp($a, $b) {
+ return strcmp($a['mac'], $b['mac']);
+}
+
+function passthrumacs_sort() {
+ global $config;
+
+ usort($config['captiveportal']['passthrumac'],"passthrumacscmp");
+}
$pgtitle = array("Services","Captive portal","Edit pass-through MAC address");
require("guiconfig.inc");
@@ -86,6 +95,7 @@ if ($_POST) {
$mac['mac'] = $_POST['mac'];
$mac['descr'] = $_POST['descr'];
+ passthrumacs_sort();
if (isset($id) && $a_passthrumacs[$id])
$a_passthrumacs[$id] = $mac;
else
@@ -93,7 +103,7 @@ if ($_POST) {
write_config();
- touch($d_passthrumacsdirty_path) ;
+ mark_subsystem_dirty('passthrumac');
header("Location: services_captiveportal_mac.php");
exit;
diff --git a/usr/local/www/services_captiveportal_vouchers.php b/usr/local/www/services_captiveportal_vouchers.php
new file mode 100644
index 0000000..b2e54bd
--- /dev/null
+++ b/usr/local/www/services_captiveportal_vouchers.php
@@ -0,0 +1,395 @@
+<?php
+/*
+ Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+##|+PRIV
+##|*IDENT=page-services-captiveportal-vouchers
+##|*NAME=Services: Captive portal Vouchers page
+##|*DESCR=Allow access to the 'Services: Captive portal Vouchers' page.
+##|*MATCH=services_captiveportal_vouchers.php*
+##|-PRIV
+
+$pgtitle = array("Services", "Captive portal", "Vouchers");
+require("guiconfig.inc");
+require_once("voucher.inc");
+
+if (!is_array($config['voucher'])) {
+ $config['voucher'] = array();
+}
+
+if (!is_array($config['voucher']['roll'])) {
+ $config['voucher']['roll'] = array();
+}
+if (!isset($config['voucher']['charset'])) {
+ $config['voucher']['charset'] = '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
+}
+if (!isset($config['voucher']['rollbits'])) {
+ $config['voucher']['rollbits'] = 16;
+}
+if (!isset($config['voucher']['ticketbits'])) {
+ $config['voucher']['ticketbits'] = 10;
+}
+if (!isset($config['voucher']['saveinterval'])) {
+ $config['voucher']['saveinterval'] = 300;
+}
+if (!isset($config['voucher']['checksumbits'])) {
+ $config['voucher']['checksumbits'] = 5;
+}
+if (!isset($config['voucher']['magic'])) {
+ $config['voucher']['magic'] = rand(); // anything slightly random will do
+}
+if (!isset($config['voucher']['publickey'])) {
+
+ /* generate a random 64 bit RSA key pair using the voucher binary */
+ $fd = popen("/usr/local/bin/voucher -g 64", "r");
+ if ($fd !== false) {
+ $output = fread($fd, 16384);
+ pclose($fd);
+
+ list($privkey, $pubkey) = explode("\0", $output);
+
+ $config['voucher']['publickey'] = base64_encode($pubkey);
+ $config['voucher']['privatekey'] = base64_encode($privkey);
+ }
+}
+if (!isset($config['voucher']['msgnoaccess'])) {
+ $config['voucher']['msgnoaccess'] = "Voucher invalid";
+}
+if (!isset($config['voucher']['msgexpired'])) {
+ $config['voucher']['msgexpired'] = "Voucher expired";
+}
+
+$a_roll = &$config['voucher']['roll'];
+
+if ($_GET['act'] == "del") {
+ $id = $_GET['id'];
+ if ($a_roll[$id]) {
+ $roll = $a_roll[$id]['number'];
+ $voucherlck = lock('voucher');
+ unset($a_roll[$id]);
+ voucher_unlink_db($roll);
+ unlock($voucherlck);
+ write_config();
+ header("Location: services_captiveportal_vouchers.php");
+ exit;
+ }
+}
+
+/* print all vouchers of the selected roll */
+if ($_GET['act'] == "csv") {
+ $privkey = base64_decode($config['voucher']['privatekey']);
+ if (strstr($privkey,"BEGIN RSA PRIVATE KEY")) {
+ $fd = fopen("{$g['varetc_path']}/voucher.private","w");
+ if (!$fd) {
+ $input_errors[] = "Cannot write private key file.\n";
+ } else {
+ chmod("{$g['varetc_path']}/voucher.private", 0600);
+ fwrite($fd, $privkey);
+ fclose($fd);
+
+ $a_voucher = &$config['voucher']['roll'];
+ $id = $_GET['id'];
+ if (isset($id) && $a_voucher[$id]) {
+ $number = $a_voucher[$id]['number'];
+ $count = $a_voucher[$id]['count'];
+
+ header("Content-Type: application/octet-stream");
+ header("Content-Disposition: attachment; filename=vouchers_roll$number.csv");
+ system("/usr/local/bin/voucher -c {$g['varetc_path']}/voucher.cfg -p {$g['varetc_path']}/voucher.private $number $count");
+ unlink("{$g['varetc_path']}/voucher.private");
+ exit;
+ }
+ }
+ } else {
+ $input_errors[] = "Need private RSA key to print vouchers\n";
+ }
+}
+
+$pconfig['enable'] = isset($config['voucher']['enable']);
+$pconfig['charset'] = $config['voucher']['charset'];
+$pconfig['rollbits'] = $config['voucher']['rollbits'];
+$pconfig['ticketbits'] = $config['voucher']['ticketbits'];
+$pconfig['saveinterval'] = $config['voucher']['saveinterval'];
+$pconfig['checksumbits'] = $config['voucher']['checksumbits'];
+$pconfig['magic'] = $config['voucher']['magic'];
+$pconfig['publickey'] = base64_decode($config['voucher']['publickey']);
+$pconfig['privatekey'] = base64_decode($config['voucher']['privatekey']);
+$pconfig['msgnoaccess'] = $config['voucher']['msgnoaccess'];
+$pconfig['msgexpired'] = $config['voucher']['msgexpired'];
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['enable']) {
+ $reqdfields = explode(" ", "charset rollbits ticketbits checksumbits publickey magic saveinterval");
+ $reqdfieldsn = explode(",", "charset,rollbits,ticketbits,checksumbits,publickey,magic,saveinterval");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ }
+
+ if ($_POST['charset'] && (strlen($_POST['charset'] < 2))) {
+ $input_errors[] = "Need at least 2 characters to create vouchers.";
+ }
+ if ($_POST['charset'] && (strpos($_POST['charset'],"\"")>0)) {
+ $input_errors[] = "Double quotes aren't allowed.";
+ }
+ if ($_POST['charset'] && (strpos($_POST['charset'],",")>0)) {
+ $input_errors[] = "',' aren't allowed.";
+ }
+ if ($_POST['rollbits'] && (!is_numeric($_POST['rollbits']) || ($_POST['rollbits'] < 1) || ($_POST['rollbits'] > 31))) {
+ $input_errors[] = "# of Bits to store Roll Id needs to be between 1..31.";
+ }
+ if ($_POST['ticketbits'] && (!is_numeric($_POST['ticketbits']) || ($_POST['ticketbits'] < 1) || ($_POST['ticketbits'] > 16))) {
+ $input_errors[] = "# of Bits to store Ticket Id needs to be between 1..16.";
+ }
+ if ($_POST['checksumbits'] && (!is_numeric($_POST['checksumbits']) || ($_POST['checksumbits'] < 1) || ($_POST['checksumbits'] > 31))) {
+ $input_errors[] = "# of Bits to store checksum needs to be between 1..31.";
+ }
+ if ($_POST['saveinterval'] && (!is_numeric($_POST['saveinterval']) || ($_POST['saveinterval'] < 1))) {
+ $input_errors[] = "Save interval in minutes cant be negative.";
+ }
+ if ($_POST['publickey'] && (!strstr($_POST['publickey'],"BEGIN PUBLIC KEY"))) {
+ $input_errors[] = "This doesn't look like an RSA Public key.";
+ }
+ if ($_POST['privatekey'] && (!strstr($_POST['privatekey'],"BEGIN RSA PRIVATE KEY"))) {
+ $input_errors[] = "This doesn't look like an RSA Private key.";
+ }
+
+ if (!$input_errors) {
+ $config['voucher']['enable'] = $_POST['enable'] ? true : false;
+ $config['voucher']['charset'] = $_POST['charset'];
+ $config['voucher']['rollbits'] = $_POST['rollbits'];
+ $config['voucher']['ticketbits'] = $_POST['ticketbits'];
+ $config['voucher']['checksumbits'] = $_POST['checksumbits'];
+ $config['voucher']['magic'] = $_POST['magic'];
+ $config['voucher']['saveinterval'] = $_POST['saveinterval'];
+ $config['voucher']['publickey'] = base64_encode($_POST['publickey']);
+ $config['voucher']['privatekey'] = base64_encode($_POST['privatekey']);
+ $config['voucher']['msgnoaccess'] = $_POST['msgnoaccess'];
+ $config['voucher']['msgexpired'] = $_POST['msgexpired'];
+
+ write_config();
+ voucher_configure();
+ if (isset($config['voucher']['enable']) && !isset($config['captiveportal']['enable'])) {
+ $savemsg = "Don't forget to configure and enable Captive Portal.";
+ }
+ }
+}
+include("head.inc");
+?>
+<?php include("fbegin.inc"); ?>
+<script type="text/javascript">
+<!--
+function enable_change(enable_change) {
+ var endis;
+ endis = !(document.iform.enable.checked || enable_change);
+
+ document.iform.charset.disabled = endis;
+ document.iform.rollbits.disabled = endis;
+ document.iform.ticketbits.disabled = endis;
+ document.iform.saveinterval.disabled = endis;
+ document.iform.checksumbits.disabled = endis;
+ document.iform.magic.disabled = endis;
+ document.iform.publickey.disabled = endis;
+ document.iform.privatekey.disabled = endis;
+ document.iform.msgnoaccess.disabled = endis;
+ document.iform.msgexpired.disabled = endis;
+}
+//-->
+</script>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<form action="services_captiveportal_vouchers.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="tab pane">
+ <tr><td class="tabnavtbl">
+ <ul id="tabnav">
+<?php
+ $tab_array = array();
+ $tab_array[] = array("Captive portal", false, "services_captiveportal.php");
+ $tab_array[] = array("Pass-through MAC", false, "services_captiveportal_mac.php");
+ $tab_array[] = array("Allowed IP addresses", false, "services_captiveportal_ip.php");
+ $tab_array[] = array("Vouchers", true, "services_captiveportal_vouchers.php");
+ $tab_array[] = array("File Manager", false, "services_captiveportal_filemanager.php");
+ display_top_tabs($tab_array);
+?>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0" summary="checkbox pane">
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+ <strong>Enable Vouchers</strong></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Voucher Rolls</td>
+ <td class="vtable">
+
+ <table width="100%" border="0" cellpadding="0" cellspacing="0" summary="content pane">
+ <tr>
+ <td width="10%" class="listhdrr">Roll#</td>
+ <td width="20%" class="listhdrr">Minutes/Ticket</td>
+ <td width="20%" class="listhdrr"># of Tickets</td>
+ <td width="35%" class="listhdr">Comment</td>
+ <td width="15%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach($a_roll as $rollent): ?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($rollent['number']); ?>&nbsp;
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($rollent['minutes']);?>&nbsp;
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($rollent['count']);?>&nbsp;
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($rollent['comment']); ?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list">
+ <?php if ($pconfig['enable']): ?>
+ <a href="services_captiveportal_vouchers_edit.php?id=<?=$i; ?>"><img src="e.gif" title="edit voucher" width="17" height="17" border="0" alt="edit voucher"></a>
+ <a href="services_captiveportal_vouchers.php?act=del&amp;id=<?=$i; ?>" onclick="return confirm('Do you really want to delete this voucher? This makes all vouchers from this roll invalid')"><img src="x.gif" title="delete vouchers" width="17" height="17" border="0" alt="delete vouchers"></a>
+ <a href="services_captiveportal_vouchers.php?act=csv&amp;id=<?=$i; ?>"><img src="log_s.gif" title="generate vouchers for this roll to CSV file" width="11" height="15" border="0" alt="generate vouchers for this roll to CSV file"></a>
+ <?php endif;?>
+ </td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="4"></td>
+ <?php if ($pconfig['enable']): ?>
+ <td class="list"> <a href="services_captiveportal_vouchers_edit.php"><img src="plus.gif" title="add voucher" width="17" height="17" border="0" alt="add voucher"></a></td>
+ <?php endif;?>
+ </tr>
+ </table>
+<?php if ($pconfig['enable']): ?>
+Create, generate and activate Rolls with Vouchers that allow access through the
+captive portal for the configured time. Once a voucher is activated,
+its clock is started and runs uninterrupted until it expires. During that
+time, the voucher can be re-used from the same or a different computer. If the voucher
+is used again from another computer, the previous session is stopped.
+<?php else: ?>
+Enable Voucher support first using the checkbox above and hit Save at the bottom.</td>
+<?php endif;?>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Voucher public key</td>
+ <td class="vtable">
+ <textarea name="publickey" cols="65" rows="4" id="publickey" class="formpre"><?=htmlspecialchars($pconfig['publickey']);?></textarea>
+ <br>
+ Paste an RSA public key (64 Bit or smaller) in PEM format here. This key is used to decrypt vouchers.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Voucher private key</td>
+ <td class="vtable">
+ <textarea name="privatekey" cols="65" rows="5" id="privatekey" class="formpre"><?=htmlspecialchars($pconfig['privatekey']);?></textarea>
+ <br>
+ Paste an RSA private key (64 Bit or smaller) in PEM format here. This key is only used to generate encrypted vouchers and doesn't need to be available if the vouchers have been generated offline.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Character set</td>
+ <td width="78%" class="vtable">
+ <input name="charset" type="text" class="formfld" id="charset" size="80" value="<?=htmlspecialchars($pconfig['charset']);?>">
+ <br>
+ Tickets are generated with the specified character set. It should contain printable characters (numbers, lower case and upper case letters) that are hard to confuse with others. Avoid e.g. 0/O and l/1.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq"># of Roll Bits</td>
+ <td width="78%" class="vtable">
+ <input name="rollbits" type="text" class="formfld" id="rollbits" size="2" value="<?=htmlspecialchars($pconfig['rollbits']);?>">
+ <br>
+ Reserves a range in each voucher to store the Roll# it belongs to. Allowed range: 1..31. Sum of Roll+Ticket+Checksum bits must be one Bit less than the RSA key size.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq"># of Ticket Bits</td>
+ <td width="78%" class="vtable">
+ <input name="ticketbits" type="text" class="formfld" id="ticketbits" size="2" value="<?=htmlspecialchars($pconfig['ticketbits']);?>">
+ <br>
+ Reserves a range in each voucher to store the Ticket# it belongs to. Allowed range: 1..16. Using 16 bits allows a roll to have up to 65535 vouchers. A bit array, stored in RAM and in the config, is used to mark if a voucher has been used. A bit array for 65535 vouchers requires 8 KB of storage.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq"># of Checksum Bits</td>
+ <td width="78%" class="vtable">
+ <input name="checksumbits" type="text" class="formfld" id="checksumbits" size="2" value="<?=htmlspecialchars($pconfig['checksumbits']);?>">
+ <br>
+ Reserves a range in each voucher to store a simple checksum over Roll# and Ticket#. Allowed range is 0..31.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Magic Number</td>
+ <td width="78%" class="vtable">
+ <input name="magic" type="text" class="formfld" id="magic" size="20" value="<?=htmlspecialchars($pconfig['magic']);?>">
+ <br>
+ Magic number stored in every voucher. Verified during voucher check. Size depends on how many bits are left by Roll+Ticket+Checksum bits. If all bits are used, no magic number will be used and checked.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Save Interval</td>
+ <td width="78%" class="vtable">
+ <input name="saveinterval" type="text" class="formfld" id="saveinterval" size="4" value="<?=htmlspecialchars($pconfig['saveinterval']);?>">
+ Minutes<br>
+ The list of active and used vouchers can be stored in the system's configuration file once every x minutes to survive power outages. No save is done if no new vouchers have been activated. Enter 0 to never write runtime state to XML config.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Invalid Voucher Message</td>
+ <td width="78%" class="vtable">
+ <input name="msgnoaccess" type="text" class="formfld" id="msgnoaccess" size="80" value="<?=htmlspecialchars($pconfig['msgnoaccess']);?>">
+ Error message displayed for invalid vouchers on captive portal error page ($PORTAL_MESSAGE$).</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Expired Voucher Message</td>
+ <td width="78%" class="vtable">
+ <input name="msgexpired" type="text" class="formfld" id="msgexpired" size="80" value="<?=htmlspecialchars($pconfig['msgexpired']);?>">
+ Error message displayed for expired vouchers on paptive portal error page ($PORTAL_MESSAGE$).</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change(true)">
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list"><p class="vexpl">
+ <span class="red"><strong> Note:<br> </strong></span>
+ Changing any Voucher parameter (apart from managing the list of Rolls) on this page will render existing vouchers useless if they were generated with different settings.
+ </p>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+</form>
+<script type="text/javascript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
diff --git a/usr/local/www/services_captiveportal_vouchers_edit.php b/usr/local/www/services_captiveportal_vouchers_edit.php
new file mode 100644
index 0000000..701b4de
--- /dev/null
+++ b/usr/local/www/services_captiveportal_vouchers_edit.php
@@ -0,0 +1,181 @@
+<?php
+/*
+ Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+##|+PRIV
+##|*IDENT=page-services-captiveportal-voucher-edit
+##|*NAME=Services: Captive portal Voucher Rolls page
+##|*DESCR=Allow access to the 'Services: Captive portal Edit Voucher Rolls' page.
+##|*MATCH=services_captiveportal_vouchers_edit.php*
+##|-PRIV
+
+$pgtitle = array("Services", "Captive portal", "Edit Voucher Rolls");
+require("guiconfig.inc");
+require_once("voucher.inc");
+
+if (!is_array($config['voucher'])) {
+ $config['voucher'] = array();
+}
+
+if (!is_array($config['voucher']['roll'])) {
+ $config['voucher']['roll'] = array();
+}
+$a_roll = &$config['voucher']['roll'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_roll[$id]) {
+ $pconfig['number'] = $a_roll[$id]['number'];
+ $pconfig['count'] = $a_roll[$id]['count'];
+ $pconfig['minutes'] = $a_roll[$id]['minutes'];
+ $pconfig['comment'] = $a_roll[$id]['comment'];
+}
+
+$maxnumber = (1<<$config['voucher']['rollbits']) -1; // Highest Roll#
+$maxcount = (1<<$config['voucher']['ticketbits']) -1; // Highest Ticket#
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "number count minutes");
+ $reqdfieldsn = explode(",", "Number,Count,minutes");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (!is_numeric($_POST['number']) || $_POST['number'] >= $maxnumber)
+ $input_errors[] = "Roll number must be numeric and less than $maxnumber";
+
+ if (!is_numeric($_POST['count']) || $_POST['count'] < 1 || $_POST['count'] > $maxcount)
+ $input_errors[] = "A roll has at least one voucher and less than $maxcount.";
+
+ if (!is_numeric($_POST['minutes']) || $_POST['minutes'] < 1)
+ $input_errors[] = "Each voucher must be good for at least 1 minute.";
+
+ if (!$input_errors) {
+
+ if (isset($id) && $a_roll[$id])
+ $rollent = $a_roll[$id];
+
+ $rollent['number'] = $_POST['number'];
+ $rollent['minutes'] = $_POST['minutes'];
+ $rollent['comment'] = $_POST['comment'];
+
+ /* New Roll or modified voucher count: create bitmask */
+ $voucherlck = lock('voucher');
+ if ($_POST['count'] != $rollent['count']) {
+ $rollent['count'] = $_POST['count'];
+ $len = ($rollent['count']>>3) + 1; // count / 8 +1
+ $rollent['used'] = base64_encode(str_repeat("\000",$len)); // 4 bitmask
+ $rollent['active'] = array();
+ voucher_write_used_db($rollent['number'], $rollent['used']);
+ voucher_write_active_db($rollent['number'], array()); // create empty DB
+ voucher_log(LOG_INFO, "All {$rollent['count']} vouchers from Roll {$rollent['number']} marked unused");
+ } else {
+ // existing roll has been modified but without changing the count
+ // read active and used DB from ramdisk and store it in XML config
+ $rollent['used'] = base64_encode(voucher_read_used_db($rollent['number']));
+ $activent = array();
+ $db = array();
+ $active_vouchers = voucher_read_active_db($rollent['number'], $rollent['minutes']);
+ foreach($active_vouchers as $voucher => $line) {
+ list($timestamp, $minutes) = explode(",", $line);
+ $activent['voucher'] = $voucher;
+ $activent['timestamp'] = $timestamp;
+ $activent['minutes'] = $minutes;
+ $db[] = $activent;
+ }
+ $rollent['active'] = $db;
+ }
+ unlock($voucherlck);
+
+ if (isset($id) && $a_roll[$id])
+ $a_roll[$id] = $rollent;
+ else
+ $a_roll[] = $rollent;
+
+ write_config();
+
+ header("Location: services_captiveportal_vouchers.php");
+ exit;
+ }
+}
+
+include("head.inc");
+?>
+<?php include("fbegin.inc"); ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<form action="services_captiveportal_vouchers_edit.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0" summary="content pane">
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Roll#</td>
+ <td width="78%" class="vtable">
+ <?=$mandfldhtml;?><input name="number" type="text" class="formfld" id="number" size="10" value="<?=htmlspecialchars($pconfig['number']);?>">
+ <br>
+ <span class="vexpl">Enter the Roll# (0..<?=htmlspecialchars($maxnumber);?>) found on top of the generated/printed vouchers.</span>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Minutes per Ticket</td>
+ <td width="78%" class="vtable">
+ <?=$mandfldhtml;?><input name="minutes" type="text" class="formfld" id="minutes" size="10" value="<?=htmlspecialchars($pconfig['minutes']);?>">
+ <br>
+ <span class="vexpl">Defines the time in minutes that a user is allowed access. The clock starts ticking the first time a voucher is used for authentication.</span>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Count</td>
+ <td width="78%" class="vtable">
+ <?=$mandfldhtml;?><input name="count" type="text" class="formfld" id="count" size="10" value="<?=htmlspecialchars($pconfig['count']);?>">
+ <br>
+ <span class="vexpl">Enter the number of vouchers (1..<?=htmlspecialchars($maxcount);?>) found on top of the generated/printed vouchers. WARNING: Changing this number for an existing Roll will mark all vouchers as unused again.</span>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Comment</td>
+ <td width="78%" class="vtable">
+ <?=$mandfldhtml;?><input name="comment" type="text" class="formfld" id="comment" size="60" value="<?=htmlspecialchars($pconfig['comment']);?>">
+ <br>
+ <span class="vexpl">Can be used to further identify this roll. Ignored by the system.</span>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <?php if (isset($id) && $a_roll[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+ </form>
+<?php include("fend.inc"); ?>
diff --git a/usr/local/www/services_dhcp.php b/usr/local/www/services_dhcp.php
index 99651cb..c31fa96 100755
--- a/usr/local/www/services_dhcp.php
+++ b/usr/local/www/services_dhcp.php
@@ -50,6 +50,8 @@ if(!$g['services_dhcp_server_enable']) {
function dhcp_clean_leases() {
global $g, $config;
$leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
+ if (!file_exists($leasesfile))
+ return;
/* Build list of static MACs */
$staticmacs = array();
foreach($config['interfaces'] as $ifname => $ifarr)
@@ -139,9 +141,9 @@ if (is_array($config['dhcpd'][$if])){
$pconfig['rootpath'] = $config['dhcpd'][$if]['rootpath'];
$pconfig['failover_peerip'] = $config['dhcpd'][$if]['failover_peerip'];
$pconfig['netmask'] = $config['dhcpd'][$if]['netmask'];
+ $pconfig['numberoptions'] = $config['dhcpd'][$if]['numberoptions'];
if (!is_array($config['dhcpd'][$if]['staticmap']))
$config['dhcpd'][$if]['staticmap'] = array();
- staticmaps_sort($if);
$a_maps = &$config['dhcpd'][$if]['staticmap'];
}
@@ -294,6 +296,20 @@ if ($_POST) {
$config['dhcpd'][$if]['filename'] = $_POST['filename'];
$config['dhcpd'][$if]['rootpath'] = $_POST['rootpath'];
+ // Handle the custom options rowhelper
+ $numbervalue = array();
+ unset($config['dhcpd'][$if]['numberoptions']['item']);
+ for($x=0; $x<isset($_POST["number{$x}"]); $x++) {
+ if(is_int(intval($_POST["number{$x}"]))) {
+ $numbervalue['number'] = htmlspecialchars($_POST["number{$x}"]);
+ $numbervalue['value'] = htmlspecialchars($_POST["value{$x}"]);
+ $config['dhcpd'][$if]['numberoptions']['item'][] = $numbervalue;
+ }
+ }
+
+ // Reload the new pconfig variable that the forum uses.
+ $pconfig['numberoptions'] = $config['dhcpd'][$if]['numberoptions'];
+
write_config();
/* static arp configuration */
@@ -310,17 +326,13 @@ if ($_POST) {
if (isset($config['dnsmasq']['regdhcpstatic'])) {
$retvaldns = services_dnsmasq_configure();
if ($retvaldns == 0) {
- if (file_exists($d_hostsdirty_path))
- unlink($d_hostsdirty_path);
- if (file_exists($d_staticmapsdirty_path))
- unlink($d_staticmapsdirty_path);
+ clear_subsystem_dirty('hosts');
+ clear_subsystem_dirty('staticmaps');
}
} else {
$retvaldhcp = services_dhcpd_configure();
- if ($retvaldhcp == 0) {
- if (file_exists($d_staticmapsdirty_path))
- unlink($d_staticmapsdirty_path);
- }
+ if ($retvaldhcp == 0)
+ clear_subsystem_dirty('staticmaps');
}
if($retvaldhcp == 1 || $retvaldns == 1)
$retval = 1;
@@ -333,9 +345,9 @@ if ($_GET['act'] == "del") {
unset($a_maps[$_GET['id']]);
write_config();
if(isset($config['dhcpd'][$if]['enable'])) {
- touch($d_staticmapsdirty_path);
+ mark_subsystem_dirty('staticmaps');
if (isset($config['dnsmasq']['regdhcpstatic']))
- touch($d_hostsdirty_path);
+ mark_subsystem_dirty('hosts');
}
header("Location: services_dhcp.php?if={$if}");
exit;
@@ -347,67 +359,83 @@ include("head.inc");
?>
-<script type="text/javascript" language="JavaScript">
+<script type="text/javascript" src="/javascript/row_helper.js">
+</script>
-function enable_change(enable_over) {
- var endis;
- endis = !(document.iform.enable.checked || enable_over);
- document.iform.range_from.disabled = endis;
- document.iform.range_to.disabled = endis;
- document.iform.wins1.disabled = endis;
- document.iform.wins2.disabled = endis;
- document.iform.dns1.disabled = endis;
- document.iform.dns2.disabled = endis;
- document.iform.deftime.disabled = endis;
- document.iform.maxtime.disabled = endis;
- document.iform.gateway.disabled = endis;
- document.iform.failover_peerip.disabled = endis;
- document.iform.domain.disabled = endis;
- document.iform.domainsearchlist.disabled = endis;
- document.iform.staticarp.disabled = endis;
- document.iform.ddnsdomain.disabled = endis;
- document.iform.ddnsupdate.disabled = endis;
- document.iform.ntp1.disabled = endis;
- document.iform.ntp2.disabled = endis;
- document.iform.tftp.disabled = endis;
- document.iform.ldap.disabled = endis;
- document.iform.netboot.disabled = endis;
- document.iform.nextserver.disabled = endis;
- document.iform.filename.disabled = endis;
- document.iform.rootpath.disabled = endis;
- document.iform.denyunknown.disabled = endis;
-}
+<script type="text/javascript">
+ rowname[0] = "number";
+ rowtype[0] = "textbox";
+ rowsize[0] = "10";
+ rowname[1] = "value";
+ rowtype[1] = "textbox";
+ rowsize[1] = "55";
+</script>
-function show_ddns_config() {
- document.getElementById("showddnsbox").innerHTML='';
- aodiv = document.getElementById('showddns');
- aodiv.style.display = "block";
-}
+<script type="text/javascript" language="JavaScript">
+ function enable_change(enable_over) {
+ var endis;
+ endis = !(document.iform.enable.checked || enable_over);
+ document.iform.range_from.disabled = endis;
+ document.iform.range_to.disabled = endis;
+ document.iform.wins1.disabled = endis;
+ document.iform.wins2.disabled = endis;
+ document.iform.dns1.disabled = endis;
+ document.iform.dns2.disabled = endis;
+ document.iform.deftime.disabled = endis;
+ document.iform.maxtime.disabled = endis;
+ document.iform.gateway.disabled = endis;
+ document.iform.failover_peerip.disabled = endis;
+ document.iform.domain.disabled = endis;
+ document.iform.domainsearchlist.disabled = endis;
+ document.iform.staticarp.disabled = endis;
+ document.iform.ddnsdomain.disabled = endis;
+ document.iform.ddnsupdate.disabled = endis;
+ document.iform.ntp1.disabled = endis;
+ document.iform.ntp2.disabled = endis;
+ document.iform.tftp.disabled = endis;
+ document.iform.ldap.disabled = endis;
+ document.iform.netboot.disabled = endis;
+ document.iform.nextserver.disabled = endis;
+ document.iform.filename.disabled = endis;
+ document.iform.rootpath.disabled = endis;
+ document.iform.denyunknown.disabled = endis;
+ }
-function show_ntp_config() {
- document.getElementById("showntpbox").innerHTML='';
- aodiv = document.getElementById('showntp');
- aodiv.style.display = "block";
-}
+ function show_shownumbervalue() {
+ document.getElementById("shownumbervaluebox").innerHTML='';
+ aodiv = document.getElementById('shownumbervalue');
+ aodiv.style.display = "block";
+ }
-function show_tftp_config() {
- document.getElementById("showtftpbox").innerHTML='';
- aodiv = document.getElementById('showtftp');
- aodiv.style.display = "block";
-}
+ function show_ddns_config() {
+ document.getElementById("showddnsbox").innerHTML='';
+ aodiv = document.getElementById('showddns');
+ aodiv.style.display = "block";
+ }
-function show_ldap_config() {
- document.getElementById("showldapbox").innerHTML='';
- aodiv = document.getElementById('showldap');
- aodiv.style.display = "block";
-}
+ function show_ntp_config() {
+ document.getElementById("showntpbox").innerHTML='';
+ aodiv = document.getElementById('showntp');
+ aodiv.style.display = "block";
+ }
-function show_netboot_config() {
- document.getElementById("shownetbootbox").innerHTML='';
- aodiv = document.getElementById('shownetboot');
- aodiv.style.display = "block";
-}
+ function show_tftp_config() {
+ document.getElementById("showtftpbox").innerHTML='';
+ aodiv = document.getElementById('showtftp');
+ aodiv.style.display = "block";
+ }
+ function show_ldap_config() {
+ document.getElementById("showldapbox").innerHTML='';
+ aodiv = document.getElementById('showldap');
+ aodiv.style.display = "block";
+ }
+
+ function show_netboot_config() {
+ document.getElementById("shownetbootbox").innerHTML='';
+ aodiv = document.getElementById('shownetboot');
+ aodiv.style.display = "block";
+ }
</script>
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
@@ -424,7 +452,7 @@ function show_netboot_config() {
exit;
}
?>
-<?php if (file_exists($d_staticmapsdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('staticmaps')): ?><p>
<?php print_info_box_np("The static mapping configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
@@ -462,7 +490,7 @@ function show_netboot_config() {
<tr>
<td width="22%" valign="top" class="vtable">&nbsp;</td>
<td width="78%" class="vtable">
- <input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+ <input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
<strong>Enable DHCP server on
<?=htmlspecialchars($iflist[$if]);?>
interface</strong></td>
@@ -470,7 +498,7 @@ function show_netboot_config() {
<tr>
<td width="22%" valign="top" class="vtable">&nbsp;</td>
<td width="78%" class="vtable">
- <input name="denyunknown" id="denyunknown" type="checkbox" value="yes" <?php if ($pconfig['denyunknown']) echo "checked"; ?>>
+ <input name="denyunknown" id="denyunknown" type="checkbox" value="yes" <?php if ($pconfig['denyunknown']) echo "checked"; ?>>
<strong>Deny unknown clients</strong><br>
If this is checked, only the clients defined below will get DHCP leases from this server. </td>
</tr>
@@ -519,43 +547,43 @@ function show_netboot_config() {
<td width="78%" class="vtable">
<input name="range_from" type="text" class="formfld unknown" id="range_from" size="20" value="<?=htmlspecialchars($pconfig['range_from']);?>">
&nbsp;to&nbsp; <input name="range_to" type="text" class="formfld unknown" id="range_to" size="20" value="<?=htmlspecialchars($pconfig['range_to']);?>">
- </td>
+ </td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell">WINS servers</td>
<td width="78%" class="vtable">
<input name="wins1" type="text" class="formfld unknown" id="wins1" size="20" value="<?=htmlspecialchars($pconfig['wins1']);?>"><br>
<input name="wins2" type="text" class="formfld unknown" id="wins2" size="20" value="<?=htmlspecialchars($pconfig['wins2']);?>">
- </td>
+ </td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell">DNS servers</td>
<td width="78%" class="vtable">
<input name="dns1" type="text" class="formfld unknown" id="dns1" size="20" value="<?=htmlspecialchars($pconfig['dns1']);?>"><br>
<input name="dns2" type="text" class="formfld unknown" id="dns2" size="20" value="<?=htmlspecialchars($pconfig['dns2']);?>"><br>
- NOTE: leave blank to use the system default DNS servers - this interface's IP if DNS forwarder is enabled, otherwise the servers configured on the General page.
- </td>
+ NOTE: leave blank to use the system default DNS servers - this interface's IP if DNS forwarder is enabled, otherwise the servers configured on the General page.
+ </td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell">Gateway</td>
<td width="78%" class="vtable">
<input name="gateway" type="text" class="formfld host" id="gateway" size="20" value="<?=htmlspecialchars($pconfig['gateway']);?>"><br>
- The default is to use the IP on this interface of the firewall as the gateway. Specify an alternate gateway here if this is not the correct gateway for your network.
- </td>
+ The default is to use the IP on this interface of the firewall as the gateway. Specify an alternate gateway here if this is not the correct gateway for your network.
+ </td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell">Domain-Name</td>
<td width="78%" class="vtable">
<input name="domain" type="text" class="formfld unknown" id="domain" size="20" value="<?=htmlspecialchars($pconfig['domain']);?>"><br>
- The default is to use the domainname of the router as DNS-Search string that is served via DHCP. Specify an alternate DNS-Search string here.
- </td>
+ The default is to use the domainname of the router as DNS-Search string that is served via DHCP. Specify an alternate DNS-Search string here.
+ </td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell">Domain-Searchlist</td>
<td width="78%" class="vtable">
<input name="domainsearchlist" type="text" class="formfld unknown" id="domainsearchlist" size="20" value="<?=htmlspecialchars($pconfig['domainsearchlist']);?>"><br>
- DNS-Searchlist: the DHCP server can serve a list of domains to be searched.
- </td>
+ DNS-Searchlist: the DHCP server can serve a list of domains to be searched.
+ </td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell">Default lease time</td>
@@ -565,7 +593,7 @@ function show_netboot_config() {
This is used for clients that do not ask for a specific
expiration time.<br>
The default is 7200 seconds.
- </td>
+ </td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell">Maximum lease time</td>
@@ -575,7 +603,7 @@ function show_netboot_config() {
This is the maximum lease time for clients that ask
for a specific expiration time.<br>
The default is 86400 seconds.
- </td>
+ </td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell">Failover peer IP:</td>
@@ -583,49 +611,53 @@ function show_netboot_config() {
<input name="failover_peerip" type="text" class="formfld host" id="failover_peerip" size="20" value="<?=htmlspecialchars($pconfig['failover_peerip']);?>"><br>
Leave blank to disable. Enter the REAL address of the other machine. Machines must be using CARP.
</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">
+ Static ARP
+ </td>
+ <td width="78%" class="vtable">
+ <table>
+ <tr>
+ <td>
+ <input valign="middle" type="checkbox" value="yes" name="staticarp" id="staticarp" <?php if($pconfig['staticarp']) echo " checked"; ?>>&nbsp;
+ </td>
+ <td>
+ <b>Enable Static ARP entries</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <span class="red"><strong>Note:</strong></span> Only the machines listed below will be able to communicate with the firewall on this NIC.
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">
+ Dynamic DNS
+ </td>
+ <td width="78%" class="vtable">
+ <div id="showddnsbox">
+ <input type="button" onClick="show_ddns_config()" value="Advanced"></input> - Show Dynamic DNS</a>
+ </div>
+ <div id="showddns" style="display:none">
+ <input valign="middle" type="checkbox" value="yes" name="ddnsupdate" id="ddnsupdate" <?php if($pconfig['ddnsupdate']) echo " checked"; ?>>&nbsp;
+ <b>Enable registration of DHCP client names in DNS.</b><br />
+ <p>
+ <input name="ddnsdomain" type="text" class="formfld unknown" id="ddnsdomain" size="20" value="<?=htmlspecialchars($pconfig['ddnsdomain']);?>"><br />
+ Note: Leave blank to disable dynamic DNS registration.<br />
+ Enter the dynamic DNS domain which will be used to register client names in the DNS server.
+ </div>
+ </td>
</tr>
- <tr>
- <td width="22%" valign="top" class="vncell">Static ARP</td>
- <td width="78%" class="vtable">
- <table>
- <tr>
- <td>
- <input valign="middle" type="checkbox" value="yes" name="staticarp" id="staticarp" <?php if($pconfig['staticarp']) echo " checked"; ?>>&nbsp;
- </td>
- <td>
- <b>Enable Static ARP entries</b>
- </td>
- </tr>
- <tr>
- <td>
- &nbsp;
- </td>
- <td>
- <span class="red"><strong>Note:</strong></span> Only the machines listed below will be able to communicate with the firewall on this NIC.
- </td>
- </tr>
- </table>
- </td>
- </tr>
- <tr>
- <td width="22%" valign="top" class="vncell">Dynamic DNS</td>
- <td width="78%" class="vtable">
- <div id="showddnsbox">
- <input type="button" onClick="show_ddns_config()" value="Advanced"></input> - Show Dynamic DNS</a>
- </div>
- <div id="showddns" style="display:none">
- <input valign="middle" type="checkbox" value="yes" name="ddnsupdate" id="ddnsupdate" <?php if($pconfig['ddnsupdate']) echo " checked"; ?>>&nbsp;
- <b>Enable registration of DHCP client names in DNS.</b><br />
- <p>
- <input name="ddnsdomain" type="text" class="formfld unknown" id="ddnsdomain" size="20" value="<?=htmlspecialchars($pconfig['ddnsdomain']);?>"><br />
- Note: Leave blank to disable dynamic DNS registration.<br />
- Enter the dynamic DNS domain which will be used to register client names in the DNS server.
- </div>
- </td>
- </tr>
- <tr>
- <td width="22%" valign="top" class="vncell">NTP servers</td>
- <td width="78%" class="vtable">
+ <tr>
+ <td width="22%" valign="top" class="vncell">NTP servers</td>
+ <td width="78%" class="vtable">
<div id="showntpbox">
<input type="button" onClick="show_ntp_config()" value="Advanced"></input> - Show NTP configuration</a>
</div>
@@ -634,10 +666,12 @@ function show_netboot_config() {
<input name="ntp2" type="text" class="formfld unknown" id="ntp2" size="20" value="<?=htmlspecialchars($pconfig['ntp2']);?>">
</div>
</td>
- </tr>
- <tr>
- <td width="22%" valign="top" class="vncell">TFTP server</td>
- <td width="78%" class="vtable">
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">
+ TFTP server
+ </td>
+ <td width="78%" class="vtable">
<div id="showtftpbox">
<input type="button" onClick="show_tftp_config()" value="Advanced"></input> - Show TFTP configuration</a>
</div>
@@ -646,76 +680,139 @@ function show_netboot_config() {
Leave blank to disable. Enter a full hostname or IP for the TFTP server.
</div>
</td>
- </tr>
- <tr>
- <td width="22%" valign="top" class="vncell">LDAP URI</td>
- <td width="78%" class="vtable">
- <div id="showldapbox">
- <input type="button" onClick="show_ldap_config()" value="Advanced"></input> - Show LDAP configuration</a>
- </div>
- <div id="showldap" style="display:none">
- <input name="ldap" type="text" class="formfld unknown" id="ldap" size="80" value="<?=htmlspecialchars($pconfig['ldap']);?>"><br>
- Leave blank to disable. Enter a full URI for the LDAP server in the form ldap://ldap.example.com/dc=example,dc=com
- </div>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">LDAP URI</td>
+ <td width="78%" class="vtable">
+ <div id="showldapbox">
+ <input type="button" onClick="show_ldap_config()" value="Advanced"></input> - Show LDAP configuration</a>
+ </div>
+ <div id="showldap" style="display:none">
+ <input name="ldap" type="text" class="formfld unknown" id="ldap" size="80" value="<?=htmlspecialchars($pconfig['ldap']);?>"><br>
+ Leave blank to disable. Enter a full URI for the LDAP server in the form ldap://ldap.example.com/dc=example,dc=com
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Enable Network booting</td>
+ <td width="78%" class="vtable">
+ <div id="shownetbootbox">
+ <input type="button" onClick="show_netboot_config()" value="Advanced"></input> - Show Network booting</a>
+ </div>
+ <div id="shownetboot" style="display:none">
+ <input valign="middle" type="checkbox" value="yes" name="netboot" id="netboot" <?php if($pconfig['netboot']) echo " checked"; ?>>&nbsp;
+ <b>Enables network booting.</b>
+ <p>
+ Enter the IP of the <b>next-server</b>
+ <input name="nextserver" type="text" class="formfld unknown" id="nextserver" size="20" value="<?=htmlspecialchars($pconfig['nextserver']);?>">
+ and the filename
+ <input name="filename" type="text" class="formfld unknown" id="filename" size="20" value="<?=htmlspecialchars($pconfig['filename']);?>"><br>
+ Note: You need both a filename and a boot server configured for this to work!
+ <p>
+ Enter the <b>root-path</b>-string
+ <input name="rootpath" type="text" class="formfld unknown" id="rootpath" size="90" value="<?=htmlspecialchars($pconfig['rootpath']);?>"><br>
+ Note: string-format: iscsi:(servername):(protocol):(port):(LUN):targetname
+ </div>
</td>
- </tr>
- <tr>
- <td width="22%" valign="top" class="vncell">Enable Network booting</td>
- <td width="78%" class="vtable">
- <div id="shownetbootbox">
- <input type="button" onClick="show_netboot_config()" value="Advanced"></input> - Show Network booting</a>
+ </tr>
+ <tr>
+
+
+ <td width="22%" valign="top" class="vncell">
+ Additional BOOTP/DHCP Options
+ </td>
+ <td width="78%" class="vtable">
+ <div id="shownumbervaluebox">
+ <input type="button" onClick="show_shownumbervalue()" value="Advanced"></input> - Show Additional BOOTP/DHCP Options</a>
+ </div>
+ <div id="shownumbervalue" style="display:none">
+ <table id="maintable">
+ <tbody>
+ <tr>
+ <td colspan="3">
+ <div style="padding:5px; margin-top: 16px; margin-bottom: 16px; border:1px dashed #000066; background-color: #ffffff; color: #000000; font-size: 8pt;" id="itemhelp">
+ Enter the DHCP option number and the value for each item you would like to include in the DHCP lease information. For a list of available options please visit this <a href="http://www.iana.org/assignments/bootp-dhcp-parameters/" target="_new">URL</a>.
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td><div id="onecolumn">Number</div></td>
+ <td><div id="twocolumn">Value</div></td>
+ </tr>
+ <?php $counter = 0; ?>
+ <?php
+ if($pconfig['numberoptions'])
+ foreach($pconfig['numberoptions']['item'] as $item):
+ ?>
+ <?php
+ $number = $item['number'];
+ $value = $item['value'];
+ ?>
+ <tr>
+ <td>
+ <input autocomplete="off" name="number<?php echo $counter; ?>" type="text" class="formfld" id="number<?php echo $counter; ?>" size="10" value="<?=htmlspecialchars($number);?>" />
+ </td>
+ <td>
+ <input autocomplete="off" name="value<?php echo $counter; ?>" type="text" class="formfld" id="value<?php echo $counter; ?>" size="55" value="<?=htmlspecialchars($value);?>" />
+ </td>
+ <td>
+ <input type="image" src="/themes/<?echo $g['theme'];?>/images/icons/icon_x.gif" onclick="removeRow(this); return false;" value="Delete" />
+ </td>
+ </tr>
+ <?php $counter++; ?>
+ <?php endforeach; ?>
+ </tbody>
+ <tfoot>
+ </tfoot>
+ </table>
+ <a onclick="javascript:addRowTo('maintable', 'formfldalias'); return false;" href="#">
+ <img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="add another entry" />
+ </a>
+ <script type="text/javascript">
+ field_counter_js = 2;
+ rows = 1;
+ totalrows = <?php echo $counter; ?>;
+ loaded = <?php echo $counter; ?>;
+ </script>
</div>
- <div id="shownetboot" style="display:none">
- <input valign="middle" type="checkbox" value="yes" name="netboot" id="netboot" <?php if($pconfig['netboot']) echo " checked"; ?>>&nbsp;
- <b>Enables network booting.</b>
- <p>
- Enter the IP of the <b>next-server</b>
- <input name="nextserver" type="text" class="formfld unknown" id="nextserver" size="20" value="<?=htmlspecialchars($pconfig['nextserver']);?>">
- and the filename
- <input name="filename" type="text" class="formfld unknown" id="filename" size="20" value="<?=htmlspecialchars($pconfig['filename']);?>"><br>
- Note: You need both a filename and a boot server configured for this to work!
- <p>
- Enter the <b>root-path</b>-string
- <input name="rootpath" type="text" class="formfld unknown" id="rootpath" size="90" value="<?=htmlspecialchars($pconfig['rootpath']);?>"><br>
- Note: string-format: iscsi:(servername):(protocol):(port):(LUN):targetname
- </div>
- </td>
- </tr>
- <tr>
- <td width="22%" valign="top">&nbsp;</td>
- <td width="78%">
- <input name="if" type="hidden" value="<?=$if;?>">
- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
- </td>
- </tr>
- <tr>
- <td width="22%" valign="top">&nbsp;</td>
- <td width="78%"> <p><span class="vexpl"><span class="red"><strong>Note:<br>
- </strong></span>The DNS servers entered in <a href="system.php">System:
- General setup</a> (or the <a href="services_dnsmasq.php">DNS
- forwarder</a>, if enabled) </span><span class="vexpl">will
- be assigned to clients by the DHCP server.<br>
- <br>
- The DHCP lease table can be viewed on the <a href="diag_dhcp_leases.php">Status:
- DHCP leases</a> page.<br>
- </span></p>
- </td>
- </tr>
- </table>
- <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
- <tr>
- <td width="25%" class="listhdrr">MAC address</td>
- <td width="15%" class="listhdrr">IP address</td>
- <td width="20%" class="listhdrr">Hostname</td>
- <td width="30%" class="listhdr">Description</td>
- <td width="10%" class="list">
- <table border="0" cellspacing="0" cellpadding="1">
- <tr>
+
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="if" type="hidden" value="<?=$if;?>">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%"> <p><span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>The DNS servers entered in <a href="system.php">System:
+ General setup</a> (or the <a href="services_dnsmasq.php">DNS
+ forwarder</a>, if enabled) </span><span class="vexpl">will
+ be assigned to clients by the DHCP server.<br>
+ <br>
+ The DHCP lease table can be viewed on the <a href="diag_dhcp_leases.php">Status:
+ DHCP leases</a> page.<br>
+ </span></p>
+ </td>
+ </tr>
+ </table>
+ <table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="25%" class="listhdrr">MAC address</td>
+ <td width="15%" class="listhdrr">IP address</td>
+ <td width="20%" class="listhdrr">Hostname</td>
+ <td width="30%" class="listhdr">Description</td>
+ <td width="10%" class="list">
+ <table border="0" cellspacing="0" cellpadding="1">
+ <tr>
<td valign="middle" width="17"></td>
- <td valign="middle"><a href="services_dhcp_edit.php?if=<?=$if;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td>
- </tr>
- </table>
- </td>
+ <td valign="middle"><a href="services_dhcp_edit.php?if=<?=$if;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
</tr>
<?php if(is_array($a_maps)): ?>
<?php $i = 0; foreach ($a_maps as $mapent): ?>
diff --git a/usr/local/www/services_dhcp_edit.php b/usr/local/www/services_dhcp_edit.php
index 3239d05..9ef4ab9 100755
--- a/usr/local/www/services_dhcp_edit.php
+++ b/usr/local/www/services_dhcp_edit.php
@@ -36,6 +36,16 @@
##|*MATCH=services_dhcp_edit.php*
##|-PRIV
+function staticmapcmp($a, $b) {
+ return ipcmp($a['ipaddr'], $b['ipaddr']);
+}
+
+function staticmaps_sort($ifgui) {
+ global $g, $config;
+
+ usort($config['dhcpd'][$ifgui]['staticmap'], "staticmapcmp");
+}
+
require_once('globals.inc');
if(!$g['services_dhcp_server_enable']) {
@@ -138,6 +148,7 @@ if ($_POST) {
$mapent['hostname'] = $_POST['hostname'];
$mapent['descr'] = $_POST['descr'];
+ staticmaps_sort($if);
if (isset($id) && $a_maps[$id])
$a_maps[$id] = $mapent;
else
@@ -146,9 +157,9 @@ if ($_POST) {
write_config();
if(isset($config['dhcpd'][$if]['enable'])) {
- touch($d_staticmapsdirty_path);
+ mark_subsystem_dirty('staticmaps');
if (isset($config['dnsmasq']['regdhcpstatic']))
- touch($d_hostsdirty_path);
+ mark_subsystem_dirty('hosts');
}
header("Location: services_dhcp.php?if={$if}");
diff --git a/usr/local/www/services_dnsmasq.php b/usr/local/www/services_dnsmasq.php
index 3f6e27b..1f93e2a 100755
--- a/usr/local/www/services_dnsmasq.php
+++ b/usr/local/www/services_dnsmasq.php
@@ -49,7 +49,6 @@ if (!is_array($config['dnsmasq']['hosts']))
if (!is_array($config['dnsmasq']['domainoverrides']))
$config['dnsmasq']['domainoverrides'] = array();
-hosts_sort();
$a_hosts = &$config['dnsmasq']['hosts'];
$a_domainOverrides = &$config['dnsmasq']['domainoverrides'];
@@ -68,10 +67,8 @@ if ($_POST) {
$retval = services_dnsmasq_configure();
$savemsg = get_std_save_message($retval);
- if ($retval == 0) {
- if (file_exists($d_hostsdirty_path))
- unlink($d_hostsdirty_path);
- }
+ if ($retval == 0)
+ clear_subsystem_dirty('hosts');
}
if ($_GET['act'] == "del") {
@@ -79,7 +76,7 @@ if ($_GET['act'] == "del") {
if ($a_hosts[$_GET['id']]) {
unset($a_hosts[$_GET['id']]);
write_config();
- touch($d_hostsdirty_path);
+ mark_subsystem_dirty('hosts');
header("Location: services_dnsmasq.php");
exit;
}
@@ -88,7 +85,7 @@ if ($_GET['act'] == "del") {
if ($a_domainOverrides[$_GET['id']]) {
unset($a_domainOverrides[$_GET['id']]);
write_config();
- touch($d_hostsdirty_path);
+ mark_subsystem_dirty('hosts');
header("Location: services_dnsmasq.php");
exit;
}
@@ -115,7 +112,7 @@ function enable_change(enable_over) {
<?php include("fbegin.inc"); ?>
<form action="services_dnsmasq.php" method="post" name="iform" id="iform">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_hostsdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('hosts')): ?><p>
<?php print_info_box_np("The DNS forwarder configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="6" cellspacing="0">
@@ -169,7 +166,7 @@ function enable_change(enable_over) {
</tr>
</table>
&nbsp;<br>
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <table class="sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="20%" class="listhdrr">Host</td>
<td width="25%" class="listhdrr">Domain</td>
diff --git a/usr/local/www/services_dnsmasq_domainoverride_edit.php b/usr/local/www/services_dnsmasq_domainoverride_edit.php
index 0491050..f816546 100755
--- a/usr/local/www/services_dnsmasq_domainoverride_edit.php
+++ b/usr/local/www/services_dnsmasq_domainoverride_edit.php
@@ -82,7 +82,7 @@ if ($_POST) {
else
$a_domainOverrides[] = $doment;
- touch($d_dnsmasqdirty_path);
+ mark_subsystem_dirty('dnsmasq');
write_config();
diff --git a/usr/local/www/services_dnsmasq_edit.php b/usr/local/www/services_dnsmasq_edit.php
index f14cf9d..26773b8 100755
--- a/usr/local/www/services_dnsmasq_edit.php
+++ b/usr/local/www/services_dnsmasq_edit.php
@@ -36,6 +36,18 @@
##|*MATCH=services_dnsmasq_edit.php*
##|-PRIV
+function hostcmp($a, $b) {
+ return strcasecmp($a['host'], $b['host']);
+}
+
+function hosts_sort() {
+ global $g, $config;
+
+ if (!is_array($config['dnsmasq']['hosts']))
+ return;
+
+ usort($config['dnsmasq']['hosts'], "hostcmp");
+}
require("guiconfig.inc");
@@ -94,12 +106,13 @@ if ($_POST) {
$hostent['ip'] = $_POST['ip'];
$hostent['descr'] = $_POST['descr'];
+ hosts_sort();
if (isset($id) && $a_hosts[$id])
$a_hosts[$id] = $hostent;
else
$a_hosts[] = $hostent;
- touch($d_hostsdirty_path);
+ mark_subsystem_dirty('hosts');
write_config();
diff --git a/usr/local/www/services_igmpproxy.php b/usr/local/www/services_igmpproxy.php
index c69e0a8..7307b15 100755
--- a/usr/local/www/services_igmpproxy.php
+++ b/usr/local/www/services_igmpproxy.php
@@ -86,7 +86,7 @@ include("head.inc");
<?php print_info_box_np("The IGMP entry list has been changed.<br>You must apply the changes in order for them to take effect.");?>
<?php endif; ?>
-<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="15%" class="listhdrr">Name</td>
<td width="10%" class="listhdrr">Type</td>
diff --git a/usr/local/www/services_proxyarp.php b/usr/local/www/services_proxyarp.php
index 51a29a0..d02c2d6 100755
--- a/usr/local/www/services_proxyarp.php
+++ b/usr/local/www/services_proxyarp.php
@@ -44,7 +44,6 @@ require("guiconfig.inc");
if (!is_array($config['proxyarp']['proxyarpnet'])) {
$config['proxyarp']['proxyarpnet'] = array();
}
-proxyarp_sort();
$a_proxyarp = &$config['proxyarp']['proxyarpnet'];
if ($_POST) {
@@ -54,17 +53,15 @@ if ($_POST) {
$retval = services_proxyarp_configure();
$savemsg = get_std_save_message($retval);
- if ($retval == 0) {
- if (file_exists($d_proxyarpdirty_path))
- unlink($d_proxyarpdirty_path);
- }
+ if ($retval == 0)
+ clear_subsystem_dirty('proxyarp');
}
if ($_GET['act'] == "del") {
if ($a_proxyarp[$_GET['id']]) {
unset($a_proxyarp[$_GET['id']]);
write_config();
- touch($d_proxyarpdirty_path);
+ mark_subsystem_dirty('proxyarp');
header("Location: services_proxyarp.php");
exit;
}
@@ -79,7 +76,7 @@ include("head.inc");
<?php include("fbegin.inc"); ?>
<form action="services_proxyarp.php" method="post">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_proxyarpdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('proxyarp')): ?><p>
<?php print_info_box_np("The proxy ARP configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/services_proxyarp_edit.php b/usr/local/www/services_proxyarp_edit.php
index 896424a..c84fdbc 100755
--- a/usr/local/www/services_proxyarp_edit.php
+++ b/usr/local/www/services_proxyarp_edit.php
@@ -36,6 +36,30 @@
##|*MATCH=services_proxyarp_edit.php*
##|-PRIV
+function proxyarpcmp($a, $b) {
+ if (isset($a['network']))
+ list($ast,$asn) = explode("/", $a['network']);
+ else if (isset($a['range'])) {
+ $ast = $a['range']['from'];
+ $asn = 32;
+ }
+ if (isset($b['network']))
+ list($bst,$bsn) = explode("/", $b['network']);
+ else if (isset($b['range'])) {
+ $bst = $b['range']['from'];
+ $bsn = 32;
+ }
+ if (ipcmp($ast, $bst) == 0)
+ return ($asn - $bsn);
+ else
+ return ipcmp($ast, $bst);
+}
+
+function proxyarp_sort() {
+ global $config;
+
+ usort($config['proxyarp']['proxyarpnet'], "proxyarpcmp");
+}
require("guiconfig.inc");
@@ -125,12 +149,13 @@ if ($_POST) {
$arpent['network'] = $_POST['subnet'] . "/" . $_POST['subnet_bits'];
$arpent['descr'] = $_POST['descr'];
+ proxyarp_sort();
if (isset($id) && $a_proxyarp[$id])
$a_proxyarp[$id] = $arpent;
else
$a_proxyarp[] = $arpent;
- touch($d_proxyarpdirty_path);
+ mark_subsystem_dirty('proxyarp');
write_config();
diff --git a/usr/local/www/services_wol.php b/usr/local/www/services_wol.php
index a04920b..89c3636 100755
--- a/usr/local/www/services_wol.php
+++ b/usr/local/www/services_wol.php
@@ -42,7 +42,6 @@ require("guiconfig.inc");
if (!is_array($config['wol']['wolentry'])) {
$config['wol']['wolentry'] = array();
}
-wol_sort();
$a_wol = &$config['wol']['wolentry'];
if($_GET['wakeall'] <> "") {
diff --git a/usr/local/www/services_wol_edit.php b/usr/local/www/services_wol_edit.php
index de0b3cd..e9b238e 100755
--- a/usr/local/www/services_wol_edit.php
+++ b/usr/local/www/services_wol_edit.php
@@ -36,6 +36,15 @@
##|*MATCH=services_wol_edit.php*
##|-PRIV
+function wolcmp($a, $b) {
+ return strcmp($a['descr'], $b['descr']);
+}
+
+function wol_sort() {
+ global $config;
+
+ usort($config['wol']['wolentry'], "wolcmp");
+}
require("guiconfig.inc");
@@ -85,6 +94,7 @@ if ($_POST) {
$wolent['mac'] = $_POST['mac'];
$wolent['descr'] = $_POST['descr'];
+ wol_sort();
if (isset($id) && $a_wol[$id])
$a_wol[$id] = $wolent;
else
diff --git a/usr/local/www/status_captiveportal.php b/usr/local/www/status_captiveportal.php
index 8895437..ab0e20d 100755
--- a/usr/local/www/status_captiveportal.php
+++ b/usr/local/www/status_captiveportal.php
@@ -36,11 +36,8 @@
##|*MATCH=status_captiveportal.php*
##|-PRIV
-
require("guiconfig.inc");
-$concurrent = `cat /var/db/captiveportal.db | wc -l`;
-
$pgtitle = array("Status: Captive portal");
include("head.inc");
@@ -64,14 +61,17 @@ function clientcmp($a, $b) {
}
$cpdb = array();
-if (file_exists("/var/db/captiveportal.db"))
- $cpcontents = file("/var/db/captiveportal.db", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+if (file_exists("{$g['vardb_path']}/captiveportal.db"))
+ $cpcontents = file("{$g['vardb_path']}/captiveportal.db", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
else
$cpcontents = array();
+
+$concurrent = count($cpcontents);
+
foreach ($cpcontents as $cpcontent) {
$cpent = explode(",", $cpcontent);
if ($_GET['showact'])
- $cpent[5] = captiveportal_get_last_activity($cpent[1]);
+ $cpent[5] = captiveportal_get_last_activity($cpent[2]);
$cpdb[] = $cpent;
}
if ($_GET['order']) {
@@ -88,7 +88,25 @@ if ($_GET['order']) {
usort($cpdb, "clientcmp");
}
?>
-<table class="sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
+
+<?php if (isset($config['voucher']['enable'])): ?>
+<form action="status_captiveportal.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="tab pane">
+<tr><td class="tabnavtbl">
+<?php
+ $tab_array = array();
+ $tab_array[] = array("Logged Users", true, "status_captiveportal.php");
+ $tab_array[] = array("Active Vouchers", false, "status_captiveportal_vouchers.php");
+ $tab_array[] = array("Voucher Rolls", false, "status_captiveportal_voucher_rolls.php");
+ $tab_array[] = array("Test Vouchers", false, "status_captiveportal_test.php");
+ display_top_tabs($tab_array);
+?>
+</td></tr>
+<tr>
+<td class="tabcont">
+<? endif; ?>
+
+<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="listhdrr"><a href="?order=ip&amp;showact=<?=$_GET['showact'];?>"><?=gettext("IP address");?></a></td>
<td class="listhdrr"><a href="?order=mac&amp;showact=<?=$_GET['showact'];?>"><?=gettext("MAC address");?></a></td>
@@ -115,6 +133,14 @@ if ($_GET['order']) {
</tr>
<?php endforeach; ?>
</table>
+
+<?php if (isset($config['voucher']['enable'])): ?>
+</td>
+</tr>
+</table>
+</form>
+<?php endif; ?>
+
<form action="status_captiveportal.php" method="get" style="margin: 14px;">
<input type="hidden" name="order" value="<?=$_GET['order'];?>" />
<?php if ($_GET['showact']): ?>
diff --git a/usr/local/www/status_captiveportal_test.php b/usr/local/www/status_captiveportal_test.php
new file mode 100644
index 0000000..fd5cf73
--- /dev/null
+++ b/usr/local/www/status_captiveportal_test.php
@@ -0,0 +1,95 @@
+<?php
+/*
+ Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+##|+PRIV
+##|*IDENT=page-status-captiveportal-test
+##|*NAME=Status: Captive portal test Vouchers page
+##|*DESCR=Allow access to the 'Status: Captive portal Test Vouchers' page.
+##|*MATCH=status_captiveportal_test.php*
+##|-PRIV
+
+$pgtitle = array("Status", "Captive portal", "Test Vouchers");
+require("guiconfig.inc");
+require_once("voucher.inc");
+
+include("head.inc");
+include("fbegin.inc");
+?>
+
+<form action="status_captiveportal_test.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="tab pane">
+<tr><td class="tabnavtbl">
+<?php
+ $tab_array = array();
+ $tab_array[] = array("Users", false, "status_captiveportal.php");
+ $tab_array[] = array("Active Vouchers", false, "status_captiveportal_vouchers.php");
+ $tab_array[] = array("Voucher Rolls", false, "status_captiveportal_voucher_rolls.php");
+ $tab_array[] = array("Test Vouchers", true, "status_captiveportal_test.php");
+ display_top_tabs($tab_array);
+?>
+</td></tr>
+<tr>
+<td class="tabcont">
+
+<table width="100%" border="0" cellpadding="6" cellspacing="0" summary="content pane">
+ <tr>
+ <td valign="top" class="vncellreq">Voucher(s)</td>
+ <td class="vtable">
+ <textarea name="vouchers" cols="65" rows="3" type="text" id="vouchers" class="formpre"><?=htmlspecialchars($_POST['vouchers']);?></textarea>
+ <br>
+Enter multiple vouchers separated by space or newline. The remaining time, if valid, will be shown for each voucher.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Submit">
+ </td>
+ </tr>
+</table>
+</td></tr></table>
+</form>
+<p>
+<?php
+if ($_POST) {
+ if ($_POST['vouchers']) {
+ $test_results = voucher_auth($_POST['vouchers'], 1);
+ echo "<p><table border=\"0\" cellspacing=\"0\" cellpadding=\"4\" width=\"100%\">\n";
+ foreach ($test_results as $result) {
+ if (strpos($result, " good ") || strpos($result, " granted ")) {
+ echo "<tr><td bgcolor=\"#D9DEE8\"><img src=\"/pass.gif\"></td>";
+ echo "<td bgcolor=\"#D9DEE8\">$result</td></tr>";
+ } else {
+ echo "<tr><td bgcolor=\"#FFD9D1\"><img src=\"/block.gif\"></td>";
+ echo "<td bgcolor=\"#FFD9D1\">$result</td></tr>";
+ }
+ }
+ echo "</table></p>";
+ }
+}
+
+include("fend.inc");
+?>
diff --git a/usr/local/www/status_captiveportal_voucher_rolls.php b/usr/local/www/status_captiveportal_voucher_rolls.php
new file mode 100644
index 0000000..5e8a49f
--- /dev/null
+++ b/usr/local/www/status_captiveportal_voucher_rolls.php
@@ -0,0 +1,109 @@
+<?php
+/*
+ Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+##|+PRIV
+##|*IDENT=page-status-captiveportal-voucher-rolls
+##|*NAME=Status: Captive portal Voucher Rolls page
+##|*DESCR=Allow access to the 'Status: Captive portal Voucher Rolls' page.
+##|*MATCH=status_captiveportal_voucher_rolls.php*
+##|-PRIV
+
+$pgtitle = array("Status", "Captive portal", "Voucher Rolls");
+require("guiconfig.inc");
+require_once("voucher.inc");
+
+if (!is_array($config['voucher']['roll'])) {
+ $config['voucher']['roll'] = array();
+}
+$a_roll = &$config['voucher']['roll'];
+
+include("head.inc");
+include("fbegin.inc");
+?>
+
+<form action="status_captiveportal_voucher_rolls.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="tab pane">
+<tr><td class="tabnavtbl">
+<?php
+ $tab_array = array();
+ $tab_array[] = array("Users", false, "status_captiveportal.php");
+ $tab_array[] = array("Active Vouchers", false, "status_captiveportal_vouchers.php");
+ $tab_array[] = array("Voucher Rolls", true, "status_captiveportal_voucher_rolls.php");
+ $tab_array[] = array("Test Vouchers", false, "status_captiveportal_test.php");
+ display_top_tabs($tab_array);
+?>
+</td></tr>
+<tr>
+<td class="tabcont">
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="content pane">
+ <tr>
+ <td class="listhdrr">Roll#</td>
+ <td class="listhdrr">Minutes/Ticket</td>
+ <td class="listhdrr"># of Tickets</td>
+ <td class="listhdrr">Comment</td>
+ <td class="listhdrr">used</td>
+ <td class="listhdrr">active</td>
+ <td class="listhdr">ready</td>
+ </tr>
+<?php
+ $voucherlck = lock('voucher');
+ $i = 0; foreach($a_roll as $rollent):
+ $used = voucher_used_count($rollent['number']);
+ $active = count(voucher_read_active_db($rollent['number']),$rollent['minutes']);
+ $ready = $rollent['count'] - $used;
+?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($rollent['number']); ?>&nbsp;
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($rollent['minutes']);?>&nbsp;
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($rollent['count']);?>&nbsp;
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($rollent['comment']); ?>&nbsp;
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($used); ?>&nbsp;
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($active); ?>&nbsp;
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($ready); ?>&nbsp;
+ </td>
+ </tr>
+ <?php $i++; endforeach; unlock($voucherlck); ?>
+</table>
+</td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
diff --git a/usr/local/www/status_captiveportal_vouchers.php b/usr/local/www/status_captiveportal_vouchers.php
new file mode 100644
index 0000000..5599c37
--- /dev/null
+++ b/usr/local/www/status_captiveportal_vouchers.php
@@ -0,0 +1,117 @@
+<?php
+/*
+ Copyright (C) 2007 Marcel Wiget <mwiget@mac.com>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+##|+PRIV
+##|*IDENT=page-status-captiveportal-vouchers
+##|*NAME=Status: Captive portal Vouchers page
+##|*DESCR=Allow access to the 'Status: Captive portal Vouchers' page.
+##|*MATCH=status_captiveportal_vouchers.php*
+##|-PRIV
+
+$pgtitle = array("Status", "Captive portal", "Vouchers");
+require("guiconfig.inc");
+require_once("voucher.inc");
+
+function clientcmp($a, $b) {
+ global $order;
+ return strcmp($a[$order], $b[$order]);
+}
+
+if (!is_array($config['voucher']['roll'])) {
+ $config['voucher']['roll'] = array();
+}
+$a_roll = $config['voucher']['roll'];
+
+$db = array();
+
+foreach($a_roll as $rollent) {
+ $roll = $rollent['number'];
+ $minutes = $rollent['minutes'];
+ $active_vouchers = file("{$g['vardb_path']}/voucher_active_$roll.db", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+ foreach($active_vouchers as $voucher => $line) {
+ list($voucher,$timestamp, $minutes) = explode(",", $line);
+ $remaining = (($timestamp + 60*$minutes) - time());
+ if ($remaining > 0) {
+ $dbent[0] = $voucher;
+ $dbent[1] = $roll;
+ $dbent[2] = $timestamp;
+ $dbent[3] = intval($remaining/60);
+ $dbent[4] = $timestamp + 60*$minutes; // expires at
+ $db[] = $dbent;
+ }
+ }
+}
+
+if ($_GET['order']) {
+ $order = $_GET['order'];
+ usort($db, "clientcmp");
+}
+
+include("head.inc");
+include("fbegin.inc");
+?>
+
+<form action="status_captiveportal_vouchers.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="tab pane">
+<tr><td class="tabnavtbl">
+<?php
+ $tab_array = array();
+ $tab_array[] = array("Users", false, "status_captiveportal.php");
+ $tab_array[] = array("Active Vouchers", true, "status_captiveportal_vouchers.php");
+ $tab_array[] = array("Voucher Rolls", false, "status_captiveportal_voucher_rolls.php");
+ $tab_array[] = array("Test Vouchers", false, "status_captiveportal_test.php");
+ display_top_tabs($tab_array);
+?>
+</td></tr>
+<tr>
+<td class="tabcont">
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="content pane">
+ <tr>
+ <td class="listhdrr"><a href="?order=0&showact=<?=$_GET['showact'];?>">Voucher</a></td>
+ <td class="listhdrr"><a href="?order=1&showact=<?=$_GET['showact'];?>">Roll</a></td>
+ <td class="listhdrr"><a href="?order=2&showact=<?=$_GET['showact'];?>">Activated at</a></td>
+ <td class="listhdrr"><a href="?order=3&showact=<?=$_GET['showact'];?>">Expires in</a></td>
+ <td class="listhdr"><a href="?order=4&showact=<?=$_GET['showact'];?>">Expires at</a></td>
+ <td class="list"></td>
+ </tr>
+<?php foreach ($db as $dbent): ?>
+ <tr>
+ <td class="listlr"><?=$dbent[0];?></td>
+ <td class="listr"><?=$dbent[1];?></td>
+ <td class="listr"><?=htmlspecialchars(date("m/d/Y H:i:s", $dbent[2]));?></td>
+ <td class="listr"><?=$dbent[3];?> min</td>
+ <td class="listr"><?=htmlspecialchars(date("m/d/Y H:i:s", $dbent[4]));?></td>
+ <td class="list"></td>
+ </tr>
+<?php endforeach; ?>
+</table>
+</td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
diff --git a/usr/local/www/status_gateways.php b/usr/local/www/status_gateways.php
index 048c901..e8b0702 100755
--- a/usr/local/www/status_gateways.php
+++ b/usr/local/www/status_gateways.php
@@ -66,7 +66,7 @@ include("head.inc");
<tr>
<td>
<div id="mainarea">
- <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="10%" class="listhdrr">Name</td>
<td width="10%" class="listhdrr">Gateway</td>
diff --git a/usr/local/www/status_graph.php b/usr/local/www/status_graph.php
index 2b58bad..56e1398 100755
--- a/usr/local/www/status_graph.php
+++ b/usr/local/www/status_graph.php
@@ -40,17 +40,18 @@
##|-PRIV
+
require("guiconfig.inc");
if ($_POST['width'])
$width = $_POST['width'];
else
- $width = "550";
+ $width = "100%";
if ($_POST['height'])
$height = $_POST['height'];
else
- $height = "275";
+ $height = "200";
if ($_GET['if'])
@@ -59,14 +60,101 @@ else
$curif = "wan";
$pgtitle = array("Status","Traffic Graph");
+
include("head.inc");
?>
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+
+<script src="/javascript/scriptaculous/prototype.js" type="text/javascript"></script>
+<script src="/javascript/scriptaculous/scriptaculous.js" type="text/javascript"></script>
+<script language="javascript" type="text/javascript">
+
+function updateBandwidth(){
+ var hostinterface = "<?php echo $curif; ?>";
+ bandwidthAjax(hostinterface);
+}
+
+function bandwidthAjax(hostinterface) {
+ uri = "bandwidth_by_ip.php?if=" + hostinterface;
+ var opt = {
+ // Use GET
+ method: 'get',
+ asynchronous: true,
+ // Handle 404
+ on404: function(t) {
+ alert('Error 404: location "' + t.statusText + '" was not found.');
+ },
+ // Handle other errors
+ onFailure: function(t) {
+ alert('Error ' + t.status + ' -- ' + t.statusText);
+ },
+ onSuccess: function(t) {
+ updateBandwidthHosts(t.responseText);
+ }
+ }
+ new Ajax.Request(uri, opt);
+}
+
+function updateBandwidthHosts(data){
+ var hosts_split = data.split("|");
+ d = document;
+ //parse top ten bandwidth abuser hosts
+ for (var y=0; y<10; y++){
+ if (hosts_split[y] != "" && hosts_split[y] != "no info"){
+ if (hosts_split[y]) {
+ hostinfo = hosts_split[y].split(";");
+
+ //update host ip info
+ var HostIpID = "hostip" + y;
+ var hostip = d.getElementById(HostIpID);
+ hostip.innerHTML = hostinfo[0];
+
+ //update bandwidth inbound to host
+ var hostbandwidthInID = "bandwidthin" + y;
+ var hostbandwidthin = d.getElementById(hostbandwidthInID);
+ hostbandwidthin.innerHTML = hostinfo[1] + " Bytes/sec";
+
+ //update bandwidth outbound from host
+ var hostbandwidthOutID = "bandwidthout" + y;
+ var hostbandwidthOut = d.getElementById(hostbandwidthOutID);
+ hostbandwidthOut.innerHTML = hostinfo[2] + " Bytes/sec";
+
+ //make the row appear if hidden
+ var rowid = "host" + y;
+ textlink = d.getElementById(rowid);
+ if (textlink.style.display == "none"){
+ //hide rows that contain no data
+ Effect.Appear(rowid, {duration:1});
+ }
+ }
+ }
+ else
+ {
+ var rowid = "host" + y;
+ textlink = d.getElementById(rowid);
+ if (textlink.style.display != "none"){
+ //hide rows that contain no data
+ Effect.Fade(rowid, {duration:2});
+ }
+ }
+ }
+
+ setTimeout('updateBandwidth()', 3000);
+}
+
+
+</script>
+
<?php include("fbegin.inc"); ?>
<?php
-$ifdescrs = get_configured_interface_with_descr();
+$ifdescrs = array('wan' => 'WAN', 'lan' => 'LAN');
+
+for($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
+ if(isset($config['interfaces']['opt' . $j]['enable']))
+ $ifdescrs['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+}
/* link the ipsec interface magically */
if (isset($config['ipsec']['enable']) || isset($config['ipsec']['mobileclients']['enable']))
@@ -89,13 +177,112 @@ foreach ($ifdescrs as $ifn => $ifd) {
<p><form method="post" action="status_graph.php">
</form>
<p>
-<div align="center">
- <object data="graph.php?ifnum=<?=$curif;?>&amp;ifname=<?=rawurlencode($ifdescrs[$curif]);?>" type="image/svg+xml" width="550" height="275">
- <param name="src" value="graph.php?ifnum=<?=$curif;?>&amp;ifname=<?=rawurlencode($ifdescrs[$curif]);?>" />
- Your browser does not support the type SVG! You need to either use Firefox or download the Adobe SVG plugin.
- </object>
+<div>
+ <div class="widgetdiv" style="padding: 5px; float:left; width:46%">
+ <object data="graph.php?ifnum=<?=$curif;?>&amp;ifname=<?=rawurlencode($ifdescrs[$curif]);?>" type="image/svg+xml" width="<?=$width;?>" height="<?=$height;?>">
+ <param name="src" value="graph.php?ifnum=<?=$curif;?>&amp;ifname=<?=rawurlencode($ifdescrs[$curif]);?>" />
+ Your browser does not support the type SVG! You need to either use Firefox or download the Adobe SVG plugin.
+ </object>
+ </div>
+ <div class="widgetdiv" style="padding: 5px; float:right; width:48%">
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td class="listtopic" valign="top">Host IP</td>
+ <td class="listtopic" valign="top">Bandwidth In</td>
+ <td class="listtopic" valign="top">Bandwidth Out</td>
+ </tr>
+ <tr id="host0" style="display:none">
+ <td id="hostip0" class="vncell">
+ </td>
+ <td id="bandwidthin0" class="listr">
+ </td>
+ <td id="bandwidthout0" class="listr">
+ </td>
+ </tr>
+ <tr id="host1" style="display:none">
+ <td id="hostip1" class="vncell">
+ </td>
+ <td id="bandwidthin1" class="listr">
+ </td>
+ <td id="bandwidthout1" class="listr">
+ </td>
+ </tr>
+ <tr id="host2" style="display:none">
+ <td id="hostip2" class="vncell">
+ </td>
+ <td id="bandwidthin2" class="listr">
+ </td>
+ <td id="bandwidthout2" class="listr">
+ </td>
+ </tr>
+ <tr id="host3" style="display:none">
+ <td id="hostip3" class="vncell">
+ </td>
+ <td id="bandwidthin3" class="listr">
+ </td>
+ <td id="bandwidthout3" class="listr">
+ </td>
+ </tr>
+ <tr id="host4" style="display:none">
+ <td id="hostip4" class="vncell">
+ </td>
+ <td id="bandwidthin4" class="listr">
+ </td>
+ <td id="bandwidthout4" class="listr">
+ </td>
+ </tr>
+ <tr id="host5" style="display:none">
+ <td id="hostip5" class="vncell">
+ </td>
+ <td id="bandwidthin5" class="listr">
+ </td>
+ <td id="bandwidthout5" class="listr">
+ </td>
+ </tr>
+ <tr id="host6" style="display:none">
+ <td id="hostip6" class="vncell">
+ </td>
+ <td id="bandwidthin6" class="listr">
+ </td>
+ <td id="bandwidthout6" class="listr">
+ </td>
+ </tr>
+ <tr id="host7" style="display:none">
+ <td id="hostip7" class="vncell">
+ </td>
+ <td id="bandwidthin7" class="listr">
+ </td>
+ <td id="bandwidthout7" class="listr">
+ </td>
+ </tr>
+ <tr id="host8" style="display:none">
+ <td id="hostip8" class="vncell">
+ </td>
+ <td id="bandwidthin8" class="listr">
+ </td>
+ <td id="bandwidthout8" class="listr">
+ </td>
+ </tr>
+ <tr id="host9" style="display:none">
+ <td id="hostip9" class="vncell">
+ </td>
+ <td id="bandwidthin9" class="listr">
+ </td>
+ <td id="bandwidthout9" class="listr">
+ </td>
+ </tr>
+ </table>
+ </div>
</div>
<?php include("fend.inc"); ?>
+
+<script type="text/javascript">
+window.onload = function(in_event)
+ {
+ updateBandwidth();
+ }
+
+</script>
</body>
</html>
diff --git a/usr/local/www/status_openvpn.php b/usr/local/www/status_openvpn.php
index b8c0b86..b8cae6f 100644
--- a/usr/local/www/status_openvpn.php
+++ b/usr/local/www/status_openvpn.php
@@ -110,48 +110,54 @@ echo $buff;
?>
<?php foreach ($servers as $server): ?>
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <table style="padding-top:0px; padding-bottom:0px; padding-left:0px; padding-right:0px" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td colspan="6" class="listtopic">
Client connections for <?=$server['name'];?>
</td>
</tr>
<tr>
- <td class="listhdrr">Common Name</td>
- <td class="listhdrr">Real Address</td>
- <td class="listhdrr">Virtual Address</td>
- <td class="listhdrr">Connected Since</td>
- <td class="listhdrr">Bytes Sent</td>
- <td class="listhdrr">Bytes Received</td>
- </tr>
-
- <?php foreach ($server['conns'] as $conn): ?>
- <tr>
- <td class="listlr">
- <?=$conn['common_name'];?>
- </td>
- <td class="listr">
- <?=$conn['remote_host'];?>
- </td>
- <td class="listr">
- <?=$conn['virtual_addr'];?>
- </td>
- <td class="listr">
- <?=$conn['connect_time'];?>
+ <td>
+ <table style="padding-top:0px; padding-bottom:0px; padding-left:0px; padding-right:0px" class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td class="listhdrr">Common Name</td>
+ <td class="listhdrr">Real Address</td>
+ <td class="listhdrr">Virtual Address</td>
+ <td class="listhdrr">Connected Since</td>
+ <td class="listhdrr">Bytes Sent</td>
+ <td class="listhdrr">Bytes Received</td>
+ </tr>
+
+ <?php foreach ($server['conns'] as $conn): ?>
+ <tr>
+ <td class="listlr">
+ <?=$conn['common_name'];?>
+ </td>
+ <td class="listr">
+ <?=$conn['remote_host'];?>
+ </td>
+ <td class="listr">
+ <?=$conn['virtual_addr'];?>
+ </td>
+ <td class="listr">
+ <?=$conn['connect_time'];?>
+ </td>
+ <td class="listr">
+ <?=$conn['bytes_sent'];?>
+ </td>
+ <td class="listr">
+ <?=$conn['bytes_recv'];?>
+ </td>
+ </tr>
+
+ <?php endforeach; ?>
+ <tr>
+ <td colspan="6" class="list" height="12"></td>
+ </tr>
+
+ </table>
</td>
- <td class="listr">
- <?=$conn['bytes_sent'];?>
- </td>
- <td class="listr">
- <?=$conn['bytes_recv'];?>
- </td>
- </tr>
-
- <?php endforeach; ?>
- <tr>
- <td colspan="6" class="list" height="12"></td>
</tr>
-
</table>
<?php endforeach; ?>
diff --git a/usr/local/www/status_queues.php b/usr/local/www/status_queues.php
index ac2f78b..d18ae08 100755
--- a/usr/local/www/status_queues.php
+++ b/usr/local/www/status_queues.php
@@ -169,7 +169,7 @@ if(!is_array($config['shaper']['queue']) && count($config['shaper']['queue']) <
<p>
<strong><span class="red">Note:</span></strong><strong><br></strong>
Queue graphs take 5 seconds to sample data.<br>
- You can configure the Traffic Shaper <a href="firewall_shaper.php?reset=true">here</a>.
+ You can configure the Traffic Shaper <a href="/firewall_shaper_wizards.php">here</a>.
</p>
</form>
<?php include("fend.inc"); ?>
diff --git a/usr/local/www/status_services.php b/usr/local/www/status_services.php
index a7eef1c..1a13f4e 100755
--- a/usr/local/www/status_services.php
+++ b/usr/local/www/status_services.php
@@ -35,6 +35,7 @@
require("guiconfig.inc");
+require_once("service-utils.inc");
function gentitle_pkg($pgname) {
global $config;
@@ -211,7 +212,7 @@ include("fbegin.inc");
<p>
<div id="boxarea">
-<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+<table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<table width="100%" border="0" cellpadding="6" cellspacing="0">
diff --git a/usr/local/www/status_slbd_pool.php b/usr/local/www/status_slbd_pool.php
index fb9d615..93332b8 100755
--- a/usr/local/www/status_slbd_pool.php
+++ b/usr/local/www/status_slbd_pool.php
@@ -57,6 +57,7 @@ include("head.inc");
?>
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<script src="/javascript/sorttable.js"></script>
<?php include("fbegin.inc"); ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td class="tabnavtbl">
@@ -71,10 +72,10 @@ include("head.inc");
<tr>
<td>
<div id="mainarea">
- <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0" class="tabcont sortable" name="sortabletable" id="sortabletable">
<tr>
<td width="10%" class="listhdrr">Name</td>
- <td width="10%" class="listhdrr">Type</td>
+ <td width="10%" class="listhdrr">Type</td>
<td width="10%" class="listhdrr">Gateways</td>
<td width="30%" class="listhdrr">Status</td>
<td width="30%" class="listhdr">Description</td>
diff --git a/usr/local/www/status_slbd_vs.php b/usr/local/www/status_slbd_vs.php
index e888860..b8f78cc 100755
--- a/usr/local/www/status_slbd_vs.php
+++ b/usr/local/www/status_slbd_vs.php
@@ -124,10 +124,10 @@ include("head.inc");
<tr>
<td>
<div id="mainarea">
- <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="10%" class="listhdrr">Name</td>
- <td width="10%" class="listhdrr">Port</td>
+ <td width="10%" class="listhdrr">Port</td>
<td width="10%" class="listhdrr">Servers</td>
<td width="30%" class="listhdrr">Status</td>
<td width="30%" class="listhdr">Description</td>
diff --git a/usr/local/www/status_upnp.php b/usr/local/www/status_upnp.php
index cbf848f..d2be0c2 100644
--- a/usr/local/www/status_upnp.php
+++ b/usr/local/www/status_upnp.php
@@ -71,14 +71,14 @@ if(!$config['installedpackages']['miniupnpd']['config'][0]['iface_array'] ||
<tr>
<td class="tabcont" >
<form action="status_upnp.php" method="post">
- <b><input type="submit" name="clear" id="clear" value="Clear" /></b>
+ <input type="submit" name="clear" id="clear" value="Clear" /> all currently connected sessions.
</form>
</td>
</tr>
<tr>
<td class="tabcont" >
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tr>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0" class="tabcont">
+ <tr>
<td width="10%" class="listhdrr"><?=gettext("Port")?></td>
<td width="10%" class="listhdrr"><?=gettext("Protocol")?></td>
<td width="20%" class="listhdrr"><?=gettext("Internal IP")?></td>
diff --git a/usr/local/www/system.php b/usr/local/www/system.php
index fe983a8..3c1b569 100755
--- a/usr/local/www/system.php
+++ b/usr/local/www/system.php
@@ -121,7 +121,7 @@ if ($_POST) {
$input_errors[] = "A valid TCP/IP port must be specified for the webConfigurator port.";
}
- $direct_networks_list = explode(" ", get_direct_networks_list());
+ $direct_networks_list = explode(" ", filter_get_direct_networks_list());
for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
$dnsitem = "dns{$dnscounter}";
$dnsgwitem = "dns{$dnscounter}gwint";
@@ -231,6 +231,10 @@ include("head.inc");
?>
<form action="system.php" method="post">
<table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td id="mainarea">
+ <div class="tabcont">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
<tr>
<td colspan="2" valign="top" class="listtopic">System</td>
</tr>
@@ -414,6 +418,9 @@ include("head.inc");
</td>
</tr>
</table>
+ </div>
+ </td></tr>
+ </table>
</form>
<?php include("fend.inc"); ?>
</body>
diff --git a/usr/local/www/system_advanced_admin.php b/usr/local/www/system_advanced_admin.php
index cee9221..9a6432c 100644
--- a/usr/local/www/system_advanced_admin.php
+++ b/usr/local/www/system_advanced_admin.php
@@ -196,6 +196,7 @@ function prot_change() {
$tab_array[] = array("Networking", false, "system_advanced_network.php");
$tab_array[] = array("Miscellaneous", false, "system_advanced_misc.php");
$tab_array[] = array("System Tunables", false, "system_advanced_sysctl.php");
+ $tab_array[] = array("Notifications", false, "system_advanced_notifications.php");
display_top_tabs($tab_array);
?>
</td>
diff --git a/usr/local/www/system_advanced_firewall.php b/usr/local/www/system_advanced_firewall.php
index f81a613..1e38e37 100644
--- a/usr/local/www/system_advanced_firewall.php
+++ b/usr/local/www/system_advanced_firewall.php
@@ -176,6 +176,7 @@ function update_description(itemnum) {
$tab_array[] = array("Networking", false, "system_advanced_network.php");
$tab_array[] = array("Miscellaneous", false, "system_advanced_misc.php");
$tab_array[] = array("System Tunables", false, "system_advanced_sysctl.php");
+ $tab_array[] = array("Notifications", false, "system_advanced_notifications.php");
display_top_tabs($tab_array);
?>
</ul>
diff --git a/usr/local/www/system_advanced_misc.php b/usr/local/www/system_advanced_misc.php
index 82db06a..6fbfd4f 100644
--- a/usr/local/www/system_advanced_misc.php
+++ b/usr/local/www/system_advanced_misc.php
@@ -47,6 +47,8 @@ $pconfig['harddiskstandby'] = $config['system']['harddiskstandby'];
$pconfig['lb_use_sticky'] = isset($config['system']['lb_use_sticky']);
$pconfig['preferoldsa_enable'] = isset($config['ipsec']['preferoldsa']);
$pconfig['powerd_enable'] = isset($config['system']['powerd_enable']);
+$pconfig['glxsb_enable'] = isset($config['system']['glxsb_enable']);
+$pconfig['schedule_states'] = isset($config['system']['schedule_states']);
if ($_POST) {
@@ -69,8 +71,25 @@ if ($_POST) {
else
unset($config['system']['lb_use_sticky']);
- $config['ipsec']['preferoldsa'] = $_POST['preferoldsa_enable'] ? true : false;
- $config['system']['powerd_enable'] = $_POST['powerd_enable'] ? true : false;
+ if($_POST['preferoldsa_enable'] == "yes")
+ $config['system']['preferoldsa'] = true;
+ else
+ unset($config['system']['preferoldsa']);
+
+ if($_POST['powerd_enable'] == "yes")
+ $config['system']['powerd_enable'] = true;
+ else
+ unset($config['system']['powerd_enable']);
+
+ if($_POST['glxsb_enable'] == "yes")
+ $config['system']['glxsb_enable'] = true;
+ else
+ unset($config['system']['glxsb_enable']);
+
+ if($_POST['schedule_states'] == "yes")
+ $config['system']['schedule_states'] = true;
+ else
+ unset($config['system']['schedule_states']);
write_config();
@@ -82,6 +101,7 @@ if ($_POST) {
$savemsg = $retval;
activate_powerd();
+ load_glxsb();
}
}
@@ -109,6 +129,7 @@ include("head.inc");
$tab_array[] = array("Networking", false, "system_advanced_network.php");
$tab_array[] = array("Miscellaneous", true, "system_advanced_misc.php");
$tab_array[] = array("System Tunables", false, "system_advanced_sysctl.php");
+ $tab_array[] = array("Notifications", false, "system_advanced_notifications.php");
display_top_tabs($tab_array);
?>
</td>
@@ -171,6 +192,28 @@ include("head.inc");
<td colspan="2" class="list" height="12">&nbsp;</td>
</tr>
<tr>
+ <td colspan="2" valign="top" class="listtopic">glxsb Crypto Acceleration</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">glxsb</td>
+ <td width="78%" class="vtable">
+ <input name="glxsb_enable" type="checkbox" id="glxsb_enable" value="yes" <?php if ($pconfig['glxsb_enable']) echo "checked"; ?> />
+ <strong>Use glxsb</strong><br/>
+ <br />
+ The AMD Geode LX Security Block will accelerate some cryptographic functions
+ on systems which have the chip. Do not enable this option if you have a
+ Hifn cryptographic acceleration card, as this will take precedence and the
+ Hifn card will not be used. Acceleration should be automatic for IPsec
+ when using Rijndael (AES). OpenVPN should be set for AES-128-CBC.
+ <br/><br/>
+ If you do not have a glxsb chip in your system, this option will have no
+ effect. To unload the module, uncheck this option and then reboot.
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list" height="12">&nbsp;</td>
+ </tr>
+ <tr>
<td colspan="2" valign="top" class="listtopic">IP Security</td>
</tr>
<tr>
@@ -184,6 +227,21 @@ include("head.inc");
option to always prefer old SAs over new ones.
</td>
</tr>
+ <tr>
+ <td colspan="2" class="list" height="12">&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Schedules</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Schedule States</td>
+ <td width="78%" class="vtable">
+ <input name="schedule_states" type="checkbox" id="schedule_states" value="yes" <?php if ($pconfig['schedule_states']) echo "checked"; ?> />
+ <br />
+ By default schedules clear the states of existing connections when expiry time has come.
+ This option allows to override this setting by not clearing states for existing connections.
+ </td>
+ </tr>
<tr>
<td colspan="2" class="list" height="12">&nbsp;</td>
</tr>
diff --git a/usr/local/www/system_advanced_network.php b/usr/local/www/system_advanced_network.php
index c5db50b..81b4d4d 100644
--- a/usr/local/www/system_advanced_network.php
+++ b/usr/local/www/system_advanced_network.php
@@ -40,8 +40,8 @@
##|*MATCH=system_advanced-network.php*
##|-PRIV
-
require("guiconfig.inc");
+require("filter.inc");
$pconfig['ipv6nat_enable'] = isset($config['diag']['ipv6nat']['enable']);
$pconfig['ipv6nat_ipaddr'] = $config['diag']['ipv6nat']['ipaddr'];
@@ -49,6 +49,7 @@ $pconfig['ipv6allow'] = isset($config['system']['ipv6allow']);
$pconfig['polling_enable'] = isset($config['system']['polling']);
$pconfig['sharednet'] = $config['system']['sharednet'];
$pconfig['disablechecksumoffloading'] = isset($config['system']['disablechecksumoffloading']);
+$pconfig['flowtable'] = isset($config['system']['flowtable']);
if ($_POST) {
@@ -96,6 +97,12 @@ if ($_POST) {
setup_polling();
}
+ if($_POST['flowtable'] == "yes") {
+ $config['system']['flowtable'] = $_POST['flowtable'];
+ } else {
+ unset($config['system']['flowtable']);
+ }
+
if($_POST['disablechecksumoffloading'] == "yes") {
$config['system']['disablechecksumoffloading'] = $_POST['disablechecksumoffloading'];
setup_microcode();
@@ -103,9 +110,13 @@ if ($_POST) {
unset($config['system']['disablechecksumoffloading']);
setup_microcode();
}
-
+
+ // Write out configuration (config.xml)
write_config();
+ // Configure flowtable support from filter.inc
+ flowtable_configure();
+
$retval = filter_configure();
if(stristr($retval, "error") <> true)
$savemsg = get_std_save_message($retval);
@@ -153,6 +164,7 @@ function enable_change(enable_over) {
$tab_array[] = array("Networking", true, "system_advanced_network.php");
$tab_array[] = array("Miscellaneous", false, "system_advanced_misc.php");
$tab_array[] = array("System Tunables", false, "system_advanced_sysctl.php");
+ $tab_array[] = array("Notifications", false, "system_advanced_notifications.php");
display_top_tabs($tab_array);
?>
</td>
@@ -226,6 +238,26 @@ function enable_change(enable_over) {
This option will suppress ARP log messages when multiple interfaces reside on the same broadcast domain</strong>
</td>
</tr>
+<?php
+ $version = get_freebsd_version();
+ if($version == "8"):
+?>
+ <tr>
+ <td colspan="2" class="list" height="12">&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Flowtable support</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Enable Flowtable</td>
+ <td width="78%" class="vtable">
+ <input name="flowtable" type="checkbox" id="polling_enable" value="yes" <?php if ($pconfig['flowtable']) echo "checked"; ?>>
+ <strong>Enable flowtable support</strong><br>
+ Enables infrastructure for caching flows as a means of accelerating L3 and L2 lookups
+ as well as providing stateful load balancing when used with RADIX_MPATH.<br/>
+ </td>
+ </tr>
+<?php endif; ?>
<tr>
<td colspan="2" class="list" height="12">&nbsp;</td>
</tr>
diff --git a/usr/local/www/system_advanced_notifications.php b/usr/local/www/system_advanced_notifications.php
new file mode 100644
index 0000000..d623d8a
--- /dev/null
+++ b/usr/local/www/system_advanced_notifications.php
@@ -0,0 +1,147 @@
+<?php
+/* $Id$ */
+/*
+ system_advanced_notifications.php
+ part of pfSense
+ Copyright (C) 2009 Scott Ullrich <sullrich@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+##|+PRIV
+##|*IDENT=page-system-advanced-notifications
+##|*NAME=System: Advanced: Tunables page
+##|*DESCR=Allow access to the 'System: Advanced: Tunables' page.
+##|*MATCH=system_advanced-sysctrl.php*
+##|-PRIV
+
+require("guiconfig.inc");
+
+if($config['notifications']['growl']['password'])
+ $pconfig['password'] = $config['notifications']['growl']['password'];
+if($config['notifications']['growl']['ipaddress'])
+ $pconfig['ipaddress'] = $config['notifications']['growl']['ipaddress'];
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* if this is an AJAX caller then handle via JSON */
+ if (isAjax() && is_array($input_errors)) {
+ input_errors2Ajax($input_errors);
+ exit;
+ }
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ system_setup_sysctl();
+ $savemsg = get_std_save_message($retval);
+ }
+
+ if ($_POST['Submit'] == "Save") {
+ $tunableent = array();
+
+ $config['notifications']['growl']['ipaddress'] = $_POST['ipaddress'];
+ $config['notifications']['growl']['password'] = $_POST['password'];
+
+ write_config();
+
+ register_via_growl();
+ notify_via_growl("This is a test message form pfSense. It is safe to ignore this message.");
+
+ pfSenseHeader("system_advanced_notifications.php");
+ exit;
+ }
+}
+
+include("head.inc");
+
+$pgtitle = array("System","Advanced: Notifications");
+include("head.inc");
+
+?>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+ <form action="system_advanced_notifications.php" method="post">
+ <?php
+ if ($input_errors)
+ print_input_errors($input_errors);
+ if ($savemsg)
+ print_info_box($savemsg);
+ ?>
+ </form>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+ <?php
+ $tab_array = array();
+ $tab_array[] = array("Admin Access", false, "system_advanced_admin.php");
+ $tab_array[] = array("Firewall / NAT", false, "system_advanced_firewall.php");
+ $tab_array[] = array("Networking", false, "system_advanced_network.php");
+ $tab_array[] = array("Miscellaneous", false, "system_advanced_notifications.php");
+ $tab_array[] = array("System Tunables", false, "system_advanced_sysctl.php");
+ $tab_array[] = array("Notifications", true, "system_advanced_notifications.php");
+ display_top_tabs($tab_array);
+ ?>
+ </td>
+ </tr>
+ <tr>
+ <td id="mainarea">
+ <div class="tabcont">
+ <form action="system_advanced_notifications.php" method="post" name="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Growl</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">IP Address</td>
+ <td width="78%" class="vtable">
+ <input name='ipaddress' value='<?php echo $pconfig['ipaddress']; ?>'><br/>
+ This is the IP address that you would like to send growl notifications to.
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Password</td>
+ <td width="78%" class="vtable">
+ <input name='password' type='password' value='<?php echo $pconfig['password']; ?>'><br/>
+ Enter the password of the remote growl notification device.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="">
+ &nbsp;
+ </td>
+ <td>
+ <br/>
+ <input type='submit' id='Submit' name='Submit' value='Save'></form>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </td>
+ </tr>
+ </table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/system_advanced_sysctl.php b/usr/local/www/system_advanced_sysctl.php
index 763fab8..1cd8780 100644
--- a/usr/local/www/system_advanced_sysctl.php
+++ b/usr/local/www/system_advanced_sysctl.php
@@ -74,7 +74,7 @@ if ($act == "del") {
if (!$input_errors) {
unset($a_tunable[$id]);
write_config();
- touch($d_sysctldirty_path);
+ mark_subsystem_dirty('sysctl');
pfSenseHeader("firewall_system_tunables.php");
exit;
}
@@ -96,7 +96,7 @@ if ($_POST) {
$retval = 0;
system_setup_sysctl();
$savemsg = get_std_save_message($retval);
- unlink_if_exists($d_sysctldirty_path);
+ clear_subsystem_dirty('sysctl');
}
if ($_POST['Submit'] == "Save") {
@@ -111,7 +111,7 @@ if ($_POST) {
else
$a_tunable[] = $tunableent;
- touch($d_sysctldirty_path);
+ mark_subsystem_dirty('sysctl');
write_config();
@@ -135,7 +135,7 @@ include("head.inc");
print_input_errors($input_errors);
if ($savemsg)
print_info_box($savemsg);
- if (file_exists($d_sysctldirty_path) && ($act != "edit" ))
+ if (is_subsystem_dirty('sysctl') && ($act != "edit" ))
print_info_box_np("The firewall tunables have changed. You must apply the configuration to take affect.");
?>
</form>
@@ -149,6 +149,7 @@ include("head.inc");
$tab_array[] = array("Networking", false, "system_advanced_network.php");
$tab_array[] = array("Miscellaneous", false, "system_advanced_misc.php");
$tab_array[] = array("System Tunables", true, "system_advanced_sysctl.php");
+ $tab_array[] = array("Notifications", false, "system_advanced_notifications.php");
display_top_tabs($tab_array);
?>
</td>
diff --git a/usr/local/www/system_camanager.php b/usr/local/www/system_camanager.php
index b403a00..3458da5 100644
--- a/usr/local/www/system_camanager.php
+++ b/usr/local/www/system_camanager.php
@@ -35,6 +35,7 @@
##|-PRIV
require("guiconfig.inc");
+require_once("certs.inc");
$ca_methods = array(
"existing" => "Import an existing Certificate Authority",
diff --git a/usr/local/www/system_certmanager.php b/usr/local/www/system_certmanager.php
index f469ee0..be3f88b 100644
--- a/usr/local/www/system_certmanager.php
+++ b/usr/local/www/system_certmanager.php
@@ -35,6 +35,7 @@
##|-PRIV
require("guiconfig.inc");
+require_once("certs.inc");
$cert_methods = array(
"existing" => "Import an existing Certificate",
diff --git a/usr/local/www/system_firmware.php b/usr/local/www/system_firmware.php
index 73012a7..948c97d 100755
--- a/usr/local/www/system_firmware.php
+++ b/usr/local/www/system_firmware.php
@@ -49,8 +49,29 @@ require_once("xmlrpc_client.inc");
ini_set('max_execution_time', '9999');
ini_set('max_input_time', '9999');
+function file_upload_error_message($error_code) {
+ switch ($error_code) {
+ case UPLOAD_ERR_INI_SIZE:
+ return 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
+ case UPLOAD_ERR_FORM_SIZE:
+ return 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
+ case UPLOAD_ERR_PARTIAL:
+ return 'The uploaded file was only partially uploaded';
+ case UPLOAD_ERR_NO_FILE:
+ return 'No file was uploaded';
+ case UPLOAD_ERR_NO_TMP_DIR:
+ return 'Missing a temporary folder';
+ case UPLOAD_ERR_CANT_WRITE:
+ return 'Failed to write file to disk';
+ case UPLOAD_ERR_EXTENSION:
+ return 'File upload stopped by extension';
+ default:
+ return 'Unknown upload error';
+ }
+}
+
/* if upgrade in progress, alert user */
-if(file_exists($d_firmwarelock_path)) {
+if(is_subsystem_dirty('firmwarelock')) {
$pgtitle = array("System","Firmware","Manual Update");
include("head.inc");
echo "<body link=\"#0000CC\" vlink=\"#0000CC\" alink=\"#0000CC\">\n";
@@ -72,7 +93,7 @@ if($_POST['kerneltype']) {
}
/* Handle manual upgrade */
-if ($_POST && !file_exists($d_firmwarelock_path)) {
+if ($_POST && !is_subsystem_dirty('firmwarelock')) {
unset($input_errors);
unset($sig_warning);
@@ -89,15 +110,14 @@ if ($_POST && !file_exists($d_firmwarelock_path)) {
}
if ($mode) {
if ($mode == "enable") {
- exec_rc_script("/etc/rc.firmware enable");
conf_mount_rw();
- touch($d_fwupenabled_path);
+ mark_subsystem_dirty('firmware');
} else if ($mode == "disable") {
- exec_rc_script("/etc/rc.firmware disable");
conf_mount_ro();
- if (file_exists($d_fwupenabled_path))
- unlink($d_fwupenabled_path);
+ clear_subsystem_dirty('firmware');
} else if ($mode == "upgrade") {
+ if ($_FILES['ulfile']['error'])
+ $errortext = "(" . file_upload_error_message($_FILES['ulfile']['error']) . ")";
if (is_uploaded_file($_FILES['ulfile']['tmp_name'])) {
/* verify firmware image(s) */
if (!stristr($_FILES['ulfile']['name'], $g['platform']) && !$_POST['sig_override'])
@@ -105,9 +125,8 @@ if ($_POST && !file_exists($d_firmwarelock_path)) {
else if (!file_exists($_FILES['ulfile']['tmp_name'])) {
/* probably out of memory for the MFS */
$input_errors[] = "Image upload failed (out of memory?)";
- exec_rc_script("/etc/rc.firmware disable");
- if (file_exists($d_fwupenabled_path))
- unlink($d_fwupenabled_path);
+ mwexec("/etc/rc.firmware disable");
+ clear_subsystem_dirty('firmware');
} else {
/* move the image so PHP won't delete it */
rename($_FILES['ulfile']['tmp_name'], "{$g['upload_path']}/firmware.tgz");
@@ -132,17 +151,19 @@ if ($_POST && !file_exists($d_firmwarelock_path)) {
run_plugins("/usr/local/pkg/firmware_upgrade");
/* Check for input errors, firmware locks, warnings, then check for firmware if sig_override is set */
- if (!$input_errors && !file_exists($d_firmwarelock_path) && (!$sig_warning || $_POST['sig_override'])) {
+ if (!$input_errors && !is_subsystem_dirty('firmwarelock') && (!$sig_warning || $_POST['sig_override'])) {
if (file_exists("{$g['upload_path']}/firmware.tgz")) {
/* fire up the update script in the background */
- touch($d_firmwarelock_path);
+ mark_subsystem_dirty('firmwarelock');
$savemsg = "The firmware is now being updated. The firewall will reboot automatically.";
- if(stristr($_FILES['ulfile']['tmp_name'],"bdiff"))
+ if(stristr($_FILES['ulfile']['name'],"nanobsd") or $_POST['isnano'] == "yes")
+ mwexec_bg("/etc/rc.firmware pfSenseNanoBSDupgrade {$g['upload_path']}/firmware.tgz");
+ else if(stristr($_FILES['ulfile']['name'],"bdiff"))
mwexec_bg("/etc/rc.firmware delta_update {$g['upload_path']}/firmware.tgz");
else
mwexec_bg("/etc/rc.firmware pfSenseupgrade {$g['upload_path']}/firmware.tgz");
} else {
- $savemsg = "Firmware image missing or other error, please try again.";
+ $savemsg = "Firmware image missing or other error, please try again {$errortext}.";
}
}
}
@@ -172,11 +193,13 @@ include("head.inc");
"that the image has not been tampered with.<br><br>".
"Do you want to install this image anyway (on your own risk)?";
print_info_box($sig_warning);
+if(stristr($_FILES['ulfile']['name'],"nanobsd"))
+ echo "<input type='hidden' name='isnano' id='isnano' value='yes'>\n";
?>
<input name="sig_override" type="submit" class="formbtn" id="sig_override" value=" Yes ">
<input name="sig_no" type="submit" class="formbtn" id="sig_no" value=" No ">
<?php else: ?>
-<?php if (!file_exists($d_firmwarelock_path)): ?>
+<?php if (!is_subsystem_dirty('firmwarelock')): ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
@@ -207,8 +230,8 @@ print_info_box($sig_warning);
Click &quot;Upgrade firmware&quot;
to start the upgrade process.
</p>
- <?php if (!file_exists($d_sysrebootreqd_path)): ?>
- <?php if (!file_exists($d_fwupenabled_path)): ?>
+ <?php if (!is_subsystem_dirty('rebootreq')): ?>
+ <?php if (!is_subsystem_dirty('firmware')): ?>
<input name="Submit" type="submit" class="formbtn" value="Enable firmware upload">
<?php else: ?>
<input name="Submit" type="submit" class="formbtn" value="Disable firmware upload">
diff --git a/usr/local/www/system_firmware_auto.php b/usr/local/www/system_firmware_auto.php
index 65c894f..7eeb2f6 100755
--- a/usr/local/www/system_firmware_auto.php
+++ b/usr/local/www/system_firmware_auto.php
@@ -130,23 +130,31 @@ if($current_installed_pfsense_version <> $latest_version)
if($needs_system_upgrade == true) {
update_status("Downloading updates ...");
- $status = download_file_with_progress_bar("{$updater_url}/latest.tgz", "/tmp/latest.tgz", "read_body_firmware");
- $status = download_file_with_progress_bar("{$updater_url}/latest.tgz.sha256", "/tmp/latest.tgz.sha256");
+ conf_mount_rw();
+ $status = download_file_with_progress_bar("{$updater_url}/latest.tgz", "{$g['upload_path']}/latest.tgz", "read_body_firmware");
+ $status = download_file_with_progress_bar("{$updater_url}/latest.tgz.sha256", "{$g['upload_path']}/latest.tgz.sha256");
+ conf_mount_ro();
update_output_window("{$g['product_name']} download complete.");
}
/* launch external upgrade helper */
-$external_upgrade_helper_text = "/etc/rc.firmware pfSenseupgrade ";
+$external_upgrade_helper_text = "/etc/rc.firmware ";
+
+if($g['platform'] == "nanobsd")
+ $external_upgrade_helper_text .= "pfSenseNanoBSDupgrade ";
+else
+ $external_upgrade_helper_text .= "pfSenseupgrade ";
+
if($needs_system_upgrade == true)
- $external_upgrade_helper_text .= "/tmp/latest.tgz";
+ $external_upgrade_helper_text .= "{$g['upload_path']}/latest.tgz";
-$downloaded_latest_tgz_sha256 = str_replace("\n", "", `sha256 /tmp/latest.tgz | awk '{ print $4 }'`);
-$upgrade_latest_tgz_sha256 = str_replace("\n", "", `cat /tmp/latest.tgz.sha256 | awk '{ print $4 }'`);
+$downloaded_latest_tgz_sha256 = str_replace("\n", "", `sha256 -q {$g['upload_path']}/latest.tgz`);
+$upgrade_latest_tgz_sha256 = str_replace("\n", "", `cat {$g['upload_path']}/latest.tgz.sha256 | awk '{ print $4 }'`);
$sigchk = 0;
if(!isset($curcfg['alturl']['enable']))
- $sigchk = verify_digital_signature("/tmp/latest.tgz");
+ $sigchk = verify_digital_signature("{$g['upload_path']}/latest.tgz");
if ($sigchk == 1)
$sig_warning = "The digital signature on this image is invalid.";
@@ -155,10 +163,14 @@ else if ($sigchk == 2)
else if (($sigchk == 3) || ($sigchk == 4))
$sig_warning = "There has been an error verifying the signature on this image.";
-if (!verify_gzip_file("/tmp/latest.tgz")) {
+if (!verify_gzip_file("{$g['upload_path']}/latest.tgz")) {
update_status("The image file is corrupt.");
update_output_window("Update cannot continue");
- unlink("{$g['upload_path']}/latest.tgz");
+ if (file_exists("{$g['upload_path']}/latest.tgz")) {
+ conf_mount_rw();
+ unlink("{$g['upload_path']}/latest.tgz");
+ conf_mount_ro();
+ }
require("fend.inc");
exit;
}
@@ -166,7 +178,11 @@ if (!verify_gzip_file("/tmp/latest.tgz")) {
if ($sigchk) {
update_status($sig_warning);
update_output_window("Update cannot continue");
- unlink("{$g['upload_path']}/latest.tgz");
+ if (file_exists("{$g['upload_path']}/latest.tgz")) {
+ conf_mount_rw();
+ unlink("{$g['upload_path']}/latest.tgz");
+ conf_mount_ro();
+ }
require("fend.inc");
exit;
}
@@ -177,7 +193,7 @@ if($downloaded_latest_tgz_sha256 <> $upgrade_latest_tgz_sha256) {
} else {
update_output_window("{$g['product_name']} is now upgrading.\\n\\nThe firewall will reboot once the operation is completed.");
echo "\n<script language=\"JavaScript\">document.progressbar.style.visibility='hidden';\n</script>";
- exec_rc_script_async("{$external_upgrade_helper_text}");
+ mwexec("nohup {$external_upgrade_helper_text}");
}
/*
diff --git a/usr/local/www/system_gateway_groups.php b/usr/local/www/system_gateway_groups.php
index 3d794a7..295fa26 100755
--- a/usr/local/www/system_gateway_groups.php
+++ b/usr/local/www/system_gateway_groups.php
@@ -58,11 +58,8 @@ if ($_POST) {
$retval |= filter_configure();
$savemsg = get_std_save_message($retval);
- if ($retval == 0) {
- if (file_exists($d_staticroutesdirty_path)) {
- unlink($d_staticroutesdirty_path);
- }
- }
+ if ($retval == 0)
+ clear_subsystem_dirty('staticroutes');
}
}
@@ -71,7 +68,7 @@ if ($_GET['act'] == "del") {
$changedesc .= "removed gateway group {$_GET['id']}";
unset($a_gateway_groups[$_GET['id']]);
write_config($changedesc);
- touch($d_staticroutesdirty_path);
+ mark_subsystem_dirty('staticroutes');
header("Location: system_gateway_groups.php");
exit;
}
@@ -87,7 +84,7 @@ include("head.inc");
<form action="system_gateway_groups.php" method="post">
<input type="hidden" name="y1" value="1">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_staticroutesdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('staticroutes')): ?><p>
<?php print_info_box_np("The gateway configuration has been changed.<br>You must apply the changes in order for them to take
effect.");?><br>
<?php endif; ?>
diff --git a/usr/local/www/system_gateway_groups_edit.php b/usr/local/www/system_gateway_groups_edit.php
index 1bbdeaa..1fdcdf2 100755
--- a/usr/local/www/system_gateway_groups_edit.php
+++ b/usr/local/www/system_gateway_groups_edit.php
@@ -126,7 +126,7 @@ if ($_POST) {
else
$a_gateway_groups[] = $gateway_group;
- touch($d_staticroutesdirty_path);
+ mark_subsystem_dirty('staticroutes');
write_config();
diff --git a/usr/local/www/system_gateways.php b/usr/local/www/system_gateways.php
index 6522895..c06130f 100755
--- a/usr/local/www/system_gateways.php
+++ b/usr/local/www/system_gateways.php
@@ -62,11 +62,8 @@ if ($_POST) {
setup_gateways_monitor();
$savemsg = get_std_save_message($retval);
- if ($retval == 0) {
- if (file_exists($d_staticroutesdirty_path)) {
- unlink($d_staticroutesdirty_path);
- }
- }
+ if ($retval == 0)
+ clear_subsystem_dirty('staticroutes');
}
}
@@ -79,7 +76,7 @@ if ($_GET['act'] == "del") {
$changedesc .= "removed gateway {$realid}";
unset($a_gateways[$realid]);
write_config($changedesc);
- touch($d_staticroutesdirty_path);
+ mark_subsystem_dirty('staticroutes');
header("Location: system_gateways.php");
exit;
}
@@ -96,7 +93,7 @@ include("head.inc");
<form action="system_gateways.php" method="post">
<input type="hidden" name="y1" value="1">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_staticroutesdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('staticroutes')): ?><p>
<?php print_info_box_np("The gateway configuration has been changed.<br>You must apply the changes in order for them to take
effect.");?><br>
<?php endif; ?>
diff --git a/usr/local/www/system_gateways_edit.php b/usr/local/www/system_gateways_edit.php
index 0683ef8..66ac916 100755
--- a/usr/local/www/system_gateways_edit.php
+++ b/usr/local/www/system_gateways_edit.php
@@ -38,6 +38,7 @@
require("guiconfig.inc");
+require("pkg-utils.inc");
$a_gateways = return_gateways_array();
$a_gateways_arr = array();
@@ -136,7 +137,7 @@ if ($_POST) {
$gateway['descr'] = $_POST['descr'];
$gateway['monitor'] = $_POST['monitor'];
- if ($_POST['defaultgw'] == "yes") {
+ if ($_POST['defaultgw'] == "yes" or $_POST['defaultgw'] == "on") {
$i = 0;
foreach($a_gateways as $gw) {
unset($config['gateways'][$i]['defaultgw']);
@@ -156,7 +157,7 @@ if ($_POST) {
}
}
- touch($d_staticroutesdirty_path);
+ mark_subsystem_dirty('staticroutes');
write_config();
@@ -192,12 +193,13 @@ include("head.inc");
<tr>
<td width="22%" valign="top" class="vncellreq">Interface</td>
<td width="78%" class="vtable">
- <select name="interface" class="formselect">
+ <select name="interface" class="formselect">
<?php $interfaces = get_configured_interface_with_descr(false, true);
foreach ($interfaces as $iface => $ifacename): ?>
- <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
+ <option value="<?=$iface;?>" <?php if (get_real_interface($iface) == $pconfig['interface']) echo " selected"; ?>>
<?=htmlspecialchars($ifacename);?>
</option>
+ iface = <?=$iface?> ; pconfig = <?=$pconfig['interface']?> ; ifacename = <?=$ifacename?>
<?php
endforeach;
if (is_package_installed("openbgpd") == 1) {
diff --git a/usr/local/www/system_groupmanager.php b/usr/local/www/system_groupmanager.php
index 3b202f8..8748ffb 100644
--- a/usr/local/www/system_groupmanager.php
+++ b/usr/local/www/system_groupmanager.php
@@ -49,7 +49,6 @@ $pgtitle = array("System", "Group manager");
if (!is_array($config['system']['group']))
$config['system']['group'] = array();
-admin_groups_sort();
$a_group = &$config['system']['group'];
$id = $_GET['id'];
@@ -321,7 +320,8 @@ function presubmit() {
</tr>
<?php endif; ?>
-
+ <?php if($_GET['act'] != "new"): ?>
+
<tr>
<td width="22%" valign="top" class="vncell"><?=gettext("Assigned Privileges");?></td>
<td width="78%" class="vtable">
@@ -360,11 +360,14 @@ function presubmit() {
<a href="system_groupmanager_addprivs.php?groupid=<?=$id?>">
<img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0" alt="" />
</a>
+
</td>
</tr>
+
</table>
</td>
</tr>
+ <?php endif; ?>
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
diff --git a/usr/local/www/system_groupmanager_addprivs.php b/usr/local/www/system_groupmanager_addprivs.php
index 9e625c5..95a5570 100644
--- a/usr/local/www/system_groupmanager_addprivs.php
+++ b/usr/local/www/system_groupmanager_addprivs.php
@@ -35,6 +35,18 @@
##|*MATCH=system_groupmanager_addprivs.php*
##|-PRIV
+function cpusercmp($a, $b) {
+ return strcasecmp($a['name'], $b['name']);
+}
+
+function admin_groups_sort() {
+ global $config;
+
+ if (!is_array($config['system']['group']))
+ return;
+
+ usort($config['system']['group'], "cpusercmp");
+}
require("guiconfig.inc");
@@ -88,6 +100,8 @@ if ($_POST) {
local_user_set($user);
}
+ admin_groups_sort();
+
$retval = write_config();
$savemsg = get_std_save_message($retval);
diff --git a/usr/local/www/system_routes.php b/usr/local/www/system_routes.php
index c563d5e..a142a3a 100755
--- a/usr/local/www/system_routes.php
+++ b/usr/local/www/system_routes.php
@@ -45,7 +45,6 @@ if (!is_array($config['staticroutes']['route']))
if (!is_array($config['gateways']['gateway_item']))
$config['gateways']['gateway_item'] = array();
-staticroutes_sort();
$a_routes = &$config['staticroutes']['route'];
$a_gateways = &$config['gateways']['gateway_item'];
$changedesc = "Static Routes: ";
@@ -64,11 +63,8 @@ if ($_POST) {
setup_gateways_monitor();
$savemsg = get_std_save_message($retval);
- if ($retval == 0) {
- if (file_exists($d_staticroutesdirty_path)) {
- unlink($d_staticroutesdirty_path);
- }
- }
+ if ($retval == 0)
+ clear_subsystem_dirty('staticroutes');
} else {
if ($_POST['enablefastrouting'] == "") {
/* Only update config if something changed */
@@ -93,7 +89,7 @@ if ($_GET['act'] == "del") {
$changedesc .= "removed route to " . $a_routes[$_GET['id']['route']];
unset($a_routes[$_GET['id']]);
write_config($changedesc);
- touch($d_staticroutesdirty_path);
+ mark_subsystem_dirty('staticroutes');
header("Location: system_routes.php");
exit;
}
@@ -109,7 +105,7 @@ include("head.inc");
<form action="system_routes.php" method="post">
<input type="hidden" name="y1" value="1">
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_staticroutesdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('staticroutes')): ?><p>
<?php print_info_box_np("The static route configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
diff --git a/usr/local/www/system_routes_edit.php b/usr/local/www/system_routes_edit.php
index bdd2343..4bb2e6c 100755
--- a/usr/local/www/system_routes_edit.php
+++ b/usr/local/www/system_routes_edit.php
@@ -36,6 +36,18 @@
##|*MATCH=system_routes_edit.php*
##|-PRIV
+function staticroutecmp($a, $b) {
+ return strcmp($a['network'], $b['network']);
+}
+
+function staticroutes_sort() {
+ global $g, $config;
+
+ if (!is_array($config['staticroutes']['route']))
+ return;
+
+ usort($config['staticroutes']['route'], "staticroutecmp");
+}
require("guiconfig.inc");
@@ -112,12 +124,13 @@ if ($_POST) {
$route['gateway'] = $_POST['gateway'];
$route['descr'] = $_POST['descr'];
+ staticroutes_sort();
if (isset($id) && $a_routes[$id])
$a_routes[$id] = $route;
else
$a_routes[] = $route;
- touch($d_staticroutesdirty_path);
+ mark_subsystem_dirty('staticroutes');
write_config();
diff --git a/usr/local/www/system_usermanager.php b/usr/local/www/system_usermanager.php
index e8b4d3d..931721f 100644
--- a/usr/local/www/system_usermanager.php
+++ b/usr/local/www/system_usermanager.php
@@ -57,7 +57,6 @@ if (isAllowedPage("system_usermanager")) {
if (!is_array($config['system']['user']))
$config['system']['user'] = array();
- admin_users_sort();
$a_user = &$config['system']['user'];
if ($_GET['act'] == "deluser") {
diff --git a/usr/local/www/system_usermanager_addcert.php b/usr/local/www/system_usermanager_addcert.php
index 9af9a9c..081487b 100644
--- a/usr/local/www/system_usermanager_addcert.php
+++ b/usr/local/www/system_usermanager_addcert.php
@@ -35,6 +35,7 @@
##|-PRIV
require("guiconfig.inc");
+require_once("certs.inc");
$cert_keylens = array( "512", "1024", "2048", "4096");
diff --git a/usr/local/www/system_usermanager_addprivs.php b/usr/local/www/system_usermanager_addprivs.php
index 85238c3..9ee3145 100644
--- a/usr/local/www/system_usermanager_addprivs.php
+++ b/usr/local/www/system_usermanager_addprivs.php
@@ -35,6 +35,18 @@
##|*MATCH=system_usermanager_addprivs.php*
##|-PRIV
+function admusercmp($a, $b) {
+ return strcasecmp($a['name'], $b['name']);
+}
+
+function admin_users_sort() {
+ global $g, $config;
+
+ if (!is_array($config['system']['user']))
+ return;
+
+ usort($config['system']['user'], "admusercmp");
+}
require("guiconfig.inc");
@@ -87,6 +99,7 @@ if ($_POST) {
else
$a_user['priv'] = array_merge($a_user['priv'], $pconfig['sysprivs']);
+ admin_users_sort();
local_user_set($a_user);
$retval = write_config();
$savemsg = get_std_save_message($retval);
diff --git a/usr/local/www/themes/metallic/all.css b/usr/local/www/themes/metallic/all.css
index e9e610d..06f5b4d 100644
--- a/usr/local/www/themes/metallic/all.css
+++ b/usr/local/www/themes/metallic/all.css
@@ -1211,8 +1211,10 @@ div#log span.log-protocol-mini-header {
/* Sortable tables */
table.sortable thead {
- background-color:#eee;
- color:#666666;
- font-weight: bold;
cursor: default;
+ background-color: #EEEEEE;
+ padding-right: 12px;
+ padding-left: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
}
diff --git a/usr/local/www/themes/metallic/images/button_left.gif b/usr/local/www/themes/metallic/images/button_left.gif
deleted file mode 100644
index 2e46d25..0000000
--- a/usr/local/www/themes/metallic/images/button_left.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/button_mid.gif b/usr/local/www/themes/metallic/images/button_mid.gif
deleted file mode 100644
index 4198d93..0000000
--- a/usr/local/www/themes/metallic/images/button_mid.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/button_right.gif b/usr/local/www/themes/metallic/images/button_right.gif
deleted file mode 100644
index 0faaa67..0000000
--- a/usr/local/www/themes/metallic/images/button_right.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/icons/icon_advanced.gif b/usr/local/www/themes/metallic/images/icons/icon_advanced.gif
new file mode 100644
index 0000000..3ede1ff
--- /dev/null
+++ b/usr/local/www/themes/metallic/images/icons/icon_advanced.gif
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/icons/icon_advanced_s.gif b/usr/local/www/themes/metallic/images/icons/icon_advanced_s.gif
new file mode 100644
index 0000000..b233549
--- /dev/null
+++ b/usr/local/www/themes/metallic/images/icons/icon_advanced_s.gif
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/misc/plogo_0.gif b/usr/local/www/themes/metallic/images/misc/plogo_0.gif
deleted file mode 100644
index 160b56d..0000000
--- a/usr/local/www/themes/metallic/images/misc/plogo_0.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/misc/plogo_1.gif b/usr/local/www/themes/metallic/images/misc/plogo_1.gif
deleted file mode 100644
index 50342d6..0000000
--- a/usr/local/www/themes/metallic/images/misc/plogo_1.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/misc/plogo_10.gif b/usr/local/www/themes/metallic/images/misc/plogo_10.gif
deleted file mode 100644
index 06cba14..0000000
--- a/usr/local/www/themes/metallic/images/misc/plogo_10.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/misc/plogo_2.gif b/usr/local/www/themes/metallic/images/misc/plogo_2.gif
deleted file mode 100644
index 9d10230..0000000
--- a/usr/local/www/themes/metallic/images/misc/plogo_2.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/misc/plogo_3.gif b/usr/local/www/themes/metallic/images/misc/plogo_3.gif
deleted file mode 100644
index 1983f87..0000000
--- a/usr/local/www/themes/metallic/images/misc/plogo_3.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/misc/plogo_4.gif b/usr/local/www/themes/metallic/images/misc/plogo_4.gif
deleted file mode 100644
index f7158bd..0000000
--- a/usr/local/www/themes/metallic/images/misc/plogo_4.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/misc/plogo_5.gif b/usr/local/www/themes/metallic/images/misc/plogo_5.gif
deleted file mode 100644
index c7af593..0000000
--- a/usr/local/www/themes/metallic/images/misc/plogo_5.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/misc/plogo_6.gif b/usr/local/www/themes/metallic/images/misc/plogo_6.gif
deleted file mode 100644
index 310eb22..0000000
--- a/usr/local/www/themes/metallic/images/misc/plogo_6.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/misc/plogo_7.gif b/usr/local/www/themes/metallic/images/misc/plogo_7.gif
deleted file mode 100644
index 06bd2e8..0000000
--- a/usr/local/www/themes/metallic/images/misc/plogo_7.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/misc/plogo_8.gif b/usr/local/www/themes/metallic/images/misc/plogo_8.gif
deleted file mode 100644
index c6ef564..0000000
--- a/usr/local/www/themes/metallic/images/misc/plogo_8.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/metallic/images/misc/plogo_9.gif b/usr/local/www/themes/metallic/images/misc/plogo_9.gif
deleted file mode 100644
index 4f0cd4d..0000000
--- a/usr/local/www/themes/metallic/images/misc/plogo_9.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/all.css b/usr/local/www/themes/nervecenter/all.css
index d0aa567..3babfed 100644
--- a/usr/local/www/themes/nervecenter/all.css
+++ b/usr/local/www/themes/nervecenter/all.css
@@ -158,6 +158,13 @@ iframe {
background-color: #FFFFFF;
}
+/* style of disabled formelements */
+#wrap div {margin:1em 0}
+[disabled] {
+ color:#666666;
+ background:#eeeeee;
+}
+
/* ID Based CSS Definitions */
#wrapper {
width: 810px;
@@ -954,6 +961,12 @@ ul#tabnav li.tabact {
vertical-align: top;
}
+/* style of disabled formelements */
+[disabled] {
+ color:#666666;
+ background:#eeeeee;
+}
+
/* Auto Complete Suggestions */
div.suggestions {
@@ -1230,8 +1243,10 @@ div#log span.log-protocol-mini-header {
/* Sortable tables */
table.sortable thead {
- background-color:#eee;
- color:#666666;
- font-weight: bold;
cursor: default;
+ background-color: #EEEEEE;
+ padding-right: 12px;
+ padding-left: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
}
diff --git a/usr/local/www/themes/nervecenter/images/background.gif b/usr/local/www/themes/nervecenter/images/background.gif
index 1ceb886..bdfa5b3 100644
--- a/usr/local/www/themes/nervecenter/images/background.gif
+++ b/usr/local/www/themes/nervecenter/images/background.gif
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/button_left.gif b/usr/local/www/themes/nervecenter/images/button_left.gif
deleted file mode 100644
index 2e46d25..0000000
--- a/usr/local/www/themes/nervecenter/images/button_left.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/button_mid.gif b/usr/local/www/themes/nervecenter/images/button_mid.gif
deleted file mode 100644
index 4198d93..0000000
--- a/usr/local/www/themes/nervecenter/images/button_mid.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/button_right.gif b/usr/local/www/themes/nervecenter/images/button_right.gif
deleted file mode 100644
index 0faaa67..0000000
--- a/usr/local/www/themes/nervecenter/images/button_right.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/icons/icon_advanced.gif b/usr/local/www/themes/nervecenter/images/icons/icon_advanced.gif
new file mode 100644
index 0000000..3ede1ff
--- /dev/null
+++ b/usr/local/www/themes/nervecenter/images/icons/icon_advanced.gif
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/icons/icon_advanced_s.gif b/usr/local/www/themes/nervecenter/images/icons/icon_advanced_s.gif
new file mode 100644
index 0000000..b233549
--- /dev/null
+++ b/usr/local/www/themes/nervecenter/images/icons/icon_advanced_s.gif
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/icons/icon_block_add.gif b/usr/local/www/themes/nervecenter/images/icons/icon_block_add.gif
new file mode 100644
index 0000000..eb726d6
--- /dev/null
+++ b/usr/local/www/themes/nervecenter/images/icons/icon_block_add.gif
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/icons/icon_pass_add.gif b/usr/local/www/themes/nervecenter/images/icons/icon_pass_add.gif
new file mode 100644
index 0000000..f7f4c20
--- /dev/null
+++ b/usr/local/www/themes/nervecenter/images/icons/icon_pass_add.gif
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/misc/plogo_0.gif b/usr/local/www/themes/nervecenter/images/misc/plogo_0.gif
deleted file mode 100644
index 160b56d..0000000
--- a/usr/local/www/themes/nervecenter/images/misc/plogo_0.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/misc/plogo_1.gif b/usr/local/www/themes/nervecenter/images/misc/plogo_1.gif
deleted file mode 100644
index 50342d6..0000000
--- a/usr/local/www/themes/nervecenter/images/misc/plogo_1.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/misc/plogo_10.gif b/usr/local/www/themes/nervecenter/images/misc/plogo_10.gif
deleted file mode 100644
index 06cba14..0000000
--- a/usr/local/www/themes/nervecenter/images/misc/plogo_10.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/misc/plogo_2.gif b/usr/local/www/themes/nervecenter/images/misc/plogo_2.gif
deleted file mode 100644
index 9d10230..0000000
--- a/usr/local/www/themes/nervecenter/images/misc/plogo_2.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/misc/plogo_3.gif b/usr/local/www/themes/nervecenter/images/misc/plogo_3.gif
deleted file mode 100644
index 1983f87..0000000
--- a/usr/local/www/themes/nervecenter/images/misc/plogo_3.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/misc/plogo_4.gif b/usr/local/www/themes/nervecenter/images/misc/plogo_4.gif
deleted file mode 100644
index f7158bd..0000000
--- a/usr/local/www/themes/nervecenter/images/misc/plogo_4.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/misc/plogo_5.gif b/usr/local/www/themes/nervecenter/images/misc/plogo_5.gif
deleted file mode 100644
index c7af593..0000000
--- a/usr/local/www/themes/nervecenter/images/misc/plogo_5.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/misc/plogo_6.gif b/usr/local/www/themes/nervecenter/images/misc/plogo_6.gif
deleted file mode 100644
index 310eb22..0000000
--- a/usr/local/www/themes/nervecenter/images/misc/plogo_6.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/misc/plogo_7.gif b/usr/local/www/themes/nervecenter/images/misc/plogo_7.gif
deleted file mode 100644
index 06bd2e8..0000000
--- a/usr/local/www/themes/nervecenter/images/misc/plogo_7.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/misc/plogo_8.gif b/usr/local/www/themes/nervecenter/images/misc/plogo_8.gif
deleted file mode 100644
index c6ef564..0000000
--- a/usr/local/www/themes/nervecenter/images/misc/plogo_8.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/nervecenter/images/misc/plogo_9.gif b/usr/local/www/themes/nervecenter/images/misc/plogo_9.gif
deleted file mode 100644
index 4f0cd4d..0000000
--- a/usr/local/www/themes/nervecenter/images/misc/plogo_9.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/all.css b/usr/local/www/themes/pfsense-dropdown/all.css
index 6868ef5..1891f07 100644
--- a/usr/local/www/themes/pfsense-dropdown/all.css
+++ b/usr/local/www/themes/pfsense-dropdown/all.css
@@ -953,10 +953,12 @@ div#log span.log-protocol-mini-header {
/* Sortable tables */
table.sortable thead {
- background-color:#eee;
- color:#666666;
- font-weight: bold;
cursor: default;
+ background-color: #EEEEEE;
+ padding-right: 12px;
+ padding-left: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
}
#graph {
diff --git a/usr/local/www/themes/pfsense-dropdown/images/icons/icon_advanced.gif b/usr/local/www/themes/pfsense-dropdown/images/icons/icon_advanced.gif
new file mode 100644
index 0000000..3ede1ff
--- /dev/null
+++ b/usr/local/www/themes/pfsense-dropdown/images/icons/icon_advanced.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/icons/icon_advanced_s.gif b/usr/local/www/themes/pfsense-dropdown/images/icons/icon_advanced_s.gif
new file mode 100644
index 0000000..b233549
--- /dev/null
+++ b/usr/local/www/themes/pfsense-dropdown/images/icons/icon_advanced_s.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_0.gif b/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_0.gif
deleted file mode 100644
index 160b56d..0000000
--- a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_0.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_1.gif b/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_1.gif
deleted file mode 100644
index 50342d6..0000000
--- a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_1.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_10.gif b/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_10.gif
deleted file mode 100644
index 06cba14..0000000
--- a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_10.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_2.gif b/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_2.gif
deleted file mode 100644
index 9d10230..0000000
--- a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_2.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_3.gif b/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_3.gif
deleted file mode 100644
index 1983f87..0000000
--- a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_3.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_4.gif b/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_4.gif
deleted file mode 100644
index f7158bd..0000000
--- a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_4.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_5.gif b/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_5.gif
deleted file mode 100644
index c7af593..0000000
--- a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_5.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_6.gif b/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_6.gif
deleted file mode 100644
index 310eb22..0000000
--- a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_6.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_7.gif b/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_7.gif
deleted file mode 100644
index 06bd2e8..0000000
--- a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_7.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_8.gif b/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_8.gif
deleted file mode 100644
index c6ef564..0000000
--- a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_8.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_9.gif b/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_9.gif
deleted file mode 100644
index 4f0cd4d..0000000
--- a/usr/local/www/themes/pfsense-dropdown/images/misc/plogo_9.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense/all.css b/usr/local/www/themes/pfsense/all.css
index aaa299f..e1b2200 100644
--- a/usr/local/www/themes/pfsense/all.css
+++ b/usr/local/www/themes/pfsense/all.css
@@ -961,10 +961,12 @@ div#log span.log-protocol-mini-header {
/* Sortable tables */
table.sortable thead {
- background-color:#eee;
- color:#666666;
- font-weight: bold;
cursor: default;
+ background-color: #EEEEEE;
+ padding-right: 12px;
+ padding-left: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
}
#graph {
diff --git a/usr/local/www/themes/pfsense/images/icons/icon_advanced.gif b/usr/local/www/themes/pfsense/images/icons/icon_advanced.gif
new file mode 100644
index 0000000..3ede1ff
--- /dev/null
+++ b/usr/local/www/themes/pfsense/images/icons/icon_advanced.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/icons/icon_advanced_s.gif b/usr/local/www/themes/pfsense/images/icons/icon_advanced_s.gif
new file mode 100644
index 0000000..b233549
--- /dev/null
+++ b/usr/local/www/themes/pfsense/images/icons/icon_advanced_s.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/misc/plogo_0.gif b/usr/local/www/themes/pfsense/images/misc/plogo_0.gif
deleted file mode 100644
index 160b56d..0000000
--- a/usr/local/www/themes/pfsense/images/misc/plogo_0.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/misc/plogo_1.gif b/usr/local/www/themes/pfsense/images/misc/plogo_1.gif
deleted file mode 100644
index 50342d6..0000000
--- a/usr/local/www/themes/pfsense/images/misc/plogo_1.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/misc/plogo_10.gif b/usr/local/www/themes/pfsense/images/misc/plogo_10.gif
deleted file mode 100644
index 06cba14..0000000
--- a/usr/local/www/themes/pfsense/images/misc/plogo_10.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/misc/plogo_2.gif b/usr/local/www/themes/pfsense/images/misc/plogo_2.gif
deleted file mode 100644
index 9d10230..0000000
--- a/usr/local/www/themes/pfsense/images/misc/plogo_2.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/misc/plogo_3.gif b/usr/local/www/themes/pfsense/images/misc/plogo_3.gif
deleted file mode 100644
index 1983f87..0000000
--- a/usr/local/www/themes/pfsense/images/misc/plogo_3.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/misc/plogo_4.gif b/usr/local/www/themes/pfsense/images/misc/plogo_4.gif
deleted file mode 100644
index f7158bd..0000000
--- a/usr/local/www/themes/pfsense/images/misc/plogo_4.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/misc/plogo_5.gif b/usr/local/www/themes/pfsense/images/misc/plogo_5.gif
deleted file mode 100644
index c7af593..0000000
--- a/usr/local/www/themes/pfsense/images/misc/plogo_5.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/misc/plogo_6.gif b/usr/local/www/themes/pfsense/images/misc/plogo_6.gif
deleted file mode 100644
index 310eb22..0000000
--- a/usr/local/www/themes/pfsense/images/misc/plogo_6.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/misc/plogo_7.gif b/usr/local/www/themes/pfsense/images/misc/plogo_7.gif
deleted file mode 100644
index 06bd2e8..0000000
--- a/usr/local/www/themes/pfsense/images/misc/plogo_7.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/misc/plogo_8.gif b/usr/local/www/themes/pfsense/images/misc/plogo_8.gif
deleted file mode 100644
index c6ef564..0000000
--- a/usr/local/www/themes/pfsense/images/misc/plogo_8.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense/images/misc/plogo_9.gif b/usr/local/www/themes/pfsense/images/misc/plogo_9.gif
deleted file mode 100644
index 4f0cd4d..0000000
--- a/usr/local/www/themes/pfsense/images/misc/plogo_9.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/all.css b/usr/local/www/themes/pfsense_ng/all.css
new file mode 100644
index 0000000..78ca6aa
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/all.css
@@ -0,0 +1,1349 @@
+/* Element CSS Definitions */
+html, body, td, th, input, select {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 0.9em;
+
+}
+
+.infobox {
+ width:100%;
+}
+
+.infoboxsave {
+ padding-right: 10px;
+}
+
+.infoboxnptd2 {
+ width:100%;
+ color:white;
+ background-color:#990000;
+ padding-right: 10px;
+}
+
+.infoboxnptd {
+ width:8%;
+ background-color:#990000;
+}
+
+.infoboxnptable {
+ height:32px;
+ width:100%;
+ background-color:#990000;
+}
+
+.infoboxnptable2 {
+ height:32px;
+ width:100%;
+ background-color:#990000;
+}
+
+.infoboxnp {
+ background-color:#990000;
+ width:100%;
+}
+
+.infoboxnpimg {
+ vertical-align:middle;
+ width:28px;
+ height:32px;
+ background-color:#990000;
+}
+
+.inputerrorsleft {
+ background-color: #990000;
+ width: 36px;
+}
+
+.inputerrorsright {
+ background-color: #FFD9D1;
+ color: #000000;
+ font-size: 11px;
+ padding-left: 8px;
+ padding-top: 6px;
+}
+
+div.GraphLink {
+ position: relative;
+}
+
+span.GraphLinkLine {
+ position: absolute;
+ background-color: #990000;
+ width: 100%;
+}
+
+/* DOM Tooltip CSS definitions */
+div.niceTitle
+{
+ background-color: #333333;
+ color: #FFFFFF;
+ font-weight: bold;
+ font-size: 13px;
+ font-family: "Trebuchet MS", sans-serif;
+ width: 220px;
+ left: 0;
+ top: 0;
+ padding: 4px;
+ position: absolute;
+ text-align: left;
+ z-index: 20;
+ -moz-border-radius: 0 10px 10px 10px;
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=87);
+ -moz-opacity: .87;
+ -khtml-opacity: .87;
+ opacity: .87;
+}
+div.niceTitle h1
+{
+ background: #990000;
+ border-bottom: 1px dotted #FFFFFF;
+ font-weight: bold;
+ font-size: 13px;
+ font-family: "Trebuchet MS", sans-serif;
+ margin: 3px;
+ padding-top: 1px;
+ padding-bottom: 1px;
+ padding-left: 3px;
+ text-align: left;
+ left: 0;
+ top: 0;
+ -moz-border-radius: 0 8px 0 0;
+ -moz-opacity: 1;
+}
+div.niceTitle .contents
+{
+ margin: 0;
+ padding: 0 3px;
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=100);
+ -moz-opacity: 1;
+ -khtml-opacity: 1;
+ opacity: 1;
+}
+div.niceTitle p
+{
+ background: #FFFFFF;
+ border: 1px solid #990000;
+ color: #000000;
+ font-size: 11px;
+ font-family: "Trebuchet MS", sans-serif;
+ padding: 5px;
+ margin: 3px;
+ text-align: left;
+ -moz-opacity: 1;
+ -moz-border-radius: 0 0 8px 8px;
+}
+
+body {
+ margin: 0px auto;
+ align: left;
+ background: url('images/background.jpg') no-repeat;
+ background-position : left 0px;
+ background-attachment: fixed;
+ background-color: #7f7f7f;
+}
+a:link {
+ color: #550000;
+}
+
+a:visited {
+ color: #550000;
+}
+
+a:active {
+ color: #550000;
+}
+
+a:hover {
+ color: #550000;
+}
+
+form {
+ margin: 0px;
+}
+a {
+ text-decoration: none;
+}
+form input {
+ font-size: 1.1em;
+}
+
+iframe {
+ z-index: 1;
+ border: 1px dashed #990000;
+}
+.iframe {
+ background-color: #FFFFFF;
+}
+
+/* style of disabled formelements */
+#wrap div {margin:1em 0}
+[disabled] {
+ color:#666666;
+ background:#eeeeee;
+}
+
+/* ID Based CSS Definitions */
+/* margin: 0px auto makes the content centered, margin 0px 0px makes it aligned to the left */
+#wrapper {
+ width: 810px;
+ margin: 0px 0px;
+/* left: 0px; */
+}
+
+#header {
+ background: url('images/header.png') no-repeat;
+ background-position: 0px;
+ height: 40px;
+ width: 810px;
+ position: fixed;
+ left: 0;
+ margin-bottom: 5px;
+ z-index: 2;
+}
+#header-left {
+ position: relative;
+ /* background: url('images/logo.gif') no-repeat; */
+ background-position: center;
+ height: 40px;
+ width: 80px;
+ left: 0px;
+ top:0px;
+ float: left;
+}
+#header-left #status-link {
+ position: relative;
+ top: 0px;
+ left: 0px;
+}
+#header-right {
+ position: relative;
+ /* background: url('images/header.gif') no-repeat; */
+ height: 70px;
+ color: #fff;
+ left: 0px;
+ margin-left: 165px;
+}
+#header-right .alert {
+ position: relative;
+ /* background: url('images/alert.gif') no-repeat; */
+ background-position: 4px 2px;
+ color: #fff;
+ height: 17px;
+ width: 500px;
+ padding: 4px;
+ padding-left: 27px;
+ float: left;
+}
+#header-right .container {
+ position: relative;
+}
+#header-right .container .left {
+ position: relative;
+ float: left;
+ font-size: 1.3em;
+ font-weight: bold;
+ top: 15px;
+ left: 4px;
+ display: none;
+}
+#header-right .container .right {
+ position: relative;
+ float: right;
+ top: 22px;
+ padding-right: 4px;
+ z-index: 1;
+}
+
+/* for forcing an alert run the following command from diagnostics>command, php command:
+file_notice("blah", "blah blah...testing my new theme...");
+*/
+
+#header-right .container .right #alerts {
+ position: fixed;
+ background: url('images/alert_bgr.png') no-repeat;
+ height: 40px;
+ width: 400px;
+ top: 0px;
+ left: 810px;
+ z-index: 2;
+ padding-top: 1px;
+ padding-left: 10px;
+ margin: 0px;
+}
+
+#header-right .container .right #hostname {
+ position: fixed;
+ background: url('images/hostname.png') no-repeat;
+ height: 40px;
+ width: 400px;
+ z-index: 1;
+ padding-right: 5px;
+ margin: 0px;
+ top: 0px;
+ left: 810px;
+ font-size: 12px;
+ color: #000000;
+ font-weight: bold;
+ padding-left: 40px;
+ padding-top: 2px;
+ text-align: left;
+}
+
+
+
+
+table#marquee {
+ position: relative;
+ top: -4px;
+ left: 15px;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ width: 350px;
+ background-color: transparent;
+ padding: 2px;
+ border: 0px;
+}
+span#marquee-container {
+ position: absolute;
+ visibility: hidden;
+ top: -100px;
+ left: -10000px;
+}
+div#marquee-text {
+/* font-size: 1.18em;
+ font-weight: normal;
+ font-family: Verdana;
+ color: #ffffff; */
+ font-size: 12px;
+ font-weight: normal;
+ font-style: italic;
+ color: #000000;
+}
+table#marquee div#container {
+ position: relative;
+ overflow: hidden;
+ width: 330px;
+ height: 16px;
+}
+table#marquee div#container div#scroller {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+}
+
+
+
+
+
+#content {
+ position: relative;
+ top: 0px;
+ left: 75px;
+ margin-top: 0px;
+ margin-left: 0px;
+ padding-top: 50px;
+ padding-left: 20px;
+ width: 840px;
+ background-color: #ffffff;
+ background: url('images/horizontal.png') repeat-y;
+}
+
+
+/* try to abuse left as a fadeout at the end of the page */
+#left {
+ width: 810px;
+ height: 1px;
+}
+
+#right {
+ position: relative;
+ top: -10px;
+ left: 0px;
+ width: 770px;
+ margin-top: 0px;
+ margin-left: 5px;
+ margin-right: 5px;
+ padding-top: 20px;
+ padding-left: 10px;
+ padding-right: 10px;
+ padding-bottom: 90px;
+ min-height: 400px;
+
+}
+
+#footer {
+ position: relative;
+/* margin-bottom: 5px; */
+ background: url('images/footer.png') no-repeat;
+/* top: -100px; */
+ bottom: 0px;
+ left: 75px;
+/* width: 1210px; */
+ width: 840px;
+ height: 60px;
+ color: #000000;
+ text-align: center;
+ font-size: 0.9em;
+ padding-top: 10px;
+ padding-left: 10px;
+ clear: both;
+}
+#footer p {
+ padding: 0px;
+ margin: 0px;
+
+}
+
+/* Style the List */
+#navigation {
+ /* background: url('images/menu.gif') no-repeat; */
+ /* width: 693px; */
+/* position: relative; */
+ position: fixed;
+ top: 0px;
+ left: 100px;
+ width: 810px;
+ padding: 0px;
+ height: 28px;
+ z-index: 3;
+}
+#navigation ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+ text-align: center;
+}
+#navigation ul#menu {
+ padding-top: 3px;
+ padding-left: 5px;
+}
+
+/* Style the List Elements */
+#navigation ul li {
+ float: left;
+ position: relative;
+ /* width: 7.5em; */
+ width: 100px;
+ top: 0px;
+ /* top: -1px; */
+}
+/* Text mainmenubar */
+#navigation ul li div {
+
+ background-image: url(images/mainmenu-right.gif);
+ background-position: 5% 50%;
+ background-repeat: no-repeat;
+ padding-top:0px;
+ font-size: 12px;
+ font-weight: normal;
+ color: #ffffff;
+ text-align: center;
+ height: 13px;
+
+
+
+
+/*
+background: url("images/mainmenuitem.gif") top left no-repeat;
+vertical-align: top;
+border: 0px;
+width: 100px;
+height:20px;
+*/
+
+
+}
+/* Make the List inside the List Elements */
+/* initially hidden with absolute position */
+#navigation ul li ul {
+ display: none;
+ position: absolute;
+/* top: 2em;
+ left: -2px; */
+ width: 120px;
+ font-weight: normal;
+/* background: transparent bottom left no-repeat; /* This is key to making the menu maintain visibility when not on a link */
+ /* background-color: #202020; */
+ background: url("images/menubgr_footer.png") no-repeat;
+ background-position: bottom;
+/* padding: 0em 0 0.4em 0; */
+ padding-top: 5px;
+ padding-bottom: 10px;
+}
+/* to override top and left in browsers other than IE */
+/* which will position to the top right of the containing */
+/* li, rather than bottom left */
+#navigation ul li > ul {
+ top: auto;
+ left: auto;
+ left: -1px !important;
+}
+/* Show initial drop down upon mouse over, but do not show */
+/* nested side drop menus within listed elements */
+#navigation ul li:hover ul {
+ display: block;
+ cursor: pointer;
+}
+#navigation ul li:hover {
+ cursor: pointer;
+ cursor: pointer;
+}
+#navigation ul li:hover div {
+ text-decoration: none;
+ background-image: url(images/mainmenu-down.gif);
+ background-position: 5% 50%;
+ background-repeat: no-repeat;
+
+}
+
+#navigation ul li {
+ background-color: transparent;
+ color: #000000;
+}
+/* dropdownmenu */
+#navigation ul li ul li {
+ border: 0px solid #850000;
+ width: 120px;
+ height: 1.6em;
+ line-height: 1.6em;
+/* background-color: #850000; */
+ background: url(images/menubgr.png) repeat-y;
+ z-index: 2;
+/* color: #000000; */
+/* filter:alpha(opacity=95);
+ -moz-opacity:0.95;
+ -khtml-opacity: 0.95;
+ opacity: 0.95; */
+}
+#navigation ul li ul li:hover {
+/* background-color: #666666; */
+ background-image: url(images/menubgr_highlight.png);
+ background-repeat: repeat-y;
+}
+
+/* textcolor in dropdownmenu */
+#navigation li li a {
+ display: block;
+ padding-left: 8px;
+ padding-right: 8px;
+ color: #ffffff;
+ font-size: 11px;
+ font-weight: normal;
+ text-align: left;
+/*
+ background-image: url(images/menu-dot.gif);
+ background-position: 0% 50%;
+ background-repeat: no-repeat;
+*/
+}
+
+#navigation ul li ul li a.navlnk:hover {
+ text-decoration: none;
+}
+#navigation ul li.first {
+ border-right: 0px;
+}
+#navigation ul li.middle {
+ border-right: 0px;
+}
+#navigation ul li.last {
+
+}
+
+#navigation ul li.dropfirst {
+ border-bottom: 0px;
+}
+#navigation ul li.dropmiddle {
+ border-bottom: 0px;
+}
+#navigation ul li.droplast {
+}
+
+#wzdtabcont {
+ float: left;
+ background-color: #FFFFFF;
+ color: #000000;
+ padding: 0;
+}
+
+ul#wzdnav {
+ font-size: 0.96em;
+ float: left;
+ width: 14.5em;
+ margin: 0;
+ padding-left: 18px;
+}
+
+ul#wzdnav li {
+ list-style: none;
+ margin: 0;
+ padding-bottom: 0.2em;
+ padding-left: 0;
+}
+
+ul#wzdnav a {
+ display: block;
+ padding: 0.3em;
+ font-weight: normal;
+}
+
+#wzdnavbold a {
+ display: block;
+ padding: 0.3em;
+ font-weight: bold ! important;
+}
+
+ul#wzdnav a:link {
+ color: black;
+ background-color: #eee;
+}
+
+ul#wzdnav a:visited {
+ color: #666;
+ background-color: #eee;
+}
+
+ul#wzdnav a:hover {
+ color: black;
+ background-color: white;
+}
+
+ul#wzdnav a:active {
+ color: white;
+ background-color: gray;
+}
+
+#graph {
+ position: relative;
+ z-index: 10;
+}
+
+#logoutbtn {
+ position: absolute;
+ left: 95%;
+ vertical-align: middle;
+}
+
+
+#graph {
+ position: relative;
+ z-index: 10;
+}
+
+
+
+/* Class Based CSS Definitions */
+.pgtitle {
+ font-size: 18px;
+ color: #777777;
+ font-weight: bold;
+}
+.tfrtitle {
+ font-size: 18px;
+ color: #ffffff;
+ font-weight: bold;
+}
+.vncell {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ border-bottom: 1px solid #999999;
+}
+.formfld {
+ padding-left: 19px;
+ font-size: small;
+}
+.formselect {
+ font-size: 1.0em;
+}
+.langopt {
+ padding-left: 34px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.saved {
+ /* background: url('/themes/nione/images/icons/icon_wzd_saved.png') no-repeat 0 1px #FFFFFF; */
+ list-style-image: url('/themes/nervecenter/images/icons/icon_wzd_saved.png') ! important;
+}
+.notsaved {
+ /* background: url('/themes/nione/images/icons/icon_wzd_nsaved.png') no-repeat 0 1px #FFFFFF; */
+ list-style-image: url('/themes/nervecenter/images/icons/icon_wzd_nsaved.png') ! important;
+}
+.en {
+ background: url('/themes/nervecenter/images/icons/icon_flag_en.png') no-repeat 0 1px #FFFFFF;
+}
+.de {
+ background: url('/themes/nervecenter/images/icons/icon_flag_de.png') no-repeat 0 1px #FFFFFF;
+}
+.es {
+ background: url('/themes/nervecenter/images/icons/icon_flag_es.png') no-repeat 0 1px #FFFFFF;
+}
+.pt_BR {
+ background: url('/themes/nervecenter/images/icons/icon_flag_pt_BR.png') no-repeat 0 1px #FFFFFF;
+}
+.host {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_host.png') no-repeat 0 1px #FFFFFF;
+}
+.search {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_search.png') no-repeat 0 1px #FFFFFF;
+}
+.file {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_file.png') no-repeat 0 1px #FFFFFF;
+}
+.mail {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_mail.png') no-repeat 0 1px #FFFFFF;
+}
+.imp {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_imp.png') no-repeat 0 1px #FFFFFF;
+}
+.pwd {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_pwd.png') no-repeat 0 1px #FFFFFF;
+}
+.user {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_user.png') no-repeat 0 1px #FFFFFF ;
+}
+.group {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_group.png') no-repeat 0 1px #FFFFFF;
+}
+.url {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_url.png') no-repeat 0 1px #FFFFFF;
+}
+.time {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_time.png') no-repeat 0 1px #FFFFFF;
+}
+.unknown {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_unknown.png') no-repeat 0 1px #FFFFFF;
+}
+.formfld_cert {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_cert.png') no-repeat 0 1px #FFFFFF;
+ padding-left: 28px;
+ font-family: Courier New, Courier, monospaced;
+ font-size: 11px;
+}
+.formfldalias {
+ background-color: #990000;
+ color: #FFFFFF;
+}
+.formpre {
+ font-family: Courier New, Courier, monospaced;
+ font-size: 10px;
+}
+.formbtn {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 13px;
+ font-weight: bold;
+}
+.formbtns {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 10px;
+ font-weight: bold;
+}
+.vvcell {
+ background-color: #FFFFC6;
+}
+.errmsg {
+ font-weight: bold;
+ color: #CC0000;
+}
+.red {
+ color: #CC0000;
+}
+.gray {
+ color: #A0A0A0;
+}
+.vexpl {
+ font-size: 11px;
+}
+.navlnk {
+ color: #FFFFFF;
+ text-decoration: none;
+ font-size: 13px;
+}
+.navlnks {
+ color: #FFFFFF;
+ text-decoration: none;
+ font-size: 11px;
+}
+.redlnk {
+ color: #990000;
+ text-decoration: none;
+}
+.tblnk {
+ color: #FFFFFF;
+ text-decoration: none;
+}
+.vncellreq {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+}
+.vncellt {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+}
+.vtable {
+ border-bottom: 1px solid #999999;
+}
+.vnsepcell {
+ background-color: #BBBBBB;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.cpline {
+ font-size: 11px;
+ color: #FFFFFF;
+}
+.hostname {
+ font-size: 11px;
+ color: #990000;
+ font-weight: bold;
+}
+.vnsepcellr {
+ background-color: #BBBBBB;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.listrborder {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-left: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 6px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listr {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 6px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listrpad {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 16px;
+ padding-left: 10px;
+ padding-top: 8px;
+ padding-bottom: 8px;
+}
+.listn {
+ font-size: 11px;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listbg {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ color: #FFFFFF;
+ background-color: #990000;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listbggrey {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ background-color: #999999;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listhdr {
+ background-color: #BBBBBB;
+ padding-right: 16px;
+ padding-left: 6px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.listhdr a {
+ color: #000000;
+}
+.listhdrr {
+ background-color: #BBBBBB;
+ padding-right: 16px;
+ padding-left: 6px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.listhdrr a {
+ color: #000000;
+}
+.listlr {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ border-left: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 6px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listlrns {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ border-left: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.list {
+ font-size: 11px;
+ padding-left: 6px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.listt {
+ font-size: 11px;
+ padding-top: 5px;
+}
+.listhdrrns {
+ background-color: #BBBBBB;
+ padding-left: 6px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ padding-right: 6px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.listbgns {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ background-color: #D9DEE8;
+ padding-left: 6px;
+ padding-right: 4px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listtopic {
+ border-right: 1px solid #999999;
+ font-size: 11px;
+ background-color: #990000;
+ padding-right: 16px;
+ padding-left: 6px;
+ color: #FFFFFF;
+ font-weight: bold;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+.optsect_t {
+ border-right: 1px solid #999999;
+ background-color: #990000;
+ padding-right: 6px;
+ padding-left: 6px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.optsect_s {
+ font-size: 11px;
+ color: #FFFFFF;
+ font-weight: bold;
+}
+.tabnavtbl {
+}
+
+
+/* MISC CSS Definitions */
+ul#tabnav {
+ font-size: 11px;
+ font-weight: bold;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+ul#tabnav li.tabinact1 {
+ float: left;
+ background-color: #777777;
+ color: #FFFFFF;
+ padding: 0;
+ white-space: nowrap;
+}
+ul#tabnav li.tabinact {
+ float: left;
+ border-left: 1px solid #999999;
+ background-color: #777777;
+ color: #FFFFFF;
+ padding: 0;
+ white-space: nowrap;
+}
+ul#tabnav li.tabinact a {
+ float: left;
+ display: block;
+ text-decoration: none;
+ padding: 5px 8px 5px 8px;
+ color: #FFFFFF;
+}
+ul#tabnav li.tabinact1 a {
+ float: left;
+ display: block;
+ text-decoration: none;
+ padding: 5px 8px 5px 8px;
+ color: #FFFFFF;
+}
+ul#tabnav li.tabact {
+ float: left;
+ background-color: #EEEEEE;
+ color: #000000;
+ padding: 5px 8px 5px 8px;
+ white-space: nowrap;
+}
+.tabcont {
+ background-color: #EEEEEE;
+ padding-right: 12px;
+ padding-left: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
+}
+.tabact {
+ float: left;
+ background-color: #EEEEEE;
+ color: #000000;
+ padding: 5px 8px 5px 8px;
+ white-space: nowrap;
+}
+.tabinact {
+ font-weight: bold;
+ float: left;
+ border-left: 1px solid #999999;
+ background-color: #777777;
+ color: #FFFFFF;
+ padding: 0;
+ white-space: nowrap;
+}
+.menu {
+ background-color: #000000;
+ white-space: nowrap;
+ padding: 0px 5px 0px 5px;
+ width: 100%;
+ vertical-align: top;
+}
+
+/* style of disabled formelements */
+[disabled] {
+ color:#666666;
+ background:#eeeeee;
+}
+
+
+/* Auto Complete Suggestions */
+div.suggestions {
+ -moz-box-sizing: border-box;
+ /* box-sizing: border-box; */
+ border: 1px solid black;
+ position: absolute;
+ background-color: #990000;
+ color: #FFF;
+}
+
+div.suggestions div {
+ cursor: default;
+ padding: 0px 3px;
+ background-color: #990000;
+ color: #FFF;
+}
+
+div.suggestions div.current {
+ background-color: #3366cc;
+ color: #FFF;
+}
+/* End Auto Complete Suggestions */
+
+
+/* Nifty Corners Crap */
+.rtop,.artop{display:block}
+.rtop *,.artop *{display:block;height:1px;overflow:hidden;font-size:1px}
+.artop *{border-style: solid;border-width:0 1px}
+.r1,.rl1,.re1,.rel1{margin-left:5px}
+.r1,.rr1,.re1,.rer1{margin-right:5px}
+.r2,.rl2,.re2,.rel2,.ra1,.ral1{margin-left:3px}
+.r2,.rr2,.re2,.rer2,.ra1,.rar1{margin-right:3px}
+.r3,.rl3,.re3,.rel3,.ra2,.ral2,.rs1,.rsl1,.res1,.resl1{margin-left:2px}
+.r3,.rr3,.re3,.rer3,.ra2,.rar2,.rs1,.rsr1,.res1,.resr1{margin-right:2px}
+.r4,.rl4,.rs2,.rsl2,.re4,.rel4,.ra3,.ral3,.ras1,.rasl1,.res2,.resl2{margin-left:1px}
+.r4,.rr4,.rs2,.rsr2,.re4,.rer4,.ra3,.rar3,.ras1,.rasr1,.res2,.resr2{margin-right:1px}
+.rx1,.rxl1{border-left-width:5px}
+.rx1,.rxr1{border-right-width:5px}
+.rx2,.rxl2{border-left-width:3px}
+.rx2,.rxr2{border-right-width:3px}
+.re2,.rel2,.ra1,.ral1,.rx3,.rxl3,.rxs1,.rxsl1{border-left-width:2px}
+.re2,.rer2,.ra1,.rar1,.rx3,.rxr3,.rxs1,.rxsr1{border-right-width:2px}
+.rxl1,.rxl2,.rxl3,.rxl4,.rxsl1,.rxsl2,.ral1,.ral2,.ral3,.ral4,.rasl1,.rasl2{border-right-width:0}
+.rxr1,.rxr2,.rxr3,.rxr4,.rxsr1,.rxsr2,.rar1,.rar2,.rar3,.rar4,.rasr1,.rasr2{border-left-width:0}
+.r4,.rl4,.rr4,.re4,.rel4,.rer4,.ra4,.rar4,.ral4,.rx4,.rxl4,.rxr4{height:2px}
+.rer1,.rel1,.re1,.res1,.resl1,.resr1{border-width:1px 0 0;height:0px !important;height /**/:1px}
+/* End Nifty Corners Crap */
+
+
+
+/* CSS for Dynamic Log Viewer */
+/* Author: Erik Kristensen */
+div#log div.log-entry {
+ clear: both;
+}
+
+div#log div.log-entry span,
+div#log div.log-header span {
+ padding: 3px 2px 3px 2px;
+ padding-left: 8px;
+}
+
+div#log div.log-entry span.log-action {
+ padding-bottom: 6px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+div#log div.log-header span {
+ border-top: 1px solid #999;
+ background-color: #bbb;
+ font-weight: bold;
+ text-align: left;
+}
+
+div#log span.log-action,
+div#log span.log-time,
+div#log span.log-interface,
+div#log span.log-source,
+div#log span.log-destination,
+div#log span.log-protocol {
+ float: left;
+ text-align: left;
+ border-left: 1px solid #999;
+ border-bottom: 1px solid #999;
+
+}
+
+div#log span.log-general {
+
+}
+
+div#log span.log-protocol {
+ border-right: 1px solid #999;
+}
+
+div#log span.log-action {
+ width: 2em;
+ text-align: center;
+}
+
+div#log span.log-time {
+ width: 12.5em;
+}
+
+div#log span.log-interface {
+ width: 5em;
+}
+
+div#log span.log-source,
+div#log span.log-destination {
+ width: 17.6em;
+}
+
+div#log span.log-protocol {
+ width: 5.5em;
+}
+/* END CSS FOR DYNAMIC LOG VIEWER */
+
+#login {
+ background: #cccccc;
+ border: 0px solid #666666;
+ margin: 5em auto;
+ padding: 0em;
+ width: 340px;
+}
+
+#login h1 {
+ background: url(images/misc/logon.png) no-repeat top left;
+ margin-top: 0;
+ display: block;
+ text-indent: -1000px;
+ height: 50px;
+ border-bottom: none;
+}
+
+#login p {
+ font-size: 1em;
+ font-weight: bold;
+ padding: 3px;
+ margin: 0em;
+ text-indent: 10px;
+}
+
+#login span {
+ font-size: 1em;
+ font-weight: bold;
+ width: 20%;
+ padding: 3px;
+ margin: 0em;
+ text-indent: 10px;
+}
+
+#login p#text {
+ font-size: 1em;
+ font-weight: normal;
+ padding: 3px;
+ margin: 0em;
+ text-indent: 10px;
+}
+
+#login #username, #password {
+ font-size: 1em;
+ width: 60%;
+ padding: 3px;
+ margin: 0em;
+}
+
+#login #submit {
+ font-size: 1em;
+ font-weight: bold;
+ padding: 3px;
+ margin: 0em;
+ text-indent: 10px;
+}
+
+/* Widget CSS */
+.widgetsubheader {
+ border-right: 1px solid #999999;
+ font-size: 11px;
+ background-color: #B1B1B1;
+ padding-right: 6px;
+ padding-left: 6px;
+ color: #000000;
+ font-weight: bold;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.widgetheader {
+ border-right: 1px solid #999999;
+ font-size: 11px;
+ background-color: #990000;
+ padding-right: 6px;
+ padding-left: 6px;
+ color: #FFFFFF;
+ font-weight: bold;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.widgetdiv{
+ margin:5px;
+ padding: 5px;
+ background:#CCCCCC;
+}
+.widgetconfigdiv{
+ background:#BBBBBB;
+ font-size: 11px;
+ color: #000000;
+ padding-right: 5px;
+ padding-left: 5px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+div#log div.log-entry-mini {
+ clear: both;
+}
+
+div#log div.log-entry-mini span {
+ padding: 2px 2px 2px 2px;
+ padding-left: 8px;
+}
+
+div#log span.log-action-mini-header,
+div#log span.log-interface-mini-header,
+div#log span.log-source-mini-header,
+div#log span.log-destination-mini-header,
+div#log span.log-protocol-mini-header {
+ float: left;
+ text-align: left;
+ background-color: #B1B1B1;
+ font-size: 12px;
+ border-left: 1px solid #999;
+ border-bottom: 1px solid #999;
+}
+
+div#log span.log-action-mini,
+div#log span.log-time-mini,
+div#log span.log-interface-mini,
+div#log span.log-source-mini,
+div#log span.log-destination-mini,
+div#log span.log-protocol-mini {
+ float: left;
+ text-align: left;
+ background-color: #FFFFFF;
+ font-size: 11px;
+ border-left: 1px solid #999;
+ border-bottom: 1px solid #999;
+}
+
+div#log span.log-action-mini,
+div#log span.log-action-mini-header {
+ width: 6%;
+}
+
+div#log span.log-interface-mini,
+div#log span.log-interface-mini-header {
+ width: 8%;
+}
+
+div#log span.log-source-mini,
+div#log span.log-destination-mini,
+div#log span.log-source-mini-header,
+div#log span.log-destination-mini-header {
+ width: 31%;
+}
+
+div#log span.log-protocol-mini,
+div#log span.log-protocol-mini-header {
+ width: 8%;
+ border-right: 1px solid #999;
+}
+
+/* Sortable tables */
+table.sortable thead {
+ cursor: default;
+ background-color: #EEEEEE;
+ padding-right: 12px;
+ padding-left: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
+}
diff --git a/usr/local/www/themes/pfsense_ng/bottom-loader.js b/usr/local/www/themes/pfsense_ng/bottom-loader.js
new file mode 100644
index 0000000..78e3eba
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/bottom-loader.js
@@ -0,0 +1,10 @@
+<!--
+
+ NiftyCheck();
+ Rounded("div#niftyMenu","top bottom","#FFFFFF","#000000","smooth");
+ Rounded("div#mainarea","bl br tr","#FFF","#eeeeee","smooth");
+ Rounded("div#boxarea","bl br tl tr","#FFF","#eeeeee","smooth");
+ Rounded("tr#fend","bl br tl tr","#FFF","#990000","smooth");
+ Rounded("div#topbox","all","#FFF","#990000","smooth");
+
+//-->
diff --git a/usr/local/www/themes/pfsense_ng/favicon.ico b/usr/local/www/themes/pfsense_ng/favicon.ico
new file mode 100644
index 0000000..3440bf2
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/favicon.ico
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/graphlink.css b/usr/local/www/themes/pfsense_ng/graphlink.css
new file mode 100644
index 0000000..521059e
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/graphlink.css
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ $Id: graphlink.css,v 1.2.2.1 2007/01/17 18:43:30 sullrich Exp $
+
+ This file is part of the GraphLink software.
+ GraphLink is distributed under the MIT License.
+ Copyright (C) 2005-2006 Max Khitrov <max@mxsoft.org>
+*******************************************************************************/
+
+/**
+ * Defines the background image used for the graph, as well as the actual data
+ * locations.
+ * Use padding-left and padding-top to align the data area correctly with your
+ * background image.
+ * Width and height should same as the dimensions of the image, minus the
+ * padding values in both directions.
+ */
+div.GraphLink {
+ width: 212px;
+ height: 60px;
+ padding-left: 38px;
+ padding-top: 10px;
+ background-image: url(/themes/nervecenter/images/misc/graph.png);
+ overflow: hidden;
+}
+
+/**
+ * Defines the data display area. Modify to fit your background image.
+ */
+div.GraphLinkData {
+ width: 200px;
+ height: 50px;
+ overflow: hidden;
+}
+
+/**
+ * Defines the look of one bar. Nothing to change here other than the color.
+ */
+span.GraphLinkBar {
+ background-color: #990000;
+ height: 100%;
+ float: left;
+ overflow: hidden;
+}
diff --git a/usr/local/www/themes/pfsense_ng/images/alert_bgr.png b/usr/local/www/themes/pfsense_ng/images/alert_bgr.png
new file mode 100644
index 0000000..9854054
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/alert_bgr.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/alerter.png b/usr/local/www/themes/pfsense_ng/images/alerter.png
new file mode 100644
index 0000000..0bc856e
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/alerter.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/background.jpg b/usr/local/www/themes/pfsense_ng/images/background.jpg
new file mode 100644
index 0000000..1cc621b
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/background.jpg
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/footer.png b/usr/local/www/themes/pfsense_ng/images/footer.png
new file mode 100644
index 0000000..296e7e8
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/footer.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/header.png b/usr/local/www/themes/pfsense_ng/images/header.png
new file mode 100644
index 0000000..6f8128c
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/header.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/horizontal.png b/usr/local/www/themes/pfsense_ng/images/horizontal.png
new file mode 100644
index 0000000..eadffe4
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/horizontal.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/hostname.png b/usr/local/www/themes/pfsense_ng/images/hostname.png
new file mode 100644
index 0000000..cd79f5c
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/hostname.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/favicon.ico b/usr/local/www/themes/pfsense_ng/images/icons/favicon.ico
new file mode 100644
index 0000000..3440bf2
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/favicon.ico
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_advanced.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_advanced.gif
new file mode 100644
index 0000000..3ede1ff
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_advanced.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_advanced_s.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_advanced_s.gif
new file mode 100644
index 0000000..b233549
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_advanced_s.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_alert.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_alert.gif
new file mode 100644
index 0000000..a88e61b
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_alert.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_host.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_host.gif
new file mode 100644
index 0000000..ad43e17
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_host.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_net.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_net.gif
new file mode 100644
index 0000000..abd1b8b
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_net.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_port.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_port.gif
new file mode 100644
index 0000000..4acf2aa
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_port.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_url.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_url.gif
new file mode 100644
index 0000000..660571e
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_url.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_url_reload.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_url_reload.gif
new file mode 100644
index 0000000..55c1c4a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_alias_url_reload.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_block.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_block.gif
new file mode 100644
index 0000000..670c968
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_block.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_block_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_block_d.gif
new file mode 100644
index 0000000..e6345fe
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_block_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_cablenic.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_cablenic.gif
new file mode 100644
index 0000000..a071c66
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_cablenic.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_cal.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_cal.gif
new file mode 100644
index 0000000..a9c7c87
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_cal.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_cal_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_cal_mo.gif
new file mode 100644
index 0000000..1647e2f
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_cal_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_carp.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_carp.gif
new file mode 100644
index 0000000..9454a82
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_carp.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_carp_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_carp_d.gif
new file mode 100644
index 0000000..2ba8db2
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_carp_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_chain.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_chain.png
new file mode 100644
index 0000000..cd9a7cc
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_chain.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_check.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_check.gif
new file mode 100644
index 0000000..393674d
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_check.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_clock_green.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_clock_green.gif
new file mode 100644
index 0000000..e171ba8
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_clock_green.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_clock_grey.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_clock_grey.gif
new file mode 100644
index 0000000..00c865a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_clock_grey.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_clock_red.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_clock_red.gif
new file mode 100644
index 0000000..7b412ee
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_clock_red.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_close.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_close.gif
new file mode 100644
index 0000000..e0f86a7
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_close.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_configure.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_configure.gif
new file mode 100644
index 0000000..7182e0d
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_configure.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_down.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_down.gif
new file mode 100644
index 0000000..b71a9c5
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_down.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_down_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_down_d.gif
new file mode 100644
index 0000000..70a7473
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_down_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_down_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_down_mo.gif
new file mode 100644
index 0000000..584587a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_down_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_e.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_e.gif
new file mode 100644
index 0000000..2950800
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_e.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_e_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_e_mo.gif
new file mode 100644
index 0000000..9ba5738
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_e_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_error.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_error.gif
new file mode 100644
index 0000000..e0fa659
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_error.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_exclam.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_exclam.gif
new file mode 100644
index 0000000..36c2ec7
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_exclam.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_de.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_de.png
new file mode 100644
index 0000000..a01f067
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_de.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_en.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_en.png
new file mode 100644
index 0000000..069e2e3
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_en.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_es.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_es.png
new file mode 100644
index 0000000..a56047f
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_es.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_pt_BR.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_pt_BR.png
new file mode 100644
index 0000000..4ea2503
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_flag_pt_BR.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_cert.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_cert.png
new file mode 100644
index 0000000..392f4b6
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_cert.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_file.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_file.png
new file mode 100644
index 0000000..6ea6349
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_file.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_group.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_group.png
new file mode 100644
index 0000000..031f830
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_group.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_host.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_host.png
new file mode 100644
index 0000000..75bd7a4
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_host.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_imp.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_imp.png
new file mode 100644
index 0000000..f8d846d
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_imp.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_mail.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_mail.png
new file mode 100644
index 0000000..2bd40e3
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_mail.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_pwd.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_pwd.png
new file mode 100644
index 0000000..3218268
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_pwd.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_search.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_search.png
new file mode 100644
index 0000000..23f5996
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_search.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_time.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_time.png
new file mode 100644
index 0000000..9902bdf
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_time.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_unknown.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_unknown.png
new file mode 100644
index 0000000..5134e67
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_unknown.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_url.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_url.png
new file mode 100644
index 0000000..d3cda19
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_url.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_user.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_user.png
new file mode 100644
index 0000000..185f4a0
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_frmfld_user.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_fw-update.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_fw-update.gif
new file mode 100644
index 0000000..52c18ac
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_fw-update.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_ifalias.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_ifalias.gif
new file mode 100644
index 0000000..0c569a7
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_ifalias.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_ifalias_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_ifalias_d.gif
new file mode 100644
index 0000000..faa84d4
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_ifalias_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_import_alias.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_import_alias.gif
new file mode 100644
index 0000000..d11a5f0
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_import_alias.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_in.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_in.gif
new file mode 100644
index 0000000..f1da771
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_in.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_in_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_in_d.gif
new file mode 100644
index 0000000..18e26be
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_in_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_info_pkg.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_info_pkg.gif
new file mode 100644
index 0000000..cd3a532
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_info_pkg.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_interface_down.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_interface_down.gif
new file mode 100644
index 0000000..0626655
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_interface_down.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_interface_up.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_interface_up.gif
new file mode 100644
index 0000000..1449513
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_interface_up.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_left.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_left.gif
new file mode 100644
index 0000000..8effefe
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_left.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_left_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_left_d.gif
new file mode 100644
index 0000000..c778014
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_left_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_left_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_left_mo.gif
new file mode 100644
index 0000000..84c6fa2
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_left_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_log.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_log.gif
new file mode 100644
index 0000000..4a1983a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_log.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_log_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_log_d.gif
new file mode 100644
index 0000000..d31bd9b
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_log_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_log_s.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_log_s.gif
new file mode 100644
index 0000000..f9fda33
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_log_s.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_log_s_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_log_s_d.gif
new file mode 100644
index 0000000..fb2c05f
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_log_s_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_minus.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_minus.gif
new file mode 100644
index 0000000..417544f
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_minus.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_open.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_open.gif
new file mode 100644
index 0000000..ac3da14
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_open.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_other.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_other.gif
new file mode 100644
index 0000000..e6f780f
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_other.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_other_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_other_d.gif
new file mode 100644
index 0000000..b08d970
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_other_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_out.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_out.gif
new file mode 100644
index 0000000..1a1d1d5
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_out.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_out_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_out_d.gif
new file mode 100644
index 0000000..879f1da
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_out_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_parp.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_parp.gif
new file mode 100644
index 0000000..96acaf3
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_parp.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_parp_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_parp_d.gif
new file mode 100644
index 0000000..7d7d00e
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_parp_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_pass.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_pass.gif
new file mode 100644
index 0000000..fe1bb0d
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_pass.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_pass_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_pass_d.gif
new file mode 100644
index 0000000..6adc431
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_pass_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_plus.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus.gif
new file mode 100644
index 0000000..2a94eeb
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_bl.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_bl.gif
new file mode 100644
index 0000000..8dcd7c0
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_bl.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_bl_p.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_bl_p.gif
new file mode 100644
index 0000000..0c79849
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_bl_p.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_d.gif
new file mode 100644
index 0000000..ebc7457
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_mo.gif
new file mode 100644
index 0000000..1c7ca08
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_p.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_p.gif
new file mode 100644
index 0000000..eb41284
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_plus_p.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall.gif
new file mode 100644
index 0000000..d78b867
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_d.gif
new file mode 100644
index 0000000..13658f7
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_mo.gif
new file mode 100644
index 0000000..90b576e
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg.gif
new file mode 100644
index 0000000..9aebb03
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg_d.gif
new file mode 100644
index 0000000..4ab4992
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg_mo.gif
new file mode 100644
index 0000000..7025d20
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_pkg_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml.gif
new file mode 100644
index 0000000..4542432
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml_d.gif
new file mode 100644
index 0000000..8d3a68d
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml_mo.gif
new file mode 100644
index 0000000..15e0aed
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_reinstall_xml_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_reject.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_reject.gif
new file mode 100644
index 0000000..5565cd6
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_reject.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_reject_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_reject_d.gif
new file mode 100644
index 0000000..6c09fae
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_reject_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_right.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_right.gif
new file mode 100644
index 0000000..fdf2d8b
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_right.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_service_restart.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_restart.gif
new file mode 100644
index 0000000..e49fbd7
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_restart.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_service_restart_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_restart_d.gif
new file mode 100644
index 0000000..a5d6d7c
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_restart_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_service_start.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_start.gif
new file mode 100644
index 0000000..09bb58f
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_start.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_service_start_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_start_d.gif
new file mode 100644
index 0000000..f58f111
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_start_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_service_stop.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_stop.gif
new file mode 100644
index 0000000..922addc
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_stop.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_service_stop_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_stop_d.gif
new file mode 100644
index 0000000..b4cfdea
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_service_stop_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_services_restart_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_services_restart_mo.gif
new file mode 100644
index 0000000..a092b40
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_services_restart_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_services_start_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_services_start_mo.gif
new file mode 100644
index 0000000..ecdb58f
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_services_start_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_services_stop_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_services_stop_mo.gif
new file mode 100644
index 0000000..c00e208
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_services_stop_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_system-group-grey.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_system-group-grey.png
new file mode 100644
index 0000000..5d3c543
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_system-group-grey.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_system-group.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_system-group.png
new file mode 100644
index 0000000..2c225a4
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_system-group.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_system-user-grey.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_system-user-grey.png
new file mode 100644
index 0000000..c5cea2c
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_system-user-grey.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_system-user.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_system-user.png
new file mode 100644
index 0000000..4f27610
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_system-user.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_system_lock_screen.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_system_lock_screen.png
new file mode 100644
index 0000000..2a286da
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_system_lock_screen.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_system_logout.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_system_logout.png
new file mode 100644
index 0000000..7a99168
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_system_logout.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_trapped.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_trapped.gif
new file mode 100644
index 0000000..ffeb2cd
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_trapped.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_trapped_p.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_trapped_p.gif
new file mode 100644
index 0000000..6d46aaf
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_trapped_p.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_ts_rule.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_ts_rule.gif
new file mode 100644
index 0000000..e15ab6c
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_ts_rule.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_ts_rule_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_ts_rule_d.gif
new file mode 100644
index 0000000..f776281
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_ts_rule_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_up.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_up.gif
new file mode 100644
index 0000000..883c5a2
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_up.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_up_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_up_d.gif
new file mode 100644
index 0000000..0ddcce2
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_up_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_up_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_up_mo.gif
new file mode 100644
index 0000000..9f869a4
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_up_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_wlan.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_wlan.gif
new file mode 100644
index 0000000..1f0addc
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_wlan.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_wlan_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_wlan_d.gif
new file mode 100644
index 0000000..35bf580
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_wlan_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_wol_all.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_wol_all.gif
new file mode 100644
index 0000000..2d22182
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_wol_all.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_wzd_nsaved.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_wzd_nsaved.png
new file mode 100644
index 0000000..12f3a43
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_wzd_nsaved.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_wzd_saved.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_wzd_saved.png
new file mode 100644
index 0000000..e7d64dc
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_wzd_saved.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_x.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_x.gif
new file mode 100644
index 0000000..24e4d49
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_x.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_x_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_x_d.gif
new file mode 100644
index 0000000..d2bfbc8
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_x_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_x_mo.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_x_mo.gif
new file mode 100644
index 0000000..da7b57c
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_x_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_x_p.gif b/usr/local/www/themes/pfsense_ng/images/icons/icon_x_p.gif
new file mode 100644
index 0000000..8828fa6
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_x_p.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/in.gif b/usr/local/www/themes/pfsense_ng/images/icons/in.gif
new file mode 100644
index 0000000..f1da771
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/in.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/in_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/in_d.gif
new file mode 100644
index 0000000..18e26be
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/in_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/out.gif b/usr/local/www/themes/pfsense_ng/images/icons/out.gif
new file mode 100644
index 0000000..1a1d1d5
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/out.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/out_d.gif b/usr/local/www/themes/pfsense_ng/images/icons/out_d.gif
new file mode 100644
index 0000000..879f1da
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/out_d.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/logo.gif b/usr/local/www/themes/pfsense_ng/images/logo.gif
new file mode 100644
index 0000000..e5da95c
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/logo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/logobig.jpg b/usr/local/www/themes/pfsense_ng/images/logobig.jpg
new file mode 100644
index 0000000..df9be55
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/logobig.jpg
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/mainmenu-down.gif b/usr/local/www/themes/pfsense_ng/images/mainmenu-down.gif
new file mode 100644
index 0000000..e59432a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/mainmenu-down.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/mainmenu-right.gif b/usr/local/www/themes/pfsense_ng/images/mainmenu-right.gif
new file mode 100644
index 0000000..14298a1
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/mainmenu-right.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/mainmenuitem.gif b/usr/local/www/themes/pfsense_ng/images/mainmenuitem.gif
new file mode 100644
index 0000000..6e97478
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/mainmenuitem.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/menu-dot.gif b/usr/local/www/themes/pfsense_ng/images/menu-dot.gif
new file mode 100644
index 0000000..c76609b
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/menu-dot.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/menu_footer.gif b/usr/local/www/themes/pfsense_ng/images/menu_footer.gif
new file mode 100644
index 0000000..d06faa4
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/menu_footer.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/menu_right.gif b/usr/local/www/themes/pfsense_ng/images/menu_right.gif
new file mode 100644
index 0000000..881327c
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/menu_right.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/menubgr.png b/usr/local/www/themes/pfsense_ng/images/menubgr.png
new file mode 100644
index 0000000..c24477b
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/menubgr.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/menubgr_footer.png b/usr/local/www/themes/pfsense_ng/images/menubgr_footer.png
new file mode 100644
index 0000000..b977a99
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/menubgr_footer.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/menubgr_highlight.png b/usr/local/www/themes/pfsense_ng/images/menubgr_highlight.png
new file mode 100644
index 0000000..1e3bf09
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/menubgr_highlight.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/bar_blue.gif b/usr/local/www/themes/pfsense_ng/images/misc/bar_blue.gif
new file mode 100644
index 0000000..741186a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/bar_blue.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/bar_gray.gif b/usr/local/www/themes/pfsense_ng/images/misc/bar_gray.gif
new file mode 100644
index 0000000..e86e245
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/bar_gray.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/bar_left.gif b/usr/local/www/themes/pfsense_ng/images/misc/bar_left.gif
new file mode 100644
index 0000000..af751fa
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/bar_left.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/bar_right.gif b/usr/local/www/themes/pfsense_ng/images/misc/bar_right.gif
new file mode 100644
index 0000000..ff12d9e
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/bar_right.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/bullet_toggle_minus.png b/usr/local/www/themes/pfsense_ng/images/misc/bullet_toggle_minus.png
new file mode 100644
index 0000000..b47ce55
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/bullet_toggle_minus.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/bullet_toggle_plus.png b/usr/local/www/themes/pfsense_ng/images/misc/bullet_toggle_plus.png
new file mode 100644
index 0000000..9ab4a89
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/bullet_toggle_plus.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/button.gif b/usr/local/www/themes/pfsense_ng/images/misc/button.gif
new file mode 100644
index 0000000..e85dbb3
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/button.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/graph.png b/usr/local/www/themes/pfsense_ng/images/misc/graph.png
new file mode 100644
index 0000000..ba054ff
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/graph.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/key_128.gif b/usr/local/www/themes/pfsense_ng/images/misc/key_128.gif
new file mode 100644
index 0000000..ea5ae34
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/key_128.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/key_152.gif b/usr/local/www/themes/pfsense_ng/images/misc/key_152.gif
new file mode 100644
index 0000000..6c7fc03
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/key_152.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/key_256.gif b/usr/local/www/themes/pfsense_ng/images/misc/key_256.gif
new file mode 100644
index 0000000..3e1c377
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/key_256.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/key_64.gif b/usr/local/www/themes/pfsense_ng/images/misc/key_64.gif
new file mode 100644
index 0000000..87892bd
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/key_64.gif
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/left_background.gif b/usr/local/www/themes/pfsense_ng/images/misc/left_background.gif
index 529d827..529d827 100644
--- a/usr/local/www/themes/the_wall/images/misc/left_background.gif
+++ b/usr/local/www/themes/pfsense_ng/images/misc/left_background.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/loader.gif b/usr/local/www/themes/pfsense_ng/images/misc/loader.gif
new file mode 100644
index 0000000..5d10ac3
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/loader.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/loader_all.gif b/usr/local/www/themes/pfsense_ng/images/misc/loader_all.gif
new file mode 100644
index 0000000..df7fdc4
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/loader_all.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/loader_filter.gif b/usr/local/www/themes/pfsense_ng/images/misc/loader_filter.gif
new file mode 100644
index 0000000..51856fc
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/loader_filter.gif
Binary files differ
diff --git a/usr/local/www/themes/_orange-flow/images/misc/loader_tab.gif b/usr/local/www/themes/pfsense_ng/images/misc/loader_tab.gif
index 05bb04c..05bb04c 100644
--- a/usr/local/www/themes/_orange-flow/images/misc/loader_tab.gif
+++ b/usr/local/www/themes/pfsense_ng/images/misc/loader_tab.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/logon.png b/usr/local/www/themes/pfsense_ng/images/misc/logon.png
new file mode 100644
index 0000000..023df8c
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/logon.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/progress_bar.gif b/usr/local/www/themes/pfsense_ng/images/misc/progress_bar.gif
new file mode 100644
index 0000000..3b4aa52
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/progress_bar.gif
Binary files differ
diff --git a/usr/local/www/themes/_orange-flow/images/misc/rrd_error.png b/usr/local/www/themes/pfsense_ng/images/misc/rrd_error.png
index 5a784bf..5a784bf 100644
--- a/usr/local/www/themes/_orange-flow/images/misc/rrd_error.png
+++ b/usr/local/www/themes/pfsense_ng/images/misc/rrd_error.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/status_alerter.gif b/usr/local/www/themes/pfsense_ng/images/misc/status_alerter.gif
new file mode 100644
index 0000000..7ff1e95
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/status_alerter.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/status_carpmaster.gif b/usr/local/www/themes/pfsense_ng/images/misc/status_carpmaster.gif
new file mode 100644
index 0000000..2c32908
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/status_carpmaster.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/status_left.gif b/usr/local/www/themes/pfsense_ng/images/misc/status_left.gif
new file mode 100644
index 0000000..b5a2930
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/status_left.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/status_page_loading.gif b/usr/local/www/themes/pfsense_ng/images/misc/status_page_loading.gif
new file mode 100644
index 0000000..4aa36c1
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/status_page_loading.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/status_reload_all.gif b/usr/local/www/themes/pfsense_ng/images/misc/status_reload_all.gif
new file mode 100644
index 0000000..dcf8631
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/status_reload_all.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/status_reload_filter.gif b/usr/local/www/themes/pfsense_ng/images/misc/status_reload_filter.gif
new file mode 100644
index 0000000..7d65264
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/status_reload_filter.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/status_right.gif b/usr/local/www/themes/pfsense_ng/images/misc/status_right.gif
new file mode 100644
index 0000000..bf66fdb
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/status_right.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/tri_c.gif b/usr/local/www/themes/pfsense_ng/images/misc/tri_c.gif
new file mode 100644
index 0000000..317b758
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/tri_c.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/tri_c_black.gif b/usr/local/www/themes/pfsense_ng/images/misc/tri_c_black.gif
new file mode 100644
index 0000000..309846e
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/tri_c_black.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/tri_o.gif b/usr/local/www/themes/pfsense_ng/images/misc/tri_o.gif
new file mode 100644
index 0000000..eb95c32
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/tri_o.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/tri_o_black.gif b/usr/local/www/themes/pfsense_ng/images/misc/tri_o_black.gif
new file mode 100644
index 0000000..f818f3b
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/tri_o_black.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/misc/widget_loader.gif b/usr/local/www/themes/pfsense_ng/images/misc/widget_loader.gif
new file mode 100644
index 0000000..ca35e2a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/misc/widget_loader.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/transparent.gif b/usr/local/www/themes/pfsense_ng/images/transparent.gif
new file mode 100644
index 0000000..89c5530
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/transparent.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/transparent_pixel.gif b/usr/local/www/themes/pfsense_ng/images/transparent_pixel.gif
new file mode 100644
index 0000000..35d42e8
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/transparent_pixel.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/wizards/initial/joincluster.gif b/usr/local/www/themes/pfsense_ng/images/wizards/initial/joincluster.gif
new file mode 100644
index 0000000..a6f90a2
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/wizards/initial/joincluster.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/wizards/initial/joincluster_mo.gif b/usr/local/www/themes/pfsense_ng/images/wizards/initial/joincluster_mo.gif
new file mode 100644
index 0000000..3787d69
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/wizards/initial/joincluster_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/wizards/initial/restore.gif b/usr/local/www/themes/pfsense_ng/images/wizards/initial/restore.gif
new file mode 100644
index 0000000..eb8931f
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/wizards/initial/restore.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/wizards/initial/restore_mo.gif b/usr/local/www/themes/pfsense_ng/images/wizards/initial/restore_mo.gif
new file mode 100644
index 0000000..2ee46c7
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/wizards/initial/restore_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/wizards/initial/standalone.gif b/usr/local/www/themes/pfsense_ng/images/wizards/initial/standalone.gif
new file mode 100644
index 0000000..aa035a4
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/wizards/initial/standalone.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/wizards/initial/standalone_mo.gif b/usr/local/www/themes/pfsense_ng/images/wizards/initial/standalone_mo.gif
new file mode 100644
index 0000000..c8066ef
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/wizards/initial/standalone_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/wizards/initial/startnewcluster.gif b/usr/local/www/themes/pfsense_ng/images/wizards/initial/startnewcluster.gif
new file mode 100644
index 0000000..dbe0ca2
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/wizards/initial/startnewcluster.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/images/wizards/initial/startnewcluster_mo.gif b/usr/local/www/themes/pfsense_ng/images/wizards/initial/startnewcluster_mo.gif
new file mode 100644
index 0000000..83d980a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/wizards/initial/startnewcluster_mo.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/blank.gif b/usr/local/www/themes/pfsense_ng/javascript/ie7/blank.gif
new file mode 100644
index 0000000..a4fe2e6
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/blank.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-box-model.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-box-model.js
new file mode 100644
index 0000000..45543f6
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-box-model.js
@@ -0,0 +1,2 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+if(window.IE7)IE7.addModule("ie7-box-model",function(){var NUMERIC="\x5cs*:\x5cs*\x5cd[\x5cw%]*",UNIT=/^\d\w*$/,PERCENT=/^\d+%$/,PIXEL=/^\d+(px)?$/;var MATCH=(appVersion<6)?/\b(min|max)-(width|height)\s*:\s*\d/gi:/\b(min|max)-width\s*:\s*\d/gi;var AUTO=(appVersion<5.5)?/^auto|0cm$/:/^auto$/;var ie7_tmp=tmpElement();push(IE7.recalcs,function removeTempElement(){if(ie7_tmp.parentElement)ie7_tmp.parentElement.removeChild(ie7_tmp)});CSSFixes.addFix(MATCH,function(match){return match.slice(0,3)+match.charAt(4).toUpperCase()+match.slice(5)});var viewport=(quirksMode)?document.body:documentElement;function isFixed(element){return element.style.position=="fixed"||element.currentStyle.position=="fixed"};function layoutParent(element){var layoutParent=element.offsetParent;while(layoutParent&&!hasLayout(layoutParent))layoutParent=layoutParent.offsetParent;if(!layoutParent||isFixed(element))layoutParent=viewport;return layoutParent};function fixWidth(HEIGHT){fixWidth=function(element,value){if(!element.runtimeStyle.fixedWidth&&(!isHTML||element.tagName!="HR")){if(!value)value=element.currentStyle.width;element.runtimeStyle.fixedWidth=(UNIT.test(value))?Math.max(0,getFixedWidth(element,value)):value;element.runtimeStyle.width=element.runtimeStyle.fixedWidth;boxSizing(element)}};if(quirksMode)CSSFixes.addRecalc("width\x5cs*:\x5cs*\x5cd\x5cw*[^%]",fixWidth);var getFixedWidth=(quirksMode)?function(element,value){return getPixelWidth(element,value)+getBorderWidth(element)+getPaddingWidth(element)}:function(element,value){return getPixelWidth(element,value)};function getBorderWidth(element){return element.offsetWidth-element.clientWidth};function getPaddingWidth(element){return getPixelWidth(element,element.currentStyle.paddingLeft)+getPixelWidth(element,element.currentStyle.paddingRight)};function getMarginWidth(element){return((element.currentStyle.marginLeft=="auto")?0:getPixelLeft(element,element.currentStyle.marginLeft))+((element.currentStyle.marginRight=="auto")?0:getPixelLeft(element,element.currentStyle.marginRight))};function minWidth(element){minWidth[minWidth.count++]=element;if(element.currentStyle.minHeight=="auto")element.runtimeStyle.minHeight=0;fixWidth(element);boxSizing(element);resizeWidth(element)};minWidth.count=0;CSSFixes.addRecalc("min-width"+NUMERIC,minWidth);eval(String(minWidth).replace(/min/g,"max"));maxWidth.count=0;CSSFixes.addRecalc("max-width"+NUMERIC,maxWidth);function resizeWidth(element){var rect=element.getBoundingClientRect();var width=rect.right-rect.left;if(element.currentStyle.maxWidth&&width>=getFixedWidth(element,element.currentStyle.maxWidth))element.runtimeStyle.width=getFixedWidth(element,element.currentStyle.maxWidth);else if(element.currentStyle.minWidth&&width<=getFixedWidth(element,element.currentStyle.minWidth))element.runtimeStyle.width=getFixedWidth(element,element.currentStyle.minWidth);else element.runtimeStyle.width=element.runtimeStyle.fixedWidth};function fixRight(element){if((element.currentStyle.position=="absolute"||element.currentStyle.position=="fixed")&&element.currentStyle.left!="auto"&&element.currentStyle.right!="auto"&&AUTO.test(element.currentStyle.width)){fixRight[fixRight.count++]=element;boxSizing(element);resizeRight(element)}};fixRight.count=0;CSSFixes.addRecalc("right"+NUMERIC,fixRight);function resizeRight(element){element.runtimeStyle.width="";var parentElement=layoutParent(element);var left=(element.runtimeStyle.screenLeft)?element.getBoundingClientRect().left-2:getPixelLeft(element,element.currentStyle.left);var width=parentElement.clientWidth-getPixelLeft(element,element.currentStyle.right)-left-getMarginWidth(element);if(!quirksMode)width-=getBorderWidth(element)+getPaddingWidth(element);if(width<0)width=0;if(isFixed(element)||HEIGHT||element.offsetWidth<width){element.runtimeStyle.fixedWidth=width;element.runtimeStyle.width=width}};var clientWidth=documentElement.clientWidth;addEventHandler(window,"onresize",function(){var i,wider=(clientWidth<documentElement.clientWidth);clientWidth=documentElement.clientWidth;for(i=0;i<minWidth.count;i++){var element=minWidth[i];var fixedWidth=(element.runtimeStyle.width==element.currentStyle.minWidth);if(wider&&fixedWidth)element.runtimeStyle.width="";if(wider==fixedWidth)resizeWidth(element)}for(i=0;i<maxWidth.count;i++){var element=maxWidth[i];var fixedWidth=(element.runtimeStyle.width==element.currentStyle.maxWidth);if(!wider&&fixedWidth)element.runtimeStyle.width="";if(wider!=fixedWidth)resizeWidth(element)}for(i=0;i<fixRight.count;i++)resizeRight(fixRight[i]);removeTempElement()});function getPixelWidth(element,value){if(PIXEL.test(value))return parseInt(value);if(PERCENT.test(value))return parseInt(parseFloat(value)/100*layoutParent(element).clientWidth);var parentElement=(element.canHaveChildren)?element:element.parentElement;parentElement.appendChild(ie7_tmp);ie7_tmp.style.width=value;return ie7_tmp.offsetWidth};function getPixelLeft(element,value){if(parseInt(value)>0)return getPixelWidth(element,value);if(PIXEL.test(value))return parseInt(value);element.parentElement.appendChild(ie7_tmp);ie7_tmp.style.left=value;return ie7_tmp.offsetLeft}};eval(String(fixWidth).replace(/Width/g,"Height").replace(/width/g,"height").replace(/Left/g,"Top").replace(/left/g,"top").replace(/Right/g,"Bottom").replace(/right/g,"bottom"));fixWidth();fixHeight(true)});
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-core.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-core.js
new file mode 100644
index 0000000..b11e2b1
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-core.js
@@ -0,0 +1,2 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+if(!window.IE7)new function(){try{window.IE7=this;var DUMMY=this.addModule=new Function;function unHide(){if(document.body)document.body.style.visibility="visible"};this.toString=function(){return "IE7 version 0.7.3 (alpha)"};var alert=(/ie7_debug/.test(location.search))?function(message){window.alert(IE7+"\n\n"+message)}:DUMMY;var appVersion=navigator.appVersion.match(/MSIE (\d\.\d)/)[1];if(/ie7_off/.test(location.search)||appVersion<5||!/^ms_/.test(document.documentElement.uniqueID))return unHide();var quirksMode=Boolean(document.compatMode!="CSS1Compat");var isHTML=(typeof document.mimeType=="unknown")?!/\.xml$/i.test(location.pathname):Boolean(document.mimeType!="XML Document");var LINKS=":link{ie7-link:link}:visited{ie7-link:visited}";var HEADER=LINKS;if(!isHTML)HEADER+="*{margin:0}";var HTMLFixes;var documentElement=document.documentElement;var modules={};this.addModule=function(name,script,autoload){if(!modules)return;if(loaded)eval("script="+String(script));if(autoload){script();script=DUMMY}modules[name]=script};var RELATIVE=/^[\w\.]+[^:]*$/;function makePath(href,path){if(RELATIVE.test(href))href=(path||"")+href;return href};function getPath(href,path){href=makePath(href,path);return href.slice(0,href.lastIndexOf("/")+1)};var path=getPath(document.scripts[document.scripts.length-1].src);var httpRequest=new ActiveXObject("Microsoft.XMLHTTP");function load(href,path){try{href=makePath(href,path);httpRequest.open("GET",href,false);httpRequest.send();return httpRequest.responseText}catch(ignore){alert("Error [1]: could not load file "+href);return ""}};var push=function(array,item){return array.push(item)};var pop=function(array){return array.pop()};if(appVersion<5.5)eval(load("ie7-ie5.js",path));if(document.readyState=="complete"||!isHTML)document.createStyleSheet();else document.write("<style></style>");this.styleSheet=document.styleSheets[document.styleSheets.length-1];this.styleSheet.cssText=LINKS;this.styleSheet.ie7=true;var cssText={};function loadStyleSheet(styleSheet,path){var url=makePath(styleSheet.href,path);if(cssText[url])return "";cssText[url]=(styleSheet.disabled)?"":fixUrls(getCSSText(styleSheet,path),getPath(styleSheet.href,path));return cssText[url]};var getCSSText=function(styleSheet){return styleSheet.cssText};var URL=/(url\(['"]?)([\w\.]+[^:\)]*['"]?\))/gi;function fixUrls(cssText,pathname){return cssText.replace(URL,"$1"+pathname.slice(0,pathname.lastIndexOf("/")+1)+"$2")};this.recalcs=[];this.parse=DUMMY;var complete=false;function _load(){try{complete=true;var MEDIA=/\bscreen\b|\ball\b|^$/i;var styleSheets=document.styleSheets;var inlineStyles=[];var styles=document.getElementsByTagName("style");for(var i=styles.length-1;i>=0;i--){push(inlineStyles,/ie7-link/.test(styles[i].innerHTML)?"":styles[i].innerHTML)}function getCSSText(styleSheet,path){var cssText="";if(MEDIA.test(styleSheet.media)){for(var i=0;i<styleSheet.imports.length;i++){cssText+=arguments.callee(styleSheet.imports[i],getPath(styleSheet.href,path))}cssText+=((styleSheet.href)?loadStyleSheet(styleSheet,path):pop(inlineStyles))}return cssText};IE7.cssText="";for(i=0;i<styleSheets.length;i++)IE7.cssText+=getCSSText(styleSheets[i],"");IE7.cssText=encode(IE7.cssText);for(i in modules)modules[i]();delete modules;if(HTMLFixes)HTMLFixes.apply();CSSFixes.apply();IE7.parse();IE7.styleSheet.cssText=HEADER+decode(IE7.cssText);for(i=0;i<styleSheets.length;i++){if(!styleSheets[i].disabled&&!styleSheets[i].ie7)styleSheets[i].cssText=""}IE7.recalc();alert("loaded successfully")}catch(error){alert("Error [2]: "+error.description)}finally{unHide()}};this.recalc=function(){CSSFixes.recalc();for(var i=0;i<this.recalcs.length;i++)this.recalcs[i]()};var CSSFixes=new function(){var fixes=[];this.addFix=function(){push(fixes,arguments)};var recalcs=[];this.addRecalc=function(pattern,fix){var reg=new RegExp("([^{}]*)\x5c{([^}]*[^\x5cw-])?"+pattern,"gi");var cssText=IE7.cssText;pattern=[];while(match=reg.exec(cssText)){push(pattern,match[1]);if(appVersion<5.5)cssText=cssText.slice(match.lastIndex)}if(pattern.length){pattern=pattern.toString();push(recalcs,arguments)}};this.apply=function(){for(var i=0;i<fixes.length;i++){IE7.cssText=IE7.cssText.replace(fixes[i][0],fixes[i][1])}this.addRecalc("box-sizing\x5cs*:\x5cs*content-box",boxSizing);this.addRecalc("position\x5cs*:\x5cs*absolute",function(element){if(element.offsetParent.currentStyle.position=="relative")boxSizing(element.offsetParent)})};this.recalc=function(){for(var i=0;i<recalcs.length;i++){var elements=cssQuery(recalcs[i][0]);for(var j=0;j<elements.length;j++)recalcs[i][1](elements[j])}};this.addFix(/(float\s*:\s*(left|right))/gi,"display:inline;$1");if(appVersion<6)this.addFix(/display\s*:\s*list-item/gi,"display:block");if(quirksMode){var SIZES="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");for(var i=0;i<SIZES.length;i++)SIZES[SIZES[i]]=SIZES[i-1]||"xx-small";function replace($,$1,$2,$3){return $1+SIZES[$3]};this.addFix(new RegExp("(font(-size)?\x5cs*:\x5cs*)("+SIZES.join("|")+")","gi"),replace)}};var STANDARD_SELECT=/^[^>\+~\s]/;var STREAM=/[\s>\+~:@#\.\(\)]|[^\s>\+~:@#\.\(\)]+/g;var NAMESPACE=/\|/;var IMPLIED_SELECTOR=/([\s>~\,]|[^(]\+|^)([\.:#@])/g;var ASTERISK="$1*$2";var cssCache={};function cssQuery(selector,from){var useCache=!from;var base=(from)?(from.constructor==Array)?from:[from]:[document];var selectors=selector.replace(IMPLIED_SELECTOR,ASTERISK).split(",");var match=[];for(var i=0;i<selectors.length;i++){selector=toStream(selectors[i]);if(selector.slice(0,3).join("")==" *#"){selector=selector.slice(2);from=selectById(base,selector[1])}else from=base;var j=0,token,filter,filterArgs,cacheSelector="";while(j<selector.length){token=selector[j++];filter=selector[j++];cacheSelector+=token+filter;filterArgs="";if(selector[j]=="("){while(selector[j++]!=")")filterArgs+=selector[j];filterArgs=filterArgs.slice(0,-1);cacheSelector+="("+filterArgs+")"}from=(useCache&&cssCache[cacheSelector])?cssCache[cacheSelector]:select(from,token,filter,filterArgs);if(useCache)cssCache[cacheSelector]=from}match=match.concat(from)}return match};function toStream(selector){if(STANDARD_SELECT.test(selector))selector=" "+selector;return selector.match(STREAM)};function select(from,token,filter,filterArgs){var scopeName="";if(NAMESPACE.test(filter)){filter=filter.split("|");scopeName=filter[0];filter=filter[1]}var filtered=[];if(selectors[token])selectors[token](filtered,from,filter,scopeName||filterArgs);return filtered};function selectById(from,id){var filtered=[],i,j;for(i=0;i<from.length;i++){var match=from[i].all.item(id);if(match){if(match.length==null)push(filtered,match);else for(j=0;j<match.length;j++)push(filtered,match[j])}}return filtered};var selectors={" ":function(filtered,from,filter,scopeName){for(var i=0;i<from.length;i++){var subset=(filter=="*"&&from[i].all)?from[i].all:from[i].getElementsByTagName(filter);for(var j=0;j<subset.length;j++){if(isElement(subset[j])&&(!scopeName||subset[j].scopeName==scopeName))push(filtered,subset[j])}}},"#":function(filtered,from,filter){for(var i=0;i<from.length;i++)if(from[i].id==filter)push(filtered,from[i])},".":function(filtered,from,filter){filter=new RegExp("(^|\x5cs)"+filter+"(\x5cs|$)");for(var i=0;i<from.length;i++)if(filter.test(from[i].className))push(filtered,from[i])},":":function(filtered,from,filter,filterArgs){filter=pseudoClasses[filter];if(filter)for(var i=0;i<from.length;i++)if(filter(from[i],filterArgs))push(filtered,from[i])}};var attributeTests="";var pseudoClasses={toString:function(){var toString=[];for(var pseudoClass in this){if(pseudoClass!="link"&&pseudoClass!="visited"){if(this[pseudoClass].length>1)pseudoClass+="\x5c([^)]*\x5c)";push(toString,pseudoClass)}}return toString.join("|")},"link":function(element){return Boolean(element.currentStyle["ie7-link"]=="link")},"visited":function(element){return Boolean(element.currentStyle["ie7-link"]=="visited")}};var dynamicPseudoClasses={toString:pseudoClasses.toString};function compareTagName(element,tagName,scopeName){if(scopeName&&element.scopeName!=scopeName)return false;return(tagName=="*")?isElement(element):(isHTML)?(element.tagName==tagName.toUpperCase()):(element.tagName==tagName)};var strings=[];function getString(string){return QUOTED.test(string)?strings[string.slice(1,-1)]:string};var encode=function(cssText){return cssText.replace(/(\x2f\*[^\*]*\*+([^\x2f][^\*]*\*+)*\x2f)|('[^']*')|("[^"]*")/g,function(match){return(match.charAt(0)=="/")?"":"'"+(push(strings,match.slice(1,-1))-1)+"'"}).replace(/@(namespace|import)[^;\n]+[;\n]|<!\-\-|\-\->/g,"").replace(/\x5c:/g,"|").replace(/^\s+|\s*([\{\}\+\,>~\s;])\s*|\s+$/g,"$1")};function decode(cssText){return cssText.replace(/\|/g,"\x5c:").replace(/'(\d+)'/g,function(match,key){return strings[key]})};var handlers=[];function addEventHandler(element,type,handler){element.attachEvent(type,handler);push(handlers,arguments)};function removeEventHandler(element,type,handler){try{element.detachEvent(type,handler)}catch(ignore){}};window.attachEvent("onbeforeunload",function(){while(handlers.length){var handler=pop(handlers);removeEventHandler(handler[0],handler[1],handler[2])}});var hasLayout=(appVersion<6)?function(element){return element.clientWidth}:function(element){return element.currentStyle.hasLayout};function boxSizing(element){if(!hasLayout(element)){element.contentEditable=false;fixMargins(firstChildElement(element))}};function fixMargins(element){while(element){element.runtimeStyle.marginTop=element.currentStyle.marginTop;element=nextElement(element)}};var QUOTED=/('[^']*')|("[^"]*")/;function quote(value){return(QUOTED.test(value))?value:"'"+value+"'"};function unquote(value){return(QUOTED.test(value))?value.slice(1,-1):value};function tmpElement(tagName){var element=document.createElement(tagName||"object");element.style.cssText="position:absolute;padding:0;display:block;border:none;clip:rect(0 0 0 0);left:-9999";return element};function isElement(node){return Boolean(node&&node.nodeType==1&&node.tagName!="!"&&!node.ie7_anon)};function previousElement(element){while(element&&(element=element.previousSibling)&&!isElement(element))continue;return element};function nextElement(element){while(element&&(element=element.nextSibling)&&!isElement(element))continue;return element};function firstChildElement(element){element=element.firstChild;return(isElement(element))?element:nextElement(element)};var loaded=true;if(document.readyState=="complete")_load();else addEventHandler(document,"onreadystatechange",function(){if(!complete&&document.readyState=="complete")setTimeout(_load,0)})}catch(error){unHide();alert("Error [0]: "+error.description)}finally{}}();
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css-strict.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css-strict.js
new file mode 100644
index 0000000..4406d7a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css-strict.js
@@ -0,0 +1,2 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+if(window.IE7)IE7.addModule("ie7-strict",function(){if(!modules["ie7-css2"])return;var NONE=[],ID=/#/g,CLASS=/[:@\.]/g,TAG=/^\w|[\s>+~]\w/g;IE7.parser.parse=function(cssText){var DYNAMIC=new RegExp("(.*):("+dynamicPseudoClasses+")(.*)");function addRule(selector,cssText){var match=selector.match(DYNAMIC);if(match)new DynamicRule(selector,match[1],match[2],match[3],cssText);else new Rule(selector,cssText)};cssText=cssText.replace(IE7.PseudoElement.ALL,IE7.PseudoElement.ID);var RULE=/([^\{]+)\{(\d+)\}/g,match;while(match=RULE.exec(cssText)){addRule(match[1],match[2]);if(appVersion<5.5)cssText=cssText.slice(match.lastIndex)}IE7.classes.sort(Rule.compare);return IE7.classes.join("\n")};function Rule(selector,cssText){this.cssText=cssText;this.specificity=Rule.score(selector);this.inherit=IE7.Class;this.inherit(selector)};Rule.prototype=new IE7.Class.ancestor;Rule.prototype.toString=function(){return "."+this.name+"{"+this.cssText+"}"};Rule.score=function(selector){return(selector.match(ID)||NONE).length*10000+(selector.match(CLASS)||NONE).length*100+(selector.match(TAG)||NONE).length};Rule.compare=function(rule1,rule2){return rule1.specificity-rule2.specificity};function DynamicRule(selector,attach,dynamicPseudoClass,target,cssText){this.cssText=cssText;this.specificity=Rule.score(selector);this.inherit=IE7.DynamicStyle;this.inherit(selector,attach,dynamicPseudoClass,target)};DynamicRule.prototype=new IE7.DynamicStyle.ancestor;DynamicRule.prototype.toString=Rule.prototype.toString});
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css2.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css2.js
new file mode 100644
index 0000000..7121c8e
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css2.js
@@ -0,0 +1,2 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+if(window.IE7)IE7.addModule("ie7-css2",function(){var CHILD=/>/g,ANCHOR=/(\ba(\.[\w-]+)?)$/i;IE7.classes=[];IE7.parser=new Parser;IE7.Class=Class;IE7.DynamicStyle=DynamicStyle;IE7.PseudoElement=PseudoElement;IE7.parse=function(){with(this.parser)this.cssText=decode(parse(encode(this.cssText)));for(var i=0;i<IE7.classes.length;i++)IE7.classes[i].exec();for(i=0;i<pseudoElements.length;i++)pseudoElements[i].create()};getCSSText=function(styleSheet,path){return load(styleSheet.href,path)};var encoded=[];function Parser(){this.parse=function(cssText){Class.ALL=new RegExp("[^},\x5cs]*([>+~][^:@,\x5cs{]+|:("+pseudoClasses+")|\x5c.[\x5cw-]+\x5c.[\x5cw-.]+|@[@\x5cd]+)","g");Class.COMPLEX=new RegExp("[^\x5cs(]+[+~]|@\x5cd+|:(link|visited|"+pseudoClasses+"|"+dynamicPseudoClasses+")|\x5c.[\x5cw-.]+","g");DynamicStyle.ALL=new RegExp("([^}]*):("+dynamicPseudoClasses+")([^{]*)","g");return cssText.replace(PseudoElement.ALL,PseudoElement.ID).replace(DynamicStyle.ALL,DynamicStyle.ID).replace(Class.ALL,Class.ID)};this.encode=function(cssText){AttributeSelector.ALL=new RegExp("\x5c[([^"+attributeTests+"=\x5c]]+)(["+attributeTests+"]?=?)([^\x5c]]+)?\x5c]","g");return cssText.replace(AttributeSelector.ALL,AttributeSelector.ID).replace(/\{[^\}]*\}/g,function($){return "{"+(push(encoded,$)-1)+"}"}).replace(/::/g,":").replace(/([^\}\s]*\,[^\{]*)(\{\d+\})/g,function(match,left,right){return left.split(",").join(right)+right})};this.decode=function(cssText){return cssText.replace(/\{(\d+)\}/g,function($,$1){return encoded[$1]})}};function _Class(){this.toString=function(){return "."+this.name};this.add=function(element){element.className+=" "+this.name};this.remove=function(element){element.className=element.className.replace(this.MATCH,"")};this.exec=function(){var match=cssQuery(this.selector);for(var i=0;i<match.length;i++)this.add(match[i])}};function Class(selector,cssText){this.id=IE7.classes.length;this.name=Class.PREFIX+this.id;this.selector=selector;this.MATCH=new RegExp("\x5cs"+this.name+"\x5cb","g");push(IE7.classes,this)};Class.ancestor=_Class;Class.prototype=new _Class;Class.PREFIX="ie7_";Class.ID=function(match){return simpleSelector(match)+new Class(match)};function _DynamicStyle(){this.exec=function(){var match=cssQuery(this.attach);for(var i=0;i<match.length;i++){var target=(this.target)?cssQuery(this.target,match[i]):[match[i]];if(target)this.dynamicPseudoClass(match[i],target,this)}}};_DynamicStyle.prototype=new _Class;function DynamicStyle(selector,attach,dynamicPseudoClass,target){this.attach=attach;this.dynamicPseudoClass=dynamicPseudoClasses[dynamicPseudoClass];this.target=target;this.inherit=Class;this.inherit(selector)};DynamicStyle.ancestor=_DynamicStyle;DynamicStyle.prototype=new _DynamicStyle;DynamicStyle.ID=function(match,attach,dynamicPseudoClass,target){if(isHTML&&dynamicPseudoClass!="focus"&&ANCHOR.test(attach)&&!/[+>~]/.test(target))return match;return simpleSelector(match)+new DynamicStyle(match,attach,dynamicPseudoClass,target)};HEADER+=".ie7_anon{vertical-align:top;display:inline}";var HEX=/\x5c([a-fA-F\d]+)/g;function unicode(match,code){return eval("'\x5cu"+"0000".slice(code.length)+code+"'")};var pseudoElements=[];function _PseudoElement(){this.content=null;this.toString=function(){return ""};this.specificity=0;function addTimer(object,content,cssText){var timer=setInterval(function(){try{if(!object.load)return;object.load(object,content,cssText);clearInterval(timer)}catch(ignore){clearInterval(timer)}},10)};this.create=function(){if(this.content==null)return;for(var i=0;i<this.match.length;i++){var target=this.match[i];var pseudoElement=target.runtimeStyle[this.position];if(pseudoElement){var parentElement=target.canHaveChildren?target:target.parentElement;var isURL=/^url\(.*\)$/.test(this.content);var element=document.createElement(isURL?PseudoElement.OBJECT:"!");element.ie7_anon=true;element.runtimeStyle.cssText=pseudoElement.cssText;if(!isURL)element.innerText=pseudoElement.content;if(this.position=="before"){parentElement.insertBefore(element,parentElement.firstChild)}else{parentElement.appendChild(element)}if(isURL)addTimer(element,pseudoElement.content,pseudoElement.cssText);target.runtimeStyle[this.position]=null}}};this.exec=function(){this.match=cssQuery(this.selector);for(var i=0;i<this.match.length;i++){var runtimeStyle=this.match[i].runtimeStyle;if(!runtimeStyle[this.position])runtimeStyle[this.position]={cssText:""};runtimeStyle[this.position].cssText+=";"+this.cssText;if(this.content!=null)runtimeStyle[this.position].content=this.content}}};_PseudoElement.prototype=new _Class;function PseudoElement(selector,position,cssText){this.position=position;this.cssText=encoded[cssText].slice(1,-1);var content=this.cssText.match(PseudoElement.CONTENT);if(content)this.content=getString(content[1]).replace(HEX,unicode);this.inherit=Class;this.inherit(selector);push(pseudoElements,this)};PseudoElement.ancestor=_PseudoElement;PseudoElement.prototype=new _PseudoElement;PseudoElement.ID=function(match,selector,position,cssText){return new PseudoElement(selector,position,cssText)};PseudoElement.ALL=/([^}]*):(before|after)[^{]*\{([^}]*)\}/g;PseudoElement.CONTENT=/content\s*:\s*([^;]*)(;|$)/;PseudoElement.OBJECT="<object class=ie7_anon data='"+makePath("ie7-content.htm",path)+"' width=100% height=0 type=text/x-scriptlet>";selectors[">"]=function(filtered,from,filter,scopeName){for(var i=0;i<from.length;i++){var subset=from[i].children;for(var j=0;j<subset.length;j++)if(compareTagName(subset[j],filter,scopeName))push(filtered,subset[j])}};selectors["+"]=function(filtered,from,filter,scopeName){for(var i=0;i<from.length;i++){var adjacent=nextElement(from[i]);if(adjacent&&compareTagName(adjacent,filter,scopeName))push(filtered,adjacent)}};selectors["@"]=function(filtered,from,filter){filter=attributeSelectors[filter];for(var i=0;i<from.length;i++)if(filter(from[i]))push(filtered,from[i])};pseudoClasses["first-child"]=function(element){return!previousElement(element)};pseudoClasses["lang"]=function(element,filterArgs){filterArgs=new RegExp("^"+filterArgs,"i");while(element&&!element.getAttribute("lang"))element=element.parentNode;return element&&filterArgs.test(element.getAttribute("lang"))};dynamicPseudoClasses.hover=function(element){var instance=arguments;addEventHandler(element,"onmouseover",function(){IE7.Event.hover.register(instance)});addEventHandler(element,"onmouseout",function(){IE7.Event.hover.unregister(instance)})};dynamicPseudoClasses.active=function(element){var instance=arguments;addEventHandler(element,"onmousedown",function(){IE7.Event.active.register(instance)})};dynamicPseudoClasses.focus=function(element){var instance=arguments;addEventHandler(element,"onfocus",function(){IE7.Event.focus.register(instance)});addEventHandler(element,"onblur",function(){IE7.Event.focus.unregister(instance)});if(element==document.activeElement){IE7.Event.focus.register(instance)}};addEventHandler(document,"onmouseup",function(){var ie7Event=IE7.Event.active;var instances=ie7Event.instances,i;for(i in instances)ie7Event.unregister(instances[i]);ie7Event=IE7.Event.hover;instances=ie7Event.instances;for(i in instances)if(!instances[i][0].contains(event.srcElement))ie7Event.unregister(instances[i])});var attributeSelectors=[];var ESCAPE=/([/()[\]?{}|*+])/g;function AttributeSelector(attribute,compare,value){value=getString(value);this.id=attributeSelectors.length;switch(attribute.toLowerCase()){case "id":attribute="element.id.replace(/ms_\x5cd+/g,'')";break;case "class":attribute="element.className.replace(/\x5cb\x5cs*ie7_\x5cd+/g,'')";break;default:attribute="element.getAttribute('"+attribute+"')"}compare=attributeTests[compare];push(attributeSelectors,new Function("element","return "+compare(attribute,value)))};AttributeSelector.ID=function(match,attribute,compare,value){return new AttributeSelector(attribute,compare,value)};AttributeSelector.prototype.toString=function(){return AttributeSelector.PREFIX+this.id};attributeTests={toString:function(){var toString=[];for(var i in this)if(i&&i!="escape")push(toString,i);return toString.join("").replace(/=/g,"")},escape:function(value){return value.replace(ESCAPE,"\x5c$1")},"":function(attribute){return attribute},"=":function(attribute,value){return attribute+"=="+quote(value)},"~=":function(attribute,value){return "/(^|\x5cs)"+attributeTests.escape(value)+"(\x5cs|$)/.test("+attribute+")"},"|=":function(attribute,value){return "/^"+attributeTests.escape(value)+"(-|$)/.test("+attribute+")"}};AttributeSelector.PREFIX="@";function _ie7Event(){this.register=function(instance){var element=instance[0];var target=instance[1];var Class=instance[2];for(var i=0;i<target.length;i++)Class.add(target[i]);this.instances[Class.id+element.uniqueID]=instance};this.unregister=function(instance){var element=instance[0];var target=instance[1];var Class=instance[2];for(var i=0;i<target.length;i++)Class.remove(target[i]);delete this.instances[Class.id+element.uniqueID]}};IE7.Event=function(type){this.type=type;this.instances={};IE7.Event[type]=this};IE7.Event.prototype=new _ie7Event;new IE7.Event("hover");new IE7.Event("active");new IE7.Event("focus");function simpleSelector(selector){return selector.replace(Class.COMPLEX,"").replace(CHILD," ")}},true);
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css3.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css3.js
new file mode 100644
index 0000000..86b24f5
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-css3.js
@@ -0,0 +1,2 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+if(window.IE7)IE7.addModule("ie7-css3",function(){if(!modules["ie7-css2"])return;selectors["~"]=function(filtered,from,filter,scopeName){for(var i=0;i<from.length;i++){var adjacent=from[i];while(adjacent=nextElement(adjacent)){if(adjacent&&compareTagName(adjacent,filter,scopeName))push(filtered,adjacent)}}};var documentElement=(isHTML)?document.documentElement:firstChildElement(document.body);pseudoClasses["root"]=function(element){return Boolean(element==documentElement||element==document.body)};pseudoClasses["empty"]=function(element){return!firstChildElement(element)&&!element.innerText};pseudoClasses["last-child"]=function(element){return!nextElement(element)};pseudoClasses["only-child"]=function(element){return(element.parentNode&&childElements(element.parentNode).length==1)};pseudoClasses["nth-child"]=function(element,filterArgs,step){return nthChild(element,filterArgs,previousElement)};pseudoClasses["nth-last-child"]=function(element,filterArgs){return nthChild(element,filterArgs,nextElement)};function nthChild(element,filterArgs,traverse){switch(filterArgs){case "n":return true;case "even":filterArgs="2n";break;case "odd":filterArgs="2n+1"}var children=childElements(element.parentNode);function checkIndex(index){index=(traverse==nextElement)?children.length-index:index-1;return children[index]==element};if(!isNaN(filterArgs))return checkIndex(filterArgs);filterArgs=filterArgs.split("n");var multiplier=parseInt(filterArgs[0]);var step=parseInt(filterArgs[1]);if(isNaN(multiplier)||(multiplier==1))return true;if(multiplier==0&&!isNaN(step))return checkIndex(step);if(isNaN(step))step=0;var count=1;while(element=traverse(element))count++;return((count%multiplier)==step)};function childElements(element){var childElements=[],i;for(i=0;i<element.childNodes.length;i++){if(isElement(element.childNodes[i]))push(childElements,element.childNodes[i])}return childElements};attributeTests["^="]=function(attribute,value){return "/^"+attributeTests.escape(value)+"/.test("+attribute+")"};attributeTests["$="]=function(attribute,value){return "/"+attributeTests.escape(value)+"$/.test("+attribute+")"};attributeTests["*="]=function(attribute,value){return "/"+attributeTests.escape(value)+"/.test("+attribute+")"}});
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-fixed.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-fixed.js
new file mode 100644
index 0000000..4321cda
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-fixed.js
@@ -0,0 +1,2 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+if(window.IE7)IE7.addModule("ie7-fixed",function(){var PERCENT=/^\d+%$/;CSSFixes.addRecalc("position\x5cs*:\x5cs*fixed",positionFixed);CSSFixes.addRecalc("background[\x5cw\x5cs-]*:[^};]*fixed",backgroundFixed);var body=document.body;var viewport$=(quirksMode)?"body":"documentElement";var viewport=eval(viewport$);function fixBackground(){if(body.currentStyle.backgroundAttachment!="fixed"){if(body.currentStyle.backgroundImage=="none"){body.runtimeStyle.backgroundImage="url("+location.protocol+")"}body.runtimeStyle.backgroundAttachment="fixed"}fixBackground=DUMMY};var ie7_tmp=tmpElement("img");function topFunction(leftFunction){return String(leftFunction).replace(/Left/g,"Top").replace(/left/g,"top").replace(/Width/g,"Height").replace(/X/g,"Y")};function backgroundFixed(element){if(element.currentStyle.backgroundAttachment!="fixed")return;if(!element.contains(body)){fixBackground();backgroundFixed[backgroundFixed.count++]=element;backgroundLeft(element);backgroundTop(element);backgroundPosition(element)}};backgroundFixed.count=0;function backgroundPosition(element){ie7_tmp.src=element.currentStyle.backgroundImage.slice(5,-2);var parentElement=(element.canHaveChildren)?element:element.parentElement;parentElement.appendChild(ie7_tmp);setOffsetLeft(element);setOffsetTop(element);parentElement.removeChild(ie7_tmp)};function backgroundLeft(element){element.style.backgroundPositionX=element.currentStyle.backgroundPositionX;if(!isFixed(element)){var expression="(parseInt(runtimeStyle.offsetLeft)+document."+viewport$+".scrollLeft)||0";element.runtimeStyle.setExpression("backgroundPositionX",expression)}};eval(topFunction(backgroundLeft));function setOffsetLeft(element){var propertyName=isFixed(element)?"backgroundPositionX":"offsetLeft";element.runtimeStyle[propertyName]=getOffsetLeft(element,element.style.backgroundPositionX)-element.getBoundingClientRect().left-element.clientLeft};eval(topFunction(setOffsetLeft));function isFixed(element){if(!element)return false;if(element.style.position=="fixed"||element.currentStyle.position=="fixed")return true;return arguments.callee(element.parentElement)};function getOffsetLeft(element,position){switch(position){case "left":case "top":return 0;case "right":case "bottom":return viewport.clientWidth-ie7_tmp.offsetWidth;case "center":return(viewport.clientWidth-ie7_tmp.offsetWidth)/2;default:if(PERCENT.test(position)){return parseInt((viewport.clientWidth-ie7_tmp.offsetWidth)*parseFloat(position)/100)}ie7_tmp.style.left=position;return ie7_tmp.offsetLeft}};eval(topFunction(getOffsetLeft));function positionFixed(element){if(element.currentStyle.position!="fixed")return;fixBackground();positionFixed[positionFixed.count++]=element;element.style.position="fixed";element.runtimeStyle.position="absolute";foregroundPosition(element)};positionFixed.count=0;function foregroundPosition(element,recalc){positionLeft(element,recalc);positionTop(element,recalc);if(!recalc||element.runtimeStyle.autoTop){if(parseInt(element.currentStyle.bottom)==0)element.runtimeStyle.screenTop++}};function positionLeft(element,recalc){if(!recalc&&PERCENT.test(element.currentStyle.width))element.runtimeStyle.fixWidth=element.currentStyle.width;if(element.runtimeStyle.fixWidth)element.runtimeStyle.width=parseInt(parseFloat(element.runtimeStyle.fixWidth)/100*viewport.clientWidth);if(recalc){if(!element.runtimeStyle.autoLeft)return}else{element.runtimeStyle.autoLeft=element.currentStyle.right!="auto"&&element.currentStyle.left=="auto"}element.runtimeStyle.left="";element.runtimeStyle.screenLeft=getScreenLeft(element);if(element.currentStyle.marginLeft!="auto"){element.parentElement.appendChild(ie7_tmp);ie7_tmp.style.left=element.currentStyle.marginLeft;element.runtimeStyle.screenLeft-=ie7_tmp.offsetLeft;element.parentElement.removeChild(ie7_tmp)}if(isFixed(element.offsetParent))element.runtimeStyle.pixelLeft=element.runtimeStyle.screenLeft;else if(!recalc)element.runtimeStyle.setExpression("pixelLeft","runtimeStyle.screenLeft+document."+viewport$+".scrollLeft")};eval(topFunction(positionLeft).replace(/right/g,"bottom").replace(/width/g,"height"));function getScreenLeft(element){var getScreenLeft=element.offsetLeft,nested=false;var fixed=isFixed(element.offsetParent)&&element.runtimeStyle.autoLeft;while(element=element.offsetParent){if(!fixed&&element.currentStyle.position!="static")nested=true;getScreenLeft+=element.offsetLeft*(nested?-1:1)}return getScreenLeft};eval(topFunction(getScreenLeft));function resize(){for(var i=0;i<backgroundFixed.count;i++)backgroundPosition(backgroundFixed[i]);for(i=0;i<positionFixed.count;i++)foregroundPosition(positionFixed[i],true);timer=0};var timer;addEventHandler(window,"onresize",function(){if(!timer)timer=setTimeout(resize,10)})});
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-html4.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-html4.js
new file mode 100644
index 0000000..4d2baa9
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-html4.js
@@ -0,0 +1,2 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+if(window.IE7)IE7.addModule("ie7-html4",function(){if(isHTML)HTMLFixes=new function(){var fixes=[];function fix(element){var fixedElement=document.createElement("<HTML:"+element.outerHTML.slice(1));if(element.outerHTML.slice(-2)!="/>"){var endTag="</"+element.tagName+">",nextSibling;while((nextSibling=element.nextSibling)&&nextSibling.outerHTML!=endTag){element.parentNode.removeChild(nextSibling);fixedElement.appendChild(nextSibling)}if(nextSibling)element.parentNode.removeChild(nextSibling)}element.parentNode.replaceChild(fixedElement,element);return fixedElement};this.add=function(){push(fixes,arguments)};this.apply=function(){try{if(appVersion>5)document.namespaces.add("HTML","http://www.w3.org/1999/xhtml")}catch(ignore){}finally{for(var i=0;i<fixes.length;i++){var elements=cssQuery(fixes[i][0]);for(var j=0;j<elements.length;j++)fixes[i][1](elements[j])}}};this.add("label",function(element){if(!element.htmlFor){var input=cssQuery("input,select,textarea",element)[0];if(input){if(!input.id)input.id=input.uniqueID;element.htmlFor=input.id}}});this.add("abbr",function(element){fix(element);delete cssCache[" abbr"]});this.add("button,input",function(element){if(element.tagName=="BUTTON"){var match=element.outerHTML.match(/ value="([^"]*)"/i);element.runtimeStyle.value=(match)?match[1]:""}if(element.type=="submit"){addEventHandler(element,"onclick",function(){element.runtimeStyle.clicked=true;setTimeout("document.all."+element.uniqueID+".runtimeStyle.clicked=false",1)})}});this.add("form",function(element){var UNSUCCESSFUL=/^(submit|reset|button)$/;addEventHandler(element,"onsubmit",function(){for(var i=0;i<element.length;i++){if(UNSUCCESSFUL.test(element[i].type)&&!element[i].disabled&&!element[i].runtimeStyle.clicked){element[i].disabled=true;setTimeout("document.all."+element[i].uniqueID+".disabled=false",1)}else if(element[i].tagName=="BUTTON"&&element[i].type=="submit"){setTimeout("document.all."+element[i].uniqueID+".value='"+element[i].value+"'",1);element[i].value=element[i].runtimeStyle.value}}})})}},true); \ No newline at end of file
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-ie5.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-ie5.js
new file mode 100644
index 0000000..707fa56
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-ie5.js
@@ -0,0 +1,2 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+if(isHTML){HEADER+="address,blockquote,body,dd,div,dl,dt,fieldset,form,frame,"+"frameset,h1,h2,h3,h4,h5,h6,iframe,noframes,object,p,applet,center,"+"dir,hr,menu,pre{display:block;height:0cm}li,ol,ul{display:block}"}if(![].push)push=function(array,item){array[array.length]=item;return array.length};if(![].pop)pop=function(array){var item=array[array.length-1];array.length--;return item};if("i".replace(/i/,function(){return""})){var a=String.prototype.replace,b=function(r,w){var m,n="",s=this;while((m=r.exec(s))){n+=s.slice(0,m.index)+w(m[0],m[1],m[2],m[3],m[4]);s=s.slice(m.lastIndex)}return n+s};String.prototype.replace=function(r,w){this.replace=(typeof w=="function")?b:a;return this.replace(r,w)}} \ No newline at end of file
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-lite-p.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-lite-p.js
new file mode 100644
index 0000000..ee1a96a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-lite-p.js
@@ -0,0 +1,3 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+eval(function(A,r,s,e,n,a,l){s=function(e){return((e<a)?'':s(e/a))+n[l[340]](e%a+161)};while(++r<474)l[r]=(r<378)?'/'+l[r]+'/':'"'+l[r]+'"';while(--r>=0)A=A.replace(new RegExp(s(r),'g'),l[r]);return A}('if(!ù.´)Ó £(){ÿ{ù.´=ª;¢ ¢Æ=ª.¢´=Ó ¤×;£ ¢©(){if(«.¢Ù)«.¢Ù.Í.¤Ö=¤þ};ª.Õ=£(){¤ ¤ÿ};¢ â=(¤Ù.±(¢î.£Ë))?£(£Ì){ù.â(´+¥¡+£Ì)}:¢Æ;¢ Å=¤Ñ.Å.¬(¤Ú)[1];if(¤Û.±(¢î.£Ë)||Å<5||!¤Ü.±(«.Ù.ü))¤ ¢©();¢ è=¢£(«.¤Í!=¥¢);¢ ë=(¤Ë «.£Ê==¥£)?!¤Ýi.±(¢î.¢Ç):¢£(«.£Ê!=¥¤);¢ ¢í=¥¥;¢ ¢ë=¢í;if(!ë)¢ë+=¥¦;¢ ¢¹;¢ Ù=«.Ù;¢ ó={};ª.¢´=£(£È,ô,£É){if(!ó)¤;if(¢«)¢¬(¥§+¢Î(ô));if(£É){ô();ô=¢Æ}ó[£È]=ô};¢ £Ç=¤Þ;£ ¢È(²,¹){if(£Ç.±(²))²=(¹||¥¨)+²;¤ ²};£ ¢Ä(²,¹){²=¢È(²,¹);¤ ².»(0,².£Ã(¥©)+1)};¢ ¹=¢Ä(«.£Æ[«.£Æ.­-1].¤Å);¢ ¢Ê=Ó ¤Ä(¥ª);£ ã(²,¹){ÿ{²=¢È(²,¹);¢Ê.¤Á(¥«,²,Þ);¢Ê.¤¿();¤ ¢Ê.¤¾}õ(¢à){â(¥¬+²);¤ ¥¨}};¢ ·=£(¢É,¢À){¤ ¢É.·(¢À)};¢ ¢½=£(¢É){¤ ¢É.¢½()};if(Å<5.5)¢¬(ã(¥­,¹));if(«.¢Í==¥®||!ë)«.¤¹();Ö «.¤¸(¥¯);ª.¶=«.É[«.É.­-1];ª.¶.§=¢í;ª.¶.Æ=×;¢ §={};£ £¿(¶,¹){¢ ¢§=¢È(¶.²,¹);if(§[¢§])¤ ¥¨;§[¢§]=(¶.ý)?¥¨:£Å(¢Ã(¶,¹),¢Ä(¶.²,¹));¤ §[¢§]};¢ ¢Ã=£(¶){¤ ¶.§};¢ £Ä=¤ßgi;£ £Å(§,¢Ç){¤ §.³(£Ä,¥°+¢Ç.»(0,¢Ç.£Ã(¥©)+1)+¥±)};ª.Ë=[];ª.£¾=¢Æ;¢ ä=Þ;£ _ã(){ÿ{ä=×;¢ £Á=¤ài;¢ É=«.É;¢ ¢ì=[];¢ ¢Å=«.£µ(¥²);¯(¢ i=¢Å.­-1;i>=0;i--){·(¢ì,¤á.±(¢Å[i].£Â)?¥¨:¢Å[i].£Â)}£ ¢Ã(¶,¹){¢ §=¥¨;if(£Á.±(¶.¤µ)){¯(¢ i=0;i<¶.£À.­;i++){§+=¢¡.¤´(¶.£À[i],¢Ä(¶.²,¹))}§+=((¶.²)?£¿(¶,¹):¢½(¢ì))}¤ §};´.§=¥¨;¯(i=0;i<É.­;i++)´.§+=¢Ã(É[i],¥¨);´.§=£´(´.§);¯(i in ó)ó[i]();£¦ ó;if(¢¹)¢¹.¢·();Ñ.¢·();´.£¾();´.¶.§=¢ë+£³(´.§);¯(i=0;i<É.­;i++){if(!É[i].ý&&!É[i].Æ)É[i].§=¥¨}´.¢Â();â(¥³)}õ(¢¨){â(¥´+¢¨.¢ï)}¢Ë{¢©()}};ª.¢Â=£(){Ñ.¢Â();¯(¢ i=0;i<ª.Ë.­;i++)ª.Ë[i]()};¢ Ñ=Ó £(){¢ Ç=[];ª.û=£(){·(Ç,¢¡)};¢ Ë=[];ª.Ú=£(á,¢Þ){¢ £½=Ó ¢æ(¥µ+á,¥¶);¢ §=´.§;á=[];Ê(¬=£½.¤²(§)){·(á,¬[1]);if(Å<5.5)§=§.»(¬.¤±)}if(á.­){á=á.Õ();·(Ë,¢¡)}};ª.¢·=£(){¯(¢ i=0;i<Ç.­;i++){´.§=´.§.³(Ç[i][0],Ç[i][1])}ª.Ú(¥·,é);ª.Ú(¥¸,£(¡){if(¡.¢².©.Ü==¥¹)é(¡.¢²)})};ª.¢Â=£(){¯(¢ i=0;i<Ë.­;i++){¢ î=¢¶(Ë[i][0]);¯(¢ j=0;j<î.­;j++)Ë[i][1](î[j])}};ª.û(¤âgi,¥º);if(Å<6)ª.û(¤ãgi,¥»);if(è){¢ à=¥¼.¢ç(¥½);¯(¢ i=0;i<à.­;i++)à[à[i]]=à[i-1]||¥¾;£ ³($,$1,$2,$3){¤ $1+à[$3]};ª.û(Ó ¢æ(¥¿+à.¢å(¥À)+¥Á,¥¶),³)}};¢ £¹=¤ä;¢ £¸=¤åg;¢ £·=¤æ;¢ £¼=¤çg;¢ £»=¥Â;¢ þ={};£ ¢¶(µ,¦){¢ ¢è=!¦;¢ ¢é=(¦)?(¦.¤§==¤¦)?¦:[¦]:[«];¢ ñ=µ.³(£¼,£»).¢ç(¥½);¢ ¬=[];¯(¢ i=0;i<ñ.­;i++){µ=£º(ñ[i]);if(µ.»(0,3).¢å(¥¨)==¥Ã){µ=µ.»(2);¦=£¶(¢é,µ[1])}Ö ¦=¢é;¢ j=0,ß,®,Á,ò=¥¨;Ê(j<µ.­){ß=µ[j++];®=µ[j++];ò+=ß+®;Á=¥¨;if(µ[j]==¥Ä){Ê(µ[j++]!=¥Á)Á+=µ[j];Á=Á.»(0,-1);ò+=¥Ä+Á+¥Á}¦=(¢è&&þ[ò])?þ[ò]:¢ß(¦,ß,®,Á);if(¢è)þ[ò]=¦}¬=¬.¤¥(¦)}¤ ¬};£ £º(µ){if(£¹.±(µ))µ=¥Å+µ;¤ µ.¬(£¸)};£ ¢ß(¦,ß,®,Á){¢ À=¥¨;if(£·.±(®)){®=®.¢ç(¥À);À=®[0];®=®[1]}¢ ¸=[];if(ñ[ß])ñ[ß](¸,¦,®,À||Á);¤ ¸};£ £¶(¦,id){¢ ¸=[],i,j;¯(i=0;i<¦.­;i++){¢ ¬=¦[i].ì.¢À(id);if(¬){if(¬.­==¤¤)·(¸,¬);Ö ¯(j=0;j<¬.­;j++)·(¸,¬[j])}}¤ ¸};¢ ñ={¥Å:£(¸,¦,®,À){¯(¢ i=0;i<¦.­;i++){¢ ¢¦=(®==¥Æ&&¦[i].ì)?¦[i].ì:¦[i].£µ(®);¯(¢ j=0;j<¢¦.­;j++){if(ï(¢¦[j])&&(!À||¢¦[j].À==À))·(¸,¢¦[j])}}},¥Ç:£(¸,¦,®){¯(¢ i=0;i<¦.­;i++)if(¦[i].id==®)·(¸,¦[i])},¥È:£(¸,¦,®){®=Ó ¢æ(¥É+®+¥Ê);¯(¢ i=0;i<¦.­;i++)if(®.±(¦[i].¤£))·(¸,¦[i])},¥Ë:£(¸,¦,®,Á){®=¢ä[®];if(®)¯(¢ i=0;i<¦.­;i++)if(®(¦[i],Á))·(¸,¦[i])}};¢ ¤¢=¥¨;¢ ¢ä={Õ:£(){¢ Õ=[];¯(¢ ð in ª){if(ð!=¥Ì&&ð!=¥Í){if(ª[ð].­>1)ð+=¥Î;·(Õ,ð)}}¤ Õ.¢å(¥À)},¥Ì:£(¡){¤ ¢£(¡.©[¥Ï]==¥Ì)},¥Í:£(¡){¤ ¢£(¡.©[¥Ï]==¥Í)}};¢ ¤¡={Õ:¢ä.Õ};£ £ÿ(¡,º,À){if(À&&¡.À!=À)¤ Þ;¤(º==¥Æ)?ï(¡):(ë)?(¡.º==º.¢ý()):(¡.º==º)};¢ ¢¾=[];£ £þ(¢¿){¤ ¢».±(¢¿)?¢¾[¢¿.»(1,-1)]:¢¿};¢ £´=£(§){¤ §.³(¤èg,£(¬){¤(¬.¢þ(0)==¥©)?¥¨:¥Ð+(·(¢¾,¬.»(1,-1))-1)+¥Ð}).³(¤ég,¥¨).³(¤êg,¥À).³(¤ëg,¥°)};£ £³(§){¤ §.³(¤æg,¥Ñ).³(¤ìg,£(¬,£²){¤ ¢¾[£²]})};¢ ¢¼=[];£ ö(¡,Ý,Ô){¡.£±(Ý,Ô);·(¢¼,¢¡)};£ £°(¡,Ý,Ô){ÿ{¡.£û(Ý,Ô)}õ(¢à){}};ù.£±(¥Ò,£(){Ê(¢¼.­){¢ Ô=¢½(¢¼);£°(Ô[0],Ô[1],Ô[2])}});¢ ¢³=(Å<6)?£(¡){¤ ¡.Ä}:£(¡){¤ ¡.©.¢³};£ é(¡){if(!¢³(¡)){¡.£ù=Þ;£¯(£«(¡))}};£ £¯(¡){Ê(¡){¡.°.£®=¡.©.£®;¡=¢â(¡)}};¢ ¢»=¤í;£ £ø(¥){¤(¢».±(¥))?¥:¥Ð+¥+¥Ð};£ £÷(¥){¤(¢».±(¥))?¥.»(1,-1):¥};£ £¡(º){¢ ¡=«.£ª(º||¥Ó);¡.Í.§=¥Ô;¤ ¡};£ ï(¢¢){¤ ¢£(¢¢&&¢¢.£ñ==1&&¢¢.º!=¥Õ&&!¢¢.£ð)};£ £ï(¡){Ê(¡&&(¡=¡.£î)&&!ï(¡))£¬;¤ ¡};£ ¢â(¡){Ê(¡&&(¡=¡.Ì)&&!ï(¡))£¬;¤ ¡};£ £«(¡){¡=¡.£í;¤(ï(¡))?¡:¢â(¡)};¢ ¢«=Þ;´.¢´(¥Ö,£(){if(ë)¢¹=Ó £(){¢ Ç=[];£ ¢Þ(¡){¢ ¢¸=«.£ª(¥×+¡.¢µ.»(1));if(¡.¢µ.»(-2)!=¥Ø){¢ £©=¥Ù+¡.º+¥Ú,Ì;Ê((Ì=¡.Ì)&&Ì.¢µ!=£©){¡.¢á.¢Ú(Ì);¢¸.¢Ï(Ì)}if(Ì)¡.¢á.¢Ú(Ì)}¡.¢á.£ë(¢¸,¡);¤ ¢¸};ª.í=£(){·(Ç,¢¡)};ª.¢·=£(){ÿ{if(Å>5)«.£ê.í(¥Û,¥Ü)}õ(¢à){}¢Ë{¯(¢ i=0;i<Ç.­;i++){¢ î=¢¶(Ç[i][0]);¯(¢ j=0;j<î.­;j++)Ç[i][1](î[j])}}};ª.í(¥Ý,£(¡){if(!¡.£§){¢ Ò=¢¶(¥Þ,¡)[0];if(Ò){if(!Ò.id)Ò.id=Ò.ü;¡.£§=Ò.id}}});ª.í(¥ß,£(¡){¢Þ(¡);£¦ þ[¥à]});ª.í(¥á,£(¡){if(¡.º==¥â){¢ ¬=¡.¢µ.¬(¤îi);¡.°.¥=(¬)?¬[1]:¥¨}if(¡.Ý==¥ã){ö(¡,¥ä,£(){¡.°.¢Ý=×;¢ª(¥å+¡.ü+¥æ,1)})}});ª.í(¥ç,£(¡){¢ ££=¤ï;ö(¡,¥è,£(){¯(¢ i=0;i<¡.­;i++){if(££.±(¡[i].Ý)&&!¡[i].ý&&!¡[i].°.¢Ý){¡[i].ý=×;¢ª(¥å+¡[i].ü+¥é,1)}Ö if(¡[i].º==¥â&&¡[i].Ý==¥ã){¢ª(¥å+¡[i].ü+¥ê+¡[i].¥+¥Ð,1);¡[i].¥=¡[i].°.¥}}})})}},×);´.¢´(¥ë,£(){¢ ¢¯=¥ì,¢û=¤ð,¢ñ=¤ñ,¢Ð=¤ò;¢ ¢ÿ=(Å<6)?¤ógi:¤ôgi;¢ ¢ö=(Å<5.5)?¤õ:¤ö;¢ Ã=£¡();·(´.Ë,£ ¢ò(){if(Ã.Î)Ã.Î.¢Ú(Ã)});Ñ.û(¢ÿ,£(¬){¤ ¬.»(0,3)+¬.¢þ(4).¢ý()+¬.»(5)});¢ ¢ü=(è)?«.¢Ù:Ù;£ ¢Ó(¡){¤ ¡.Í.Ü==¥í||¡.©.Ü==¥í};£ ¾(¡){¢ ¾=¡.¢²;Ê(¾&&!¢³(¾))¾=¾.¢²;if(!¾||¢Ó(¡))¾=¢ü;¤ ¾};£ å(¢ó){å=£(¡,¥){if(!¡.°.¿&&(!ë||¡.º!=¥î)){if(!¥)¥=¡.©.¨;¡.°.¿=(¢û.±(¥))?£Þ.ú(0,ê(¡,¥)):¥;¡.°.¨=¡.°.¿;é(¡)}};if(è)Ñ.Ú(¥ï,å);¢ ê=(è)?£(¡,¥){¤ ç(¡,¥)+¢Õ(¡)+¢Ô(¡)}:£(¡,¥){¤ ç(¡,¥)};£ ¢Õ(¡){¤ ¡.¢Ñ-¡.Ä};£ ¢Ô(¡){¤ ç(¡,¡.©.£Ý)+ç(¡,¡.©.£Ü)};£ ¢ô(¡){¤((¡.©.¢ù==¥ð)?0:÷(¡,¡.©.¢ù))+((¡.©.¢ø==¥ð)?0:÷(¡,¡.©.¢ø))};£ ¼(¡){¼[¼.Ï++]=¡;if(¡.©.¢÷==¥ð)¡.°.¢÷=0;å(¡);é(¡);¢®(¡)};¼.Ï=0;Ñ.Ú(¥ñ+¢¯,¼);¢¬(¢Î(¼).³(¤÷g,¥ò));Ð.Ï=0;Ñ.Ú(¥ó+¢¯,Ð);£ ¢®(¡){¢ ¢°=¡.¢õ();¢ ¨=¢°.æ-¢°.Â;if(¡.©.Ð&&¨>=ê(¡,¡.©.Ð))¡.°.¨=ê(¡,¡.©.Ð);Ö if(¡.©.¼&&¨<=ê(¡,¡.©.¼))¡.°.¨=ê(¡,¡.©.¼);Ö ¡.°.¨=¡.°.¿};£ Ø(¡){if((¡.©.Ü==¥ô||¡.©.Ü==¥í)&&¡.©.Â!=¥ð&&¡.©.æ!=¥ð&&¢ö.±(¡.©.¨)){Ø[Ø.Ï++]=¡;é(¡);¢Ò(¡)}};Ø.Ï=0;Ñ.Ú(¥õ+¢¯,Ø);£ ¢Ò(¡){¡.°.¨=¥¨;¢ Î=¾(¡);¢ Â=(¡.°.£Û)?¡.¢õ().Â-2:÷(¡,¡.©.Â);¢ ¨=Î.Ä-÷(¡,¡.©.æ)-Â-¢ô(¡);if(!è)¨-=¢Õ(¡)+¢Ô(¡);if(¨<0)¨=0;if(¢Ó(¡)||¢ó||¡.¢Ñ<¨){¡.°.¿=¨;¡.°.¨=¨}};¢ Ä=Ù.Ä;ö(ù,¥ö,£(){¢ i,ø=(Ä<Ù.Ä);Ä=Ù.Ä;¯(i=0;i<¼.Ï;i++){¢ ¡=¼[i];¢ ¿=(¡.°.¨==¡.©.¼);if(ø&&¿)¡.°.¨=¥¨;if(ø==¿)¢®(¡)}¯(i=0;i<Ð.Ï;i++){¢ ¡=Ð[i];¢ ¿=(¡.°.¨==¡.©.Ð);if(!ø&&¿)¡.°.¨=¥¨;if(ø!=¿)¢®(¡)}¯(i=0;i<Ø.Ï;i++)¢Ò(Ø[i]);¢ò()});£ ç(¡,¥){if(¢Ð.±(¥))¤ ¢­(¥);if(¢ñ.±(¥))¤ ¢­(£Ù(¥)/100*¾(¡).Ä);¢ Î=(¡.£Ø)?¡:¡.Î;Î.¢Ï(Ã);Ã.Í.¨=¥;¤ Ã.¢Ñ};£ ÷(¡,¥){if(¢­(¥)>0)¤ ç(¡,¥);if(¢Ð.±(¥))¤ ¢­(¥);¡.Î.¢Ï(Ã);Ã.Í.Â=¥;¤ Ã.£×}};¢¬(¢Î(å).³(¤øg,¥÷).³(¤ùg,¥ø).³(¤úg,¥ù).³(¤ûg,¥ú).³(¤üg,¥û).³(¤ýg,¥ü));å();£Î(×)});¢«=×;if(«.¢Í==¥®)_ã();Ö ö(«,¥ý,£(){if(!ä&&«.¢Í==¥®)¢ª(_ã,0)})}õ(¢¨){¢©();â(¥þ+¢¨.¢ï)}¢Ë{}}();',340,0,/./,String,95,'element`var`function`return`value`from`cssText`width`currentStyle`this`document`match`length`filter`for`runtimeStyle`test`href`replace`IE7`selector`styleSheet`push`filtered`path`tagName`slice`minWidth`x5cs`layoutParent`fixedWidth`scopeName`filterArgs`left`ie7_tmp`clientWidth`appVersion`ie7`fixes`link`styleSheets`while`recalcs`nextSibling`style`parentElement`count`maxWidth`CSSFixes`input`new`handler`toString`else`true`fixRight`documentElement`addRecalc`auto`position`type`false`token`SIZES`pattern`alert`load`complete`fixWidth`right`getPixelWidth`quirksMode`boxSizing`getFixedWidth`isHTML`all`add`elements`isElement`pseudoClass`selectors`cacheSelector`modules`script`catch`addEventHandler`getPixelLeft`wider`window`max`addFix`uniqueID`disabled`cssCache`try`arguments`node`Boolean`x5c`visited`subset`url`error`unHide`setTimeout`loaded`eval`parseInt`resizeWidth`NUMERIC`rect`min`offsetParent`hasLayout`addModule`outerHTML`cssQuery`apply`fixedElement`HTMLFixes`display`QUOTED`handlers`pop`strings`string`item`small`recalc`getCSSText`getPath`styles`DUMMY`pathname`makePath`array`httpRequest`finally`Error`readyState`String`appendChild`PIXEL`offsetWidth`resizeRight`isFixed`getPaddingWidth`getBorderWidth`fixed`absolute`x5cw`body`removeChild`box`submit`clicked`fix`select`ignore`parentNode`nextElement`x2f`pseudoClasses`join`RegExp`split`useCache`base`large`HEADER`inlineStyles`LINKS`location`description`height`PERCENT`removeTempElement`HEIGHT`getMarginWidth`getBoundingClientRect`AUTO`minHeight`marginRight`marginLeft`x5cd`UNIT`viewport`toUpperCase`charAt`MATCH`tmpElement`BUTTON`UNSUCCESSFUL`button`abbr`delete`htmlFor`HTML`endTag`createElement`firstChildElement`continue`block`marginTop`fixMargins`removeEventHandler`attachEvent`key`decode`encode`getElementsByTagName`selectById`NAMESPACE`STREAM`STANDARD_SELECT`toStream`ASTERISK`IMPLIED_SELECTOR`reg`parse`loadStyleSheet`imports`MEDIA`innerHTML`lastIndexOf`URL`fixUrls`scripts`RELATIVE`name`autoload`mimeType`search`message`onreadystatechange`fixHeight`bottom`Bottom`Right`top`Top`Left`Height`Width`offsetLeft`canHaveChildren`parseFloat`onresize`screenLeft`paddingRight`paddingLeft`Math`model`onsubmit`reset`form`onclick`textarea`label`xhtml`org`www`http`namespaces`replaceChild`html4`firstChild`previousSibling`previousElement`ie7_anon`nodeType`clip`none`border`padding`object`unquote`quote`contentEditable`onbeforeunload`detachEvent`import`namespace`getString`compareTagName`dynamicPseudoClasses`attributeTests`className`null`concat`Array`constructor`size`font`medium`list`inline`float`relative`content`sizing`lastIndex`exec`successfully`callee`media`ball`bscreen`write`createStyleSheet`ie5`file`not`could`responseText`send`GET`open`XMLHTTP`Microsoft`ActiveXObject`src`margin`Document`XML`xml`unknown`typeof`CSS1Compat`compatMode`ms_`ie7_off`MSIE`navigator`ie7_debug`alpha`version`visible`visibility`Function`fromCharCode`¤Ò`¤Ð (\\d\\.\\d)`¤Ï`^¤Î`\\.¤É$`^[\\w\\.]+[^:]*$`(¢§\\([\x27"]?)([\\w\\.]+[^:\\)]*[\x27"]?\\))`\\¤·\\b|\\¤¶\\b|^$`Æ-È`(¤­\\s*:\\s*(Â|æ))`¢º\\s*:\\s*¤«-¢À`^[^>\\+~\\s]`[\\s>\\+~:@#\\.\\(\\)]|[^\\s>\\+~:@#\\.\\(\\)]+`\\|`([\\s>~\\,]|[^(]\\+|^)([\\.:#@])`(\\¢ã\\*[^\\*]*\\*+([^\\¢ã][^\\*]*\\*+)*\\¢ã)|(\x27[^\x27]*\x27)|("[^"]*")`@(£ý|£ü)[^;\\n]+[;\\n]|<!\\-\\-|\\-\\->`\\¢¤:`^\\s+|\\s*([\\{\\}\\+\\,>~\\s;])\\s*|\\s+$`\x27(\\d+)\x27`(\x27[^\x27]*\x27)|("[^"]*")` ¥="([^"]*)"`^(¢Ü|£á|£¤)$`^\\d\\w*$`^\\d+%$`^\\d+(px)?$`\\b(¢±|ú)-(¨|¢ð)\\s*:\\s*\\d`\\b(¢±|ú)-¨\\s*:\\s*\\d`^Û|0cm$`^Û$`¢±`£Ö`¨`£Ô`Â`£Ñ`æ`¤Õ`´ ¤Ô 0.7.3 (¤Ó)`\\n\\n`¤Ì`¤Ê`¤È ¤Ç`:È{Æ-È:È}:¢¥{Æ-È:¢¥}`*{¤Æ:0}`ô=``/`¤Ã.¤Â`¤À`¢Ì [1]: ¤½ ¤¼ ã ¤» `Æ-¤º.js`ä`<Í></Í>`$1`$2`Í`¢« ¤³`¢Ì [2]: `([^{}]*)\\¢¤{([^}]*[^\\¢Ø-])?`gi`¢Û-¤°\\½*:\\½*¤¯-¢Û`Ü\\½*:\\½*¢×`¤®`¢º:¤¬;$1`¢º:£­`xx-¢Á,x-¢Á,¢Á,¤ª,¢ê,x-¢ê,xx-¢ê`,`xx-¢Á`(¤©(-¤¨)?\\½*:\\½*)(`|`)`$1*$2` *#`(` `*`#`.`(^|\\½)`(\\½|$)`:`È`¢¥`\\¢¤([^)]*\\¢¤)`Æ-È`\x27`\\¢¤:`£ú`£ö`Ü:¢×;£õ:0;¢º:£­;£ô:£ó;£ò:¢°(0 0 0 0);Â:-9999`!`Æ-£ì`<£¨:`/>`</`>`£¨`£é://£è.w3.£ç/1999/£æ`£å`Ò,¢ß,£ä`£¥` £¥`£¤,Ò`£¢`¢Ü`£ã`«.ì.`.°.¢Ý=Þ`£â`£à`.ý=Þ`.¥=\x27`Æ-¢Û-£ß`\\½*:\\½*\\¢ú[\\¢Ø%]*`¢Ö`HR`¨\\½*:\\½*\\¢ú\\¢Ø*[^%]`Û`¢±-¨`ú`ú-¨`¢×`æ`£Ú`£Õ`¢ð`£Ó`£Ò`£Ð`£Ï`£Í`¢Ì [0]: '.split('\x60')));
+/* packed with http://dean.edwards.name/packer/ */
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-lite.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-lite.js
new file mode 100644
index 0000000..88c764f
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-lite.js
@@ -0,0 +1,2 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+if(!window.IE7)new function(){try{window.IE7=this;var DUMMY=this.addModule=new Function;function unHide(){if(document.body)document.body.style.visibility="visible"};this.toString=function(){return "IE7 version 0.7.3 (alpha)"};var alert=(/ie7_debug/.test(location.search))?function(message){window.alert(IE7+"\n\n"+message)}:DUMMY;var appVersion=navigator.appVersion.match(/MSIE (\d\.\d)/)[1];if(/ie7_off/.test(location.search)||appVersion<5||!/^ms_/.test(document.documentElement.uniqueID))return unHide();var quirksMode=Boolean(document.compatMode!="CSS1Compat");var isHTML=(typeof document.mimeType=="unknown")?!/\.xml$/i.test(location.pathname):Boolean(document.mimeType!="XML Document");var LINKS=":link{ie7-link:link}:visited{ie7-link:visited}";var HEADER=LINKS;if(!isHTML)HEADER+="*{margin:0}";var HTMLFixes;var documentElement=document.documentElement;var modules={};this.addModule=function(name,script,autoload){if(!modules)return;if(loaded)eval("script="+String(script));if(autoload){script();script=DUMMY}modules[name]=script};var RELATIVE=/^[\w\.]+[^:]*$/;function makePath(href,path){if(RELATIVE.test(href))href=(path||"")+href;return href};function getPath(href,path){href=makePath(href,path);return href.slice(0,href.lastIndexOf("/")+1)};var path=getPath(document.scripts[document.scripts.length-1].src);var httpRequest=new ActiveXObject("Microsoft.XMLHTTP");function load(href,path){try{href=makePath(href,path);httpRequest.open("GET",href,false);httpRequest.send();return httpRequest.responseText}catch(ignore){alert("Error [1]: could not load file "+href);return ""}};var push=function(array,item){return array.push(item)};var pop=function(array){return array.pop()};if(appVersion<5.5)eval(load("ie7-ie5.js",path));if(document.readyState=="complete"||!isHTML)document.createStyleSheet();else document.write("<style></style>");this.styleSheet=document.styleSheets[document.styleSheets.length-1];this.styleSheet.cssText=LINKS;this.styleSheet.ie7=true;var cssText={};function loadStyleSheet(styleSheet,path){var url=makePath(styleSheet.href,path);if(cssText[url])return "";cssText[url]=(styleSheet.disabled)?"":fixUrls(getCSSText(styleSheet,path),getPath(styleSheet.href,path));return cssText[url]};var getCSSText=function(styleSheet){return styleSheet.cssText};var URL=/(url\(['"]?)([\w\.]+[^:\)]*['"]?\))/gi;function fixUrls(cssText,pathname){return cssText.replace(URL,"$1"+pathname.slice(0,pathname.lastIndexOf("/")+1)+"$2")};this.recalcs=[];this.parse=DUMMY;var complete=false;function _load(){try{complete=true;var MEDIA=/\bscreen\b|\ball\b|^$/i;var styleSheets=document.styleSheets;var inlineStyles=[];var styles=document.getElementsByTagName("style");for(var i=styles.length-1;i>=0;i--){push(inlineStyles,/ie7-link/.test(styles[i].innerHTML)?"":styles[i].innerHTML)}function getCSSText(styleSheet,path){var cssText="";if(MEDIA.test(styleSheet.media)){for(var i=0;i<styleSheet.imports.length;i++){cssText+=arguments.callee(styleSheet.imports[i],getPath(styleSheet.href,path))}cssText+=((styleSheet.href)?loadStyleSheet(styleSheet,path):pop(inlineStyles))}return cssText};IE7.cssText="";for(i=0;i<styleSheets.length;i++)IE7.cssText+=getCSSText(styleSheets[i],"");IE7.cssText=encode(IE7.cssText);for(i in modules)modules[i]();delete modules;if(HTMLFixes)HTMLFixes.apply();CSSFixes.apply();IE7.parse();IE7.styleSheet.cssText=HEADER+decode(IE7.cssText);for(i=0;i<styleSheets.length;i++){if(!styleSheets[i].disabled&&!styleSheets[i].ie7)styleSheets[i].cssText=""}IE7.recalc();alert("loaded successfully")}catch(error){alert("Error [2]: "+error.description)}finally{unHide()}};this.recalc=function(){CSSFixes.recalc();for(var i=0;i<this.recalcs.length;i++)this.recalcs[i]()};var CSSFixes=new function(){var fixes=[];this.addFix=function(){push(fixes,arguments)};var recalcs=[];this.addRecalc=function(pattern,fix){var reg=new RegExp("([^{}]*)\x5c{([^}]*[^\x5cw-])?"+pattern,"gi");var cssText=IE7.cssText;pattern=[];while(match=reg.exec(cssText)){push(pattern,match[1]);if(appVersion<5.5)cssText=cssText.slice(match.lastIndex)}if(pattern.length){pattern=pattern.toString();push(recalcs,arguments)}};this.apply=function(){for(var i=0;i<fixes.length;i++){IE7.cssText=IE7.cssText.replace(fixes[i][0],fixes[i][1])}this.addRecalc("box-sizing\x5cs*:\x5cs*content-box",boxSizing);this.addRecalc("position\x5cs*:\x5cs*absolute",function(element){if(element.offsetParent.currentStyle.position=="relative")boxSizing(element.offsetParent)})};this.recalc=function(){for(var i=0;i<recalcs.length;i++){var elements=cssQuery(recalcs[i][0]);for(var j=0;j<elements.length;j++)recalcs[i][1](elements[j])}};this.addFix(/(float\s*:\s*(left|right))/gi,"display:inline;$1");if(appVersion<6)this.addFix(/display\s*:\s*list-item/gi,"display:block");if(quirksMode){var SIZES="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");for(var i=0;i<SIZES.length;i++)SIZES[SIZES[i]]=SIZES[i-1]||"xx-small";function replace($,$1,$2,$3){return $1+SIZES[$3]};this.addFix(new RegExp("(font(-size)?\x5cs*:\x5cs*)("+SIZES.join("|")+")","gi"),replace)}};var STANDARD_SELECT=/^[^>\+~\s]/;var STREAM=/[\s>\+~:@#\.\(\)]|[^\s>\+~:@#\.\(\)]+/g;var NAMESPACE=/\|/;var IMPLIED_SELECTOR=/([\s>~\,]|[^(]\+|^)([\.:#@])/g;var ASTERISK="$1*$2";var cssCache={};function cssQuery(selector,from){var useCache=!from;var base=(from)?(from.constructor==Array)?from:[from]:[document];var selectors=selector.replace(IMPLIED_SELECTOR,ASTERISK).split(",");var match=[];for(var i=0;i<selectors.length;i++){selector=toStream(selectors[i]);if(selector.slice(0,3).join("")==" *#"){selector=selector.slice(2);from=selectById(base,selector[1])}else from=base;var j=0,token,filter,filterArgs,cacheSelector="";while(j<selector.length){token=selector[j++];filter=selector[j++];cacheSelector+=token+filter;filterArgs="";if(selector[j]=="("){while(selector[j++]!=")")filterArgs+=selector[j];filterArgs=filterArgs.slice(0,-1);cacheSelector+="("+filterArgs+")"}from=(useCache&&cssCache[cacheSelector])?cssCache[cacheSelector]:select(from,token,filter,filterArgs);if(useCache)cssCache[cacheSelector]=from}match=match.concat(from)}return match};function toStream(selector){if(STANDARD_SELECT.test(selector))selector=" "+selector;return selector.match(STREAM)};function select(from,token,filter,filterArgs){var scopeName="";if(NAMESPACE.test(filter)){filter=filter.split("|");scopeName=filter[0];filter=filter[1]}var filtered=[];if(selectors[token])selectors[token](filtered,from,filter,scopeName||filterArgs);return filtered};function selectById(from,id){var filtered=[],i,j;for(i=0;i<from.length;i++){var match=from[i].all.item(id);if(match){if(match.length==null)push(filtered,match);else for(j=0;j<match.length;j++)push(filtered,match[j])}}return filtered};var selectors={" ":function(filtered,from,filter,scopeName){for(var i=0;i<from.length;i++){var subset=(filter=="*"&&from[i].all)?from[i].all:from[i].getElementsByTagName(filter);for(var j=0;j<subset.length;j++){if(isElement(subset[j])&&(!scopeName||subset[j].scopeName==scopeName))push(filtered,subset[j])}}},"#":function(filtered,from,filter){for(var i=0;i<from.length;i++)if(from[i].id==filter)push(filtered,from[i])},".":function(filtered,from,filter){filter=new RegExp("(^|\x5cs)"+filter+"(\x5cs|$)");for(var i=0;i<from.length;i++)if(filter.test(from[i].className))push(filtered,from[i])},":":function(filtered,from,filter,filterArgs){filter=pseudoClasses[filter];if(filter)for(var i=0;i<from.length;i++)if(filter(from[i],filterArgs))push(filtered,from[i])}};var attributeTests="";var pseudoClasses={toString:function(){var toString=[];for(var pseudoClass in this){if(pseudoClass!="link"&&pseudoClass!="visited"){if(this[pseudoClass].length>1)pseudoClass+="\x5c([^)]*\x5c)";push(toString,pseudoClass)}}return toString.join("|")},"link":function(element){return Boolean(element.currentStyle["ie7-link"]=="link")},"visited":function(element){return Boolean(element.currentStyle["ie7-link"]=="visited")}};var dynamicPseudoClasses={toString:pseudoClasses.toString};function compareTagName(element,tagName,scopeName){if(scopeName&&element.scopeName!=scopeName)return false;return(tagName=="*")?isElement(element):(isHTML)?(element.tagName==tagName.toUpperCase()):(element.tagName==tagName)};var strings=[];function getString(string){return QUOTED.test(string)?strings[string.slice(1,-1)]:string};var encode=function(cssText){return cssText.replace(/(\x2f\*[^\*]*\*+([^\x2f][^\*]*\*+)*\x2f)|('[^']*')|("[^"]*")/g,function(match){return(match.charAt(0)=="/")?"":"'"+(push(strings,match.slice(1,-1))-1)+"'"}).replace(/@(namespace|import)[^;\n]+[;\n]|<!\-\-|\-\->/g,"").replace(/\x5c:/g,"|").replace(/^\s+|\s*([\{\}\+\,>~\s;])\s*|\s+$/g,"$1")};function decode(cssText){return cssText.replace(/\|/g,"\x5c:").replace(/'(\d+)'/g,function(match,key){return strings[key]})};var handlers=[];function addEventHandler(element,type,handler){element.attachEvent(type,handler);push(handlers,arguments)};function removeEventHandler(element,type,handler){try{element.detachEvent(type,handler)}catch(ignore){}};window.attachEvent("onbeforeunload",function(){while(handlers.length){var handler=pop(handlers);removeEventHandler(handler[0],handler[1],handler[2])}});var hasLayout=(appVersion<6)?function(element){return element.clientWidth}:function(element){return element.currentStyle.hasLayout};function boxSizing(element){if(!hasLayout(element)){element.contentEditable=false;fixMargins(firstChildElement(element))}};function fixMargins(element){while(element){element.runtimeStyle.marginTop=element.currentStyle.marginTop;element=nextElement(element)}};var QUOTED=/('[^']*')|("[^"]*")/;function quote(value){return(QUOTED.test(value))?value:"'"+value+"'"};function unquote(value){return(QUOTED.test(value))?value.slice(1,-1):value};function tmpElement(tagName){var element=document.createElement(tagName||"object");element.style.cssText="position:absolute;padding:0;display:block;border:none;clip:rect(0 0 0 0);left:-9999";return element};function isElement(node){return Boolean(node&&node.nodeType==1&&node.tagName!="!"&&!node.ie7_anon)};function previousElement(element){while(element&&(element=element.previousSibling)&&!isElement(element))continue;return element};function nextElement(element){while(element&&(element=element.nextSibling)&&!isElement(element))continue;return element};function firstChildElement(element){element=element.firstChild;return(isElement(element))?element:nextElement(element)};var loaded=false;IE7.addModule("ie7-html4",function(){if(isHTML)HTMLFixes=new function(){var fixes=[];function fix(element){var fixedElement=document.createElement("<HTML:"+element.outerHTML.slice(1));if(element.outerHTML.slice(-2)!="/>"){var endTag="</"+element.tagName+">",nextSibling;while((nextSibling=element.nextSibling)&&nextSibling.outerHTML!=endTag){element.parentNode.removeChild(nextSibling);fixedElement.appendChild(nextSibling)}if(nextSibling)element.parentNode.removeChild(nextSibling)}element.parentNode.replaceChild(fixedElement,element);return fixedElement};this.add=function(){push(fixes,arguments)};this.apply=function(){try{if(appVersion>5)document.namespaces.add("HTML","http://www.w3.org/1999/xhtml")}catch(ignore){}finally{for(var i=0;i<fixes.length;i++){var elements=cssQuery(fixes[i][0]);for(var j=0;j<elements.length;j++)fixes[i][1](elements[j])}}};this.add("label",function(element){if(!element.htmlFor){var input=cssQuery("input,select,textarea",element)[0];if(input){if(!input.id)input.id=input.uniqueID;element.htmlFor=input.id}}});this.add("abbr",function(element){fix(element);delete cssCache[" abbr"]});this.add("button,input",function(element){if(element.tagName=="BUTTON"){var match=element.outerHTML.match(/ value="([^"]*)"/i);element.runtimeStyle.value=(match)?match[1]:""}if(element.type=="submit"){addEventHandler(element,"onclick",function(){element.runtimeStyle.clicked=true;setTimeout("document.all."+element.uniqueID+".runtimeStyle.clicked=false",1)})}});this.add("form",function(element){var UNSUCCESSFUL=/^(submit|reset|button)$/;addEventHandler(element,"onsubmit",function(){for(var i=0;i<element.length;i++){if(UNSUCCESSFUL.test(element[i].type)&&!element[i].disabled&&!element[i].runtimeStyle.clicked){element[i].disabled=true;setTimeout("document.all."+element[i].uniqueID+".disabled=false",1)}else if(element[i].tagName=="BUTTON"&&element[i].type=="submit"){setTimeout("document.all."+element[i].uniqueID+".value='"+element[i].value+"'",1);element[i].value=element[i].runtimeStyle.value}}})})}},true);IE7.addModule("ie7-box-model",function(){var NUMERIC="\x5cs*:\x5cs*\x5cd[\x5cw%]*",UNIT=/^\d\w*$/,PERCENT=/^\d+%$/,PIXEL=/^\d+(px)?$/;var MATCH=(appVersion<6)?/\b(min|max)-(width|height)\s*:\s*\d/gi:/\b(min|max)-width\s*:\s*\d/gi;var AUTO=(appVersion<5.5)?/^auto|0cm$/:/^auto$/;var ie7_tmp=tmpElement();push(IE7.recalcs,function removeTempElement(){if(ie7_tmp.parentElement)ie7_tmp.parentElement.removeChild(ie7_tmp)});CSSFixes.addFix(MATCH,function(match){return match.slice(0,3)+match.charAt(4).toUpperCase()+match.slice(5)});var viewport=(quirksMode)?document.body:documentElement;function isFixed(element){return element.style.position=="fixed"||element.currentStyle.position=="fixed"};function layoutParent(element){var layoutParent=element.offsetParent;while(layoutParent&&!hasLayout(layoutParent))layoutParent=layoutParent.offsetParent;if(!layoutParent||isFixed(element))layoutParent=viewport;return layoutParent};function fixWidth(HEIGHT){fixWidth=function(element,value){if(!element.runtimeStyle.fixedWidth&&(!isHTML||element.tagName!="HR")){if(!value)value=element.currentStyle.width;element.runtimeStyle.fixedWidth=(UNIT.test(value))?Math.max(0,getFixedWidth(element,value)):value;element.runtimeStyle.width=element.runtimeStyle.fixedWidth;boxSizing(element)}};if(quirksMode)CSSFixes.addRecalc("width\x5cs*:\x5cs*\x5cd\x5cw*[^%]",fixWidth);var getFixedWidth=(quirksMode)?function(element,value){return getPixelWidth(element,value)+getBorderWidth(element)+getPaddingWidth(element)}:function(element,value){return getPixelWidth(element,value)};function getBorderWidth(element){return element.offsetWidth-element.clientWidth};function getPaddingWidth(element){return getPixelWidth(element,element.currentStyle.paddingLeft)+getPixelWidth(element,element.currentStyle.paddingRight)};function getMarginWidth(element){return((element.currentStyle.marginLeft=="auto")?0:getPixelLeft(element,element.currentStyle.marginLeft))+((element.currentStyle.marginRight=="auto")?0:getPixelLeft(element,element.currentStyle.marginRight))};function minWidth(element){minWidth[minWidth.count++]=element;if(element.currentStyle.minHeight=="auto")element.runtimeStyle.minHeight=0;fixWidth(element);boxSizing(element);resizeWidth(element)};minWidth.count=0;CSSFixes.addRecalc("min-width"+NUMERIC,minWidth);eval(String(minWidth).replace(/min/g,"max"));maxWidth.count=0;CSSFixes.addRecalc("max-width"+NUMERIC,maxWidth);function resizeWidth(element){var rect=element.getBoundingClientRect();var width=rect.right-rect.left;if(element.currentStyle.maxWidth&&width>=getFixedWidth(element,element.currentStyle.maxWidth))element.runtimeStyle.width=getFixedWidth(element,element.currentStyle.maxWidth);else if(element.currentStyle.minWidth&&width<=getFixedWidth(element,element.currentStyle.minWidth))element.runtimeStyle.width=getFixedWidth(element,element.currentStyle.minWidth);else element.runtimeStyle.width=element.runtimeStyle.fixedWidth};function fixRight(element){if((element.currentStyle.position=="absolute"||element.currentStyle.position=="fixed")&&element.currentStyle.left!="auto"&&element.currentStyle.right!="auto"&&AUTO.test(element.currentStyle.width)){fixRight[fixRight.count++]=element;boxSizing(element);resizeRight(element)}};fixRight.count=0;CSSFixes.addRecalc("right"+NUMERIC,fixRight);function resizeRight(element){element.runtimeStyle.width="";var parentElement=layoutParent(element);var left=(element.runtimeStyle.screenLeft)?element.getBoundingClientRect().left-2:getPixelLeft(element,element.currentStyle.left);var width=parentElement.clientWidth-getPixelLeft(element,element.currentStyle.right)-left-getMarginWidth(element);if(!quirksMode)width-=getBorderWidth(element)+getPaddingWidth(element);if(width<0)width=0;if(isFixed(element)||HEIGHT||element.offsetWidth<width){element.runtimeStyle.fixedWidth=width;element.runtimeStyle.width=width}};var clientWidth=documentElement.clientWidth;addEventHandler(window,"onresize",function(){var i,wider=(clientWidth<documentElement.clientWidth);clientWidth=documentElement.clientWidth;for(i=0;i<minWidth.count;i++){var element=minWidth[i];var fixedWidth=(element.runtimeStyle.width==element.currentStyle.minWidth);if(wider&&fixedWidth)element.runtimeStyle.width="";if(wider==fixedWidth)resizeWidth(element)}for(i=0;i<maxWidth.count;i++){var element=maxWidth[i];var fixedWidth=(element.runtimeStyle.width==element.currentStyle.maxWidth);if(!wider&&fixedWidth)element.runtimeStyle.width="";if(wider!=fixedWidth)resizeWidth(element)}for(i=0;i<fixRight.count;i++)resizeRight(fixRight[i]);removeTempElement()});function getPixelWidth(element,value){if(PIXEL.test(value))return parseInt(value);if(PERCENT.test(value))return parseInt(parseFloat(value)/100*layoutParent(element).clientWidth);var parentElement=(element.canHaveChildren)?element:element.parentElement;parentElement.appendChild(ie7_tmp);ie7_tmp.style.width=value;return ie7_tmp.offsetWidth};function getPixelLeft(element,value){if(parseInt(value)>0)return getPixelWidth(element,value);if(PIXEL.test(value))return parseInt(value);element.parentElement.appendChild(ie7_tmp);ie7_tmp.style.left=value;return ie7_tmp.offsetLeft}};eval(String(fixWidth).replace(/Width/g,"Height").replace(/width/g,"height").replace(/Left/g,"Top").replace(/left/g,"top").replace(/Right/g,"Bottom").replace(/right/g,"bottom"));fixWidth();fixHeight(true)});loaded=true;if(document.readyState=="complete")_load();else addEventHandler(document,"onreadystatechange",function(){if(!complete&&document.readyState=="complete")setTimeout(_load,0)})}catch(error){unHide();alert("Error [0]: "+error.description)}finally{}}();
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-png.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-png.js
new file mode 100644
index 0000000..7b8f2cf
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-png.js
@@ -0,0 +1,2 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+if(window.IE7)IE7.addModule("ie7-png",function(){if(appVersion<5.5)return;var FILTER="progid:DXImageTransform.Microsoft.AlphaImageLoader(src=%1,sizingMethod='scale')";var NULL=(/\bSV1\b/.test(navigator.userAgent))?makePath("blank.gif",path):"javascript:'#define x_width 1\x5cn#define x_height 1\x5cnstatic char x_bits[]={0x00}'";var pngTest=new RegExp((window.IE7_PNG_SUFFIX||"-trans.png")+"$","i");function addFilter(element,src){element.runtimeStyle.filter=FILTER.replace(/%1/,src)};var MATCH=/background(-image)?\s*:([^(};]*)url\(([^\)]+)\)([^;}]*)/gi;CSSFixes.addFix(MATCH,function replace(match,image,prefix,url,suffix){url=getString(url);return pngTest.test(url)?"filter:"+FILTER.replace(/scale/,"crop").replace(/%1/,url)+";zoom:1;background"+(image||"")+":"+(prefix||"")+"none"+(suffix||""):match});if(HTMLFixes){function fixImg(element){if(pngTest.test(element.src)){var width=element.width,height=element.height;addFilter(element,element.src);element.src=NULL;element.width=width;element.height=height}else element.runtimeStyle.filter=""};HTMLFixes.add("img,input",function(element){if(element.tagName=="INPUT"&&element.type!="image")return;fixImg(element);addEventHandler(element,"onpropertychange",function(){if(event.propertyName=="src")fixImg(element)})})}});
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-server.css b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-server.css
new file mode 100644
index 0000000..47c7edd
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-server.css
@@ -0,0 +1,43 @@
+body, td, dd {font: 10pt Verdana, Arial, Helvetica, sans-serif; color: black;}
+body {margin: 8px; background: #333;}
+h1 {margin: 0;}
+h1 a:hover {background-color: transparent;}
+h2 {font-size: 1.75em;}
+h3 {font-size: 1.1em;}
+a:active {color: #ff0000;}
+a:link {color: #0a6cce;}
+a:visited {color: #0a6cce;}
+code, *.code {font-family: monospace; font-size: 100%; font-style: normal; white-space: nowrap;
+ padding: 0 1px; background: #f2f3f8; border: #d6d9e9 1px solid;}
+code.box {display: block; padding: 10px; margin: 0.5em 0;}
+ul {list-style-type: square;}
+dd {margin: .2em 0 .5em 1em;}
+dl.library dt {display: list-item; margin-left: 3em; list-style-type: square;}
+dl.library dd {font-style: italic; margin-left: 3em;}
+dt {font-weight: bold;}
+dt.pack {color: brown;}
+a img {border-style: none;}
+hr {height: 1px; color: #000; border-style: solid;}
+hr.short {height: 2px; width: 100px;}
+div.document {background: #eef; padding: 20px 20px 5px 20px; width: 600px; border: 1px solid black;}
+hr {border-bottom-width: 0px;}
+div.header hr {color: #0a6cce; background-color: #0a6cce;}
+div.content {min-height: 100px;}
+div.footer hr {color: #898e79; background-color: #898e79; }
+div.header, div.header a:link, div.header a:visited, h3 a:link, h3 a:visited {text-decoration: none;}
+a:hover {color: #fff; background-color: #0a6cce; text-decoration: none;}
+div.footer a:hover {background-color: transparent; text-decoration: none;}
+div.header .menu {text-align: right;}
+div.footer {font-size: x-small; margin-top: 8px;}
+div.footnote {font-family: "times new roman", times; font-style: italic; margin-top: 10px;}
+#license {margin-top: 5px; font-size: xx-small;}
+table {border-top: 1px solid #000; border-left: 1px solid #000;}
+th {background-color: #fff; text-align: left;}
+th, td {border-right: 1px solid #000; border-bottom: 1px solid #000;}
+th.small {width: 100px;}
+th.medium {width: 200px;}
+th.large {width: 270px;}
+th.x-large {width: 408px;}
+table.fixed {table-layout: fixed;}
+span.comment {color: #666;}
+
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-standard-p.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-standard-p.js
new file mode 100644
index 0000000..27cfa2c
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-standard-p.js
@@ -0,0 +1,3 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+eval(function(A,r,s,e,n,a,l){s=function(e){return((e<a)?'':s(e/a))+n[l[493]](e%a+161)};while(++r<735)l[r]=(r<549)?'/'+l[r]+'/':'"'+l[r]+'"';while(--r>=0)A=A.replace(new RegExp(s(r),'g'),l[r]);return A}('if(!¢¡.ª)¶ ¢(){¢Æ{¢¡.ª=¤;£ ¢Ø=¤.¢©=¶ ¤¬;¢ ¢ì(){if(².ß)².ß.Ì.¦²=¦ë};¤.È=¢(){¥ ¦ì};£ ¢¶=(¦´.µ(¢ô.¤ì))?¢(¤í){¢¡.¢¶(ª+¦í+¤í)}:¢Ø;£ á=¤¥.á.§(¦µ)[1];if(¦¶.µ(¢ô.¤ì)||á<5||!¦·.µ(².ù.¢«))¥ ¢ì();£ ¢§=¢ê(².¦«!=¦î);£ ¢±=(¦© ².¤ë==¦ï)?!¦¸i.µ(¢ô.£»):¢ê(².¤ë!=¦ð);£ £ê=¦ñ;£ £¦=£ê;if(!¢±)£¦+=¦ò;£ ¢½;£ ù=².ù;£ ¢Ñ={};¤.¢©=¢(¢Ç,¢Ò,¤ê){if(!¢Ñ)¥;if(¢í)Ü(¦ó+¢ó(¢Ò));if(¤ê){¢Ò();¢Ò=¢Ø}¢Ñ[¢Ç]=¢Ò};£ ¤é=¦¹;¢ ¢À(¾,Á){if(¤é.µ(¾))¾=(Á||¦ô)+¾;¥ ¾};¢ £¹(¾,Á){¾=¢À(¾,Á);¥ ¾.Æ(0,¾.¤å(¦õ)+1)};£ Á=£¹(².¤è[².¤è.¯-1].î);£ £½=¶ ¦£(¦ö);¢ ê(¾,Á){¢Æ{¾=¢À(¾,Á);£½.¦¡(¦÷,¾,ë);£½.¥þ();¥ £½.¥ý}¢·(£¥){¢¶(¦ø+¾);¥ ¦ô}};£ ¸=¢(£¼,£·){¥ £¼.¸(£·)};£ £´=¢(£¼){¥ £¼.£´()};if(á<5.5)Ü(ê(¦ù,Á));if(².£À==¦ú||!¢±)².¥ø();Û ².¥÷(¦û);¤.¿=².é[².é.¯-1];¤.¿.¨=£ê;¤.¿.Î=Ö;£ ¨={};¢ ¤á(¿,Á){£ Ô=¢À(¿.¾,Á);if(¨[Ô])¥ ¦ô;¨[Ô]=(¿.¢ç)?¦ô:¤ç(¢ã(¿,Á),£¹(¿.¾,Á));¥ ¨[Ô]};£ ¢ã=¢(¿){¥ ¿.¨};£ ¤æ=¦ºgi;¢ ¤ç(¨,£»){¥ ¨.¬(¤æ,¦ü+£».Æ(0,£».¤å(¦õ)+1)+¦ý)};¤.ô=[];¤.¢â=¢Ø;£ ¢¸=ë;¢ _ê(){¢Æ{¢¸=Ö;£ ¤ã=¦»i;£ é=².é;£ £é=[];£ £º=².¤Ø(¦þ);®(£ i=£º.¯-1;i>=0;i--){¸(£é,¦¼.µ(£º[i].¤ä)?¦ô:£º[i].¤ä)}¢ ¢ã(¿,Á){£ ¨=¦ô;if(¤ã.µ(¿.¥ô)){®(£ i=0;i<¿.¤â.¯;i++){¨+=í.£ó(¿.¤â[i],£¹(¿.¾,Á))}¨+=((¿.¾)?¤á(¿,Á):£´(£é))}¥ ¨};ª.¨=¦ô;®(i=0;i<é.¯;i++)ª.¨+=¢ã(é[i],¦ô);ª.¨=£©(ª.¨);®(i in ¢Ñ)¢Ñ[i]();£Ö ¢Ñ;if(¢½)¢½.£°();à.£°();ª.¢â();ª.¿.¨=£¦+£§(ª.¨);®(i=0;i<é.¯;i++){if(!é[i].¢ç&&!é[i].Î)é[i].¨=¦ô}ª.Ø();¢¶(¦ÿ)}¢·(¢ë){¢¶(§¡+¢ë.£ë)}£¾{¢ì()}};¤.Ø=¢(){à.Ø();®(£ i=0;i<¤.ô.¯;i++)¤.ô[i]()};£ à=¶ ¢(){£ è=[];¤.¢¿=¢(){¸(è,í)};£ ô=[];¤.ï=¢(¢µ,£ä){£ ¤à=¶ ç(§¢+¢µ,§£);£ ¨=ª.¨;¢µ=[];Ý(§=¤à.¢ß(¨)){¸(¢µ,§[1]);if(á<5.5)¨=¨.Æ(§.¥ò)}if(¢µ.¯){¢µ=¢µ.È();¸(ô,í)}};¤.£°=¢(){®(£ i=0;i<è.¯;i++){ª.¨=ª.¨.¬(è[i][0],è[i][1])}¤.ï(§¤,¢Ê);¤.ï(§¥,¢(¡){if(¡.¢¥.«.³==§¦)¢Ê(¡.¢¥)})};¤.Ø=¢(){®(£ i=0;i<ô.¯;i++){£ ¢Í=ü(ô[i][0]);®(£ j=0;j<¢Í.¯;j++)ô[i][1](¢Í[j])}};¤.¢¿(¦½gi,§§);if(á<6)¤.¢¿(¦¾gi,§¨);if(¢§){£ ¢´=§©.£¨(§ª);®(£ i=0;i<¢´.¯;i++)¢´[¢´[i]]=¢´[i-1]||§«;¢ ¬($,$1,$2,$3){¥ $1+¢´[$3]};¤.¢¿(¶ ç(§¬+¢´.¢Ü(§­)+§®,§£),¬)}};£ ¤Ü=¦¿;£ ¤Û=¦Àg;£ ¤Ú=¦Á;£ ¤ß=¦Âg;£ ¤Þ=§¯;£ ¢è={};¢ ü(´,­){£ £æ=!­;£ £ç=(­)?(­.¥ê==¥é)?­:[­]:[²];£ ò=´.¬(¤ß,¤Þ).£¨(§ª);£ §=[];®(£ i=0;i<ò.¯;i++){´=¤Ý(ò[i]);if(´.Æ(0,3).¢Ü(¦ô)==§°){´=´.Æ(2);­=¤Ù(£ç,´[1])}Û ­=£ç;£ j=0,¢³,±,É,¢Ð=¦ô;Ý(j<´.¯){¢³=´[j++];±=´[j++];¢Ð+=¢³+±;É=¦ô;if(´[j]==§±){Ý(´[j++]!=§®)É+=´[j];É=É.Æ(0,-1);¢Ð+=§±+É+§®}­=(£æ&&¢è[¢Ð])?¢è[¢Ð]:£å(­,¢³,±,É);if(£æ)¢è[¢Ð]=­}§=§.¥è(­)}¥ §};¢ ¤Ý(´){if(¤Ü.µ(´))´=§²+´;¥ ´.§(¤Û)};¢ £å(­,¢³,±,É){£ Ê=¦ô;if(¤Ú.µ(±)){±=±.£¨(§­);Ê=±[0];±=±[1]}£ ¼=[];if(ò[¢³])ò[¢³](¼,­,±,Ê||É);¥ ¼};¢ ¤Ù(­,id){£ ¼=[],i,j;®(i=0;i<­.¯;i++){£ §=­[i].¢Ì.£·(id);if(§){if(§.¯==¢Þ)¸(¼,§);Û ®(j=0;j<§.¯;j++)¸(¼,§[j])}}¥ ¼};£ ò={§²:¢(¼,­,±,Ê){®(£ i=0;i<­.¯;i++){£ ó=(±==§³&&­[i].¢Ì)?­[i].¢Ì:­[i].¤Ø(±);®(£ j=0;j<ó.¯;j++){if(¢Î(ó[j])&&(!Ê||ó[j].Ê==Ê))¸(¼,ó[j])}}},§´:¢(¼,­,±){®(£ i=0;i<­.¯;i++)if(­[i].id==±)¸(¼,­[i])},§µ:¢(¼,­,±){±=¶ ç(§¶+±+§·);®(£ i=0;i<­.¯;i++)if(±.µ(­[i].¢Ý))¸(¼,­[i])},§¸:¢(¼,­,±,É){±=¢®[±];if(±)®(£ i=0;i<­.¯;i++)if(±(­[i],É))¸(¼,­[i])}};£ ¢¬=¦ô;£ ¢®={È:¢(){£ È=[];®(£ ¢Ï in ¤){if(¢Ï!=§¹&&¢Ï!=§º){if(¤[¢Ï].¯>1)¢Ï+=§»;¸(È,¢Ï)}}¥ È.¢Ü(§­)},§¹:¢(¡){¥ ¢ê(¡.«[§¼]==§¹)},§º:¢(¡){¥ ¢ê(¡.«[§¼]==§º)}};£ ¢­={È:¢®.È};¢ £Ù(¡,Ï,Ê){if(Ê&&¡.Ê!=Ê)¥ ë;¥(Ï==§³)?¢Î(¡):(¢±)?(¡.Ï==Ï.¤Ç()):(¡.Ï==Ï)};£ £µ=[];¢ ¢ö(£¶){¥ £².µ(£¶)?£µ[£¶.Æ(1,-1)]:£¶};£ £©=¢(¨){¥ ¨.¬(¦Ãg,¢(§){¥(§.¤È(0)==¦õ)?¦ô:§½+(¸(£µ,§.Æ(1,-1))-1)+§½}).¬(¦Äg,¦ô).¬(¦Åg,§­).¬(¦Æg,¦ü)};¢ £§(¨){¥ ¨.¬(¦Ág,§¾).¬(¦Çg,¢(§,¤×){¥ £µ[¤×]})};£ £³=[];¢ Ó(¡,Õ,þ){¡.¤Ö(Õ,þ);¸(£³,í)};¢ ¤Õ(¡,Õ,þ){¢Æ{¡.¥å(Õ,þ)}¢·(£¥){}};¢¡.¤Ö(§¿,¢(){Ý(£³.¯){£ þ=£´(£³);¤Õ(þ[0],þ[1],þ[2])}});£ £®=(á<6)?¢(¡){¥ ¡.Í}:¢(¡){¥ ¡.«.£®};¢ ¢Ê(¡){if(!£®(¡)){¡.¥ã=ë;¤Ô(¤Ð(¡))}};¢ ¤Ô(¡){Ý(¡){¡.¦.¤Ó=¡.«.¤Ó;¡=¢þ(¡)}};£ £²=¦È;¢ ¤ª(©){¥(£².µ(©))?©:§½+©+§½};¢ ¥â(©){¥(£².µ(©))?©.Æ(1,-1):©};¢ £Ï(Ï){£ ¡=².£Û(Ï||§À);¡.Ì.¨=§Á;¥ ¡};¢ ¢Î(¢é){¥ ¢ê(¢é&&¢é.¥Þ==1&&¢é.Ï!=§Â&&!¢é.¢ÿ)};¢ ¤²(¡){Ý(¡&&(¡=¡.¥Ý)&&!¢Î(¡))¤Ñ;¥ ¡};¢ ¢þ(¡){Ý(¡&&(¡=¡.õ)&&!¢Î(¡))¤Ñ;¥ ¡};¢ ¤Ð(¡){¡=¡.¤¹;¥(¢Î(¡))?¡:¢þ(¡)};£ ¢í=ë;ª.¢©(§Ã,¢(){if(¢±)¢½=¶ ¢(){£ è=[];¢ £ä(¡){£ £±=².£Û(§Ä+¡.£¯.Æ(1));if(¡.£¯.Æ(-2)!=§Å){£ ¤Ï=§Æ+¡.Ï+§Ç,õ;Ý((õ=¡.õ)&&õ.£¯!=¤Ï){¡.¢ü.¢Õ(õ);£±.¢»(õ)}if(õ)¡.¢ü.¢Õ(õ)}¡.¢ü.¥Û(£±,¡);¥ £±};¤.æ=¢(){¸(è,í)};¤.£°=¢(){¢Æ{if(á>5)².¥Ú.æ(§È,§É)}¢·(£¥){}£¾{®(£ i=0;i<è.¯;i++){£ ¢Í=ü(è[i][0]);®(£ j=0;j<¢Í.¯;j++)è[i][1](¢Í[j])}}};¤.æ(§Ê,¢(¡){if(!¡.¤Í){£ ð=ü(§Ë,¡)[0];if(ð){if(!ð.id)ð.id=ð.¢«;¡.¤Í=ð.id}}});¤.æ(§Ì,¢(¡){£ä(¡);£Ö ¢è[§Í]});¤.æ(§Î,¢(¡){if(¡.Ï==§Ï){£ §=¡.£¯.§(¦Éi);¡.¦.©=(§)?§[1]:¦ô}if(¡.Õ==§Ð){Ó(¡,§Ñ,¢(){¡.¦.£ã=Ö;¢Ó(§Ò+¡.¢«+§Ó,1)})}});¤.æ(§Ô,¢(¡){£ ¤Ê=¦Ê;Ó(¡,§Õ,¢(){®(£ i=0;i<¡.¯;i++){if(¤Ê.µ(¡[i].Õ)&&!¡[i].¢ç&&!¡[i].¦.£ã){¡[i].¢ç=Ö;¢Ó(§Ò+¡[i].¢«+§Ö,1)}Û if(¡[i].Ï==§Ï&&¡[i].Õ==§Ð){¢Ó(§Ò+¡[i].¢«+§×+¡[i].©+§½,1);¡[i].©=¡[i].¦.©}}})})}},Ö);ª.¢©(§Ø,¢(){£ £«=§Ù,¤Æ=¦Ë,¢Ö=¦Ì,£Ý=¦Í;£ ¢¾=(á<6)?¦Îgi:¦Ïgi;£ ¤Ã=(á<5.5)?¦Ð:¦Ñ;£ ¹=£Ï();¸(ª.ô,¢ ¤À(){if(¹.½)¹.½.¢Õ(¹)});à.¢¿(¢¾,¢(§){¥ §.Æ(0,3)+§.¤È(4).¤Ç()+§.Æ(5)});£ Þ=(¢§)?².ß:ù;¢ ö(¡){¥ ¡.Ì.³==§Ú||¡.«.³==§Ú};¢ ã(¡){£ ã=¡.¢¥;Ý(ã&&!£®(ã))ã=ã.¢¥;if(!ã||ö(¡))ã=Þ;¥ ã};¢ ì(¤Á){ì=¢(¡,©){if(!¡.¦.ä&&(!¢±||¡.Ï!=§Û)){if(!©)©=¡.«.°;¡.¦.ä=(¤Æ.µ(©))?¥Î.¢æ(0,¢Ë(¡,©)):©;¡.¦.°=¡.¦.ä;¢Ê(¡)}};if(¢§)à.ï(§Ü,ì);£ ¢Ë=(¢§)?¢(¡,©){¥ ¢É(¡,©)+£à(¡)+£ß(¡)}:¢(¡,©){¥ ¢É(¡,©)};¢ £à(¡){¥ ¡.¢¼-¡.Í};¢ £ß(¡){¥ ¢É(¡,¡.«.¥Í)+¢É(¡,¡.«.¥Ì)};¢ ¤Â(¡){¥((¡.«.¢ï==§Ý)?0:¢ä(¡,¡.«.¢ï))+((¡.«.¤Å==§Ý)?0:¢ä(¡,¡.«.¤Å))};¢ Ú(¡){Ú[Ú.Ë++]=¡;if(¡.«.¤Ä==§Ý)¡.¦.¤Ä=0;ì(¡);¢Ê(¡);£ª(¡)};Ú.Ë=0;à.ï(§Þ+£«,Ú);Ü(¢ó(Ú).¬(¦Òg,§ß));ý.Ë=0;à.ï(§à+£«,ý);¢ £ª(¡){£ £¬=¡.£É();£ °=£¬.×-£¬.À;if(¡.«.ý&&°>=¢Ë(¡,¡.«.ý))¡.¦.°=¢Ë(¡,¡.«.ý);Û if(¡.«.Ú&&°<=¢Ë(¡,¡.«.Ú))¡.¦.°=¢Ë(¡,¡.«.Ú);Û ¡.¦.°=¡.¦.ä};¢ ¢²(¡){if((¡.«.³==§á||¡.«.³==§Ú)&&¡.«.À!=§Ý&&¡.«.×!=§Ý&&¤Ã.µ(¡.«.°)){¢²[¢².Ë++]=¡;¢Ê(¡);£Þ(¡)}};¢².Ë=0;à.ï(§â+£«,¢²);¢ £Þ(¡){¡.¦.°=¦ô;£ ½=ã(¡);£ À=(¡.¦.¢Ô)?¡.£É().À-2:¢ä(¡,¡.«.À);£ °=½.Í-¢ä(¡,¡.«.×)-À-¤Â(¡);if(!¢§)°-=£à(¡)+£ß(¡);if(°<0)°=0;if(ö(¡)||¤Á||¡.¢¼<°){¡.¦.ä=°;¡.¦.°=°}};£ Í=ù.Í;Ó(¢¡,§ã,¢(){£ i,¢å=(Í<ù.Í);Í=ù.Í;®(i=0;i<Ú.Ë;i++){£ ¡=Ú[i];£ ä=(¡.¦.°==¡.«.Ú);if(¢å&&ä)¡.¦.°=¦ô;if(¢å==ä)£ª(¡)}®(i=0;i<ý.Ë;i++){£ ¡=ý[i];£ ä=(¡.¦.°==¡.«.ý);if(!¢å&&ä)¡.¦.°=¦ô;if(¢å!=ä)£ª(¡)}®(i=0;i<¢².Ë;i++)£Þ(¢²[i]);¤À()});¢ ¢É(¡,©){if(£Ý.µ(©))¥ ø(©);if(¢Ö.µ(©))¥ ø(£Æ(©)/100*ã(¡).Í);£ ½=(¡.£Ì)?¡:¡.½;½.¢»(¹);¹.Ì.°=©;¥ ¹.¢¼};¢ ¢ä(¡,©){if(ø(©)>0)¥ ¢É(¡,©);if(£Ý.µ(©))¥ ø(©);¡.½.¢»(¹);¹.Ì.À=©;¥ ¹.¢¤}};Ü(¢ó(ì).¬(¦Óg,§ä).¬(¦Ôg,§å).¬(¦Õg,§æ).¬(¦Ög,§ç).¬(¦×g,§è).¬(¦Øg,§é));ì();¥É(Ö)});ª.¢©(§ê,¢(){£ ¤§=¦Ùg,¤½=¦Úi;ª.¢á=[];ª.¤¿=¶ ¤¾;ª.·=·;ª.Ò=Ò;ª.Ã=Ã;ª.¢â=¢(){¥Ç(¤.¤¿)¤.¨=£§(¢â(£©(¤.¨)));®(£ i=0;i<ª.¢á.¯;i++)ª.¢á[i].¢ß();®(i=0;i<£¡.¯;i++)£¡[i].¤º()};¢ã=¢(¿,Á){¥ ê(¿.¾,Á)};£ ££=[];¢ ¤¾(){¤.¢â=¢(¨){·.û=¶ ç(§ë+¢®+§ì,§í);·.¤¨=¶ ç(§î+¢®+§­+¢­+§ï,§í);Ò.û=¶ ç(§ð+¢­+§ñ,§í);¥ ¨.¬(Ã.û,Ã.ID).¬(Ò.û,Ò.ID).¬(·.û,·.ID)};¤.£©=¢(¨){ñ.û=¶ ç(§ò+¢¬+§ó+¢¬+§ô,§í);¥ ¨.¬(ñ.û,ñ.ID).¬(¦Ûg,¢($){¥ §õ+(¸(££,$)-1)+§ö}).¬(¦Üg,§¸).¬(¦Ýg,¢(§,À,×){¥ À.£¨(§ª).¢Ü(×)+×})};¤.£§=¢(¨){¥ ¨.¬(¦Þg,¢($,$1){¥ ££[$1]})}};¢ _·(){¤.È=¢(){¥ §µ+¤.¢Ç};¤.æ=¢(¡){¡.¢Ý+=§²+¤.¢Ç};¤.¤©=¢(¡){¡.¢Ý=¡.¢Ý.¬(¤.¢¾,¦ô)};¤.¢ß=¢(){£ §=ü(¤.´);®(£ i=0;i<§.¯;i++)¤.æ(§[i])}};¢ ·(´,¨){¤.id=ª.¢á.¯;¤.¢Ç=·.¢ø+¤.id;¤.´=´;¤.¢¾=¶ ç(§÷+¤.¢Ç+§ø,§í);¸(ª.¢á,¤)};·.£Ú=_·;·.¢ª=¶ _·;·.¢ø=§ù;·.ID=¢(§){¥ £Õ(§)+¶ ·(§)};¢ _Ò(){¤.¢ß=¢(){£ §=ü(¤.¢°);®(£ i=0;i<§.¯;i++){£ º=(¤.º)?ü(¤.º,§[i]):[§[i]];if(º)¤.¢¯(§[i],º,¤)}}};_Ò.¢ª=¶ _·;¢ Ò(´,¢°,¢¯,º){¤.¢°=¢°;¤.¢¯=¢­[¢¯];¤.º=º;¤.£¢=·;¤.£¢(´)};Ò.£Ú=_Ò;Ò.¢ª=¶ _Ò;Ò.ID=¢(§,¢°,¢¯,º){if(¢±&&¢¯!=§ú&&¤½.µ(¢°)&&!¦ß.µ(º))¥ §;¥ £Õ(§)+¶ Ò(§,¢°,¢¯,º)};£¦+=§û;£ ¤·=¦àg;¢ ¤¶(§,£Ü){¥ Ü(§ü+§ý.Æ(£Ü.¯)+£Ü+§½)};£ £¡=[];¢ _Ã(){¤.Å=¢Þ;¤.È=¢(){¥ ¦ô};¤.¥Ã=0;¢ ¤¸(¢Ä,Å,¨){£ ÿ=¥Â(¢(){¢Æ{if(!¢Ä.ê)¥;¢Ä.ê(¢Ä,Å,¨);¤»(ÿ)}¢·(£¥){¤»(ÿ)}},10)};¤.¤º=¢(){if(¤.Å==¢Þ)¥;®(£ i=0;i<¤.§.¯;i++){£ º=¤.§[i];£ ¢Å=º.¦[¤.³];if(¢Å){£ ½=º.£Ì?º:º.½;£ £¤=¦á.µ(¤.Å);£ ¡=².£Û(£¤?Ã.¤³:§Â);¡.¢ÿ=Ö;¡.¦.¨=¢Å.¨;if(!£¤)¡.¥Á=¢Å.Å;if(¤.³==§þ){½.¥À(¡,½.¤¹)}Û{½.¢»(¡)}if(£¤)¤¸(¡,¢Å.Å,¢Å.¨);º.¦[¤.³]=¢Þ}}};¤.¢ß=¢(){¤.§=ü(¤.´);®(£ i=0;i<¤.§.¯;i++){£ ¦=¤.§[i].¦;if(!¦[¤.³])¦[¤.³]={¨:¦ô};¦[¤.³].¨+=§ÿ+¤.¨;if(¤.Å!=¢Þ)¦[¤.³].Å=¤.Å}}};_Ã.¢ª=¶ _·;¢ Ã(´,³,¨){¤.³=³;¤.¨=££[¨].Æ(1,-1);£ Å=¤.¨.§(Ã.¤´);if(Å)¤.Å=¢ö(Å[1]).¬(¤·,¤¶);¤.£¢=·;¤.£¢(´);¸(£¡,¤)};Ã.£Ú=_Ã;Ã.¢ª=¶ _Ã;Ã.ID=¢(§,´,³,¨){¥ ¶ Ã(´,³,¨)};Ã.û=¦âg;Ã.¤´=¦ã;Ã.¤³=¨¡+¢À(¨¢,Á)+¨£;ò[§Ç]=¢(¼,­,±,Ê){®(£ i=0;i<­.¯;i++){£ ó=­[i].¥º;®(£ j=0;j<ó.¯;j++)if(£Ù(ó[j],±,Ê))¸(¼,ó[j])}};ò[¨¤]=¢(¼,­,±,Ê){®(£ i=0;i<­.¯;i++){£ ¢ý=¢þ(­[i]);if(¢ý&&£Ù(¢ý,±,Ê))¸(¼,¢ý)}};ò[¨¥]=¢(¼,­,±){±=¢ú[±];®(£ i=0;i<­.¯;i++)if(±(­[i]))¸(¼,­[i])};¢®[¨¦]=¢(¡){¥!¤²(¡)};¢®[¨§]=¢(¡,É){É=¶ ç(¨¨+É,¨©);Ý(¡&&!¡.£×(¨§))¡=¡.¢ü;¥ ¡&&É.µ(¡.£×(¨§))};¢­.¢Ù=¢(¡){£ Â=í;Ó(¡,¨ª,¢(){ª.Ð.¢Ù.¢Û(Â)});Ó(¡,¨«,¢(){ª.Ð.¢Ù.¢Ú(Â)})};¢­.¢÷=¢(¡){£ Â=í;Ó(¡,¨¬,¢(){ª.Ð.¢÷.¢Û(Â)})};¢­.¢Á=¢(¡){£ Â=í;Ó(¡,¨­,¢(){ª.Ð.¢Á.¢Û(Â)});Ó(¡,¨®,¢(){ª.Ð.¢Á.¢Ú(Â)});if(¡==².¥²){ª.Ð.¢Á.¢Û(Â)}};Ó(²,¨¯,¢(){£ ú=ª.Ð.¢÷;£ Ù=ú.Ù,i;®(i in Ù)ú.¢Ú(Ù[i]);ú=ª.Ð.¢Ù;Ù=ú.Ù;®(i in Ù)if(!Ù[i][0].£õ(£ü.¥°))ú.¢Ú(Ù[i])});£ ¢ú=[];£ ¤«=¦äg;¢ ñ(Ä,¢Â,©){©=¢ö(©);¤.id=¢ú.¯;£ò(Ä.¥¯()){¢¦ ¨°:Ä=¨±;¤­;¢¦ ¨²:Ä=¨³;¤­;£ñ:Ä=¨´+Ä+¨µ}¢Â=¢¬[¢Â];¸(¢ú,¶ ¤¬(¨¶,¨·+¢Â(Ä,©)))};ñ.ID=¢(§,Ä,¢Â,©){¥ ¶ ñ(Ä,¢Â,©)};ñ.¢ª.È=¢(){¥ ñ.¢ø+¤.id};¢¬={È:¢(){£ È=[];®(£ i in ¤)if(i&&i!=¨¸)¸(È,i);¥ È.¢Ü(¦ô).¬(¦åg,¦ô)},¢ù:¢(©){¥ ©.¬(¤«,¨¹)},¦ô:¢(Ä){¥ Ä},¨º:¢(Ä,©){¥ Ä+¨»+¤ª(©)},¨¼:¢(Ä,©){¥ ¨½+¢¬.¢ù(©)+¨¾+Ä+§®},¨¿:¢(Ä,©){¥ ¨À+¢¬.¢ù(©)+¨Á+Ä+§®}};ñ.¢ø=¨¥;¢ _ú(){¤.¢Û=¢(Â){£ ¡=Â[0];£ º=Â[1];£ ·=Â[2];®(£ i=0;i<º.¯;i++)·.æ(º[i]);¤.Ù[·.id+¡.¢«]=Â};¤.¢Ú=¢(Â){£ ¡=Â[0];£ º=Â[1];£ ·=Â[2];®(£ i=0;i<º.¯;i++)·.¤©(º[i]);£Ö ¤.Ù[·.id+¡.¢«]}};ª.Ð=¢(Õ){¤.Õ=Õ;¤.Ù={};ª.Ð[Õ]=¤};ª.Ð.¢ª=¶ _ú;¶ ª.Ð(¨Â);¶ ª.Ð(¨Ã);¶ ª.Ð(§ú);¢ £Õ(´){¥ ´.¬(·.¤¨,¦ô).¬(¤§,§²)}},Ö);ª.¢©(¨Ä,¢(){if(á<5.5)¥;£ £Ô=¨Å;£ £ý=(¦æ.µ(¤¥.¥©))?¢À(¨Æ,Á):¨Ç;£ £Ó=¶ ç((¢¡.¤ý||¨È)+¨É,¨©);¢ £þ(¡,î){¡.¦.±=£Ô.¬(¦ç,î)};£ ¢¾=¦ègi;à.¢¿(¢¾,¢ ¬(§,¢õ,¤¡,Ô,£ÿ){Ô=¢ö(Ô);¥ £Ó.µ(Ô)?¨Ê+£Ô.¬(¦é,¨Ë).¬(¦ç,Ô)+¨Ì+(¢õ||¦ô)+§¸+(¤¡||¦ô)+¨Í+(£ÿ||¦ô):§});if(¢½){¢ £Ò(¡){if(£Ó.µ(¡.î)){£ °=¡.°,÷=¡.÷;£þ(¡,¡.î);¡.î=£ý;¡.°=°;¡.÷=÷}Û ¡.¦.±=¦ô};¢½.æ(¨Î,¢(¡){if(¡.Ï==¨Ï&&¡.Õ!=¨Ð)¥;£Ò(¡);Ó(¡,¨Ñ,¢(){if(£ü.£Ê==¨Ò)£Ò(¡)})})}});ª.¢©(¨Ó,¢(){£ ¢Ö=¦Ì;à.ï(¨Ô,¢¢);à.ï(¨Õ,¢£);£ ß=².ß;£ Þ$=(¢§)?¨Ö:¨×;£ Þ=Ü(Þ$);¢ ¢ñ(){if(ß.«.£Î!=§Ú){if(ß.«.£Í==¨Í){ß.¦.£Í=¨Ø+¢ô.¤÷+§®}ß.¦.£Î=§Ú}¢ñ=¢Ø};£ ¹=£Ï(¨Ù);¢ ¢º(£ú){¥ ¢ó(£ú).¬(¦Õg,§æ).¬(¦Ög,§ç).¬(¦Óg,§ä).¬(¦êg,¨Ú)};¢ ¢£(¡){if(¡.«.£Î!=§Ú)¥;if(!¡.£õ(ß)){¢ñ();¢£[¢£.Ë++]=¡;£Ë(¡);¤ö(¡);£Â(¡)}};¢£.Ë=0;¢ £Â(¡){¹.î=¡.«.£Í.Æ(5,-2);£ ½=(¡.£Ì)?¡:¡.½;½.¢»(¹);£È(¡);¤õ(¡);½.¢Õ(¹)};¢ £Ë(¡){¡.Ì.¢×=¡.«.¢×;if(!ö(¡)){£ £ô=¨Û+Þ$+¨Ü;¡.¦.£ð(¨Ý,£ô)}};Ü(¢º(£Ë));¢ £È(¡){£ £Ê=ö(¡)?¨Ý:¨Þ;¡.¦[£Ê]=£Ç(¡,¡.Ì.¢×)-¡.£É().À-¡.¤ô};Ü(¢º(£È));¢ ö(¡){if(!¡)¥ ë;if(¡.Ì.³==§Ú||¡.«.³==§Ú)¥ Ö;¥ í.£ó(¡.½)};¢ £Ç(¡,³){£ò(³){¢¦ ¨ß:¢¦ §ç:¥ 0;¢¦ §â:¢¦ §é:¥ Þ.Í-¹.¢¼;¢¦ ¨à:¥(Þ.Í-¹.¢¼)/2;£ñ:if(¢Ö.µ(³)){¥ ø((Þ.Í-¹.¢¼)*£Æ(³)/100)}¹.Ì.À=³;¥ ¹.¢¤}};Ü(¢º(£Ç));¢ ¢¢(¡){if(¡.«.³!=§Ú)¥;¢ñ();¢¢[¢¢.Ë++]=¡;¡.Ì.³=§Ú;¡.¦.³=§á;£Á(¡)};¢¢.Ë=0;¢ £Á(¡,Ø){£Å(¡,Ø);¤ò(¡,Ø);if(!Ø||¡.¦.¤ñ){if(ø(¡.«.¢î)==0)¡.¦.¤ð++}};¢ £Å(¡,Ø){if(!Ø&&¢Ö.µ(¡.«.°))¡.¦.ì=¡.«.°;if(¡.¦.ì)¡.¦.°=ø(£Æ(¡.¦.ì)/100*Þ.Í);if(Ø){if(!¡.¦.£Ä)¥}Û{¡.¦.£Ä=¡.«.×!=§Ý&&¡.«.À==§Ý}¡.¦.À=¦ô;¡.¦.¢Ô=¢¹(¡);if(¡.«.¢ï!=§Ý){¡.½.¢»(¹);¹.Ì.À=¡.«.¢ï;¡.¦.¢Ô-=¹.¢¤;¡.½.¢Õ(¹)}if(ö(¡.¢¥))¡.¦.£ï=¡.¦.¢Ô;Û if(!Ø)¡.¦.£ð(¨á,¨â+Þ$+¨ã)};Ü(¢º(£Å).¬(¦Øg,§é).¬(¦Ôg,§å));¢ ¢¹(¡){£ ¢¹=¡.¢¤,£Ã=ë;£ Ç=ö(¡.¢¥)&&¡.¦.£Ä;Ý(¡=¡.¢¥){if(!Ç&&¡.«.³!=¨ä)£Ã=Ö;¢¹+=¡.¢¤*(£Ã?-1:1)}¥ ¢¹};Ü(¢º(¢¹));¢ £ì(){®(£ i=0;i<¢£.Ë;i++)£Â(¢£[i]);®(i=0;i<¢¢.Ë;i++)£Á(¢¢[i],Ö);ÿ=0};£ ÿ;Ó(¢¡,§ã,¢(){if(!ÿ)ÿ=¢Ó(£ì,10)})});¢í=Ö;if(².£À==¦ú)_ê();Û Ó(²,¨å,¢(){if(!¢¸&&².£À==¦ú)¢Ó(_ê,0)})}¢·(¢ë){¢ì();¢¶(¨æ+¢ë.£ë)}£¾{}}();',493,0,/./,String,95,'element`function`var`this`return`runtimeStyle`match`cssText`value`IE7`currentStyle`replace`from`for`length`width`filter`document`position`selector`test`new`Class`push`ie7_tmp`target`x5cs`filtered`parentElement`href`styleSheet`left`path`instance`PseudoElement`attribute`content`slice`fixed`toString`filterArgs`scopeName`count`style`clientWidth`ie7`tagName`Event`x5c`DynamicStyle`addEventHandler`url`type`true`right`recalc`instances`minWidth`else`eval`while`viewport`body`CSSFixes`appVersion`link`layoutParent`fixedWidth`auto`add`RegExp`fixes`styleSheets`load`false`fixWidth`arguments`src`addRecalc`input`AttributeSelector`selectors`subset`recalcs`nextSibling`isFixed`height`parseInt`documentElement`ie7Event`ALL`cssQuery`maxWidth`handler`timer`window`positionFixed`backgroundFixed`offsetLeft`offsetParent`case`quirksMode`x5cw`addModule`prototype`uniqueID`attributeTests`dynamicPseudoClasses`pseudoClasses`dynamicPseudoClass`attach`isHTML`fixRight`token`SIZES`pattern`alert`catch`complete`getScreenLeft`topFunction`appendChild`offsetWidth`HTMLFixes`MATCH`addFix`makePath`focus`compare`x5cd`object`pseudoElement`try`name`visited`getPixelWidth`boxSizing`getFixedWidth`all`elements`isElement`pseudoClass`cacheSelector`modules`script`setTimeout`screenLeft`removeChild`PERCENT`backgroundPositionX`DUMMY`hover`unregister`register`join`className`null`exec`display`classes`parse`getCSSText`getPixelLeft`wider`max`disabled`cssCache`node`Boolean`error`unHide`loaded`bottom`marginLeft`absolute`fixBackground`top`String`location`image`getString`active`PREFIX`escape`attributeSelectors`x2f`parentNode`adjacent`nextElement`ie7_anon`pseudoElements`inherit`encoded`isURL`ignore`HEADER`decode`split`encode`resizeWidth`NUMERIC`rect`min`hasLayout`outerHTML`apply`fixedElement`QUOTED`handlers`pop`strings`string`item`small`getPath`styles`pathname`array`httpRequest`finally`Error`readyState`foregroundPosition`backgroundPosition`nested`autoLeft`positionLeft`parseFloat`getOffsetLeft`setOffsetLeft`getBoundingClientRect`propertyName`backgroundLeft`canHaveChildren`backgroundImage`backgroundAttachment`tmpElement`none`background`fixImg`pngTest`FILTER`simpleSelector`delete`getAttribute`lang`compareTagName`ancestor`createElement`code`PIXEL`resizeRight`getPaddingWidth`getBorderWidth`box`submit`clicked`fix`select`useCache`base`large`inlineStyles`LINKS`description`resize`onresize`scrollLeft`pixelLeft`setExpression`default`switch`callee`expression`contains`Height`Width`Top`Left`leftFunction`img`event`NULL`addFilter`suffix`prefix`scale`png`define`navigator`Microsoft`CHILD`COMPLEX`remove`quote`ESCAPE`Function`break`ie7_`x5cb`class`ms_`previousElement`OBJECT`CONTENT`before`unicode`HEX`addTimer`firstChild`create`clearInterval`inline`ANCHOR`Parser`parser`removeTempElement`HEIGHT`getMarginWidth`AUTO`minHeight`marginRight`UNIT`toUpperCase`charAt`BUTTON`UNSUCCESSFUL`button`abbr`htmlFor`HTML`endTag`firstChildElement`continue`block`marginTop`fixMargins`removeEventHandler`attachEvent`key`getElementsByTagName`selectById`NAMESPACE`STREAM`STANDARD_SELECT`toStream`ASTERISK`IMPLIED_SELECTOR`reg`loadStyleSheet`imports`MEDIA`innerHTML`lastIndexOf`URL`fixUrls`scripts`RELATIVE`autoload`mimeType`search`message`onreadystatechange`static`screenTop`autoTop`positionTop`center`clientLeft`setOffsetTop`backgroundTop`protocol`onpropertychange`INPUT`zoom`crop`trans`IE7_PNG_SUFFIX`x00`x_bits`char`x5cnstatic`x_height`x5cn`x_width`javascript`gif`blank`userAgent`bSV1`sizingMethod`AlphaImageLoader`DXImageTransform`progid`toLowerCase`srcElement`onmouseup`activeElement`onblur`onfocus`onmousedown`onmouseout`onmouseover`child`first`children`scriptlet`text`htm`data`after`insertBefore`innerText`setInterval`specificity`x5cu`align`vertical`with`css2`fixHeight`Bottom`Right`paddingRight`paddingLeft`Math`model`onsubmit`reset`form`onclick`textarea`label`xhtml`org`www`http`namespaces`replaceChild`html4`previousSibling`nodeType`clip`border`padding`unquote`contentEditable`onbeforeunload`detachEvent`import`namespace`concat`Array`constructor`size`font`medium`list`float`relative`sizing`lastIndex`successfully`media`ball`bscreen`write`createStyleSheet`ie5`file`not`could`responseText`send`GET`open`XMLHTTP`ActiveXObject`margin`Document`XML`xml`unknown`typeof`CSS1Compat`compatMode`ie7_off`MSIE`ie7_debug`alpha`version`visible`visibility`fromCharCode`¦®`¦­ (\\d\\.\\d)`¦¬`^¤±`\\.¦§$`^[\\w\\.]+[^:]*$`(Ô\\([\x27"]?)([\\w\\.]+[^:\\)]*[\x27"]?\\))`\\¥ö\\b|\\¥õ\\b|^$`Î-â`(¥ï\\s*:\\s*(À|×))`¢à\\s*:\\s*¥î-£·`^[^>\\+~\\s]`[\\s>\\+~:@#\\.\\(\\)]|[^\\s>\\+~:@#\\.\\(\\)]+`\\|`([\\s>~\\,]|[^(]\\+|^)([\\.:#@])`(\\¢û\\*[^\\*]*\\*+([^\\¢û][^\\*]*\\*+)*\\¢û)|(\x27[^\x27]*\x27)|("[^"]*")`@(¥ç|¥æ)[^;\\n]+[;\\n]|<!\\-\\-|\\-\\->`\\Ñ:`^\\s+|\\s*([\\{\\}\\+\\,>~\\s;])\\s*|\\s+$`\x27(\\d+)\x27`(\x27[^\x27]*\x27)|("[^"]*")` ©="([^"]*)"`^(£â|¥Ñ|¤Ë)$`^\\d\\w*$`^\\d+%$`^\\d+(px)?$`\\b(£­|¢æ)-(°|÷)\\s*:\\s*\\d`\\b(£­|¢æ)-°\\s*:\\s*\\d`^å|0cm$`^å$`£­`£÷`°`£ù`À`¥Ë`×`>`(\\ba(\\.[\\w-]+)?)$`\\{[^\\}]*\\}`::`([^\\}\\s]*\\,[^\\{]*)(\\{\\d+\\})`\\{(\\d+)\\}`[+>~]`\\Ñ([a-fA-F\\d]+)`^Ô\\(.*\\)$`([^}]*):(¤µ|¥¿)[^{]*\\{([^}]*)\\}`Å\\s*:\\s*([^;]*)(;|$)`([\\¢û()[\\]?{}|*+])`=`\\¥ª\\b`%1`£Ñ(-¢õ)?\\s*:([^(};]*)Ô\\(([^\\)]+)\\)([^;}]*)`¤¢`X`¦±`ª ¦° 0.7.3 (¦¯)`\\n\\n`¦ª`¦¨`¦¦ ¦¥`:â{Î-â:â}:¢È{Î-â:¢È}`*{¦¤:0}`¢Ò=``/`¤¦.¦¢`¥ÿ`£¿ [1]: ¥ü ¥û ê ¥ú `Î-¥ù.js`¢¸`<Ì></Ì>`$1`$2`Ì`¢í ¥ó`£¿ [2]: `([^{}]*)\\Ñ{([^}]*[^\\¢¨-])?`gi`£á-¥ñ\\»*:\\»*Å-£á`³\\»*:\\»*¢ð`¥ð`¢à:¤¼;$1`¢à:¤Ò`xx-£¸,x-£¸,£¸,¥í,£è,x-£è,xx-£è`,`xx-£¸`(¥ì(-¥ë)?\\»*:\\»*)(`|`)`$1*$2` *#`(` `*`#`.`(^|\\»)`(\\»|$)`:`â`¢È`\\Ñ([^)]*\\Ñ)`Î-â`\x27`\\Ñ:`¥ä`¢Ä`³:¢ð;¥á:0;¢à:¤Ò;¥à:£Ð;¥ß:£¬(0 0 0 0);À:-9999`!`Î-¥Ü`<¤Î:`/>`</`>`¤Î`¥Ù://¥Ø.w3.¥×/1999/¥Ö`¥Õ`ð,£å,¥Ô`¤Ì` ¤Ì`¤Ë,ð`¤É`£â`¥Ó`².¢Ì.`.¦.£ã=ë`¥Ò`¥Ð`.¢ç=ë`.©=\x27`Î-£á-¥Ï`\\»*:\\»*\\¢Ã[\\¢¨%]*`Ç`HR`°\\»*:\\»*\\¢Ã\\¢¨*[^%]`å`£­-°`¢æ`¢æ-°`¢ð`×`£í`£ö`÷`£ø`¢ò`¥Ê`¢î`Î-¥È`[^},\\»]*([>+~][^:@,\\»{]+|:(`)|\\Ñ.[\\¢¨-]+\\Ñ.[\\¢¨-.]+|@[@\\¢Ã]+)`g`[^\\»(]+[+~]|@\\¢Ã+|:(â|¢È|`)|\\Ñ.[\\¢¨-.]+`([^}]*):(`)([^{]*)`\\Ñ[([^`=\\Ñ]]+)([`]?=?)([^\\Ñ]]+)?\\Ñ]`{`}`\\»`\\¤¯`¤®`¢Á`.¢ÿ{¥Æ-¥Å:¢ò;¢à:¤¼}`\x27\\¥Ä`0000`¤µ`;`<¢Ä ¤°=¢ÿ ¥¾=\x27`Î-Å.¥½`\x27 °=100% ÷=0 Õ=¥¼/x-¥»>`+`@`¥¹-¥¸`£Ø`^`i`¥·`¥¶`¥µ`¥´`¥³`¥±`id`¡.id.¬(/¤±\\¢Ã+/g,\x27\x27)`¤°`¡.¢Ý.¬(/\\¤¯\\»*¤®\\¢Ã+/g,\x27\x27)`¡.£×(\x27`\x27)`¡`¥ `¢ù`\\Ñ$1`=`==`~=`/(^|\\»)`(\\»|$)/.µ(`|=`/^`(-|$)/.µ(`¢Ù`¢÷`Î-¤£`¥®:¥­.¤¦.¥¬(î=%1,¥«=\x27¤¢\x27)`¥¨.¥§`¥¦:\x27#¤¤ ¥¥ 1\\¥¤#¤¤ ¥£ 1\\¥¢ ¥¡ ¤ÿ[]={0¤þ}\x27`-¤ü.¤£`$`±:`¤û`;¤ú:1;£Ñ`£Ð`£û,ð`¤ù`¢õ`¤ø`î`Î-Ç`³\\»*:\\»*Ç`£Ñ[\\¢¨\\»-]*:[^};]*Ç`ß`ù`Ô(`£û`Y`(ø(¦.¢¤)+².`.£î)||0`¢×`¢¤`À`¤ó`£ï`¦.¢Ô+².`.£î`¤ï`¤î`£¿ [0]: '.split('\x60')));
+/* packed with http://dean.edwards.name/packer/ */
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-standard.js b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-standard.js
new file mode 100644
index 0000000..2109905
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/ie7-standard.js
@@ -0,0 +1,2 @@
+/* IE7 version 0.7.3 (alpha) 2004/09/18 */
+if(!window.IE7)new function(){try{window.IE7=this;var DUMMY=this.addModule=new Function;function unHide(){if(document.body)document.body.style.visibility="visible"};this.toString=function(){return "IE7 version 0.7.3 (alpha)"};var alert=(/ie7_debug/.test(location.search))?function(message){window.alert(IE7+"\n\n"+message)}:DUMMY;var appVersion=navigator.appVersion.match(/MSIE (\d\.\d)/)[1];if(/ie7_off/.test(location.search)||appVersion<5||!/^ms_/.test(document.documentElement.uniqueID))return unHide();var quirksMode=Boolean(document.compatMode!="CSS1Compat");var isHTML=(typeof document.mimeType=="unknown")?!/\.xml$/i.test(location.pathname):Boolean(document.mimeType!="XML Document");var LINKS=":link{ie7-link:link}:visited{ie7-link:visited}";var HEADER=LINKS;if(!isHTML)HEADER+="*{margin:0}";var HTMLFixes;var documentElement=document.documentElement;var modules={};this.addModule=function(name,script,autoload){if(!modules)return;if(loaded)eval("script="+String(script));if(autoload){script();script=DUMMY}modules[name]=script};var RELATIVE=/^[\w\.]+[^:]*$/;function makePath(href,path){if(RELATIVE.test(href))href=(path||"")+href;return href};function getPath(href,path){href=makePath(href,path);return href.slice(0,href.lastIndexOf("/")+1)};var path=getPath(document.scripts[document.scripts.length-1].src);var httpRequest=new ActiveXObject("Microsoft.XMLHTTP");function load(href,path){try{href=makePath(href,path);httpRequest.open("GET",href,false);httpRequest.send();return httpRequest.responseText}catch(ignore){alert("Error [1]: could not load file "+href);return ""}};var push=function(array,item){return array.push(item)};var pop=function(array){return array.pop()};if(appVersion<5.5)eval(load("ie7-ie5.js",path));if(document.readyState=="complete"||!isHTML)document.createStyleSheet();else document.write("<style></style>");this.styleSheet=document.styleSheets[document.styleSheets.length-1];this.styleSheet.cssText=LINKS;this.styleSheet.ie7=true;var cssText={};function loadStyleSheet(styleSheet,path){var url=makePath(styleSheet.href,path);if(cssText[url])return "";cssText[url]=(styleSheet.disabled)?"":fixUrls(getCSSText(styleSheet,path),getPath(styleSheet.href,path));return cssText[url]};var getCSSText=function(styleSheet){return styleSheet.cssText};var URL=/(url\(['"]?)([\w\.]+[^:\)]*['"]?\))/gi;function fixUrls(cssText,pathname){return cssText.replace(URL,"$1"+pathname.slice(0,pathname.lastIndexOf("/")+1)+"$2")};this.recalcs=[];this.parse=DUMMY;var complete=false;function _load(){try{complete=true;var MEDIA=/\bscreen\b|\ball\b|^$/i;var styleSheets=document.styleSheets;var inlineStyles=[];var styles=document.getElementsByTagName("style");for(var i=styles.length-1;i>=0;i--){push(inlineStyles,/ie7-link/.test(styles[i].innerHTML)?"":styles[i].innerHTML)}function getCSSText(styleSheet,path){var cssText="";if(MEDIA.test(styleSheet.media)){for(var i=0;i<styleSheet.imports.length;i++){cssText+=arguments.callee(styleSheet.imports[i],getPath(styleSheet.href,path))}cssText+=((styleSheet.href)?loadStyleSheet(styleSheet,path):pop(inlineStyles))}return cssText};IE7.cssText="";for(i=0;i<styleSheets.length;i++)IE7.cssText+=getCSSText(styleSheets[i],"");IE7.cssText=encode(IE7.cssText);for(i in modules)modules[i]();delete modules;if(HTMLFixes)HTMLFixes.apply();CSSFixes.apply();IE7.parse();IE7.styleSheet.cssText=HEADER+decode(IE7.cssText);for(i=0;i<styleSheets.length;i++){if(!styleSheets[i].disabled&&!styleSheets[i].ie7)styleSheets[i].cssText=""}IE7.recalc();alert("loaded successfully")}catch(error){alert("Error [2]: "+error.description)}finally{unHide()}};this.recalc=function(){CSSFixes.recalc();for(var i=0;i<this.recalcs.length;i++)this.recalcs[i]()};var CSSFixes=new function(){var fixes=[];this.addFix=function(){push(fixes,arguments)};var recalcs=[];this.addRecalc=function(pattern,fix){var reg=new RegExp("([^{}]*)\x5c{([^}]*[^\x5cw-])?"+pattern,"gi");var cssText=IE7.cssText;pattern=[];while(match=reg.exec(cssText)){push(pattern,match[1]);if(appVersion<5.5)cssText=cssText.slice(match.lastIndex)}if(pattern.length){pattern=pattern.toString();push(recalcs,arguments)}};this.apply=function(){for(var i=0;i<fixes.length;i++){IE7.cssText=IE7.cssText.replace(fixes[i][0],fixes[i][1])}this.addRecalc("box-sizing\x5cs*:\x5cs*content-box",boxSizing);this.addRecalc("position\x5cs*:\x5cs*absolute",function(element){if(element.offsetParent.currentStyle.position=="relative")boxSizing(element.offsetParent)})};this.recalc=function(){for(var i=0;i<recalcs.length;i++){var elements=cssQuery(recalcs[i][0]);for(var j=0;j<elements.length;j++)recalcs[i][1](elements[j])}};this.addFix(/(float\s*:\s*(left|right))/gi,"display:inline;$1");if(appVersion<6)this.addFix(/display\s*:\s*list-item/gi,"display:block");if(quirksMode){var SIZES="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");for(var i=0;i<SIZES.length;i++)SIZES[SIZES[i]]=SIZES[i-1]||"xx-small";function replace($,$1,$2,$3){return $1+SIZES[$3]};this.addFix(new RegExp("(font(-size)?\x5cs*:\x5cs*)("+SIZES.join("|")+")","gi"),replace)}};var STANDARD_SELECT=/^[^>\+~\s]/;var STREAM=/[\s>\+~:@#\.\(\)]|[^\s>\+~:@#\.\(\)]+/g;var NAMESPACE=/\|/;var IMPLIED_SELECTOR=/([\s>~\,]|[^(]\+|^)([\.:#@])/g;var ASTERISK="$1*$2";var cssCache={};function cssQuery(selector,from){var useCache=!from;var base=(from)?(from.constructor==Array)?from:[from]:[document];var selectors=selector.replace(IMPLIED_SELECTOR,ASTERISK).split(",");var match=[];for(var i=0;i<selectors.length;i++){selector=toStream(selectors[i]);if(selector.slice(0,3).join("")==" *#"){selector=selector.slice(2);from=selectById(base,selector[1])}else from=base;var j=0,token,filter,filterArgs,cacheSelector="";while(j<selector.length){token=selector[j++];filter=selector[j++];cacheSelector+=token+filter;filterArgs="";if(selector[j]=="("){while(selector[j++]!=")")filterArgs+=selector[j];filterArgs=filterArgs.slice(0,-1);cacheSelector+="("+filterArgs+")"}from=(useCache&&cssCache[cacheSelector])?cssCache[cacheSelector]:select(from,token,filter,filterArgs);if(useCache)cssCache[cacheSelector]=from}match=match.concat(from)}return match};function toStream(selector){if(STANDARD_SELECT.test(selector))selector=" "+selector;return selector.match(STREAM)};function select(from,token,filter,filterArgs){var scopeName="";if(NAMESPACE.test(filter)){filter=filter.split("|");scopeName=filter[0];filter=filter[1]}var filtered=[];if(selectors[token])selectors[token](filtered,from,filter,scopeName||filterArgs);return filtered};function selectById(from,id){var filtered=[],i,j;for(i=0;i<from.length;i++){var match=from[i].all.item(id);if(match){if(match.length==null)push(filtered,match);else for(j=0;j<match.length;j++)push(filtered,match[j])}}return filtered};var selectors={" ":function(filtered,from,filter,scopeName){for(var i=0;i<from.length;i++){var subset=(filter=="*"&&from[i].all)?from[i].all:from[i].getElementsByTagName(filter);for(var j=0;j<subset.length;j++){if(isElement(subset[j])&&(!scopeName||subset[j].scopeName==scopeName))push(filtered,subset[j])}}},"#":function(filtered,from,filter){for(var i=0;i<from.length;i++)if(from[i].id==filter)push(filtered,from[i])},".":function(filtered,from,filter){filter=new RegExp("(^|\x5cs)"+filter+"(\x5cs|$)");for(var i=0;i<from.length;i++)if(filter.test(from[i].className))push(filtered,from[i])},":":function(filtered,from,filter,filterArgs){filter=pseudoClasses[filter];if(filter)for(var i=0;i<from.length;i++)if(filter(from[i],filterArgs))push(filtered,from[i])}};var attributeTests="";var pseudoClasses={toString:function(){var toString=[];for(var pseudoClass in this){if(pseudoClass!="link"&&pseudoClass!="visited"){if(this[pseudoClass].length>1)pseudoClass+="\x5c([^)]*\x5c)";push(toString,pseudoClass)}}return toString.join("|")},"link":function(element){return Boolean(element.currentStyle["ie7-link"]=="link")},"visited":function(element){return Boolean(element.currentStyle["ie7-link"]=="visited")}};var dynamicPseudoClasses={toString:pseudoClasses.toString};function compareTagName(element,tagName,scopeName){if(scopeName&&element.scopeName!=scopeName)return false;return(tagName=="*")?isElement(element):(isHTML)?(element.tagName==tagName.toUpperCase()):(element.tagName==tagName)};var strings=[];function getString(string){return QUOTED.test(string)?strings[string.slice(1,-1)]:string};var encode=function(cssText){return cssText.replace(/(\x2f\*[^\*]*\*+([^\x2f][^\*]*\*+)*\x2f)|('[^']*')|("[^"]*")/g,function(match){return(match.charAt(0)=="/")?"":"'"+(push(strings,match.slice(1,-1))-1)+"'"}).replace(/@(namespace|import)[^;\n]+[;\n]|<!\-\-|\-\->/g,"").replace(/\x5c:/g,"|").replace(/^\s+|\s*([\{\}\+\,>~\s;])\s*|\s+$/g,"$1")};function decode(cssText){return cssText.replace(/\|/g,"\x5c:").replace(/'(\d+)'/g,function(match,key){return strings[key]})};var handlers=[];function addEventHandler(element,type,handler){element.attachEvent(type,handler);push(handlers,arguments)};function removeEventHandler(element,type,handler){try{element.detachEvent(type,handler)}catch(ignore){}};window.attachEvent("onbeforeunload",function(){while(handlers.length){var handler=pop(handlers);removeEventHandler(handler[0],handler[1],handler[2])}});var hasLayout=(appVersion<6)?function(element){return element.clientWidth}:function(element){return element.currentStyle.hasLayout};function boxSizing(element){if(!hasLayout(element)){element.contentEditable=false;fixMargins(firstChildElement(element))}};function fixMargins(element){while(element){element.runtimeStyle.marginTop=element.currentStyle.marginTop;element=nextElement(element)}};var QUOTED=/('[^']*')|("[^"]*")/;function quote(value){return(QUOTED.test(value))?value:"'"+value+"'"};function unquote(value){return(QUOTED.test(value))?value.slice(1,-1):value};function tmpElement(tagName){var element=document.createElement(tagName||"object");element.style.cssText="position:absolute;padding:0;display:block;border:none;clip:rect(0 0 0 0);left:-9999";return element};function isElement(node){return Boolean(node&&node.nodeType==1&&node.tagName!="!"&&!node.ie7_anon)};function previousElement(element){while(element&&(element=element.previousSibling)&&!isElement(element))continue;return element};function nextElement(element){while(element&&(element=element.nextSibling)&&!isElement(element))continue;return element};function firstChildElement(element){element=element.firstChild;return(isElement(element))?element:nextElement(element)};var loaded=false;IE7.addModule("ie7-html4",function(){if(isHTML)HTMLFixes=new function(){var fixes=[];function fix(element){var fixedElement=document.createElement("<HTML:"+element.outerHTML.slice(1));if(element.outerHTML.slice(-2)!="/>"){var endTag="</"+element.tagName+">",nextSibling;while((nextSibling=element.nextSibling)&&nextSibling.outerHTML!=endTag){element.parentNode.removeChild(nextSibling);fixedElement.appendChild(nextSibling)}if(nextSibling)element.parentNode.removeChild(nextSibling)}element.parentNode.replaceChild(fixedElement,element);return fixedElement};this.add=function(){push(fixes,arguments)};this.apply=function(){try{if(appVersion>5)document.namespaces.add("HTML","http://www.w3.org/1999/xhtml")}catch(ignore){}finally{for(var i=0;i<fixes.length;i++){var elements=cssQuery(fixes[i][0]);for(var j=0;j<elements.length;j++)fixes[i][1](elements[j])}}};this.add("label",function(element){if(!element.htmlFor){var input=cssQuery("input,select,textarea",element)[0];if(input){if(!input.id)input.id=input.uniqueID;element.htmlFor=input.id}}});this.add("abbr",function(element){fix(element);delete cssCache[" abbr"]});this.add("button,input",function(element){if(element.tagName=="BUTTON"){var match=element.outerHTML.match(/ value="([^"]*)"/i);element.runtimeStyle.value=(match)?match[1]:""}if(element.type=="submit"){addEventHandler(element,"onclick",function(){element.runtimeStyle.clicked=true;setTimeout("document.all."+element.uniqueID+".runtimeStyle.clicked=false",1)})}});this.add("form",function(element){var UNSUCCESSFUL=/^(submit|reset|button)$/;addEventHandler(element,"onsubmit",function(){for(var i=0;i<element.length;i++){if(UNSUCCESSFUL.test(element[i].type)&&!element[i].disabled&&!element[i].runtimeStyle.clicked){element[i].disabled=true;setTimeout("document.all."+element[i].uniqueID+".disabled=false",1)}else if(element[i].tagName=="BUTTON"&&element[i].type=="submit"){setTimeout("document.all."+element[i].uniqueID+".value='"+element[i].value+"'",1);element[i].value=element[i].runtimeStyle.value}}})})}},true);IE7.addModule("ie7-box-model",function(){var NUMERIC="\x5cs*:\x5cs*\x5cd[\x5cw%]*",UNIT=/^\d\w*$/,PERCENT=/^\d+%$/,PIXEL=/^\d+(px)?$/;var MATCH=(appVersion<6)?/\b(min|max)-(width|height)\s*:\s*\d/gi:/\b(min|max)-width\s*:\s*\d/gi;var AUTO=(appVersion<5.5)?/^auto|0cm$/:/^auto$/;var ie7_tmp=tmpElement();push(IE7.recalcs,function removeTempElement(){if(ie7_tmp.parentElement)ie7_tmp.parentElement.removeChild(ie7_tmp)});CSSFixes.addFix(MATCH,function(match){return match.slice(0,3)+match.charAt(4).toUpperCase()+match.slice(5)});var viewport=(quirksMode)?document.body:documentElement;function isFixed(element){return element.style.position=="fixed"||element.currentStyle.position=="fixed"};function layoutParent(element){var layoutParent=element.offsetParent;while(layoutParent&&!hasLayout(layoutParent))layoutParent=layoutParent.offsetParent;if(!layoutParent||isFixed(element))layoutParent=viewport;return layoutParent};function fixWidth(HEIGHT){fixWidth=function(element,value){if(!element.runtimeStyle.fixedWidth&&(!isHTML||element.tagName!="HR")){if(!value)value=element.currentStyle.width;element.runtimeStyle.fixedWidth=(UNIT.test(value))?Math.max(0,getFixedWidth(element,value)):value;element.runtimeStyle.width=element.runtimeStyle.fixedWidth;boxSizing(element)}};if(quirksMode)CSSFixes.addRecalc("width\x5cs*:\x5cs*\x5cd\x5cw*[^%]",fixWidth);var getFixedWidth=(quirksMode)?function(element,value){return getPixelWidth(element,value)+getBorderWidth(element)+getPaddingWidth(element)}:function(element,value){return getPixelWidth(element,value)};function getBorderWidth(element){return element.offsetWidth-element.clientWidth};function getPaddingWidth(element){return getPixelWidth(element,element.currentStyle.paddingLeft)+getPixelWidth(element,element.currentStyle.paddingRight)};function getMarginWidth(element){return((element.currentStyle.marginLeft=="auto")?0:getPixelLeft(element,element.currentStyle.marginLeft))+((element.currentStyle.marginRight=="auto")?0:getPixelLeft(element,element.currentStyle.marginRight))};function minWidth(element){minWidth[minWidth.count++]=element;if(element.currentStyle.minHeight=="auto")element.runtimeStyle.minHeight=0;fixWidth(element);boxSizing(element);resizeWidth(element)};minWidth.count=0;CSSFixes.addRecalc("min-width"+NUMERIC,minWidth);eval(String(minWidth).replace(/min/g,"max"));maxWidth.count=0;CSSFixes.addRecalc("max-width"+NUMERIC,maxWidth);function resizeWidth(element){var rect=element.getBoundingClientRect();var width=rect.right-rect.left;if(element.currentStyle.maxWidth&&width>=getFixedWidth(element,element.currentStyle.maxWidth))element.runtimeStyle.width=getFixedWidth(element,element.currentStyle.maxWidth);else if(element.currentStyle.minWidth&&width<=getFixedWidth(element,element.currentStyle.minWidth))element.runtimeStyle.width=getFixedWidth(element,element.currentStyle.minWidth);else element.runtimeStyle.width=element.runtimeStyle.fixedWidth};function fixRight(element){if((element.currentStyle.position=="absolute"||element.currentStyle.position=="fixed")&&element.currentStyle.left!="auto"&&element.currentStyle.right!="auto"&&AUTO.test(element.currentStyle.width)){fixRight[fixRight.count++]=element;boxSizing(element);resizeRight(element)}};fixRight.count=0;CSSFixes.addRecalc("right"+NUMERIC,fixRight);function resizeRight(element){element.runtimeStyle.width="";var parentElement=layoutParent(element);var left=(element.runtimeStyle.screenLeft)?element.getBoundingClientRect().left-2:getPixelLeft(element,element.currentStyle.left);var width=parentElement.clientWidth-getPixelLeft(element,element.currentStyle.right)-left-getMarginWidth(element);if(!quirksMode)width-=getBorderWidth(element)+getPaddingWidth(element);if(width<0)width=0;if(isFixed(element)||HEIGHT||element.offsetWidth<width){element.runtimeStyle.fixedWidth=width;element.runtimeStyle.width=width}};var clientWidth=documentElement.clientWidth;addEventHandler(window,"onresize",function(){var i,wider=(clientWidth<documentElement.clientWidth);clientWidth=documentElement.clientWidth;for(i=0;i<minWidth.count;i++){var element=minWidth[i];var fixedWidth=(element.runtimeStyle.width==element.currentStyle.minWidth);if(wider&&fixedWidth)element.runtimeStyle.width="";if(wider==fixedWidth)resizeWidth(element)}for(i=0;i<maxWidth.count;i++){var element=maxWidth[i];var fixedWidth=(element.runtimeStyle.width==element.currentStyle.maxWidth);if(!wider&&fixedWidth)element.runtimeStyle.width="";if(wider!=fixedWidth)resizeWidth(element)}for(i=0;i<fixRight.count;i++)resizeRight(fixRight[i]);removeTempElement()});function getPixelWidth(element,value){if(PIXEL.test(value))return parseInt(value);if(PERCENT.test(value))return parseInt(parseFloat(value)/100*layoutParent(element).clientWidth);var parentElement=(element.canHaveChildren)?element:element.parentElement;parentElement.appendChild(ie7_tmp);ie7_tmp.style.width=value;return ie7_tmp.offsetWidth};function getPixelLeft(element,value){if(parseInt(value)>0)return getPixelWidth(element,value);if(PIXEL.test(value))return parseInt(value);element.parentElement.appendChild(ie7_tmp);ie7_tmp.style.left=value;return ie7_tmp.offsetLeft}};eval(String(fixWidth).replace(/Width/g,"Height").replace(/width/g,"height").replace(/Left/g,"Top").replace(/left/g,"top").replace(/Right/g,"Bottom").replace(/right/g,"bottom"));fixWidth();fixHeight(true)});IE7.addModule("ie7-css2",function(){var CHILD=/>/g,ANCHOR=/(\ba(\.[\w-]+)?)$/i;IE7.classes=[];IE7.parser=new Parser;IE7.Class=Class;IE7.DynamicStyle=DynamicStyle;IE7.PseudoElement=PseudoElement;IE7.parse=function(){with(this.parser)this.cssText=decode(parse(encode(this.cssText)));for(var i=0;i<IE7.classes.length;i++)IE7.classes[i].exec();for(i=0;i<pseudoElements.length;i++)pseudoElements[i].create()};getCSSText=function(styleSheet,path){return load(styleSheet.href,path)};var encoded=[];function Parser(){this.parse=function(cssText){Class.ALL=new RegExp("[^},\x5cs]*([>+~][^:@,\x5cs{]+|:("+pseudoClasses+")|\x5c.[\x5cw-]+\x5c.[\x5cw-.]+|@[@\x5cd]+)","g");Class.COMPLEX=new RegExp("[^\x5cs(]+[+~]|@\x5cd+|:(link|visited|"+pseudoClasses+"|"+dynamicPseudoClasses+")|\x5c.[\x5cw-.]+","g");DynamicStyle.ALL=new RegExp("([^}]*):("+dynamicPseudoClasses+")([^{]*)","g");return cssText.replace(PseudoElement.ALL,PseudoElement.ID).replace(DynamicStyle.ALL,DynamicStyle.ID).replace(Class.ALL,Class.ID)};this.encode=function(cssText){AttributeSelector.ALL=new RegExp("\x5c[([^"+attributeTests+"=\x5c]]+)(["+attributeTests+"]?=?)([^\x5c]]+)?\x5c]","g");return cssText.replace(AttributeSelector.ALL,AttributeSelector.ID).replace(/\{[^\}]*\}/g,function($){return "{"+(push(encoded,$)-1)+"}"}).replace(/::/g,":").replace(/([^\}\s]*\,[^\{]*)(\{\d+\})/g,function(match,left,right){return left.split(",").join(right)+right})};this.decode=function(cssText){return cssText.replace(/\{(\d+)\}/g,function($,$1){return encoded[$1]})}};function _Class(){this.toString=function(){return "."+this.name};this.add=function(element){element.className+=" "+this.name};this.remove=function(element){element.className=element.className.replace(this.MATCH,"")};this.exec=function(){var match=cssQuery(this.selector);for(var i=0;i<match.length;i++)this.add(match[i])}};function Class(selector,cssText){this.id=IE7.classes.length;this.name=Class.PREFIX+this.id;this.selector=selector;this.MATCH=new RegExp("\x5cs"+this.name+"\x5cb","g");push(IE7.classes,this)};Class.ancestor=_Class;Class.prototype=new _Class;Class.PREFIX="ie7_";Class.ID=function(match){return simpleSelector(match)+new Class(match)};function _DynamicStyle(){this.exec=function(){var match=cssQuery(this.attach);for(var i=0;i<match.length;i++){var target=(this.target)?cssQuery(this.target,match[i]):[match[i]];if(target)this.dynamicPseudoClass(match[i],target,this)}}};_DynamicStyle.prototype=new _Class;function DynamicStyle(selector,attach,dynamicPseudoClass,target){this.attach=attach;this.dynamicPseudoClass=dynamicPseudoClasses[dynamicPseudoClass];this.target=target;this.inherit=Class;this.inherit(selector)};DynamicStyle.ancestor=_DynamicStyle;DynamicStyle.prototype=new _DynamicStyle;DynamicStyle.ID=function(match,attach,dynamicPseudoClass,target){if(isHTML&&dynamicPseudoClass!="focus"&&ANCHOR.test(attach)&&!/[+>~]/.test(target))return match;return simpleSelector(match)+new DynamicStyle(match,attach,dynamicPseudoClass,target)};HEADER+=".ie7_anon{vertical-align:top;display:inline}";var HEX=/\x5c([a-fA-F\d]+)/g;function unicode(match,code){return eval("'\x5cu"+"0000".slice(code.length)+code+"'")};var pseudoElements=[];function _PseudoElement(){this.content=null;this.toString=function(){return ""};this.specificity=0;function addTimer(object,content,cssText){var timer=setInterval(function(){try{if(!object.load)return;object.load(object,content,cssText);clearInterval(timer)}catch(ignore){clearInterval(timer)}},10)};this.create=function(){if(this.content==null)return;for(var i=0;i<this.match.length;i++){var target=this.match[i];var pseudoElement=target.runtimeStyle[this.position];if(pseudoElement){var parentElement=target.canHaveChildren?target:target.parentElement;var isURL=/^url\(.*\)$/.test(this.content);var element=document.createElement(isURL?PseudoElement.OBJECT:"!");element.ie7_anon=true;element.runtimeStyle.cssText=pseudoElement.cssText;if(!isURL)element.innerText=pseudoElement.content;if(this.position=="before"){parentElement.insertBefore(element,parentElement.firstChild)}else{parentElement.appendChild(element)}if(isURL)addTimer(element,pseudoElement.content,pseudoElement.cssText);target.runtimeStyle[this.position]=null}}};this.exec=function(){this.match=cssQuery(this.selector);for(var i=0;i<this.match.length;i++){var runtimeStyle=this.match[i].runtimeStyle;if(!runtimeStyle[this.position])runtimeStyle[this.position]={cssText:""};runtimeStyle[this.position].cssText+=";"+this.cssText;if(this.content!=null)runtimeStyle[this.position].content=this.content}}};_PseudoElement.prototype=new _Class;function PseudoElement(selector,position,cssText){this.position=position;this.cssText=encoded[cssText].slice(1,-1);var content=this.cssText.match(PseudoElement.CONTENT);if(content)this.content=getString(content[1]).replace(HEX,unicode);this.inherit=Class;this.inherit(selector);push(pseudoElements,this)};PseudoElement.ancestor=_PseudoElement;PseudoElement.prototype=new _PseudoElement;PseudoElement.ID=function(match,selector,position,cssText){return new PseudoElement(selector,position,cssText)};PseudoElement.ALL=/([^}]*):(before|after)[^{]*\{([^}]*)\}/g;PseudoElement.CONTENT=/content\s*:\s*([^;]*)(;|$)/;PseudoElement.OBJECT="<object class=ie7_anon data='"+makePath("ie7-content.htm",path)+"' width=100% height=0 type=text/x-scriptlet>";selectors[">"]=function(filtered,from,filter,scopeName){for(var i=0;i<from.length;i++){var subset=from[i].children;for(var j=0;j<subset.length;j++)if(compareTagName(subset[j],filter,scopeName))push(filtered,subset[j])}};selectors["+"]=function(filtered,from,filter,scopeName){for(var i=0;i<from.length;i++){var adjacent=nextElement(from[i]);if(adjacent&&compareTagName(adjacent,filter,scopeName))push(filtered,adjacent)}};selectors["@"]=function(filtered,from,filter){filter=attributeSelectors[filter];for(var i=0;i<from.length;i++)if(filter(from[i]))push(filtered,from[i])};pseudoClasses["first-child"]=function(element){return!previousElement(element)};pseudoClasses["lang"]=function(element,filterArgs){filterArgs=new RegExp("^"+filterArgs,"i");while(element&&!element.getAttribute("lang"))element=element.parentNode;return element&&filterArgs.test(element.getAttribute("lang"))};dynamicPseudoClasses.hover=function(element){var instance=arguments;addEventHandler(element,"onmouseover",function(){IE7.Event.hover.register(instance)});addEventHandler(element,"onmouseout",function(){IE7.Event.hover.unregister(instance)})};dynamicPseudoClasses.active=function(element){var instance=arguments;addEventHandler(element,"onmousedown",function(){IE7.Event.active.register(instance)})};dynamicPseudoClasses.focus=function(element){var instance=arguments;addEventHandler(element,"onfocus",function(){IE7.Event.focus.register(instance)});addEventHandler(element,"onblur",function(){IE7.Event.focus.unregister(instance)});if(element==document.activeElement){IE7.Event.focus.register(instance)}};addEventHandler(document,"onmouseup",function(){var ie7Event=IE7.Event.active;var instances=ie7Event.instances,i;for(i in instances)ie7Event.unregister(instances[i]);ie7Event=IE7.Event.hover;instances=ie7Event.instances;for(i in instances)if(!instances[i][0].contains(event.srcElement))ie7Event.unregister(instances[i])});var attributeSelectors=[];var ESCAPE=/([\x2f()[\]?{}|*+])/g;function AttributeSelector(attribute,compare,value){value=getString(value);this.id=attributeSelectors.length;switch(attribute.toLowerCase()){case "id":attribute="element.id.replace(/ms_\x5cd+/g,'')";break;case "class":attribute="element.className.replace(/\x5cb\x5cs*ie7_\x5cd+/g,'')";break;default:attribute="element.getAttribute('"+attribute+"')"}compare=attributeTests[compare];push(attributeSelectors,new Function("element","return "+compare(attribute,value)))};AttributeSelector.ID=function(match,attribute,compare,value){return new AttributeSelector(attribute,compare,value)};AttributeSelector.prototype.toString=function(){return AttributeSelector.PREFIX+this.id};attributeTests={toString:function(){var toString=[];for(var i in this)if(i&&i!="escape")push(toString,i);return toString.join("").replace(/=/g,"")},escape:function(value){return value.replace(ESCAPE,"\x5c$1")},"":function(attribute){return attribute},"=":function(attribute,value){return attribute+"=="+quote(value)},"~=":function(attribute,value){return "/(^|\x5cs)"+attributeTests.escape(value)+"(\x5cs|$)/.test("+attribute+")"},"|=":function(attribute,value){return "/^"+attributeTests.escape(value)+"(-|$)/.test("+attribute+")"}};AttributeSelector.PREFIX="@";function _ie7Event(){this.register=function(instance){var element=instance[0];var target=instance[1];var Class=instance[2];for(var i=0;i<target.length;i++)Class.add(target[i]);this.instances[Class.id+element.uniqueID]=instance};this.unregister=function(instance){var element=instance[0];var target=instance[1];var Class=instance[2];for(var i=0;i<target.length;i++)Class.remove(target[i]);delete this.instances[Class.id+element.uniqueID]}};IE7.Event=function(type){this.type=type;this.instances={};IE7.Event[type]=this};IE7.Event.prototype=new _ie7Event;new IE7.Event("hover");new IE7.Event("active");new IE7.Event("focus");function simpleSelector(selector){return selector.replace(Class.COMPLEX,"").replace(CHILD," ")}},true);IE7.addModule("ie7-png",function(){if(appVersion<5.5)return;var FILTER="progid:DXImageTransform.Microsoft.AlphaImageLoader(src=%1,sizingMethod='scale')";var NULL=(/\bSV1\b/.test(navigator.userAgent))?makePath("blank.gif",path):"javascript:'#define x_width 1\x5cn#define x_height 1\x5cnstatic char x_bits[]={0x00}'";var pngTest=new RegExp((window.IE7_PNG_SUFFIX||"-trans.png")+"$","i");function addFilter(element,src){element.runtimeStyle.filter=FILTER.replace(/%1/,src)};var MATCH=/background(-image)?\s*:([^(};]*)url\(([^\)]+)\)([^;}]*)/gi;CSSFixes.addFix(MATCH,function replace(match,image,prefix,url,suffix){url=getString(url);return pngTest.test(url)?"filter:"+FILTER.replace(/scale/,"crop").replace(/%1/,url)+";zoom:1;background"+(image||"")+":"+(prefix||"")+"none"+(suffix||""):match});if(HTMLFixes){function fixImg(element){if(pngTest.test(element.src)){var width=element.width,height=element.height;addFilter(element,element.src);element.src=NULL;element.width=width;element.height=height}else element.runtimeStyle.filter=""};HTMLFixes.add("img,input",function(element){if(element.tagName=="INPUT"&&element.type!="image")return;fixImg(element);addEventHandler(element,"onpropertychange",function(){if(event.propertyName=="src")fixImg(element)})})}});IE7.addModule("ie7-fixed",function(){var PERCENT=/^\d+%$/;CSSFixes.addRecalc("position\x5cs*:\x5cs*fixed",positionFixed);CSSFixes.addRecalc("background[\x5cw\x5cs-]*:[^};]*fixed",backgroundFixed);var body=document.body;var viewport$=(quirksMode)?"body":"documentElement";var viewport=eval(viewport$);function fixBackground(){if(body.currentStyle.backgroundAttachment!="fixed"){if(body.currentStyle.backgroundImage=="none"){body.runtimeStyle.backgroundImage="url("+location.protocol+")"}body.runtimeStyle.backgroundAttachment="fixed"}fixBackground=DUMMY};var ie7_tmp=tmpElement("img");function topFunction(leftFunction){return String(leftFunction).replace(/Left/g,"Top").replace(/left/g,"top").replace(/Width/g,"Height").replace(/X/g,"Y")};function backgroundFixed(element){if(element.currentStyle.backgroundAttachment!="fixed")return;if(!element.contains(body)){fixBackground();backgroundFixed[backgroundFixed.count++]=element;backgroundLeft(element);backgroundTop(element);backgroundPosition(element)}};backgroundFixed.count=0;function backgroundPosition(element){ie7_tmp.src=element.currentStyle.backgroundImage.slice(5,-2);var parentElement=(element.canHaveChildren)?element:element.parentElement;parentElement.appendChild(ie7_tmp);setOffsetLeft(element);setOffsetTop(element);parentElement.removeChild(ie7_tmp)};function backgroundLeft(element){element.style.backgroundPositionX=element.currentStyle.backgroundPositionX;if(!isFixed(element)){var expression="(parseInt(runtimeStyle.offsetLeft)+document."+viewport$+".scrollLeft)||0";element.runtimeStyle.setExpression("backgroundPositionX",expression)}};eval(topFunction(backgroundLeft));function setOffsetLeft(element){var propertyName=isFixed(element)?"backgroundPositionX":"offsetLeft";element.runtimeStyle[propertyName]=getOffsetLeft(element,element.style.backgroundPositionX)-element.getBoundingClientRect().left-element.clientLeft};eval(topFunction(setOffsetLeft));function isFixed(element){if(!element)return false;if(element.style.position=="fixed"||element.currentStyle.position=="fixed")return true;return arguments.callee(element.parentElement)};function getOffsetLeft(element,position){switch(position){case "left":case "top":return 0;case "right":case "bottom":return viewport.clientWidth-ie7_tmp.offsetWidth;case "center":return(viewport.clientWidth-ie7_tmp.offsetWidth)/2;default:if(PERCENT.test(position)){return parseInt((viewport.clientWidth-ie7_tmp.offsetWidth)*parseFloat(position)/100)}ie7_tmp.style.left=position;return ie7_tmp.offsetLeft}};eval(topFunction(getOffsetLeft));function positionFixed(element){if(element.currentStyle.position!="fixed")return;fixBackground();positionFixed[positionFixed.count++]=element;element.style.position="fixed";element.runtimeStyle.position="absolute";foregroundPosition(element)};positionFixed.count=0;function foregroundPosition(element,recalc){positionLeft(element,recalc);positionTop(element,recalc);if(!recalc||element.runtimeStyle.autoTop){if(parseInt(element.currentStyle.bottom)==0)element.runtimeStyle.screenTop++}};function positionLeft(element,recalc){if(!recalc&&PERCENT.test(element.currentStyle.width))element.runtimeStyle.fixWidth=element.currentStyle.width;if(element.runtimeStyle.fixWidth)element.runtimeStyle.width=parseInt(parseFloat(element.runtimeStyle.fixWidth)/100*viewport.clientWidth);if(recalc){if(!element.runtimeStyle.autoLeft)return}else{element.runtimeStyle.autoLeft=element.currentStyle.right!="auto"&&element.currentStyle.left=="auto"}element.runtimeStyle.left="";element.runtimeStyle.screenLeft=getScreenLeft(element);if(element.currentStyle.marginLeft!="auto"){element.parentElement.appendChild(ie7_tmp);ie7_tmp.style.left=element.currentStyle.marginLeft;element.runtimeStyle.screenLeft-=ie7_tmp.offsetLeft;element.parentElement.removeChild(ie7_tmp)}if(isFixed(element.offsetParent))element.runtimeStyle.pixelLeft=element.runtimeStyle.screenLeft;else if(!recalc)element.runtimeStyle.setExpression("pixelLeft","runtimeStyle.screenLeft+document."+viewport$+".scrollLeft")};eval(topFunction(positionLeft).replace(/right/g,"bottom").replace(/width/g,"height"));function getScreenLeft(element){var getScreenLeft=element.offsetLeft,nested=false;var fixed=isFixed(element.offsetParent)&&element.runtimeStyle.autoLeft;while(element=element.offsetParent){if(!fixed&&element.currentStyle.position!="static")nested=true;getScreenLeft+=element.offsetLeft*(nested?-1:1)}return getScreenLeft};eval(topFunction(getScreenLeft));function resize(){for(var i=0;i<backgroundFixed.count;i++)backgroundPosition(backgroundFixed[i]);for(i=0;i<positionFixed.count;i++)foregroundPosition(positionFixed[i],true);timer=0};var timer;addEventHandler(window,"onresize",function(){if(!timer)timer=setTimeout(resize,10)})});loaded=true;if(document.readyState=="complete")_load();else addEventHandler(document,"onreadystatechange",function(){if(!complete&&document.readyState=="complete")setTimeout(_load,0)})}catch(error){unHide();alert("Error [0]: "+error.description)}finally{}}();
diff --git a/usr/local/www/themes/pfsense_ng/javascript/ie7/test-trans.png b/usr/local/www/themes/pfsense_ng/javascript/ie7/test-trans.png
new file mode 100644
index 0000000..e187e2c
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/ie7/test-trans.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/javascript/img/grey-40.png b/usr/local/www/themes/pfsense_ng/javascript/img/grey-40.png
new file mode 100644
index 0000000..0d4abf9
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/img/grey-40.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/javascript/img/submenu-off.gif b/usr/local/www/themes/pfsense_ng/javascript/img/submenu-off.gif
new file mode 100644
index 0000000..ddcdcae
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/img/submenu-off.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/javascript/img/submenu-on.gif b/usr/local/www/themes/pfsense_ng/javascript/img/submenu-on.gif
new file mode 100644
index 0000000..7a58077
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/img/submenu-on.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/javascript/img/white-90.png b/usr/local/www/themes/pfsense_ng/javascript/img/white-90.png
new file mode 100644
index 0000000..9ba5c83
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/img/white-90.png
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/javascript/img/x.gif b/usr/local/www/themes/pfsense_ng/javascript/img/x.gif
new file mode 100644
index 0000000..5bfd67a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/img/x.gif
Binary files differ
diff --git a/usr/local/www/themes/pfsense_ng/javascript/niftyjsCode.js b/usr/local/www/themes/pfsense_ng/javascript/niftyjsCode.js
new file mode 100644
index 0000000..8e76d46
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/niftyjsCode.js
@@ -0,0 +1,174 @@
+function NiftyCheck(){
+if(!document.getElementById || !document.createElement)
+ return(false);
+isXHTML=/html\:/.test(document.getElementsByTagName('body')[0].nodeName);
+if(Array.prototype.push==null){Array.prototype.push=function(){
+ this[this.length]=arguments[0]; return(this.length);}}
+return(true);
+}
+
+function Rounded(selector,wich,bk,color,opt){
+var i,prefixt,prefixb,cn="r",ecolor="",edges=false,eclass="",b=false,t=false;
+
+if(color=="transparent"){
+ cn=cn+"x";
+ ecolor=bk;
+ bk="transparent";
+ }
+else if(opt && opt.indexOf("border")>=0){
+ var optar=opt.split(" ");
+ for(i=0;i<optar.length;i++)
+ if(optar[i].indexOf("#")>=0) ecolor=optar[i];
+ if(ecolor=="") ecolor="#666";
+ cn+="e";
+ edges=true;
+ }
+else if(opt && opt.indexOf("smooth")>=0){
+ cn+="a";
+ ecolor=Mix(bk,color);
+ }
+if(opt && opt.indexOf("small")>=0) cn+="s";
+prefixt=cn;
+prefixb=cn;
+if(wich.indexOf("all")>=0){t=true;b=true}
+else if(wich.indexOf("top")>=0) t="true";
+else if(wich.indexOf("tl")>=0){
+ t="true";
+ if(wich.indexOf("tr")<0) prefixt+="l";
+ }
+else if(wich.indexOf("tr")>=0){
+ t="true";
+ prefixt+="r";
+ }
+if(wich.indexOf("bottom")>=0) b=true;
+else if(wich.indexOf("bl")>=0){
+ b="true";
+ if(wich.indexOf("br")<0) prefixb+="l";
+ }
+else if(wich.indexOf("br")>=0){
+ b="true";
+ prefixb+="r";
+ }
+var v=getElementsBySelector(selector);
+var l=v.length;
+for(i=0;i<l;i++){
+ if(edges) AddBorder(v[i],ecolor);
+ if(t) AddTop(v[i],bk,color,ecolor,prefixt);
+ if(b) AddBottom(v[i],bk,color,ecolor,prefixb);
+ }
+}
+
+function AddBorder(el,bc){
+var i;
+if(!el.passed){
+ if(el.childNodes.length==1 && el.childNodes[0].nodeType==3){
+ var t=el.firstChild.nodeValue;
+ el.removeChild(el.lastChild);
+ var d=CreateEl("span");
+ d.style.display="block";
+ d.appendChild(document.createTextNode(t));
+ el.appendChild(d);
+ }
+ for(i=0;i<el.childNodes.length;i++){
+ if(el.childNodes[i].nodeType==1){
+ el.childNodes[i].style.borderLeft="1px solid "+bc;
+ el.childNodes[i].style.borderRight="1px solid "+bc;
+ }
+ }
+ }
+el.passed=true;
+}
+
+function AddTop(el,bk,color,bc,cn){
+var i,lim=4,d=CreateEl("b");
+
+if(cn.indexOf("s")>=0) lim=2;
+if(bc) d.className="artop";
+else d.className="rtop";
+d.style.backgroundColor=bk;
+for(i=1;i<=lim;i++){
+ var x=CreateEl("b");
+ x.className=cn + i;
+ x.style.backgroundColor=color;
+ if(bc) x.style.borderColor=bc;
+ d.appendChild(x);
+ }
+el.style.paddingTop=0;
+el.insertBefore(d,el.firstChild);
+}
+
+function AddBottom(el,bk,color,bc,cn){
+var i,lim=4,d=CreateEl("b");
+
+if(cn.indexOf("s")>=0) lim=2;
+if(bc) d.className="artop";
+else d.className="rtop";
+d.style.backgroundColor=bk;
+for(i=lim;i>0;i--){
+ var x=CreateEl("b");
+ x.className=cn + i;
+ x.style.backgroundColor=color;
+ if(bc) x.style.borderColor=bc;
+ d.appendChild(x);
+ }
+el.style.paddingBottom=0;
+el.appendChild(d);
+}
+
+function CreateEl(x){
+if(isXHTML) return(document.createElementNS('http://www.w3.org/1999/xhtml',x));
+else return(document.createElement(x));
+}
+
+function getElementsBySelector(selector){
+var i,selid="",selclass="",tag=selector,f,s=[],objlist=[];
+
+if(selector.indexOf(" ")>0){ //descendant selector like "tag#id tag"
+ s=selector.split(" ");
+ var fs=s[0].split("#");
+ if(fs.length==1) return(objlist);
+ f=document.getElementById(fs[1]);
+ if(f) return(f.getElementsByTagName(s[1]));
+ return(objlist);
+ }
+if(selector.indexOf("#")>0){ //id selector like "tag#id"
+ s=selector.split("#");
+ tag=s[0];
+ selid=s[1];
+ }
+if(selid!=""){
+ f=document.getElementById(selid);
+ if(f) objlist.push(f);
+ return(objlist);
+ }
+if(selector.indexOf(".")>0){ //class selector like "tag.class"
+ s=selector.split(".");
+ tag=s[0];
+ selclass=s[1];
+ }
+var v=document.getElementsByTagName(tag); // tag selector like "tag"
+if(selclass=="")
+ return(v);
+for(i=0;i<v.length;i++){
+ if(v[i].className.indexOf(selclass)>=0){
+ objlist.push(v[i]);
+ }
+ }
+return(objlist);
+}
+
+function Mix(c1,c2){
+var i,step1,step2,x,y,r=new Array(3);
+if(c1.length==4)step1=1;
+else step1=2;
+if(c2.length==4) step2=1;
+else step2=2;
+for(i=0;i<3;i++){
+ x=parseInt(c1.substr(1+step1*i,step1),16);
+ if(step1==1) x=16*x+x;
+ y=parseInt(c2.substr(1+step2*i,step2),16);
+ if(step2==1) y=16*y+y;
+ r[i]=Math.floor((x*50+y*50)/100);
+ }
+return("#"+r[0].toString(16)+r[1].toString(16)+r[2].toString(16));
+} \ No newline at end of file
diff --git a/usr/local/www/themes/pfsense_ng/javascript/transmenu-body.php b/usr/local/www/themes/pfsense_ng/javascript/transmenu-body.php
new file mode 100644
index 0000000..76b936f
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/transmenu-body.php
@@ -0,0 +1,51 @@
+<?php
+/* $Id: transmenu-body.php,v 1.1.2.1 2007/01/17 18:43:47 sullrich Exp $ */
+/* DISABLE_PHP_LINT_CHECKING */
+/* ========================================================================== */
+/*
+ transmenu.php
+ Copyright (C) 2006 Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ All rights reserved.
+ */
+/* ========================================================================== */
+/*
+ Originally part of m0n0wall (http://m0n0.ch/wall)
+ Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+/* ========================================================================== */
+
+function nervecenterTransmenuGetBodyJS() {
+ global $rootmenu;
+
+ if (isset($rootmenu)) {
+ return $rootmenu->getMenuJScript();
+ } else if (empty($rootmenu)) {
+ return "alert('No rootmenu object found.');";
+ } else {
+ return "alert('No JavaScript attached to rootmenu object.');";
+ }
+}
+
+?>
diff --git a/usr/local/www/themes/pfsense_ng/javascript/transmenu-head.php b/usr/local/www/themes/pfsense_ng/javascript/transmenu-head.php
new file mode 100644
index 0000000..bd44dcc
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/transmenu-head.php
@@ -0,0 +1,85 @@
+<?php
+/* $Id: transmenu-head.php,v 1.2.2.1 2007/01/17 18:43:47 sullrich Exp $ */
+/* DISABLE_PHP_LINT_CHECKING */
+/* ========================================================================== */
+/*
+ transmenu.php
+ Copyright (C) 2006 Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ All rights reserved.
+ */
+/* ========================================================================== */
+/*
+ Originally part of m0n0wall (http://m0n0.ch/wall)
+ Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+/* ========================================================================== */
+
+function nervecenterTransmenuGetHeadJS() {
+ global $g, $rootmenu;
+
+ $transmenu_stub =<<<EOD
+ function tmenuinit() {
+ //==========================================================================================
+ // if supported, initialize TransMenus
+ //==========================================================================================
+ // Check isSupported() so that menus aren't accidentally sent to non-supporting browsers.
+ // This is better than server-side checking because it will also catch browsers which would
+ // normally support the menus but have javascript disabled.
+ //
+ // If supported, call initialize() and then hook whatever image rollover code you need to do
+ // to the .onactivate and .ondeactivate events for each menu.
+ //==========================================================================================
+ if (TransMenu.isSupported()) {
+ TransMenu.initialize();
+
+ // hook all the highlight swapping of the main toolbar to menu activation/deactivation
+ // instead of simple rollover to get the effect where the button stays hightlit until
+ // the menu is closed.
+ @@CHILD_JSCRIPT@@
+ }
+ } // end function
+EOD;
+
+ if (empty($rootmenu)) {
+ require_once("menudef.inc");
+ }
+
+ $childJScript = "";
+ foreach ($rootmenu->getChildren() as $component) {
+ $id = "mnua_" . str_replace(" ", "", strtolower($component->getID()));
+
+ $childJScript .=<<<EOD
+ {$id}.onactivate = function() { document.getElementById("{$id}").className = "hover"; };
+ {$id}.ondeactivate = function() { document.getElementById("{$id}").className = ""; };
+
+EOD;
+ }
+
+ $transmenu_stub = basename($_SERVER['PHP_SELF']) != "wizard.php" ? str_replace("@@CHILD_JSCRIPT@@", $childJScript, $transmenu_stub) : "";
+
+ return $transmenu_stub;
+}
+
+?>
diff --git a/usr/local/www/themes/pfsense_ng/javascript/transmenu.org b/usr/local/www/themes/pfsense_ng/javascript/transmenu.org
new file mode 100644
index 0000000..6c9e353
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/transmenu.org
@@ -0,0 +1,785 @@
+/* =================================================================================================
+ * TransMenu
+ * March, 2003
+ *
+ * Customizable multi-level animated DHTML menus with transparency.
+ *
+ * Copyright 2003-2004, Aaron Boodman (www.youngpup.net)
+ * =================================================================================================
+ * "Can I use this?"
+ *
+ * Use of this library is governed by the Creative Commons Attribution 2.0 License. You can check it
+ * out at: http://creativecommons.org/licenses/by/2.0/
+ *
+ * Basically: You may copy, distribute, and eat this code as you wish. But you must give me credit
+ * for writing it. You may not misrepresent yourself as the author of this code.
+ * =================================================================================================
+ * "It's kinda hard to read, though"
+ *
+ * The uncompressed, commented version of this script can be found at:
+ * http://youngpup.net/projects/transMenus
+ * =================================================================================================
+ * updates:
+ * 04.19.04 fixed cascade problem with menus nested greater than two levels.
+ * 12.23.03 added hideCurrent for menu actuators with no menus. renamed to TransMenu.
+ * 04.18.03 fixed render bug in IE 5.0 Mac by removing that browser from compatibility table ;)
+ * also made gecko check a little more strict by specifying build no.
+ * ============================================================================================== */
+
+
+
+//==================================================================================================
+// Configuration properties
+//==================================================================================================
+TransMenu.spacerGif = "themes/nervecenter/javascript/img/x.gif"; // path to a transparent spacer gif
+TransMenu.dingbatOn = "themes/nervecenter/javascript/img/submenu-on.gif"; // path to the active sub menu dingbat
+TransMenu.dingbatOff = "themes/nervecenter/javascript/img/submenu-off.gif"; // path to the inactive sub menu dingbat
+TransMenu.dingbatSize = 14; // size of the dingbat (square shape assumed)
+TransMenu.menuPadding = 5; // padding between menu border and items grid
+TransMenu.itemPadding = 3; // additional padding around each item
+TransMenu.shadowSize = 2; // size of shadow under menu
+TransMenu.shadowOffset = 3; // distance shadow should be offset from leading edge
+TransMenu.shadowColor = "#FF0000"; // color of shadow (transparency is set in CSS)
+TransMenu.shadowPng = "themes/nervecenter/javascript/img/grey-40.png"; // a PNG graphic to serve as the shadow for mac IE5
+TransMenu.backgroundColor = "#990000"; // color of the background (transparency set in CSS)
+TransMenu.backgroundPng = "themes/nervecenter/javascript/img/white-90.png"; // a PNG graphic to server as the background for mac IE5
+TransMenu.hideDelay = 1000; // number of milliseconds to wait before hiding a menu
+TransMenu.slideTime = 400; // number of milliseconds it takes to open and close a menu
+
+
+//==================================================================================================
+// Internal use properties
+//==================================================================================================
+TransMenu.reference = {topLeft:1,topRight:2,bottomLeft:3,bottomRight:4};
+TransMenu.direction = {down:1,right:2};
+TransMenu.registry = [];
+TransMenu._maxZ = 100;
+
+
+
+//==================================================================================================
+// Static methods
+//==================================================================================================
+// supporting win ie5+, mac ie5.1+ and gecko >= mozilla 1.0
+TransMenu.isSupported = function() {
+ var ua = navigator.userAgent.toLowerCase();
+ var pf = navigator.platform.toLowerCase();
+ var an = navigator.appName;
+ var r = false;
+
+ if (ua.indexOf("gecko") > -1 && navigator.productSub >= 20020605) r = true; // gecko >= moz 1.0
+ else if (an == "Microsoft Internet Explorer") {
+ if (document.getElementById) { // ie5.1+ mac,win
+ if (pf.indexOf("mac") == 0) {
+ r = /msie (\d(.\d*)?)/.test(ua) && Number(RegExp.$1) >= 5.1;
+ }
+ else r = true;
+ }
+ }
+
+ return r;
+}
+
+// call this in onload once menus have been created
+TransMenu.initialize = function() {
+ for (var i = 0, menu = null; menu = this.registry[i]; i++) {
+ menu.initialize();
+ }
+}
+
+// call this in document body to write out menu html
+TransMenu.renderAll = function() {
+ var aMenuHtml = [];
+ for (var i = 0, menu = null; menu = this.registry[i]; i++) {
+ aMenuHtml[i] = menu.toString();
+ }
+ document.write(aMenuHtml.join(""));
+}
+
+//==================================================================================================
+// TransMenu constructor (only called internally)
+//==================================================================================================
+// oActuator : The thing that causes the menu to be shown when it is mousedover. Either a
+// reference to an HTML element, or a TransMenuItem from an existing menu.
+// iDirection : The direction to slide out. One of TransMenu.direction.
+// iLeft : Left pixel offset of menu from actuator
+// iTop : Top pixel offset of menu from actuator
+// iReferencePoint : Corner of actuator to measure from. One of TransMenu.referencePoint.
+// parentMenuSet : Menuset this menu will be added to.
+//==================================================================================================
+function TransMenu(oActuator, iDirection, iLeft, iTop, iReferencePoint, parentMenuSet) {
+ // public methods
+ this.addItem = addItem;
+ this.addMenu = addMenu;
+ this.toString = toString;
+ this.initialize = initialize;
+ this.isOpen = false;
+ this.show = show;
+ this.hide = hide;
+ this.items = [];
+
+ // events
+ this.onactivate = new Function(); // when the menu starts to slide open
+ this.ondeactivate = new Function(); // when the menu finishes sliding closed
+ this.onmouseover = new Function(); // when the menu has been moused over
+ this.onqueue = new Function(); // hack .. when the menu sets a timer to be closed a little while in the future
+ this.ondequeue = new Function();
+
+ // initialization
+ this.index = TransMenu.registry.length;
+ TransMenu.registry[this.index] = this;
+
+ var id = "TransMenu" + this.index;
+ var contentHeight = null;
+ var contentWidth = null;
+ var childMenuSet = null;
+ var animating = false;
+ var childMenus = [];
+ var slideAccel = -1;
+ var elmCache = null;
+ var ready = false;
+ var _this = this;
+ var a = null;
+
+ var pos = iDirection == TransMenu.direction.down ? "top" : "left";
+ var dim = null;
+
+ // private and public method implimentations
+ function addItem(sText, sUrl) {
+ var item = new TransMenuItem(sText, sUrl, this);
+ item._index = this.items.length;
+ this.items[item._index] = item;
+ }
+
+ function addMenu(oMenuItem) {
+ if (!oMenuItem.parentMenu == this) throw new Error("Cannot add a menu here");
+
+ if (childMenuSet == null) childMenuSet = new TransMenuSet(TransMenu.direction.right, -5, 2, TransMenu.reference.topRight);
+
+ var m = childMenuSet.addMenu(oMenuItem);
+
+ childMenus[oMenuItem._index] = m;
+ m.onmouseover = child_mouseover;
+ m.ondeactivate = child_deactivate;
+ m.onqueue = child_queue;
+ m.ondequeue = child_dequeue;
+
+ return m;
+ }
+
+ function initialize() {
+ initCache();
+ initEvents();
+ initSize();
+ ready = true;
+ }
+
+ function show() {
+ //dbg_dump("show");
+ if (ready) {
+ _this.isOpen = true;
+ animating = true;
+ setContainerPos();
+ elmCache["clip"].style.visibility = "visible";
+ elmCache["clip"].style.zIndex = TransMenu._maxZ++;
+ //dbg_dump("maxZ: " + TransMenu._maxZ);
+ slideStart();
+ _this.onactivate();
+ }
+ }
+
+ function hide() {
+ if (ready) {
+ _this.isOpen = false;
+ animating = true;
+
+ for (var i = 0, item = null; item = elmCache.item[i]; i++)
+ dehighlight(item);
+
+ if (childMenuSet) childMenuSet.hide();
+
+ slideStart();
+ _this.ondeactivate();
+ }
+ }
+
+ function setContainerPos() {
+ var sub = oActuator.constructor == TransMenuItem;
+ var act = sub ? oActuator.parentMenu.elmCache["item"][oActuator._index] : oActuator;
+ var el = act;
+
+ var x = 0;
+ var y = 0;
+
+
+ var minX = 0;
+ var maxX = (window.innerWidth ? window.innerWidth : document.body.clientWidth) - parseInt(elmCache["clip"].style.width);
+ var minY = 0;
+ var maxY = (window.innerHeight ? window.innerHeight : document.body.clientHeight) - parseInt(elmCache["clip"].style.height);
+
+ // add up all offsets... subtract any scroll offset
+ while (sub ? el.parentNode.className.indexOf("transMenu") == -1 : el.offsetParent) {
+ x += el.offsetLeft;
+ y += el.offsetTop;
+
+ if (el.scrollLeft) x -= el.scrollLeft;
+ if (el.scrollTop) y -= el.scrollTop;
+
+ el = el.offsetParent;
+ }
+
+ if (oActuator.constructor == TransMenuItem) {
+ x += parseInt(el.parentNode.style.left);
+ y += parseInt(el.parentNode.style.top);
+ }
+
+ switch (iReferencePoint) {
+ case TransMenu.reference.topLeft:
+ break;
+ case TransMenu.reference.topRight:
+ x += act.offsetWidth;
+ break;
+ case TransMenu.reference.bottomLeft:
+ y += act.offsetHeight;
+ break;
+ case TransMenu.reference.bottomRight:
+ x += act.offsetWidth;
+ y += act.offsetHeight;
+ break;
+ }
+
+ x += iLeft;
+ y += iTop;
+
+ x = Math.max(Math.min(x, maxX), minX);
+ y = Math.max(Math.min(y, maxY), minY);
+
+ elmCache["clip"].style.left = x + "px";
+ elmCache["clip"].style.top = y + "px";
+ }
+
+ function slideStart() {
+ var x0 = parseInt(elmCache["content"].style[pos]);
+ var x1 = _this.isOpen ? 0 : -dim;
+
+ if (a != null) a.stop();
+ a = new Accelimation(x0, x1, TransMenu.slideTime, slideAccel);
+
+ a.onframe = slideFrame;
+ a.onend = slideEnd;
+
+ a.start();
+ }
+
+ function slideFrame(x) {
+ elmCache["content"].style[pos] = x + "px";
+ }
+
+ function slideEnd() {
+ if (!_this.isOpen) elmCache["clip"].style.visibility = "hidden";
+ animating = false;
+ }
+
+ function initSize() {
+ // everything is based off the size of the items table...
+ var ow = elmCache["items"].offsetWidth;
+ var oh = elmCache["items"].offsetHeight;
+ var ua = navigator.userAgent.toLowerCase();
+
+ // clipping container should be ow/oh + the size of the shadow
+ elmCache["clip"].style.width = ow + TransMenu.shadowSize + 2 + "px";
+ elmCache["clip"].style.height = oh + TransMenu.shadowSize + 2 + "px";
+
+ // same with content...
+ elmCache["content"].style.width = ow + TransMenu.shadowSize + "px";
+ elmCache["content"].style.height = oh + TransMenu.shadowSize + "px";
+
+ contentHeight = oh + TransMenu.shadowSize;
+ contentWidth = ow + TransMenu.shadowSize;
+
+ dim = iDirection == TransMenu.direction.down ? contentHeight : contentWidth;
+
+ // set initially closed
+ elmCache["content"].style[pos] = -dim - TransMenu.shadowSize + "px";
+ elmCache["clip"].style.visibility = "hidden";
+
+ // if *not* mac/ie 5
+ if (ua.indexOf("mac") == -1 || ua.indexOf("gecko") > -1) {
+ // set background div to offset size
+ elmCache["background"].style.width = ow + "px";
+ elmCache["background"].style.height = oh + "px";
+ elmCache["background"].style.backgroundColor = TransMenu.backgroundColor;
+
+ // shadow left starts at offset left and is offsetHeight pixels high
+ elmCache["shadowRight"].style.left = ow + "px";
+ elmCache["shadowRight"].style.height = oh - (TransMenu.shadowOffset - TransMenu.shadowSize) + "px";
+ elmCache["shadowRight"].style.backgroundColor = TransMenu.shadowColor;
+
+ // shadow bottom starts at offset height and is offsetWidth - shadowOffset
+ // pixels wide (we don't want the bottom and right shadows to overlap or we
+ // get an extra bright bottom-right corner)
+ elmCache["shadowBottom"].style.top = oh + "px";
+ elmCache["shadowBottom"].style.width = ow - TransMenu.shadowOffset + "px";
+ elmCache["shadowBottom"].style.backgroundColor = TransMenu.shadowColor;
+ }
+ // mac ie is a little different because we use a PNG for the transparency
+ else {
+ // set background div to offset size
+ elmCache["background"].firstChild.src = TransMenu.backgroundPng;
+ elmCache["background"].firstChild.width = ow;
+ elmCache["background"].firstChild.height = oh;
+
+ // shadow left starts at offset left and is offsetHeight pixels high
+ elmCache["shadowRight"].firstChild.src = TransMenu.shadowPng;
+ elmCache["shadowRight"].style.left = ow + "px";
+ elmCache["shadowRight"].firstChild.width = TransMenu.shadowSize;
+ elmCache["shadowRight"].firstChild.height = oh - (TransMenu.shadowOffset - TransMenu.shadowSize);
+
+ // shadow bottom starts at offset height and is offsetWidth - shadowOffset
+ // pixels wide (we don't want the bottom and right shadows to overlap or we
+ // get an extra bright bottom-right corner)
+ elmCache["shadowBottom"].firstChild.src = TransMenu.shadowPng;
+ elmCache["shadowBottom"].style.top = oh + "px";
+ elmCache["shadowBottom"].firstChild.height = TransMenu.shadowSize;
+ elmCache["shadowBottom"].firstChild.width = ow - TransMenu.shadowOffset;
+ }
+ }
+
+ function initCache() {
+ var menu = document.getElementById(id);
+ var all = menu.all ? menu.all : menu.getElementsByTagName("*"); // IE/win doesn't support * syntax, but does have the document.all thing
+
+ elmCache = {};
+ elmCache["clip"] = menu;
+ elmCache["item"] = [];
+
+ for (var i = 0, elm = null; elm = all[i]; i++) {
+ switch (elm.className) {
+ case "items":
+ case "content":
+ case "background":
+ case "shadowRight":
+ case "shadowBottom":
+ elmCache[elm.className] = elm;
+ break;
+ case "item":
+ elm._index = elmCache["item"].length;
+ elmCache["item"][elm._index] = elm;
+ break;
+ }
+ }
+
+ // hack!
+ _this.elmCache = elmCache;
+ }
+
+ function initEvents() {
+ // hook item mouseover
+ for (var i = 0, item = null; item = elmCache.item[i]; i++) {
+ item.onmouseover = item_mouseover;
+ item.onmouseout = item_mouseout;
+ item.onclick = item_click;
+ }
+
+ // hook actuation
+ if (typeof oActuator.tagName != "undefined") {
+ oActuator.onmouseover = actuator_mouseover;
+ oActuator.onmouseout = actuator_mouseout;
+ }
+
+ // hook menu mouseover
+ elmCache["content"].onmouseover = content_mouseover;
+ elmCache["content"].onmouseout = content_mouseout;
+ }
+
+ function highlight(oRow) {
+ oRow.className = "item hover";
+ if (childMenus[oRow._index])
+ oRow.lastChild.firstChild.src = TransMenu.dingbatOn;
+ }
+
+ function dehighlight(oRow) {
+ oRow.className = "item";
+ if (childMenus[oRow._index])
+ oRow.lastChild.firstChild.src = TransMenu.dingbatOff;
+ }
+
+ function item_mouseover() {
+ if (!animating) {
+ highlight(this);
+
+ if (childMenus[this._index])
+ childMenuSet.showMenu(childMenus[this._index]);
+ else if (childMenuSet) childMenuSet.hide();
+ }
+ }
+
+ function item_mouseout() {
+ if (!animating) {
+ if (childMenus[this._index])
+ childMenuSet.hideMenu(childMenus[this._index]);
+ else // otherwise child_deactivate will do this
+ dehighlight(this);
+ }
+ }
+
+ function item_click() {
+ if (!animating) {
+ if (_this.items[this._index].url)
+ location.href = _this.items[this._index].url;
+ }
+ }
+
+ function actuator_mouseover() {
+ parentMenuSet.showMenu(_this);
+ }
+
+ function actuator_mouseout() {
+ parentMenuSet.hideMenu(_this);
+ }
+
+ function content_mouseover() {
+ if (!animating) {
+ parentMenuSet.showMenu(_this);
+ _this.onmouseover();
+ }
+ }
+
+ function content_mouseout() {
+ if (!animating) {
+ parentMenuSet.hideMenu(_this);
+ }
+ }
+
+ function child_mouseover() {
+ if (!animating) {
+ parentMenuSet.showMenu(_this);
+ }
+ }
+
+ function child_deactivate() {
+ for (var i = 0; i < childMenus.length; i++) {
+ if (childMenus[i] == this) {
+ dehighlight(elmCache["item"][i]);
+ break;
+ }
+ }
+ }
+
+ function child_queue() {
+ parentMenuSet.hideMenu(_this);
+ }
+
+ function child_dequeue() {
+ parentMenuSet.showMenu(_this);
+ }
+
+ function toString() {
+ var aHtml = [];
+ var sClassName = "transMenu" + (oActuator.constructor != TransMenuItem ? " top" : "");
+
+ for (var i = 0, item = null; item = this.items[i]; i++) {
+ aHtml[i] = item.toString(childMenus[i]);
+ }
+
+ return '<div id="' + id + '" class="' + sClassName + '">' +
+ '<div class="content"><table class="items" cellpadding="0" cellspacing="0" border="0">' +
+ '<tr><td colspan="2"><img src="' + TransMenu.spacerGif + '" width="1" height="' + TransMenu.menuPadding + '"></td></tr>' +
+ aHtml.join('') +
+ '<tr><td colspan="2"><img src="' + TransMenu.spacerGif + '" width="1" height="' + TransMenu.menuPadding + '"></td></tr></table>' +
+ '<div class="shadowBottom"><img src="' + TransMenu.spacerGif + '" width="1" height="1"></div>' +
+ '<div class="shadowRight"><img src="' + TransMenu.spacerGif + '" width="1" height="1"></div>' +
+ '<div class="background"><img src="' + TransMenu.spacerGif + '" width="1" height="1"></div>' +
+ '</div></div>';
+ }
+}
+
+
+//==================================================================================================
+// TransMenuSet
+//==================================================================================================
+// iDirection : The direction to slide out. One of TransMenu.direction.
+// iLeft : Left pixel offset of menus from actuator
+// iTop : Top pixel offset of menus from actuator
+// iReferencePoint : Corner of actuator to measure from. One of TransMenu.referencePoint.
+//==================================================================================================
+TransMenuSet.registry = [];
+
+function TransMenuSet(iDirection, iLeft, iTop, iReferencePoint) {
+ // public methods
+ this.addMenu = addMenu;
+ this.showMenu = showMenu;
+ this.hideMenu = hideMenu;
+ this.hide = hide;
+ this.hideCurrent = hideCurrent;
+
+ // initialization
+ var menus = [];
+ var _this = this;
+ var current = null;
+
+ this.index = TransMenuSet.registry.length;
+ TransMenuSet.registry[this.index] = this;
+
+ // method implimentations...
+ function addMenu(oActuator) {
+ var m = new TransMenu(oActuator, iDirection, iLeft, iTop, iReferencePoint, this);
+ menus[menus.length] = m;
+ return m;
+ }
+
+ function showMenu(oMenu) {
+ if (oMenu != current) {
+ // close currently open menu
+ if (current != null) hide(current);
+
+ // set current menu to this one
+ current = oMenu;
+
+ // if this menu is closed, open it
+ oMenu.show();
+ }
+ else {
+ // hide pending calls to close this menu
+ cancelHide(oMenu);
+ }
+ }
+
+ function hideMenu(oMenu) {
+ //dbg_dump("hideMenu a " + oMenu.index);
+ if (current == oMenu && oMenu.isOpen) {
+ //dbg_dump("hideMenu b " + oMenu.index);
+ if (!oMenu.hideTimer) scheduleHide(oMenu);
+ }
+ }
+
+ function scheduleHide(oMenu) {
+ //dbg_dump("scheduleHide " + oMenu.index);
+ oMenu.onqueue();
+ oMenu.hideTimer = window.setTimeout("TransMenuSet.registry[" + _this.index + "].hide(TransMenu.registry[" + oMenu.index + "])", TransMenu.hideDelay);
+ }
+
+ function cancelHide(oMenu) {
+ //dbg_dump("cancelHide " + oMenu.index);
+ if (oMenu.hideTimer) {
+ oMenu.ondequeue();
+ window.clearTimeout(oMenu.hideTimer);
+ oMenu.hideTimer = null;
+ }
+ }
+
+ function hide(oMenu) {
+ if (!oMenu && current) oMenu = current;
+
+ if (oMenu && current == oMenu && oMenu.isOpen) {
+ hideCurrent();
+ }
+ }
+
+ function hideCurrent() {
+ if (null != current) {
+ cancelHide(current);
+ current.hideTimer = null;
+ current.hide();
+ current = null;
+ }
+ }
+}
+
+//==================================================================================================
+// TransMenuItem (internal)
+// represents an item in a dropdown
+//==================================================================================================
+// sText : The item display text
+// sUrl : URL to load when the item is clicked
+// oParent : Menu this item is a part of
+//==================================================================================================
+function TransMenuItem(sText, sUrl, oParent) {
+ this.toString = toString;
+ this.text = sText;
+ this.url = sUrl;
+ this.parentMenu = oParent;
+
+ function toString(bDingbat) {
+ var sDingbat = bDingbat ? TransMenu.dingbatOff : TransMenu.spacerGif;
+ var iEdgePadding = TransMenu.itemPadding + TransMenu.menuPadding;
+ var sPaddingLeft = "padding:" + TransMenu.itemPadding + "px; padding-left:" + iEdgePadding + "px;"
+ var sPaddingRight = "padding:" + TransMenu.itemPadding + "px; padding-right:" + iEdgePadding + "px;"
+
+ return '<tr class="item"><td nowrap style="' + sPaddingLeft + '">' +
+ sText + '</td><td width="14" style="' + sPaddingRight + '">' +
+ '<img src="' + sDingbat + '" width="14" height="14"></td></tr>';
+ }
+}
+
+
+
+
+
+
+//=====================================================================
+// Accel[erated] [an]imation object
+// change a property of an object over time in an accelerated fashion
+//=====================================================================
+// obj : reference to the object whose property you'd like to animate
+// prop : property you would like to change eg: "left"
+// to : final value of prop
+// time : time the animation should take to run
+// zip : optional. specify the zippiness of the acceleration. pick a
+// number between -1 and 1 where -1 is full decelerated, 1 is
+// full accelerated, and 0 is linear (no acceleration). default
+// is 0.
+// unit : optional. specify the units for use with prop. default is
+// "px".
+//=====================================================================
+// bezier functions lifted from the lib_animation.js file in the
+// 13th Parallel API. www.13thparallel.org
+//=====================================================================
+
+function Accelimation(from, to, time, zip) {
+ if (typeof zip == "undefined") zip = 0;
+ if (typeof unit == "undefined") unit = "px";
+
+ this.x0 = from;
+ this.x1 = to;
+ this.dt = time;
+ this.zip = -zip;
+ this.unit = unit;
+ this.timer = null;
+ this.onend = new Function();
+ this.onframe = new Function();
+}
+
+
+
+//=====================================================================
+// public methods
+//=====================================================================
+
+// after you create an accelimation, you call this to start it-a runnin'
+Accelimation.prototype.start = function() {
+ this.t0 = new Date().getTime();
+ this.t1 = this.t0 + this.dt;
+ var dx = this.x1 - this.x0;
+ this.c1 = this.x0 + ((1 + this.zip) * dx / 3);
+ this.c2 = this.x0 + ((2 + this.zip) * dx / 3);
+ Accelimation._add(this);
+}
+
+// and if you need to stop it early for some reason...
+Accelimation.prototype.stop = function() {
+ Accelimation._remove(this);
+}
+
+
+
+//=====================================================================
+// private methods
+//=====================================================================
+
+// paints one frame. gets called by Accelimation._paintAll.
+Accelimation.prototype._paint = function(time) {
+ if (time < this.t1) {
+ var elapsed = time - this.t0;
+ this.onframe(Accelimation._getBezier(elapsed/this.dt,this.x0,this.x1,this.c1,this.c2));
+ }
+ else this._end();
+}
+
+// ends the animation
+Accelimation.prototype._end = function() {
+ Accelimation._remove(this);
+ this.onframe(this.x1);
+ this.onend();
+}
+
+
+
+
+//=====================================================================
+// static methods (all private)
+//=====================================================================
+
+// add a function to the list of ones to call periodically
+Accelimation._add = function(o) {
+ var index = this.instances.length;
+ this.instances[index] = o;
+ // if this is the first one, start the engine
+ if (this.instances.length == 1) {
+ this.timerID = window.setInterval("Accelimation._paintAll()", this.targetRes);
+ }
+}
+
+// remove a function from the list
+Accelimation._remove = function(o) {
+ for (var i = 0; i < this.instances.length; i++) {
+ if (o == this.instances[i]) {
+ this.instances = this.instances.slice(0,i).concat( this.instances.slice(i+1) );
+ break;
+ }
+ }
+ // if that was the last one, stop the engine
+ if (this.instances.length == 0) {
+ window.clearInterval(this.timerID);
+ this.timerID = null;
+ }
+}
+
+// "engine" - call each function in the list every so often
+Accelimation._paintAll = function() {
+ var now = new Date().getTime();
+ for (var i = 0; i < this.instances.length; i++) {
+ this.instances[i]._paint(now);
+ }
+}
+
+
+// Bezier functions:
+Accelimation._B1 = function(t) { return t*t*t }
+Accelimation._B2 = function(t) { return 3*t*t*(1-t) }
+Accelimation._B3 = function(t) { return 3*t*(1-t)*(1-t) }
+Accelimation._B4 = function(t) { return (1-t)*(1-t)*(1-t) }
+
+
+//Finds the coordinates of a point at a certain stage through a bezier curve
+Accelimation._getBezier = function(percent,startPos,endPos,control1,control2) {
+ return endPos * this._B1(percent) + control2 * this._B2(percent) + control1 * this._B3(percent) + startPos * this._B4(percent);
+}
+
+
+//=====================================================================
+// static properties
+//=====================================================================
+
+Accelimation.instances = [];
+Accelimation.targetRes = 10;
+Accelimation.timerID = null;
+
+
+//=====================================================================
+// IE win memory cleanup
+//=====================================================================
+
+if (window.attachEvent) {
+ var cearElementProps = [
+ 'data',
+ 'onmouseover',
+ 'onmouseout',
+ 'onmousedown',
+ 'onmouseup',
+ 'ondblclick',
+ 'onclick',
+ 'onselectstart',
+ 'oncontextmenu'
+ ];
+
+ window.attachEvent("onunload", function() {
+ var el;
+ for(var d = document.all.length;d--;){
+ el = document.all[d];
+ for(var c = cearElementProps.length;c--;){
+ el[cearElementProps[c]] = null;
+ }
+ }
+ });
+} \ No newline at end of file
diff --git a/usr/local/www/themes/pfsense_ng/javascript/transmenuC.js b/usr/local/www/themes/pfsense_ng/javascript/transmenuC.js
new file mode 100644
index 0000000..88626c7
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/javascript/transmenuC.js
@@ -0,0 +1,86 @@
+/* =================================================================================================
+ * TransMenu
+ * March, 2003
+ * Customizable multi-level animated DHTML menus with transparency.
+ * =================================================================================================
+ * "Can I use this?"
+ *
+ * Use of this library is governed by the Creative Commons Attribution 2.0 License. You can check it
+ * out at: http://creativecommons.org/licenses/by/2.0/
+ *
+ * Basically: You may copy, distribute, and eat this code as you wish. But you must give me credit
+ * for writing it. You may not misrepresent yourself as the author of this code.
+ * =================================================================================================
+ * "It's kinda hard to read, though"
+ *
+ * The uncompressed, commented version of this script can be found at:
+ * http://youngpup.net/projects/transMenus
+ * ============================================================================================== */
+TransMenu.spacerGif="themes/nervecenter/javascript/img/x.gif";TransMenu.dingbatOn="themes/nervecenter/javascript/img/submenu-on.gif";TransMenu.dingbatOff="themes/nervecenter/javascript/img/submenu-off.gif";TransMenu.dingbatSize=14;TransMenu.menuPadding=5;TransMenu.itemPadding=3;TransMenu.shadowSize=2;TransMenu.shadowOffset=3;TransMenu.shadowColor="#000000";TransMenu.shadowPng="themes/nervecenter/javascript/img/grey-40.png";TransMenu.backgroundColor="#990000";TransMenu.backgroundPng="themes/nervecenter/javascript/img/white-90.png";TransMenu.hideDelay=1000;TransMenu.slideTime=400;TransMenu.reference={topLeft:1,topRight:2,bottomLeft:3,bottomRight:4};TransMenu.direction={down:1,right:2};TransMenu.registry=[];TransMenu._maxZ=100;TransMenu.isSupported=function(){var ua=navigator.userAgent.toLowerCase();var pf=navigator.platform.toLowerCase();var an=navigator.appName;var r=false;if(ua.indexOf("gecko")>-1&&navigator.productSub>=20020605)r=true;else if(an=="Microsoft Internet Explorer"){if(document.getElementById){if(pf.indexOf("mac")==0){r=/msie (\d(.\d*)?)/.test(ua)&&Number(RegExp.$1)>=5.1;}
+else r=true;}}
+return r;}
+TransMenu.initialize=function(){for(var i=0,menu=null;menu=this.registry[i];i++){menu.initialize();}}
+TransMenu.renderAll=function(){var aMenuHtml=[];for(var i=0,menu=null;menu=this.registry[i];i++){aMenuHtml[i]=menu.toString();}
+document.write(aMenuHtml.join(""));}
+function TransMenu(oActuator,iDirection,iLeft,iTop,iReferencePoint,parentMenuSet){this.addItem=addItem;this.addMenu=addMenu;this.toString=toString;this.initialize=initialize;this.isOpen=false;this.show=show;this.hide=hide;this.items=[];this.onactivate=new Function();this.ondeactivate=new Function();this.onmouseover=new Function();this.onqueue=new Function();this.ondequeue=new Function();this.index=TransMenu.registry.length;TransMenu.registry[this.index]=this;var id="TransMenu"+this.index;var contentHeight=null;var contentWidth=null;var childMenuSet=null;var animating=false;var childMenus=[];var slideAccel=-1;var elmCache=null;var ready=false;var _this=this;var a=null;var pos=iDirection==TransMenu.direction.down?"top":"left";var dim=null;function addItem(sText,sUrl){var item=new TransMenuItem(sText,sUrl,this);item._index=this.items.length;this.items[item._index]=item;}
+function addMenu(oMenuItem){if(!oMenuItem.parentMenu==this)throw new Error("Cannot add a menu here");if(childMenuSet==null)childMenuSet=new TransMenuSet(TransMenu.direction.right,-5,2,TransMenu.reference.topRight);var m=childMenuSet.addMenu(oMenuItem);childMenus[oMenuItem._index]=m;m.onmouseover=child_mouseover;m.ondeactivate=child_deactivate;m.onqueue=child_queue;m.ondequeue=child_dequeue;return m;}
+function initialize(){initCache();initEvents();initSize();ready=true;}
+function show(){if(ready){_this.isOpen=true;animating=true;setContainerPos();elmCache["clip"].style.visibility="visible";elmCache["clip"].style.zIndex=TransMenu._maxZ++;slideStart();_this.onactivate();}}
+function hide(){if(ready){_this.isOpen=false;animating=true;for(var i=0,item=null;item=elmCache.item[i];i++)dehighlight(item);if(childMenuSet)childMenuSet.hide();slideStart();_this.ondeactivate();}}
+function setContainerPos(){var sub=oActuator.constructor==TransMenuItem;var act=sub?oActuator.parentMenu.elmCache["item"][oActuator._index]:oActuator;var el=act;var x=0;var y=0;var minX=0;var maxX=(window.innerWidth?window.innerWidth:document.body.clientWidth)-parseInt(elmCache["clip"].style.width);var minY=0;var maxY=(window.innerHeight?window.innerHeight:document.body.clientHeight)-parseInt(elmCache["clip"].style.height);while(sub?el.parentNode.className.indexOf("transMenu")==-1:el.offsetParent){x+=el.offsetLeft;y+=el.offsetTop;if(el.scrollLeft)x-=el.scrollLeft;if(el.scrollTop)y-=el.scrollTop;el=el.offsetParent;}
+if(oActuator.constructor==TransMenuItem){x+=parseInt(el.parentNode.style.left);y+=parseInt(el.parentNode.style.top);}
+switch(iReferencePoint){case TransMenu.reference.topLeft:break;case TransMenu.reference.topRight:x+=act.offsetWidth;break;case TransMenu.reference.bottomLeft:y+=act.offsetHeight;break;case TransMenu.reference.bottomRight:x+=act.offsetWidth;y+=act.offsetHeight;break;}
+x+=iLeft;y+=iTop;x=Math.max(Math.min(x,maxX),minX);y=Math.max(Math.min(y,maxY),minY);elmCache["clip"].style.left=x+"px";elmCache["clip"].style.top=y+"px";}
+function slideStart(){var x0=parseInt(elmCache["content"].style[pos]);var x1=_this.isOpen?0:-dim;if(a!=null)a.stop();a=new Accelimation(x0,x1,TransMenu.slideTime,slideAccel);a.onframe=slideFrame;a.onend=slideEnd;a.start();}
+function slideFrame(x){elmCache["content"].style[pos]=x+"px";}
+function slideEnd(){if(!_this.isOpen)elmCache["clip"].style.visibility="hidden";animating=false;}
+function initSize(){var ow=elmCache["items"].offsetWidth;var oh=elmCache["items"].offsetHeight;var ua=navigator.userAgent.toLowerCase();elmCache["clip"].style.width=ow+TransMenu.shadowSize+2+"px";elmCache["clip"].style.height=oh+TransMenu.shadowSize+2+"px";elmCache["content"].style.width=ow+TransMenu.shadowSize+"px";elmCache["content"].style.height=oh+TransMenu.shadowSize+"px";contentHeight=oh+TransMenu.shadowSize;contentWidth=ow+TransMenu.shadowSize;dim=iDirection==TransMenu.direction.down?contentHeight:contentWidth;elmCache["content"].style[pos]=-dim-TransMenu.shadowSize+"px";elmCache["clip"].style.visibility="hidden";if(ua.indexOf("mac")==-1||ua.indexOf("gecko")>-1){elmCache["background"].style.width=ow+"px";elmCache["background"].style.height=oh+"px";elmCache["background"].style.backgroundColor=TransMenu.backgroundColor;elmCache["shadowRight"].style.left=ow+"px";elmCache["shadowRight"].style.height=oh-(TransMenu.shadowOffset-TransMenu.shadowSize)+"px";elmCache["shadowRight"].style.backgroundColor=TransMenu.shadowColor;elmCache["shadowBottom"].style.top=oh+"px";elmCache["shadowBottom"].style.width=ow-TransMenu.shadowOffset+"px";elmCache["shadowBottom"].style.backgroundColor=TransMenu.shadowColor;}
+else{elmCache["background"].firstChild.src=TransMenu.backgroundPng;elmCache["background"].firstChild.width=ow;elmCache["background"].firstChild.height=oh;elmCache["shadowRight"].firstChild.src=TransMenu.shadowPng;elmCache["shadowRight"].style.left=ow+"px";elmCache["shadowRight"].firstChild.width=TransMenu.shadowSize;elmCache["shadowRight"].firstChild.height=oh-(TransMenu.shadowOffset-TransMenu.shadowSize);elmCache["shadowBottom"].firstChild.src=TransMenu.shadowPng;elmCache["shadowBottom"].style.top=oh+"px";elmCache["shadowBottom"].firstChild.height=TransMenu.shadowSize;elmCache["shadowBottom"].firstChild.width=ow-TransMenu.shadowOffset;}}
+function initCache(){var menu=document.getElementById(id);var all=menu.all?menu.all:menu.getElementsByTagName("*");elmCache={};elmCache["clip"]=menu;elmCache["item"]=[];for(var i=0,elm=null;elm=all[i];i++){switch(elm.className){case"items":case"content":case"background":case"shadowRight":case"shadowBottom":elmCache[elm.className]=elm;break;case"item":elm._index=elmCache["item"].length;elmCache["item"][elm._index]=elm;break;}}
+_this.elmCache=elmCache;}
+function initEvents(){for(var i=0,item=null;item=elmCache.item[i];i++){item.onmouseover=item_mouseover;item.onmouseout=item_mouseout;item.onclick=item_click;}
+if(typeof oActuator.tagName!="undefined"){oActuator.onmouseover=actuator_mouseover;oActuator.onmouseout=actuator_mouseout;}
+elmCache["content"].onmouseover=content_mouseover;elmCache["content"].onmouseout=content_mouseout;}
+function highlight(oRow){oRow.className="item hover";if(childMenus[oRow._index])oRow.lastChild.firstChild.src=TransMenu.dingbatOn;}
+function dehighlight(oRow){oRow.className="item";if(childMenus[oRow._index])oRow.lastChild.firstChild.src=TransMenu.dingbatOff;}
+function item_mouseover(){if(!animating){highlight(this);if(childMenus[this._index])childMenuSet.showMenu(childMenus[this._index]);else if(childMenuSet)childMenuSet.hide();}}
+function item_mouseout(){if(!animating){if(childMenus[this._index])childMenuSet.hideMenu(childMenus[this._index]);else dehighlight(this);}}
+function item_click(){if(!animating){if(_this.items[this._index].url)location.href=_this.items[this._index].url;}}
+function actuator_mouseover(){parentMenuSet.showMenu(_this);}
+function actuator_mouseout(){parentMenuSet.hideMenu(_this);}
+function content_mouseover(){if(!animating){parentMenuSet.showMenu(_this);_this.onmouseover();}}
+function content_mouseout(){if(!animating){parentMenuSet.hideMenu(_this);}}
+function child_mouseover(){if(!animating){parentMenuSet.showMenu(_this);}}
+function child_deactivate(){for(var i=0;i<childMenus.length;i++){if(childMenus[i]==this){dehighlight(elmCache["item"][i]);break;}}}
+function child_queue(){parentMenuSet.hideMenu(_this);}
+function child_dequeue(){parentMenuSet.showMenu(_this);}
+function toString(){var aHtml=[];var sClassName="transMenu"+(oActuator.constructor!=TransMenuItem?" top":"");for(var i=0,item=null;item=this.items[i];i++){aHtml[i]=item.toString(childMenus[i]);}
+return'<div id="'+id+'" class="'+sClassName+'">'+'<div class="content"><table class="items" cellpadding="0" cellspacing="0" border="0">'+'<tr><td colspan="2"><img src="'+TransMenu.spacerGif+'" width="1" height="'+TransMenu.menuPadding+'"></td></tr>'+aHtml.join('')+'<tr><td colspan="2"><img src="'+TransMenu.spacerGif+'" width="1" height="'+TransMenu.menuPadding+'"></td></tr></table>'+'<div class="shadowBottom"><img src="'+TransMenu.spacerGif+'" width="1" height="1"></div>'+'<div class="shadowRight"><img src="'+TransMenu.spacerGif+'" width="1" height="1"></div>'+'<div class="background"><img src="'+TransMenu.spacerGif+'" width="1" height="1"></div>'+'</div></div>';}}
+TransMenuSet.registry=[];function TransMenuSet(iDirection,iLeft,iTop,iReferencePoint){this.addMenu=addMenu;this.showMenu=showMenu;this.hideMenu=hideMenu;this.hide=hide;this.hideCurrent=hideCurrent;var menus=[];var _this=this;var current=null;this.index=TransMenuSet.registry.length;TransMenuSet.registry[this.index]=this;function addMenu(oActuator){var m=new TransMenu(oActuator,iDirection,iLeft,iTop,iReferencePoint,this);menus[menus.length]=m;return m;}
+function showMenu(oMenu){if(oMenu!=current){if(current!=null)hide(current);current=oMenu;oMenu.show();}
+else{cancelHide(oMenu);}}
+function hideMenu(oMenu){if(current==oMenu&&oMenu.isOpen){if(!oMenu.hideTimer)scheduleHide(oMenu);}}
+function scheduleHide(oMenu){oMenu.onqueue();oMenu.hideTimer=window.setTimeout("TransMenuSet.registry["+_this.index+"].hide(TransMenu.registry["+oMenu.index+"])",TransMenu.hideDelay);}
+function cancelHide(oMenu){if(oMenu.hideTimer){oMenu.ondequeue();window.clearTimeout(oMenu.hideTimer);oMenu.hideTimer=null;}}
+function hide(oMenu){if(!oMenu&&current)oMenu=current;if(oMenu&&current==oMenu&&oMenu.isOpen){hideCurrent();}}
+function hideCurrent(){if (null != current){cancelHide(current);current.hideTimer=null;current.hide();current=null;}}}
+function TransMenuItem(sText,sUrl,oParent){this.toString=toString;this.text=sText;this.url=sUrl;this.parentMenu=oParent;function toString(bDingbat){var sDingbat=bDingbat?TransMenu.dingbatOff:TransMenu.spacerGif;var iEdgePadding=TransMenu.itemPadding+TransMenu.menuPadding;var sPaddingLeft="padding:"+TransMenu.itemPadding+"px; padding-left:"+iEdgePadding+"px;"
+var sPaddingRight="padding:"+TransMenu.itemPadding+"px; padding-right:"+iEdgePadding+"px;"
+return'<tr class="item"><td nowrap style="'+sPaddingLeft+'">'+sText+'</td><td width="14" style="'+sPaddingRight+'">'+'<img src="'+sDingbat+'" width="14" height="14"></td></tr>';}}
+function Accelimation(from,to,time,zip){if(typeof zip=="undefined")zip=0;if(typeof unit=="undefined")unit="px";this.x0=from;this.x1=to;this.dt=time;this.zip=-zip;this.unit=unit;this.timer=null;this.onend=new Function();this.onframe=new Function();}
+Accelimation.prototype.start=function(){this.t0=new Date().getTime();this.t1=this.t0+this.dt;var dx=this.x1-this.x0;this.c1=this.x0+((1+this.zip)*dx/3);this.c2=this.x0+((2+this.zip)*dx/3);Accelimation._add(this);}
+Accelimation.prototype.stop=function(){Accelimation._remove(this);}
+Accelimation.prototype._paint=function(time){if(time<this.t1){var elapsed=time-this.t0;this.onframe(Accelimation._getBezier(elapsed/this.dt,this.x0,this.x1,this.c1,this.c2));}
+else this._end();}
+Accelimation.prototype._end=function(){Accelimation._remove(this);this.onframe(this.x1);this.onend();}
+Accelimation._add=function(o){var index=this.instances.length;this.instances[index]=o;if(this.instances.length==1){this.timerID=window.setInterval("Accelimation._paintAll()",this.targetRes);}}
+Accelimation._remove=function(o){for(var i=0;i<this.instances.length;i++){if(o==this.instances[i]){this.instances=this.instances.slice(0,i).concat(this.instances.slice(i+1));break;}}
+if(this.instances.length==0){window.clearInterval(this.timerID);this.timerID=null;}}
+Accelimation._paintAll=function(){var now=new Date().getTime();for(var i=0;i<this.instances.length;i++){this.instances[i]._paint(now);}}
+Accelimation._B1=function(t){return t*t*t}
+Accelimation._B2=function(t){return 3*t*t*(1-t)}
+Accelimation._B3=function(t){return 3*t*(1-t)*(1-t)}
+Accelimation._B4=function(t){return(1-t)*(1-t)*(1-t)}
+Accelimation._getBezier=function(percent,startPos,endPos,control1,control2){return endPos*this._B1(percent)+control2*this._B2(percent)+control1*this._B3(percent)+startPos*this._B4(percent);}
+Accelimation.instances=[];Accelimation.targetRes=10;Accelimation.timerID=null;
+if(window.attachEvent){var cearElementProps=['data','onmouseover','onmouseout','onmousedown','onmouseup','ondblclick','onclick','onselectstart','oncontextmenu'];window.attachEvent("onunload", function() {var el;for(var d=document.all.length;d--;){el=document.all[d];for(var c=cearElementProps.length;c--;){el[cearElementProps[c]] = null;}}});} \ No newline at end of file
diff --git a/usr/local/www/themes/pfsense_ng/jsevents/body.def b/usr/local/www/themes/pfsense_ng/jsevents/body.def
new file mode 100644
index 0000000..df461e2
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/jsevents/body.def
@@ -0,0 +1,7 @@
+# Format: <event_name>=<jsfunction_name> !<forbidden_page_0>,<forbidden_page_1>...<forbidden_page_n>
+# where: forbidden pages are those pages that should *not* use
+# the particular JavaScript function within the JS event
+# specified below.
+# $Id: body.def,v 1.2.2.1 2007/01/17 18:43:52 sullrich Exp $
+#
+onload=tmenuinit(); !wizard.php \ No newline at end of file
diff --git a/usr/local/www/themes/pfsense_ng/loader.js b/usr/local/www/themes/pfsense_ng/loader.js
new file mode 100644
index 0000000..5eb41e1
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/loader.js
@@ -0,0 +1,29 @@
+<!--
+var browser = '';
+var version = '';
+var entrance = '';
+var cond = '';
+
+// BROWSER?
+if (browser == '') {
+ if (navigator.appName.indexOf('Microsoft') != -1)
+ browser = 'IE'
+ else if (navigator.appName.indexOf('Netscape') != -1)
+ browser = 'Netscape'
+ else
+ browser = 'IE';
+}
+if (version == '') {
+ version= navigator.appVersion;
+ paren = version.indexOf('(');
+ whole_version = navigator.appVersion.substring(0,paren-1);
+ version = parseInt(whole_version);
+}
+
+if (browser == 'IE' && version < 7) {
+ document.write('<script type="text/javascript" src="/themes/nervecenter/javascript/ie7/ie7-standard-p.js"></scr'+'ipt>');
+}
+
+document.write('<script type="text/javascript" src="/themes/nervecenter/javascript/niftyjsCode.js"></scr'+'ipt>');
+
+// -->
diff --git a/usr/local/www/themes/pfsense_ng/login.css b/usr/local/www/themes/pfsense_ng/login.css
new file mode 100644
index 0000000..919f405
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/login.css
@@ -0,0 +1,1099 @@
+/* Element CSS Definitions */
+html, body, td, th, input, select {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 0.9em;
+
+}
+
+/* please adjust the bgcolor to be used together with niftycorners! */
+.rtop, .artop {
+ background-color: #999999;
+}
+
+div.GraphLink {
+ position: relative;
+}
+
+span.GraphLinkLine {
+ position: absolute;
+ background-color: #990000;
+ width: 100%;
+}
+
+/* DOM Tooltip CSS definitions */
+div.niceTitle
+{
+ background-color: #333333;
+ color: #FFFFFF;
+ border-bottom: 1px dotted #FFFFFF;
+ font-weight: bold;
+ font-size: 13px;
+ font-family: "Trebuchet MS", sans-serif;
+ width: 250px;
+ left: 0;
+ top: 0;
+ padding: 4px;
+ position: absolute;
+ text-align: left;
+ z-index: 20;
+ -moz-border-radius: 0 10px 10px 10px;
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=87);
+ -moz-opacity: .87;
+ -khtml-opacity: .87;
+ opacity: .87;
+}
+div.niceTitle h1
+{
+ background: #990000;
+ border-bottom: 1px dotted #FFFFFF;
+ font-weight: bold;
+ font-size: 13px;
+ font-family: "Trebuchet MS", sans-serif;
+ margin: 3px;
+ padding-top: 1px;
+ padding-bottom: 1px;
+ padding-left: 3px;
+ text-align: left;
+ left: 0;
+ top: 0;
+ -moz-border-radius: 0 8px 0 0;
+ -moz-opacity: 1;
+}
+div.niceTitle .contents
+{
+ margin: 0;
+ padding: 0 3px;
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=100);
+ -moz-opacity: 1;
+ -khtml-opacity: 1;
+ opacity: 1;
+}
+div.niceTitle p
+{
+ background: #FFFFFF;
+ border: 1px solid #990000;
+ color: #000000;
+ font-size: 9px;
+ padding: 5px;
+ margin: 3px;
+ text-align: left;
+ -moz-opacity: 1;
+ -moz-border-radius: 0 0 8px 8px;
+}
+
+body {
+ margin: 0px auto;
+ background-position : center 0px;
+ background-color: #999999;
+}
+
+form {
+ margin: 0px;
+}
+a {
+ text-decoration: none;
+}
+form input {
+ font-size: 1.1em;
+}
+
+iframe {
+ z-index: 1;
+ border: 1px dashed #990000;
+}
+.iframe {
+ background-color: #FFFFFF;
+}
+
+/* ID Based CSS Definitions */
+#wrapper {
+ width: 810px;
+ margin: 0px auto;
+}
+
+#header {
+ background: url('images/header.png') no-repeat;
+ background-position: 0px;
+ height: 102px;
+ width: 810px;
+ margin-bottom: 5px;
+ z-index: 2;
+}
+#header-left {
+ position: relative;
+ /* background: url('images/logo.gif') no-repeat; */
+ background-position: center;
+ height: 65px;
+ width: 145px;
+ left: 10px;
+ float: left;
+}
+#header-left #status-link {
+ position: relative;
+ top: 10px;
+ left: 6px;
+}
+#header-right {
+ position: relative;
+ /* background: url('images/header.gif') no-repeat; */
+ height: 70px;
+ color: #fff;
+ left: 0px;
+ margin-left: 165px;
+}
+#header-right .alert {
+ position: relative;
+ /* background: url('images/alert.gif') no-repeat; */
+ background-position: 4px 2px;
+ color: #fff;
+ height: 17px;
+ width: 500px;
+ padding: 4px;
+ padding-left: 27px;
+ float: left;
+}
+#header-right .container {
+ position: relative;
+}
+#header-right .container .left {
+ position: relative;
+ float: left;
+ font-size: 1.3em;
+ font-weight: bold;
+ top: 15px;
+ left: 4px;
+ display: none;
+}
+#header-right .container .right {
+ position: relative;
+ float: right;
+ top: 22px;
+ padding-right: 4px;
+ z-index: 1;
+}
+
+#header-right .container .right #alerts {
+ position: relative;
+ background: url('images/alert_bgr.png') no-repeat;
+ height: 39px;
+ width: 431px;
+ z-index: 1;
+ padding-top: 20px;
+ padding-left: 5px;
+ margin: 0px;
+}
+#header-right .container .right #hostname {
+ position: relative;
+ height: 39px;
+ width: 431px;
+ z-index: 1;
+ padding-left: 5px;
+ margin: 0px;
+ top: 25px;
+ left: 230px;
+ font-size: 14px;
+ color: #cccccc;
+ font-weight: bold;
+}
+
+
+
+table#marquee {
+ position: relative;
+ top: -6px;
+ left: -5px;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ width: 424px;
+ background-color: transparent;
+ padding: 2px;
+ border: 0px;
+}
+span#marquee-container {
+ position: absolute;
+ visibility: hidden;
+ top: -100px;
+ left: -10000px;
+}
+div#marquee-text {
+ font-size: 1.18em;
+ font-weight: normal;
+ font-family: Verdana;
+ color: #ffffff;
+}
+table#marquee div#container {
+ position: relative;
+ overflow: hidden;
+ width: 418px;
+ height: 20px;
+}
+table#marquee div#container div#scroller {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+}
+
+
+
+
+
+#content {
+ position: relative;
+ top: -15px;
+ left: 0px;
+ margin-top: 0px;
+ margin-left: 0px;
+ padding-top: 0px;
+ width: 810px;
+ background-color: #ffffff;
+}
+
+#left {
+ width: 810px;
+ height: 1px;
+}
+#right {
+ position: relative;
+ top: -10px;
+ width: 770px;
+ margin-top: 0px;
+ margin-left: 5px;
+ margin-right: 5px;
+ padding-top: 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ padding-bottom: 20px;
+ min-height: 400px;
+}
+
+#footer {
+ position: relative;
+ background: url('images/footer.png') no-repeat;
+ top: -18px;
+ left: 0px;
+ width: 810px;
+ height: 75px;
+ color: #ffffff;
+ text-align: center;;
+ font-size: 0.9em;
+ padding-top: 17px;
+ margin-bottom: 20px;
+ clear: both;
+}
+#footer p {
+ padding: 0px;
+ margin: 0px;
+}
+
+/* Style the List */
+#navigation {
+ /* background: url('images/menu.gif') no-repeat; */
+ /* width: 693px; */
+ position: relative;
+ top: -25px;
+ left: 3px;
+ width: 810px;
+ padding: 0px;
+ height: 28px;
+ z-index: 3;
+}
+#navigation ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+ text-align: center;
+}
+#navigation ul#menu {
+ padding-top: 3px;
+ padding-left: 5px;
+}
+
+/* Style the List Elements */
+#navigation ul li {
+ float: left;
+ position: relative;
+ /* width: 7.5em; */
+ width: 8.77em;
+}
+#navigation ul li div {
+ font-size: 1em;
+ font-weight: bold;
+}
+/* Make the List inside the List Elements */
+/* initially hidden with absolute position */
+#navigation ul li ul {
+ display: none;
+ position: absolute;
+ top: 2em;
+ left: -2px;
+ width: 9em;
+ font-weight: normal;
+ background: transparent bottom left no-repeat; /* This is key to making the menu maintain visibility when not on a link */
+ /* background-color: #202020;
+ background: url("images/menu_footer.gif") no-repeat;
+ background-position: bottom;
+ */
+ padding: 0em 0 0.4em 0;
+ padding-top: 0.3em;
+}
+/* to override top and left in browsers other than IE */
+/* which will position to the top right of the containing */
+/* li, rather than bottom left */
+#navigation ul li > ul {
+ top: auto;
+ left: auto;
+ left: -1px !important;
+}
+/* Show initial drop down upon mouse over, but do not show */
+/* nested side drop menus within listed elements */
+#navigation ul li:hover ul {
+ display: block;
+ cursor: pointer;
+}
+#navigation ul li:hover {
+ cursor: pointer;
+ cursor: pointer;
+}
+#navigation ul li:hover div {
+ text-decoration: none;
+}
+
+#navigation ul li {
+ background-color: transparent;
+ color: #FFF;
+}
+#navigation ul li ul li {
+ border: 1px solid #990000;
+ width: 8.8em;
+ height: 1.6em;
+ line-height: 1.6em;
+ background-color: #990000;
+ color: #FFF;
+}
+#navigation ul li ul li:hover {
+ background-color: #666666;
+}
+
+#navigation li li a {
+ display: block;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+#navigation ul li ul li a.navlnk:hover {
+ text-decoration: none;
+}
+#navigation ul li.first {
+ border-right: 0px;
+}
+#navigation ul li.middle {
+ border-right: 0px;
+}
+#navigation ul li.last {
+
+}
+
+#navigation ul li.dropfirst {
+ border-bottom: 0px;
+}
+#navigation ul li.dropmiddle {
+ border-bottom: 0px;
+}
+#navigation ul li.droplast {
+}
+
+#wzdtabcont {
+ float: left;
+ background-color: #FFFFFF;
+ color: #000000;
+ padding: 0;
+}
+
+ul#wzdnav {
+ font-size: 0.96em;
+ float: left;
+ width: 14.5em;
+ margin: 0;
+ padding-left: 18px;
+}
+
+ul#wzdnav li {
+ list-style: none;
+ margin: 0;
+ padding-bottom: 0.2em;
+ padding-left: 0;
+}
+
+ul#wzdnav a {
+ display: block;
+ padding: 0.3em;
+ font-weight: normal;
+}
+
+#wzdnavbold a {
+ display: block;
+ padding: 0.3em;
+ font-weight: bold ! important;
+}
+
+ul#wzdnav a:link {
+ color: black;
+ background-color: #eee;
+}
+
+ul#wzdnav a:visited {
+ color: #666;
+ background-color: #eee;
+}
+
+ul#wzdnav a:hover {
+ color: black;
+ background-color: white;
+}
+
+ul#wzdnav a:active {
+ color: white;
+ background-color: gray;
+}
+
+#graph {
+ position: relative;
+ z-index: 10;
+}
+
+#logoutbtn {
+ position: absolute;
+ left: 95%;
+ vertical-align: middle;
+}
+
+
+#graph {
+ position: relative;
+ z-index: 10;
+}
+
+
+
+/* Class Based CSS Definitions */
+.pgtitle {
+ font-size: 18px;
+ color: #777777;
+ font-weight: bold;
+}
+.tfrtitle {
+ font-size: 18px;
+ color: #ffffff;
+ font-weight: bold;
+}
+.vncell {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ border-bottom: 1px solid #999999;
+}
+.formfld {
+ padding-left: 19px;
+ font-size: small;
+}
+.formselect {
+ font-size: 1.0em;
+}
+.langopt {
+ padding-left: 34px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.saved {
+ /* background: url('/themes/nione/images/icons/icon_wzd_saved.png') no-repeat 0 1px #FFFFFF; */
+ list-style-image: url('/themes/nervecenter/images/icons/icon_wzd_saved.png') ! important;
+}
+.notsaved {
+ /* background: url('/themes/nione/images/icons/icon_wzd_nsaved.png') no-repeat 0 1px #FFFFFF; */
+ list-style-image: url('/themes/nervecenter/images/icons/icon_wzd_nsaved.png') ! important;
+}
+.en {
+ background: url('/themes/nervecenter/images/icons/icon_flag_en.png') no-repeat 0 1px #FFFFFF;
+}
+.de {
+ background: url('/themes/nervecenter/images/icons/icon_flag_de.png') no-repeat 0 1px #FFFFFF;
+}
+.es {
+ background: url('/themes/nervecenter/images/icons/icon_flag_es.png') no-repeat 0 1px #FFFFFF;
+}
+.pt_BR {
+ background: url('/themes/nervecenter/images/icons/icon_flag_pt_BR.png') no-repeat 0 1px #FFFFFF;
+}
+.host {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_host.png') no-repeat 0 1px #FFFFFF;
+}
+.search {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_search.png') no-repeat 0 1px #FFFFFF;
+}
+.file {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_file.png') no-repeat 0 1px #FFFFFF;
+}
+.mail {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_mail.png') no-repeat 0 1px #FFFFFF;
+}
+.imp {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_imp.png') no-repeat 0 1px #FFFFFF;
+}
+.pwd {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_pwd.png') no-repeat 0 1px #FFFFFF;
+}
+.user {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_user.png') no-repeat 0 1px #FFFFFF ;
+}
+.group {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_group.png') no-repeat 0 1px #FFFFFF;
+}
+.url {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_url.png') no-repeat 0 1px #FFFFFF;
+}
+.time {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_time.png') no-repeat 0 1px #FFFFFF;
+}
+.unknown {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_unknown.png') no-repeat 0 1px #FFFFFF;
+}
+.formfld_cert {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_cert.png') no-repeat 0 1px #FFFFFF;
+ padding-left: 28px;
+ font-family: Courier New, Courier, monospaced;
+ font-size: 11px;
+}
+.formfldalias {
+ background-color: #990000;
+ color: #FFFFFF;
+}
+.formpre {
+ font-family: Courier New, Courier, monospaced;
+ font-size: 10px;
+}
+.formbtn {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 13px;
+ font-weight: bold;
+}
+.formbtns {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 10px;
+ font-weight: bold;
+}
+.vvcell {
+ background-color: #FFFFC6;
+}
+.errmsg {
+ font-weight: bold;
+ color: #CC0000;
+}
+.red {
+ color: #CC0000;
+}
+.gray {
+ color: #A0A0A0;
+}
+.vexpl {
+ font-size: 11px;
+}
+.navlnk {
+ color: #FFFFFF;
+ text-decoration: none;
+ font-size: 13px;
+}
+.navlnks {
+ color: #FFFFFF;
+ text-decoration: none;
+ font-size: 11px;
+}
+.redlnk {
+ color: #990000;
+ text-decoration: none;
+}
+.tblnk {
+ color: #FFFFFF;
+ text-decoration: none;
+}
+.vncellreq {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+}
+.vncellt {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+}
+.vtable {
+ border-bottom: 1px solid #999999;
+}
+.vnsepcell {
+ background-color: #BBBBBB;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.cpline {
+ font-size: 11px;
+ color: #FFFFFF;
+}
+.hostname {
+ font-size: 11px;
+ color: #990000;
+ font-weight: bold;
+}
+.vnsepcellr {
+ background-color: #BBBBBB;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.listr {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 6px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listrpad {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 16px;
+ padding-left: 10px;
+ padding-top: 8px;
+ padding-bottom: 8px;
+}
+.listn {
+ font-size: 11px;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listbg {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ background-color: #990000;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listbggrey {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ background-color: #999999;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listhdr {
+ background-color: #BBBBBB;
+ padding-right: 16px;
+ padding-left: 6px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.listhdr a {
+ color: #000000;
+}
+.listhdrr {
+ background-color: #BBBBBB;
+ padding-right: 16px;
+ padding-left: 6px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.listhdrr a {
+ color: #000000;
+}
+.listlr {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ border-left: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 6px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listlrns {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ border-left: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.list {
+ font-size: 11px;
+ padding-left: 6px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.listt {
+ font-size: 11px;
+ padding-top: 5px;
+}
+.listhdrrns {
+ background-color: #BBBBBB;
+ padding-left: 6px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ padding-right: 6px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.listbgns {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ background-color: #D9DEE8;
+ padding-left: 6px;
+ padding-right: 4px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listtopic {
+ border-right: 1px solid #999999;
+ font-size: 11px;
+ background-color: #990000;
+ padding-right: 16px;
+ padding-left: 6px;
+ color: #FFFFFF;
+ font-weight: bold;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.optsect_t {
+ border-right: 1px solid #999999;
+ background-color: #990000;
+ padding-right: 6px;
+ padding-left: 6px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.optsect_s {
+ font-size: 11px;
+ color: #FFFFFF;
+ font-weight: bold;
+}
+.tabnavtbl {
+}
+
+
+/* MISC CSS Definitions */
+ul#tabnav {
+ font-size: 11px;
+ font-weight: bold;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+ul#tabnav li.tabinact1 {
+ float: left;
+ background-color: #777777;
+ color: #FFFFFF;
+ padding: 0;
+ white-space: nowrap;
+}
+ul#tabnav li.tabinact {
+ float: left;
+ border-left: 1px solid #999999;
+ background-color: #777777;
+ color: #FFFFFF;
+ padding: 0;
+ white-space: nowrap;
+}
+ul#tabnav li.tabinact a {
+ float: left;
+ display: block;
+ text-decoration: none;
+ padding: 5px 8px 5px 8px;
+ color: #FFFFFF;
+}
+ul#tabnav li.tabinact1 a {
+ float: left;
+ display: block;
+ text-decoration: none;
+ padding: 5px 8px 5px 8px;
+ color: #FFFFFF;
+}
+ul#tabnav li.tabact {
+ float: left;
+ background-color: #EEEEEE;
+ color: #000000;
+ padding: 5px 8px 5px 8px;
+ white-space: nowrap;
+}
+.tabcont {
+ background-color: #EEEEEE;
+ padding-right: 12px;
+ padding-left: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
+}
+.tabact {
+ float: left;
+ background-color: #EEEEEE;
+ color: #000000;
+ padding: 5px 8px 5px 8px;
+ white-space: nowrap;
+}
+.tabinact {
+ font-weight: bold;
+ float: left;
+ border-left: 1px solid #999999;
+ background-color: #777777;
+ color: #FFFFFF;
+ padding: 0;
+ white-space: nowrap;
+}
+.menu {
+ background-color: #000000;
+ white-space: nowrap;
+ padding: 0px 5px 0px 5px;
+ width: 100%;
+ vertical-align: top;
+}
+
+
+/* Auto Complete Suggestions */
+div.suggestions {
+ -moz-box-sizing: border-box;
+ /* box-sizing: border-box; */
+ border: 1px solid black;
+ position: absolute;
+ background-color: #990000;
+ color: #FFF;
+}
+
+div.suggestions div {
+ cursor: default;
+ padding: 0px 3px;
+ background-color: #990000;
+ color: #FFF;
+}
+
+div.suggestions div.current {
+ background-color: #3366cc;
+ color: #FFF;
+}
+/* End Auto Complete Suggestions */
+
+
+/* Nifty Corners Crap */
+.rtop,.artop{display:block}
+.rtop *,.artop *{display:block;height:1px;overflow:hidden;font-size:1px}
+.artop *{border-style: solid;border-width:0 1px}
+.r1,.rl1,.re1,.rel1{margin-left:5px}
+.r1,.rr1,.re1,.rer1{margin-right:5px}
+.r2,.rl2,.re2,.rel2,.ra1,.ral1{margin-left:3px}
+.r2,.rr2,.re2,.rer2,.ra1,.rar1{margin-right:3px}
+.r3,.rl3,.re3,.rel3,.ra2,.ral2,.rs1,.rsl1,.res1,.resl1{margin-left:2px}
+.r3,.rr3,.re3,.rer3,.ra2,.rar2,.rs1,.rsr1,.res1,.resr1{margin-right:2px}
+.r4,.rl4,.rs2,.rsl2,.re4,.rel4,.ra3,.ral3,.ras1,.rasl1,.res2,.resl2{margin-left:1px}
+.r4,.rr4,.rs2,.rsr2,.re4,.rer4,.ra3,.rar3,.ras1,.rasr1,.res2,.resr2{margin-right:1px}
+.rx1,.rxl1{border-left-width:5px}
+.rx1,.rxr1{border-right-width:5px}
+.rx2,.rxl2{border-left-width:3px}
+.rx2,.rxr2{border-right-width:3px}
+.re2,.rel2,.ra1,.ral1,.rx3,.rxl3,.rxs1,.rxsl1{border-left-width:2px}
+.re2,.rer2,.ra1,.rar1,.rx3,.rxr3,.rxs1,.rxsr1{border-right-width:2px}
+.rxl1,.rxl2,.rxl3,.rxl4,.rxsl1,.rxsl2,.ral1,.ral2,.ral3,.ral4,.rasl1,.rasl2{border-right-width:0}
+.rxr1,.rxr2,.rxr3,.rxr4,.rxsr1,.rxsr2,.rar1,.rar2,.rar3,.rar4,.rasr1,.rasr2{border-left-width:0}
+.r4,.rl4,.rr4,.re4,.rel4,.rer4,.ra4,.rar4,.ral4,.rx4,.rxl4,.rxr4{height:2px}
+.rer1,.rel1,.re1,.res1,.resl1,.resr1{border-width:1px 0 0;height:0px !important;height /**/:1px}
+/* End Nifty Corners Crap */
+
+
+
+/* CSS for Dynamic Log Viewer */
+/* Author: Erik Kristensen */
+div#log div.log-entry {
+ clear: both;
+}
+
+div#log div.log-entry span,
+div#log div.log-header span {
+ padding: 3px 2px 3px 2px;
+ padding-left: 8px;
+}
+
+div#log div.log-entry span.log-action {
+ padding-bottom: 6px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+div#log div.log-header span {
+ border-top: 1px solid #999;
+ background-color: #bbb;
+ font-weight: bold;
+ text-align: left;
+}
+
+div#log span.log-action,
+div#log span.log-time,
+div#log span.log-interface,
+div#log span.log-source,
+div#log span.log-destination,
+div#log span.log-protocol {
+ float: left;
+ text-align: left;
+ border-left: 1px solid #999;
+ border-bottom: 1px solid #999;
+}
+
+div#log span.log-general {
+
+}
+
+div#log span.log-protocol {
+ border-right: 1px solid #999;
+}
+
+div#log span.log-action {
+ width: 2em;
+ text-align: center;
+}
+
+div#log span.log-time {
+ width: 12.5em;
+}
+
+div#log span.log-interface {
+ width: 5em;
+}
+
+div#log span.log-source,
+div#log span.log-destination {
+ width: 17.6em;
+}
+
+div#log span.log-protocol {
+ width: 5.5em;
+}
+/* END CSS FOR DYNAMIC LOG VIEWER */
+
+
+#login {
+/* background: #cccccc; */
+ background-color: transparent;
+ border: 0px solid #cccccc;
+ margin: 5em auto;
+ padding: 0em;
+ width: 400px;
+/* filter:alpha(opacity=60);
+ -moz-opacity:0.6;
+ -khtml-opacity: 0.6;
+ opacity: 0.6; */
+}
+
+#login h1 {
+ background: url(images/misc/logon.png) no-repeat top left;
+/* background: #ffffff; */
+ margin-top: 0;
+ display: block;
+ text-indent: -1000px;
+ height: 400px;
+ border-bottom: none;
+}
+
+#login p {
+ font-size: 1em;
+ font-weight: bold;
+ padding: 3px;
+ margin: 0em;
+/* text-indent: 10px; */
+ position: relative;
+ top: -420px;
+ left: 70px;
+}
+
+#login span {
+ font-size: 1em;
+ font-weight: bold;
+ width: 20%;
+ padding: 3px;
+ margin: 0em;
+/* text-indent: 10px; */
+}
+
+#login p#text {
+ font-size: 1em;
+ font-weight: normal;
+ padding: 3px;
+ margin: 0em;
+/* text-indent: 10px;
+ position: relative;
+ top: -300px; */
+}
+
+#login #username, #password {
+ font-size: 1em;
+ width: 60%;
+ padding: 3px;
+ margin: 0em;
+/* text-indent: 10px;
+ position: relative;
+ left: 10px;
+ top: -300px; */
+}
+
+#login #submit {
+ font-size: 1em;
+ font-weight: bold;
+ text-align: center;
+ padding: 3px;
+ margin: 0em;
+/* text-indent: 10px; */
+ position: relative;
+ top: -20px;
+ left: 170px;
+}
+
+/* loginerror box follows */
+
+#login #inputerrors {
+ background-color: transparent;
+ border: 0px solid #666666;
+ margin: 5em auto;
+ vertical-align: middle;
+ padding: 0em;
+ width: 330px;
+ height: 50px;
+ position: relative;
+ top: -370px;
+} \ No newline at end of file
diff --git a/usr/local/www/themes/pfsense_ng/menu.inc b/usr/local/www/themes/pfsense_ng/menu.inc
new file mode 100644
index 0000000..ae55e64
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/menu.inc
@@ -0,0 +1,178 @@
+<?php
+/* $Id: menu.inc,v 1.3.2.1 2007/01/17 18:43:30 sullrich Exp $ */
+/* DISABLE_PHP_LINT_CHECKING */
+/* ========================================================================== */
+/*
+ menu.inc
+ Copyright (C) 2006 Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ All rights reserved.
+ */
+/* ========================================================================== */
+/*
+ Originally part of m0n0wall (http://m0n0.ch/wall)
+ Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+/* ========================================================================== */
+
+require("menu.inc");
+
+define("TMENU_STUB", "
+ // set up drop downs anywhere in the body of the page. I think the bottom of the page is better..
+ // but you can experiment with effect on loadtime.
+ if (TransMenu.isSupported()) {
+
+ //==================================================================================================
+ // create a set of dropdowns
+ //==================================================================================================
+ // the first param should always be down, as it is here
+ //
+ // The second and third param are the top and left offset positions of the menus from their actuators
+ // respectively. To make a menu appear a little to the left and bottom of an actuator, you could use
+ // something like -5, 5
+ //
+ // The last parameter can be .topLeft, .bottomLeft, .topRight, or .bottomRight to inidicate the corner
+ // of the actuator from which to measure the offset positions above. Here we are saying we want the
+ // menu to appear directly below the bottom left corner of the actuator
+ //==================================================================================================
+ var ms = new TransMenuSet(TransMenu.direction.down, 1, 0, TransMenu.reference.bottomLeft);
+
+ //==================================================================================================
+ // create a dropdown menu
+ //==================================================================================================
+ // the first parameter should be the HTML element which will act actuator for the menu
+ //==================================================================================================
+
+ @@MENU_DEFINITIONS@@
+
+ //==================================================================================================
+ // write drop downs into page
+ //==================================================================================================
+ // this method writes all the HTML for the menus into the page with document.write(). It must be
+ // called within the body of the HTML page.
+ //==================================================================================================
+ TransMenu.renderAll();
+ }
+");
+
+class NervecenterMenu extends Menu {
+ private $menuJScript = "NOT-SET";
+ private $menuJScriptEvents = "NOT-SET";
+ private $menuID = "NOT-SET";
+
+ public function __construct($identification = "", $filename = "", Component $c = NULL) {
+ parent::__construct($identification, $filename, $c);
+
+ $id = "mnua_" . str_replace(" ", "", strtolower($this->getID()));
+ $this->menuID = $id;
+
+ if ($this->hasParent()) {
+ $this->menuJScript = "\tvar {$id} = ms.addMenu(document.getElementById('{$id}'));\n";
+ }
+ } // end __construct
+
+ public function getMenuID() {
+ return $this->menuID;
+ }
+
+ public function setMenuID($myMenuID) {
+ $this->menuID = $myMenuID;
+ }
+
+ public function getMenuJScript() {
+ $childJScript = "";
+ foreach ($this->getChildren() as $component) {
+ $childJScript .= $component->getMenuJScript();
+ }
+
+ if (! $this->hasParent()) {
+ $this->menuJScript = str_replace("@@MENU_DEFINITIONS@@", $childJScript, TMENU_STUB);
+ } else {
+ $this->menuJScript .= "\n$childJScript\n";
+ }
+
+ return $this->menuJScript;
+ }
+
+ public function getMenuJScriptEvents() {
+ return $this->menuJScriptEvents;
+ }
+
+ public function __toString() {
+ if (! $this->hasParent()) {
+ $menuMarkup =<<<EOD
+ <div id="menu">
+ @@CHILD_ELEMENTS@@
+ </div>
+
+EOD;
+ } else {
+ $name = gettext($this->getID());
+ $id = "mnua_" . str_replace(" ", "", strtolower($this->getID()));
+
+ $menuMarkup =<<<EOD
+ <a id="{$id}" href="#">{$name}</a>
+ @@CHILD_ELEMENTS@@
+EOD;
+ }
+
+ $childMarkup = "";
+ foreach ($this->getChildren() as $component) {
+ $childMarkup .= $component;
+ }
+
+ $menuMarkup = str_replace("@@CHILD_ELEMENTS@@", $childMarkup, $menuMarkup);
+
+ return $menuMarkup;
+ }
+}
+
+class NervecenterMenuItem extends MenuItem {
+ private $menuJScript = "NOT-SET";
+ private $menuJScriptEvents = "NOT-SET";
+
+ public function __construct($identification = "", $filename = "", $href = "", Component $c = NULL) {
+ parent::__construct($identification, $filename, $href, $c);
+
+ $href = $this->getHref() <> "" ? $this->getHref() : "{$this->getFile()}";
+ $name = gettext($this->getID());
+ $file = $this->getFile();
+
+ $this->menuJScript = $this->check_access("{$file}", "\t{$this->getParent()->getMenuID()}.addItem('{$name}', '{$href}');\n");
+ }
+
+ public function getMenuJScript() {
+ return $this->menuJScript;
+ }
+
+ public function getMenuJScriptEvents() {
+ return $this->menuJScriptEvents;
+ }
+
+ public function __toString() {
+ return "";
+ }
+}
+
+?>
diff --git a/usr/local/www/themes/pfsense_ng/no_big_logo b/usr/local/www/themes/pfsense_ng/no_big_logo
new file mode 100644
index 0000000..6e5c70d
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/no_big_logo
@@ -0,0 +1 @@
+NO! DONT! \ No newline at end of file
diff --git a/usr/local/www/themes/_orange-flow/rrdcolors.inc.php b/usr/local/www/themes/pfsense_ng/rrdcolors.inc.php
index 14eb2cc..9360d0c 100644
--- a/usr/local/www/themes/_orange-flow/rrdcolors.inc.php
+++ b/usr/local/www/themes/pfsense_ng/rrdcolors.inc.php
@@ -30,10 +30,10 @@
/* This file is included by the RRD graphing page and sets the colors */
-$colortrafficup = "666666";
-$colortrafficdown = "990000";
-$colorpacketsup = "666666";
-$colorpacketsdown = "990000";
+$colortrafficup = array("666666", "CCCCCC");
+$colortrafficdown = array("990000", "CC0000");
+$colorpacketsup = array("666666", "CCCCCC");
+$colorpacketsdown = array("990000", "CC0000");
$colorstates = array('990000','a83c3c','b36666','bd9090','cccccc','000000');
$colorprocessor = array('990000','a83c3c','b36666','bd9090','cccccc','000000');
$colormemory = array('990000','a83c3c','b36666','bd9090','cccccc','000000');
@@ -43,6 +43,7 @@ $colorqueuesdropup = array('000000','7B0000','990000','BB0000','CC0000','D90000'
$colorqueuesdropdown = array('000000','7B7B7B','999999','BBBBBB','CCCCCC','D9D9D9','EEEEEE','FFFFFF','CCCCCC');
$colorqualityrtt = array('990000','a83c3c','b36666','bd9090','cccccc','000000');
$colorqualityloss = "ee0000";
+$colorwireless = array('990000','a83c3c','b36666');
$colorspamdtime = array('DDDDFF', 'AAAAFF', 'DDDDFF', '000066');
$colorspamdconn = array('00AA00BB', 'FFFFFFFF', '00660088', 'FFFFFF88', '006600');
diff --git a/usr/local/www/themes/pfsense_ng/styles/menustyles.css b/usr/local/www/themes/pfsense_ng/styles/menustyles.css
new file mode 100644
index 0000000..06b3c7a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/styles/menustyles.css
@@ -0,0 +1,44 @@
+#navigation {
+ /* border:1px solid black; */
+ width: 98%;
+ vertical-align: middle;
+ height: 16px;
+ padding-top: 4px;
+ }
+
+#menu {
+ /* background: #990000; */
+ /* border-bottom:1px solid white; */
+ padding: 0 0 0 0;
+ width: 98%;
+ vertical-align: middle;
+ height: 16px;
+ }
+#menu a {
+ padding: 2px 28px 4px 28px;
+ text-decoration: none;
+ font-weight: bold;
+ font-size: 1.0em;
+ color: #FFFFFF;
+ width: 08%;
+ height: 16px;
+ }
+#menu a.hover {
+ background: #AF2020;
+ }
+#menu span {
+ display: none;
+ }
+
+#subnav {
+ font-size: 10px;
+ margin-bottom: 2em;
+ }
+#subnav a {
+ color: #FF0000; /* #FB3B00; */
+ margin-right: 1em;
+ }
+#subnav span {
+ color: silver;
+ margin-right: 1em;
+ }
diff --git a/usr/local/www/themes/pfsense_ng/styles/transmenu.css b/usr/local/www/themes/pfsense_ng/styles/transmenu.css
new file mode 100644
index 0000000..f683574
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/styles/transmenu.css
@@ -0,0 +1,75 @@
+/* this is the clipping region for the menu. it's width and height get set by script, depending on the size of the items table */
+.transMenu {
+ position:absolute;
+ overflow:hidden;
+ left:-1000px;
+ top:-1000px;
+ }
+
+/* this is the main container for the menu itself. it's width and height get set by script, depending on the size of the items table */
+.transMenu .content {
+ position:absolute;
+ }
+
+/* this table comprises all menu items. each TR is one item. It is relatively positioned so that the shadow and background transparent divs can be positioned underneath it */
+.transMenu .items {
+ position:relative;
+ left:0px; top:0px;
+ z-index:2;
+ }
+
+.transMenu.top .items {
+ border-top:none;
+ }
+
+/* each TR.item is one menu item */
+.transMenu .item {
+ color: #FFFFFF; /* #336; */
+ font-size: 1.1em;
+ font-weight: normal;
+ font-family:sans-serif;
+ text-decoration:none;
+ /* this is a hack for mac/ie5, whom incorrectly cascades the border properties of the parent table to each row */
+ border:none;
+ cursor:pointer;
+ cursor:hand;
+ }
+
+/* this DIV is the semi-transparent white background of each menu. the -moz-opacity is a proprietary way to get transparency in mozilla, the filter is for IE/windows 5.0+. */
+/* we set the background color in script because ie mac does not use it; that browser only uses a semi-transparent white PNG that the spacer gif inside this DIV is replaced by */
+.transMenu .background {
+ position:absolute;
+ left:0px; top:0px;
+ z-index:1;
+ -moz-opacity:.8;
+ filter:alpha(opacity=80);
+ }
+
+/* same concept as .background, but this is the sliver of shadow on the right of the menu. It's left, height, and background are set by script. In IE5/mac, it uses a PNG */
+.transMenu .shadowRight {
+ position:absolute;
+ z-index:3;
+ top:3px; width:2px;
+ -moz-opacity:.4;
+ filter:alpha(opacity=40);
+ }
+
+/* same concept as .background, but this is the sliver of shadow on the bottom of the menu. It's top, width, and background are set by script. In IE5/mac, it uses a PNG */
+.transMenu .shadowBottom {
+ position:absolute;
+ z-index:1;
+ left:3px; height:2px;
+ -moz-opacity:.4;
+ filter:alpha(opacity=40);
+ }
+
+/* this is the class that is used when the mouse is over an item. script sets the row to this class when required. */
+.transMenu .item.hover {
+ background:#fdfdfd;
+ color:black;
+ }
+
+/* this is either the dingbat that indicates there is a submenu, or a spacer gif in it's place. We give it extra margin to create some space between the text and the dingbat */
+.transMenu .item img {
+ margin-left:10px;
+ } \ No newline at end of file
diff --git a/usr/local/www/themes/pfsense_ng/wizard.css b/usr/local/www/themes/pfsense_ng/wizard.css
new file mode 100644
index 0000000..1c4596a
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/wizard.css
@@ -0,0 +1,1065 @@
+/* Element CSS Definitions */
+html, body, td, th, input, select {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 0.9em;
+
+}
+
+/* please adjust the bgcolor to be used together with niftycorners! */
+.rtop, .artop {
+ background-color: #999999;
+}
+
+div.GraphLink {
+ position: relative;
+}
+
+span.GraphLinkLine {
+ position: absolute;
+ background-color: #990000;
+ width: 100%;
+}
+
+/* DOM Tooltip CSS definitions */
+div.niceTitle
+{
+ background-color: #333333;
+ color: #FFFFFF;
+ border-bottom: 1px dotted #FFFFFF;
+ font-weight: bold;
+ font-size: 13px;
+ font-family: "Trebuchet MS", sans-serif;
+ width: 250px;
+ left: 0;
+ top: 0;
+ padding: 4px;
+ position: absolute;
+ text-align: left;
+ z-index: 20;
+ -moz-border-radius: 0 10px 10px 10px;
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=87);
+ -moz-opacity: .87;
+ -khtml-opacity: .87;
+ opacity: .87;
+}
+div.niceTitle h1
+{
+ background: #990000;
+ border-bottom: 1px dotted #FFFFFF;
+ font-weight: bold;
+ font-size: 13px;
+ font-family: "Trebuchet MS", sans-serif;
+ margin: 3px;
+ padding-top: 1px;
+ padding-bottom: 1px;
+ padding-left: 3px;
+ text-align: left;
+ left: 0;
+ top: 0;
+ -moz-border-radius: 0 8px 0 0;
+ -moz-opacity: 1;
+}
+div.niceTitle .contents
+{
+ margin: 0;
+ padding: 0 3px;
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=100);
+ -moz-opacity: 1;
+ -khtml-opacity: 1;
+ opacity: 1;
+}
+div.niceTitle p
+{
+ background: #FFFFFF;
+ border: 1px solid #990000;
+ color: #000000;
+ font-size: 9px;
+ padding: 5px;
+ margin: 3px;
+ text-align: left;
+ -moz-opacity: 1;
+ -moz-border-radius: 0 0 8px 8px;
+}
+
+body {
+ margin: 0px auto;
+ /* background: url('images/background.png') no-repeat; */
+ background-position : center 0px;
+ background-color: #999999;
+}
+
+form {
+ margin: 0px;
+}
+a {
+ text-decoration: none;
+}
+form input {
+ font-size: 1.1em;
+}
+
+iframe {
+ z-index: 1;
+ border: 1px dashed #990000;
+}
+.iframe {
+ background-color: #FFFFFF;
+}
+
+/* ID Based CSS Definitions */
+#wrapper {
+ width: 810px;
+ margin: 0px auto;
+}
+
+#header {
+ background: url('images/header.png') no-repeat;
+ background-position: 0px;
+ height: 102px;
+ width: 810px;
+ margin-bottom: 5px;
+ z-index: 2;
+}
+#header-left {
+ position: relative;
+ /* background: url('images/logo.gif') no-repeat; */
+ background-position: center;
+ height: 65px;
+ width: 145px;
+ left: 10px;
+ float: left;
+}
+#header-left #status-link {
+ position: relative;
+ top: 10px;
+ left: 6px;
+}
+#header-right {
+ position: relative;
+ /* background: url('images/header.gif') no-repeat; */
+ height: 70px;
+ color: #fff;
+ left: 0px;
+ margin-left: 165px;
+}
+#header-right .alert {
+ position: relative;
+ /* background: url('images/alert.gif') no-repeat; */
+ background-position: 4px 2px;
+ color: #fff;
+ height: 17px;
+ width: 500px;
+ padding: 4px;
+ padding-left: 27px;
+ float: left;
+}
+#header-right .container {
+ position: relative;
+}
+#header-right .container .left {
+ position: relative;
+ float: left;
+ font-size: 1.3em;
+ font-weight: bold;
+ top: 15px;
+ left: 4px;
+ display: none;
+}
+#header-right .container .right {
+ position: relative;
+ float: right;
+ top: 22px;
+ padding-right: 4px;
+ z-index: 1;
+}
+
+#header-right .container .right #alerts {
+ position: relative;
+ background: url('images/alert_bgr.png') no-repeat;
+ height: 39px;
+ width: 431px;
+ z-index: 1;
+ padding-top: 20px;
+ padding-left: 5px;
+ margin: 0px;
+}
+#header-right .container .right #hostname {
+ position: relative;
+ height: 39px;
+ width: 431px;
+ z-index: 1;
+ padding-left: 5px;
+ margin: 0px;
+ top: 25px;
+ left: 230px;
+ font-size: 14px;
+ color: #cccccc;
+ font-weight: bold;
+}
+
+
+
+table#marquee {
+ position: relative;
+ top: -6px;
+ left: -5px;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ width: 424px;
+ background-color: transparent;
+ padding: 2px;
+ border: 0px;
+}
+span#marquee-container {
+ position: absolute;
+ visibility: hidden;
+ top: -100px;
+ left: -10000px;
+}
+div#marquee-text {
+ font-size: 1.18em;
+ font-weight: normal;
+ font-family: Verdana;
+ color: #ffffff;
+}
+table#marquee div#container {
+ position: relative;
+ overflow: hidden;
+ width: 418px;
+ height: 20px;
+}
+table#marquee div#container div#scroller {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+}
+
+
+
+
+
+#content {
+ position: relative;
+ top: -15px;
+ left: 0px;
+ margin-top: 0px;
+ margin-left: 0px;
+ padding-top: 0px;
+ width: 810px;
+ background-color: #ffffff;
+}
+
+#left {
+ width: 810px;
+ height: 1px;
+}
+#right {
+ position: relative;
+ top: -10px;
+ width: 770px;
+ margin-top: 0px;
+ margin-left: 5px;
+ margin-right: 5px;
+ padding-top: 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ padding-bottom: 20px;
+ min-height: 400px;
+}
+
+#footer {
+ position: relative;
+ background: url('images/footer.png') no-repeat;
+ top: -18px;
+ left: 0px;
+ width: 810px;
+ height: 75px;
+ color: #ffffff;
+ text-align: center;;
+ font-size: 0.9em;
+ padding-top: 17px;
+ margin-bottom: 20px;
+ clear: both;
+}
+#footer p {
+ padding: 0px;
+ margin: 0px;
+}
+
+/* Style the List */
+#navigation {
+ /* background: url('images/menu.gif') no-repeat; */
+ /* width: 693px; */
+ position: relative;
+ top: -25px;
+ left: 3px;
+ width: 810px;
+ padding: 0px;
+ height: 28px;
+ z-index: 3;
+}
+#navigation ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+ text-align: center;
+}
+#navigation ul#menu {
+ padding-top: 3px;
+ padding-left: 5px;
+}
+
+/* Style the List Elements */
+#navigation ul li {
+ float: left;
+ position: relative;
+ /* width: 7.5em; */
+ width: 8.77em;
+}
+#navigation ul li div {
+ font-size: 1em;
+ font-weight: bold;
+}
+/* Make the List inside the List Elements */
+/* initially hidden with absolute position */
+#navigation ul li ul {
+ display: none;
+ position: absolute;
+ top: 2em;
+ left: -2px;
+ width: 9em;
+ font-weight: normal;
+ background: transparent bottom left no-repeat; /* This is key to making the menu maintain visibility when not on a link */
+ /* background-color: #202020;
+ background: url("images/menu_footer.gif") no-repeat;
+ background-position: bottom;
+ */
+ padding: 0em 0 0.4em 0;
+ padding-top: 0.3em;
+}
+/* to override top and left in browsers other than IE */
+/* which will position to the top right of the containing */
+/* li, rather than bottom left */
+#navigation ul li > ul {
+ top: auto;
+ left: auto;
+ left: -1px !important;
+}
+/* Show initial drop down upon mouse over, but do not show */
+/* nested side drop menus within listed elements */
+#navigation ul li:hover ul {
+ display: block;
+ cursor: pointer;
+}
+#navigation ul li:hover {
+ cursor: pointer;
+ cursor: pointer;
+}
+#navigation ul li:hover div {
+ text-decoration: none;
+}
+
+#navigation ul li {
+ background-color: transparent;
+ color: #FFF;
+}
+#navigation ul li ul li {
+ border: 1px solid #990000;
+ width: 8.8em;
+ height: 1.6em;
+ line-height: 1.6em;
+ background-color: #990000;
+ color: #FFF;
+}
+#navigation ul li ul li:hover {
+ background-color: #666666;
+}
+
+#navigation li li a {
+ display: block;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+#navigation ul li ul li a.navlnk:hover {
+ text-decoration: none;
+}
+#navigation ul li.first {
+ border-right: 0px;
+}
+#navigation ul li.middle {
+ border-right: 0px;
+}
+#navigation ul li.last {
+
+}
+
+#navigation ul li.dropfirst {
+ border-bottom: 0px;
+}
+#navigation ul li.dropmiddle {
+ border-bottom: 0px;
+}
+#navigation ul li.droplast {
+}
+
+#wzdtabcont {
+ float: left;
+ background-color: #FFFFFF;
+ color: #000000;
+ padding: 0;
+}
+
+ul#wzdnav {
+ font-size: 0.96em;
+ float: left;
+ width: 14.5em;
+ margin: 0;
+ padding-left: 18px;
+}
+
+ul#wzdnav li {
+ list-style: none;
+ margin: 0;
+ padding-bottom: 0.2em;
+ padding-left: 0;
+}
+
+ul#wzdnav a {
+ display: block;
+ padding: 0.3em;
+ font-weight: normal;
+}
+
+#wzdnavbold a {
+ display: block;
+ padding: 0.3em;
+ font-weight: bold ! important;
+}
+
+ul#wzdnav a:link {
+ color: black;
+ background-color: #eee;
+}
+
+ul#wzdnav a:visited {
+ color: #666;
+ background-color: #eee;
+}
+
+ul#wzdnav a:hover {
+ color: black;
+ background-color: white;
+}
+
+ul#wzdnav a:active {
+ color: white;
+ background-color: gray;
+}
+
+#graph {
+ position: relative;
+ z-index: 10;
+}
+
+#logoutbtn {
+ position: absolute;
+ left: 95%;
+ vertical-align: middle;
+}
+
+
+#graph {
+ position: relative;
+ z-index: 10;
+}
+
+
+
+/* Class Based CSS Definitions */
+.pgtitle {
+ font-size: 18px;
+ color: #777777;
+ font-weight: bold;
+}
+.tfrtitle {
+ font-size: 18px;
+ color: #ffffff;
+ font-weight: bold;
+}
+.vncell {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ border-bottom: 1px solid #999999;
+}
+.formfld {
+ font-size: small;
+}
+.formselect {
+ font-size: 1.0em;
+}
+.langopt {
+ padding-left: 34px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.saved {
+ /* background: url('/themes/nione/images/icons/icon_wzd_saved.png') no-repeat 0 1px #FFFFFF; */
+ list-style-image: url('/themes/nervecenter/images/icons/icon_wzd_saved.png') ! important;
+}
+.notsaved {
+ /* background: url('/themes/nione/images/icons/icon_wzd_nsaved.png') no-repeat 0 1px #FFFFFF; */
+ list-style-image: url('/themes/nervecenter/images/icons/icon_wzd_nsaved.png') ! important;
+}
+.en {
+ background: url('/themes/nervecenter/images/icons/icon_flag_en.png') no-repeat 0 1px #FFFFFF;
+}
+.de {
+ background: url('/themes/nervecenter/images/icons/icon_flag_de.png') no-repeat 0 1px #FFFFFF;
+}
+.es {
+ background: url('/themes/nervecenter/images/icons/icon_flag_es.png') no-repeat 0 1px #FFFFFF;
+}
+.pt_BR {
+ background: url('/themes/nervecenter/images/icons/icon_flag_pt_BR.png') no-repeat 0 1px #FFFFFF;
+}
+.host {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_host.png') no-repeat 0 1px #FFFFFF;
+}
+.search {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_search.png') no-repeat 0 1px #FFFFFF;
+}
+.file {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_file.png') no-repeat 0 1px #FFFFFF;
+}
+.mail {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_mail.png') no-repeat 0 1px #FFFFFF;
+}
+.imp {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_imp.png') no-repeat 0 1px #FFFFFF;
+}
+.pwd {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_pwd.png') no-repeat 0 1px #FFFFFF;
+}
+.user {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_user.png') no-repeat 0 1px #FFFFFF ;
+}
+.group {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_group.png') no-repeat 0 1px #FFFFFF;
+}
+.url {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_url.png') no-repeat 0 1px #FFFFFF;
+}
+.time {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_time.png') no-repeat 0 1px #FFFFFF;
+}
+.unknown {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_unknown.png') no-repeat 0 1px #FFFFFF;
+}
+.formfld_cert {
+ background: url('/themes/nervecenter/images/icons/icon_frmfld_cert.png') no-repeat 0 1px #FFFFFF;
+ padding-left: 28px;
+ font-family: Courier New, Courier, monospaced;
+ font-size: 11px;
+}
+.formfldalias {
+ background-color: #990000;
+ color: #FFFFFF;
+}
+.formpre {
+ font-family: Courier New, Courier, monospaced;
+ font-size: 10px;
+}
+.formbtn {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 13px;
+ font-weight: bold;
+}
+.formbtns {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 10px;
+ font-weight: bold;
+}
+.vvcell {
+ background-color: #FFFFC6;
+}
+.errmsg {
+ font-weight: bold;
+ color: #CC0000;
+}
+.red {
+ color: #CC0000;
+}
+.gray {
+ color: #A0A0A0;
+}
+.vexpl {
+ font-size: 11px;
+}
+.navlnk {
+ color: #FFFFFF;
+ text-decoration: none;
+ font-size: 13px;
+}
+.navlnks {
+ color: #FFFFFF;
+ text-decoration: none;
+ font-size: 11px;
+}
+.redlnk {
+ color: #990000;
+ text-decoration: none;
+}
+.tblnk {
+ color: #FFFFFF;
+ text-decoration: none;
+}
+.vncellreq {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+}
+.vncellt {
+ background-color: #DDDDDD;
+ padding-right: 20px;
+ padding-left: 8px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+}
+.vtable {
+ border-bottom: 1px solid #999999;
+}
+.vnsepcell {
+ background-color: #BBBBBB;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.cpline {
+ font-size: 11px;
+ color: #FFFFFF;
+}
+.hostname {
+ font-size: 11px;
+ color: #990000;
+ font-weight: bold;
+}
+.vnsepcellr {
+ background-color: #BBBBBB;
+ padding-right: 20px;
+ padding-left: 8px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.listr {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 6px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listrpad {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 16px;
+ padding-left: 10px;
+ padding-top: 8px;
+ padding-bottom: 8px;
+}
+.listn {
+ font-size: 11px;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listbg {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ background-color: #990000;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listbggrey {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ background-color: #999999;
+ padding-right: 16px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listhdr {
+ background-color: #BBBBBB;
+ padding-right: 16px;
+ padding-left: 6px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.listhdr a {
+ color: #000000;
+}
+.listhdrr {
+ background-color: #BBBBBB;
+ padding-right: 16px;
+ padding-left: 6px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.listhdrr a {
+ color: #000000;
+}
+.listlr {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ border-left: 1px solid #999999;
+ font-size: 11px;
+ padding-right: 6px;
+ padding-left: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listlrns {
+ background-color: #FFFFFF;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ border-left: 1px solid #999999;
+ font-size: 11px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.list {
+ font-size: 11px;
+ padding-left: 6px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.listt {
+ font-size: 11px;
+ padding-top: 5px;
+}
+.listhdrrns {
+ background-color: #BBBBBB;
+ padding-left: 6px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ padding-right: 6px;
+ font-weight: bold;
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+}
+.listbgns {
+ border-right: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ font-size: 11px;
+ background-color: #D9DEE8;
+ padding-left: 6px;
+ padding-right: 4px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+.listtopic {
+ border-right: 1px solid #999999;
+ font-size: 11px;
+ background-color: #990000;
+ padding-right: 16px;
+ padding-left: 6px;
+ color: #FFFFFF;
+ font-weight: bold;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.optsect_t {
+ border-right: 1px solid #999999;
+ background-color: #990000;
+ padding-right: 6px;
+ padding-left: 6px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+.optsect_s {
+ font-size: 11px;
+ color: #FFFFFF;
+ font-weight: bold;
+}
+.tabnavtbl {
+}
+
+
+/* MISC CSS Definitions */
+ul#tabnav {
+ font-size: 11px;
+ font-weight: bold;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+ul#tabnav li.tabinact1 {
+ float: left;
+ background-color: #777777;
+ color: #FFFFFF;
+ padding: 0;
+ white-space: nowrap;
+}
+ul#tabnav li.tabinact {
+ float: left;
+ border-left: 1px solid #999999;
+ background-color: #777777;
+ color: #FFFFFF;
+ padding: 0;
+ white-space: nowrap;
+}
+ul#tabnav li.tabinact a {
+ float: left;
+ display: block;
+ text-decoration: none;
+ padding: 5px 8px 5px 8px;
+ color: #FFFFFF;
+}
+ul#tabnav li.tabinact1 a {
+ float: left;
+ display: block;
+ text-decoration: none;
+ padding: 5px 8px 5px 8px;
+ color: #FFFFFF;
+}
+ul#tabnav li.tabact {
+ float: left;
+ background-color: #EEEEEE;
+ color: #000000;
+ padding: 5px 8px 5px 8px;
+ white-space: nowrap;
+}
+.tabcont {
+ background-color: #EEEEEE;
+ padding-right: 12px;
+ padding-left: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
+}
+.tabact {
+ float: left;
+ background-color: #EEEEEE;
+ color: #000000;
+ padding: 5px 8px 5px 8px;
+ white-space: nowrap;
+}
+.tabinact {
+ font-weight: bold;
+ float: left;
+ border-left: 1px solid #999999;
+ background-color: #777777;
+ color: #FFFFFF;
+ padding: 0;
+ white-space: nowrap;
+}
+.menu {
+ background-color: #000000;
+ white-space: nowrap;
+ padding: 0px 5px 0px 5px;
+ width: 100%;
+ vertical-align: top;
+}
+
+
+/* Auto Complete Suggestions */
+div.suggestions {
+ -moz-box-sizing: border-box;
+ /* box-sizing: border-box; */
+ border: 1px solid black;
+ position: absolute;
+ background-color: #990000;
+ color: #FFF;
+}
+
+div.suggestions div {
+ cursor: default;
+ padding: 0px 3px;
+ background-color: #990000;
+ color: #FFF;
+}
+
+div.suggestions div.current {
+ background-color: #3366cc;
+ color: #FFF;
+}
+/* End Auto Complete Suggestions */
+
+
+/* Nifty Corners Crap */
+.rtop,.artop{display:block}
+.rtop *,.artop *{display:block;height:1px;overflow:hidden;font-size:1px}
+.artop *{border-style: solid;border-width:0 1px}
+.r1,.rl1,.re1,.rel1{margin-left:5px}
+.r1,.rr1,.re1,.rer1{margin-right:5px}
+.r2,.rl2,.re2,.rel2,.ra1,.ral1{margin-left:3px}
+.r2,.rr2,.re2,.rer2,.ra1,.rar1{margin-right:3px}
+.r3,.rl3,.re3,.rel3,.ra2,.ral2,.rs1,.rsl1,.res1,.resl1{margin-left:2px}
+.r3,.rr3,.re3,.rer3,.ra2,.rar2,.rs1,.rsr1,.res1,.resr1{margin-right:2px}
+.r4,.rl4,.rs2,.rsl2,.re4,.rel4,.ra3,.ral3,.ras1,.rasl1,.res2,.resl2{margin-left:1px}
+.r4,.rr4,.rs2,.rsr2,.re4,.rer4,.ra3,.rar3,.ras1,.rasr1,.res2,.resr2{margin-right:1px}
+.rx1,.rxl1{border-left-width:5px}
+.rx1,.rxr1{border-right-width:5px}
+.rx2,.rxl2{border-left-width:3px}
+.rx2,.rxr2{border-right-width:3px}
+.re2,.rel2,.ra1,.ral1,.rx3,.rxl3,.rxs1,.rxsl1{border-left-width:2px}
+.re2,.rer2,.ra1,.rar1,.rx3,.rxr3,.rxs1,.rxsr1{border-right-width:2px}
+.rxl1,.rxl2,.rxl3,.rxl4,.rxsl1,.rxsl2,.ral1,.ral2,.ral3,.ral4,.rasl1,.rasl2{border-right-width:0}
+.rxr1,.rxr2,.rxr3,.rxr4,.rxsr1,.rxsr2,.rar1,.rar2,.rar3,.rar4,.rasr1,.rasr2{border-left-width:0}
+.r4,.rl4,.rr4,.re4,.rel4,.rer4,.ra4,.rar4,.ral4,.rx4,.rxl4,.rxr4{height:2px}
+.rer1,.rel1,.re1,.res1,.resl1,.resr1{border-width:1px 0 0;height:0px !important;height /**/:1px}
+/* End Nifty Corners Crap */
+
+
+
+/* CSS for Dynamic Log Viewer */
+/* Author: Erik Kristensen */
+div#log div.log-entry {
+ clear: both;
+}
+
+div#log div.log-entry span,
+div#log div.log-header span {
+ padding: 3px 2px 3px 2px;
+ padding-left: 8px;
+}
+
+div#log div.log-entry span.log-action {
+ padding-bottom: 6px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+div#log div.log-header span {
+ border-top: 1px solid #999;
+ background-color: #bbb;
+ font-weight: bold;
+ text-align: left;
+}
+
+div#log span.log-action,
+div#log span.log-time,
+div#log span.log-interface,
+div#log span.log-source,
+div#log span.log-destination,
+div#log span.log-protocol {
+ float: left;
+ text-align: left;
+ border-left: 1px solid #999;
+ border-bottom: 1px solid #999;
+}
+
+div#log span.log-general {
+
+}
+
+div#log span.log-protocol {
+ border-right: 1px solid #999;
+}
+
+div#log span.log-action {
+ width: 2em;
+ text-align: center;
+}
+
+div#log span.log-time {
+ width: 12.5em;
+}
+
+div#log span.log-interface {
+ width: 5em;
+}
+
+div#log span.log-source,
+div#log span.log-destination {
+ width: 17.6em;
+}
+
+div#log span.log-protocol {
+ width: 5.5em;
+}
+/* END CSS FOR DYNAMIC LOG VIEWER */
+
+#login {
+ background: #cccccc;
+ border: 0px solid #666666;
+ margin: 5em auto;
+ padding: 0em;
+ width: 340px;
+}
+
+#login h1 {
+ background: url(images/misc/logon.png) no-repeat top left;
+ margin-top: 0;
+ display: block;
+ text-indent: -1000px;
+ height: 50px;
+ border-bottom: none;
+}
+
+#login p {
+ font-size: 1em;
+ font-weight: bold;
+ padding: 3px;
+ margin: 0em;
+ text-indent: 10px;
+}
+
+#login span {
+ font-size: 1em;
+ font-weight: bold;
+ width: 20%;
+ padding: 3px;
+ margin: 0em;
+ text-indent: 10px;
+}
+
+#login p#text {
+ font-size: 1em;
+ font-weight: normal;
+ padding: 3px;
+ margin: 0em;
+ text-indent: 10px;
+}
+
+#login #username, #password {
+ font-size: 1em;
+ width: 60%;
+ padding: 3px;
+ margin: 0em;
+}
+
+#login #submit {
+ font-size: 1em;
+ font-weight: bold;
+ padding: 3px;
+ margin: 0em;
+ text-indent: 10px;
+}
diff --git a/usr/local/www/themes/the_wall/all.css b/usr/local/www/themes/the_wall/all.css
index 039285b..0fe39e2 100644
--- a/usr/local/www/themes/the_wall/all.css
+++ b/usr/local/www/themes/the_wall/all.css
@@ -1251,8 +1251,10 @@ div#log span.log-protocol-mini-header {
/* Sortable tables */
table.sortable thead {
- background-color:#eee;
- color:#666666;
- font-weight: bold;
cursor: default;
+ background-color: #EEEEEE;
+ padding-right: 12px;
+ padding-left: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
}
diff --git a/usr/local/www/themes/the_wall/images/button_left.gif b/usr/local/www/themes/the_wall/images/button_left.gif
deleted file mode 100644
index 2e46d25..0000000
--- a/usr/local/www/themes/the_wall/images/button_left.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/button_mid.gif b/usr/local/www/themes/the_wall/images/button_mid.gif
deleted file mode 100644
index 4198d93..0000000
--- a/usr/local/www/themes/the_wall/images/button_mid.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/button_right.gif b/usr/local/www/themes/the_wall/images/button_right.gif
deleted file mode 100644
index 0faaa67..0000000
--- a/usr/local/www/themes/the_wall/images/button_right.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/icons/icon_advanced.gif b/usr/local/www/themes/the_wall/images/icons/icon_advanced.gif
new file mode 100644
index 0000000..3ede1ff
--- /dev/null
+++ b/usr/local/www/themes/the_wall/images/icons/icon_advanced.gif
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/icons/icon_advanced_s.gif b/usr/local/www/themes/the_wall/images/icons/icon_advanced_s.gif
new file mode 100644
index 0000000..b233549
--- /dev/null
+++ b/usr/local/www/themes/the_wall/images/icons/icon_advanced_s.gif
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/plogo_0.gif b/usr/local/www/themes/the_wall/images/misc/plogo_0.gif
deleted file mode 100644
index 160b56d..0000000
--- a/usr/local/www/themes/the_wall/images/misc/plogo_0.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/plogo_1.gif b/usr/local/www/themes/the_wall/images/misc/plogo_1.gif
deleted file mode 100644
index 50342d6..0000000
--- a/usr/local/www/themes/the_wall/images/misc/plogo_1.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/plogo_10.gif b/usr/local/www/themes/the_wall/images/misc/plogo_10.gif
deleted file mode 100644
index 06cba14..0000000
--- a/usr/local/www/themes/the_wall/images/misc/plogo_10.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/plogo_2.gif b/usr/local/www/themes/the_wall/images/misc/plogo_2.gif
deleted file mode 100644
index 9d10230..0000000
--- a/usr/local/www/themes/the_wall/images/misc/plogo_2.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/plogo_3.gif b/usr/local/www/themes/the_wall/images/misc/plogo_3.gif
deleted file mode 100644
index 1983f87..0000000
--- a/usr/local/www/themes/the_wall/images/misc/plogo_3.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/plogo_4.gif b/usr/local/www/themes/the_wall/images/misc/plogo_4.gif
deleted file mode 100644
index f7158bd..0000000
--- a/usr/local/www/themes/the_wall/images/misc/plogo_4.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/plogo_5.gif b/usr/local/www/themes/the_wall/images/misc/plogo_5.gif
deleted file mode 100644
index c7af593..0000000
--- a/usr/local/www/themes/the_wall/images/misc/plogo_5.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/plogo_6.gif b/usr/local/www/themes/the_wall/images/misc/plogo_6.gif
deleted file mode 100644
index 310eb22..0000000
--- a/usr/local/www/themes/the_wall/images/misc/plogo_6.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/plogo_7.gif b/usr/local/www/themes/the_wall/images/misc/plogo_7.gif
deleted file mode 100644
index 06bd2e8..0000000
--- a/usr/local/www/themes/the_wall/images/misc/plogo_7.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/plogo_8.gif b/usr/local/www/themes/the_wall/images/misc/plogo_8.gif
deleted file mode 100644
index c6ef564..0000000
--- a/usr/local/www/themes/the_wall/images/misc/plogo_8.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/themes/the_wall/images/misc/plogo_9.gif b/usr/local/www/themes/the_wall/images/misc/plogo_9.gif
deleted file mode 100644
index 4f0cd4d..0000000
--- a/usr/local/www/themes/the_wall/images/misc/plogo_9.gif
+++ /dev/null
Binary files differ
diff --git a/usr/local/www/vpn_ipsec.php b/usr/local/www/vpn_ipsec.php
index 8eb81ce..8654fa0 100755
--- a/usr/local/www/vpn_ipsec.php
+++ b/usr/local/www/vpn_ipsec.php
@@ -36,7 +36,7 @@
##|*MATCH=vpn_ipsec.php*
##|-PRIV
-
+require("functions.inc");
require("guiconfig.inc");
if (!is_array($config['ipsec']['phase1']))
@@ -62,8 +62,8 @@ if ($_POST) {
filter_configure();
$savemsg = get_std_save_message($retval);
if ($retval == 0) {
- if (file_exists($d_ipsecconfdirty_path))
- unlink($d_ipsecconfdirty_path);
+ if (is_subsystem_dirty('ipsec'))
+ clear_subsystem_dirty('ipsec');
}
} else if ($_POST['submit']) {
$pconfig = $_POST;
@@ -91,8 +91,8 @@ if ($_GET['act'] == "delph1")
unset($a_phase1[$_GET['p1index']]);
vpn_ipsec_refresh_policies();
vpn_ipsec_configure();
- filter_configure();
write_config();
+ filter_configure();
header("Location: vpn_ipsec.php");
exit;
}
@@ -124,7 +124,7 @@ include("head.inc");
<?php
if ($savemsg)
print_info_box($savemsg);
- if ($pconfig['enable'] && file_exists($d_ipsecconfdirty_path))
+ if ($pconfig['enable'] && is_subsystem_dirty('ipsec'))
print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect.");
?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
@@ -302,7 +302,7 @@ include("head.inc");
else
$spans = $spane = "";
?>
- <tr valign="top" ondblclick="document.location='vpn_ipsec_phase2.php?p2index=<?=$i;?>'">
+ <tr valign="top" ondblclick="document.location='vpn_ipsec_phase2.php?p2index=<?=$j;?>'">
<td nowrap class="listlr">
<?=$spans;?>
diff --git a/usr/local/www/vpn_ipsec_mobile.php b/usr/local/www/vpn_ipsec_mobile.php
index 47ac3a3..c3f605d 100755
--- a/usr/local/www/vpn_ipsec_mobile.php
+++ b/usr/local/www/vpn_ipsec_mobile.php
@@ -34,7 +34,7 @@
##|*MATCH=vpn_ipsec_mobile.php*
##|-PRIV
-
+require("functions.inc");
require("guiconfig.inc");
if (!is_array($config['ipsec']['phase1']))
@@ -103,8 +103,8 @@ if ($_POST['apply']) {
$retval = vpn_ipsec_configure();
$savemsg = get_std_save_message($retval);
if ($retval == 0)
- if (file_exists($d_ipsecconfdirty_path))
- unlink($d_ipsecconfdirty_path);
+ if (is_subsystem_dirty('ipsec'))
+ clear_subsystem_dirty('ipsec');
}
if ($_POST['submit']) {
@@ -201,7 +201,7 @@ if ($_POST['submit']) {
$a_client = $client;
write_config();
- touch($d_ipsecconfdirty_path);
+ mark_subsystem_dirty('ipsec');
header("Location: vpn_ipsec_mobile.php");
exit;
@@ -287,7 +287,7 @@ function login_banner_change() {
<?php
if ($savemsg)
print_info_box($savemsg);
- if (isset($config['ipsec']['enable']) && file_exists($d_ipsecconfdirty_path))
+ if (isset($config['ipsec']['enable']) && is_subsystem_dirty('ipsec'))
print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect.");
foreach ($a_phase1 as $ph1ent)
if (isset($ph1ent['mobile']))
diff --git a/usr/local/www/vpn_ipsec_phase1.php b/usr/local/www/vpn_ipsec_phase1.php
index 36e1924..b1f7a1a 100644
--- a/usr/local/www/vpn_ipsec_phase1.php
+++ b/usr/local/www/vpn_ipsec_phase1.php
@@ -36,7 +36,7 @@
##|*MATCH=vpn_ipsec_phase1.php*
##|-PRIV
-
+require("functions.inc");
require("guiconfig.inc");
if (!is_array($config['ipsec']['phase1']))
@@ -48,9 +48,6 @@ if (!is_array($config['ipsec']['phase2']))
$a_phase1 = &$config['ipsec']['phase1'];
$a_phase2 = &$config['ipsec']['phase2'];
-if($config['interfaces']['lan'])
- $specialsrcdst = explode(" ", "lan");
-
$p1index = $_GET['p1index'];
if (isset($_POST['p1index']))
$p1index = $_POST['p1index'];
@@ -64,6 +61,7 @@ if (isset($p1index) && $a_phase1[$p1index])
// don't copy the ikeid on dup
if (!isset($_GET['dup']))
$pconfig['ikeid'] = $a_phase1[$p1index]['ikeid'];
+
$old_ph1ent = $a_phase1[$p1index];
$pconfig['disabled'] = isset($a_phase1[$p1index]['disabled']);
@@ -266,8 +264,8 @@ if ($_POST) {
/* if the remote gateway changed and the interface is not WAN then remove route */
/* the vpn_ipsec_configure() handles adding the route */
if ($pconfig['interface'] <> "wan") {
- if($ph1ent['remote-gateway'] <> $pconfig['remotegw']) {
- mwexec("/sbin/route delete -host {$ph1ent['remote-gateway']}");
+ if($old_ph1ent['remote-gateway'] <> $pconfig['remotegw']) {
+ mwexec("/sbin/route delete -host {$oldph1ent['remote-gateway']}");
}
}
@@ -313,7 +311,7 @@ if ($_POST) {
if (is_array($a_phase2) && (count($a_phase2))) {
foreach ($a_phase2 as $phase2) {
if($phase2['ikeid'] == $ph1ent['ikeid']) {
- log_error("Reload {$ph1ent['descr']} tunnels");
+ log_error("Reload {$ph1ent['descr']} tunnel(s)");
$old_ph1ent['remote-gateway'] = resolve_retry($old_ph1ent['remote-gateway']);
$old_phase2 = $phase2;
reload_tunnel_spd_policy ($ph1ent, $phase2, $old_ph1ent, $old_phase2);
@@ -321,7 +319,7 @@ if ($_POST) {
}
}
write_config();
- touch($d_ipsecconfdirty_path);
+ mark_subsystem_dirty('ipsec');
header("Location: vpn_ipsec.php");
exit;
diff --git a/usr/local/www/vpn_ipsec_phase2.php b/usr/local/www/vpn_ipsec_phase2.php
index 1056497..340a638 100644
--- a/usr/local/www/vpn_ipsec_phase2.php
+++ b/usr/local/www/vpn_ipsec_phase2.php
@@ -36,7 +36,7 @@
##|*MATCH=vpn_ipsec_phase2.php*
##|-PRIV
-
+require("functions.inc");
require("guiconfig.inc");
if (!is_array($config['ipsec']['client']))
@@ -49,9 +49,6 @@ if (!is_array($config['ipsec']['phase2']))
$a_phase2 = &$config['ipsec']['phase2'];
-if($config['interfaces']['lan'])
- $specialsrcdst = explode(" ", "lan");
-
$p2index = $_GET['p2index'];
if (isset($_POST['p2index']))
$p2index = $_POST['p2index'];
@@ -189,7 +186,7 @@ if ($_POST) {
}
write_config();
- touch($d_ipsecconfdirty_path);
+ mark_subsystem_dirty('ipsec');
header("Location: vpn_ipsec.php");
exit;
diff --git a/usr/local/www/vpn_l2tp.php b/usr/local/www/vpn_l2tp.php
index 3c6cdea..0c0336e 100644
--- a/usr/local/www/vpn_l2tp.php
+++ b/usr/local/www/vpn_l2tp.php
@@ -28,6 +28,13 @@
POSSIBILITY OF SUCH DAMAGE.
*/
+##|+PRIV
+##|*IDENT=page-vpn-vpnl2tp
+##|*NAME=VPN: VPN L2TP page
+##|*DESCR=Allow access to the 'VPN: VPN L2TP' page.
+##|*MATCH=vpn_l2tp.php*
+##|-PRIV
+
$pgtitle = array(gettext("VPN"), gettext("L2TP"), gettext("L2TP"));
require("guiconfig.inc");
diff --git a/usr/local/www/vpn_l2tp_users.php b/usr/local/www/vpn_l2tp_users.php
index b402f18..7aa358d 100644
--- a/usr/local/www/vpn_l2tp_users.php
+++ b/usr/local/www/vpn_l2tp_users.php
@@ -28,6 +28,13 @@
POSSIBILITY OF SUCH DAMAGE.
*/
+##|+PRIV
+##|*IDENT=page-vpn-vpnl2tp-users
+##|*NAME=VPN: VPN L2TP : Users page
+##|*DESCR=Allow access to the 'VPN: VPN L2TP : Users' page.
+##|*MATCH=vpn_l2tp_users.php*
+##|-PRIV
+
$pgtitle = array(gettext("VPN"),gettext("L2TP"),gettext("Users"));
require("guiconfig.inc");
@@ -35,7 +42,6 @@ require("guiconfig.inc");
if (!is_array($config['l2tp']['user'])) {
$config['l2tp']['user'] = array();
}
-l2tp_users_sort();
$a_secret = &$config['l2tp']['user'];
if ($_POST) {
@@ -44,7 +50,7 @@ if ($_POST) {
if ($_POST['apply']) {
$retval = 0;
- if (!file_exists($d_sysrebootreqd_path)) {
+ if (!is_subsystem_dirty('rebootreq')) {
$retval = vpn_l2tp_configure();
}
$savemsg = get_std_save_message($retval);
diff --git a/usr/local/www/vpn_l2tp_users_edit.php b/usr/local/www/vpn_l2tp_users_edit.php
index 98d2dc7..c54a449 100644
--- a/usr/local/www/vpn_l2tp_users_edit.php
+++ b/usr/local/www/vpn_l2tp_users_edit.php
@@ -28,8 +28,28 @@
POSSIBILITY OF SUCH DAMAGE.
*/
+##|+PRIV
+##|*IDENT=page-vpn-vpnl2tp-users-edit
+##|*NAME=VPN: VPN L2TP : Users : Edit page
+##|*DESCR=Allow access to the 'VPN: VPN L2TP : Users : Edit' page.
+##|*MATCH=vpn_l2tp_users_edit.php*
+##|-PRIV
+
$pgtitle = array(gettext("VPN"),gettext("L2TP"),gettext("User"),gettext("Edit"));
+function l2tpusercmp($a, $b) {
+ return strcasecmp($a['name'], $b['name']);
+}
+
+function l2tp_users_sort() {
+ global $config;
+
+ if (!is_array($config['l2tp']['user']))
+ return;
+
+ usort($config['l2tp']['user'], "l2tpusercmp");
+}
+
require("guiconfig.inc");
if (!is_array($config['l2tp']['user'])) {
@@ -103,6 +123,7 @@ if ($_POST) {
if ($_POST['passwordfld'])
$secretent['password'] = $_POST['passwordfld'];
+ l2tp_users_sort();
if (isset($id) && $a_secret[$id])
$a_secret[$id] = $secretent;
else
@@ -127,7 +148,6 @@ include("head.inc");
<?php if ($input_errors) print_input_errors($input_errors); ?>
<div id="inputerrors"></div>
<form action="vpn_l2tp_users_edit.php" method="post" name="iform" id="iform">
- <?display_topbar()?>
<div id="mainarea">
<table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
<tr>
diff --git a/usr/local/www/vpn_openvpn_client.php b/usr/local/www/vpn_openvpn_client.php
index 0aef437..5f1df40 100644
--- a/usr/local/www/vpn_openvpn_client.php
+++ b/usr/local/www/vpn_openvpn_client.php
@@ -36,6 +36,7 @@
require("guiconfig.inc");
+require_once("openvpn.inc");
$pgtitle = array("OpenVPN", "Client");
diff --git a/usr/local/www/vpn_openvpn_csc.php b/usr/local/www/vpn_openvpn_csc.php
index e2596ab..2a0670a 100644
--- a/usr/local/www/vpn_openvpn_csc.php
+++ b/usr/local/www/vpn_openvpn_csc.php
@@ -36,6 +36,7 @@
require("guiconfig.inc");
+require_once("openvpn.inc");
$pgtitle = array("OpenVPN", "Client Specific Override");
diff --git a/usr/local/www/vpn_openvpn_server.php b/usr/local/www/vpn_openvpn_server.php
index 7979070..2b06f97 100644
--- a/usr/local/www/vpn_openvpn_server.php
+++ b/usr/local/www/vpn_openvpn_server.php
@@ -36,6 +36,7 @@
require("guiconfig.inc");
+require_once("openvpn.inc");
$pgtitle = array("OpenVPN", "Server");
@@ -85,6 +86,7 @@ if($_GET['act']=="edit"){
$pconfig['interface'] = $a_server[$id]['interface'];
$pconfig['local_port'] = $a_server[$id]['local_port'];
$pconfig['description'] = $a_server[$id]['description'];
+ $pconfig['custom_options'] = $a_server[$id]['custom_options'];
if ($pconfig['mode'] != "p2p_shared_key") {
if ($a_server[$id]['tls']) {
@@ -259,6 +261,7 @@ if ($_POST) {
$server['interface'] = $pconfig['interface'];
$server['local_port'] = $pconfig['local_port'];
$server['description'] = $pconfig['description'];
+ $server['custom_options'] = $pconfig['custom_options'];
if ($tls_mode) {
if ($pconfig['tlsauth_enable']) {
@@ -1082,6 +1085,31 @@ function netbios_change() {
<table width="100%" border="0" cellpadding="6" cellspacing="0" id="client_opts">
<tr>
+ <td colspan="2" class="list" height="12"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Advanced configuration</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Advanced</td>
+ <td width="78%" class="vtable">
+ <table border="0" cellpadding="2" cellspacing="0">
+ <tr>
+ <td>
+ <textarea rows="6" cols="78" name="custom_options" id="custom_options"><?=$pconfig['custom_options'];?></textarea><br/>
+ Paste any additional options you would like to pass through to the openvpn server here seperated by a semicoloin ;<br/>
+ EXAMPLE: push "route 10.0.0.0 255.255.255.0";
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+
+ <br/>
+
+ <table width="100%" border="0" cellpadding="6" cellspacing="0" id="client_opts">
+ <tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
<input name="save" type="submit" class="formbtn" value="Save">
@@ -1096,7 +1124,7 @@ function netbios_change() {
<?php else: ?>
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <table class="sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="10%" class="listhdrr">Disabled</td>
<td width="10%" class="listhdrr">Protocol</td>
@@ -1112,16 +1140,16 @@ function netbios_change() {
$disabled = "YES";
?>
<tr>
- <td class="listlr">
+ <td class="listlr" ondblclick="document.location='vpn_openvpn_server.php?act=edit&id=<?=$i;?>'">
<?=$disabled;?>
</td>
- <td class="listr">
+ <td class="listr" ondblclick="document.location='vpn_openvpn_server.php?act=edit&id=<?=$i;?>'">
<?=htmlspecialchars($server['protocol']);?>
</td>
- <td class="listr">
+ <td class="listr" ondblclick="document.location='vpn_openvpn_server.php?act=edit&id=<?=$i;?>'">
<?=htmlspecialchars($server['tunnel_network']);?>
</td>
- <td class="listbg">
+ <td class="listbg" ondblclick="document.location='vpn_openvpn_server.php?act=edit&id=<?=$i;?>'">
<?=htmlspecialchars($server['description']);?>
</td>
<td valign="middle" nowrap class="list">
@@ -1145,15 +1173,10 @@ function netbios_change() {
</a>
</td>
</tr>
- <tr>
- <td colspan="4">
- <p>
- <?=gettext("Additional OpenVPN servers can be added here.");?>
- </p>
- </td>
- </tr>
</table>
+ <?=gettext("Additional OpenVPN servers can be added here.");?>
+
<? endif; ?>
</td>
@@ -1187,4 +1210,3 @@ function set_checked($var,& $chk) {
}
?>
-
diff --git a/usr/local/www/vpn_pppoe.php b/usr/local/www/vpn_pppoe.php
index 592ba07..581fb24 100755
--- a/usr/local/www/vpn_pppoe.php
+++ b/usr/local/www/vpn_pppoe.php
@@ -118,7 +118,6 @@ if ($_POST) {
}
}
unset($config['pppoe']);
- write_config();
}
if (!$input_errors) {
@@ -172,7 +171,7 @@ if ($_POST) {
write_config();
$retval = 0;
- $retval = vpn_setup();
+ $retval = vpn_pppoe_configure();
$savemsg = get_std_save_message($retval);
}
}
@@ -332,7 +331,7 @@ function enable_change(enable_over) {
</td>
</tr>
<tr>
- <td width="22%" valign="top" class="vncellreq">No. PPPOE users</td>
+ <td width="22%" valign="top" class="vncellreq">No. PPPoE users</td>
<td width="78%" class="vtable">
<select id="n_pppoe_units" name="n_pppoe_units">
<?php
@@ -371,7 +370,7 @@ function enable_change(enable_over) {
<br>
<input name="pppoe_dns2" type="text" class="formfld unknown" id="pppoe_dns2" size="20" value="<?=htmlspecialchars($pconfig['pppoe_dns2']);?>">
<br>
- If entered they will be given to all pppoe clients else lan dns and one wan dns will go to all clients<br>
+ If entered they will be given to all PPPoE clients, else LAN DNS and one WAN DNS will go to all clients<br>
</td>
</tr>
<tr>
@@ -392,21 +391,21 @@ function enable_change(enable_over) {
When set, if primary server fails all requests will be sent via backup server</td>
</tr>
<tr>
- <td width="22%" valign="top" class="vncellreq">NAS IP ADDRESS</td>
+ <td width="22%" valign="top" class="vncellreq">NAS IP Address</td>
<td width="78%" class="vtable">
<?=$mandfldhtml;?><input name="radius_nasip" type="text" class="formfld unknown" id="radius_nasip" size="20" value="<?=htmlspecialchars($pconfig['radius_nasip']);?>">
<br>radius server NAS ip Address<br>
</td>
</tr>
<tr>
- <td width="22%" valign="top" class="vncellreq">Radius Accounting Update</td>
+ <td width="22%" valign="top" class="vncellreq">RADIUS Accounting Update</td>
<td width="78%" class="vtable">
<?=$mandfldhtml;?><input name="radius_acct_update" type="text" class="formfld unknown" id="radius_acct_update" size="20" value="<?=htmlspecialchars($pconfig['radius_acct_update']);?>">
<br>Radius accounting update period in seconds
</td>
</tr>
<tr>
- <td width="22%" valign="top" class="vncell">RADIUS issued IP's</td>
+ <td width="22%" valign="top" class="vncell">RADIUS issued IPs</td>
<td width="78%" valign="top" class="vtable">
<input name="radiusissueips" value="yes" type="checkbox" class="formfld" id="radiusissueips"<?php if($pconfig['radiusissueips']) echo " CHECKED"; ?>>
<br>Issue IP Addresses via RADIUS server.</td>
@@ -417,7 +416,7 @@ function enable_change(enable_over) {
<input name="radiusserver" type="text" class="formfld unknown" id="radiusserver" size="20" value="<?=htmlspecialchars($pconfig['radiusserver']);?>">
<input name="radiusserverport" type="text" class="formfld unknown" id="radiusserverport" size="4" value="<?=htmlspecialchars($pconfig['radiusserverport']);?>">
<input name="radiusserveracctport" type="text" class="formfld unknown" id="radiusserveracctport" size="4" value="<?=htmlspecialchars($pconfig['radiusserveracctport']);?>">
- <br>Enter the IP address and portof the RADIUS server. Format ip auth_port acct_port<br>
+ <br>Enter the IP address and port of the RADIUS server. Format ip auth_port acct_port<br>
<br> standard port 1812 and 1813 accounting</td>
</tr>
<tr>
diff --git a/usr/local/www/vpn_pppoe_users.php b/usr/local/www/vpn_pppoe_users.php
index 30de917..b92fcef 100755
--- a/usr/local/www/vpn_pppoe_users.php
+++ b/usr/local/www/vpn_pppoe_users.php
@@ -41,7 +41,6 @@ require("guiconfig.inc");
if (!is_array($config['pppoe']['user'])) {
$config['pppoe']['user'] = array();
}
-pppoe_users_sort();
$a_secret = &$config['pppoe']['user'];
if ($_POST) {
@@ -53,8 +52,8 @@ if ($_POST) {
$retval = vpn_setup();
$savemsg = get_std_save_message($retval);
if ($retval == 0) {
- if (file_exists($d_pppoeuserdirty_path))
- unlink($d_pppoeuserdirty_path);
+ if (is_subsystem_dirty('pppoeusers'))
+ clear_subsystem_dirty('pppoeusers');
}
}
}
@@ -63,7 +62,7 @@ if ($_GET['act'] == "del") {
if ($a_secret[$_GET['id']]) {
unset($a_secret[$_GET['id']]);
write_config();
- touch($d_pppoeuserdirty_path);
+ mark_subsystem_dirty('pppoeusers');
header("Location: vpn_pppoe_users.php");
exit;
}
@@ -80,7 +79,7 @@ include("head.inc");
<?php if ($savemsg) print_info_box($savemsg); ?>
<?php if (isset($config['pppoe']['radius']['enable']))
print_info_box("Warning: RADIUS is enabled. The local user database will not be used."); ?>
-<?php if (file_exists($d_pppoeuserdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('pppoeusers')): ?><p>
<?php print_info_box_np("The PPPoE user list has been modified.<br>You must apply the changes in order for them to take effect.<br><b>Warning: this will terminate all current PPPoE sessions!</b>");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/vpn_pppoe_users_edit.php b/usr/local/www/vpn_pppoe_users_edit.php
index 816772b..de5a314 100755
--- a/usr/local/www/vpn_pppoe_users_edit.php
+++ b/usr/local/www/vpn_pppoe_users_edit.php
@@ -35,6 +35,18 @@
##|*MATCH=vpn_pppoe_users_edit.php*
##|-PRIV
+function pppoeusercmp($a, $b) {
+ return strcasecmp($a['name'], $b['name']);
+}
+
+function pppoe_users_sort() {
+ global $config;
+
+ if (!is_array($config['pppoe']['user']))
+ return;
+
+ usort($config['pppoe']['user'], "pppoeusercmp");
+}
require("guiconfig.inc");
@@ -103,6 +115,7 @@ if ($_POST) {
if ($_POST['password'])
$secretent['password'] = $_POST['password'];
+ pppoe_users_sort();
if (isset($id) && $a_secret[$id])
$a_secret[$id] = $secretent;
else
diff --git a/usr/local/www/vpn_pptp.php b/usr/local/www/vpn_pptp.php
index 7f9f80a..1a94c39 100755
--- a/usr/local/www/vpn_pptp.php
+++ b/usr/local/www/vpn_pptp.php
@@ -119,16 +119,7 @@ if ($_POST) {
$input_errors[] = "A valid target address must be specified.";
}
} else {
- /* turning pptp off, lets dump any custom rules */
- $rules = &$config['filter']['rule'];
- for($x=0; $x<count($rules); $x++) {
- if($rules[$x]['interface'] == "pptp") {
- unset($rules[$x]);
- }
- }
unset($config['pptpd']['mode']);
-
- write_config();
}
if (!$input_errors) {
@@ -188,7 +179,7 @@ if ($_POST) {
write_config();
$retval = 0;
- $retval = vpn_setup();
+ $retval = vpn_pptpd_configure();
$savemsg = get_std_save_message($retval);
filter_configure();
diff --git a/usr/local/www/vpn_pptp_users.php b/usr/local/www/vpn_pptp_users.php
index d49dd43..31aa0ad 100755
--- a/usr/local/www/vpn_pptp_users.php
+++ b/usr/local/www/vpn_pptp_users.php
@@ -41,7 +41,6 @@ require("guiconfig.inc");
if (!is_array($config['pptpd']['user'])) {
$config['pptpd']['user'] = array();
}
-pptpd_users_sort();
$a_secret = &$config['pptpd']['user'];
if ($_POST) {
@@ -53,8 +52,8 @@ if ($_POST) {
$retval = vpn_setup();
$savemsg = get_std_save_message($retval);
if ($retval == 0) {
- if (file_exists($d_pptpuserdirty_path))
- unlink($d_pptpuserdirty_path);
+ if (is_subsystem_dirty('pptpusers'))
+ clear_subsystem_dirty('pptpusers');
}
}
}
@@ -63,7 +62,7 @@ if ($_GET['act'] == "del") {
if ($a_secret[$_GET['id']]) {
unset($a_secret[$_GET['id']]);
write_config();
- touch($d_pptpuserdirty_path);
+ mark_subsystem_dirty('pptpusers');
header("Location: vpn_pptp_users.php");
exit;
}
@@ -80,7 +79,7 @@ include("head.inc");
<?php if ($savemsg) print_info_box($savemsg); ?>
<?php if (isset($config['pptpd']['radius']['enable']))
print_info_box("Warning: RADIUS is enabled. The local user database will not be used."); ?>
-<?php if (file_exists($d_pptpuserdirty_path)): ?><p>
+<?php if (is_subsystem_dirty('pptpusers')): ?><p>
<?php print_info_box_np("The PPTP user list has been modified.<br>You must apply the changes in order for them to take effect.<br><b>Warning: this will terminate all current PPTP sessions!</b>");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
diff --git a/usr/local/www/vpn_pptp_users_edit.php b/usr/local/www/vpn_pptp_users_edit.php
index dfad162..b8ad074 100755
--- a/usr/local/www/vpn_pptp_users_edit.php
+++ b/usr/local/www/vpn_pptp_users_edit.php
@@ -35,6 +35,18 @@
##|*MATCH=vpn_pptp_users_edit.php*
##|-PRIV
+function pptpusercmp($a, $b) {
+ return strcasecmp($a['name'], $b['name']);
+}
+
+function pptpd_users_sort() {
+ global $config;
+
+ if (!is_array($config['ppptpd']['user']))
+ return;
+
+ usort($config['pptpd']['user'], "pptpusercmp");
+}
require("guiconfig.inc");
@@ -103,13 +115,14 @@ if ($_POST) {
if ($_POST['password'])
$secretent['password'] = $_POST['password'];
+ pptpd_users_sort();
if (isset($id) && $a_secret[$id])
$a_secret[$id] = $secretent;
else
$a_secret[] = $secretent;
write_config();
- touch($d_pptpuserdirty_path);
+ mark_subsystem_dirty('pptpusers');
header("Location: vpn_pptp_users.php");
exit;
diff --git a/usr/local/www/widgets/widgets/captive_portal_status.widget.php b/usr/local/www/widgets/widgets/captive_portal_status.widget.php
index 74ec780..1b74d26 100644
--- a/usr/local/www/widgets/widgets/captive_portal_status.widget.php
+++ b/usr/local/www/widgets/widgets/captive_portal_status.widget.php
@@ -36,8 +36,6 @@ require_once("guiconfig.inc");
require_once("pfsense-utils.inc");
require_once("functions.inc");
-$concurrent = `cat /var/db/captiveportal.db | wc -l`;
-
?>
<script src="/javascript/sorttable.js"></script>
@@ -55,35 +53,36 @@ function clientcmp($a, $b) {
}
$cpdb = array();
-$wdgcplck = lock('captiveportal');
-$fp = @fopen("{$g['vardb_path']}/captiveportal.db","r");
+if (file_exists("{$g['vardb_path']}/captiveportal.db"))
+ $cpcontents = file("{$g['vardb_path']}/captiveportal.db", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+else
+ $cpcontents = array();
+
+$concurrent = count($cpcontents);
if ($fp) {
- while (!feof($fp)) {
- $line = trim(fgets($fp));
- if ($line) {
- $cpent = explode(",", $line);
- if ($_GET['showact'])
- $cpent[4] = captiveportal_get_last_activity($cpent[1]);
- $cpdb[] = $cpent;
- }
+
+ foreach ($cpcontents as $cpcontent) {
+ $cpent = explode(",", $cpcontent);
+ if ($_GET['showact'])
+ $cpent[5] = captiveportal_get_last_activity($cpent[2]);
+ $cpdb[] = $cpent;
}
-
- fclose($fp);
-
+
if ($_GET['order']) {
if ($_GET['order'] == "ip")
$order = 2;
else if ($_GET['order'] == "mac")
$order = 3;
+ else if ($_GET['order'] == "user")
+ $order = 4;
else if ($_GET['order'] == "lastact")
- $order = 4;
+ $order = 5;
else
$order = 0;
usort($cpdb, "clientcmp");
}
}
-unlock($wdgcplck);
?>
<table class="sortable" name="sortabletable" id="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
@@ -97,7 +96,7 @@ unlock($wdgcplck);
<td class="listr"><?=$cpent[3];?>&nbsp;</td>
<td class="listr"><?=htmlspecialchars(date("m/d/Y H:i:s", $cpent[0]));?></td>
<?php if ($_GET['showact']): ?>
- <td class="listr"><?php if ($cpent[4]) echo htmlspecialchars(date("m/d/Y H:i:s", $cpent[4]));?></td>
+ <td class="listr"><?php if ($cpent[5]) echo htmlspecialchars(date("m/d/Y H:i:s", $cpent[5]));?></td>
<?php endif; ?>
<td valign="middle" class="list" nowrap>
<a href="?order=<?=$_GET['order'];?>&showact=<?=$_GET['showact'];?>&act=del&id=<?=$cpent[1];?>" onclick="return confirm('Do you really want to disconnect this client?')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td>
diff --git a/usr/local/www/widgets/widgets/services_status.widget.php b/usr/local/www/widgets/widgets/services_status.widget.php
index 60c9636..714d912 100644
--- a/usr/local/www/widgets/widgets/services_status.widget.php
+++ b/usr/local/www/widgets/widgets/services_status.widget.php
@@ -30,8 +30,7 @@
*/
require_once("guiconfig.inc");
-require_once("pfsense-utils.inc");
-require_once("functions.inc");
+require_once("service-utils.inc");
require_once("/usr/local/www/widgets/include/services_status.inc");
function get_pkg_descr($package_name) {
diff --git a/usr/local/www/wizard.php b/usr/local/www/wizard.php
index 7dee0a4..f834e0b 100755
--- a/usr/local/www/wizard.php
+++ b/usr/local/www/wizard.php
@@ -283,7 +283,11 @@ function enablechange() {
echo "<tr>";
if ($field['type'] == "input") {
- if(!$field['dontdisplayname']) {
+ if ($field['displayname']) {
+ echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
+ echo $field['displayname'];
+ echo ":</td>\n";
+ } else if(!$field['dontdisplayname']) {
echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
echo fixup_string($field['name']);
echo ":</td>\n";
@@ -299,7 +303,11 @@ function enablechange() {
} else if ($field['type'] == "inputalias") {
- if(!$field['dontdisplayname']) {
+ if ($field['displayname']) {
+ echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
+ echo $field['displayname'];
+ echo ":</td>\n";
+ } else if(!$field['dontdisplayname']) {
echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
echo fixup_string($field['name']);
echo ":</td>\n";
@@ -319,7 +327,7 @@ function enablechange() {
$multiple = "";
$name = strtolower($name);
echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
- echo fixup_string($field['name']) . ":\n";
+ echo fixup_string($field['displayname'] ? $field['displayname'] : $field['name']) . ":\n";
echo "</td>";
echo "<td class=\"vtable\">\n";
if($field['size'] <> "") $size = "size=\"{$field['size']}\"";
@@ -377,7 +385,11 @@ function enablechange() {
echo "<td class=\"vtable\">";
echo "<input id='" . $name . "' name='" . $name . "' value='" . $value . "' type='password'>\n";
} else if ($field['type'] == "select") {
- if(!$field['dontdisplayname']) {
+ if ($field['displayname']) {
+ echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
+ echo $field['displayname'];
+ echo ":</td>\n";
+ } else if(!$field['dontdisplayname']) {
echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
echo fixup_string($field['name']);
echo ":</td>\n";
@@ -396,11 +408,20 @@ function enablechange() {
foreach ($field['options']['option'] as $opt) {
$selected = "";
if($value == $opt['value']) $selected = " SELECTED";
- echo "\t<option name='" . $opt['name'] . "' value='" . $opt['value'] . "'" . $selected . ">" . $opt['name'] . "</option>\n";
+ echo "\t<option name='" . $opt['name'] . "' value='" . $opt['value'] . "'" . $selected . ">";
+ if ($opt['displayname'])
+ echo $opt['displayname'];
+ else
+ echo $opt['name'];
+ echo "</option>\n";
}
echo "</select>\n";
} else if ($field['type'] == "textarea") {
- if(!$field['dontdisplayname']) {
+ if ($field['displayname']) {
+ echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
+ echo $field['displayname'];
+ echo ":</td>\n";
+ } else if(!$field['dontdisplayname']) {
echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
echo fixup_string($field['name']);
echo ":</td>";
@@ -416,7 +437,11 @@ function enablechange() {
echo "<td>&nbsp;</td><tr>";
echo "<tr><td colspan=\"2\" class=\"listtopic\">" . $field['name'] . "<br></td>\n";
} else if ($field['type'] == "subnet_select") {
- if(!$field['dontdisplayname']) {
+ if ($field['displayname']) {
+ echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
+ echo $field['displayname'];
+ echo ":</td>\n";
+ } else if(!$field['dontdisplayname']) {
echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
echo fixup_string($field['name']);
echo ":</td>";
@@ -432,7 +457,11 @@ function enablechange() {
}
echo "</select>\n";
} else if ($field['type'] == "timezone_select") {
- if(!$field['dontdisplayname']) {
+ if ($field['displayname']) {
+ echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
+ echo $field['displayname'];
+ echo ":</td>\n";
+ } else if(!$field['dontdisplayname']) {
echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
echo fixup_string($field['name']);
echo ":</td>";
@@ -449,7 +478,11 @@ function enablechange() {
}
echo "</select>\n";
} else if ($field['type'] == "checkbox") {
- if(!$field['dontdisplayname']) {
+ if ($field['displayname']) {
+ echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
+ echo $field['displayname'];
+ echo ":</td>\n";
+ } else if(!$field['dontdisplayname']) {
echo "<td width=\"22%\" align=\"right\" class=\"vncellreq\">\n";
echo $field['name'];
echo ":</td>";
diff --git a/usr/local/www/wizards/setup_wizard.xml b/usr/local/www/wizards/setup_wizard.xml
index bc09aed..3f5c3de 100644
--- a/usr/local/www/wizards/setup_wizard.xml
+++ b/usr/local/www/wizards/setup_wizard.xml
@@ -412,6 +412,7 @@
&lt;meta http-equiv="refresh" content="60; url=$myurl" &gt;</description>
<stepafterformdisplay>
reload_all();
+ mwexec_bg("/etc/rc.update_bogons.sh now");
</stepafterformdisplay>
</step>
</pfsensewizard>
diff --git a/usr/local/www/wizards/traffic_shaper_wizard.inc b/usr/local/www/wizards/traffic_shaper_wizard.inc
index bb4559b..74df441 100644
--- a/usr/local/www/wizards/traffic_shaper_wizard.inc
+++ b/usr/local/www/wizards/traffic_shaper_wizard.inc
@@ -50,15 +50,14 @@ function step2_stepbeforeformdisplay() {
$numberofinterfaces = 0;
$iflist = array();
- foreach ($config['interfaces'] as $if => $ifdesc) {
- if (!is_altq_capable($ifdesc['if']))
- continue;
- if (!isset($ifdesc['enable']) && $if != "lan" && $if != "wan")
+ $iflisttmp = get_configured_interface_with_descr();
+ foreach ($iflisttmp as $if => $ifdesc) {
+ if (!is_altq_capable(get_real_interface($if)))
continue;
if ($if == "lan")
continue;
$numberofinterfaces++;
- $iflist[] = $if;
+ $iflist[$if] = $ifdesc;
}
$numberofconnections = intval($config['ezshaper']['step1']['numberofconnections']);
if ($numberofconnections > $numberofinterfaces) {
@@ -78,50 +77,53 @@ function step2_stepbeforeformdisplay() {
*/
$fields = array();
- $field = array();
- $field['name'] = "Setup LAN scheduler";
- $field['type'] = "listtopic";
- $fields[] = $field;
- $field = array();
- $field['name'] = "downloadscheduler";
+ $field = array();
+ $field['name'] = "Setup LAN scheduler";
+ $field['type'] = "listtopic";
+ $fields[] = $field;
+ $field = array();
+ $field['displayname'] = "Download Scheduler";
+ $field['name'] = "downloadscheduler";
$field['type'] = "select";
$field['typehint'] = "Queueing discipline to apply on the download of this connection.";
- $field['options']['option'] = array();
- $opts = array();
- $opts['name'] = "HFSC";
- $opts['value'] = "HFSC";
- $field['options']['option'][] = $opts;
- $opts = array();
- $opts['name'] = "CBQ";
- $opts['value'] = "CBQ";
- $field['options']['option'][] = $opts;
- $opts = array();
- $opts['name'] = "PRIQ";
- $opts['value'] = "PRIQ";
- $field['options']['option'][] = $opts;
- $field['bindstofield'] = "ezshaper->step2->downloadscheduler";
- $fields[] = $field;
-
- $field = array();
- $field['name'] = "Setup connections speeds";
- $field['type'] = "listtopic";
- $fields[] = $field;
+ $field['options']['option'] = array();
+ $opts = array();
+ $opts['name'] = "HFSC";
+ $opts['value'] = "HFSC";
+ $field['options']['option'][] = $opts;
+ $opts = array();
+ $opts['name'] = "CBQ";
+ $opts['value'] = "CBQ";
+ $field['options']['option'][] = $opts;
+ $opts = array();
+ $opts['name'] = "PRIQ";
+ $opts['value'] = "PRIQ";
+ $field['options']['option'][] = $opts;
+ $field['bindstofield'] = "ezshaper->step2->downloadscheduler";
+ $fields[] = $field;
+ $field = array();
+ $field['name'] = "Setup connections speeds";
+ $field['type'] = "listtopic";
+ $fields[] = $field;
for ($i = 0; $i < $numberofconnections; $i++) {
$field = array();
+ $field['displayname'] = "Interface";
$field['name'] = "conn{$i}interface";
$field['type'] = "select";
$field['typehint'] = "Interface of this connection.";
$field['options']['option'] = array();
- foreach ($iflist as $ifname) {
- $opts = array();
- $opts['name'] = $ifname;
- $opts['value'] = $ifname;
+ foreach ($iflist as $ifname => $ifdescr) {
+ $opts = array();
+ $opts['displayname'] = $ifdescr;
+ $opts['name'] = $ifname;
+ $opts['value'] = $ifname;
$field['options']['option'][] = $opts;
}
$field['bindstofield'] = "ezshaper->step2->conn{$i}interface";
- $fields[] = $field;
+ $fields[] = $field;
+ $field['displayname'] = "Upload Scheduler";
$field['name'] = "conn{$i}uploadscheduler";
$field['type'] = "select";
$field['typehint'] = "Queueing discipline to apply on the upload of this connection.";
@@ -139,14 +141,15 @@ function step2_stepbeforeformdisplay() {
$opts['value'] = "PRIQ";
$field['options']['option'][] = $opts;
$field['bindstofield'] = "ezshaper->step2->conn{$i}uploadscheduler";
- $fields[] = $field;
+ $fields[] = $field;
$field = array();
+ $field['displayname'] = "Connection Upload";
$field['name'] = "conn{$i}upload";
$field['type'] = "input";
$field['bindstofield'] = "ezshaper->step2->conn{$i}upload";
$field['combinefieldsbegin'] = "true";
- $fields[] = $field;
+ $fields[] = $field;
$field = array();
$field['combinefieldsend'] = "true";
@@ -154,56 +157,57 @@ function step2_stepbeforeformdisplay() {
$field['dontcombinecells'] = "true";
$field['name'] = "conn{$i}uploadspeed";
$field['typehint'] = "Upload bandwidth on this connection.";
- $field['type'] = "select";
- $field['options']['option'] = array();
- $opts = array();
- $opts['value'] = "Kb";
- $opts['name'] = "Kbit/s";
- $field['options']['option'][] = $opts;
- $opts = array();
- $opts['value'] = "Mb";
- $opts['name'] = "Mbit/s";
- $field['options']['option'][] = $opts;
- $opts = array();
- $opts['value'] = "Gb";
- $opts['name'] = "Gbit/s";
- $field['options']['option'][] = $opts;
- $field['bindstofield'] = "ezshaper->step2->conn{$i}uploadspeed";
- $fields[] = $field;
+ $field['type'] = "select";
+ $field['options']['option'] = array();
+ $opts = array();
+ $opts['value'] = "Kb";
+ $opts['name'] = "Kbit/s";
+ $field['options']['option'][] = $opts;
+ $opts = array();
+ $opts['value'] = "Mb";
+ $opts['name'] = "Mbit/s";
+ $field['options']['option'][] = $opts;
+ $opts = array();
+ $opts['value'] = "Gb";
+ $opts['name'] = "Gbit/s";
+ $field['options']['option'][] = $opts;
+ $field['bindstofield'] = "ezshaper->step2->conn{$i}uploadspeed";
+ $fields[] = $field;
$field = array();
+ $field['displayname'] = "Connection Download";
$field['name'] = "conn{$i}download";
$field['type'] = "input";
$field['bindstofield'] = "ezshaper->step2->conn{$i}download";
$field['combinefieldsbegin'] = "true";
- $fields[] = $field;
+ $fields[] = $field;
$field = array();
- $field['combinefieldsend'] = "true";
- $field['dontdisplayname'] = "true";
- $field['dontcombinecells'] = "true";
- $field['name'] = "conn{$i}downloadspeed";
+ $field['combinefieldsend'] = "true";
+ $field['dontdisplayname'] = "true";
+ $field['dontcombinecells'] = "true";
+ $field['name'] = "conn{$i}downloadspeed";
$field['typehint'] = "Download bandwidth on this connection.";
- $field['type'] = "select";
- $field['options']['option'] = array();
- $opts = array();
- $opts['value'] = "Kb";
- $opts['name'] = "Kbit/s";
- $field['options']['option'][] = $opts;
- $opts = array();
- $opts['value'] = "Mb";
- $opts['name'] = "Mbit/s";
- $field['options']['option'][] = $opts;
- $opts = array();
- $opts['value'] = "Gb";
- $opts['name'] = "Gbit/s";
- $field['options']['option'][] = $opts;
- $field['bindstofield'] = "ezshaper->step2->conn{$i}downloadspeed";
- $fields[] = $field;
+ $field['type'] = "select";
+ $field['options']['option'] = array();
+ $opts = array();
+ $opts['value'] = "Kb";
+ $opts['name'] = "Kbit/s";
+ $field['options']['option'][] = $opts;
+ $opts = array();
+ $opts['value'] = "Mb";
+ $opts['name'] = "Mbit/s";
+ $field['options']['option'][] = $opts;
+ $opts = array();
+ $opts['value'] = "Gb";
+ $opts['name'] = "Gbit/s";
+ $field['options']['option'][] = $opts;
+ $field['bindstofield'] = "ezshaper->step2->conn{$i}downloadspeed";
+ $fields[] = $field;
}
- $field = array();
- $field['name'] = "Next";
- $field['type'] = "submit";
+ $field = array();
+ $field['name'] = "Next";
+ $field['type'] = "submit";
$fields[] = $field;
}
@@ -336,6 +340,7 @@ function step3_stepbeforeformdisplay() {
for ($i = 0; $i < $numberofconnections; $i++) {
$field = array();
+ $field['displayname'] = "Connection upload";
$field['name'] = "conn{$i}upload";
$field['type'] = "input";
$field['bindstofield'] = "ezshaper->step3->conn{$i}upload";
@@ -513,7 +518,7 @@ function step5_stepsubmitphpaction() {
}
function step8_stepsubmitphpaction() {
- global $g, $config, $d_shaperconfdirty_path;
+ global $g, $config;
/* save the new configuration */
apply_all_choosen_items();
@@ -527,7 +532,7 @@ function step8_stepsubmitphpaction() {
filter_configure();
/* And we're no longer dirty! */
- unlink_if_exists($d_shaperconfdirty_path);
+ clear_subsystem_dirty('shaper');
update_filter_reload_status("Initializing");
diff --git a/usr/local/www/wizards/traffic_shaper_wizard.xml b/usr/local/www/wizards/traffic_shaper_wizard.xml
index f2128cd..cdbf296 100644
--- a/usr/local/www/wizards/traffic_shaper_wizard.xml
+++ b/usr/local/www/wizards/traffic_shaper_wizard.xml
@@ -160,7 +160,7 @@
</field>
<field>
<name>Address</name>
- <type>input</type>
+ <type>inputalias</type>
<description>This allows you to just provide the IP address of the computer(s) to Penalize. NOTE: You can also use a Firewall Alias in this location.</description>
<bindstofield>ezshaper-&gt;step4-&gt;address</bindstofield>
<message>IP Address field is non-blank and doesn't look like an IP address.</message>
diff --git a/usr/local/www/wizards/traffic_shaper_wizard_dedicated.inc b/usr/local/www/wizards/traffic_shaper_wizard_dedicated.inc
index 3d05c7f..650e878 100755
--- a/usr/local/www/wizards/traffic_shaper_wizard_dedicated.inc
+++ b/usr/local/www/wizards/traffic_shaper_wizard_dedicated.inc
@@ -549,7 +549,7 @@ function step5_stepsubmitphpaction() {
}
function step8_stepsubmitphpaction() {
- global $g, $config, $d_shaperconfdirty_path;
+ global $g, $config;
/* save the new configuration */
apply_all_choosen_items();
@@ -563,7 +563,7 @@ function step8_stepsubmitphpaction() {
filter_configure();
/* And we're no longer dirty! */
- unlink_if_exists($d_shaperconfdirty_path);
+ clear_subsystem_dirty('shaper');
update_filter_reload_status("Initializing");
diff --git a/usr/local/www/wizards/traffic_shaper_wizard_multi_all.inc b/usr/local/www/wizards/traffic_shaper_wizard_multi_all.inc
index 1173a1e..dd6caa5 100755
--- a/usr/local/www/wizards/traffic_shaper_wizard_multi_all.inc
+++ b/usr/local/www/wizards/traffic_shaper_wizard_multi_all.inc
@@ -594,7 +594,7 @@ function step5_stepsubmitphpaction() {
}
function step8_stepsubmitphpaction() {
- global $g, $config, $d_shaperconfdirty_path;
+ global $g, $config;
/* save the new configuration */
apply_all_choosen_items();
@@ -608,7 +608,7 @@ function step8_stepsubmitphpaction() {
filter_configure();
/* And we're no longer dirty! */
- unlink_if_exists($d_shaperconfdirty_path);
+ clear_subsystem_dirty('shaper');
update_filter_reload_status("Initializing");
diff --git a/usr/local/www/wizards/traffic_shaper_wizard_multi_lan.inc b/usr/local/www/wizards/traffic_shaper_wizard_multi_lan.inc
index 1de1269..a876839 100644
--- a/usr/local/www/wizards/traffic_shaper_wizard_multi_lan.inc
+++ b/usr/local/www/wizards/traffic_shaper_wizard_multi_lan.inc
@@ -377,7 +377,7 @@ function step5_stepsubmitphpaction() {
}
function step8_stepsubmitphpaction() {
- global $g, $config, $d_shaperconfdirty_path;
+ global $g, $config;
/* save the new configuration */
apply_all_choosen_items();
@@ -391,7 +391,7 @@ function step8_stepsubmitphpaction() {
filter_configure();
/* And we're no longer dirty! */
- unlink_if_exists($d_shaperconfdirty_path);
+ clear_subsystem_dirty('shaper');
update_filter_reload_status("Initializing");
diff --git a/usr/local/www/wlan_strong_key_generator/generator.php b/usr/local/www/wlan_strong_key_generator/generator.php
deleted file mode 100755
index 467feb6..0000000
--- a/usr/local/www/wlan_strong_key_generator/generator.php
+++ /dev/null
@@ -1,376 +0,0 @@
-#!/usr/local/bin/php
-
-<html>
-<head>
-<title>WLAN Strong Key Generator version 2.2 by Warewolf Labs ( formerly WEP Strong Key Generator )</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<script language="JavaScript">
-<!--
-/*
-
-version 2.2.1
-
-This file was included as is with only minor changes for pfSense.
-All (C) and Author information has been left alone.
-
-==
-
-Title: WLAN Strong Key Generator (wlanSKG) version 2.2
-
- (formerly WEP Strong Key Generator)
-
-Author: Chris Elliott
- Warewolf Labs
- www.warewolflabs.com
-
-Release Notes:
-
-=== version 2.2
-
-Date: 2005-01-25
-
-Info: 1. Contains minor updates to the instructions in preparation for a full rewrite and
- increase in functionality of this script (i.e. WPA-PSK generation, etc.), slated
- for a later release (2.3+).
-
-
-==== version 2.1
-
-
-Version: 2.1
-Date: 2002-12-14
-
-Info: A JavaScript program written to enable Wireless LAN (WLAN) administrators
- to quickly create strong keys for implementing Wired Equivalent Privacy
- (WEP) as a first line of defense in strengthening the security of their
- wireless networks. Keys can be selectively generated for use with 64-,
- 128-, 152-, and 256-bit WEP key lengths. Additionally, user-defined pass
- phrases can be converted to Hex format for use as WEP keys (more info below).
-
- It has been freely released to the public as part of an effort to increase
- awareness of WLAN security issues, and to increase the baseline security
- of current and future installations.
-
- While this file may be freely distributed, the copyright has been retained
- for all code generated by Chris Elliott / Warewolf Labs, and this information
- must remain intact (i.e. don't pretend that you or your company wrote this, or
- offer it to your clients without giving due credit).
-
- The addition of the custom passphrase code in version 2.1 was based on a
- suggestion/initial implementation by Kraix (www.kraix.com); additionally, Kraix
- supplied some needed refinements to the instructions included for this program.
- Much thanks is in order for those things, as they provided the impetus to update
- this script from its original release in order to support 256-bit WEP keys along
- with some other touch-ups.
-
-*/
-
-// initialize WEP key variables
-
-var ascWEPkey = '';
-var hexWEPkey = '';
-
-// creates an array of 95 possible characters from which to choose for generating our WEP key
-var charArray = new Array(' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '\'', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~');
-
-// functions
-
-function gen_prn() { // generates a pseudo-random number
-
- return Math.floor(Math.random() * charArray.length); // range is 0 ~ 94
-}
-
-function gen_key(keyLengthInBytes) { // generate a WEP key with the specified key length in bytes (5/13/16/29 bytes for 64/128/152/256-bit WEP)
-
- for (i = 0; i < keyLengthInBytes; i++)
- {
- ascWEPkey += charArray[gen_prn()]; // creates the ASCII version of the WEP key
- }
-
- for (i = 0; i < ascWEPkey.length; i++)
- {
- hexWEPkey += ascWEPkey.charCodeAt(i).toString(16); // creates the HEX WEP key from the ASCII
- }
-}
-
-function write_key(tf) { // write the WEP key into the form text fields
- tf.ascKeyTextField.value = ascWEPkey;
- tf.hexKeyTextField.value = hexWEPkey;
-}
-
-function reset_key() { // reset the WEP key variables for further use
- ascWEPkey = '';
- hexWEPkey = '';
-}
-
-function go(form, klib) { // trigger function to generate a key, display the output, and then reset the variables
-
- gen_key(klib);
- write_key(form);
- reset_key();
-}
-
-function go_ck(form) { // trigger function to generate a custom key from a user-supplied pass phrase
- // checking for proper key lengths is left up to the user
-
- if ( form.customPhraseField.value != '') // did they actually enter anything?
- {
- ascWEPkey = form.customPhraseField.value;
- for (i = 0; i < ascWEPkey.length; i++)
- hexWEPkey += ascWEPkey.charCodeAt(i).toString(16); // creates the HEX WEP key from the ASCII
- }
- else
- {
- alert("Please enter a pass phrase.");
- }
- write_key(form);
- reset_key();
-}
-
-// -->
-</script>
-<script language="Javascript">
-<!--
-
-/*
-Highlight and Copy form element script- By Dynamicdrive.com
-For full source, Terms of service, and 100s DTHML scripts
-Visit http://www.dynamicdrive.com
-*/
-
-//specify whether contents should be auto copied to clipboard (memory)
-//Applies only to IE 4+
-var copytoclip=1
-
-function HighlightAll(theField) {
-var tempval=eval("document."+theField)
-tempval.focus()
-tempval.select()
-if (document.all&&copytoclip==1){
-therange=tempval.createTextRange()
-therange.execCommand("Copy")
-window.status="Contents highlighted and copied to clipboard!"
-setTimeout("window.status=''",1800)
-}
-}
-//-->
-</script>
-
-<style type="text/css">
-<!--
-.button { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; color: #FFFFFF; background-color: #990000}
-.header { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; font-weight: bold; color: #000000; background-color: #FFFFFF; border-color: #999999 #999999 #000000 #000000; text-decoration: underline}
-.textfield { font-family: "Courier New", Courier, mono; font-size: 12px}
-.header2 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: bold; color: #000000; background-color: #FFFFFF; border-color: #999999 #999999 #000000 #000000; text-decoration: underline}
-p { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px; color: #000000}
--->
-</style>
-</head>
-<body bgcolor="#FFFFFF" text="#000000">
-<form name="sweps" method="post" action="">
- <p class="header">WLAN STRONG KEY GENERATOR v2.2 by Warewolf Labs</p>
-
- <p><b>NEWS &amp; UPDATES</b>:</p>
- <p><u>2005-01-25</u>: This program was originally written and freely
- distributed in 2001 with the goal of allowing the average consumer to easily
- lock down their wireless network with WEP, while at the same time employing
- something stronger than simple, easily-guessed words or phrases that were
- susceptible to offline dictionary attacks.&nbsp; </p>
- <p>Much has changed in the wireless network security landscape since the
- inception of this program.&nbsp; Techniques and programs are now available
- (cf. the article
- <a target="_blank" href="http://securityfocus.com/infocus/1814">here</a>)
- which can crack a WEP key in such a short period, that any
- last vestiges of credibility that WEP may have once held in providing
- effective security have been cast out.</p>
-
- <p>Therefore, it is important to realize that WEP (regardless of key
- strength) will only keep out casual
- intruders, and any concerted effort will allow an attacker into your network
- without too much trouble.&nbsp; With this caveat in mind, the generation of
- WEP keys will remain intact in this tool to allow for some (albeit slim)
- measure of protection for network devices which are limited to WEP-based
- protective measures. </p>
- <p>A future release of the WLAN Strong Key Generator will provide the
- capability to generate a strong Wi-Fi Protected Access Pre-Shared Key
- (WPA-PSK).</p>
- <p><b>INSTRUCTIONS</b>:</p>
- <p>To generate a <a href="#random">random WEP key</a>, select the bit key length
- to generate and press the corresponding button; the ASCII or HEX key can then
- be copied to your clipboard manually or via the &quot;<b>copy to clipboard</b>&quot; button to
- the right of the <a href="#generated_key">Generated Key</a> text fields.&nbsp;
- Note that in order to be as platform-independent as possible, characters
- used for generation of these keys are limited to a subset of
- the basic ASCII code table (95 elements, including the letters &quot;a&quot; to &quot;z&quot;, &quot;A&quot; to &quot;Z&quot;,
- and most
- punctuation and other standard symbols; at the time that this original
- program was written, support for Unicode was not widely present
- among the installed base of consumer operating systems to allow for the inclusion of extended characters which would increase the strength of WEP
- keys generated with this program).</p>
-
- <p>You can also generate a <a href="#custom">custom WEP key</a> based on your
- own pass phrase or other input.&nbsp; <u>IMPORTANT:</u> this function simply
- converts your supplied input from ASCII to HEX form; it does not apply
- any other transformations or algorithms upon it, therefore <i>your custom
- key will only be as strong as your source material</i>.</p>
- <p>A good primer on WEP key setup and terms is located <a href="http://www.practicallynetworked.com/support/mixed_wep.htm" target="_blank">here</a>.</p>
-
- <p><b>NOTES</b>:</p>
- <p><!-- begin / added by Kraix -->
- - If your product vendor requests 40-bit keys, use the 64-bit key<br>
- - If your product vendor requests 104-bit keys, use the 128-bit key<br>
- <!-- end / added by Kraix -->
- - Apple users can enter HEX keys into their AirPort setup by prefixing the
- generated string with a&quot;<b>$</b>&quot; symbol<br>
-
- (i.e. if the generated HEX code is <span class="textfield"><b>6b5e454532</b></span>
- then you would enter <span class="textfield"><b>$6b5e454532</b></span> into
- your configuration)</p>
- <table border="0" cellspacing="0" cellpadding="0">
- <tr>
- <td align="right" class="header2" width="120"><a name="random">Random WEP Key</a></td>
- <td width="10">&nbsp;</td>
-
- <td width="150">&nbsp;</td>
- </tr>
- <tr>
- <td align="right" width="120"><img src="/themes/pfsense/images/misc/key_64.gif" width="81" height="42"></td>
- <td>&nbsp;</td>
- <td width="150">
- <input type="button" class="button" name="gen64" value="generate 64-bit key" onClick="javascript:go(this.form, 5)">
- </td>
- </tr>
- <tr>
- <td align="right" width="120">&nbsp;</td>
-
- <td>&nbsp;</td>
- <td width="150">&nbsp;</td>
- </tr>
- <tr>
- <td align="right" width="120"><img src="/themes/pfsense/images/misc/key_128.gif" width="81" height="42"></td>
- <td>&nbsp;</td>
- <td width="150">
- <input type="button" class="button" name="gen128" value="generate 128-bit key" onClick="javascript:go(this.form, 13)">
- </td>
- </tr>
-
- <tr>
- <td align="right" width="120">&nbsp;</td>
- <td>&nbsp;</td>
- <td width="150">&nbsp;</td>
- </tr>
- <tr>
- <td align="right" width="120"><img src="/themes/pfsense/images/misc/key_152.gif" width="81" height="42"></td>
- <td>&nbsp;</td>
- <td width="150">
- <input type="button" class="button" name="gen152" value="generate 152-bit key" onClick="javascript:go(this.form, 16)">
-
- </td>
- </tr>
- <tr>
- <td width="120">&nbsp;</td>
- <td>&nbsp;</td>
- <td width="150">&nbsp;</td>
- </tr>
- <tr>
- <td align="right" width="120"><img src="/themes/pfsense/images/misc/key_256.gif" width="81" height="42"></td>
- <td>&nbsp;</td>
-
- <td width="150">
- <input type="button" class="button" name="gen256" value="generate 256-bit key" onClick="javascript:go(this.form, 29)">
- </td>
- </tr>
- <tr>
- <td width="120">&nbsp;</td>
- <td>&nbsp;</td>
- <td width="150">&nbsp;</td>
- </tr>
- <tr>
- <td width="120">
- <p align="left" class="header2"><a name="custom">Custom WEP Key</a></p>
-
- </td>
- <td>&nbsp;</td>
- <td width="150">&nbsp;</td>
- </tr>
- <tr>
- <td colspan="3">
- <p align="left"><b>NOTE</b>: 5/13/16/29 characters are needed for 64/128/152/256-bit
- WEP</p>
- </td>
- </tr>
-
- <tr>
- <td width="120">
- <p align="right">Custom Phrase</p>
- </td>
- <td>&nbsp;</td>
- <td width="150" valign="top">
- <p>
- <input type="text" name="customPhraseField" size="30" class="textfield" maxlength="29" value="enter your phrase here" onClick="this.value=''"; onChange="document.sweps.customPhraseCCField.value=document.sweps.customPhraseField.value.length;" onBlur="document.sweps.customPhraseCCField.value=document.sweps.customPhraseField.value.length;">
- </p>
- </td>
-
- </tr>
- <tr>
- <td width="120">
- <p align="right">Character Count</p>
- </td>
- <td>&nbsp;</td>
- <td width="150" valign="middle">
- <p>
- <input type="text" name="customPhraseCCField" size="2" class="textfield" maxlength="2">
- </p>
-
- </td>
- </tr>
- <tr>
- <td width="120">&nbsp;</td>
- <td>&nbsp;</td>
- <td width="150" valign="middle">
- <input type="button" class="button" name="genck" value="generate custom key" onClick="javascript:go_ck(this.form)">
- </td>
- </tr>
- </table>
-
- <br>
- <table width="500" border="0" cellspacing="0" cellpadding="0">
- <tr>
- <td align="left" colspan="3">
- <p></p>
- <p class="header2"><a name="generated_key">Generated Key</a></p>
- </td>
- <td>&nbsp; </td>
- </tr>
-
- <tr>
- <td align="right" width="125">
- <p></p>
- <p>ASCII</p>
- </td>
- <td width="10">&nbsp;</td>
- <td>
- <input type="text" name="ascKeyTextField" size="60" class="textfield" maxlength="29">
- </td>
- <td>
- <input type="button" name="copyASCII" value="copy to clipboard" onClick="javascript:HighlightAll('sweps.ascKeyTextField')" class="button">
-
- </td>
- </tr>
- <tr>
- <td align="right" width="125">
- <p>HEX</p>
- </td>
- <td>&nbsp;</td>
- <td>
- <input type="text" name="hexKeyTextField" size="60" class="textfield" maxlength="58">
- </td>
-
- <td>
- <input type="button" name="copyHEX" value="copy to clipboard" onClick="javascript:HighlightAll('sweps.hexKeyTextField')" class="button">
- </td>
- </tr>
- </table>
-</form>
-</body>
-</html>
OpenPOWER on IntegriCloud